程序员主页 > 程序员 >
Android中的GraphicBuffer同步机制-Fence
新闻来源:AG集&# 添加时间:2019-02-06

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标记着它的状态:

vcv8yrGjrLvht6Kz9tDFusXWuMq+ttPB0Meww+a1xMP8we7S0cirsr/WtNDQzeqxz6Gjuq/K/WVnbENsaWVudFdhaXRTeW5jS0hSKCm/ycjDtffTw9Xf1+jI+7XItP3QxbrFt6LJ+qGjPGJyPgo8YnI+CtTatMu7+bSh1q7Jz6OsQW5kcm9pZLbUxuS9+NDQwcvAqdW5LUFORFJPSURfbmF0aXZlX2ZlbmNlX3N5bmMgIChodHRwOi8vd3d3Lmtocm9ub3Mub3JnL3JlZ2lzdHJ5L2VnbC9leHRlbnNpb25zL0FORFJPSUQvRUdMX0FORFJPSURfbmF0aXZlX2ZlbmNlX3N5bmMudHh0KaOs0MK808HLvdO/2mVnbER1cE5hdGl2ZUZlbmNlRkRBTkRST0lEKCmho8v8v8nS1LDR0ru49s2ssr221M/z16q7r86q0ru49s7EvP7D6Mr2t/ujqLe0uf3AtKOsZWdsQ3JlYXRlU3luY0tIUigpv8nS1LDRzsS8/sPoyva3+9eqs8nNrLK9ttTP8ymho9XiuPbAqdW5z+C1sdPayMNDUFXW0NPQwctHUFXW0M2ssr221M/ztcS+5LH6o6zOxLz+w+jK9rf7v8nS1NTavfizzLzktKu13SjNqLn9YmluZGVyu/Jkb21haW4KIHNvY2tldLXISVBDu/rWximjrNXivs3OqrbgvfizzLzktcTNrLK9zOG5qcHLu/m0oaGjztLDx9aqtcBVbml4z7XNs9K7x9C91M7EvP6jrNLytMujrNPQuPbV4rj2wKnVudLUuvNGZW5jZbXEzajTw9DUtPO089T2x7/By6GjPGJyPgo8YnI+CkFuZHJvaWS7ub340ruyvbfhuLvBy0ZlbmNltcRzb2Z0d2FyZSBzdGFja6Gj1vfSqrfWsrzU2sj9sr+31qO6QyYjNDM7JiM0MzsgRmVuY2XA4M6709ovZnJhbWV3b3Jrcy9uYXRpdmUvbGlicy91aS9GZW5jZS5jcHA7IEO1xGxpYnN5bmO/4s6709ovc3lzdGVtL2NvcmUvbGlic3luYy9zeW5jLmM7IEtlcm5lbCBkcml2ZXKyv7fWzrvT2i9kcml2ZXJzL2Jhc2Uvc3luYy5joaPX3LXDwLTLtaOsa2VybmVsIGRyaXZlcrK/t9bKx82ssr21xNb30qrKtc/Wo6xsaWJzeW5jyse21GRyaXZlcr3Tv9q1xLfi17CjrEZlbmNlyse21GxpYnN5bmO1xL340ruyvbXEQyYjNDM7JiM0Mzu34tewoaNGZW5jZbvhsbvX986qR3JhcGhpY0J1ZmZlcrXEuL3K9Mvm18VHcmFwaGljQnVmZmVy1NrJ+rL61d+6zc/7t9G85LSryuSho8HtzeJGZW5jZbXEyO28/sq1z9bOu9PaL2RyaXZlcnMvYmFzZS9zd19zeW5jLmOho1N5bmNGZWF0dXJlc9PD0tSy6dGvz7XNs9ans9a1xM2ssr27+tbGo7ovZnJhbWV3b3Jrcy9uYXRpdmUvbGlicy9ndWkvU3luY0ZlYXR1cmVzLmNwcKGjPC9wPgo8cD48YnI+Cs/Cw+a31s72z8JGZW5jZdTaQW5kcm9pZNbQtcS+38zl08O3qKGjy/zW99KqtcTX99PDysdHcmFwaGljQnVmZmVy1NpBcHAsIEdQVbrNSFdDyP3V37zktKu13cqx1/fNrLK9oaM8YnI+Cjxicj4KytfPyM7CucrSu8/CR3JhcGhpY0J1ZmZlcrTTQXBwtb1EaXNwbGF5tcTCw7PMoaNHcmFwaGljQnVmZmVyz8jTyUFwcLbL1/fOqsn6svrV37340NC75tbGo6zIu7rzt8XI67W9QnVmZmVyUXVldWWjrLXItP3P+7fR1d/IobP21/fPwtK7sr21xOTWyL66z7PJoaNTdXJmYWNlRmxpbmdlctf3zqrP+7fR1d+jrLvhsNHDv7j2suO21NOmtcRHcmFwaGljQnVmZmVyyKHAtMn6s8lFR0xJbWFnZUtIUrbUz/Oho7rPs8nKsbbU09pHcmFwaGljQnVmZmVytcS0psDtt9bBvdbWx+m/9qGjttTT2k92ZXJsYXm1xLLjo6xTdXJmYWNlRmxpbmdlcrvh1rG9072rxuRidWZmZXIgaGFuZGxlt8XI60hXQ7XETGF5ZXIgbGlzdKGjttTT2tDo0qpHUFW75tbGtcSy46Oos6yz9khXQ7SmwO2y48r9u/LV39PQuLTU07Hku7u1xKOpo6xTdXJmYWNlRmxpbmdlcrvhvavHsMPmyfqzybXERUdMSW1hZ2VLSFLNqLn9Z2xFR0xJbWFnZVRhcmdldFRleHR1cmUyRE9FUygp1/fOqs7GwO29+NDQus+zyaOoaHR0cDovL3Nub3JwLm5ldC8yMDExLzEyLzE2L2FuZHJvaWQtZGlyZWN0LXRleHR1cmUuaHRtbKOpoaO6z7PJzeq681N1cmZhY2VGbGluZ2Vy09bX986qyfqy+tXfo6yw0UdQVbrPs8m6w7XEZnJhbWVidWZmZXK1xGhhbmRsZdbDtb1IV0PW0LXERnJhbWVidWZmZXJUYXJnZXTW0ChIV0PW0Gh3Y19kaXNwbGF5X2NvbnRlbnRzXzFfdNbQtcRod2NfbGF5ZXJfMV90wdCx7dfuuvPSu7j2c2xvdNPD09q3xUdQVbXE5NbIvr3hufvL+dTaYnVmZmVyKaGjSFdD1+6687X+vNNPdmVybGF5suPU2c35RGlzcGxhecnPyNOjrNXiyrFIV0PKx8/7t9HV36Gj1fu49rTz1sLB97PMyOfNvKO6PGJyPgo8L3A+CjxwPjxpbWcgc3JjPQ=="http://www.2cto.com/uploadfile/Collfiles/20141001/201410010908579.png" alt="">

