Hardware rendering of SurfaceFlinger on Qualcomm Adreno GPUs

When I first started porting CyanogenMod to the Huawei U8185 I was blown away by the performance of Qualcomm’s Adreno 200 GPU; paired with the Adreno 200 GPU, the U8185’s msm7225a Snapdragon architecture made for a snappy and pleasurable experience on ICS. Meanwhile, its cousin (the U8150) could barely handle its stock Android 2.2, leave alone my CyanogenMod 7 (Android 2.3, Gingerbread) port!

As impressed as I was, it turns out I was missing a critical run-time configuration property, and therefore still using the CPU for rendering the UI. The sky, it seems, was NOT the limit!

Enabling hardware-accelerated rendering

If you have your Adreno graphics blobs in place and gralloc is working properly, then you need to enable hardware-accelerated rendering of SurfaceFlinger in your build.prop. Here’s the relevant section of mine, configured for the Huawei U8185 on CyanogenMod 9:

# Graphics

The most important part is the debug.sf.hw=1; if you’re not at least using that, then you’re defaulting to CPU rendering (see code snippet below). The other stuff is implementation/device specific, so you’ll have to experiment with your device to figure out what settings to use.

Not your average speed tweaks

You might have seen these flags floating around on lame XDA “speed tweak” threads, but trust me: these are not your average speed tweaks. This is vanilla Android (or at least CAF-enhanced Android for Qualcomm SoCs), so don’t feel ashamed for using them.

The logic in hardware/qcom/display/libgralloc/gpu.cpp (CyanogenMod 9, ICS) is very easy to understand:

    if (property_get("debug.sf.hw", property, NULL) > 0) {
        if(atoi(property) == 0) {
            //debug.sf.hw = 0
            compositionType = CPU_COMPOSITION;
        } else { //debug.sf.hw = 1
            // Get the composition type
            property_get("debug.composition.type", property, NULL);
            if (property == NULL) {
                compositionType = GPU_COMPOSITION;
            } else if ((strncmp(property, "mdp", 3)) == 0) {
                compositionType = MDP_COMPOSITION;
            } else if ((strncmp(property, "c2d", 3)) == 0) {
                compositionType = C2D_COMPOSITION;
            } else {
                compositionType = GPU_COMPOSITION;
    } else { //debug.sf.hw is not set. Use cpu composition
        compositionType = CPU_COMPOSITION;

There’s similar logic in hardware/qcom/display/libhwcomposer/hwcomposer.cpp, so make sure to check it out, understand it, and set the appropriate system properties in your device tree. Regarding the difference between composition types (mdp, c2d, and GPU_COMPOSITION), I’m not sure. That might be a good area to delve into later…

9 thoughts on “Hardware rendering of SurfaceFlinger on Qualcomm Adreno GPUs

  1. So after this, smoother than before? This is a very interesting post. Keep up the good work Alan. I hear hardware….

    1. Yeah, it’s way smooth, dude! One app, Falcon Pro (the Twitter client), is noticeably smoother than on my Exynos4 tablet (with Mali 400MP!). Adreno is no joke, dude…

    1. No downloads yet. It’s really not usable… at all. Haha. You can make phone calls and browse the net, but it’s still really beta.

  2. The difference is the path that the buffers take out to the hardware, and the different hardware that is used during the final composition step

  3. Is it ready to run command line apps? I’m just after a device that has camera / GPS and some CPU to act as a brain for a robot. will this do the trick?

Comments are closed.