第六篇 ANDROID窗口系统机制之显示机制与架构

本文深入剖析ANDROID的显示系统,重点解析视图如何绘制,包括窗口管理服务、视图树结构、硬件加速绘制过程。介绍了从主视图draw函数开始,如何根据硬件加速情况创建不同画布,以及硬件加速下DisplayList和HardwareLayer的绘制原理,提高视图显示速度。
摘要由CSDN通过智能技术生成

ANDROID的显示系统是整个框架中最复杂的系统之一,涉及包括窗口管理服务、VIEW视图系统、SurfaceFlinger本地服务、硬件加速等。窗口管理服务与SurfaceFlinger本地服务都属于系统服务,客户端采用远程代理模式访问服务,而这部分机制在上一篇博文《窗口管理服务实现机制》已经分析过,本篇主要解析视图如何绘制相关的部分。

窗口中显示的页面和控件以树的形式组织成一颗以主视图为根的视图树,系统要显示输出时统一调用主视图的draw函数,由主视图的draw函数负责各个子视图(如LayoutWidgets等)的递归绘制和效果处理。

 

 

主视图的draw 函数由ViewRootImpl对象的draw 函数调用,在draw 函数中根据硬件加速与否采用不同的方式创建不同的画布,并作为参数调用相同的相同的视图绘制函数(视图的draw接口)。

在硬件加速打开的情况下, 采用HardwareRenderer对象创建的画布进行硬件加速绘制,否则则采用ViewRootImpl对象对应的Surface对象创建的画布进行软绘制,画布由Surface对象的lockCanvas函数经过JNI调用获取绘制输出缓冲区后初始化一个bitmap,并赋值给Surface对象相关的Canvas对象中的mNativeCanvas然后返回Canvas对象。以后视图的绘制实际上是在Canvas对象的bitmap上绘制。

        在硬件加速的情况下绘制分两步,第一步是把视图的各种绘制函数作为绘制指令(包含操作指令和绘制参数)写到DisplayListRenderer对象的SkWriter32对象中,第二步是读取SkWriter32对象中保存的绘制指令调用OPENGL相关函数完成实际绘制。把视图的各种绘制函数翻译成绘制指令保存起来,可以达到重用的目的,在视图绘制过一次且没有或很少发生改变的情况下,在视图重绘时,可以重用原先DisplayListRenderer对象保存的操作指令,不用再按照原先复杂的操作顺序(每一步都需要经过JAVA对象的操作函数通过JNI调用C++本地对象的操作函数)继续重新绘制一遍,而只需对于发生改变的部分按照上面的顺序进行录制及绘制,而对于没有发生改变的视图把原先保存的操作指令重新读取出来重放一次就可以了,提高视图的显示速度。

       整个视图绘制相关的JAVA类图如下图:

     

视图绘制相关的对象主要由五个对象完成。视图(view)和画布(canvas)对象,视图在具体画布对象上完成各种绘制图形操作,根据不同需求视图绘制可以使用不同的画布对象(当前有三个具体的画布对象,两个硬件加速使用的继承于HardwareCanvasGLES20CanvasGLES20RecordingCanvas,不使用硬件加速的CompatibleCanvas)。通过使用抽象接口和桥接设计模式(Bridge模式)视图的绘制操作可以不管具体的具体画布对象是什么,也就是不论是否使用硬件加速与否,统一由一个绘制函数完成当前视图及子视图的递归绘制,只是根据函数参数传进去不同的画布对象。

另外三个对象是Gl20RendererGLES20DisplayListGLES20RenderLayer.

Gl20Renderer对象相当于硬件加速视图绘制模型的呈现引擎,负责整个与硬件加速相关的视图绘制过程,包括创建具体的DisplayListHardwareLayer对象,调用视图相关函数完成DisplayList命令的录制和在HardwareLayer上的绘制,DisplayList录制命令的重放及HardwareLayer在主显示缓冲区上的复合等工作。Gl20Renderer对象对应的画布为GLES20Canvas类型,在Gl20Renderer对象画布上的绘制实际绘制在OPENGL绘制上下文对应的主缓冲区上。Gl20Renderer派生自GlRenderer,GlRenderer又派生自HardwareRenderer。HardwareRenderer可以是说是DisplayListHardwareLayer<

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值