深入理解 Android:Surface 系统
FrameBufferDevice:
FrameBuffer就是存储图像帧数据的缓冲区;FrameBufferDevice是 Linux 平台的虚拟显示设备,为真实设备提供统一框架,这样应用层通过标准的ioctl、mmap系统调用就可以操作显示设备;FrameBuffer中的缓冲区就是通过mmap把设备中的显存映射到用户空间的:在这块缓冲区写数据,就相当于在屏幕上绘制;
Window 和 View:
Window是抽象基类,用于控制顶层窗口的外观和行为(背景、标题栏、默认按键处理等);View是基本的 UI 单元,占据屏幕一块矩形区域,用于绘制和事件处理;
ViewRoot:
ViewRoot继承自Handler(可处理消息),并实现了ViewParent接口(不处理绘制、没有onDraw());ViewRoot内部有一个IWindow.Stub对象(用于 Binder 通信)、View对象和Surface对象(用于View绘制,有一块 Raw buffer,可以和SurfaceFlibger交互);ViewRoot构造方法调用getWindowSession()将ViewRoot和WindowManagerService关联起来;ViewRoot::setView():将传入的
View指向PhoneWindow的DecorView;调用
requestLayout(), 向Handler发送DO_TRAVERSAL消息; 收到消息后调用IWindowSession的relayout(),调用
draw(),先从Surface中 lock 一块Canvas,然后让View绘制,最后调用unlockCanvasAndPost();调用
IWindowSession的add()方法,这是一个跨进程的 Binder 通信;
ViewRoot与其子View共用一个Canvas,但lockCanvas()得到的内存不同;它们一般也共用一个Surface(SurfaceView除外,它在单独线程绘制);
Activity 的创建:
Activity主线程ActivityThread类的handleLaunchActivity()方法用于创建Activity;用
ClassLoader和反射创建Activity对象,并调用其onCreate();调用
Activity的attach()方法,内部调用PolicyManager的makeNewWindow()方法创建PhoneWindow对象;调用
setWindowManager(),创建LocalWindowManager对象,内部保存WindowManager对象,而其实际类型为WindowManagerImpl;setContentView()设置的View其实是DecorView的子View;DecorView是FrameLayout类型的ViewGroup,处理了标题栏显示等工作;LocalWindowManager的addView()方法内部创建了ViewRoot对象;
WindowManagerService:
openSession():创建内部类Session对象,可用于响应 Binder 通信中的请求;addWindow(): 创建WindowState和SurfaceSession对象,窗口数mNumWindow自增;relayoutWindow():先创建本地
Surface,并分别调用Surface.openTransaction()和closeTransaction()进行事务处理;调用
Surface的copyFrom()拷贝本地Surface的信息;调用
Surface的writeToParcel()写入数据;
对按键事件的分发:
WMS 所在的 SystemServer 进程接收到事件;
WMS 找到 UI 位于屏幕顶端的进程所对应的
IWindow对象;调用
IWindow对象的dispatchKey()分发事件;ViewRoot找到真正处理该事件的View,并调用其dispatchKey();
Java 层 Surface:
无参构造方法:创建一个
CompatibleCanvas对象,而Canvas一般会封装一个Bitmap对象用于绘制;有参构造方法:
创建一个
CompatibleCanvas对象,并调用本地init()方法;创建一个
SurfaceComposerClient,并调用其createSurface()函数得到SurfaceControl对象;调用
SurfaceControl对象的writeSurfaceToParcel()把数据写入Parcel包;根据
Parcel包构造一个Surface对象,并保存到 Java 层,这样ViewRoot就得到一个 Native 的 Surface 对象;
lockCanvas():取到 Native 的
Canvas对象,并根据dirtyRect(需要重绘的矩形区域)创建Region对象;调用 Native 层
Canvas的lock()函数;取出 Java 层的
CompatibleCanvas对象,给Bitmap指定存储区域,并将Bitmap和Canvas绑定;
Native 层 Surface:
构造函数:定义
GraphicBuffer数组,读取Parcel中的数据,创建SurfaceComposerClient对象;lock():设置
usage标志,用于GraphicBuffer分配缓冲;调用
dequeueBuffer():调用SharedBufferClient的dequeueBuffer(),并调用Layer的requestBuffer()得到GraphicBuffer;调用
lockBuffer():调用SharedBufferClient的lock();调用
copyBlt():把FrontBuffer(mPostedBuffer)中的旧数据拷贝回 BackBuffer(叠加后防止重复绘制);
unlockAndPost():返回GraphicBuffer编号,调用queueBuffer(),设置 DirtyRegion,更新写位置;
SurfaceComposerClient:
SurfaceComposerClient建立了和SurfaceFlinger交互的通道:构造函数会调用SurfaceFlinger的createConnection()创建连接;初始化时会创建
BpSurfaceFlinger类型的mSignalServer对象,用于在客户端更新 BackBuffer 后通知SurfaceFlinger进行 PageFlipping 和输出;createSurface():创建ISurface对象,并以其为参数创建SurfaceControl对象(封装了一些函数,可以方便地调用SurfaceComposerClient和ISurface提供的函数);openTransaction():主要是用AutoLock控制计数变量mTransactionOpen自增;setPosition():修改控制Surface在屏幕上的位置和宽高信息的layer_state_t;closeGlobalTransaction():先调用
SurfaceFlinger.openGlobalTransaction():也是一个计数控制;然后调用
SurfaceFlinger.setClientState():遍历所有Layer,调用其setPosition(),最后设置flag;最后调用
SurfaceFlinger.closeGlobalTransaction():调用siginalEvent()提交事务;
SurfaceFlinger:
SurfaceFlinger驻留于 system_server 进程,是从Thread派生的,会单独启用一个工作线程;onFirstRef():第一次创建引用时调用;
首先启用工作线程,然后调用
Barrier(封装了Mutex和Condition的同步类)的wait();
createConnection():创建
Client,并保存到ClientsMap,Client内部会创建一块共享内存MemoryHeapBase,以及用于读写控制的SharedClient对象;根据
Client创建用于Binder通信的BClient,BClient派生于ISurfaceFlingerClient,用于接收客户端请求,并提交给SurfaceFlinger;
createSurface(): 根据传入的flag创建 PushBuffer / Normal / Blur / Dim 等不同类型的显示层(LayerBaseClient);readyToRun():创建
GraphicPlane(目前只支持一块屏幕),并设置 HAL 对象DisplayHardware;创建共享内存
MemoryHeapBase;获取屏幕信息,调用 OpenGL 相关函数;
调用
Barrier.open()触发同步条件;调用
property_set设置 boot 动画;
SurfaceFlinger创建FrameBuffer,并将各个Surface传输的数据通过GraphicBuffer混合后,再由自己传输到FrameBuffer;threadLoop()线程循环:调用
waitForEvent():等待INVALIDATE重绘消息(unlockCanvasAndPost()会调用signal(),进而调用mEventQueue.invalidate());调用
handleTransaction():调用handleTransactionLocked()处理事务,调用每个Layer.ditch()丢弃被 hide 的层;调用
handlePageFlip():调用Layer.lockPageFlip()根据 FrontBuffer 数据生成 Texture;调用Layer.unlockPageFlip()做清理工作;调用
handleRepaint():获取DisplayHardware,计算 DirtyRegion;按 Z 轴顺序由里到外依次调用Layer.draw()函数;调用
unlockClients():调用Layer.unlock(mFrontBufferIndex),释放占用的 FrontBuffer;调用
postFrameBuffer():调用DisplayHardware.flip(),交换 buffer,使图像显示;
handleTransactionLocked()事务处理:获得所有显示层数组
layersSortedByZ;如需要遍历,则调用所有
Layer.onTransaction();处理横竖屏切换和
layersRemoved;调用
commitTransaction():调用同步变量的broadcast()函数;
SharedClient 与 SharedBuffer 家族:
每个
SurfaceFlinger内部定义一个跨进程共享的SharedClient;SharedClient内部的SharedBufferStack数组有 31 个元素,对应 31 个显示层,每层的读写步调由SharedBufferStack内部的成员变量控制;SharedBuffer家族在SurfaceFlinger端的代表是SharedBufferServer, 在Activity端的代表是SharedBufferClient;
LayerBaseClient:
LayerBaseClient继承自LayerBase,且有四个派生类:Layer、LayerBuffer、LayerDim、LayerBlur;LayerBaseClient定义了内部类Surface,它继承自ISurface,支持 Binder 通信;构造函数:使用
SharedClient对象创建SharedBufferServer对象;setBuffs():创建用于 PageFlipping 的两个GraphicBuffer对象:FrontBuffer 和 BackBuffer;addLayer_l():把新创建的 Layer 加入自己的 Z 轴 Layer 数组:layersSortedByZ;onDraw(): 调用 OpenGL 相关函数绘制;
GraphicBuffer:
继承自
LightRefBase使它支持引用计数;继承自
Flattenable使它支持序列化和反序列化,可封装于Parcel中用于 Binder 通信:响应端
BnSurface的onTransact()方法中reply.write(*buffer)会触发flatten()序列化;请求端
BpSurface的requestBuffer中reply.read(*buffer)会触发unflatten()反序列化;
内部的
GraphicBufferAllocator对象用于内存分配;
参考: