赞
踩
Android 的显示过程可以简单概括为:Android 应用程序把经过测量、布局、绘制后的surface 缓存数据,通过 SurfaceFlinger 把数据渲染到显示屏幕上,通过 Android 的刷新机制 来刷新数据。也就是说应用层负责绘制,系统层负责渲染,通过进程间通信把应用层需要 绘制的数据传递到系统层服务,系统层服务通过刷新机制把数据更新到屏幕。 通过阅读 Android 系统的源码可以了解显示的流程,Android 的图形显示系统采用的是 Client/Server 架构。SurfaceFlinger(Server)由 C++代码编写。Client 端代码分为两部分,一 部分是由 Java 提供给应用使用的 API,另一部分则是由 C++写成的底层具体实现。
绘制任务是由应用发起的,最终通过系统层绘制到硬件屏幕上,也就是说,应用进程绘 制好后,通过跨进程通信机制把需要显示的数据传到系统层,由系统层中的 SurfaceFlinger 服务绘制到屏幕上。那么应用层和系统层中的流程是什么样的呢?
1、应用层
(1)Measure 用深度优先原则递归得到所有视图(View)的宽、高;获取当前 View 的正确宽度 childWidthMeasureSpec 和高度 childHeightMeasureSpec 之后,可以调用它的成员函数 Measure 来设置它的大小。如果当前正在测量的子视图 child 是一个视图容器,那么它又会 重复执行操作,直到它的所有子孙视图的大小都测量完成为止。
(2)Layout 用深度优先原则递归得到所有视图(View)的位置;当一个子 View 在应用程序窗口左 上角的位置确定之后,再结合它在前面测量过程中确定的宽度和高度,就可以完全确定它在 应用程序窗口中的布局。
(3)Draw 目前 Android 支持了两种绘制方式:软件绘制(CPU)和硬件加速(GPU),其中硬件加 速在 Android 3.0 开始已经全面支持,很明显,硬件加速在 UI 的显示和绘制的效率远远高于 CPU 绘制,但硬件加速并非如大家所想的那么完善,它也存在明显的缺点: ·耗电:GPU 的功耗比 CPU 高。 ·兼容问题:某些接口和函数不支持硬件加速。 ·内存大:使用 OpenGL 的接口至少需要 8MB 内存。 所以是否使用硬件加速,需要考虑一些接口是否支持硬件加速,同时结合产品的形态和 平台,比如 TV 版本就不需要考虑功耗的问题,而且 TV 屏幕大,使用硬件加速容易实现更 好的显示效果。
2、系统层
真正把需要显示的数据渲染到屏幕上,是通过系统级进程中的 SurfaceFlinger 服务来实 现的,SurfaceFlinger 的主要工作如下:
既然是两个不同进程,那么肯定需要一个跨进程的通信机制来实现数据传输,在 Android 的显示系统,使用了 Android 的匿名共享内存:SharedClient,每一个应用和 SurfaceFlinger 之间都会创建一个 SharedClient,如下图所示。从图中可以看出,在每个 SharedClient 中,最多可以创建 31 个 SharedBufferStack,每个 Surface 都对应一个 SharedBufferStack,也 就是一个 window。 一个 SharedClient 对应一个 Android 应用程序,而一个 Android 应用程序可能包含多个窗 口,即 Surface。也就是说 SharedClient 包含的是 SharedBufferStack 的集合。因为最多可以创 建 31 个 SharedBufferStack,这也意味着一个 Android 应用程序最多可以包含 31 个窗口,同 时每个 SharedBufferStack 中又包含了两个(低于 4.1 版本)或者三个(4.1 及以上版本)缓 冲区,刷新机制中的双缓冲和三重缓冲技术。
最后总结起来显示整体流程分为三个模块:应用层绘制到缓存区,SurfaceFlinger 把缓存 区数据渲染到屏幕,由于是两个不同的进程,所以使用 Android 的匿名共享内存 SharedClient 缓存需要显示的数据来达到目的。 SurfaceFlinger 把缓存区数据渲染到屏幕(流程如下图所示),主要是驱动层的事情,这 里不做太多解释。
从图中可以看出,绘制过程首先是 CPU 准备数据,通过 Driver 层把数据交给 CPU 渲 染,其中 CPU 主要负责 Measure、Layout、Record、Execute 的数据计算工作,GPU 负责 Rasterization(栅格化)、渲染。由于图形 API 不允许 CPU 直接与 GPU 通信,而是通过中间 的一个图形驱动层(Graphics Driver)来连接这两部分。图形驱动维护了一个队列,CPU 把 display list 添加到队列中,GPU 从这个队列取出数据进行绘制,最终才在显示屏上显示出来。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。