深入理解 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
对象用于内存分配;
参考: