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

Android的UI View是如何最终绘制成一帧显示在手机屏幕上?

Android的UI View是如何最终绘制成一帧显示在手机屏幕上?

Android View的onmeasure,onlayout和ondraw过程中,会生成绘制指令,存在DisplayList缓存区,每个View内部都有一个DisplayList,当View需要重绘时,这个View被标记为dirty,在draw的时候,View的DisplayList都会被更新,这个时候的DisplayList就会保存最新的绘制指令,这都是在主线程完成。在绘制流程走完,生成一系列DisplayList 绘制指令后,随后这些绘制指令会被同步到Render Thread。DisplayList可以认为是一系列绘制指令(比如将canvas的命令转换为OpenGL指令)。
VSYNC全称 Vertical Synchronization,垂直同步,简单的理解为一种时钟中断。Android的VSYNC消费者有两个,对应两类VSYNC信号,分别是VSYNC-app和VSYNC-sf,所对应的也是上层View绘制和SurfaceFlinger合成。App代表的是生产者,sf代表的是消费者,两者交付的中间产物则是 surface buffer。

手机屏幕渲染显示的一个关键,是对图像数据的生产和消费。生产和消费的对象,是 BufferQueue里的Buffer。
生产者使用 dequeueBuffer 取出可用的 Buffer,往里面填充图像数据(CPU或GPU 生产),然后 queueBuffer 把图像数据放回到 BufferQueue ;消费者使用 requireBuffer 取出可用于屏幕显示的图像数据,然后显示,接着再把 Buffer release 后,返还 BufferQueue。

要理解Android UI渲染流程,就要了解谁是生产者(Producer),谁是消费者(Consumer),以及 BufferQueue 怎么轮转。

生产者和消费者双方:
生产者之一就是App应用。不论是Android UI组件本身的绘制,还是播放器解码出来的视频帧,还是从手机摄像头取出的拍摄数据,App 都是图像数据的生产者。
消费者是 SurfaceFlinger 和 HWC(Hardware Composer),对各生产者生产出来 Buffer 进行合成,显示到屏幕。

Choreographer 和 Vsync

Choreographer(编舞者) 和 Vsync 协调生产者何时生产,消费者何时消费。Choreographer 本质是一个 Java 类。简单说,Choreographer 作用是协调输入、动画、和绘制等任务的执行时机,它从显示子系统接收定时脉冲VSYNC,然后安排渲染下一个显示 Frame 的部分工作。
如果生产者和消费者的行为都是非常激进:生产者先生产,然后把 Buffer 放回到 BufferQueue 后,消费者马上消费,然后生产者又马上拿出来生产,假设两者不会有时间间隙,全过程持续进行。
这有什么问题吗?
手机屏幕刷新率在 60Hz ~ 144Hz 之间。1S内,每次刷新间隔即约7ms~16ms,要产生流畅的画面,1S按照60帧~144帧就可以,但如果以这样的方式生产和消费,那么大概率会产出很多无用功,带来功耗问题。因此需要一个协调者来协调,平衡功耗和绘制节奏。
这就是Choreographer(编舞者):a person who composes the sequence of steps and moves for a performance of dance.
Choreographer 协调生产者什么时候生产,什么时候绘制一帧。既然要协调,那么需要一个协调依据,这个依据就是 Vsync 信号。
Vsync 信号一般是由硬件产生,每个 Vsync 信号之间的时间,就是每一帧生产 / 消费的间隙。Vsync 有两种,Vsync-app 和 Vsync-sf,前者用于告诉 Choreographer,是时候协调 app 生产了;后者用于告诉 SurfaceFlinger,是时候来消费合成并显示到屏幕了。
Vsync-app 和 Vsync-sf 几乎同时发生的(不同手机厂商自定义 Vsync Offset ,每个手机可能不尽完全一样),Android系统使用数字信号的变化来表示 Vsync 的发生,从 1 到 0 或者从 0 到 1 都表示发生了 Vsync 信号。


Vsync-app 和 Vsync-sf 发生时,Choreographer 是怎么协调的?


Choreographer 的引入,主要是配合 Vsync ,给App 的渲染提供一个稳定的 Message 处理时机,系统通过对 Vsync 信号周期的调整,控制每一帧绘制的时机。比如手机的屏幕刷新率是 60Hz,也就是 16.6ms 刷新一次,系统为了配合屏幕的刷新频率,将 Vsync 的周期也设置为 16.6 ms,每隔 16.6 ms ,Vsync 信号到来唤醒 Choreographer 来做 App 的绘制操作 ,如果每个 Vsync 周期应用都能渲染完成,那么应用的 fps 就是 60 ,给用户的感觉就是流畅。

