Platform/GFX/Gralloc: Difference between revisions

Jump to navigation Jump to search
Line 134: Line 134:
SurfaceTexture is a client-server architecture. The SurfaceTextureClient implements EGLNativeWindow, into which the application renders. When the Android hardware UI is used, the SurfaceTextureClient is bound into a EGLSurface, and when the application wants to present the buffer, it calls eglSwapBuffers which calls to EGLNativeWindow::queue and EGLNativeWindow::dequeue.
SurfaceTexture is a client-server architecture. The SurfaceTextureClient implements EGLNativeWindow, into which the application renders. When the Android hardware UI is used, the SurfaceTextureClient is bound into a EGLSurface, and when the application wants to present the buffer, it calls eglSwapBuffers which calls to EGLNativeWindow::queue and EGLNativeWindow::dequeue.


Where EGLNativeWindow::queue cause the GraphicBuffer returned to SurfaceTexture side (server side). And EGLNativeWindow::dequeue return a new back buffer for drawing into.
SurfaceTexture has a buffer queue SurfaceTexture::mSlots to store a list of GraphicBuffers owned by this class. SurfaceTextureClient side cache the shared GraphicBuffers in its own mSlots once the buffer allocated. The mechenism here is the client side issues SurfaceTextureClient::dequeueBuffer for new buffer, if there are no enough buffer and the buffer amount is not over the limit, it cause SurfaceTexture::dequeueBuffer occurs which allocate the GraphicBuffer. And after buffer allocation, the client side will issue SurfaceTexture::requestBuffer to get a reference to the GraphicBuffer just allocated, and cache the buffer into its own mSlots. Then SurfaceTexture can communicate with the buffer index rather then the GraphicBuffer.


For performance, the client and server side do not pass GraphicBuffer each time queue/dequeue incurred in fact. They refer to the same buffer queue, and just communicate with each other by buffer index.
When the client side calls EGLNativeWindow::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.


In Android SurfaceFlinger, the GraphicBuffer bind into GPU is not unlocked explicitly in fact. Since SurfaceTexture runs in sync mode for SurfaceFlinger, the buffer are queued into a queue until it got rendered. When rendering, the SurfaceTexture::updateTexImage are called to update the GraphicBuffer undering the SurfaceTexture. After rendering, the buffer are not used again until next SurfaceTexture::updateTexImage called. Which means Android do not force GPU unlock the buffer, just lock another buffer and return the old buffer until the new buffer comes. (It use fence object to make sure GPU are done with the buffer, and just call glFinish after fence object creation)
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.
Confirmed users
157

edits

Navigation menu