Vsync垂直同步信号分发和SurfaceFlinger响应执行渲染流程分析(一)

本文分析了Android系统中Vsync垂直同步信号的引入背景,以及如何解决界面错乱问题。通过硬件或软件产生Vsync信号,协调CPU、GPU和Display同步进行UI合成、渲染和显示。文章深入探讨了Vsync的产生过程,并介绍了在硬件支持时的注册回调机制,以及SurfaceFlinger在初始化中的角色。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     之前有一篇博客已经讲过一点Android应用程序和SurfaceFlinger建立连接,获取一个binder本地代理对象的过程,有了这个本地代理对象,应用程序就可以使用它调用SurfaceFlinger的UI合成、渲染功能了,可参考:Android Application与SurfaceFlinger连接过程分析,讲的很粗糙,但是我们可以看到一个大致过程,就是在WindowManagerService为每个Activity执行添加窗口addView方法时,创建好了WindowState对象,然后会调用win.attch()方法,和SurfaceFlinger取得连接也就是这个时候建立的。如果大家还想了解更细的话,可以参考老罗的博客:Android应用程序与SurfaceFlinger服务的连接过程分析,这里讲的非常详细。

     关于UI合成渲染这块的知识,用到的东西太多了,我也是平时看看书,查查百度,想尽量搞清楚一些,但是目前为止,还是只能了解的部分,无法从全面掌握,也是为了怕自己忘记,所以将自己学习到的总结出来,方便随时查阅,如果能给大家带来帮助,那就更好了。

     好了,我们进入正题,话说Android在4.1版本之前,UI界面方面存在很大的一个问题,就是经常会出现界面错乱,Google官方叫Jank,我们来看看下面这幅图:

绘制过程没有采用Vsync同步的情况

     从图上我们就很明显可以看出来问题产生的原因了,就是我们的CPU、GPU、Display三个器件需要进行配合对所有的UI进行合成、渲染、显示,但是之前的版本当中,没有一个统一的命令,导致CPU不知道何时开始执行合成,于是推迟了时间,后边的渲染和显示自然也就耽误了,那么就会出现数字1的画面显示了两帧,还有可能出现,数字1的一部分和数字2的一部分显示在同一界面上了,Google为了解决这个问题,所以加入了Vsync垂直同步信息,我们来看看加入了Vsync垂直同步信息后的情况:

加入了Vsync之后的情况

     从加入了垂直同步信号后的情况明显可以看出来,情况好了很多,由信号产生模块发出信号,只要信号发出,CPU马上进行合成,完成后交给GPU渲染,最后由Display进行显示,这样的话,就能很好的保证我们的界面显示问题了,当然,任何软件措施都无法保证100%的解决问题,但是从现在实际场景来看效果,确实还是非常满意的。

     现在呢,我们就来了解一下Vsync垂直同步信号。从上面的逻辑图当中,应该也很容易看出来,我们需要的是什么呢?就是一个信号产生器就OK了,由它产生信号,指挥CPU、GPU、Display三者对UI进行同步的合成,这样就够了,那么Google在提供这个功能的时候,提供了两种方式:一种是由硬件产生,一种是由软件产生。接下来我们就来看一下Vsync的生产过程,产生的代码在HWComposer.cpp当中,composer的英文意思就是设计者,看着这个名字都让我们非常清晰它的作用,这也是细节之处,高手写出来的代码,处处都是亮点,小到一个变量、一个方法的修饰词,大到一个类、项目框架,里边有很多值得我们学习的地方。下面我们来看一下这块的代码:     

HWComposer::HWComposer(
        const sp
    
     & flinger,
        EventHandler& handler)
    : mFlinger(flinger),
      mFbDev(0), mHwc(0), mNumDisplays(1),
      mCBContext(new cb_context),
      mEventHandler(handler),
      mDebugForceFakeVSync(false)
{
    for (size_t i =0 ; i
     
      > 24) & 0xff,
              (hwcApiVersion(mHwc) >> 16) & 0xff);
        if (mHwc->registerProcs) {
            mCBContext->hwc = this;
            mCBContext->procs.invalidate = &hook_invalidate;
            mCBContext->procs.vsync = &hook_vsync;
            
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

红-旺永福

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值