Android的UI渲染机制(二)

安卓系统中有 2 种 vsync 信号: 

(1)屏幕产生的硬件 vsync信号,主要用于通知应用程序开始在自己的窗口“画布”中执行一帧画面的绘制和渲染

(2)由SurfaceFlinger将其转成的软件 vsync 信号,经由 Binder 传递给 Choreographer。在该信号到来时执行合成,最终渲染至屏幕上。

        如果VSync到来时, 缓冲中的内容未准备好,就可能导致卡顿。所谓掉帧, 其实帧并未丢弃, 只是延迟显示。屏幕每收到vsync信号刷新一次, 但若当前绘制内容未准备好, 则显示上一次的内容。

        当界面有变化或者主动调用invalidate申请重绘, 会首先标记当前UI需要重新绘制,但绘制不是同步的,只有当下一次vsync信号到来时, 才会执行measure/layout/draw开始绘制。上屏幕则是收到下一个vsync信号时进行。

        如果CPU绘制的速率跟不上屏幕刷新速率,如果将部分绘制完成的内容就提交上屏,就会导致只显示部分画面的问题。

        为解决这一问题,Android引入了双缓冲策略, 即增加一个backing_buffer, 只有一帧完成渲染后, 才将内容从backing_buffer交换到frame_buffer。如下图所示。

       

        但双缓冲策略仍然存在一个缺陷,由于每次都是在收到下一个vsync信号才开始绘制, 一旦上一帧出现jank, 由于backing_buffer还在占用, 下一帧的绘制会被延迟到下下一个vsync开始。

        实际上,我们可以另外再开辟一个buffer,替代被占用的backing_buffer,下一帧仍然在vsync到来时就开始绘制,这就是三缓冲策略。

     

        三缓冲策略更加充分利用了CPU的计算能力,可以减少后续出现jank的几率。

相关推荐

  1. 深入理解浏览器页面渲染机制

    2024-03-15 03:14:04       44 阅读
  2. Android消息机制--Handler

    2024-03-15 03:14:04       50 阅读
  3. Android UI:ViewTree中事件传递

    2024-03-15 03:14:04       40 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-15 03:14:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-15 03:14:04       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-15 03:14:04       82 阅读
  4. Python语言-面向对象

    2024-03-15 03:14:04       91 阅读

热门阅读

  1. Winform程序中UI更新延迟

    2024-03-15 03:14:04       37 阅读
  2. 爬虫:爬取新闻内容及图片,存入数据库

    2024-03-15 03:14:04       44 阅读
  3. 怎样把1.ts-10.ts的文件拼接成一个MP4文件

    2024-03-15 03:14:04       47 阅读
  4. C语言统计书本借阅情况

    2024-03-15 03:14:04       38 阅读
  5. linuxi系统docker容器编排工具compose

    2024-03-15 03:14:04       42 阅读
  6. 记一次实战项目所学(通用接口篇)

    2024-03-15 03:14:04       39 阅读