分析SurfaceFlinger过程中遇到的对象
2012-11-29 10:41
316 查看
注:本文有部分内容并非原创,感谢原来的作者以及红黑联盟的参考图! Surface 这一块确实有点复杂,对象非常多,所以想要了解清楚它们之间的关系并不是一件容易的事情。这里建议大家拿邓凡平老师的《深入理解Android 卷I》由里到外撸上一把! 不过这本书参照的源码是2.2的,市场上使用比较多的是2.3,所以本文分析也是基于2.3的。 对象间的关系: (1)图中的BClient对象在android 2.2及以前版本还有,2.3之后就改名了,2.3的Surface模块有细微的变化。 (2)SurfaceFlinger的定义: @SurfaceFlinger.h class SurfaceFlinger : public BinderService<SurfaceFlinger>, public BnSurfaceComposer, protected Thread (3)SurfaceFlinger对象的创建在:(这跟SurfaceFlinger的启动过程有关,这里暂且不讲,直接跳到它被实例化的地方) @BinderService.h static void publishAndJoinThreadPool() { sp<ProcessState> proc(ProcessState::self()); sp<IServiceManager> sm(defaultServiceManager()); sm->addService(String16(SERVICE::getServiceName()), new SERVICE()); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); } BinderService是一个模板类。 (4)其实ComposerService就是SurfaceFlinger: @SurfaceComposerClient.cpp ComposerService::ComposerService() : Singleton<ComposerService>() { const String16 name("SurfaceFlinger"); while (getService(name, &mComposerService) != NO_ERROR) { usleep(250000); } mServerCblkMemory = mComposerService->getCblk(); mServerCblk = static_cast<surface_flinger_cblk_t volatile *>( mServerCblkMemory->getBase()); } SurfaceComposerClient与SurfaceFlinger交互的建立过程: (1)其中蓝色箭头是SurfaceComposerClient通过ComposerService获得SurfaceFlinger的IBinder接口ISurfaceComposer过程; (2)红色箭头表示SurfaceComposerClient通过IPC请求SurfaceFlinger创建Client的过程,并获得Client的IBinder接口ISurfaceComposerClient; (3)绿色箭头表示SurfaceComposerClient通过IPC请求SurfaceFlinger端的Client创建Surface。 (4)为什么SurfaceFlinger端多出一个Client?因为SurfaceFlinger是服务端,它会为每个发起请求连接的Client创建一个Client对象(为区分与客户端的Client,这里暂且把它称为mClient),SurfaceFlinger会把mClient放到自己的一个记录着所有客户端连接的列表里。所以,Client端通过调用createConnection()返回的其实是服务端的mClient。 Client端Surface的形态: @SurfaceComposerClient.cpp sp<SurfaceControl> SurfaceComposerClient::createSurface( int pid, const String8& name, DisplayID display, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { sp<SurfaceControl> result; if (mStatus == NO_ERROR) { ISurfaceComposerClient::surface_data_t data; sp<ISurface> surface = mClient->createSurface(&data, pid, name, display, w, h, format, flags); if (surface != 0) { result = new SurfaceControl(this, surface, data, w, h, format, flags); } } return result; } 从上面的代码我们可以看出,SurfaceComposerClient为WMS返回的是一个SurfaceControl对象,这个 SurfaceControl对象包含了surfaceFlinger为SurfaceComposerClient创建的surface,这个 SurfaceFlinge创建的Surface在Client端的形态为ISurface。 SurfaceControl提供了一些(通过SF端返回的Client句柄)控制Surface的操作,例如销毁Surface、隐藏Surface等。 SurfaceControl类中还有一个非常重要的成员,它的类型也叫做Surface,定义在frameworks/base/libs/surfaceflinger/Surface.h。这个Surface提供了显示Buffer的管理,它负责向LayerBaseClient::Surface请求显示Buffer,同时将显示Buffer交给J***A Surface的Canvas去绘制窗口,我们称这个Surface为native Surface。这个Surface是在client端的。 SurfaceFlinger端Surface形态: (1) @ SurfaceFlinger.cpp::Client:: createSurface sp<ISurface> Client::createSurface( ISurfaceComposerClient::surface_data_t* params, int pid, const String8& name, DisplayID display, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { return mFlinger->createSurface(this, pid, name, params, display, w, h, format, flags); } (2) @ SurfaceFlinger.cpp::createSurface sp<ISurface> SurfaceFlinger::createSurface(const sp<Client>& client, int pid, const String8& name, ISurfaceComposerClient::surface_data_t* params, DisplayID d, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { sp<LayerBaseClient> layer; sp<LayerBaseClient::Surface> surfaceHandle; if (int32_t(w|h) < 0) { LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)", int(w), int(h)); return surfaceHandle; } LOGD("createSurface for pid %d (%d x %d)", pid, w, h); sp<Layer> normalLayer; switch (flags & eFXSurfaceMask) { case eFXSurfaceNormal: if (UNLIKELY(flags & ePushBuffers)) { layer = createPushBuffersSurface(client, d, w, h, flags); } else { normalLayer = createNormalSurface(client, d, w, h, flags, format); layer = normalLayer; } break; case eFXSurfaceBlur: layer = createBlurSurface(client, d, w, h, flags); break; case eFXSurfaceDim: layer = createDimSurface(client, d, w, h, flags); break; } if (layer != 0) { layer->initStates(w, h, flags); layer->setName(name); ssize_t token = addClientLayer(client, layer); surfaceHandle = layer->getSurface(); if (surfaceHandle != 0) { params->token = token; params->identity = surfaceHandle->getIdentity(); params->width = w; params->height = h; params->format = format; if (normalLayer != 0) { Mutex::Autolock _l(mStateLock); mLayerMap.add(surfaceHandle->asBinder(), normalLayer); } } setTransactionFlags(eTransactionNeeded); } return surfaceHandle; } 当client请求SurfaceFlinger创建Surface时,SurfaceFlinger首先根据WMS提供的窗口的属性来创建一个命名为 Layer概念的对象,然后再根据Layer来创建它的子类对象LayerBaseClient::Surface。所以SurfaceFlinger端返回的Surface是LayerBaseClient::Surface。 Layer 上面出现了一个Layer对象,我们可以理解为client端的一个surface对应server端(SF)的一个Layer。 Layer的对象继承关系 Layer的管理: 我们知道一个Client可能会创建多个Surface,也就是要创建多个Layer,那么 SurfaceFlinger端如何管理这些Layer呢?SurfaceFlinger维护了2个Vector来管理Layer。 第一种方式,我们知道SurfaceFlinger会为每个SurfaceSession创建一个Client对象,这第一种方式就是将所有为某一个SurfacSession创建的Layer保存在它对应的Client对象中: SurfaceFlinger::createSurface()@SurfaceFlinger.cpp ssize_t token = addClientLayer(client, layer); 第二种方式,将所有的创建的普通的Layer保存起来,以便native Surface在请求实现Buffer时能够辨识native Surface对应的Layer: SurfaceFlinger::createSurface()@SurfaceFlinger.cpp mLayerMap.add(surfaceHandle->asBinder(), normalLayer); Surface 显示Buffer的存储管理: 在前文介绍Client端的Surface形态的内容时,我们提到SurfaceControl中还会维护一个名为native Surface对象,它定义在 frameworks/base/libs/surfaceflinger/Surface.h中,它负责向LayerBaseClient::Surface请求显示Buffer,同时将显示Buffer交给J***A Surface的Canvas去绘制窗口。 native Surface的创建是从ViewRoot首次Lock canvas时进行的,这么做的目的可能也是为了节约空间,减少不必要的开支。 native Surface的初始化和显示Buffer的管理过程比较复杂,下图给出了这一部分的一个静态结构图,有些东西从图上表现不出来,下面简单的介绍一下。 SharedClient
SharedClient是这一部分实现的关键所在,它是在共享内存上创建的。下面代码中可以看出,UserClient在初始化时,提供了一个MemoryHeapBase来供SharedClient创建,MemoryHeapBase是创建的共享内存。
@SurfaceFlinger.cpp
UserClient::UserClient(constsp<SurfaceFlinger>& flinger)
: ctrlblk(0), mBitmap(0),mFlinger(flinger)
{
const int pgsize = getpagesize();
const int cblksize =((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
mCblkHeap = new MemoryHeapBase(cblksize, 0,
"SurfaceFlingerClient control-block");
ctrlblk =static_cast<SharedClient *>(mCblkHeap->getBase());
if(ctrlblk) { // construct the shared structure in-place.
new(ctrlblk) SharedClient;
}
}
为什么需要将SharedClient设计为共享内存呢?每个ClientSurface需要的SharedBufferStack寄存在SharedClient中,而对于每个SharedBufferStack,一方面,nativeSurface需要对它进行一些区域尺寸等的设置;另一方面,在render时,Layer需要获得当前ClientSurfce对应的SharedBufferStack中获得区域尺寸等设置信息。
classSharedClient@SharedBufferStack.h
SharedBufferStack surfaces[SharedBufferStack::NUM_LAYERS_MAX ];
SurfaceClient
SurfaceClient是在创建nativeSurface时调用的,它的作用是调用SF的createUserClient,进而调用UserClient的构造函数创建了SharedClient.
native Surace请求GraphicBuffer
这里将ClientSurface的GraphicBuffer的创建过程以时序图的形式展现出来。
这里需要注意的是,nativeSurface的2个GraphicBuffer只有在lock()时才会去创建,而不是在nativeSurface被创建的时候创建的
现在在客户端的native层有3个对象:SurfaceControl、nativeSurface、SurfaceClient。那么,它们里面之间的关系是怎样的呢?请看它们的成员变量:
SurfaceControl
mClient:SurfaceComposerClient
mSurface:ISurface
Surface
mClient:SurfaceClient
mSurface:SurfaceControl->mSurface
mSharedBufferClient
mBufferMapper
SurfaceClient
mClient:sf->createClientConnection()
*mControl:SharedClient
mControl:IMemoryHeap
SharedBufferStack、SharedBufferClient和SharedBufferServer,简称为SBT、SBC、SBS
SharedBufferStack
SharedBufferStack在这个模块中所处的地位在上面的小节中介绍了,下面主要介绍一下它的作用。
(1)设置当前窗口要显示的区域等信息;
class SharedBufferStack@SharedBufferStack.h
status_tsetDirtyRegion(int buffer, const Region& reg);
status_tsetCrop(int buffer, const Rect& reg);
status_tsetTransform(int buffer, uint8_ttransform);
(2)android的图形系统中提供了两个显示Buffer,nativeSurface有2个GraphicBuffer,2个Buffer其中一个显示,称之为FrontBuffer,另外一个交给ViewRoot去绘制窗口,称之为BackBuffer。等BackBuffer绘制完成,SurfaceFlinger在将两者调换,这样就大大提高了显示的效率。
而sharedBufferStack第二个很重要的作用就是提供了一套机制来实现这个调换的过程,以保证提供给ViewRoot的Buffer符合当前Buffer轮转的要求。
class SharedBufferStack@SharedBufferStack.h
volatileint32_t head; // server's current front buffer
(SBS当前使用的缓冲区编号)
volatile int32_t available; //number of dequeue-able buffers(当前可用的空闲缓冲区个数)
volatile int32_t queued; //number of buffers waiting for post(SBC投递的脏缓冲个数)
volatile int32_t inUse; //buffer currently in use by SF(SBS正在使用的缓冲编号)
这几个变量的值来确定nativeSurface中GraphicBuffer的索引,其中SharedBufferClient::tail记录的是BackBuffer的索引;SharedBufferStack::head记录的是FrontBuffer的索引。
SharedBufferServer
SharedBufferServer是在nativeSurface的init函数中间接创建的:
token =mClient.getTokenForSurface(mSurface);
这个函数经过层层调用,来到了SF端,最后调用Layer->setToken()创建了SharedBufferServer。来看它的构造函数:
SharedBufferServer::SharedBufferServer(SharedClient* sharedClient,
int surface, int num, int32_tidentity)
: SharedBufferBase(sharedClient,surface, identity),
mNumBuffers(num)
{
mSharedStack->init(identity); //这个函数将会设置inUse为-1
mSharedStack->token = surface;
mSharedStack->head = num-1; //head=1
mSharedStack->available = num;//
空闲缓冲区的个数为2
mSharedStack->queued = 0; //已使用的缓冲区个数为0
mSharedStack->reallocMask = 0;
memset(mSharedStack->buffers, 0,sizeof(mSharedStack->buffers));
for (int i=0 ; i<num ; i++) {
mBufferList.add(i);
mSharedStack->index[i] = i;
}
}
原来SharedBufferServer的构造函数主要是设置SBT的一些参数。
SharedBufferClient
SharedBufferClient也是在nativeSurface的init函数中创建的,来看SharedBufferClient的构造函数:
SharedBufferClient::SharedBufferClient(SharedClient* sharedClient,
int surface, int num, int32_tidentity)
: SharedBufferBase(sharedClient,surface, identity),
mNumBuffers(num), tail(0)
{
SharedBufferStack& stack(*mSharedStack );
tail = computeTail();
queued_head = stack.head;
}
再看computeTail():
int32_tSharedBufferClient::computeTail() const
{
SharedBufferStack& stack(*mSharedStack );
return (mNumBuffers + stack.head -stack.available + 1) % mNumBuffers; //返回0
}
这样,SBS和SBC的创建就设置了tail(BackBuffer)的索引为0,head(FrontBuffer)的索引为1。
请看SBT、SBC和SBS的关系图
客户端的一个Surface对应SF端的一个Layer,SF端的SharedClient成员有一个包含31个SBT元素的数组,客户端每申请创建一个Surface就会消耗一个SBT,SF端对应的会创建一个Layer。而客户端的Surface(nativeSurface)包含一个SharedBufferClient对象,SF端的Layer包含一个SharedBufferServer对象。就这样,系统通过客户端的SBC和SF端的SBS控制着作图缓冲区的交换,而具体的控制参数是保存在SBT中的。
SBC的dequeue、lock和queue:
dequeue:根据tail计算本次应当使用的画图Buffer的编号
lock:确保dequeue返回的Buffer编号没有被SF当作FrontBuffer使用
queue:作图完毕后更新参数,以便下次能获取到另一块作图Buffer
相关文章推荐
- 分析SurfaceFlinger过程遇到的知识点
- 深入分析虚拟机在Java堆中对象分配、布局和访问的全过程
- SurfaceFlinger启动过程分析(二)
- Android应用程序窗口(Activity)的窗口对象(Window)的创建过程分析
- 利用postgresql进行缓冲区内对象检测过程中遇到的sql查询效率问题解决方案记录
- [项目过程中所遇到的各种问题记录]ORM篇——使用NHibernate配置对象实体的一些小问题 22
- Android SurfaceFlinger服务代理对象获取过程源码分析
- Android系统Surface机制的SurfaceFlinger服务渲染应用程序UI的过程分析(2)
- 分析驱动程序在IRQL>=DISPATCH_LEVEL时和DPC过程中不能用KeWaitForSingleObject等待对象的原因
- 面向对象分析过程案例实战
- Android应用程序与SurfaceFlinger服务的连接过程分析
- SurfaceFlinger启动过程分析
- Android应用程序窗口(Activity)的窗口对象(Window)的创建过程分析
- Android应用程序与SurfaceFlinger服务之间的共享UI元数据(SharedClient)的创建过程分析
- COM对象创建过程详细分析
- MyBatis运行原理(二)SqlSession对象创建过程分析
- SurfaceFlinger启动过程分析(三)
- Android 8.0系统源码分析--Activity的窗口Window对象添加过程源码分析
- ART运行时为新创建对象分配内存的过程分析
- Android应用程序窗口(Activity)的窗口对象(Window)的创建过程分析