https://wenku.baidu.com/view/7ff097d4f7ec4afe04a1dfc8.html
最上面一层为应用程序,根据数据类型以及应用的不同可以分为几种。
第一种是最普通的应用,如 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. 客户端显示系统的创建和初始化
客户端的最上层为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来进行需要的操作。
其初始化流程如下图所示:
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交互。
2.2.2 SurfaceControl
Surface_init调用SurfaceComposerClient::createSurface创建一个Surface,可却返回了一个SurfaceControl,
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 上的一系列画图之类的操作。
因为SurfaceFlinger 要管理多个应用程序的多个窗口界面,为了进行管理它提供了一个Client 类,每个来请求服
务的应用程序就对应了一个Client。因为surface 是在SurfaceFlinger 创建的,必须返回一个结构让应用程序知道自己
申请的surface 信息,因此SurfaceFlinger 将Client 创建的控制结构per_client_cblk_t 经过BClient 的封装以后返回给
SurfaceComposerClient ,并向应用程序提供了一组创建和销毁surface 的操作
为应用程序创建一个 Client 以后,下面需要做的就是为这个 Client 分配 Surface , Flinger 为每个 Client 提供了
8M 的空间 ,包括控制信息和存储内容的 buffer 。在说创建 surface 之前首先要理解 layer 这个概念,实际上每个窗
口就是 z 轴上的一个 layer , layer 提供了对窗口控制信息的操作,以及内容的处理 ( 调用 opengl 或者 skia),可以
理解为创建一个 Surface 就是创建一个 Layer 。最后应用程序会根据返回来的 ISurface 信息等创建自己的一个
Surface 。
3.2 SurfaceFlinger的处理过程
SurfaceFlinger这个服务在创建的时候会启动一个监听的线程,这个线程负责每次窗口更新时候的处理,大致就
是下面的这个图:
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 内显示了。