网站怎么收费,手机端网站建设的费用清单,制作wordpress模板教程视频,重庆市建设工程信息网南川区“ 最近忙着新房子装修的事情#xff0c;这篇计划内的文章拖了好久一直没有足够的时间来写作#xff0c;终于挤出些儿时间来继续研究学习了。” 整了四个晚上终于拼凑出一篇文章#xff0c;虽说是讲FPS计算原理#xff0c;但该文涉及的知识点还是蛮多的#xff0c;特别是对…“ 最近忙着新房子装修的事情这篇计划内的文章拖了好久一直没有足够的时间来写作终于挤出些儿时间来继续研究学习了。” 整了四个晚上终于拼凑出一篇文章虽说是讲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 nameBuilt-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 个数字每个数字都是时间戳单位是纳秒分别表示 desiredPresentTimeactualPresentTimeframeReadyTime在计算FPS的时候使用的是第二个时间戳。
actualPresentTime就是present fence signal的时间根据获取的这127个actualPresentTime数据就可以计算一秒内有多少个present fence signal了也即多少帧刷新到屏幕了。
计算公式
更多信息阅读原文
Android Graphics 显示系统 - 计算FPS的原理与探秘Present Fence