27 Apr 2012

First light from Weston on Android

A couple of months ago, Collabora assigned me first to research and then make a proof of concept port of Wayland on Android. I had never even seen an Android before. Yesterday, Weston on Android achieved first light!
Galaxy Nexus running Weston and simple-shm.
That is a Samsung Galaxy Nexus smart phone, running a self-built image of Android 4.0.1. Weston is driving the screen, where you see the simple-shm Wayland client. There is no desktop nor wallpaper, because right now, simple-shm is the only ported client.

How is that possible? Android has no DRI, no DRM, no KMS (the DRM API), no GBM, no Mesa, and for this device the graphics drivers are proprietary and I do not have access to the closed driver source.

Fortunately, Android's self-invented graphics stack has pretty similar requirements to Weston. All it took was to write a new Android specific backend for Weston, that interfaces to the Android APIs. Writing it took roughly three days.

And the rest of the two months? I spent some time in studying Android's graphics stack, but the majority of the time sunk into porting the minimum required library dependencies, libwayland, Weston, and simple-shm to the Android platform and build environment. Simply getting the Android build system to build stuff properly took a huge effort, and then I got to write workarounds to features missing in Android's C library (Bionic). Features, that we have taken for granted on standard Linux operating systems for years. I also had to completely remove signal handling and timers from libwayland, because signalfd and timerfd interfaces do not exist in Bionic. Those need to be reinvented still.

Android has gralloc and fb hardware abstraction layer (HAL) APIs. Hardware vendors are required to implement these APIs, and provide EGL and GL support libraries. These implementations are usually closed and proprietary. On top of these is the Android wrapper-libEGL, written in C++, open source. My first thought was to use the gralloc and fb HAL APIs directly, but turned out that the wrapper-libEGL does not support using them in the application side. Instead, I was forced to use some Android C++ API (there is no C API for this, as far as I can tell) to get access to the framebuffer in an EGL-compatible way. In the end, I had to write a lot less code than using the HALs directly.

The Android backend for Weston so far only provides basic graphics output to the screen, and offers (presumably) accelerated GLES2 via EGL for the server. No input devices are hooked up yet, so you cannot interact with Weston. I do not know how to get pageflip completion events (if possible?), so that is hacked over.

Simple-shm is the only client that runs for now. There is no support for EGL/GL in Wayland clients. Toytoolkit clients are waiting for Cairo and dependencies to be ported.

The framebuffer can be used by one program at a time. Normally that program is SurfaceFlinger, the Android system compositor. To be able to run Weston, I have to kill SurfaceFlinger and make sure it stays down. Killing SurfaceFlinger also kills the whole Android UI infrastructure. You cannot even power off the phone by pressing or holding down the physical power button!

A video about simple-shm running on Galaxy Nexus:

The sources with Android build integration and other hacks can be found here:
The wayland_aggregate is how I actually connect to the Android build system. Building is not trivial, and you cannot simply do a checkout and start compiling. You have to get the right Android tree for your device, add my local manifest (which still points to repositories on my hard drive, i.e., won't work for you), download and extract binary blobs, and whatnot. Be warned, I will rebase the above branches.

This is the beginning of pushing a Wayland stack into Android. Next I need to clean up, send stuff upstream, add input support, find out about that pageflip, reinvent signal handling and timerfd, and then move on to the second major task: supporting Wayland GL clients. I hope it is possible to implement the Wayland platform in the wrapper-libEGL.

This work is sponsored by Collabora, Ltd, and I also thank my fellow collaborans for guidance through the vast jungles of Android.


Unknown said...

very nice work :) sounds like fun :)

Unknown said...

I definitely agree with you in that "Fortunately, Android's self-invented graphics stack has pretty similar requirements to Weston"

Then could we simply utilize or extend android surface flinger in order to replace "X"? It is also an open source project licensed under Apache and already proven in many mobile products.

pq said...

Matt, SurfaceFlinger does not handle input at all, does it? You would be missing half of the point then. I am not really interested in SurfaceFlinger for anything, and we are pretty much trying to replace it, so I'm not a right person to answer that. ;-)

Srikant Patnaik said...

Nice work.
I'm on ICS, killing surfaceflinger doesn't blank screen, I have killed and renamed also so that it couldn't auto restart but still no luck. I have a similar project where I'm trying to port plasma-active in dual boot with android, I need to free fb0 so that chrooted Linux's xorg can kick in.

Any help is useful :-)

Anonymous said...

There is a new project called libhybris. May be it can be used to cower missing api's in bionic?

pq said...

Srikant, strange. I've no idea what could be going on. Killing surfaceflinger IIRC makes the screen black, and if I boot without SF, only the bootloader image stays, the one with "Google" and an open padlock white on black. The display device is free. Though I don't think I ever tried legacy fb interface, I've always used EGL with GLESv2 on the "bare" hw. Maybe you have some rescue thing reviving SF every time? o_O

mikolatorbins, yes I know about libhybris. It does cover for the missing APIs in Bionic: we can throw Bionic away and use glibc.

Post a Comment