Android Graphics 显示系统 - Android Jank detection with FrameTimeline

“ 最近有公司同事在处理UI卡顿及FPS自动化监测的问题,我也顺便看了一点相关的内容,其中在Perfetto的官方说明文档中有一篇关于利用FrameTimeLine进行Jank监测的解读,个人觉得蛮有意思的,借助工具翻译该篇文章并加上本人拙劣的解读供大家把玩!

注意:Android 12(S)以及更高版本的安卓系统的SurfaceFlinger中才有实现FrameTimeLine的逻辑。

/frameworks/native/services/surfaceflinger/FrameTimeline/

英文好且对Graphics知识有一定了解的,无需阅读拙作,直接读英文原文即可,地址:

https://perfetto.dev/docs/data-sources/frametimeline


01 前言

Jank/Janky直译就是劣质的、不可靠的。如果一个Frame被认为出现了Jank,则说明该帧图像没有按照调度器给出的预计时间显示到屏幕上,通常就是显示晚了。

Jank会造成什么影响呢?

  • 不稳定的帧率 -- 比如正常是60fps,但因为Jank帧率可能只有50fps,导致画面不流畅;

  • 延迟增加 -- 在一些实时性要求高的场景,画面可能延时几个vsync显示,比如视频播放时AV不sync;

怎么监测Jank呢?

FrameTimeline是SurfaceFlinger中的一个模块,用于监测Jank并报告Jank的来源。

02 APP Timeline

对于至少有一帧画面显示到屏幕上的应用,在抓取的Perfetto信息中会看到两个Timeline轨迹:Expected Timeline 和 Actual Timeline

图片

Expected Timeline:预期时间线,每个切片表示应用程序渲染帧的时间。为了避免系统中出现janks,该应用程序预计将在此时间范围内完成。切片开始时间是Choreographer callback计划运行的时间。

Actual Timeline:这些切片表示应用程序完成帧的绘制(包括GPU工作)并将其发送给SurfaceFlinger进行合成所花费的实际时间。起始时间是Choreographer#doFrame或AChoreographer_vsyncCallback开始运行的时间。切片的结束时间表示 (gpu time, post time) 两者的最大值。post time是应用的帧发送到SurfaceFlinger的时间。

图片

看到这里大家会不会有什么疑问或发现?

对于Case 2,比较符合常规理解,CPU和GPU的工作都做完了,即APP的一帧图片绘制完成了,然后才送到SurfaceFlinger去显示;

对于Case 1,GPU的绘制还没完成就先送去SurfaceFlinger了,这不会有问题吧?当然不会,这就是acquire fence的意义了,不熟悉的可以参考前面文章

Android Graphics 显示系统 - GraphicBuffer同步机制-Fence(二十)

我们看Android 14代码中,主要是哪里在等待acquire fence:

CLIENT合成时,会调用到RenderEngine::drawLayers方法来呼叫GPU完成合成工作,要等到layer的buffer准备好后才能开始合成工作,此时就要等待acquire fence。

/frameworks/native/libs/renderengine/skia/SkiaRenderEngine.cpp
ftl::Future<FenceResult> RenderEngine::drawLayers(...) {
    ......
    drawLayersInternal(std::move(resultPromise), display, layers, buffer, useFramebufferCache,
                       std::move(bufferFence));
    return resultFuture;
}

