1. BufferQueue
连接图形数据的生产者和消费者,生产者和消费者可以存在于不同的进程中,几乎所有的图形数据buffer的传递都依赖于BufferQueue。
2. 如何传递
生产者先指定好需要的空闲buffer的属性,如:宽,高,像素格式,用法标识等,然后想BufferQueue请求一块符合要求的空闲buffer(dequeueBuffer()),当这个buffer使用完后会通过queueBuffer()方法将这块有数据的buffer返回给BuuferQueue,然后消费者会通过acquireBuffer()获取这个buffer并处理其中的内容,最后处理完,会通过releaseBuffer()将这块buffer归还给BufferQueue。
Android BufferQueue中核心数据是一个GraphicBuffer的队列。而GraphicBuffer根据使用的场合不同可以从共享内存(Ashmem,共享内存要在应用程序和服务端程序两个进程之间共享)或者从硬件缓冲图形缓冲区(Framebuffer,硬件图形缓冲区是SurfaceFlinger渲染完成要放到屏幕上的)中分配。
每个buffer的用途不同,所以buffer的相关属性以及数量都是不同的。
3. Fence
Fence是一种同步机制,用于GraphicBuffer的同步。用来处理跨硬件平台不同的情况(CPU和GPU),尤其是CPU、GPU和HWC之间的同步。另外,也可用于多个时间点之间的同步,当Graphics Buffer的生产者或消费者在对buffer处理完之后,通过fence发出信号,这样系统可以异步queue当前不需要但有可能接下来会使用读写的buffer。简言之,在合适的时间发一种信号,将先到的buffer拦住,等后来的到达,两者步调一致再一起走。
4. BufferQueue State
- FREE:表明这块buffer现在可以被生产者dequeue出来,但是这块buffer当下这一小段时间内仍可能被消费者使用着.所以就算生产者dequeue到了这块buffer,它也还不能立即修改。buffer里的任何东西,直到收到fence信号,那就表示消费者已经用完这块buffer了。这时,生产者才能往里写东西。
- DEQUEUED:表明这块buffer被生产者dequeu出来了,得等到fence信号才能写。
- QUEUED:表明这块buffer被生产者填完数据后,重新放回到了队列供消费者使用,得等到fence信号,后其内容才能被访问。
- ACQUIRED:表明这块buffer以经被消费者获取到了,得等到fence信号后才能读。
5. 参与对buffer进行管理的对象
- BufferQueue:可以认为BufferQueue是一个服务中心,其它两个owner必须要通过它来管理buffer。比如说当producer想要获取一个buffer时,它不能越过BufferQueue直接与consumer进行联系,反之亦然。这有点像房产中介一样,房主与买方的任何交易都需要经过中介的同意,私自达成的协议都是违反规定的
- Producer:生产者就是“填充”buffer空间的人,通常情况下当然就是应用程序。因为应用程序不断地刷新UI,从而将产生的显示数据源源不断地写到buffer中。当Producer需要使用一块buffer时,它首先会向中介BufferQueue发起dequeue申请,然后才能对指定的缓冲区进行操作。这种情况下buffer就属于producer一个人的了,它可以对buffer进行任何必要的操作,而其它owner此刻绝不能擅自插手。当生产者认为一块buffer已经写入完成后,它进一步调用BufferQueue的queue。从字面上看这个函数是“入列”的意思,形象地表达了buffer此时的操作——把buffer归还到BufferQueue的队列中。一旦queue成功后,owner也就随之改变为BufferQueue了
- Consumer:消费者是与生产者相对应的,它的操作同样受到BufferQueue的管控。当一块buffer已经就绪后,Consumer就可以开始工作了。