Changes

Jump to: navigation, search

Platform/GFX/Gralloc

4,132 bytes added, 21:58, 15 May 2013
Allocation and lifetime of Gralloc buffers
= Allocation and lifetime of Gralloc buffers =
== How Gralloc buffers are created and refcounted (non Mozilla-specific) == The android::GraphicBuffer class is refcounted. It is meant to be used with Android Strong Pointers (android::sp). That's why you'll see a lot of   android::sp<android::GraphicBuffer>. That's in fact the right way (the only way) to hold on to a GraphicBuffer. The GraphicBuffer constructors take a "usage" bitfield. We should always pass HW_TEXTURE there, as we always want to use gralloc buffers as the backing surface of OpenGL textures. We also want to pass the right SW_READ_ and SW_WRITE_ flags.
== How we create Gralloc buffers ==
 
Most of out GraphicBuffer's are constructed by GrallocBufferActor::Create. This unconditionally uses SW_READ_OFTEN and SW_WRITE_OFTEN, which is probably bad at least for some use cases.
 
Out protocol to create GraphicBuffers is as follows. It's generally the content side that wants to create a new GraphicBuffer to draw to. It sends a message to the compositor side, which creates the Gralloc buffer and returns a serialized handle to it; then back to the content side, we receive the serialized handle and construct our own Gralloc buffer instance from it.
 
In more detail (this is from [https://wiki.mozilla.org/User:VladVukicevic/Gralloc Vlad's wiki page]):
 
Content side:
* Entry point: PLayersTransactionChild::SendPGrallocBufferConstructor (generally called by ISurfaceAllocator::AllocGrallocBuffer).
* This sends a synchronous IPC message to the compositor side.
 
Over to the compositor side:
* The message is received and this comes in as a call to PLayerTransactionParent::AllocPGrallocBuffer, implemented in LayersTransactionParent.cpp.
* This calls GrallocBufferActor::Create(...), which actually creates the GraphicBuffer* and a GrallocBufferActor* (The GrallocBufferActor contains a sp<GraphicBuffer> that references the newly-created GraphicBuffer*).
* GrallocBufferActor::Create returns the GrallocBufferActor as a PGrallocBufferParent*, and the GraphicBuffer* as a MaybeMagicGrallocBufferHandle.
* The GrallocBufferActor/PGrallocBufferParent* is added to the LayerTransactionParent's managed list.
* The MaybeMagicGrallocBufferHandle is serialized for reply (sending back the fd that represents the GraphicBuffer) -- using code in ShadowLayerUtilsGralloc ParamTraits<MGBH>::Write.
 
Back to the content side:
* After the sync IPC call, the child receives the MaybeMagicGrallocBufferHandle, using ShadowLayerUtilsGralloc.cpp's ParamTraits<MGBH>::Read.
* Allocates empty GrallocBufferActor() to use a PGrallocBufferChild.
* Sets the previously created GrallocBufferActor/PGrallocBufferChild's mGraphicBuffer to the newly-received sp<GraphicBuffer>.
* The GrallocBufferActor/PGrallocBufferChild is added to the LayerTransactionChild's managed list.
* A SurfaceDescriptorGralloc is created using the PGrallocBufferChild, and returned to the caller.
== How we manage the lifetime of Gralloc buffers ==
 
As said above, what effectively controls the lifetime of gralloc buffers is reference counting, by means of android::sp pointers.
 
Most of our gralloc buffers are owned in this way by GrallocBufferActor's. The question then becomes, what controls the lifetime of GrallocBufferActors?
 
GrallocBufferActors are "managed" by IPDL-generated code. When they are created by the above-described protocol, as said above, they are added to the "managee lists" of the LayerTransactionParent on the compositor side, and of the LayerTransactionParent on the content side.
 
FIXME XXX QUESTION: what then decides when GrallocBufferActors are destroyed and removed from the managee lists?
== Unresolved problems ==
 
We don't have a good way of passing the appropriate USAGE flags when creating gralloc buffers. In most cases, we shouldn't pass SW_READ_OFTEN. If the SyncFrontBufferToBackBuffer mechanism requires that, that's sad and we should try to fix it (by doing this copy on the GPU). In many cases, it also doesn't make sense to pass SW_WRITE_OFTEN --- that basically only makes sense for Thebes layers, and Canvas2D if not using SkiaGL, but that doesn't make any sense for WebGL, SkiaGL canvas, or video.
 
It sucks that when content wants a new gralloc buffer to draw to, it has to wait for all the synchronous IPC work described above. Could we get async gralloc buffer creation?
= Gralloc buffers locking =
Confirm
753
edits

Navigation menu