Android SurfaceFlinger中Fence机制--个人理解整理

1 Fence 是什么?

Fence中文是栅栏/围墙的意思,理解成分界/界限的东西。android中的一个资源锁机制。(i.e. a kind of memory barrier)

下面链接是english 介绍

Bringing Android explicit fencing to the mainline

2 Fence是干什么的?

android 从4.4开始提供提供了fence机制,协调下面各模块的运作。各模块都是操作的buffer信息,所有对于buffer加一个资源锁,就可以实现buffer在各模块的流转,且起到保护的作用。

在Display大模块中有三个:CPU/GPU/HWC,这三个硬件模块在display系统中需要联合起来工作,但又是独立,有差异的运行速度。

比如CPU擅长逻辑控制与串行运算,而GPU擅长大规模并行运算,图像中大量有数字运算,所有渲染工作可以大部分交由GPU实现,(比如硬件加速打开后就基本上都是GPU实现的渲染逻辑)。HWC也是硬件设备,可以减缓部分layer的合成逻辑。

The idea behind fencing is to ensure ordering between operations—in particular to synchronize buffer sharing between the GPU and display drivers. It will make sure that the GPU does not write to a buffer that is still being displayed and that buffers won't be displayed while the GPU is still rendering to them. It allows the display driver and the GPU to operate asynchronously.

3 Fence是怎么做的?

一个UI的显示需要讲过三个步骤:1 渲染 2 合成 3 显示

结合这三个步骤,看Fence是如何呢?

总体来说,一个buffer在三个步骤的流转过程中加上fence,下一步骤使用的时候检测这个fence是可用;如果可用,则当前步骤可以操作这个buffer;如果不可用,则wait等待直到fence变成可用状态。

4 Fence实现的层级关系:

driver 层: fence其实是硬件的保护机制,所有真正的实现是在底层逻辑中,可能是在DRM/KMS中

libsync:是对driver的封装,对fd的ioctl操作

Fence: 对libsync的c++ 封装,mFenceFd的封装,再调用libsync实现api

FenceTime:对Fence的封装,提供简单的API:isValid getSignalTime

5 dirver中Fence实现机制?

参考这个博客,driver 提供了timeline/sync_pt/sync_fence.

timeline是只增不加的,每个driver context都有自己的timeline,维护了一个sync_pt 链表;

sync_pt 是timeline到点后通知的对象

sync fence可以有一个或多个sync_pt,所有的sync pt都触发后,该sync fence也就被触发。

可以理解成定时器的功能吧,时间轴一直往前走,到时间点触发一个pt,类似脉冲的逻辑。

user space层通过fd的方式与driver通信,使用fd还可以实现跨进程的逻辑。

wait等待fence执行完成,getSignalTime获取fence的触发时间。

可以merge,就是再sync_fence上实现监听多个timeline的sync_pt,所有的point触发后才有效。

这边理解与下图不同,下面sync_fence 链接是同一timeline的不同sync_pt,这样就fence的通知时间就会以最后一个sync_pt有效?

Android fb driver中的fence机制_ear5cm的博客-CSDN博客 

6 SurfaceFlinger中Fence情况:

1) SurfaceFlinger中Fence使用总共有三个体现,基本都是FenceTime,

acquireFence: 保护渲染执行完成,由apk传给sf,供合成使用

releaseFence: 保护显示执行完成,由sf传给apk,等待显示完成才可以拿去做渲染

presentFence: 显示完成,主要是记录显示时间的作用

[注]acquireFence和releaseFence是对每个layer有效,不同layer其fence不同

presentFence是每个vsync周期体现,从hwc获取

2)也有对Fence的使用,主要是wait和getfd等操作

7 acquireFence

acquireFence是通过queueBuffer从apk端传给了surfaceflinger。

如果是通过CPU渲染,就是canvas执行的,则这个fence是Fence::NO_FENCE;

如果是GPU渲染,应该是eglswapbuffers将GPU测创建的fence通过queueBuffer传递给SurfaceFlinger。

说明下:NO_FENCE的fd是-1, isValid 方法就是判断的fd != -1.

acquireFence的作用:

1) queueBuffer后将这个acqurieFence传递到对应layer中,

这个acquireFence会保存在了FrameEventHistory中,看到里面还有一个mAcquireTimeLine,这个FenceTimeLine类存储的是weak_ptr<FenceTime>,使用时需要转成shared_ptr<FenceTime>

 2) FenceTime 还会保存在BufferItem中

BufferItem在queueBuffer后,会存在于BufferQueueCore和BufferLayer中,当下一个vsync周期,BufferLayer的latchBuffer将其放到BufferLayerConsumer的mCurrentFence/mCurrentFenceTime变量中。

 3) 下一个周期的page flip中,用于判断是否有fence已经signal了

如果没有signal,则本vsync周期内不处理该layer的逻辑

 4)Client模式的layer合成逻辑中也会check fence是否signal

doComposition -> doDisplayComposition> doComposeSurfaces >

layer->draw(renderArea, clip);

 

 

 5) 如果是Device模式的layer,将acquireFence传给HWC,里面可能会执行fence的wait逻辑

setUpHWComposer >

layer->setPerFrameData(displayDevice);

7 releaseFence

1)首先确认releaseFence是从SurfaceFlinger端传给apk使用的,通过dequeueBuffer这个api实现的。

2) 这个OutputFence是从BufferQueueCore的mSlot数组中取出来的,所以与这块buffer是对应的,

如果这个buffer没有使用过,则fence未NO_FENCE;

如果这块buffer不是第一次使用,则该值应该就是有效的,所以我看使用的情况

        *outFence = (mCore->mSharedBufferMode &&
                mCore->mSharedBufferSlot == found) ?
                Fence::NO_FENCE : mSlots[found].mFence;

3) ConsumerBase::addReleaseFenceLocked 函数就是将fence 存到bufferqueuecore中的mSlots中

mSlots[slot].mFence = mergedFence;

mSlots[slot].mFence = fence;

这边就出现了merge的情况,这样看releaseFence可能有多个fd的情况,merge在上文中有提供底层是支持的,所以不再多介绍。

4) 接着看,BufferLayerConsumer中有两处设置fence的地方

void BufferLayerConsumer::setReleaseFence(const sp<Fence>& fence) {

status_t BufferLayerConsumer::syncForReleaseLocked() {

5) 这两个API是从两路掉到的

handlePageFlip > latchBuffer > updateTexImage >updateAndReleaseLocked > syncForReleaseLocked

handleMessageRefresh > doComposition > postFramebuffer> onLayerDisplayed > setReleaseFence

这两路来看,一个是vsync周期开始时获取buffer的时候,一个时合成显示后的逻辑。

6) 两路fence的差异, 一个与RenderEngine有关,一个是从hwc获取的

 

 8 presentFence

看下面的截图,presentFence主要是用在Layer和vsync里面

handleMessageRefresh>postComposition

layer中的实现主要就是记录的作用,将presentFence存在stats和tracker中

 

 vsync的作用则是使用presentFence 时间去计算下一次的vsync生效时间,好保证60fps;举例来说这次耗时较长,再后面就要更少的时间去触发vsync,比如16.7/ 16.5等。

  • 7
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值