1. android显示系统整体框架

8fffe57689cbb8d4bed8bbf0b0856e5d.png

最上面一层为应用程序,根据数据类型以及应用的不同可以分为几种。

第一种是最普通的应用,如UI界面的显示,这部分通常数据类型为RGB格式,数据无须再经过特殊的处理。该

应用可以说遍布各个应用程序,几乎是实时存在的。一般是通过Open GL渲染到framebuffer然后通过lcd显示输出。

第二种是针对大块YUV数据的应用,如camera的preview、视频的播放等。该应用只针对特定的应用程序,一

般是通过Hwcomposer直接将YUV数据送到内核通过硬件输出显示。

第三种其实和第一种类似,只不过由于应用的需求在显示之前需要对数据进行2D、3D的处理(使

用OpenGL、OpenVG、SVG、SKIA),处理之后的流程和普通的显示就没什么差别了。一般在Game、地

图、Flash等应用中会用到。

应用之下是服务的framework,其中最核心的就是surfaceflinger了,它为所有的应用程序的显示提供服务。

OpenGL主要用来compose surface和2D、3D的图形处理。通过OpenGL来处理的主要是UI、Game、地

图、Flash等应用。

Hwcomposer主要用在视频方面,通过直接将YUV的视频数据直接输出显示,如camera的preview、视频的播

放。

DisplayDispatcher用于获取和设置显示的配置参数,如获取hdmi和tv的热拔插状态,然后根据获取到的状态设置从

hdmi还是tv输出等。

服务的framework最底下是硬件抽象层,用于抽象各个厂商的硬件细节,为硬件抽象层的上一层提供共用的接

口。

2. 客户端显示系统的创建和初始化

0cc991a53e2e15a7df8e14f2550c2826.png

客户端的最上层为java的应用,一般apk的开发都在这一层,往下是java框架和JNI。

java框架文件路径是:frameworks/base/core/java/android/view/Surface.java,该文件中的接口会被应用间接调用,同

时会调用JNI。

JNI文件路径是:frameworks/base/core/jni/android_view_Surface.cpp,里面的接口大概分为2类,一类是负责管

理binder通信的;另一类才是和显示控制相关的,第二类接口会直接调用Native Surface。

Native Surface文件路径是:frameworks/base/libs/ui/Surface.cpp

2.1 SurfaceSession操作

android_view_Surface.cpp中,此文件主要包含以下两部分给Java层调用:

1)gSurfaceSessionMethods:操作SurfaceSession的方法,主要是创建和销毁SurfaceComposerClient。

2)gSurfaceMethods:操作Surface的方法,通过SurfaceComposerClient与SurfaceFlinger的Client进行Binder通信,实

现对服务端的Surface的操作。

2.1.1 SurfaceSession_init

其功能如下:

1)创建SurfaceComposerClient对象

2)调用SurfaceComposerClient::onFirstRef方法

SurfaceComposerClient是一个进行Surface合成的客户端,通过它发命令给SurfaceFlinger来进行需要的操作。

其初始化流程如下图所示:

57c18496cc9607da548dde9589ca984c.png

2.1.2 Composer

Composer管理每个SurfaceComposerClient中的每一个Surface的状态,如位置、Z序和屏幕方向等,并记录在

ComposerState的layer_state_t中,然后调用者可以调用其closeGlobalTransaction方法把这些mStates发送给SurfaceFlinger

处理(处理函数为:SurfaceFlinger::setTransactionState)。

2.1.3 ComposerService

用于从SurfaceFlinger中获取Service以建立连接关系,然后供后面进行相关的操作,ComposerService主要是获取

SurfaceFlinger服务、获取在SurfaceFlinger::readyToRun中创建的共享内存块及其基地址。在Client中,谁要想与

SurfaceFlinger通信,需要通过接口getComposerService来获取此BpSurfaceComposer。

2.1.4 SurfaceComposerClient

SurfaceComposerClient的功能:

1)获取BpSurfaceComposerClient(即mClient),在onFirstRef中实现

2)通过BpSurfaceComposerClient(即mClient)创建和销毁Surface

