Android VSYNC双Buffer与三Buffer渲染线程RenderThread(5)

Android VSYNC双Buffer与三Buffer渲染线程RenderThread(5)

 

手机自带的卡顿丢帧分析工具,柱状图:

3a9de541702343d18babd00f84e99a79.png

7a64713140ea47d1b71f0507118f1796.png

 

 

帧的大体绘制过程:

fc3f615e7cd843a3a1fa12a5cfc34278.png

帧绘制中的重要概念:BufferQueue
首先看一下 BufferQueue,BufferQueue 是一个生产者(Producer)-消费者(Consumer)模型中的数据结构,一般来说,消费者(Consumer) 创建 BufferQueue,而生产者(Producer) 一般不和 BufferQueue 在同一个进程里面

当生产者(Producer) 需要 Buffer 时,它通过调用 dequeueBuffer()并指定 Buffer 的宽度,高度,像素格式和使用标志,从 BufferQueue 请求释放 Buffer
生产者(Producer) 将填充缓冲区,并通过调用 queueBuffer()将缓冲区返回到队列。
消费者(Consumer) 使用 acquireBuffer()获取 Buffer 并消费 Buffer 的内容
使用完成后,消费者(Consumer)将通过调用 releaseBuffer()将 Buffer 返回到队列
 

在 Android App 的渲染流程里面,App 就是个生产者(Producer) ,而 SurfaceFlinger 是一个消费者(Consumer),所以上面的流程就可以翻译为

当 App 需要 Buffer 时,它通过调用 dequeueBuffer()并指定 Buffer 的宽度,高度,像素格式和使用标志,从 BufferQueue 请求释放 Buffer
App 可以用 cpu 进行渲染也可以调用用 gpu 来进行渲染,渲染完成后,通过调用 queueBuffer()将缓冲区返回到 App 对应的 BufferQueue(如果是 gpu 渲染的话,这里还有个 gpu 处理的过程)
SurfaceFlinger 在收到 Vsync 信号之后,开始准备合成,使用 acquireBuffer()获取 App 对应的 BufferQueue 中的 Buffer 并进行合成操作
合成结束后,SurfaceFlinger 将通过调用 releaseBuffer()将 Buffer 返回到 App 对应的 BufferQueue

 

单缓存
单 Buffer 情况,因为只有一个 Buffer 可用,这个 Buffer 既要用来做合成显示,又要被应用拿去做渲染。

d3007f8ba2cc4dc69e47e3dfdc9e0246.jpeg
理想情况下,单 Buffer 也是可以完成任务不卡顿丢帧的。
1、App 收到 Vsync 信号,获取 Buffer 开始渲染;
2、间隔 Vsync-Offset 时间后,SurfaceFlinger 收到 Vsync 信号,开始合成;
3、屏幕刷新,我们看到合成后的画面。

4c9a6e3ba7904faf989780d373b99ad5.jpeg

但很不幸,理想情况也就想一想,任何一个环节,如果 App 渲染或者 SurfaceFlinger 合成,在屏幕显示刷新之前还没完成,那么屏幕刷新时候,拿到的 Buffer 就是不完整的,用户看来,就有撕裂的视觉效果。

 

双缓冲

两个缓存区: Back Buffer 、 Frame Buffer。当写入下一帧时,GPU会先填充 Back Buffer 中,当刷新屏幕时,屏幕从 Frame Buffer 中读数据。VSYNC 主要是完成帧的复制,开始下一帧的渲染。

a6fa2a3afb0f4a9e940e877763bda4a5.webp
 

 

