这里的过程是这样的,Native中先创建一个SurfaceComposerClient,调用createSurface得到一个SurfaceControl对象,调用
writeToParcel写入parcel包,readFromparcel根据信息包构造一个surface,调用Surface的lock,UI画图,调用unlockAndPost释放锁。
Surface相关基础:
FrameBuffer截屏。
PageFlipping 画面交换,分配一个能容纳两帧数据的缓冲,第一个为FrontBuffer,后一个叫BackBuffer。消费者使用
FrontBuffer,生产者填充BackBuffer,更新时,Back变为Front,Front变为Back。
图像混合:
软件层面:使用copyBlt进行源数据和目标数据的混合
硬件层面:使用Overlay系统提供的接口。
SurfaceComposerClient分析:
在SurfaceSeesion_init函数中,new 出了一个SurfacecomposerClient对象,该对象调用了
_init(sm,sm->createConnection)函数,createConnection中创建了一块共享内存,为Surface的ControlBlock对象,这个对象为sharedclient对象,该对象有一个SharedBufferStack数组。
SurfaceFlinger的一个Client分配一个跨进程的SharedClient共享对象,有31个shareBufferStack元素,每一个元素对应一个显示层。
一个显示层创建两个Buffer,pageFlipping基于这两个Buffer展开。
SurfaceControl分析:
调用createSurface创建SurfaceControl,这里面有一个DisplayID为屏幕编号,目前Android只支持一块屏幕,所以为0,利用Binder通信将请求发送给SurfaceFlinger,最终在SF的createSurface创建了一个ISurface对象,这个对象里面创建的是Normal类型的显示层,或者Blur类型的显示层,或者Dim类型的显示层,类型为LayerBaseClient,创建该显示层时,会创建一个layer类型的对象,调用layer的setBuffer函数会创建一个GraphicBuffer缓冲数组,元素个数为2,即FrontBuffer和BackBuffer,
再调用
Surfacecontrol的构造,参数有Isurface。
Layer的家族介绍:
LayerBaseClient从LayerBase类派生
LayerBaseClient有四个派生类,分别是Layer、LayerBuffer、Layerdim和LayerBlur(这里创建了SharedBufferServer,控制shareBufferStack数组)
LayerBaseClient定义了一个内部类surface,从ISurface派生,支持Binder通信
Layer和LayerBuffer分别有一个内部类SurfaceLayer和SurfaceLayerBuffer,继承了LayerBaseclient的
surface类。而LayerDim和LayerBlur直接使用LayerBaseclient的surface。
关于SurfaceControl:
有一个成员变量mclient,指向SurfaceComposerClient
mSurface为Binder通信端的SurfaceLayer
mSurface有一个mOwner变量指向Layer,而Layer有一个成员变量mSurface指向SurfaceLayer。这个SurfaceLayer对象由getSurface返回。
SurfaceControl的writeToParcel函数,传递mClient信息和ISurface信息,发往Activity端。readFromParcel根据写入的Parcel包构造一个Surface对象,new Surface 的时候,构造了shareBufferClient。在Native端的Surface构造中,定义了一个mBuffers变量,也是一个GraphicBuffer数组,Bp端的。
lockCanvas分析:
通过这个函数得到一块存储空间,也就是BackBuffer。该函数最终调用Surface的lock函数。
lock函数调用dequeueBuffer得到一个空闲缓冲队列,第一次调用时调用getBufferLocked,该函数调用ISurface的requestBuffer函数,而ISurface实际上是Layer类中的SurfaceLayer,得到指定索引index的Buffer,再调用lockBuffer,最后调用copyBlt拷贝旧数据,把frontBuffer的数据拷贝到backBuffer中,解决了只更新改变的UI部分。
unlockCanvasAndPost分析:
调用queueBuffer,更新新数据的缓冲加入空闲缓冲队列,保存新的队列到mPostedBuffer中,后续更新只要更新
shareBufferClient的脏区域即可。
GraphicBuffer分析:
无参的构造函数没有分配存储内存,在reallocate函数中,GraphicBufferAllocator的alloc函数分配内存,该函数在创建时,会调用hw_get_module取出一个hw_module_t类型的对象,与硬件平台有关,会加载一个叫“libgralloc.硬件平台名.so”的动态库。这个库为了分配一块用于显示的内存,封装成这样的目的就是为了屏蔽不同硬件平台的差别。这里分析硬件无关的分配方式,由于GraphicBuffer从Flattenable类派生,当响应端write包信息的时候,会调用Flattenable的flatten函数,接收端read包时,会调用Flattenable的unflatten函数,该函数根据parcel包中的native_handle信息,构造一个对等的GraphicBuffer,并返回这块内存的文件句柄,这样Native Surface端的GraphicBuffer和layer中的GraphicBuffer管理同一块内存。
RegisteBuffer会根据unflatten函数返回的文件句柄对它进行内存映射。
SurfaceFlinger分析:
SurfaceFlinge继承Thread,会单独启动一个工作线程。Run函数在OnFirstRef中进行的,这个线程的触发在ReadyToRun中,调用SurfaceFlinger的readyToRun函数,这个函数有一个GraphicPlane,是屏幕在SF中的对应物,调用setDisplayHardware,把代表显示设备的HAL对象和GraphicPlane关联起来。接着new出一个DisplayHardware,这个函数的构造中会创建FrameBuffer,将Surface传输的数据通过GraphicBuffer混合后,再由自己传输到FrameBuffer中显示。
SF的工作线程是用来做图像混合的,threadLoop中:
waitForEvent首先等待重绘消息,这个消息在unlockCanvasAndPost函数中调用signal后收到。
handlePageFlip函数中调用lockPageFlip根据FrontBuffer的内容生成一张OpenGL的纹理,即图片
handleRepaint调用composeSurface函数在脏区域进行绘制,按Z轴的顺序从里到外依次绘制,调用各个显示层layer的draw函数,函数实现在LayerBase类中。
unlockClient释放之前占着的FrontBuffer的索引号,再调用postFrameBuffer,将图像传到屏幕中显示,flip函数在DisplayHardware类中完成。
Transact分析:
以WindowManagerService的createSurfaceLocked函数为例:
openTransact调用了SurfaceComposerClient的openTransaction,打开事务,里面有一个gOpenTranscations对象,是一个全局变量,用来存储当前提交事务请求的Client,layer_state_t是用来保存Surface信息的。
SetPosition改变Surface在屏幕上的位置,即修改layer_state_t里的值。
closeTransaction一次性的将这些修改提交给SurfaceFlinger。首先调用SF的openGlobalTransaction,再调用SurfaceComposerClient的closeTransaction,遍历所有Layer显示层,会触发threadLoop的waitForEvent事件。最后调用SF的CloseGlobalTransaction,如果涉及尺寸调整,则在这里设置一个等待。
工作线程的事务处理,重要的在handleTransaction中,每个显示层对事务的具体处理,都在他们的doTransaction函数中,最后调用commitTransaction函数提交事务,该函数boardcast会触发一个条件变量,使SF中的CloseGlobalTransaction返回。