刷新机制_Framework深入探索之 UI刷新机制

本文详细探讨了Android系统的屏幕刷新流程,包括屏幕图像缓存、屏幕周期刷新、Surface绘制原理以及Vsync信号机制。解释了如何避免丢帧,阐述了Android刷新频率与onDraw方法的关系,以及Surface在跨进程传递中的作用。通过对这些概念的解析,有助于深入理解Android UI的刷新机制。
摘要由CSDN通过智能技术生成

67426a1e7eb4e86514a3e07b050c2b27.png

屏幕刷新机制

与屏幕刷新相关的有很多,比如刷新流程,屏幕缓存,周期刷新,vsync信号,SurfaceFlinger,接下来就一个个讨论具体的内容,并根据具体的内容,提出一些问题,做简单的解答

屏幕刷新流程

首先应用会向系统服务申请buffer,然后系统服务返回buffer,应用绘制后提交buffer给系统服务,系统服务再将buffer写入到屏幕缓冲区中,屏幕会以一定的帧率去刷新,从buffer中读取图像数据显示出来,buffer中没有新的图像数据,那么屏幕就会用老的数据,这样屏幕看起来就没有变化。

屏幕图像缓存

图像缓存不止有一个,因为假如只有一个缓存,系统服务向缓存写入数据,屏幕又读取缓存,这样屏幕就会一下子显示第一帧,一下子显示第二帧。可以申请两个缓存,如果要显示下一个缓存,可以进行缓存交换

屏幕周期刷新

屏幕周期刷新,根据vsync信号,每次根据信号,收到信号从缓存区中获取图像绘制,vsync信号是脉冲信号。

这里谈到到周期刷新,我们在进行view绘制的时候,会调用requestLayout进行重走一下measure,Layout,onDraw,那么此时调用10次requestLayout,会进行10次重绘吗 答案是当然不会,因为如果调用10次requestLayout,那么在下次vsync信号来的时候并不会触发10次ui重绘,在vsync周期中,只会触发一次界面重绘。

那绘制原理是什么呢,下面来具体讨论一下绘制原理

首先应用层的view调用requestLayout要进行重绘,其实通过callback新建一个runnable对象放入choreographer队列中,并没有马上处理这个消息,它首先向SurfaceFlinger请求下一个vsync信号,调用的就是requestNextVsync函数,然后SurfaceFlinger就会在下一个vsync信号来的时候,通过postSyncEventchoreographe发送一个通知,choreographe收到通知,就会处理消息队列中的消息,调用performTraversal进行重绘

总结

屏幕刷新流程,屏幕图像缓存,周期性刷新都讨论过了,还剩下vsync信号与SurfaceFlinger,剩下的在下面讨论,这时候针对之前的屏幕刷新机制,在来讨论几个问题

丢帧一般什么原因引起的

耗时操作,耽误view绘制

Android刷新频率60帧/秒,每个16ms调用onDraw方法?

刷新屏幕指的是vsync信号的屏幕,但是不是每次vsync都去绘制,需要应用发起重绘,向SurfaceFlinger请求vsync信号,这样在下一次vsync信号来的时候,才会进行绘制

onDraw完后屏幕会马上刷新吗

屏幕并不会立即刷新,需要等到下次vsync信号来的时候才会进行刷新

如果界面没有重绘,还会每隔16ms刷新屏幕吗

如果界面没有进行重绘,并不会收到vsync信号进行重绘,但是屏幕还会每隔16ms进行重绘,不过用的数据是旧图像数据,看起来屏幕没有变化

如果在屏幕快要刷新的时候才会去绘制会丢帧吗

不会丢帧,调用重绘,并不会马上执行,只是等到下次vsync信号来的时候才会执行,所以什么时候发起绘制操作没有太大关系,并不会丢帧

Surface 绘制原理

上面讨论了屏幕刷新大致流程,接下来说下与屏幕相关的Surface绘制原理 那什么是Surface绘制,具体都做了哪些操作呢,绘制原理如下

应用需要绘制,首先创建Surface,但Surface需要buffer,它需要在SurfaceFlinger中创建BufferQueue,这个BufferQueue中有很多buffer,每个buffer对应一个Surface,buffer有两端,一个producer端,一定要跨进程传回给Surface进行保管 ,另一个consumer端,Surface要进行绘制,需要通过producer端进行bind调用,向BufferQueue中申请一块buffer,绘制完成后返回给BufferQueueBufferQueue就会通知consumer端回调,表示又有一帧数据好可以,用来消费这一帧数据

其实Surface中有两个buffer,一个是前台用来显示的buffer,另一个是用来绘制的后台buffer,互不影响,后台绘制好后切换到前台进行显示

说道Surface的buffer,那不得不谈一谈buffer相关内容

Surface绘制的buffer怎么来的

通过GraphicBufferProducer向buffer申请

buffer绘制完了又是怎么提交的

通过GraphicBufferProducer向buffer进行提交的

怎么理解Surface,它是一块buffer吗

它不是buffer,只是一个壳子,内部包含可以生产buffer的对象,就是GraphicBufferProducer

Surface 跨进程传递

Surface还可以进程跨进程传递数据

Surface到底是怎么跨进程传递的

是传递GraphicBufferProducer对象

Activity的Surface是怎么跨进程传递的

activity在第一次进行绘制的时候会在performTraversals中申请Surface

Activity的Surface在系统中创建后,是怎么跨进程传回应用的?

系统中创建是SurfaceControl对象,并不是Surface对象,SurfaceControl中有GraphicBufferProducer,就可以创建Surface,然后返回给应用

Vsync 机制

最后再说一下vsync机制相关内容

Vsync信号的生成机制

通过接口回调给上层

Vsync在SurfaceFlinger中分发流程

一种通过HWComposer进程硬件生成,另一种通过VsyncThread进行软件生成。都是分发给DispSyncThread工作线程。这个工作线程又会分发给app-EventThread(App进程)线程,另一个是sf-EventThread(SurfaceFlinger自己使用)

Vsync信号分发原理

一方面分发个应用进程,另一方面分发给SurfaceFlinger。主要是因为一方面通知应用进行绘制UI,另一个方面通知SurfaceFlinger对图像进行合成与渲染操作。分开分发避免同时抢占CPU资源

总结

学习完以上内容,我们对整个UI刷新流程,及刷新涉及的相关知识点,有了一定的了解,以上内容只是大致给出了结论,我们再通过阅读相关源码,将会对整个UI刷新有了更深的认识

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值