Choreographer主要是配合 Vsync ,给上层 App 的渲染提供稳定的 Message 处理的时机,Vsync 到来时候 ,系统通过对 Vsync 信号周期的调整,控制每1帧绘制时机。Vsync 周期如果是 16.6ms (60 fps) ,是因为手机屏幕是 60Hz 的刷新率,也就是 16.6ms 刷新1次,系统为了配合屏幕刷新频率,将 Vsync 的周期也设置为 16.6 ms,每隔 16.6 ms ,Vsync 信号到来唤醒 Choreographer 来做 App 的绘制操作 ,如果每个 Vsync 周期应用都能渲染完成,那么应用的 fps 就是 60 ,用户的感觉就是非常流畅,这就是引入 Choreographer 的主要作用。

Android双Buffer与三Buffer丢帧卡顿对比

92b71164f9f54daa99480b5ec6f3aeb4.png

双buffer下,主线程连续超时,开始丢帧。三buffer减轻丢帧情况,从原先丢2帧减轻到丢1帧。

主线程有时要等待 SurfaceFlinger释放Buffer后,才能获取 Buffer 进行生产,但大部分情况下, SurfaceFlinger 和应用主线程 同时收到 Vsync 信号,如果应用主线程等待SurfaceFlinger释放 Buffer,那会让应用主线程执行时间延后。

双 Buffer 时候,App生产的 Buffer 必须要及时拿去让 GPU 渲染,然后 SurfaceFlinger 才能进行合成,一旦 GPU 超时,就容易出现 SurfaceFlinger 无法及时合成而导致掉帧;在三 Buffer 轮转时候,App 生产的 Buffer 可及早进入 BufferQueue,让 GPU 去进行渲染(因为不需等待),当 SurfaceFlinger 本身负载比较大,三个 Buffer 轮转也会有效降低 dequeueBuffer 等待时间。

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

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

RenderThread 的 dequeueBuffer

dequeue 有出队的意思,dequeueBuffer 顾名思义,就是从队列中拿出一个 Buffer,这个队列就是 SurfaceFlinger 中的 BufferQueue。如下图,应用开始渲染前,首先需要通过 Binder 调用从 SurfaceFlinger 的 BufferQueue 中获取一个 Buffer。

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

当 VSYNC 信号到达时,SurfaceFlinger 会遍历它的层列表,以寻找新的缓冲区。如果找到新的缓冲区,它会获取该缓冲区;否则,它会继续使用以前获取的缓冲区。SurfaceFlinger 必须始终显示内容,因此它会保留一个缓冲区。如果在某个层上没有提交缓冲区,则该层会被忽略。SurfaceFlinger 在收集可见层的所有缓冲区之后,便会询问 Hardware Composer 应如何进行合成。

这里丢帧了(Jank),丢1帧:

f9820bda816f45c9a5e2cdbf090c9505.png

 

从SurfaceFlinger端才能真正认定丢帧:

212fbf201835403e8095f5db93ad5d27.jpeg

 

 

 

 