/frameworks/native/libs/renderengine/skia/SkiaRenderEngine.cpp
void SkiaRenderEngine::drawLayersInternal(......) {
    ...
    if (layer.source.buffer.buffer) {
        ATRACE_NAME("DrawImage");

        // if the layer's buffer has a fence, then we must must respect the fence prior to using
        // the buffer.
        if (layer.source.buffer.fence != nullptr) {
            waitFence(grContext, layer.source.buffer.fence->get()); // 等待acquire fence
        }
    ...
}

DEVICE合成时,layer的buffer连同其acquire fence会送到HWC,HWC合成前会等待acquire fence。以/external/drm_hwcomposer为例来看:

点击阅读全文:

Android Jank detection with FrameTimeline

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

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

相关文章

linux(centos7)开机自启jar文件

问题 之前参考网上说的直接在/etc/rc.local文件中增加sh文件启动语句&#xff0c;但是没有效果&#xff1a; /root/dashboard/dashboard_backend/start_dashboard.sh 权限也增加了&#xff0c;还是不行&#xff1a; chmod x /etc/rc.local 排查 排查了一下&#xff1a; 查…

基于聚类和回归分析方法探究蓝莓产量影响因素与预测模型研究附录

&#x1f31f;欢迎来到 我的博客 —— 探索技术的无限可能&#xff01; &#x1f31f;博客的简介&#xff08;文章目录&#xff09; 目录 背景数据说明数据来源思考 附录数据预处理导入包以及数据读取数据预览数据处理 相关性分析聚类分析数据处理确定聚类数建立k均值聚类模型 …

FFmpeg播放器的相关概念【1】

播放器框架 相关术语 •容器&#xff0f;文件&#xff08;Conainer/File&#xff09;&#xff1a;即特定格式的多媒体文件&#xff0c;比如mp4、flv、mkv等。 • 媒体流&#xff08;Stream&#xff09;&#xff1a;表示时间轴上的一段连续数据&#xff0c;如一段声音数据、一段…

BIOS主板(非UEFI)安装fedora40的方法

BIOS主板(非UEFI)安装fedora40的方法 现实困难&#xff1a;将Fedora-Workstation-Live-x86_64-40-1.14.iso写入U盘制作成可启动U盘启动fedora40&#xff0c;按照向导将fedora40安装到真机的sda7分区中得到报错如下内容&#xff1a; Failed to find a suitable stage1 device: E…

氯气安全阀检测流程揭秘:保障化工安全新举措

在化工行业中&#xff0c;氯气作为一种重要的工业原料&#xff0c;广泛应用于多个生产领域。 然而&#xff0c;氯气的危险性也不容忽视&#xff0c;一旦发生泄漏或超压等安全事故&#xff0c;后果不堪设想。因此&#xff0c;氯气安全阀的重要性便显得尤为突出。 在这篇文章中…

WindowManager相关容器类

窗口中容器类介绍&#xff1a; 本节内容较多&#xff0c;建议结合前面的内容一起阅读&#xff1a; 1、addWindow的宏观概念 2、WindowManager#addView_1 3、WindowManager#addView_2 1&#xff09;、WindowContainer&#xff1a; class WindowContainer<E extends WindowC…

Python编程基础2

文件对象&#xff1a; open内建函数&#xff1a;通过了初始化输入、输出&#xff08;I/O&#xff09;操作的通用接口&#xff0c;成功打开文件后会返回一个文件对象&#xff0c;否则引发错误。file_objectopen&#xff08;file_name&#xff0c;mode‘r’&#xff09;:file_nam…

一款仅200kb好看的免费引导页源码

源码介绍: 这是一款200kb左右的引导页,超级好看,用服务器或者主机均可搭建 下载压缩包解压至根目录即可&#xff0c;页面内容在index.html里修改 左边图片采用的是API接口&#xff08;不喜欢可以自行更换,在66/67行&#xff09; 引导页压缩包放在下面了,有需要的朋友可以直接下…

【热点】老黄粉碎摩尔定律被,量产Blackwell解决ChatGPT耗电难题

6月3日&#xff0c;老黄又高调向全世界秀了一把&#xff1a;已经量产的Blackwell&#xff0c;8年内将把1.8万亿参数GPT-4的训练能耗狂砍到1/350&#xff1b; 英伟达惊人的产品迭代&#xff0c;直接原地冲破摩尔定律&#xff1b;Blackwell的后三代路线图&#xff0c;也一口气被…

杂谈k8s

其实看我之前的博客&#xff0c;k8s刚有点苗头的时候我就研究过&#xff0c;然后工作的时候间接接触 也自己玩过 但是用的不多就忘记了&#xff0c;正苦于不知道写什么&#xff0c;水一篇 简化容器应用程序的部署和管理 自动化部署、自动伸缩、负载均衡、存储管理、自我修复 支…

DP-Kmaens密度峰值聚类算法

我有个问题 关于 [密度值>密度阈值] 的判定这里&#xff0c;新进来的新数据怎么确定他的密度值&#xff1f;密度阈值又是怎样确定的呢&#xff1f;

Golang | Leetcode Golang题解之第129题求根节点到叶节点数字之和

题目&#xff1a; 题解&#xff1a; type pair struct {node *TreeNodenum int }func sumNumbers(root *TreeNode) (sum int) {if root nil {return}queue : []pair{{root, root.Val}}for len(queue) > 0 {p : queue[0]queue queue[1:]left, right, num : p.node.Left, …

RPM包方式离线部署gitlab

下载安装包 要求&#xff1a;可以联网&#xff0c;系统及版本与目标服务器一致。配置gitlab yum仓库 curl -s https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash 新建包存放目录 mkdir /root/gitlab 下载gitlab及相关安装包 …

Linux之线程及线程安全详解

前言&#xff1a;在操作系统中&#xff0c;进程是资源分配的基本单位&#xff0c;那么线程是什么呢&#xff1f;线程是调度的基本单位&#xff0c;我们该怎么理解呢&#xff1f; 目录 一&#xff0c;线程概念理解 二&#xff0c;Linux里面的线程原理 三&#xff0c;为什么要…

《MySQL索引》学习笔记

《MySQL索引》学习笔记 MySQL的体系结构存储引擎简介InnoDB简介MyISAM简介 索引索引结构BTreeHash索引思考索引分类 索引语法SQL性能分析索引使用最左前缀法则 索引失效的情况范围查询索引列运算字符串不加引号模糊查询or连接的条件数据分布影响 SQL提示覆盖索引前缀索引单列索…

【MyBatisPlus】DML编程控制

【MyBatisPlus】DML编程控制 文章目录 【MyBatisPlus】DML编程控制1、id生成策略2、逻辑删除 1、id生成策略 id生成策略控制&#xff08;TableId注解&#xff09; 名称&#xff1a;TableId 类型&#xff1a;属性注解 位置&#xff1a;模型类中用于表示主键的属性定义上方 作…

机器学习中的集成学习

&#x1f4ac;内容概要 1 集成学习概述及主要研究领域 2 简单集成技术  2.1 投票法  2.2 平均法  2.3 加权平均 3 高级集成技术  3.1 Bagging  3.2 Boosting  3.3 Bagging vs Boosting 4 基于Bagging和Boosting的机器学习算法  4.1 sklearn中的Bagging算法  4.2 sklea…

AI大模型探索之路-实战篇15: Agent智能数据分析平台之整合封装Tools和Memory功能代码

系列篇章&#x1f4a5; AI大模型探索之路-实战篇4&#xff1a;深入DB-GPT数据应用开发框架调研 AI大模型探索之路-实战篇5&#xff1a;探索Open Interpreter开放代码解释器调研 AI大模型探索之路-实战篇6&#xff1a;掌握Function Calling的详细流程 AI大模型探索之路-实战篇7…

C++基础-vector容器

目录 零. 前言: 一.简介 二. 主要特点 三. 例子 1.创建 2.添加元素 3.访问元素 4.获取大小 5.删除元素 6.扩展 begin() end() 零. 前言: 在编程中&#xff0c;数组通常具有固定的大小&#xff0c;这在某些情况下可能会带来一些限制。 当我们事先无法确切知道需要存…

topK 问题

topK 问题 topK二、实验内容三、数据结构设计四、算法设计五、运行结果六、程序源码 topK &#xff08;1&#xff09;实验题目 topK 问题 &#xff08;2&#xff09;问题描述 从大批量数据序列中寻找最大的前 k 个数据&#xff0c;比如从 10 万个数据中&#xff0c;寻找最大的…