为什么App 需要重绘?既然重绘,那么是 App 内容发生变化,这里的内容变化由多种情况发生:用户通过物理按键或者手指触摸屏幕,产生了交互行为,App 需要响应交互,做出相应的UI变化,比如改变按钮的文字、颜色等;
动画过程,每隔一段时间触发一次内容的改变,比如改变背景透明度,View 位置等;
视频播放场景。
典型的,以用户交互行为导致重绘的场景为例,收到 Vsync-app 信号后,Choreographer:
分派触控事件;
Measure、Layout 和 Draw等;
以上都是发生在主线程,其中 Draw:
如果开启了硬件(GPU)加速(默认都是开了的),那么不会走 CPU 绘制,这里会产生用来描述绘制行为的 DisplayList;
没开启硬件加速的话,会调用 libSkia 来绘制(CPU);
不要混淆硬件加速和 Software Layer / Hardware Layer 。开启硬件加速后,可以用 Hardware Layer 来对内容本身很少改变的 View 来做显存上的缓存;而不开启硬件加速,或者不支持 Hardware Layer 的话,可以选择使用 Software Layer 来告诉 UI Framework 帮你构造 Bitmap 缓存。对于不使用 Layer 的情况,View 该怎么绘制就怎么绘制。
在开启硬件(GPU)加速后,主线程就会把 DisplayList 同步给 RenderThread,RenderThread 这里可以做一些优化的操作(比如 Reordering),然后提交给 GPU 进行绘制(这里会进行 dequeueBuffer),当绘制完毕后(eglSwapBuffers),通过 queueBuffer 把 Buffer 放回到 BufferQueue 里。

 Vsync-sf 发生后,SurfaceFlinger 就跟 HAL 打交道,把图像数据渲染到 Display 上。


SurfaceFlinger跟 Hardware Composer 打交道,把各个 Layer 的数据进行合成,然后交由 HardwareComposer 显示。

SurfaceFlinger及Android应用RenderThread角度观察Jank丢帧卡顿_图像卡顿 surfaceflinger-CSDN博客文章浏览阅读904次,点赞14次,收藏28次。在Android系统中,Jank(卡顿)问题主要涉及CPU、GPU和Display三个部分。CPU负责计算帧数据,GPU进行图形渲染,渲染后的数据存储在Buffer中,最后由Display呈现到屏幕。Google在Android 4.1中引入了Project Butter,通过Vsync信号优化了帧处理流程,确保CPU和GPU在收到Vsync信号后立即处理下一帧数据。应用在绘制前需从SurfaceFlinger管理的BufferQueue申请Buffer,渲染完成后通过queueBuffer将数据返回给Bu_图像卡顿 surfaceflinger https://blog.csdn.net/zhangphil/article/details/148176456Android屏幕刷新率与FPS(Frames Per Second) 120hz_帧时间16.67ms多少帧-CSDN博客文章浏览阅读1.5k次,点赞14次,收藏17次。Android屏幕刷新率与FPS的关系决定了显示流畅度。120Hz屏幕每秒刷新120次(8.33ms/次),而FPS指系统生成帧数。理想状态下FPS应与刷新率匹配,如120FPS对应120Hz。当FPS低于刷新率时会出现卡顿,高于则浪费资源。Android 12引入Surface.setFrameRate()API让应用指定帧率。系统通过BufferQueue管理帧缓冲,渲染完成数据通过queueBuffer传给SurfaceFlinger显示。VSync信号同步处理流程,确保CPU/GPU及时处理帧数据,_帧时间16.67ms多少帧 https://blog.csdn.net/zhangphil/article/details/148543654

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

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

相关文章:

  • 阿里云-通义灵码:解锁云原生智能开发新能力,让云开发更“灵”~
  • 福彩双色球第2025089期篮球号码分析
  • 理解 JavaScript 中的“ / ”:路径、资源与目录、nginx配置、请求、转义的那些事
  • 超急评估:用提前计算分摊性能成本
  • go学习笔记:panic是什么含义
  • 工作流绑定卡片优化用户体验-练习我要找工作智能体
  • 豆包1.6+PromptPilot实战:构建智能品牌评价情感分类系统的技术探索
  • 基于Spring Cloud Gateway和Resilience4j的微服务容错与流量控制实战经验分享
  • Solidity智能合约开发全攻略
  • 电商系统想撑住大流量?ZKmall开源商城靠微服务 + Spring Boot3 解决单体架构难题
  • 设计模式-创建型-工厂模式
  • 134页PPT华为项目管理之道PPT
  • 期权投资盈利之道书籍推荐
  • Scrapy爬虫集成MongoDB存储
  • 13.Home-面板组件封装
  • 区块链 和 一致性哈希的结合
  • 基于高斯光束干涉的微球体相位成像系统设计与实现
  • JVM学习日记(十六)Day16——性能监控与调优(三)
  • Python实现Word转PDF全攻略:从入门到实战
  • Linux U盘识别问题排查指南
  • Spring Boot + ShardingSphere 分库分表实战
  • 机器学习——决策树(DecisionTree)+ 过采样 + 交叉验证 案例:电信客户流失数据
  • 飞算科技:用自主创新技术,为行业数字化转型按下 “加速键”
  • ICCV2025 Tracking相关paper汇总和解读(19篇)
  • 13015计算机系统原理-速记宝典
  • Web 开发 12
  • 移动前后端全栈项目
  • 小迪安全v2023学习笔记(五十一讲)—— 持续更新中
  • Nexus配置npm私有仓库
  • Java项目:基于SSM框架实现的商铺租赁管理系统【ssm+B/S架构+源码+数据库+毕业论文+开题报告+任务书+远程部署】