淄博网站推广/seo优化怎么做
“ 最近忙着新房子装修的事情,这篇计划内的文章拖了好久一直没有足够的时间来写作,终于挤出些儿时间来继续研究学习了。”
整了四个晚上终于拼凑出一篇文章,虽说是讲FPS计算原理,但该文涉及的知识点还是蛮多的,特别是对于present fence的来龙去脉重点做了分析,还牵涉到一些合成&HWC的逻辑。全文5000多字,内容丰满。一个业余爱好者的拙劣认知,请大家审慎阅读!
01
前言
FPS即Frames Per Second,表示每秒显示的帧数。作为衡量UI流畅度、视频播放性能、游戏性能的基础指标,开发者通常会观察FPS来评价应用是否有掉帧/卡顿等性能问题。前面我们分享了两篇计算FPS的文章:
Android Graphics 显示系统 - 监测、计算FPS的工具及设计分析
Android Graphics 显示系统 - 通过dumpsys SurfaceFlinger --latency计算FPS
那这些方法计算FPS的原理是什么呢?本篇我们就着手探索下利用dumpsys SurfaceFlinger --latency计算FPS的原理
02
Fence的概念
在介绍FPS计算原理前,需要先理解Android中Fence的概念。在前面的文章中我们有对Fence做过讲解,这里我们就简略赘述。
Android Graphics 显示系统 - GraphicBuffer同步机制-Fence(二十)
Fence是什么呢?
Fence,直译为“栅栏”,用来把某个东西拦截住。顾名思义,它是一种同步机制:把东西拦截住,又在合适的时机放行,达到同步的效果。
CPU、GPU、HWC是异步工作的,所以需要Fence这种同步机制来协调他们的工作。
那么Fence要拦住什么东西呢?
就是GraphicBuffer。GraphicBuffer中存放了应用绘制好的待要显示的数据,GraphicBuffer在整个绘制、合成、显示的过程中一直在 CPU、GPU 和 HWC 之前传递,某一方要使用GraphicBuffer之前,需要先检查上一个使用者是否已经移交了GraphicBuffer的“使用权”。而这里的“使用权”,就是Fence。当Fence 释放(即signal)的时候,说明GraphicBuffer的上一个使用者已经交出了使用权,此时对于GraphicBuffer 进行操作(read or write)是安全的。
Android中有哪些Fence呢?
在Android里面,总共有3类Fence:
-
acquire fence
生产者(App)将GraphicBuffer通过queueBuffer()还给BufferQueue的时候,此时异步工作的GPU可能还没有完成绘制,此时会带上一个Fence,这个 Fence就是acquire fence。当消费者(SurfaceFlinger/HWC)要读取GraphicBuffer以进行合成操作的时候,需要等acquire fence释放之后才行。
acquire fence就是生产者用来告诉消费者生产数据完成的同步信号!
-
release fence
当生产者(App)通过dequeueBuffer()从BufferQueue申请到一块GraphicBuffer,要对GraphicBuffer进行绘制(写操作)的时候,需要保证消费者(上一个使用者)已经不再使用这个GraphicBuffer了,即需要等release fence signal才能对这块GraphicBuffer进行写操作。
acquire fence就是消费者用来告诉生产者Buffer中的数据我已消费完毕的信号!
-
present fence
当前帧成功显示到屏幕的时候,present fence就会signal。
解释比较简略,建议大家阅读Android官网的英文解读,从不同角度并结合API理解
https://source.android.com/docs/core/graphics/sync
03
计算Layer FPS的方法
计算Layer FPS的方法我们前面提供了两种方法,本篇我们主要分析利用dumpsys命令计算FPS的原理:
dumpsys SurfaceFlinger --latency Layer-name
让我们看看这条命令执行后会输出什么内容呢?
以播放Youtube视频时抓取信息为例:
首先,看看当前可见图层的状况
$ adb shell dumpsys SurfaceFlinger --hwclayers
Display 4629995505126966272 (active) HWC layers:
---------------------------------------------------------------------------------------------------------------------------------------------------------------Layer nameZ | Window Type | Comp Type | Transform | Disp Frame (LTRB) | Source Crop (LTRB) | Frame Rate (Explicit) (Seamlessness) [Focused]
---------------------------------------------------------------------------------------------------------------------------------------------------------------SurfaceView[com.google.android.youtu[...].tv.activity.MainActivity](BLAST)#99rel 0 | 0 | DEVICE | 0 | 0 0 1920 1080 | 0.0 0.0 1920.0 1080.0 | [*]
---------------------------------------------------------------------------------------------------------------------------------------------------------------com.google.android.youtube.tv/com.go[...].youtube.tv.activity.MainActivity#96rel 0 | 1 | CLIENT | 0 | 0 0 1920 1080 | 0.0 0.0 1920.0 1080.0 | [*]
---------------------------------------------------------------------------------------------------------------------------------------------------------------
可知,Youtube播放时是有一个SurfaceView来显示video画面的,我们要监测的图层也是这个SurfaceView,它的id是#99
然后要获取这个layer的完整名字
$ adb shell dumpsys SurfaceFlinger --list
Display 0 name="Built-in Screen"#363cfece ActivityRecordInputSink com.google.android.youtube.tv/com.google.android.apps.youtube.tv.activity.MainActivity#102
ActivityRecord{eef71ef u0 com.google.android.youtube.tv/com.google.android.apps.youtube.tv.activity.MainActivity#94
e145d51 com.google.android.youtube.tv/com.google.android.apps.youtube.tv.activity.MainActivity#95
Background for SurfaceView[com.google.android.youtube.tv/com.google.android.apps.youtube.tv.activity.MainActivity]#100
SurfaceView[com.google.android.youtube.tv/com.google.android.apps.youtube.tv.activity.MainActivity]#98
SurfaceView[com.google.android.youtube.tv/com.google.android.apps.youtube.tv.activity.MainActivity](BLAST)#99
最后执行dumpsys SurfaceFlinger --latency看看到底会输出什么内容:
$ adb shell dumpsys SurfaceFlinger --latency "SurfaceView[com.google.android.youtube.tv/com.google.android.apps.youtube.tv.activity.MainActivity]\(BLAST\)#99"
16683294
6870189659137 6870202006496 6870189659137
6870206342431 6870218689941 6870206342431
6870223025725 6870235371015 6870223025725
6870239709019 6870252064348 6870239709019
6870256392313 6870268737385 6870256392313
6870273075607 6870285421718 6870273075607
6870289758901 6870302111163 6870289758901
6870306442195 6870318792718 6870306442195
6870323125489 6870335474904 6870323125489
6870339808783 6870352160978 6870339808783
6870356492077 6870368841496 6870356492077
6870373175371 6870385524422 6870373175371
......
一坨一坨的数字到底是啥意思呢?
-
第一行的数字
代表当前的VSYNC间隔,单位是纳秒。例如现在的屏幕刷新率是60Hz的,因此就是16.6ms
-
后面 3列127行 的数字
每一行有 3 个数字,每个数字都是时间戳,单位是纳秒,分别表示 desiredPresentTime,actualPresentTime,frameReadyTime,在计算FPS的时候,使用的是第二个时间戳。
actualPresentTime就是present fence signal的时间,根据获取的这127个actualPresentTime数据,就可以计算一秒内有多少个present fence signal了,也即多少帧刷新到屏幕了。
计算公式
更多信息阅读原文
Android Graphics 显示系统 - 计算FPS的原理与探秘Present Fence
相关文章:

Android Graphics 显示系统 - 计算FPS的原理与探秘Present Fence
“ 最近忙着新房子装修的事情,这篇计划内的文章拖了好久一直没有足够的时间来写作,终于挤出些儿时间来继续研究学习了。” 整了四个晚上终于拼凑出一篇文章,虽说是讲FPS计算原理,但该文涉及的知识点还是蛮多的,特别是对…...

图论:1857. 有向图中最大颜色值(拓扑排序+动态规划)
文章目录 1.问题分析2.代码解析2.1 代码步骤1. 初始化数据结构2. 构建图和入度数组3. 初始化队列4. 拓扑排序和动态规划5. 检查是否存在环并返回结果 3. 问题扩展1. 最长路径问题(DAG)2. 最短路径问题(DAG)3. 最大路径和问题4. 路…...

pytorch学习笔记3 tensor索引和切片
dim 0 占先 切片 (前N或者后N个) :2 表示 0到2(不包含2), 1:表示 1到末尾, -1表示最后一个元素,-2表示倒数第二个 0:28:2 表示从0到27隔点采样 :ÿ…...

学习记录——day23 多进程编程
目录 一、多进程引入 1.1、引入目的 1.2、进程的概念 1.3、进程的种类 1.4、进程号的概念 1.5、特殊进程 0号 1号 2号 孤儿 僵尸 1.6、进程的相关命令 1)查看进程信息的命令:ps 跟不同的选项,执行不同的状态 2&am…...

