资讯专栏INFORMATION COLUMN

Android Vsync 原理浅析

shinezejian / 2774人阅读

摘要:这就是卡顿出现的原因和情况。这个时候重复了上一个情况,也是太耗时了,然后又覆盖了下一个发出的时间,再次造成卡顿依次类推,会造成多次卡顿。但是注意了只有在需要时,才会进行三重缓冲。

Preface

Android中,Client测量和计算布局,SurfaceFlienger(server)用来渲染绘制界面,client和server的是通过匿名共享内存(SharedClient)通信。

每个应用和SurfaceFlienger之间都会创建一个SharedClient,一个SharedClient最多可以创建31个SharedBufferStack,每个surface对应一个SharedBufferStack,也就是一个Window。也就意味着,每个应用最多可以创建31个窗口。


Android 4.1 之后,AndroidOS 团队对Android Display进行了不断地进化和改变。引入了三个核心元素:Vsync,Triple Butter,Choreographer。

首先来理解一下,图形界面的绘制,大概是有CPU准备数据,然后通过驱动层把数据交给GPU来进行绘制。图形API不允许CPU和GPU直接通信,所以就有了图形驱动(Graphics Driver)来进行联系。Graphics Driver维护了一个序列(Display List),CPU不断把需要显示的数据放进去,GPU不断取出来进行显示。

其中Choreographer起调度的作用。统一绘制图像到Vsync的某个时间点。

Choreographer在收到Vsync信号时,调用用户设置的回调函数。函数的先后顺序如下:

CALLBACK_INPUT:与输入事件有关
CALLBACK_ANIMATION:与动画有关
CALLBACK_TRAVERSAL:与UI绘制有关

Vsync是什么呢?首先来说一下什么是FPS,FPS就是Frame Per Second(每秒的帧数)的缩写,我们知道,FPS>=60时,我们就不会觉得动画卡顿。当FPS=60时是个什么概念呢?1000/60≈16.6,也就是说在大概16ms中,我们要进行一次屏幕的刷新绘制。Vsync是垂直同步的缩写。这里我们可以简单的理解成,这就是一个时间中断。例如,每16ms会有一个Vsync信号,那么系统在每次拿到Vsync信号时刷新屏幕,我们就不会觉得卡顿了。

但实现起来还是有点困难的。


多重缓冲是什么技术呢?我们先来说双重缓冲。在Linux上,通常使用FrameBuffer来做显示输出。双重缓冲会创建一个FrontBuffer和一个BackBuffer,顾名思义,FrontBuffer是当前显示的页面,BackBuffer是下一个要显示的画面。然后滚动电梯式显示数据。为什么呢?这样好在哪里呢?首先他并不是不卡了,他还是会卡。但是如果是单重缓冲,页面可能会有这种情况:A面数据需要显示,然后是B面数据显示,B面数据显示需要耗费一定时间,但是这个时间里,C面数据也请求了展示,我们可能会看到,在展示C面数据的时候,还有B面数据的残影…

下面分情况来具体说明一下(Vsync每16秒一次)。

1.没有使用Vsync的情况

可以看出,在第一个16ms之内,一切正常。然而在第二个16ms之内,几乎是在时间段的最后CPU才计算出了数据,交给了Graphics Driver,导致GPU也是在第二段的末尾时间才进行了绘制,整个动作延后到了第三段内。从而影响了下一个画面的绘制。这时会出现Jank(闪烁,可以理解为卡顿或者停顿)。那么在第二个16ms前半段的时间CPU和GPU干什么了?哦,他们可能忙别的事情了。这就是卡顿出现的原因和情况。CPU和GPU很随意,爱什么时候刷新什么时候刷新,很随意。

2.有Vsync的情况

如果,按照之前的前提来说,Vsync每16ms一次,那么在每次发出Vsync命令时,CPU都会进行刷新的操作。也就是在每个16ms的第一时间,CPU就会想赢Vsync的命令,来进行数据刷新的动作。CPU和GPU的刷新时间,和Display的FPS是一致的。因为只有到发出Vsync命令的时候,CPU和GPU才会进行刷新或显示的动作。图中是正常情况。那么不正常情况是怎么个情况?我们先来说一下双重缓冲,然后再说。

3.双重缓冲

逻辑就是和之前一样。多重缓冲页面在Back Buffer,然后根据需求来显示不同数据。但是会有什么问题呢(这就是2中提到的问题)?

首先我们看Display行,A页面需要了两个时间单位,为什么?因为B Buffer在处理的时候太耗时了。然后导致了,在第一个Vsync发出的时候,还在GPU还在绘制B Buffer。那么,刚好,第一个Vsync发出之后很短的时间,A页面展示完了,B Buffer的也在一开始的时候就不进行计算了。那么接下来的时间呢?屏幕还是展示着B Buffer,这时候就会造成Jank现象。他不会动,因为他在等下一个Vsync过来的时候,才会显示下一个数据。

