当前位置: 首页 > ds >正文

SurfaceFlinger及Android应用RenderThread角度观察Jank丢帧卡顿

SurfaceFlinger及Android应用RenderThread角度观察Jank丢帧卡顿


CPU、GPU、Display 三个部分:CPU 负责计算帧数据,把计算好的数据交给 GPU,GPU 会对图形数据进行渲染,渲染好后放到 buffer (图像缓冲区)存起来,然后 Display (屏幕或显示器)把 Buffer呈现到屏幕。
Google 在 Android 4.1 系统中对 Android Display 系统进行了重构,引入了 Project Butter(黄油计划):在系统收到 Vsync 信号后,上层 CPU 和 GPU 马上进行下一帧画面数据的处理,完成后及时将数据写入到 Buffer 中,Google 称之为 Drawing with Vsync。
在ViewRootImpl中完成对界面的measure、layout和draw等绘制流程后,用户依然还是看不到内容,因为Android系统的显示流程除了UI 线程的绘制外,还需要经过RenderThread线程的渲染处理,渲染完成后,还需要通过Binder调用“上帧”交给surfaceflinger进程进行合成后才能最终显示到屏幕上。
Android应用渲染流程中,应用扮演的是生产者角色,SurfaceFlinger扮演的是消费者,工作的流程如下:
应用在开始绘制渲染之前,需要通过调用dequeueBuffer从SurfaceFlinger管理的BufferQueue 申请一处于free状态的可用Buffer,如果此时没有可用Buffer则阻塞等待;
应用拿到可用的Buffer后,使用GPU绘制渲染,渲染完成后再通过Binder调用queueBuffer将数据返回给应用进程对应的BufferQueue,如果是 GPU 渲染的话,这里还有个 GPU处理的过程,所以这个 Buffer 不会马上可用,需要等 GPU 渲染完成的Fence信号,并申请sf的Vsync-sf唤醒消费者SurfaceFlinger进行消费;
SurfaceFlinger 收到 Vsync-sf 信号之后,开始准备合成,使用 acquireBuffer获取应用对应的 BufferQueue 中的 Buffer 并进行合成操作;
合成结束后,SurfaceFlinger 调用 releaseBuffer将 Buffer 置为可用的free状态,返回到应用对应的 BufferQueue中。
从 SurfaceFlinger 角度来说,在 App 连续的动画或者手指滑动列表时(关键是连续),如果有一个 Vsync 到来时候 ,App 没有可以用来合成的 Buffer,那么这个 Vsync 周期 SurfaceFlinger 就不会走合成逻辑(或者是去合成其他的 Layer),那么这一帧就会显示 App 的上一帧的画面,这里发生了卡顿;
从App的角度来看,如果渲染线程在一个 Vsync 周期内没有 queueBuffer 到 SurfaceFlinger 中 App 对应的 BufferQueue 中,那么我们认为这里发生了卡顿。
如果线程Running时长过长导致运行变慢,最终出现上帧超时而掉帧,就需要结合具体tag信息查看到底在执行什么逻辑,然后结合自身的代码实现看是否可以优化。或者看看当前JIT线程任务是否繁忙,判断是否是因为应用没有被及时编译成机器码而导致运行时长过长。
出于功耗节能的原因,VSYNC-sf与VSYNC-app并不一定会固定不停触发。如果app或sf并没有刷新画面的需求,那么触发信号进行绘制和合成是不必要的(功耗)。触发VSYNC-sf和VSYNC-app的两个EventThread会在requestNextVsync调用后才会将下一个VSYNC-sf或VSYNC-app发出。因此,当(各自EventThread)requestNextVsync没有调用时,VSYNC-app和VSYNC-sf也就出现异常。BufferQueueLayer::onFrameAvailable会在应用提交后调用,该方法通过调用SF的signalLayerUpdate触发产生下一个VSYNC-sf。

Android trace presentFence屏幕显示的帧-CSDN博客文章浏览阅读807次,点赞20次,收藏21次。在Android系统中,presentFence是屏幕显示帧的关键信号,当帧成功显示时,presentFence会发出信号。FrameMissed、GpuFrameMissed和HwcFrameMissed表示上一次合成的结果,SurfaceFlinger在每次被Vsync-sf唤醒时会检查上一次合成的presentFence是否已发出信号,若未发出则认为是帧丢失。BufferTx在queueBuffer后增加,在SurfaceFlinger合成时减少,其内有可用Buffer时,SurfaceFlinger https://blog.csdn.net/zhangphil/article/details/148099387

http://www.xdnf.cn/news/8525.html

相关文章:

  • 【漫话机器学习系列】274.基尼指数(Gini Index)
  • 在Vue3 + Vite 项目安装使用 Tailwind CSS 4.0报错
  • 小白刷题之链表中的 “龟兔赛跑“:快慢指针算法详解
  • python打卡day34@浙大疏锦行
  • C++线程池的使用
  • 力扣 128.最长连续序列
  • 缓存和数据库一致性问题
  • 对于geoserver发布数据后的开发应用
  • MYSQL之复合查询
  • 基于51单片机和8X8点阵屏、独立按键的飞行躲闪类小游戏
  • wordpress上传图片时出现服务器无法处理图片
  • Vue3 + Element Plus表格筛选样式设置
  • ES6 哈希数据结构
  • 【maxcompute】阿里maxcompute Python开发个人经验汇总
  • 为何在VMware中清理CentOS虚拟机后,本地磁盘空间未减少的问题解决
  • 工业RTOS生态重构:从PLC到“端 - 边 - 云”协同调度
  • PCIe Gen3 phy(编解码,token相关)
  • 谢飞机的Java面试奇遇:AIO、BIO、NIO与Netty深度解析
  • openEuler 22.03安装zabbix7 LTS(容器化部署)
  • ajax中get和post的区别,datatype返回的数据类型有哪些?
  • STM32 SPI通信(硬件)
  • 2025 最新教程:注册并切换到美区 Apple ID
  • 3dczml时间动态图型场景
  • 怎么判断一个Android APP使用了taro 这个跨端框架
  • 自制操作系统day9内存管理(cache、位图、列表管理、内存的释放)(ai辅助整理)
  • Web前端开发:JavaScript的使用
  • 【软件安装】Windows操作系统中安装mongodb数据库和mongo-shell工具
  • 从零入门:Google Cloud Platform (GCP) 基础架构与核心服务全解析
  • 推荐一款滴滴团队开源流程图编辑框架logic-flow
  • 禅道——安装PHP的ioncube扩展