英特尔股市暴跌,财报亏损 | HuggingFace 实现盈利 |iOS18 Beta 苹果AI
写在前面 了解一下最近科技圈发生的一些事情 英特尔 硬件巨头英特尔宣布裁掉1.5w个岗位,约占英特尔员工的12%,非常的夸张。本次裁员可能是由于前段时间英特尔的i7,i9的13/14代处理器的暴雷,导致英特尔Q2的财报低迷。 今年以来…...

C++入门基础(二)
6. 引用(引用就是取别名) 6.1 引用的概念和定义 引用不是新定义一个变量,而是给已存在变量取了⼀个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。比如:水浒传中李逵&…...

fabricjs 实现图像的二值化功能
一、效果图 二、图像二值化的作用 二值化是图像处理中常用的一种方法,其作用是将灰度图像转换为二值图像,即将图像中的像素点根据其灰度值分成两类:黑色和白色。这种处理方法可以帮助我们更清晰地识别图像中的目标,简化图像的复杂…...

修改本地hosts文件及外部访问机器本地hosts文件后,rancher UI网站仍然不能访问
原因排查 kubectl get svc # 输出: NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4d17hkubectl get svc -A # 输出: NAMESPACE …...

西北潮榆林范儿,新榆林首个360°沉浸式剧场发布会闪耀亮相
这是一场城市更迭的未来大赏,也是一场商业蝶变的复合对话 8月3日,朗阁集团商业品牌发布会在榆林银杏熙悦酒店隆重启幕。朗阁集团董事长杨志成携众多集团领导出席;多家主流媒体代表联袂参加;喜茶、中影时光国际影城、汉堡王、鲍师傅…...

