SurfaceFlinger对象建立过程示意
1 SurfaceSession的建立
客户端请求建立Surface时,首先在要与SurfaceFlinger建立一个Session,然后再Session上建立一个Connection通过概念返回Bclient对象。WindowManagerService在添加第一个窗口前会检查SurfaceSession是否建立,如何没有建立,将会新建立一个实例来代表与SurfaceFlinger的一个连接。
new SurfaceSession()@windowAddedLocked() @WindowManagerService.java。
SurfaceSession的建立过程大部分是在C++ Native空间中完成的,表现在SurfaceSession的初始化函数:init()本地函数上。从下面的初始化函数可以看到:
SurfaceSession在C++Native空间建立一个SurfaceComposerClient实例。而该实例的建立实现了如下的与SurfaceFlinger通讯基础:Init()<->SurfaceSession_init@Android_view_Surface.cpp
new SurfaceComposerClient
(1)建立了代理SurfaceFlinger服务的代理服务端
(2)建立了IsurfaceFlingerClient连接,在SurfaceFlinger端建立了对应的Client,并将BClient返回给WindowManagerService。
2 Surface的建立
在WindowManagerService中WindowState类中,我们知道每个主窗口子啊需要是都需要建立一个Surface与之对应。win.createSurfaceLocked()@relayoutWindow
Surface.java
Init()< -- >Surface_init(….,session,pid,dpy,w,h,format)@Android_view_Surface.cpp
SurfaceControl surface(client->createSurface
在mClient的连接上:建立ISurface接口:
M_Client->greateSurface(...)@
Bclient ::createSurface(mId...)@SurfaceFlinger.cpp
mFlinger->createSurface(clientid....)
createNormalSurfaceLocked
*createNormalSurfaceLocked:建立一个Layer分配显示内存
*createPushBuffersSurfaceLocked:建立一个LayBuffer但是不分配显示内存。
Surface&Canvas
Canvas为在画布的意思。Android上层的作图几乎都通过Canvas实例来完成,其实Canvas更多是一种接口的包装。drawPaints ,drawPoints,drawRect,drawBitmap ...
1 Canvas与Surface之间本质关系
对于本节,我们不去研究Skia图形引擎本身,我们需要了解的我们的所做的图形到底放置到了那个地方,并且这个Canvas如何与Surface连接在一起的。
Canvas(Java)在C++Native层有一个Native Canvas的C++对象所对应。
lockCanvas()@java
Surface_lockCanvas@Android_view_Surface.cpp
SurfaceControl->new Surface(control) @Surface.cpp
Surface: lock操作:
GraphicBuffer :lock
getBufferMapper().lock<-> GraphicBufferMapper ::lock
mAllocMod->lock<->gralloc_module_t::lock
通过SurfaceLock可取得Surface(mLockedBuffe)所对应的图形缓冲区地址。
(1) 建立与SkCanvas连接的位图设备,而该位图使用上面取得的图形缓冲区地址做自己的位图内存。
(2) 设置SkCanvas的作图目标设备为该位图。
通过该过程就建立起了SurfaceControl与Canvas之间的联系。
2 View:OnDraw的本源
不是使用OpenGL绘制时,Android在View属性发生变化,新建View时,或者Z-order发生变化时,需要对系统屏幕上的View重新绘制,此时我们的View会执行OnDraw(canvas),这个根源在哪里呢?
ViewRoot.Java
performTraversals(..)
…
draw()
canvas = surface.lockCanvas(dirty);
…
mView.draw(canvas);
draw(cavas)@view.java
background.draw(canvas);
onDraw(cavas)
dispatchDraw(cavas)
onDrawScrolbars(cavas)
surface.unlockCanvasAndPost(canvas);