Android性能分析:卡顿丢帧基础CPU/GPU原理(4)-CSDN博客文章浏览阅读821次,点赞18次,收藏19次。产生 Jank 的那一帧的显示期间,GPU/CPU 在闲置的。CPU返回后,会直接将GraphicBuffer提交给SurfaceFlinger,告诉SurfaceFlinger进行合成,但是这个时候GPU可能并未完成之前的图像渲染,这时候就牵扯到一个同步,Android中,用的是Fence机制,SurfaceFlinger合成前会查询Fence,如果GPU渲染没有结束,则等待GPU渲染结束,GPU结束后,会通知SurfaceFlinger进行合成,SF合成后,提交显示,最终完成图像的渲染显示。https://blog.csdn.net/zhangphil/article/details/138804486

 Android GPU渲染屏幕绘制显示基础概念(1)-CSDN博客文章浏览阅读1k次,点赞30次,收藏18次。CPU返回后,会直接将GraphicBuffer提交给SurfaceFlinger,告诉SurfaceFlinger进行合成,但是这个时候GPU可能并未完成之前的图像渲染,这时候就牵扯到一个同步,Android中,用的是Fence机制,SurfaceFlinger合成前会查询Fence,如果GPU渲染没有结束,则等待GPU渲染结束,GPU结束后,会通知SurfaceFlinger进行合成,SF合成后,提交显示,最终完成图像的渲染显示。而对SF来说,只要有合成任务,它就得再去申请VSYNC-sf。https://blog.csdn.net/zhangphil/article/details/138585120Android GPU渲染SurfaceFlinger合成RenderThread的dequeueBuffer/queueBuffer与fence机制(2)-CSDN博客文章浏览阅读794次,点赞12次,收藏17次。t 时长,20s,20秒的trace文件。CPU返回后,会直接将GraphicBuffer提交给SurfaceFlinger,告诉SurfaceFlinger进行合成,但是这个时候GPU可能并未完成之前的图像渲染,这时候就牵扯到一个同步,Android中,用的是Fence机制,SurfaceFlinger合成前会查询Fence,如果GPU渲染没有结束,则等待GPU渲染结束,GPU结束后,会通知SurfaceFlinger进行合成,SF合成后,提交显示,最终完成图像的渲染显示。就是 Buffer。https://blog.csdn.net/zhangphil/article/details/138628225Android性能:SurfaceFlinger与BufferQueue(3)-CSDN博客文章浏览阅读757次,点赞25次,收藏24次。t 时长,20s,20秒的trace文件。CPU返回后,会直接将GraphicBuffer提交给SurfaceFlinger,告诉SurfaceFlinger进行合成,但是这个时候GPU可能并未完成之前的图像渲染,这时候就牵扯到一个同步,Android中,用的是Fence机制,SurfaceFlinger合成前会查询Fence,如果GPU渲染没有结束,则等待GPU渲染结束,GPU结束后,会通知SurfaceFlinger进行合成,SF合成后,提交显示,最终完成图像的渲染显示。就是 Buffer。https://blog.csdn.net/zhangphil/article/details/138631517

Android性能:Double Buffer双缓冲/Triple Buffer三缓冲丢帧Jank与无丢帧No Jank-CSDN博客文章浏览阅读842次,点赞6次,收藏13次。Android ADB调试真机设备Android ADB(Andorid Debug Bridge),是Android开发中有用的测试和调试工具。使用Android ADB调试设备,直接在Windows的dos命令窗口输入命名adb即可,如图:为什么执行adb命令后是这样?_android 抓trace。三Buffer轮转情况下,基本不会有这种情况的发生,渲染线程一般在 dequeueBuffer 时,都可以顺利拿到可用的 Buffer (如果 dequeueBuffer 本身耗时那就也会拉长时间)。https://zhangphil.blog.csdn.net/article/details/138213964

Android硬件加速hardwareAccelerated支持/不支持的绘图接口-CSDN博客文章浏览阅读262次,点赞3次,收藏14次。三Buffer轮转情况下,基本不会有这种情况的发生,渲染线程一般在 dequeueBuffer 时,都可以顺利拿到可用的 Buffer (如果 dequeueBuffer 本身耗时那就也会拉长时间)。在Android早期的版本,由于硬件制造商差异大,增加了这一开关,但随着Android系统版本的迭代,以及硬件技术水平提升,现有的绝大多数Android手机硬件层面均已支持硬件加速(GPU渲染),Android本身也只有有限几个接口不支持硬件加速。https://blog.csdn.net/zhangphil/article/details/138502494

Android adb shell命令捕获systemtrace_android 抓trace-CSDN博客文章浏览阅读1.7k次,点赞2次,收藏5次。Android ADB调试真机设备Android ADB(Andorid Debug Bridge),是Android开发中有用的测试和调试工具。使用Android ADB调试设备,直接在Windows的dos命令窗口输入命名adb即可,如图:为什么执行adb命令后是这样?Android ADB(Andorid Debug Bridge)调试真机设备_adb在线执行器_zhangphil的博客-CSDN博客。-t 时长,20s,20秒的trace文件。-o 保存文件路径。_android 抓tracehttps://blog.csdn.net/zhangphil/article/details/131249820