如何创建响应式移动端网页设计?最佳实践详解
移动端网页设计是一个耗时而复杂的过程开发,包括UI设计、UX设计、检测、发布、改进、维护和持续的错误修复。通过学习这篇文章,你将掌握什么是移动端网页,如何制作移动端网页,以及设计网页的技巧。 什么是移动端网页?…...

Python 如何进行Web抓取(BeautifulSoup, Scrapy)
Web抓取(Web Scraping)是一种从网站提取数据的技术。Python有许多用于Web抓取的库,其中最常用的是BeautifulSoup和Scrapy。 BeautifulSoup BeautifulSoup是一个用于解析HTML和XML文档的Python库,适合处理简单的Web抓取任务。它将…...

白骑士的PyCharm教学进阶篇 2.5 数据库连接与管理
系列目录 上一篇:白骑士的PyCharm教学进阶篇 2.4 Django开发支持 在Web开发中,数据库是必不可少的部分。PyCharm不仅是一款功能强大的IDE,还提供了丰富的数据库连接和管理工具,使开发者可以更方便地浏览和操作数据库。本篇将详细…...

(五)activiti-modeler 编辑器初步优化
最终效果: 1..首先去掉顶部的logo,没什么用,还占用空间。 修改modeler.html文件,添加样式: <style type"text/css"> #main-header{display: none; } #main{padding: 0px; } </style> 2.左边组…...

(学习总结12)C++类和对象3
C类和对象3 一、初始化列表二、类型转换三、static成员四、友元五、内部类六、匿名对象 以下代码环境在 VS2022。 一、初始化列表 之前我们实现构造函数时,初始化成员变量主要使用函数体内赋值,构造函数初始化还有⼀种方式,就是初始化列表&a…...

docxtpl,一个强大的 Python 库!
更多资料获取 📚 个人网站:ipengtao.com 大家好,今天为大家分享一个强大的 Python 库 - docxtpl。 项目地址:https://docxtpl.readthedocs.io/en/latest/ 在日常工作中,自动生成和处理 Word 文档是一个常见需求。doc…...

捷途山海T2:超长续航,节能环保的驾驶新星
在当今的汽车市场中,消费者的购车选择日趋多样化,不再仅限于传统的燃油车。随着环保理念的深入人心以及人们对用车成本的日益关注,像捷途山海T2这样配备高效混动系统的车型逐渐受到大众的青睐。 捷途山海T2,以其杰出的节能性、强劲…...

[Day 45] 區塊鏈與人工智能的聯動應用:理論、技術與實踐
區塊鏈的可擴展性挑戰 概述 區塊鏈技術在過去幾年中取得了顯著的進展,其去中心化、透明和安全的特性使其在金融、供應鏈管理、醫療等領域得到了廣泛應用。然而,區塊鏈技術的一個重大挑戰是其可擴展性。可擴展性是指系統能夠有效處理日益增長的數據和用…...