那么,如图,在A Buffer过来的时候,展示B页面的数据。这个时候!重复了上一个情况,也是太耗时了,然后又覆盖了下一个Vysnc发
出的时间,再次造成卡顿!依次类推,会造成多次卡顿。这个时候就有了三重缓冲的概念。

4.三重缓冲

首先看图。我们看到,B Buffer依旧很耗时,同样覆盖了第一个Vsync发出的时间点。但是,在第一个Vsync发出的时候,C Buffer站了出来,说,我来展示这个页面,你去缓冲A后面需要缓冲的页面吧!然后会发生什么?然后就是出现了一个Jank…,但是这个Jank只在这一个时间单位出现,是可以忽略不计的。因为之后的逻辑都是顺畅的了。依次类推,除了A和B 两个图层在交替显示,还有个“第三者”在不断帮他们两个可能需要展示的数据进行缓冲。但是注意了:

只有在需要时,才会进行三重缓冲。正常情况下,只使用二级缓冲!

另外,缓冲区不是越多越好。上图,C页面在第四个时间段才展示出来,就是因为中间多了一个Buffer(C Buffer)来进行缓冲。

但是,虽然谷歌给了你这么牛逼的前提逻辑,实际开发中你写的APP还是会卡,为什么呢?原因大概有两点:

1.界面太复杂。

2.主线程(UI线程)太忙。他可能还在处理用户交互或者其他事情。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/2883.html

相关文章

  • Android绘制优化(一)绘制性能分析

    摘要:绘制原理绘制有三个主要的步骤,分别是和。过度绘制,导致某些像素在同一帧时间内被绘制多次。是中新增的性能数据采样和分析工具。有了这些总体的分析,方便开发者对该时间段的绘制性能有一个整体的大概了解,便于进行下一步分析。前言 一个优秀的应用不仅仅是要有吸引人的功能和交互,同时在性能上也有很高的要求。运行Android系统的手机,虽然配置在不断的提升,但仍旧无法和PC相比,无法做到PC那样拥有超大的...

    番茄西红柿 评论0 收藏0
  • 那些年我们用过的显示性能指标

    摘要:若某个的合成不在中进行如,则该的显示性能无法用这类指标进行衡量。我们再来仔细瞧瞧给出的显示性能测试的十全大补丸。通过这条命令,我们获取每一帧绘制过程中每个关键节点的耗时情况,从而仔细的分析潜在的性能问题。 前言 注:Google 在自己文章中用了 Display Performance 来描述我们常说的流畅度,为了显得有文化,本文主要用显示性能一词来代指流畅度(虽然两者在概念上有细微差...

    Forest10 评论0 收藏0
  • 浅谈移动端 View 的显示过程

    摘要:被电子束轰击的每个位置,荧光层都会产生一个小亮点,最终小亮点们将会组成一幅幅影像,显示在电视屏幕上。下图展示的是摄像机慢放后,电子束的绘制过程。未来,个推技术团队将继续关注移动端的性能优化,为大家分享相关的技术干货。 作者:个推安卓开发工程师 一七 随着科技的发展,各种移动端早已成为人们日常生活中不可或缺的部分,人们使用移动端产品工作、社交、娱乐……移动端界面的流畅性已经成为影响用户...

    Zhuxy 评论0 收藏0
  • 浅谈移动端 View 的显示过程

    摘要:被电子束轰击的每个位置,荧光层都会产生一个小亮点,最终小亮点们将会组成一幅幅影像,显示在电视屏幕上。下图展示的是摄像机慢放后,电子束的绘制过程。未来,个推技术团队将继续关注移动端的性能优化,为大家分享相关的技术干货。 作者:个推安卓开发工程师 一七 随着科技的发展,各种移动端早已成为人们日常生活中不可或缺的部分,人们使用移动端产品工作、社交、娱乐……移动端界面的流畅性已经成为影响用户...

    李世赞 评论0 收藏0
  • 浅谈移动端 View 的显示过程

    摘要:被电子束轰击的每个位置,荧光层都会产生一个小亮点,最终小亮点们将会组成一幅幅影像,显示在电视屏幕上。下图展示的是摄像机慢放后,电子束的绘制过程。未来,个推技术团队将继续关注移动端的性能优化,为大家分享相关的技术干货。 作者:个推安卓开发工程师 一七 随着科技的发展,各种移动端早已成为人们日常生活中不可或缺的部分,人们使用移动端产品工作、社交、娱乐……移动端界面的流畅性已经成为影响用户...

    LiangJ 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<