Perfetto D3

三、SurfaceFlinger讲解
SurfaceFlinger 的主要功能是接收缓冲区,创建缓冲区,并将缓冲区发送到显示器。WindowManager 为 SurfaceFlinger 提供了缓冲区和窗口元数据,SurfaceFlinger 使用这些缓冲区和窗口元数据来组合具有显示的表面。

详细定义可以看官网: SurfaceFlinger 的定义


在Perfetto中,我们关注的重点就是上面这幅图对应的部分

App 部分
BufferQueue 部分
SurfaceFlinger 部分
HWComposer 部分
这四部分,在 Perfetto 中都有可以对应的地方,以时间发生的顺序排序就是 1、2、3、4,下面我们从 Perfetto 的这四部分来看整个渲染的流程

1、App 部分
关于 App 部分,在上面的主线程渲染线程部分已经讲解过了,其主要的流程如下图:


从 SurfaceFlinger 的角度来看,App 部分主要负责生产 SurfaceFlinger 合成所需要的 Surface。

App 与 SurfaceFlinger 的交互主要集中在三点

  1. Vsync 信号的接收和处理
  2. RenderThread 的 dequeueBuffer
  3. RenderThread 的 queueBuffer
1.1 Vsync 信号的接收和处理

App 和 SurfaceFlinger 的第一个交互点就是 Vsync 信号的请求和接收,Vsync-App 信号到达,应用收到这个信号后,开始一帧的渲染准备

2、Triple Buffer
2.1 BufferQueue 部分
如下图,每个有显示界面的进程对应一个 BufferQueue,使用方创建并拥有 BufferQueue 数据结构,并且可存在于与其生产方不同的进程中,BufferQueue 工作流程如下:

上图主要是 dequeue、queue、acquire、release ,在这个例子里面,App 是生产者,负责填充显示缓冲区(Buffer);SurfaceFlinger 是消费者,将各个进程的显示缓冲区做合成操作

dequeue(生产者发起) : 当生产者需要缓冲区时,它会通过调用 dequeueBuffer() 从 BufferQueue 请求一个可用的缓冲区,并指定缓冲区的宽度、高度、像素格式和使用标记。
queue(生产者发起):生产者填充缓冲区并通过调用 queueBuffer() 将缓冲区返回到队列。
acquire(消费者发起) :消费者通过 acquireBuffer() 获取该缓冲区并使用该缓冲区的内容
release(消费者发起) :当消费者操作完成后,它会通过调用 releaseBuffer() 将该缓冲区返回到队列

2.2 Single Buffer
单 Buffer 的情况下,因为只有一个 Buffer 可用,那么这个 Buffer 既要用来做合成显示,又要被应用拿去做渲染

理想情况下,单 Buffer 是可以完成任务的(有 Vsync-Offset 存在的情况下)

App 收到 Vsync 信号,获取 Buffer 开始渲染
间隔 Vsync-Offset 时间后,SurfaceFlinger 收到 Vsync 信号,开始合成
屏幕刷新,我们看到合成后的画面

但是很不幸,理想情况我们也就想一想,这期间如果 App 渲染或者 SurfaceFlinger 合成在屏幕显示刷新之前还没有完成,那么屏幕刷新的时候,拿到的 Buffer 就是不完整的,在用户看来,就有种撕裂的感觉

当然 Single Buffer 已经没有在使用,上面只是一个例子

2.3 Double Buffer
Double Buffer 相当于 BufferQueue 中有两个 Buffer 可供轮转,消费者在消费 Buffer的同时,生产者也可以拿到备用的 Buffer 进行生产操作

下面我们来看理想情况下,Double Buffer 的工作流程

但是 Double Buffer 也会存在性能上的问题,比如下面的情况,App 连续两帧生产都超过 Vsync 周期(准确的说是错过 SurfaceFlinger 的合成时机) ,就会出现掉帧情况

2.4 Triple Buffer
Triple Buffer 中,我们又加入了一个 BackBuffer ,这样的话 BufferQueue 里面就有三个 Buffer 可以轮转了,当 FrontBuffer 在被使用的时候,App 有两个空闲的 Buffer 可以拿去生产,就算生产过程中有 GPU 超时,CPU 任然可以拿到新的 Buffer 进行生产(即 SurfaceFling 消费 FrontBuffer,GPU 使用一个 BackBuffer,CPU使用一个 BackBuffer)

下面就是引入 Triple Buffer 之后,解决了 Double Buffer 中遇到的由于 Buffer 不足引起的掉帧问题

这里把两个图放到一起来看,方便大家做对比(一个是 Double Buffer 掉帧两次,一个是使用 Triple Buffer 只掉了一帧)

3、Triple Buffer 的作用
3.1 缓解掉帧
从上一节 Double Buffer 和 Triple Buffer 的对比图可以看到,在这种情况下(出现连续主线程超时),三个 Buffer 的轮转有助于缓解掉帧出现的次数(从掉帧两次 -> 只掉帧一次)

所以从第一节如何定义掉帧这里我们就知道,App 主线程超时不一定会导致掉帧,由于 Triple Buffer 的存在,部分 App 端的掉帧(主要是由于 GPU 导致),到 SurfaceFlinger 这里未必是掉帧,这是看 Perfetto 的时候需要注意的一个点、

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/weixin_47465999/article/details/131613815

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值