Android 图形系统-图解和初步探究_猎羽的博客-CSDN博客https://blog.csdn.net/feather_wch/article/details/131486729
Android图形系统
2023-7-1
问题:如何将一帧画面显示到屏幕上?
绘制流程
Activity代码
Window的结构
绘制流程
Activity启动后,不会立即绘制,而是在下一个VSYNC到来时,触发绘制performTraversals
ViewRoot是什么?
图像绘制到屏幕完整流程
VSYNC信号
Buffer
显示屏上的内容,是从硬件帧缓冲区读取的,大致读取过程为:从Buffer的起始地址开始,从上往下,从左往右扫描整个Buffer,将内容映射到显示屏上
屏幕上的内容需要需要不断的更新,如果在同一个Buffer进行读取和写入(合成)操作,将会导致屏幕显示多帧内容。所以硬件层除了提供一个Buffer用于屏幕显示,还提供了一个Buffer用于后台的图形合成,也就是我们常说的双缓冲:
上图中包含两个缓冲区:
前缓冲区:用来显示内容到屏幕的帧缓冲区
后缓冲区:用于后台合成下一帧图形的帧缓冲区
正常渲染过程
画面撕裂
VSYNC意义
Janky Frame
1、缓存区backBuffer用于CPU/GPU图形处理
2、缓存区TripleBuffer用于CPU/GPU图形处理
3、缓存区frameBuffer用于显示器显示
VSYNC信号是如何产生的?
收到vsync events的汇集到了两个地方:
1. MessageQueue::vsyncCallback ==> VSYNC-sf
2. EventThread::onVSyncEvent ==> VSYNC-app & VSYNC-appSf
Surface
Surface的创建
Surface建立关系
获取画布Canvas(软解)
帧的绘制(硬解)
ThreadedRenderer 管理所有的硬件渲染对象,是ViewRootImpl进行硬件渲染的入口对象 RenderNode 和View一一对应,硬件渲染打开时,放入渲染逻辑,内部是DisplayList RenderNode会构成View树 DisplayList View通过draw函数绘制的指令,以DisplayList的形式记录下来 内部节点是DisplayListData RecordingCanvas 绘图指令的记录员 将View通过draw函数绘制的指令以DisplayList的形式记录下来 CanvasContext 渲染上下文,内部持有Pipeline PipeLine 渲染管道 如OpenGLPipeLine,SkiaOpenGLPipeLine,VulkanPipeLine DrawFrameTask 整个ThreadedRender中真正开始执行渲染的对象
SurfaceFlinger
CPU/GPU执⾏⻆⾊划分关系:
第⼀步:CPU:Measure,Layout,纹理和多边形⽣成,发送纹理和多边形到GPU
第⼆步:GPU:将CPU⽣成的纹理和多边形进⾏栅格化以及合成
驱动SurfaceFlinger合成
该环节分为两个部分:
1、请求Vsync信号
准备更新显示画面或其它UI的信息变化时,首先调用MessageQueue::invalidate方法,其中会去请求一次vsync callback;
2、等待VSYNC
VSYNC机制会默默的等到时机到来时,回调MessageQueue::vsyncCallback;然后消息队列的处理机制就会dispatchInvalidate;最后调用到SurfaceFlinger::onMessageInvalidate去具体做事。
onMessageInvalidate
-->handleMessageInvalidate
-->handlePageFlip 将需要更新的Layer放入到集合中
-->signalRefresh向消息队列发送一次消息,消息到达时会去触发onMessageRefresh
onMessageRefresh
-->handleMessageRefresh
-->present(送显) 1.prepareFrame 2.finishFrame 3.postFramebuffer
-->postComposition-->releaseBuffer
参考文章:
Android 图形图像 - 随笔分类 - 二的次方 - 博客园 (cnblogs.com)