Initial Support for Freedreno on Android

I now have Android-x86 running Freedreno on my IFC6410 \o/!

Freedreno on Android

The setup:

on an IFC6410 (A320 GPU) with an ancient CRT

The gralloc module carries two responsibilities: providing an interface to /dev/graphics/fb0 for creating FrameBufferNativeWindow-s and, handling buffer requests that come in through a singleton system wide GraphicBufferAllocator object. Each request is stamped with a usage flag to help gralloc decide how to provide it.

Current setup uses the default eglSwapBuffers() based HWC, i.e. all-GPU composition for now:

$ dumpsys SurfaceFlinger
numHwLayers=3, flags=00000000
type    |  handle  |   hints  |   flags  | tr | blend |  format  |          source crop            |           frame           name
GLES | 2a2a31e0 | 00000000 | 00000000 | 00 | 00100 | 00000005 | [      0,     13,   1024,    744] | [    0,   13, 1024,  744]
GLES | 2a060ad8 | 00000000 | 00000000 | 00 | 00105 | 00000005 | [      0,      0,   1024,     13] | [    0,    0, 1024,   13] StatusBar
GLES | 2a0614d8 | 00000000 | 00000000 | 00 | 00105 | 00000005 | [      0,      0,   1024,     24] | [    0,  744, 1024,  768] NavigationBar

Shortlog of issues faced:

I started with getting bare kitkat-x86 up on the IFC6410 with an ARM build setup. Fast forward multiple tries figuring out the build system and setting up the board-specific init scripts, I added Mesa to the build. The default HWC doesn’t implement blank(), which took some time to realize and fix a segfault. With all parts in place, I had the boot logo, with two boot flows due to a race condition. Disabling GPU authentication was another hack that needed to be put in.

Finally, I had Skia causing trouble while starting the UI. This turned out to be a simple fix to drm_gralloc, but had me looking everywhere through the sources and mistaking it to be a NEON specific issue with Skia.


Currently, Android only renders a few windows before SurfaceFlinger crashes while gralloc::unregisterBuffer() and restarts. Also, dexopt dies causing app installation failure, so not many apps to play around with.


  • Add a KMS based Hardware Composer.
  • GBM for drm_gralloc

Here is my trello board:

Thanks Rob, Emil, #freedreno, #android-x86 and #linaro!


Android-x86 on IFC6410

Documenting how to get Android-x86 up on an IFC6410.


0. Install repo.
1. Get the source. Shallow syncing to save space (full source >30G):

mkdir android-x86
cd android-x86
repo init --depth=1 -u -b kitkat-x86 -g default,arm,pdk,-darwin
repo sync -j16