adb shell top -m 10 -s 1 -d 1 -o %CPU,%MEM,TIME+,PID,COMMAND,CMDLINE_adb shell top -m 10 -s cpu-CSDN博客文章浏览阅读390次。使用Android ADB调试设备,直接在Windows的dos命令窗口输入命名adb即可,如图:为什么执行adb命令后是这样?Android ADB(Andorid Debug Bridge)调试真机设备_adb在线执行器_zhangphil的博客-CSDN博客。Android adb shell dump当前手机设备的所有activity_dump当前activity_zhangphil的博客-CSDN博客。Android adb获取CPU信息_zhangphil的博客-CSDN博客。_adb shell top -m 10 -s cpuhttps://blog.csdn.net/zhangphil/article/details/131412814

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/664768.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

广告联盟如何实现

在互联网时代,各种广告形式无处不在,无论是在社交媒体、网站还是APP上,广告无处不在。然而,广告对于一些人来说并不只是一种干扰,还可以是一种赚钱方式。下载广告联盟看广告能赚钱吗?这是一个很有趣的问题&#xff0c…

【Qt秘籍】[001]-从入门到成神-前言

一、Qt是什么?[概念] Qt是一个跨平台的应用程序开发框架,简单来说,它是一套工具和库,帮助软件开发者编写可以在多种操作系统上运行的图形用户界面(GUI)应用程序。比如,你用Qt写了一个软件&#…

Linux常用环境Docker安装

一、mysql安装 简单安装 docker run -d \--name mysql \-p 3306:3306 \-e TZAsia/Shanghai \-e MYSQL_ROOT_PASSWORD123 \mysql mysql容器本地挂载 cd /usr mkdir mysql cd mysql/ mkdir data mkdir conf mkdir init可以手动导入自己的数据库信息 docker run -d \--name mys…

DALL-E 2:突破性人工智能图像生成技术的全方位解析

目录 引言 一、技术背景 1.1 生成对抗网络(GAN) 1.2 变分自动编码器(VAE) 1.3 GPT-3 和自然语言处理 1.4 DALL-E 的诞生 二、DALL-E 2 的模型架构 2.1 模型概述 2.2 CLIP 的作用 2.3 DALL-E 2 的生成过程 2.4 模型训练 …

ADB安装教程

1 adb简介 Android 调试桥 (adb) 是一种功能多样的命令行工具,可让您与设备进行通信。 adb命令可用于执行各种设备操作,例如安装和调试应用。 adb 提供对 Unix shell(可用来在设备上运行各种命令)的访问权限。它是一种客户端-服务…

苏州金龙客车为新疆哪吒车队提供车辆交车

2024年旅游旺季提前到来、时间延长,新疆旅游市场有望延续去年火爆态势。 近期,新疆哪吒运输服务有限公司(以下简称“哪吒车队”)订购的最新一批10辆苏州金龙海格高端旅游大巴在苏州金龙厂区正式交付。哪吒车队负责人伍亚丽笑容满…

RabbitMQ-发布/订阅模式

1、发布/订阅模式介绍 在普通的生产者、消费者模式,rabbitmq会将消息依次传递给每一个消费者,一个worker一个,平均分配,这就是Round-robin调度方式,为了实现更加复杂的调度,我们就需要使用发布/订阅的方式…

【linux】开机调用python脚本

linux中,可以使用crontab 设置开机自动调用 crontab的安装在前面文章里写过了,不再重复 首先,还是进入crontab配置文件 crontab -e 进入之后,跟其他定时任务不同,只需要在时间配置那里用rebooot 这类之后的两个文件的…

qwen-moe

一、定义 qwen-moe 代码讲解, 代码qwen-moe与Mixtral-moe 一样, 专家模块qwen-moe 开源教程Mixture of Experts (MoE) 模型在Transformer结构中如何实现,Gate的实现一般采用什么函数? Sparse MoE的优势有哪些?MoE是如…

