概述
先给出本篇的主要结论:
1.ISurfaceComposer,ISurfaceComposerClient, ISurfaceTexture,ISurface这四个接口描述了SurfaceFlinger系统及其客户端的定义和协作方式。2.ISurfaceComposer定义了SurfaceFlinger系统,它的server端的具体实现类是SurfaceFlinger。它的Proxy端封装在类ComposerService中。ComposerService的定义在SurfaceComposerClient.h中。 SurfaceFlinger的客户端通过ComposerService与SurfaceFlinger系统 通信。
3.ISurfaceComposerClient定义了SurfaceFlinger系统的客户端,它的server端的具体实现类是Client, 定义在SurfaceFlinger.h中。它的Proxy端封装在类 SurfaceComposerClient中,每个SurfaceComposerClient的创建都会使SurfaceFlinger系统创建类Client的一个实例。ISurfaceComposerClient接口只提供两个操作createSurface和destroySurface。
4.ISurfaceTexture接口非常重要,是连接SurfaceFlinger系统及其客户端的桥梁,ISurfaceTexture接口的server端实现是SurfaceTexture。ISurfaceTexture接口的proxy端的具体实现封装在SurfaceTextureClient中。Surface是SurfaceTextureClient的子类,客户端通过Surface实例与server端的SurfaceTexture协作。SurfaceTexture中维护着一组GraphicBuffer,这组GraphicBuffer被SurfaceFlinger及其客户端使用。客户端通过Surface(即通过SurfaceTextureClient)提供的接口获得这组 GraphicBuffer的某一空闲块,将需要显示的屏幕内容绘制在其上,然后再通过Surface(即通过SurfaceTextureClient)提供的接口将这块含有屏幕内容的Buffer放回队列。SurfaceFlinger通过Layer操作这组GraphicBuffer中含有当前屏幕内容的一块,通过Layer调用SurfaceTexture中封装的gles操作,将包含屏幕内容的GraphicBuffer上传给纹理,再通过LayerBase::drawWithOpenGL中调用glDrawArrays将纹理内容渲染到framebuffer。SurfaceFlinger接着调用egl接口eglSwapBuffer将绘制好的framebuffer显示在屏幕上。
5.Layer类中封装了SurfaceTexture,SurfaceTexture中维护着一组GraphicBuffer,屏幕内容会先绘制在这组GraphicBuffer上。
6.ISurface的Server端实现类是Layer::createSurface()函数中创建的类Bsurface,ISurface的proxy端封装在类Surface中,ISurface只提供一个操作getSurfaceTexture。Surface调用这个接口取得SurfaceTexture的proxy端,以便与SurfaceTexture通信。
下面的类图是ISurfaceComposer,ISurfaceComposerClient,ISurfaceTexture,ISurface这四个接口的Binder结构,封装各个接口Proxy端的类也一并给出,便于后面分析:
接下来看几组类之间关系的建立过程。
1.SurfaceComposerClient与SurfaceFlinger之间关系的建立过程分析
Android4.0.1 Activity的DecorView与SurfaceFlinger的Surface之间关系的建立过程分析中提到过
WindowMangerService中代表客户端的Session会创建一个SurfaceSession实例,这个SurfaceSession
实例代表着与SurfaceFlinger之间的一个连接。SurfaceSession的构造函数会调用native函数init(),
这个函数的实现SurfaceSession_init()定义在android_view_surface.cpp中。
SurfaceSession_init()函数会创建一个SurfaceComposerClient实例,并将这个实例保存到java层
SurfaceSession的mClient变量中。SurfaceSession_init()在创建完SurfaceComposerClient实例后会
调用它的incStrong()接口,这个接口继承自RefBase,用来增加引用计数。
incStrong()接口在第一次调用时又会调用到SurfaceComposerClient::onFirstRef()函数。
SurfaceComposerClient::onFirstRef()调用全局的inline 函数getComposerService()。这个函数接着调用
ComposerService::getComposerService(),得到SurfaceFlinger的本地代理类BpSurfaceComposer的实例。
ComposerService的定义在SurfaceComposerClient.h中。SurfaceComposerClient::onFirstRef()通过
ComposerService得到BpSurfaceComposer的实例后,就可以通过BpSurfaceComposer与
SurfaceFlinger通信。SurfaceComposerClient::onFirstRef()接着调用
BpSurfaceComposer::createConnection(),最终调用的是surfaceFlinger::createConnection(),
这个接口创建一个Client实例并将自身作为参数传给Client的构造函数,
并将这个Client实例返回。Client声明在SurfaceFlinger.h中。
所以SurfaceComposerClient::onFirstRef()中得到的是Client的本地代理类BpSurfaceComposerClient的实例.
SurfaceComposerClient将这个BpSurfaceComposerClient的实例存在它自己的mClient变量中。
Client运行在SurfaceFlinger进程中,是客户端在SurfaceFlinger进程中的代表,SurfaceComposerClient的
mClient变量指向Client的本地代理类BpSurfaceComposerClient,所以SurfaceComposerClient是通过
2.Surface与SurfaceTexture之间关系的建立过程分析
java层Surface的构造函数会调用native层的init()函数,
这个函数的具体实现Surface_init()在文件android_view_surface.cpp中.
SurfaceSession和Surface的native层实现都在android_view_surface.cpp中。
Surface_init()中会调用SurfaceComposerClient::createSurface创建一个Surface实例,并以这个Surface实例
为参数创建一个SurfaceControl实例,SurfaceControl与Surface的声明都在Surface.h中。
看下SurfaceComposerClient::createSurface()函数,这个函数是通过mClient变量调用
BpSurfaceComposerClient::createSurface函数,最终调用到SurfaceFlinger进程中的Client::createSurface
函数,Client的createSurface函数最终是通过调用SurfaceFlinger::createSurface函数完成的Surface创建。
SurfaceFlinger::createSurface()调用createNormalSurface()创建一个Layer.再调用
Layer的getSurface()获得一个Surface。getSurface()的具体实现是LayerBaseClient::getSurface()。
LayerBaseClient的实现在LayerBase.cpp中。LayerBaseClient::getSurface()会调用Layer::createSurface().
这个函数中定义了ISurface的具体实现类BSurface。Layer::createSurface()中创建的就是BSurface的实例。
所以SurfaceFlinger::createSurface()返回的就是BSurface的实例。
所以SurfaceComposerClient::createSurface()调用mClient变量返回的就是Lay::createSurface()函数中
创建的类Bsurface的实例的本地代理类BpSurface的实例.
SurfaceComposerClient::createSurface()接着将BpSurface的实例传给SurfaceControl的构造函数创建
了一个SurfaceControl的实例。Bpsurface实例保存在SurfaceControl的sp<ISurface>类型成员变量
mSurface中。android_view_surface.cpp中的Surface_init()将调用SurfaceComposerClient::createSurface()
得到的SurfaceControl实例保存到了java层Surface的mSurfaceControl变量中。这个保存过程是调用
setSurfaceControl()完成的。android_view_surface.cpp中的getSurface()在第一被调用时会调用
Surface_init()中创建的SurfaceControl实例的getSurface()函数。SurfaceControl::getSurface()在第一次调用时
会创建一个Surface实例。并将这个Surface实例保存在自身的sp<Surface>类型变量mSurfaceData中。
Surface的构造函数将SurfaceControl的mSurface变量保存在自身的mSurface变量中,
即将Layer::createSurface()函数中创建的类Bsurface的实例的本地代理类BpSurface的实例
保存在了Surface的mSurface变量中。Surface的构造函数接着调用mSurface->getSurfaceTexture(),
即通过BpSurface::getSurfaceTexture()最终调用到Layer::createSurface()函数中创建的类Bsurface的实例的
getSurfaceTexture()接口。Layer::createSurface()函数中创建的Bsurface实例的getSurfaceTexture()返回的是
当前Layer实例的mSurfaceTexture变量指向的ISurfaceTexture的具体实现类的实例。
接下来就看一下当前Layer实例的mSurfaceTexture变量指向的ISurfaceTexture的具体实现类到底是哪个类。
Layer::onFirstRef()中创建了SurfaceTextureLayer的实例,并将这个实例保存在了mSurfaceTexture变量中。
mSurfaceTexture = new SurfaceTextureLayer()。
所以Layer::createSurface()函数中创建的Bsurface实例的getSurfaceTexture()返回的是
SurfaceTextureLayer的实例。所以Surface的构造函数调用mSurface->getSurfaceTexture()返回的是
SurfaceTextureLayer的本地代理类BpSurfaceTextue的实例。Surface的构造函数接着调用init()函数,
init()函数接着调用SurfaceTextureClient::setISurfaceTexture()(Surface是SurfaceTextureClient的子类)。
将SurfaceTextureLayer的本地代理类BpSurfaceTextue的实例保存在SurfaceTextureClient的
sp<ISurfaceTexture> mSurfaceTexture变量中。
这样Suface就可以通过mSurfaceTexture变量中保存的BpSurfaceTexture来与服务端的SurfaceTexture通信了。
3.SurfaceFlinger与SurfaceTexture之间关系的建立过程分析
SurfaceFlinger::createSurface()调用createNormalSurface创建Layer,Layer的构造函数中调用glGenTextures
生成了一个纹理索引,Layer::onFirstRef()中以生成的纹理索引为参数创建了SurfaceTextureLayer的实例,
并将这个实例保存在Layer的变量mSurfaceTexture中,SurfaceTextureLayer是SurfaceTexture的子类。
Layer中生成的纹理索引唯一标识了SurfaceTextureLayer实例的父类实例SurfaceTexture。
Layer::onFirstRef()中还将Layer自身作为参数构建了FrameQueuedListener,并将这个FrameQueuedListener
注册给了SurfaceTexture。SurfaceTexture在有可用的GraphicBuffer时,会通过FrameQueuedListener的接口
onFrameAvailable通知Layer有可用的GraphicBuffer.Layer中的成员变量sp<GraphicBuffer>mActiveBuffer保存的
是SurfaceTexture中含有当前屏幕内容的一块GraphicBuffer.Layer::lockPageFlip中给mActiveBuffer赋值的
语句如下:mActiveBuffer = mSurfaceTexture->getCurrentBuffer();SurfaceFlinger::createSurface()在创建完
Layer之后调用addClientLayer()将新创建的Layer保存到了mCurrentState.layersSortedByZ中。
所以SurfaceFlinger直接管理的对象是Layer,而Layer的一个主要工作就是将SurfaceTexture中包含屏幕内容的
GrphicBuffer,通过gles操作上传给FrameBuffer.
基于以上分析我们可以得到SurfaceFlinger系统实现和使用相关的一个较完整的类图如下:
有了上面的基础,接下来就可以看一下一个Activity的ViewTree显示在屏幕上的大致过程:
这个过程开始于ViewRootImpl.java的draw()方法中,结束于SurfaceFlinger调用eglSwapBuffer。
所以我们将整个过程分成四个步骤:
步骤1: ViewRootImpl.java的draw()中调用Surface.lockCanvas,获得SurfaceTexture中维护的一块
空闲的GraphicBuffer;
步骤2: ViewRootImpl.java的draw()中调用view.draw(),
android4.0.1 Activity的Window,DecorView 之间关系的建立过程分析中有提到
ViewRootImpl中的view变量存储的是整个Activity的ViewTree的根视图DecorVIew,所以,
view.draw()触发的是整个ViewTreee的绘制过程。这个过程结束后,整个ViewTree的可视
部分就绘制在了步骤1中得到的GraphicBuffer上;
步骤3: ViewRootImpl.java的draw()中调用Surface.unlockCanvas,将含有当前屏幕内容的
GraphicBuffer放回SurfaceTexture的队列中;这个过程会通过Layer类触发SurfaceFlinger的合成;
步骤4: SurfaceFlinger调用eglSwapBuffer,用含有新的屏幕内容的FrameBuffer替换
当前的FrameBuffer,从而更新屏幕内容,至此Activiity的内容就显示在屏幕上了。
我们主要看步骤1,3,4的具体实现过程,步骤2与本篇关注点不同,我们先不考虑。
步骤1的实现过程顺序图如下:
ViewRootImpl.java的draw()中调用Surface.lockCanvas,通过JNI调用到Surface::lock,
Surface::lock调用SurfaceTextureClient::lock。SurfaceTextureClient通过SurfaceTextureLayer的
本地代理类BpSurfaceTexture与SurfaceTextureLayer通信。
SurfaceTexture::dequeueBuffer()先在mSlots中查找一个空闲Slot,然后调用GraphicBufferAlloc为
这个Slot的GraphicBuffer分配一块内存。GraphicBufferAlloc定义在SurfaceFlinger中。
SurfaceTexture中的这组GraphicBuffer在Server端和Client端(SurfaceTextureClient)的使用方式是个
值得深究的问题,以后专门看一下。这里不仔细看了。
总之,SurfaceTexture::dequeueBuffer执行完后,有一个空闲Slot的GraphicBuffer被分配了内存。
同时这个空闲Slot的编号通过指针参数返回给了SurfaceTextureClient。
接着SurfaceTextureClient又调用SurfaceTexture::requestBuffer,得到指向dequeueBuffer中分配的
GraphicBuffer的指针。
android_view_surface.cpp的 Surface_lockCanvas最终会将SurfaceTexturee::dequeueBuffer分
配的GraphicBuffer作为BitmapDevice设置给Canvas.这个Canvas会返回给java层供步骤2使用。
步骤3的实现过程顺序图如下:
SurfaceTexture::queueBuffer将含有屏幕内容的GraphicBuffer的Slot号存放在mQueue中。
接着调用FrameAvailableListener的onFrameAvailable接口.前面有讲过Layer将自身作为
FrameQueuedListener注册给了SurfaceTexture,FrameQueuedListener是
FrameAvailableListener的子类。所以SurfaceTexture::queueBuffer调用了Layer::onFirstRef
中创建的FrameQueuedListener的onFrameAvailable()接口。这个接口同时又调用了
Layer::onFrameQueued。Layer::onFrameQueued调用了SurfaceFlinger::signalEvent。
SurfaceFlinger::signalEvent会释放信号,使SurfaceFlinger::waitForEvent可以执行下去,
从而使SurfaceFlinger::threadLoop()可以继续执行。
重点看下SurfaceFlinger::threadLoop()中的操作。首先调用
SurfaceFlinger::handlePageFlip()。这个函数先调用lockPageFlip。
SurfaceFlinger::lockPageFlip这个函数对当前的所有层调用lockPageFlip。
所以我们看Layer::lockPageFlip,这个函数先调用SurfaceTexture::updateTexImage。
SurfaceTexture::updateTexImage先调用createImage。createImage中调用
eglCreateImageKHR,这个函数以SurfaceTexture的含有当前屏幕内容的GraphicBuffer为源创建
EGLImage。所以createImage执行完后,屏幕内容包含在了EGLImage中。
SurfaceTexture::updateTexImage调用完createImage后,调用glBindTexture,绑定当前活动的
纹理单元,绑定后所有的gles操作都会是对当前纹理的操作。SurfaceTexture::updateTexImage接着
以新创建的EGLImage为参数调用了glEGLImageTargetTexture2DOES,用来更新当前纹理内容。这样
屏幕内容就被加载到了一个纹理单元中。之后SurfaceTexture::updateTexImage将SurfaceTexture的
一些状态信息更新为当前GraphicBuffer的信息。Layer::lockPageFlip在调用完
SurfaceTexture::updateTexImage后,根据SurfaceTexture的当前状态信息更新自身相应的状态信息。
SurfaceFlinger::handlePageFlip在调用完各个Layer::lockPageFlip后,接着计算各个Layer的可视
部分,并重建存储可视Layer的list。之后调用unlockPageFlip。接着看SurfaceFlinger::threadLoop
调用handleRepaint。handleRepaint先调用setupHardwareComposer作framebuffer相关的准备工作。
接着调用composeSurfaces,这个函数的主要功能就是将前面讲到的可视Layer list中的所有Layer
渲染到framebuffer上。这个函数依次对可视layer list中的所有Layer调用LayerBase::draw。
LayerBase::draw()调用到Layer::onDraw().Layer::onDraw()又调用到layerBase::drawWithOpenGL。
这个函数中的核心操作就是遍历当前Layer需要重绘的区域,对每个需要重绘的区域调用glScissor标
识出,然后调用glDrawArrays将屏幕内容具体绘制到framebuffer,因为前面讲过每个可视Layer的内容都
已经通过EGLImage的形式加载到了纹理中。所以这里调用glDrawArrays就可以将前面加载到纹理中的
内容具体绘制到framebuffer上了。
步骤4的实现过程:
接着步骤3,SurfaceFlinger::threadLoop在调用完handleRepaint()后,屏幕内容已经完全渲染到framebuffer
上了,SurfaceFlinger::threadLoop接着调用了postFramebuffer,postFramebuffer接着调用
DisplayHardware::flip,这个函数中调用eglSwapBuffers,交换framebuffer,从而更新屏幕内容。
本章图片下载地址
1.SurfaceComposerClient与SurfaceFlinger之间关系的建立过程分析
Android4.0.1 Activity的DecorView与SurfaceFlinger的Surface之间关系的建立过程分析中提到过
WindowMangerService中代表客户端的Session会创建一个SurfaceSession实例,这个SurfaceSession
实例代表着与SurfaceFlinger之间的一个连接。SurfaceSession的构造函数会调用native函数init(),
这个函数的实现SurfaceSession_init()定义在android_view_surface.cpp中。
SurfaceSession_init()函数会创建一个SurfaceComposerClient实例,并将这个实例保存到java层
SurfaceSession的mClient变量中。SurfaceSession_init()在创建完SurfaceComposerClient实例后会
调用它的incStrong()接口,这个接口继承自RefBase,用来增加引用计数。
incStrong()接口在第一次调用时又会调用到SurfaceComposerClient::onFirstRef()函数。
SurfaceComposerClient::onFirstRef()调用全局的inline 函数getComposerService()。这个函数接着调用
ComposerService::getComposerService(),得到SurfaceFlinger的本地代理类BpSurfaceComposer的实例。
ComposerService的定义在SurfaceComposerClient.h中。SurfaceComposerClient::onFirstRef()通过
ComposerService得到BpSurfaceComposer的实例后,就可以通过BpSurfaceComposer与
SurfaceFlinger通信。SurfaceComposerClient::onFirstRef()接着调用
BpSurfaceComposer::createConnection(),最终调用的是surfaceFlinger::createConnection(),
这个接口创建一个Client实例并将自身作为参数传给Client的构造函数,
并将这个Client实例返回。Client声明在SurfaceFlinger.h中。
所以SurfaceComposerClient::onFirstRef()中得到的是Client的本地代理类BpSurfaceComposerClient的实例.
SurfaceComposerClient将这个BpSurfaceComposerClient的实例存在它自己的mClient变量中。
Client运行在SurfaceFlinger进程中,是客户端在SurfaceFlinger进程中的代表,SurfaceComposerClient的
mClient变量指向Client的本地代理类BpSurfaceComposerClient,所以SurfaceComposerClient是通过
它的mClient变量与SurfaceFlinger进程中的Client实例通信。
2.Surface与SurfaceTexture之间关系的建立过程分析
java层Surface的构造函数会调用native层的init()函数,
这个函数的具体实现Surface_init()在文件android_view_surface.cpp中.
SurfaceSession和Surface的native层实现都在android_view_surface.cpp中。
Surface_init()中会调用SurfaceComposerClient::createSurface创建一个Surface实例,并以这个Surface实例
为参数创建一个SurfaceControl实例,SurfaceControl与Surface的声明都在Surface.h中。
看下SurfaceComposerClient::createSurface()函数,这个函数是通过mClient变量调用
BpSurfaceComposerClient::createSurface函数,最终调用到SurfaceFlinger进程中的Client::createSurface
函数,Client的createSurface函数最终是通过调用SurfaceFlinger::createSurface函数完成的Surface创建。
SurfaceFlinger::createSurface()调用createNormalSurface()创建一个Layer.再调用
Layer的getSurface()获得一个Surface。getSurface()的具体实现是LayerBaseClient::getSurface()。
LayerBaseClient的实现在LayerBase.cpp中。LayerBaseClient::getSurface()会调用Layer::createSurface().
这个函数中定义了ISurface的具体实现类BSurface。Layer::createSurface()中创建的就是BSurface的实例。
所以SurfaceFlinger::createSurface()返回的就是BSurface的实例。
所以SurfaceComposerClient::createSurface()调用mClient变量返回的就是Lay::createSurface()函数中
创建的类Bsurface的实例的本地代理类BpSurface的实例.
SurfaceComposerClient::createSurface()接着将BpSurface的实例传给SurfaceControl的构造函数创建
了一个SurfaceControl的实例。Bpsurface实例保存在SurfaceControl的sp<ISurface>类型成员变量
mSurface中。android_view_surface.cpp中的Surface_init()将调用SurfaceComposerClient::createSurface()
得到的SurfaceControl实例保存到了java层Surface的mSurfaceControl变量中。这个保存过程是调用
setSurfaceControl()完成的。android_view_surface.cpp中的getSurface()在第一被调用时会调用
Surface_init()中创建的SurfaceControl实例的getSurface()函数。SurfaceControl::getSurface()在第一次调用时
会创建一个Surface实例。并将这个Surface实例保存在自身的sp<Surface>类型变量mSurfaceData中。
Surface的构造函数将SurfaceControl的mSurface变量保存在自身的mSurface变量中,
即将Layer::createSurface()函数中创建的类Bsurface的实例的本地代理类BpSurface的实例
保存在了Surface的mSurface变量中。Surface的构造函数接着调用mSurface->getSurfaceTexture(),
即通过BpSurface::getSurfaceTexture()最终调用到Layer::createSurface()函数中创建的类Bsurface的实例的
getSurfaceTexture()接口。Layer::createSurface()函数中创建的Bsurface实例的getSurfaceTexture()返回的是
当前Layer实例的mSurfaceTexture变量指向的ISurfaceTexture的具体实现类的实例。
接下来就看一下当前Layer实例的mSurfaceTexture变量指向的ISurfaceTexture的具体实现类到底是哪个类。
Layer::onFirstRef()中创建了SurfaceTextureLayer的实例,并将这个实例保存在了mSurfaceTexture变量中。
mSurfaceTexture = new SurfaceTextureLayer()。
所以Layer::createSurface()函数中创建的Bsurface实例的getSurfaceTexture()返回的是
SurfaceTextureLayer的实例。所以Surface的构造函数调用mSurface->getSurfaceTexture()返回的是
SurfaceTextureLayer的本地代理类BpSurfaceTextue的实例。Surface的构造函数接着调用init()函数,
init()函数接着调用SurfaceTextureClient::setISurfaceTexture()(Surface是SurfaceTextureClient的子类)。
将SurfaceTextureLayer的本地代理类BpSurfaceTextue的实例保存在SurfaceTextureClient的
sp<ISurfaceTexture> mSurfaceTexture变量中。
这样Suface就可以通过mSurfaceTexture变量中保存的BpSurfaceTexture来与服务端的SurfaceTexture通信了。
3.SurfaceFlinger与SurfaceTexture之间关系的建立过程分析
SurfaceFlinger::createSurface()调用createNormalSurface创建Layer,Layer的构造函数中调用glGenTextures
生成了一个纹理索引,Layer::onFirstRef()中以生成的纹理索引为参数创建了SurfaceTextureLayer的实例,
并将这个实例保存在Layer的变量mSurfaceTexture中,SurfaceTextureLayer是SurfaceTexture的子类。
Layer中生成的纹理索引唯一标识了SurfaceTextureLayer实例的父类实例SurfaceTexture。
Layer::onFirstRef()中还将Layer自身作为参数构建了FrameQueuedListener,并将这个FrameQueuedListener
注册给了SurfaceTexture。SurfaceTexture在有可用的GraphicBuffer时,会通过FrameQueuedListener的接口
onFrameAvailable通知Layer有可用的GraphicBuffer.Layer中的成员变量sp<GraphicBuffer>mActiveBuffer保存的
是SurfaceTexture中含有当前屏幕内容的一块GraphicBuffer.Layer::lockPageFlip中给mActiveBuffer赋值的
语句如下:mActiveBuffer = mSurfaceTexture->getCurrentBuffer();SurfaceFlinger::createSurface()在创建完
Layer之后调用addClientLayer()将新创建的Layer保存到了mCurrentState.layersSortedByZ中。
所以SurfaceFlinger直接管理的对象是Layer,而Layer的一个主要工作就是将SurfaceTexture中包含屏幕内容的
GrphicBuffer,通过gles操作上传给FrameBuffer.
基于以上分析我们可以得到SurfaceFlinger系统实现和使用相关的一个较完整的类图如下:
有了上面的基础,接下来就可以看一下一个Activity的ViewTree显示在屏幕上的大致过程:
这个过程开始于ViewRootImpl.java的draw()方法中,结束于SurfaceFlinger调用eglSwapBuffer。
所以我们将整个过程分成四个步骤:
步骤1: ViewRootImpl.java的draw()中调用Surface.lockCanvas,获得SurfaceTexture中维护的一块
空闲的GraphicBuffer;
步骤2: ViewRootImpl.java的draw()中调用view.draw(),
android4.0.1 Activity的Window,DecorView 之间关系的建立过程分析中有提到
ViewRootImpl中的view变量存储的是整个Activity的ViewTree的根视图DecorVIew,所以,
view.draw()触发的是整个ViewTreee的绘制过程。这个过程结束后,整个ViewTree的可视
部分就绘制在了步骤1中得到的GraphicBuffer上;
步骤3: ViewRootImpl.java的draw()中调用Surface.unlockCanvas,将含有当前屏幕内容的
GraphicBuffer放回SurfaceTexture的队列中;这个过程会通过Layer类触发SurfaceFlinger的合成;
步骤4: SurfaceFlinger调用eglSwapBuffer,用含有新的屏幕内容的FrameBuffer替换
当前的FrameBuffer,从而更新屏幕内容,至此Activiity的内容就显示在屏幕上了。
我们主要看步骤1,3,4的具体实现过程,步骤2与本篇关注点不同,我们先不考虑。
步骤1的实现过程顺序图如下:
ViewRootImpl.java的draw()中调用Surface.lockCanvas,通过JNI调用到Surface::lock,
Surface::lock调用SurfaceTextureClient::lock。SurfaceTextureClient通过SurfaceTextureLayer的
本地代理类BpSurfaceTexture与SurfaceTextureLayer通信。
SurfaceTexture::dequeueBuffer()先在mSlots中查找一个空闲Slot,然后调用GraphicBufferAlloc为
这个Slot的GraphicBuffer分配一块内存。GraphicBufferAlloc定义在SurfaceFlinger中。
SurfaceTexture中的这组GraphicBuffer在Server端和Client端(SurfaceTextureClient)的使用方式是个
值得深究的问题,以后专门看一下。这里不仔细看了。
总之,SurfaceTexture::dequeueBuffer执行完后,有一个空闲Slot的GraphicBuffer被分配了内存。
同时这个空闲Slot的编号通过指针参数返回给了SurfaceTextureClient。
接着SurfaceTextureClient又调用SurfaceTexture::requestBuffer,得到指向dequeueBuffer中分配的
GraphicBuffer的指针。
android_view_surface.cpp的 Surface_lockCanvas最终会将SurfaceTexturee::dequeueBuffer分
配的GraphicBuffer作为BitmapDevice设置给Canvas.这个Canvas会返回给java层供步骤2使用。
步骤3的实现过程顺序图如下:
SurfaceTexture::queueBuffer将含有屏幕内容的GraphicBuffer的Slot号存放在mQueue中。
接着调用FrameAvailableListener的onFrameAvailable接口.前面有讲过Layer将自身作为
FrameQueuedListener注册给了SurfaceTexture,FrameQueuedListener是
FrameAvailableListener的子类。所以SurfaceTexture::queueBuffer调用了Layer::onFirstRef
中创建的FrameQueuedListener的onFrameAvailable()接口。这个接口同时又调用了
Layer::onFrameQueued。Layer::onFrameQueued调用了SurfaceFlinger::signalEvent。
SurfaceFlinger::signalEvent会释放信号,使SurfaceFlinger::waitForEvent可以执行下去,
从而使SurfaceFlinger::threadLoop()可以继续执行。
重点看下SurfaceFlinger::threadLoop()中的操作。首先调用
SurfaceFlinger::handlePageFlip()。这个函数先调用lockPageFlip。
SurfaceFlinger::lockPageFlip这个函数对当前的所有层调用lockPageFlip。
所以我们看Layer::lockPageFlip,这个函数先调用SurfaceTexture::updateTexImage。
SurfaceTexture::updateTexImage先调用createImage。createImage中调用
eglCreateImageKHR,这个函数以SurfaceTexture的含有当前屏幕内容的GraphicBuffer为源创建
EGLImage。所以createImage执行完后,屏幕内容包含在了EGLImage中。
SurfaceTexture::updateTexImage调用完createImage后,调用glBindTexture,绑定当前活动的
纹理单元,绑定后所有的gles操作都会是对当前纹理的操作。SurfaceTexture::updateTexImage接着
以新创建的EGLImage为参数调用了glEGLImageTargetTexture2DOES,用来更新当前纹理内容。这样
屏幕内容就被加载到了一个纹理单元中。之后SurfaceTexture::updateTexImage将SurfaceTexture的
一些状态信息更新为当前GraphicBuffer的信息。Layer::lockPageFlip在调用完
SurfaceTexture::updateTexImage后,根据SurfaceTexture的当前状态信息更新自身相应的状态信息。
SurfaceFlinger::handlePageFlip在调用完各个Layer::lockPageFlip后,接着计算各个Layer的可视
部分,并重建存储可视Layer的list。之后调用unlockPageFlip。接着看SurfaceFlinger::threadLoop
调用handleRepaint。handleRepaint先调用setupHardwareComposer作framebuffer相关的准备工作。
接着调用composeSurfaces,这个函数的主要功能就是将前面讲到的可视Layer list中的所有Layer
渲染到framebuffer上。这个函数依次对可视layer list中的所有Layer调用LayerBase::draw。
LayerBase::draw()调用到Layer::onDraw().Layer::onDraw()又调用到layerBase::drawWithOpenGL。
这个函数中的核心操作就是遍历当前Layer需要重绘的区域,对每个需要重绘的区域调用glScissor标
识出,然后调用glDrawArrays将屏幕内容具体绘制到framebuffer,因为前面讲过每个可视Layer的内容都
已经通过EGLImage的形式加载到了纹理中。所以这里调用glDrawArrays就可以将前面加载到纹理中的
内容具体绘制到framebuffer上了。
步骤4的实现过程:
接着步骤3,SurfaceFlinger::threadLoop在调用完handleRepaint()后,屏幕内容已经完全渲染到framebuffer
上了,SurfaceFlinger::threadLoop接着调用了postFramebuffer,postFramebuffer接着调用
DisplayHardware::flip,这个函数中调用eglSwapBuffers,交换framebuffer,从而更新屏幕内容。
本章图片下载地址
最后
以上就是痴情耳机为你收集整理的android4.0.1 surfaceflinger系统分析的全部内容,希望文章能够帮你解决android4.0.1 surfaceflinger系统分析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复