Changes

Jump to: navigation, search

Platform/GFX/Gralloc

14 bytes removed, 07:15, 22 May 2013
How Android is using Gralloc
== SurfaceTexture ==
SurfaceTexture is a client-server architecture. The SurfaceTextureClient implements EGLNativeWindowANativeWindow, into which the application renders.
The EGLNativeWindow ANativeWindow is a glue to make SurfaceTexture can be used as render surface of EGL, which abstract out some buffer management detail when use OpenGL to manipulate shared memory in Android and make it easier to use OpenGL across process. Since eglSwapBuffers calls to EGLNativeWindowANativeWindow::dequeueBuffer to acquire new buffer and EGLNativeWindowANativeWindow::queueBuffer to return the buffer implicitly, the user can avoid to create several textures and manage them directly. The other useful feature of implement it in this way is that most BSP vendor provided graphics profilers(e.g. Adreno profiler from QCOM, PerfHUD ES from nVidia) that recognize the eglSwapBuffers call as frame boundary to collect frame based GL information from driver to help developement and performance tuning. SurfaceTexture is a unified buffer management mechanism on Android, which you can setup it to run in different mode: sync/async, single/multiple buffer by simple function call which make SurfaceTexture be used everywhere in Android: Codec/Camera configure it to have serveral buffer (based on hardware, 9 for camera preview in Unagi) run asynchronously, Layer rendering configure it to have 2~3 buffer (based on BSP) run synchronously. And since its flexbility, you can encode a OpenGL rendered surface on-the-fly by using SurfaceMediaSource (which implement ISurfaceTexture) which is the core of Google Miracast.
SurfaceTexture is the server-side class. SurfaceTextureClient is the client-side class. Both store an array of GraphicBuffers, called mSlots. The GraphicBuffer objects are separate instances in SurfaceTexture and in SurfaceTextureClient, but the underlying gralloc buffer handles are the same. The mechanism here is the client side issues a SurfaceTextureClient::dequeueBuffer call to get a new buffer to paint to. If there are not already enough buffers, and the number of buffers is not over the limit (32), it sends an IPC message that results in a call to SurfaceTexture::dequeueBuffer which allocates the GraphicBuffer. And after buffer allocation, the client side will send an IPC message that results in a call to SurfaceTexture::requestBuffer to get the gralloc buffer handle serialized over IPC back to it, and construct a GraphicBuffer around this handle, and cache it into its own mSlots. The mSlots arrays on both sides mirror each other, so that the two sides can refer to GraphicBuffers by index.
When the client side calls EGLNativeWindowANativeWindow::queue to present the frame from eglSwapBuffers call, SurfaceTextureClient::queue is issued and send the index where the rendered buffer is to server side SurfaceTexture::queue. Which cause the index queued into SurfaceTexture::mQueue for rendering. SurfaceTexture::mQueue is a wait queue for frame that wants to be rendered. In sync mode, the frame are showed one after another, but may dropped in async mode.
For SurfaceFlinger, after each time SurfaceTexture::queue are issued, it will start for next renderloop. In each render loop, SurfaceFlinger calls to SurfaceTexture::updateTexImage to dequeue a frame from SurfaceTexture::mQueue and bind the GraphicBuffer into a texture.
As a result, Android does not explicit unlock the GraphicBuffer as B2G did now. Since it will lock next buffer each time new buffer comes. And it will use eglCreateSyncKHR/eglClientWaitSyncKHR to make sure the buffer are not locked before it returns the GraphicBuffer into the buffer pool.
Confirm
753
edits

Navigation menu