Android GPU渲染SurfaceFlinger合成RenderThread的dequeueBuffer/queueBuffer与fence机制(2)
Android GPU渲染SurfaceFlinger合成RenderThread的dequeueBuffer/queueBuffer与fence机制(2)
计算fps帧率
用
adb shell dumpsys SurfaceFlinger --list
查询当前的SurfaceView,然后有好多行,再把要查询的行内容完整的传给
adb shell dumpsys SurfaceFlinger --latency 窗口名
输出一堆数字,第一行数字是当前的 VSYNC 间隔,单位纳秒。如果屏幕是 60Hz ,就是 16.6ms,然后下面一堆数字,总共有 127 行,每一行有 3 个数字,每个数字都是时间戳,单位是纳秒。
Android 显示一帧大致分为几个步骤
1,App 接收到 vsync-app 信号后开始工作。
2,App 主线程被Message唤醒,执行onVsync。
3,App 执行 doFrame ,处理input、animation、traversal、draw等。
4,App UIThread 跟RenderThread sync 数据。
5,App 执行DrawFrame,从SurfaceFlinger(后续简称SF) 的 BufferQueue 中 dequeueBuffer,取出一个bufffer后,执行渲染绘制,接着将绘制好的Buffer 通过queueBuffer 放回到BufferQueue中给 SF消费。
6,App queueBuffer 后, SF 中对应的 app buffer 会增加 +1。
7,Vsync-sf 到来后,SF 从BufferQueue 中 acquireBuffer一个Buffer 进行消费, 对应SF 中的 app buffer 会减 - 1 , SF 消费处理后,通过 releaseBuffer 将buffer 归还到BufferQueue 中。
8,SF 通过 bind 跟 Hardware Composer HAL(HWC) 进行通信,通过一些处理后显示到手机屏幕上。

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

App 绘制的图像内容是怎么最终显示到手机屏幕?
App 要显示的内容要绘制在 Buffer 里,这个 Buffer 是从 BufferQueue 通过 dequeueBuffer() 申请。申请到 Buffer 后,App 将内容填充到 Buffer ,通过 queueBuffer() 将 Buffer 还回去交给 SurfaceFlinger 去进行合成和显示。然后,SurfaceFlinger 开始合成时候,调用 acquireBuffer() 从 BufferQueue 里面拿一个 Buffer 合成,合成完以后通过 releaseBuffer() 将 Buffer 还给 BufferQueue。

RenderThread 的 dequeueBuffer
dequeue 出队,dequeueBuffer 就是从队列中拿出一个 Buffer,这个队列就是 SurfaceFlinger 中的 BufferQueue。app开始渲染前,首先需要通过 Binder 调用从 SurfaceFlinger 的 BufferQueue 中获取一个 Buffer。

RenderThread 的 queueBuffer
queue 入队,queueBuffer 是把 Buffer 放回到 BufferQueue,App 处理完 Buffer 后,会把这个 Buffer 通过 eglSwapBuffersWithDamageKHR -> queueBuffer ,将 Buffer 放回 BufferQueue。

上面流程有一个问题,在 App 绘制完通过 queueBuffer() 将 Buffer 还回时候,此时仅仅只是 CPU 侧完成,GPU 实际上有没有真正完成,CPU并不知道。因此如果此时GPU拿这个 Buffer 去合成/显示,就会有问题(Buffer 可能还没有完全绘制完)。由于 CPU 和 GPU 是异步的,因此CPU在代码里执行一系列绘图函数调用后,看上去函数已经返回,实际上,具体什么时候被GPU真正执行完毕 CPU 不知道,除非阻塞等待这些命令完全执行完,但这样会带来严重的性能问题,因为这样使得 CPU 和 GPU 的并行完全丧失,CPU 会在 GPU 完成之前一直处于空等状态。因此,需要一种机制,在不需要对 Buffer 进行读写时候,大家各干各的;当需要对 Buffer 进行读写时候,CPU可以知道此时 Buffer 在 GPU 的状态,必要时候等一下。
fence 是这样的同步机制——“栅栏”,把东西拦住。fence 要拦住什么东西呢?就是 Buffer。Buffer 在整个绘制、合成、显示过程中,一直在 CPU,GPU 和 HWC 之间传递,某一方要使用 Buffer 前,需要检查之前的使用者是否已经移交 Buffer 的“使用权”。而这里的“使用权”,就是 fence。当 fence 释放(即 signal)时候,说明 Buffer 的上一个使用者已经交出了使用权,对于 Buffer 进行操作是安全的。
Android 总共有三类 fence —— acquire fence,release fence 和 present fence。
•acquire fence
App 将 Buffer 通过 queueBuffer() 还给 BufferQueue 的时候,此时该 Buffer 的 GPU 侧其实未必完成,此时会带上一个 fence,这个 fence 就是 acquire fence。当 SurfaceFlinger/ HWC 要读取 Buffer 以进行合成操作的时候,需要等 acquire fence 释放之后才行。
•release fence
当 App 通过 dequeueBuffer() 从 BufferQueue 申请 Buffer,要对 Buffer 进行绘制时候,需要保证 HWC 已经不再需要这个 Buffer 了,即需要等 release fence signal 才能对 Buffer 进行写操作。
•present fence
当前帧成功显示到屏幕的时候,present fence 就会 signal。