3)通过Composer来记录Surface和显示屏状态变化,及在Composer中通过BpSurfaceComposer把状态变化发给

SurfaceFlinger处理

2.2 Surface操作

2.2.1Surface_init调用流程

在SurfaceFlinger端创建BSurface,在客户端返回SurfaceControl,同时在SurfaceControl中拥有了BpSurface用于与

BSurface交互。

414acd08bc5363c7ce4b3b0c5d9e3560.png

2.2.2 SurfaceControl

Surface_init调用SurfaceComposerClient::createSurface创建一个Surface,可却返回了一个SurfaceControl,

7d5bf53bdce26f2fb7f9b54d057e1bc3.png

getSurface在客户端返回Surface(派生于SurfaceTextureClient),并在Surface的mSurfaceTexture域中保存了

BpSurfaceTexture。

3. SurfaceFlinger

SurfaceFlinger只是负责merge Surface的控制,比如说计算出两个Surface重叠的区域,至于Surface需要显示的内

容,则通过skia,opengl和pixflinger来计算。

3.1 SurfaceFlinger的创建过程

每个应用程序可能有一个或者多个Surface,我们需要一些数据结构来存储我们的窗口信息,我们还需要buffer来

存储我们的窗口内容,下面的Surface创建过程的类图:

在IBinder左边的就是客户端部分,也就是需要窗口显示的应用程序,而右边就是我们的SurfaceFlinger service。

创建一个surface分为两个过程,

一个是在SurfaceFlinger这边为每个应用程序(Client)创建一个管理结构

另一个就是创建存储内容的buffer ,以及在这个buffer 上的一系列画图之类的操作。

0b5496216bedfbeeacf41325dd9b0fef.png

因为SurfaceFlinger 要管理多个应用程序的多个窗口界面,为了进行管理它提供了一个Client 类,每个来请求服

务的应用程序就对应了一个Client。因为surface 是在SurfaceFlinger 创建的,必须返回一个结构让应用程序知道自己

申请的surface 信息,因此SurfaceFlinger 将Client 创建的控制结构per_client_cblk_t 经过BClient 的封装以后返回给

SurfaceComposerClient ,并向应用程序提供了一组创建和销毁surface 的操作

f378d43bf13af97fb843b6313e52f90d.png

为应用程序创建一个 Client 以后,下面需要做的就是为这个 Client 分配 Surface , Flinger 为每个 Client 提供了

8M 的空间 ,包括控制信息和存储内容的 buffer 。在说创建 surface 之前首先要理解 layer 这个概念,实际上每个窗

口就是 z 轴上的一个 layer , layer 提供了对窗口控制信息的操作,以及内容的处理 ( 调用 opengl 或者 skia),可以

理解为创建一个 Surface 就是创建一个 Layer 。最后应用程序会根据返回来的 ISurface 信息等创建自己的一个

Surface 。

6d4fc26c1fc86b6bd92035685ced5a11.png

3.2 SurfaceFlinger的处理过程

SurfaceFlinger这个服务在创建的时候会启动一个监听的线程,这个线程负责每次窗口更新时候的处理,大致就

是下面的这个图:

6e166dc9899975f92857e2d850815a64.png

3.2.1 handleTransaction

Layer列表的这些状态的变化,计算是否有可见区域内需要更新,并设置状态变量mVisibleRegionsDirty,然后把mCurrentState赋值给mDrawingState,最后释放已经被丢弃的Layer

3.2.2 handlePageFlip

这里会处理每个窗口surface buffer之间的翻转,根据layer_state_t的swapsate来决定是否要翻转,当swapsate的值是eNextFlipPending是就会翻转。处理完翻转以后它会重新计算每个layer的可见区域。

3.2.3 handleRepaint

计算出每个layer的可见区域以后,这一步就是将所有可见区域的内容画到主layer的相应部分了,也就是说将各个surfacebuffer 里面相应的内容拷贝到主layer相应的buffer。

3.2.4 postFrameBuffer

最后的任务就是翻转主layer的两个buffer,将刚刚写入的内容放入FB内显示了。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