Android 渲染机制

Android 渲染机制

View 的绘制流程有3个步骤,分别是measure 、layout和draw,它们主要运用在系统的应用框架层,而真正将数据渲染到屏幕上的则是系统Native层的SurfaceFlinger服务来完成的。

绘制过程主要由CPU来进行Measure、Layout、Record、Execute的数据计算工作,GPU负责栅格化、渲染。CPU和GPU是通过图形驱动层来进行连接的,图形驱动层维护了一个队列,CPU将display list添加到该队列中,这样GPU就可以从这个队列中取出数据进行绘制。

应用程序的帧率是多少呢?我们的目标是,让应用程序在其整个生命周期中,始终保持60FPS的帧速率。这意味着要在一秒内刷新60次,也就是每16.6667毫秒刷新一次。
在这里插入图片描述
Android 系统每隔16ms发出VSYNC信号,触发对UI进行渲染,触发对UI进行渲染,如果每次渲染都成功,这样就能达到流畅的画面所需要的60fps,那么什么事VSYNC呢?VSYNC是Vertical Synchronization(垂直同步)的缩写,是一种定时中断,一旦收到VSYNC信号,CPU就开始处理各帧数据。

屏幕撕裂和垂直同步

关于刷新,主要有两方面需要考虑:

  • 帧速率: 指的是设备的GPU每秒能为整个屏幕绘制多少帧。我们的目标是维持Android设备的标准。
  • 刷新率: 指的是屏幕在一秒内更新的次数,以赫兹为单位。大部分Android设备的刷新率为60Hz。

刷新率是固定不变的,但帧速率取决于众多因素,其中最重要的因素是开发人员的技能

这两个有可能不同步。当屏幕在刷新过程中,相邻的不同两帧图像被
绘制到同一个屏幕上,造成屏幕出现明显的截断现象。这一现象直到屏幕完成下一次绘制才消失。我们把这种情况称为屏幕撕裂,他会影响GPU系统的每次显示。图片上非来那段的线被称为撕裂点,它们是屏幕撕裂的结果。

在这里插入图片描述
造成这一现象的主要原因是,绘制帧的数据源是单向的。新的一帧会覆盖在上一帧,然而只有一个缓冲区可供读取。当屏幕要刷新时,它会从缓冲区读取要被绘制的帧,但如果这一帧还处于未完成的状态,就会出现上图的现象。

针对该问题最常用的解决方案是采用双缓冲区。该方案可通过以下方式实现:

  • 所有的绘制操作被保存在一个后台缓冲区。
  • 当这些操作完成时,将整个后台缓冲区复制到另一块,被称为前台缓冲区的内存区域。

复制操作与屏幕的速率保持同步。屏幕只需要从前台缓冲区读取,以避免屏幕撕裂,并且所有的后台绘制操作不会影响屏幕的绘制。但是,在讲缓冲区从后台复制到前台的这一过程中,需要有一种机制来防止屏幕被更新,我们把这种机制成为垂直同步(VSYNC)

垂直同步并不是问题的终极解决方案。如果帧速率大于等于刷新率,那么一切都很正常。如下图,帧速率为80FPS,而刷新率为60Hz。对屏幕绘制来说,新的帧一直够用,所以屏幕不会出现延迟。
在这里插入图片描述

但如果帧速率小于刷新率,会发生什么情况呢?接下来,让我们通过示例一步步分析一个40FPS的GPU和一个60Hz刷新率的屏幕在一起会出现什么情况?也就会是说,帧速率是刷新率的2/3,导致每一帧会被屏幕刷新1.5次。

  1. 屏幕首次刷新,每一帧进入前台缓冲区,同时GPU在后台缓冲区准备第二帧。
  2. 屏幕第二次刷新,然而此时GPU还未完成绘制操作,刚进行到操作的2/3阶段,因此,不能将它复制到前台缓冲区。
  3. 屏幕第三次刷新,第二帧已经被复制到前台缓冲区,这时它可以被显示在屏幕上。而GPU也在为第三帧做准备。
  4. 屏幕第四次刷新,第二帧被绘制在屏幕上,因为它已经在前台缓冲区,同时GPU仍然在为第三帧做准备。
  5. 屏幕第五次刷新和第二次刷新类似的,第三帧不能被显示在屏幕上,因为需要等待一次新的刷新。所以,新的一帧在第二次刷新中才能被显示。
    在这里插入图片描述
    最终,在四次屏幕刷新中,实际只绘制了两帧。当帧速率小于刷新率时,这种情况每次都会发生。哪怕帧速率为59FPS,而实际显示到屏幕上也仅为每秒30帧。因为GPU在后台缓冲区启动一次新的绘制操作之前,需要等待一次新的刷新发生。

产生卡顿原因有很多,主要有哪些呢

  • 布局Layout过于复杂,无法在16ms内完成渲染
  • 同一时间动画执行的次数过多,导致CPU或GPU负载过重
  • View过度绘制,导致某些像素在同一帧时间内被绘制多次
  • 在UI线程中做了稍微耗时的操作
  • GC回收时暂停时间过长或者频繁的GC产生大量的暂停时间
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值