NFTScan 获 Google Cloud 战略支持!

近日,NFT 数据基础设施服务商 NFTScan 获得全球领先云计算服务提供商 Google Cloud 战略支持。未来,双方将在链上数据和区块链领域展开战略合作,高效联动,共同探索区块链技术的更多可能性,为用户和行业带来更多惊喜与成…

强烈推荐十款数据防泄密软件,高人气的数据防泄密软件

100G的文件不见了?客户的电话信息被拷贝走了?源代码被竞争对手搞到手了?这些都是严重的数据泄密事件,为此,我们需要数据防泄密软件来全方位保护数据安全。根据当前市场上的热门推荐和综合评价,以下几款数据…

基于Linux的文件操作(socket操作)

基于Linux的文件操作(socket操作) 1. 文件描述符基本概念文件描述符的定义:标准文件描述符:文件描述符的分配: 2. 文件描述符操作打开文件读取文件中的数据 在linux中,socket也被认为是文件的一种&#xff…

JS【详解】快速排序

快速排序的时间复杂度为 O(n2) 排序流程 1、首先设定一个分界值(比如数组最中间的元素),通过该分界值将数组分成左右两部分。 2、将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。 3、对左侧和右侧的…

项目中父模块调用子模块出现 Invalid bound statement (not found)问题

背景 做某个saas项目的时候,我把用户、角色、菜单、字典等模块弄成了一个基础包,想着如果之后又类似的项目的时候可以偷个懒 直接引用基础包就可以了。 当我引用的时候出现了这个问题 Invalid bound statement (not found):xxx 分析思路 这个问题一般…

卧式饲料搅拌机:养殖场得力助手

卧式饲料搅拌机采用卧式结构,设计科学合理,操作简便。相比传统的立式搅拌机,卧式搅拌机具有更大的搅拌容量和更均匀的搅拌效果。它能够轻松应对不同种类、不同比例的饲料混合需求,确保饲料成分的均衡分布,从而提高饲料…

【强化学习】DPO(Direct Preference Optimization)算法学习笔记

【强化学习】DPO(Direct Preference Optimization)算法学习笔记 RLHF与DPO的关系KL散度Bradley-Terry模型DPO算法流程参考文献 RLHF与DPO的关系 DPO(Direct Preference Optimization)和RLHF(Reinforcement Learning f…

KMPlayer v2024.4.25.13 官方版 (万能播放器)

前言 KMPlaye通过各种插件扩展KMP可以支持层出不穷的新格式。KMPlaye强大的插件功能,直接从Winamp继承的插件功能,能够直接使用Winamp的音频,输入,视觉效果插件,而通过独有的扩展能力,只要你喜欢&#xff…

【linux-imx6ull-设备树点灯】

目录 1. 设备树简介1.1 编译-引用1.2 设备树文件结构1.3 设备树节点介绍1.3.1 特殊节点chosen 1.4 节点内容追加 2. 设备树常用OF操作函数2.1 节点寻找类2.2 属性提取类2.3 其它常用类 4. 设备树下LED实验4.1 实验简介4.2 添加LED设备节点4.3 获取设备节点并提取属性4.3.1 获取…

国内类似ChatGPT的大模型应用有哪些?发展情况如何了

第一部分:几个容易混淆的概念 很多人,包括很多粉丝的科技博主,经常把ChatGPT和预训练大模型混为一谈,因此有必要先做一个澄清。预训练大语言模型属于预训练大模型的一类,而ChatGPT、文心一言又是预训练大语言模型的一个…

【Linux】Linux基本指令3

目录 1.date指令 2.cal指令 3.find指令:(灰常重要) -name 4.grep指令——行文本过滤工具 5.zip/unzip指令: 6.tar指令(重要):打包/解包,不打开它,直接看内容 7.bc…