每一个buffer都一个Fence状态,代表这块buffer是否还在被上一个使用者使用完,并且在转移时都会携带当前Fence的fd,然后可以调用Fence的wait或者waitForever查询Fence状态,如果还在使用则等待,否则就可以使用。Fence按作用大体分两种:acquireFence和releaseFence。前者用于生产者通知消费者生产已完成,后者用于消费者通知生产者消费已完成。
Fence保证GraphicBuffer在App, GPU和HWC三者间流转时数据读写同步(不同进程 or 不同硬件间同步)。
从 SurfaceFlinger 的角度来看,App 部分主要负责生产 SurfaceFlinger 合成所需要的 Surface。
App 与 SurfaceFlinger 的交互主要集中在三点
1 Vsync 信号的接收和处理
2 RenderThread 的 dequeueBuffer
3 RenderThread 的 queueBuffer

从 dumpsys SurfaceFlinger --latency 获取最新 127 帧的 present fence 的 signal time,当某帧 present fence 被 signal 时候,说明这一帧已经被显示到屏幕上。因此,可以通过判断1秒内有多少个 present fence signal ,反推出一秒内有多少帧被刷新(显示)到屏幕上,从而计算出 fps。
统计一秒内 App 往屏幕刷了多少帧,在 Android 里,每一帧显示到屏幕的标志是:present fence signal ,因此计算 App 的 fps 就可以转换为:一秒内 App 的 Layer 有多少个有效 present fence signal 。
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
Android GPU渲染屏幕绘制显示基础概念(1)-CSDN博客文章浏览阅读696次,点赞20次,收藏12次。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性能:Double Buffer双缓冲/Triple Buffer三缓冲丢帧Jank与无丢帧No Jank-CSDN博客文章浏览阅读858次,点赞6次,收藏13次。Android ADB调试真机设备Android ADB(Andorid Debug Bridge),是Android开发中有用的测试和调试工具。使用Android ADB调试设备,直接在Windows的dos命令窗口输入命名adb即可,如图:为什么执行adb命令后是这样?_android 抓trace。三Buffer轮转情况下,基本不会有这种情况的发生,渲染线程一般在 dequeueBuffer 时,都可以顺利拿到可用的 Buffer (如果 dequeueBuffer 本身耗时那就也会拉长时间)。
https://blog.csdn.net/zhangphil/article/details/138213964
相关文章:
Android GPU渲染SurfaceFlinger合成RenderThread的dequeueBuffer/queueBuffer与fence机制(2)
Android GPU渲染SurfaceFlinger合成RenderThread的dequeueBuffer/queueBuffer与fence机制(2) 计算fps帧率 用 adb shell dumpsys SurfaceFlinger --list 查询当前的SurfaceView,然后有好多行,再把要查询的行内容完整的传给 ad…...
人民币数字和中文汉字转换
在PHP中,将人民币的中文汉字金额转换为数字,或者将数字转换为人民币的中文汉字金额,通常需要自定义一些函数来实现这一转换过程。下面分别给出这两个转换的示例代码。 数字转人民币中文汉字 function numberToChinese($num) { $cnNums arr…...
07_Flutter使用NestedScrollView+TabBarView滚动位置共享问题修复
07_Flutter使用NestedScrollViewTabBarView滚动位置共享问题修复 一.案发现场 可以看到,上图中三个列表的滑动位置共享了,滑动其中一个列表,会影响到另外两个,这显然不符合要求,先来看下布局,再说明产生这个…...
Java解决垂直鉴权问题(对垂直权限进行校验)
Java解决垂直鉴权问题(对垂直权限进行校验) 文章目录 Java解决垂直鉴权问题(对垂直权限进行校验)前言一、垂直鉴权是什么?二、实现过程1.新建接口权限菜单映射表2.项目初始化时加载接口菜单映射关系3.自定义过滤器拦截…...
【MySQL工具】pt-heartbeat
功能 pt-heartbeat - 监控 MySQL 复制延迟。 用法 pt-heartbeat [OPTIONS] [DSN] --update|--monitor|--check|--stop pt-heartbeat 用于测量 MySQL 或 PostgreSQL 服务器上的复制延迟。您可以使用它来更新主服务器或监控从服务器。如果可能,MySQL 连接选项将从您…...
实现vant的年月日时分秒组件
方法:van-datetime-picker(type:datetime)和 van-picker结合实现。 <template><div class"datetimesec-picker"><van-datetime-pickerref"timePickerRef"type"datetime" //年月日时…...
typescript 命名空间、装饰器
1、命名空间 命名空间:在代码量较大的情况下,为了避免各种变量命名的冲突,可将相似功能的函数、类、接口等放置到命名空间内。同Java的包.Net的命名空间一样,typescript 的命名空间可以将代码包裹起来,只对外暴露需要在…...
GPT问答SAP BW
以下回答由GPT-3.5回答,仅供参考. 这个AI工具超好用,每天都有免费额度,写文章、总结长视频、画图等,都几秒搞定!快去下载Sider Chrome或Edge插件,薅羊毛! https://sider.ai/invited?c43b289bf2616575daecf…...
使用zdppy_amauth开发激活用户接口
服务端代码: 1、创建数据库连接对象2、初始化数据库3、声明一个上下文4、挂载用户相关的路由,这里主要由 用户登录接口用户注册注册获取用户列表接口激活指定用户接口 5、启动服务 import mcrud import api import amauth import env import contextli…...
c++ memset 指针示例
目录 C 传一个float指针,在函数内部修改指针的值 c memset 指针示例 C 传一个float指针,在函数内部修改指针的值 #include <iostream>// 定义一个函数,它接受一个指向float的指针 void modifyValue(float* ptr) {// 通过解引用指针来…...
24考研双非上岸武汉理工大学电子信息专硕,855考研经验
目录 一、考研择校经验 二、武理考研初试经验 三、武理考研复试经验 一、考研择校经验 我建议学弟学妹们确定院校时没必要一上来就说我一定要考某个院校。其实考哪个学校是要在考研备考的过程中慢慢探索,慢慢研究的,不过最晚9月初一定要确定院校了&a…...
使用KubeKey 快速交付k8s v1.28.8集群
文章目录 服务器配置使用kubekey部署k8s1. 操作系统基础配置2. 安装部署 K8s2.1 下载 KubeKey2.2 创建 K8s 集群部署配置文件 3. 验证 K8s 集群3.1 验证集群状态 4. 部署测试资源5.验证服务 服务器配置 主机名IPCPU内存系统盘数据盘用途vm-16-11-ubuntu192.168.9.131128256Gi5…...
nginx--压缩https证书favicon.iconginx隐藏版本号 去掉nginxopenSSL
压缩功能 简介 Nginx⽀持对指定类型的⽂件进行压缩然后再传输给客户端,而且压缩还可以设置压缩比例,压缩后的文件大小将比源文件显著变小,这样有助于降低出口带宽的利用率,降低企业的IT支出,不过会占用相应的CPU资源…...
通俗的理解网关的概念的用途(四):什么是网关设备?(网络层面)
任何一台Windows XP操作系统之后的个人电脑、Linux操作系统电脑都可以简单的设置,就可以成为一台具备“网关”性质的设备,因为它们都直接内置了其中的实现程序。MacOS有没有就不知道,因为没用过。 简单的理解,就是运行了具备第二…...
Spring JdbcTemplate实现自定义动态sql拼接功能
需求描述: sql 需要能满足支持动态拼接,包含 查询字段、查询表、关联表、查询条件、关联表的查询条件、排序、分组、去重等 实现步骤: 1,创建表及导入测试数据 CREATE TABLE YES_DEV.T11 (ID BINARY_BIGINT NOT NULL,NAME VARCH…...
第十一篇:操作系统新纪元:智能融合、量子跃迁与虚拟现实的交响曲
操作系统新纪元:智能融合、量子跃迁与虚拟现实的交响曲 1 引言 在数字化的浪潮中,操作系统如同一位智慧的舵手,引领着信息技术的航船穿越波涛汹涌的海洋。随着人工智能、物联网、量子计算等前沿技术的蓬勃发展,操作系统正站在一个…...
【大数据】学习笔记
文章目录 [toc]NAT配置IP配置SecureCRT配置PropertiesTerminal Java安装环境变量配置 Hadoop安装修改配置文件hadoop-env.shyarn-env.shslavescore-site.xmlhdfs-site.xmlmapred-site.xmlyarn-site.xml 环境变量配置 IP与主机名映射关系配置hostname配置映射关系配置 关闭防火墙…...
PHP 框架安全:ThinkPHP 序列 漏洞测试.
什么是 ThinkPHP 框架. ThinkPHP 是一个流行的国内 PHP 框架,它提供了一套完整的安全措施来帮助开发者构建安全可靠的 web 应用程序。ThinkPHP 本身不断更新和改进,以应对新的安全威胁和漏洞。 目录: 什么是 ThinkPHP 框架. ThinkPHP 框架…...
厂家自定义 Android Ant编译流程源码分析
0、Ant安装 Windows下安装Ant: ant 官网可下载 http://ant.apache.org ant 环境配置: 解压ant的包到本地目录。 在环境变量中设置ANT_HOME,值为你的安装目录。 把ANT_HOME/bin加到你系统环境的path。 Ubuntu下安装Ant: sudo apt…...
基于springboot+vue+Mysql的体质测试数据分析及可视化设计
开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
[USACO23FEB] Bakery S
题目描述 Bessie 开了一家面包店! 在她的面包店里,Bessie 有一个烤箱,可以在 t C t_C tC 的时间内生产一块饼干或在 t M t_M tM 单位时间内生产一块松糕。 ( 1 ≤ t C , t M ≤ 10 9 ) (1 \le t_C,t_M \le 10^9) (1≤tC,tM≤109)。由于空间…...
