博客园Logo
首页
新闻
博问
专区
闪存
班级
代码改变世界
搜索
注册
登录
brucemengbm
博客园
首页
新随笔
联系
订阅
管理
随笔 - 1645 文章 - 0 评论 - 7 阅读 - 117万
Android中的GraphicBuffer同步机制-Fence
Fence是一种同步机制,在Android里主要用于图形系统中GraphicBuffer的同步。那它和已有同步机制相比有什么特点呢?它主要被用来处理跨硬件的情况。尤其是CPU。GPU和HWC之间的同步,另外它还能够用于多个时间点之间的同步。GPU编程和纯CPU编程一个非常大的不同是它是异步的。也就是说当我们调用GL command返回时这条命令并不一定完毕了。仅仅是把这个命令放在本地的command buffer里。详细什么时候这条GL command被真正运行完毕CPU是不知道的,除非CPU使用glFinish()等待这些命令运行完,第二种方法就是基于同步对象的Fence机制。以下举个生产者把GraphicBuffer交给消费者的样例。如生产者是App中的renderer。消费者是SurfaceFlinger。GraphicBuffer的队列放在缓冲队列BufferQueue中。
BufferQueue对App端的接口为IGraphicBufferProducer,实现类为Surface,对SurfaceFlinger端的接口为IGraphicBufferConsumer,实现类为SurfaceFlingerConsumer。
BufferQueue中对每一个GraphiBuffer都有BufferState标记着它的状态:
这个状态一定程度上说明了该GraphicBuffer的归属,但仅仅指示了CPU里的状态,而GraphicBuffer的真正使用者是GPU。也就是说,当生产者把一个GraphicBuffer放入BufferQueue时,仅仅是在CPU层面完毕了归属的转移。
但GPU说不定还在用,假设还在用的话消费者是不能拿去合成的。这时候GraphicBuffer和生产消费者的关系就比較暧昧了。消费者对GraphicBuffer具有拥有权。但无使用权,它须要等一个信号,告诉它GPU用完了,消费者才真正拥有使用权。一个简化的模型例如以下:
这个通知GraphicBuffer被上一个使用者用完的信号就是由Fence完毕的。Fence的存在很单纯,从诞生開始就是为了在合适的时间发出一个信号。
还有一个角度来说,为什么不在生产者把GraphicBuffer交给消费者时就调用glFinish()等GPU完毕呢?这样拥有权和使用权就一并传递了。无需Fence。就功能上这样做是能够的,但性能会有影响,由于glFinish()是堵塞的。这时CPU为了等GPU自己也不能工作了。假设用Fence的话就能够等这个GraphicBuffer真正要被消费者用到时再堵塞,而那之前CPU和GPU是能够并行工作的。这样相当于实现了临界资源的lazy passing。
说完Fence的基本作用,再说下它的实现。
Fence。顾名思义就是把先到的拦住,等后来的。两者步调一致了再往前走。抽象地说。Fence包括了同一或不同一时候间轴上的多个时间点。仅仅有当这些点同一时候到达时Fence才会被触发。更具体的介绍能够參考这篇文章(http://netaz.blogspot.com/2013/10/android-fences-introduction-in-any.html)。
Fence能够由硬件实现(Graphic driver),也能够由软件实现(Android kernel中的sw_sync)。
EGL中提供了同步对象的扩展KHR_fence_sy