framework之深入surface系统

一个Activity的显示:

创建Activity

a:performLaunchActivity:根据类名通过java反射机制创建一个Activity。
调用Instrumentation的newActivity,调用attach函数:
PolicyManager的makeNewWindow,创建window对象,返回的mWindow是一个PhoneWindow对象。
windowManager的setWindowManager,由父类window实现,实际上是LocalWindowManager,具体实现在WindowManagerImpl中,采用了委托(Proxy)模式,再调用Activity的Oncreate函数,开始Activity的生命周期。
调用setContentView设置UI外观时,调用installDecor,generateDecor函数创建mDecor,为DecorView类型,从FrameLayout派生。这里设置的其实是DecorView的子View,DecorView还处理了标题栏等一系列工作。

b:handleResumeActivity

关键点在于addView函数,具体实现在WindowManagerImpl中。这里创建了一个ViewRoot,以及setView。
ViewRoot中调用IWindow的getWindowSession函数,调用openSession,得到一个IWindowSession对象。
setView中主要有两个函数:
requestLayout,往handler中发送了一个DO_TRAVERSAL的消息,收到消息后调用performTraversals函数,该函数调用IWindowSession的relayout,以及ViewRoot的draw函数,整个绘图是在这个draw函数中完成的。主要从mSurface中lock出一块
Canvas,然后交给mView去自由发挥画画的才能,最后unlockCanvasAndPost释放这块Canvas,屏幕马上就有显示了。
IWindowSession的add函数,也就是WindowManagerService的addWindow函数,实现了与WindowManagerService的交互。

初识Surface

在WindowmanagerImpl中实现addView时,ViewRoot的变量中有surface,new surface无参构造,调用openSession,new出一个session。接着setView中调用IWindowSession的add函数,new出一个surfaceSession对象,以及requestLayout函数,发出消息,收到消息后,调用IWindowSeesion的relayout函数,调用WindowManagerService的relayoutWindow函数,该函数创建一个本地的surface对象,再将本地对象拷贝到ViewRoot中的变量surface中,这里本地的surface对象是一个有参的构造。
aidl揭秘:Native层的实现:这里为一个Bp端,transact给服务端一个为null的surface,Bn服务端new出一个新的surface,调用writeToPacel函数传给Bp端,Bp端调用readFromParcel读取信息,得到一个Native的surface对象。

Surface和画图:

    lockCanvas 获得一块存储区域,然后将它和Canvas绑定在一起,这样,UI绘画的结果就记录在这块存储区域里了。
这里的过程是这样的,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返回。





你可能感兴趣的:(framework之深入surface系统)