In this post, we discuss BufferQueue, BufferQueue::BufferSlotand BufferQueue::BufferState defined
We have learned the concepts of ANativeWindow andANativeWindowBuffer defined
in system/core/include/system/window.h with class Surface (in frameworks/native/include/gui/Surface.h) being
concrete implementation of the former class and GraphicBuffer (in frameworks/native/include/ui/GraphicBuffer.h) being an
implementation of the latter. IGraphicBufferProducer (in frameworks/native/include/gui/IGraphicBufferProducer.h) defines
the Binder API interface for buffer interactions between a surface and SurfaceFlinger. Therefore a UI may draw on a GraphicBuffer and
by invoking eglSwitchBuffesr() to render the current buffer; WithineglSwitchBuffers() calls queueBuffer(),
dequeueBuffer(), and other APIs in ANativeWindow as necessary.
What is yet to learn is how a graphic buffer queued througheglSwitchBuffers() is composed into frame buffer or hardware-over-laid
for rendering and then how the buffer is released to the surface. Here we attempt to uncover part of the myth.
IGraphicBufferProducer was named after the relation of GraphiBuffer content producer and consumer. When a surface finishes
drawing on a graphic buffer and subsequent calling of the Surface::queueBuffer() in eglSwitchBuffers()
will invoke BpGraphicBufferProducer::queueBuffer()
to pass the graphic buffer (through BufferQueue::queueBuffer())to a BufferQueue object
in the Layer object corresponding to the Surface object.
BufferQueue implements BnGraphicBufferProducer and
provides the graphic Buffer consumer APIs( e.g. acquireBuffer(),releaseBuffer(), etc.), Going
forward, we use a more formal term frame to denote the content in the graphic buffer.
The Layer class implementsSurfaceFlingerConsumer::FrameAvailableListener::onFrameAvailable()
is set to be invoked in BufferQueue::queueBuffer(); Layer::onFrameAvailable () marks arrival of a new frame and signals
to SurfaceFlinger by a signalLayerUpdate() call. ThesignalLayerUpdate()
will either request a vsync on behalf of the surface or post a MessageQueue::INVALIDATE message.
BufferQueue::BufferSlot and BufferQueue::BufferSlot::BufferState.
Within BufferQueue, a GraphicBuffer object is assigned a descriptor BufferSlot object to contain attribute metadata such
as associated EGLDisplay, timestamp, transform, cropping, framenumber, fence, buffer state, and so on.
BufferQueue::BufferSlot::BufferState represents the different states in which a buffer slot can be. SurfaceFlinger recognizes
four buffer states, namely, FREE, DEQUED, QUEUED, ACQUIRED, respectively. You may refer to the BufferQueue.h for further information.
BufferQueue tracks all BufferSlots in an array and index each slot by a cardinal slot number, which is reference as buffer
Before ending this post, I want to note that inBufferQueue::acquireBuffer(), an argument type BufferItem is used, which
is sort of equivalent to BufferQueue::BufferSlot.