前面提到合成的过程先是GPU工作,在doComposition()函数中合成非Overlay的层,结果放在framebuffer中。然后SurfaceFlinger会调用postFramebuffer()让HWC开始工作。postFramebuffer()中最主要是调用HWC的set()接口通知HWC进行合成显示,然后会将HWC中产生的releaseFence(如有)同步到SurfaceFlingerConsumer中。实现位于Layer的onLayerDisplayed()函数中:
151 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
上面主要是针对Overlay的层,那对于GPU绘制的层呢?在收到INVALIDATE消息时,SurfaceFlinger会依次调用handleMessageInvalidate()->handlePageFlip()->Layer::latchBuffer()->SurfaceFlingerConsumer::updateTexImage() ,其中会调用该层对应Consumer的GLConsumer::updateAndReleaseLocked() 函数。该函数会释放老的GraphicBuffer,释放前会通过syncForReleaseLocked()函数插入releaseFence,代表如果触发时该GraphicBuffer消费者已经使用完毕。然后调用releaseBufferLocked()还给BufferQueue,当然还带着这个releaseFence。这样,当这个GraphicBuffer被生产者再次通过dequeueBuffer()拿出时,就可以通过这个releaseFence来判断消费者是否仍然在使用。

另一方面,HWC合成完毕后,SurfaceFlinger会依次调用DisplayDevice::onSwapBuffersCompleted() -> FramebufferSurface::onFrameCommitted()。onFrameCommitted()核心代码如下:
148 sp fence = mHwc.getAndResetReleaseFence(mDisplayType);
...
151 status_t err = addReleaseFence(mCurrentBufferSlot,
152 mCurrentBuffer, fence);
此处拿到HWC生成的FramebufferTarget的releaseFence,设到FramebufferSurface中相应的GraphicBuffer Slot中。这样FramebufferSurface对应的GraphicBuffer也可以被释放回BufferQueue了。当将来EGL从中拿到这个buffer时,照例也要先等待这个releaseFence触发才能使用。

http://www.bkjia.com/Androidjc/888376.htmlwww.bkjia.comtruehttp://www.bkjia.com/Androidjc/888376.htmlTechArticleAndroid中的GraphicBuffer同步机制-Fence Fence是一种同步机制,在Android里主要用于图形系统中GraphicBuffer的同步。那它和已有同步机制相比有什么特...

本文源自: 凯发K8

程序员
联系方式