systrace/perfetto如何看surfaceflinger的vsync信号方法-android framework实战车载手机系统开发

本文主要是介绍systrace/perfetto如何看surfaceflinger的vsync信号方法-android framework实战车载手机系统开发,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

背景:

hi,粉丝朋友们:
大家好!近期分享了surfaceflinger相关的一些blog,有同学就对相关的一些内容产生了一些疑问。
比如:vsync查看问题,即怎么才可以说是vsync到来了。
在这里插入图片描述
比如perfetto中surfaceflinger的VSYNC脉冲经典图如上图所示的,看到一个的小方块,上升下降的方波形,那么通过看这些方块了解真实的vsync信号到来呢?

大部分同学常规方法:

第一种方法:

方波方块确定vsync,这个很多同学不了解原理的或者属于自己看trace同学,看到一个方块的脉冲,然后测量一下方块刚好耗时是16ms左右,任务一个方块就代表一个vsync周期

在这里插入图片描述
哈哈,这种想法其实一开始很多新手自己看vsync都是这样的,属于自己想当然情况,随便一个脉冲就可以反驳比如如下:
在这里插入图片描述
所以这种方式其实不准确哈,很多时候不便于理解

第二种方式:
判断变脉冲方波变化的上升下降的瞬间代表vsync来临方式。

在这里插入图片描述

这种思路和观点其实已经基本上已经算正确了,因为vsync本身是一个信号,属于瞬时的动作,上升和下降代表这个时候的vsync是有变化的。但是有一些场景有问题比如如下这种:
在这里插入图片描述上面问题是课程学员提出的,相关framework干货课程看这里:
更多framework干货课程优惠获取相关可以+V(androidframework007)
视频:https://www.bilibili.com/video/BV1ah411d7Y3
在这里插入图片描述

真实的vsync理解方法:

这个情况就可以看到如果按照上升下降理论确实这个同学说的是对的。但其实这个上升下降理解也还是缺少点理论支持,最好可以结合代码来验证一下。首先看看这个VSYNC-app信号是在哪里:
打印这个VSYNC-app信号的代码如下:

frameworks/native/services/surfaceflinger/Scheduler/DispSyncSource.cpp


void DispSyncSource::onVsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime,nsecs_t readyTime) {VSyncSource::Callback* callback;{std::lock_guard lock(mCallbackMutex);callback = mCallback;}if (mTraceVsync) {//正常都进行tracevsyncmValue = (mValue + 1) % 2;//这里就是trace的值,所以只有0和1}if (callback != nullptr) {callback->onVSyncEvent(targetWakeupTime, {vsyncTime, readyTime});}
}

上面大家可能有疑问,这里

mValue = (mValue + 1) % 2

明明就是对 mValue只是个简单赋值,哪来的TRACE打印。哈哈,这里你得知道c++的符号重载,可以看看mValue的源码就了解了

class TracedOrdinal {
public:static_assert(std::is_same<bool, T>() || (std::is_signed<T>() && std::is_integral<T>()) ||std::is_same<std::chrono::nanoseconds, T>(),"Type is not supported. Please test it with systrace before adding ""it to the list.");TracedOrdinal(std::string name, T initialValue): mName(std::move(name)),mHasGoneNegative(std::signbit(initialValue)),mData(initialValue) {trace();}T get() const { return mData; }operator T() const { return get(); }TracedOrdinal& operator=(T other) { //对赋值进行重载mData = other;mHasGoneNegative = mHasGoneNegative || std::signbit(mData);trace();//打印TRACEreturn *this;}private:void trace() {if (CC_LIKELY(!ATRACE_ENABLED())) {return;}if (mNameNegative.empty()) {mNameNegative = mName + "Negative";}if (!std::signbit(mData)) {ATRACE_INT64(mName.c_str(), to_int64(mData));if (mHasGoneNegative) {ATRACE_INT64(mNameNegative.c_str(), 0);}} else {ATRACE_INT64(mNameNegative.c_str(), -to_int64(mData));ATRACE_INT64(mName.c_str(), 0);}}const std::string mName;std::string mNameNegative;bool mHasGoneNegative;T mData;
};

所以说mValue = (mValue + 1) % 2的这个赋值操作就是打印trace了,也就是说系统执行到了 DispSyncSource::onVsyncCallback就代表有vsync到来,上升和下降那种理论就说的过去了,因为上升下降代表mValue确实有变化了。但是上面方法二那个同学疑问怎么解释呢?
在这里插入图片描述
这里大家要注意看这个信号图:

在这里插入图片描述
关注VSYNC-appSf这一栏信号,是不是发现第一个绘制第一个信号value为0,在这个第一个信号绘制以前图形中其实并没有看到有任何的value。
相当于这个信号在我们这个trace中属于第一次有value情况。

那么结合我们上面的代码结论我们知道,第一次有value的trace打印了,说明肯定是有vsync的回调了,至于之前脉冲图没有打印,那一般是因为抓取时候就没有触发这个onVsyncCallback回调,所以自然不会打印出来啦。这样理解了代码再去看这个vsync脉冲图是不是好理解多了。

这篇关于systrace/perfetto如何看surfaceflinger的vsync信号方法-android framework实战车载手机系统开发的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/291084

相关文章

PHP轻松处理千万行数据的方法详解

《PHP轻松处理千万行数据的方法详解》说到处理大数据集,PHP通常不是第一个想到的语言,但如果你曾经需要处理数百万行数据而不让服务器崩溃或内存耗尽,你就会知道PHP用对了工具有多强大,下面小编就... 目录问题的本质php 中的数据流处理:为什么必不可少生成器:内存高效的迭代方式流量控制:避免系统过载一次性

基于 Cursor 开发 Spring Boot 项目详细攻略

《基于Cursor开发SpringBoot项目详细攻略》Cursor是集成GPT4、Claude3.5等LLM的VSCode类AI编程工具,支持SpringBoot项目开发全流程,涵盖环境配... 目录cursor是什么?基于 Cursor 开发 Spring Boot 项目完整指南1. 环境准备2. 创建

MyBatis分页查询实战案例完整流程

《MyBatis分页查询实战案例完整流程》MyBatis是一个强大的Java持久层框架,支持自定义SQL和高级映射,本案例以员工工资信息管理为例,详细讲解如何在IDEA中使用MyBatis结合Page... 目录1. MyBATis框架简介2. 分页查询原理与应用场景2.1 分页查询的基本原理2.1.1 分

python获取指定名字的程序的文件路径的两种方法

《python获取指定名字的程序的文件路径的两种方法》本文主要介绍了python获取指定名字的程序的文件路径的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 最近在做项目,需要用到给定一个程序名字就可以自动获取到这个程序在Windows系统下的绝对路径,以下

JavaScript中的高级调试方法全攻略指南

《JavaScript中的高级调试方法全攻略指南》什么是高级JavaScript调试技巧,它比console.log有何优势,如何使用断点调试定位问题,通过本文,我们将深入解答这些问题,带您从理论到实... 目录观点与案例结合观点1观点2观点3观点4观点5高级调试技巧详解实战案例断点调试:定位变量错误性能分

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

Python中 try / except / else / finally 异常处理方法详解

《Python中try/except/else/finally异常处理方法详解》:本文主要介绍Python中try/except/else/finally异常处理方法的相关资料,涵... 目录1. 基本结构2. 各部分的作用tryexceptelsefinally3. 执行流程总结4. 常见用法(1)多个e

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法

《JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法》:本文主要介绍JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法,每种方法结合实例代码给大家介绍的非常... 目录引言:为什么"相等"判断如此重要?方法1:使用some()+includes()(适合小数组)方法2