Understanding Android Graphics Internals -SurfaceFlinger(V)

This SurfaceFlinger series turns lengthy. Let’s see if we can wrap it up in this post.

  • FramebufferSurface and DisplayDevice

Jelly Bean supports external displays(e.g. HDMI, WiDi). Each display is represented by a DisplayDevice instance and associated with a FramebufferSurface instance which makes the mDisplaySurface field.

FramebufferSurface subclasses both ConsumeBase and DisplaySurface and wraps around a BufferQueue instance.

DisplayDevice  maintains a reference to  a vector of all sorted visible layers in mVisibleLayersSortedByZ, which is tracked in SurfaceFlinger::mDrawingState.

SurfaceFlinger tracks all DisplayDevice in an keyed vector mDisplaysSurfaceFlinger::readyToRun() creates each DisplayDevice along with FramebufferSurface and adds each to mDisplays.

In SurfaceFlinger::doDisplayComposition(),when composition is complete and the display back frame buffer is drawn; then  DisplayDevice::swapBuffers() is invoked for a DisplayDevice instance. Within the latter call, eglSwapBuffers() is called. As a result,  FramebufferSurface::onFrameAvailable() is called.

In FramebufferSurface::onFrameAvailable(), HwComposer::fbPost() is called, in which for non HWC_DEVICE_API_VERSION_1_1, framebuffer_device_t::post in gralloc module is called to post the back frame buffer to frame buffer device driver.

  • HWComposer

This class wraps framebuffer_device_t and struct hwc_composer_device_1 and manages the vsync with HWComposer::event_control(), HWComposer::sync().

SurfaceFlinger owns an instance of HWComposer.

  • SurfaceFlinger

1.  Implements BnISurfaceComposer functionality

BnISurfaceComposerClient is implemented by Client class; responsible for creation of Layer instances.

2. Implements HWComposer::EventHandler

Accepts on vsync and hotplug in events from hwcomposer module; process vsync enable/disable in eventControl().

3.  Runs message queue on its own thread loop.

after initialization in readyToRun(), all handling is asynchronous and message driven.

4.  readyToRun()

Instantiates HWComposer instances, instantiates and Initializes DisplayDevice objects and corresponding FramebufferSurface objects, initializes egl config, context, etc.

5. Maintains the current and the drawing SurfaceFlinger::State

Drawing state is the state being rendered, the current state is open for modifications. mCurrentState is copied to mDrawingState  in CommitTransaction during handling of  MessageQueue::TRANSACTION and MessageQueue::INVALIDATE messages.

6. Several sources may trigger composition

new surface frame queued, changes in orientation and other flags, surface removal, vsync.

7. Composition and rendering

All layers are sorted by depth dimension Z, send layer state information to hwcomposer module to determine rendering by overlay or composition (by the prepare method in hwcomposer).

For layers selected for composition,  compute visible regions based on Z and alpha blending factor, and draw them to each DisplayDevice object’s back FramebufferSurface.

When composition on a display is complete, invoke eglSwapBuffers to switch back FramebufferSurface to the front and posted to frame buffer device.

In summary, SurfaceFlinger design is complex and has to deal with many usage scenarios and corner use cases.

2 thoughts on “Understanding Android Graphics Internals -SurfaceFlinger(V)”

  1. Hello Charles,
    thanks for your blog i find useful information.
    But I have a question, maybe you could answer it, i hope so, thank you very much.
    I try to capture screen data from the surface flinger, using the captureScreen method like this:
    composer->captureScreen(mainDisplay, bufferProducer, width, height, …. )
    It works but if the screen is rotated then I have data in the bad orientation.
    I did not found how to get rotated data corresponding to the rotation of the screen.
    Do you have any idea on how to do ?

    Thank you very much.

Leave a comment