白骑士的PyCharm教学实战项目篇 4.3 自动化测试与持续集成
系列目录 上一篇: 在现代软件开发过程中,自动化测试与持续集成(CI)是确保代码质量和快速交付的关键环节。PyCharm作为一款强大的集成开发环境(IDE),为自动化测试和持续集成提供了全面的支持。本…...

权限模块开发+权限与角色关联(完整CRUD)
文章目录 🌞 Sun Frame:SpringBoot 的轻量级开发框架(个人开源项目推荐)🌟 亮点功能📦 spring cloud模块概览常用工具 🔗 更多信息1.easycode生成代码1.配置2.AuthPermissionDao.java剪切到mapp…...

llama神经网络的结构,llama-3-8b.layers=32 llama-3-70b.layers=80; 2000汉字举例说明
目录 llama-3-8b.layers=32 llama-3-70b.layers=80 llama神经网络的结构 Llama神经网络结构示例 示例中的输入输出大小 实际举例说明2000个汉字文本数据集 初始化词嵌入矩阵 1. 输入层 2. 嵌入层 3. 卷积层 4. 全连接层 llama-3-8b.layers=32 llama-3-70b.laye…...

单细胞数据怎么表现genes mRNA表达的热图?
愿武艺晴小朋友一定得每天都开心 #热图 library("ComplexHeatmap") exp <- AverageExpression(subset(fasting_memory, Celltype %in% c("Pre-B")), layer = "data", #即CPM值 features …...

Java聚合快递对接云洋系统小程序源码
🚀【物流新纪元】聚合快递如何无缝对接云洋系统,效率飙升秘籍大公开!✨ 🔍 开篇揭秘:聚合快递的魅力所在 Hey小伙伴们,你是否还在为多家快递公司账号管理繁琐、订单处理效率低下而头疼?&#…...

MySQL——数据表的基本操作(三)修改数据表
有时候,希望对表中的某些信息进行修改,这时就需要修改数据表。所谓修改数据表指的是修改数据库中已经存在的数据表结构,比如,修改表名、修改字段名、修改字段的数据类型等。在 MySQL中,修改数据表的操作都是使用 ALTER…...

医学图像分割的基准:TransUnet(用于医学图像分割的Transformer编码器)器官分割
1、 TransUnet 介绍 TransUnet是一种用于医学图像分割的深度学习模型。它是基于Transformer模型的图像分割方法,由AI研究公司Hugging Face在2021年提出。 医学图像分割是一项重要的任务,旨在将医学图像中的不同结构和区域分离出来,以便医生可…...

java-swing编写学生成绩查询管理系统
本文是本人大二上实训项目-学生成绩查询管理系统,采用本项目使用Java、MySQL技术。界面框架由Java Swing搭建,用JDBC实现Java与MySQL的连接。 本项目适合初学java和mysql的同学,来做一些小项目来提升自己,因为兴趣所以想要做去尝…...

volatile浅解
volatile修饰的变量有两个特点 线程中修改了自己工作内存中的副本后,立即将其刷新到主内存工作内存中每次读取共享变量时,都会去主内存中重新读取,然后拷贝到工作内存 内存 -> CPU Cache -> CPU 如果没有volatile那么就会继续读取缓存…...

世媒讯带您了解什么是媒体邀约
什么是媒体邀约?其实媒体邀约是一种公关策略,旨在通过邀请媒体记者和编辑参加特定的活动、发布会或其他重要事件,以确保这些活动能够得到广泛的报道和关注。通过这种方式,企业和组织希望能够传达重要信息,提高品牌知名…...

[Kimi 笔记]“面向搜索引擎”
"面向搜索引擎"(Search Engine-Oriented,SEO-Oriented 或 SEO-Friendly)通常指的是在设计和开发网站时,采取一系列措施来优化网站内容和结构,以便提高网站在搜索引擎结果页面(SERP)中…...

如何在亚马逊云科技AWS上利用LoRA高效微调AI大模型减少预测偏差
简介: 小李哥将继续每天介绍一个基于亚马逊云科技AWS云计算平台的全球前沿AI技术解决方案,帮助大家快速了解国际上最热门的云计算平台亚马逊云科技AWS AI最佳实践,并应用到自己的日常工作里。 在机器学习和人工智能领域,生成偏差…...

订单定时状态处理业务(SpringTask)
文章目录 概要整体架构流程技术细节小结 概要 订单定时状态处理通常涉及到对订单状态进行定期检查,并根据订单的状态自动执行某些操作,比如关闭未支付的订单、自动确认收货等. 需求分析以及接口设计 需求分析 用户下单后可能存在的情况: …...