Platform/GFX/Gralloc: Difference between revisions

Line 21: Line 21:
   android::sp<android::GraphicBuffer>.
   android::sp<android::GraphicBuffer>.


That's in fact the right way (the only way) to hold on to a GraphicBuffer.
That's the right way to hold on to a gralloc buffer in a given process. But since gralloc buffers are shared across multiple processes, and GraphicBuffer objects only exist in one process, a different type of object has to be actually shared and reference-counted across processes. That is the notion of a gralloc buffer ''handle''.


Since sp object is allocated on stack of each process that share it. The undering buffer handle must be refcounted otherwise the refcount goes wrong when it shared across process. The trick is when GraphicBuffer going shared by processes, the IPC code of Android will call GraphicBuffer::flatten to serialize the GraphicBuffer object, and call GraphicBuffer::unflatten to deserialize it. And GraphicBuffer::unflatten will call mBufferMapper.registerBuffer to make sure the undering buffer handle is refcounted correctly.
So when a gralloc buffer is shared between two processes, each process has its own GraphicBuffer object with its own refcount; these are sharing the same underlying gralloc buffer ''handle''. The sharing happens by calling GraphicBuffer::flatten to serialize and GraphicBuffer::unflatten to deserialize it. GraphicBuffer::unflatten will call mBufferMapper.registerBuffer to ensure that the underlying buffer handle is refcounted correctly.


And when GraphicBuffer refcount goes to zero, GraphicBuffer::~GraphicBuffer will incurred, and it will call free_handle which call mBufferMapper.unregisterBuffer. So the undering buffer will not released untill all the GraphicBuffer got released and the undering buffer handle refcount goes to zero.
When a GraphicBuffer's refcount goes to zero, the destructor will call free_handle which call mBufferMapper.unregisterBuffer, which will decrement the refcount of the gralloc buffer ''handle''.


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.
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.


The usage flag is some kind of hint for performance optimization. When you use SW flags, it may just disable all possible optimize there. Since CPU usually cache data into register, when we want to lock the buffer for read/write, it have to maintain the cache for correct data. However, other hardware that can use GraphicBuffer on Android e.g. Codec, Camera, GPU do not cache data. It locks/unlocks the buffer in a faster fashion.
The usage flag is some kind of hint for performance optimization. When you use SW flags, it may just disable all possible optimizations there. Since CPU usually cache data into registers, when we want to lock the buffer for read/write, it have to maintain the cache for correct data. However, other hardware that can use GraphicBuffer on Android e.g. Codec, Camera, GPU do not cache data. It locks/unlocks the buffer in a faster fashion.


It may helps on perforamce if we can use the usage flag correctly to describe our purpose about the buffer.
It may helps on perforamce if we can use the usage flag correctly to describe our purpose about the buffer.
Confirmed users
753

edits