2. add local_manifests ( with drm_gralloc and mesa at the right location.


Compiling the kernel:

EDIT: apply kernel-* at over 4.2 (integration-linux-qcomlt) to get logger and disable gpu auth.

git clone
git checkout -t origin/integration-linux-qcomlt
cd kernel
make ARCH=arm CROSS_COMPILE=~/devel/android-x86/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi- qcom_defconfig
make -j16

The zImage needs to have a binary blob prepended to it to boot with the LK bootloader on IFC6410.

cat fixup.bin arch/arm/boot/zImage arch/arm/boot/dts/qcom-apq8064-ifc6410.dtb > zImage-dtb

Building Android-x86 requires JDK (see build requirements). I used JDK 7 on openSUSE, and needed a bunch of patches to get a successful build:

Single Patch:

This may be helpful when applying the first patch, since repo doesn’t support diff style patching.

EDIT: use repo diff at instead.!topic/repo-discuss/43juvD1qGIQ should work to apply.

The Qualcomm specific init scripts (not packaged with Android-x86) are available here.

git clone ~/devel/qcom-android

cd android-x86/system/core

git apply ~/devel/qcom-android/android-x86-avoid-parentheses-from-fdt.patch

EDIT: ^ repo diff above contains these changes.

Building the source:

cd android-x86
source build/
lunch mini_armv7a_neon-userdebug
make -j8 TARGET_PREBUILT_KERNEL=<path-to-zImage-dtb> libGLES_mesa gralloc.drm

This prepares the necessary images at `android-x86/out/target/product/armv7-a-neon`.

Preparing boot.img:

Extract the qualcomm-specific init scripts (for fstab partitions) into `android-x86/out/target/product/armv7-a-neon/root` for the ramdisk. These are taken from Linaro’s android-ifc6410.

cd android-x86/out/target/product/armv7-a-neon/root
mv ~/devel/qcom-android/init.* .
mv ~/devel/qcom/android/fstab.* .

# prepare initrd
find . | cpio -o -H newc | gzip > ../qcom-ramdisk.img

# make boot.img (= zImage + ramdisk)
# from armv7-a-neon:
abootimg --create qcom-boot.img -k  -r qcom-ramdisk.img -f ~/devel/qcom-android/bootimg.cfg

Preparing system_ext4.img

EDIT: run from out/target/product/armv7-a-neon/ .

The system.img created isn’t ext4 formatted (shows as dBase IV DBT!), and init refuses to mount it as /system : (. Repacking:

dd if=/dev/zero of=system_ext4.img bs=4K count=100000  # large enough
mkfs.ext4 system_ext4.img
tune2fs -c0 -i0 system_ext4.img
mkdir system-ext4
mount -o loop system_ext4.img system-ext4/
cp -v -r -p system/* system-ext4/
umount system-ext4/



Flashing images:

Boot IFC6410 into fastboot mode by holding SW4 during power up.

fastboot flash boot qcom-boot.img
fastboot flash system system_ext4.img
fastboot continue

Reboot with a UART cable attached to get serial console.

Freedreno on Android – Overview

I’m working on adding Freedreno support to Android this summer with the Foundation! This post documents the technical specifics of what I’ll be doing.

Android abstracts its hardware interfaces behind device-specific Hardware Abstraction Layers which can be customized by the vendors. The compositor, called SurfaceFlinger uses the Hardware Composer HAL to
1) decide if a layer must be processed through OpenGL/GPU (HWC_FRAMEBUFFER) or the SoC display controller (HWC_OVERLAY) during prepare().
2) handle VSYNCs through vsync().
3) select displays and provide modesetting.
The OpenGL composition pathway requires libEGL and libGLES to be present. In the absence of a HWC, all compositions use this pathway.

Buffer allocations happen through gralloc HAL, which uses an in-kernel memory manager to provide alloc() and free() calls. It allocates suitable buffers depending on the requested usage type. HWC and gralloc API documentation is available at hwcomposer.h and gralloc.h.
A KMS based HWC would reduce GPU dependency and improve performance by handling composition through the display controller.

This project targets providing a functional Android graphics path using DRM/KMS based gralloc and HWC with atomic pageflips using Freedreno/Mesa EGL/GLES running on upstream Android or Android-x86 on an IFC6410. A stretch goal is to have Freedreno support with an Android distro (CyanogenMod).

Implementation Plans:
I am starting with testing and fixing the existing bits and proceeding to interface HWC with KMS APIs to use the SoC display controller.

The libEGL and libGLES requirements would be provided using Mesa, similar to Android-x86. drm_gralloc support for Freedreno has been developed, but remains largely untested. The existing reference HWC implementation just uses eglSwapBuffers (i.e. GPU composition).

Initial task would be assembling these untested parts to run on the IFC6410. After fixing the issues discovered, we would have Freedreno running on Android, but *without* any modesetting support in place.

The project would then proceed to implementing the HWC with KMS APIs. A reference implementation exists using userspace fences – sw_sync, but atomic modesetting support within MSM kernel can provide a way to do away with these.

Android Graphics Stack Requirements
Freedreno drm_gralloc in Android-x86