分析SurfaceFlinger过程中遇到的对象

 注:本文有部分内容并非原创,感谢原来的作者以及红黑联盟的参考图!


    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交给JAVA 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交给JAVA 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时调用的,它的作用是调用SFcreateUserClient,进而调用UserClient的构造函数创建了SharedClient.



native Surace请求GraphicBuffer
    这里将ClientSurfaceGraphicBuffer的创建过程以时序图的形式展现出来。
 

    这里需要注意的是,nativeSurface2GraphicBuffer只有在lock()时才会去创建,而不是在nativeSurface被创建的时候创建的

现在在客户端的native层有3个对象:SurfaceControlnativeSurfaceSurfaceClient那么,它们里面之间的关系是怎样的呢?请看它们的成员变量:

SurfaceControl

mClient:SurfaceComposerClient

mSurface:ISurface


Surface

mClient:SurfaceClient

mSurface:SurfaceControl->mSurface

mSharedBufferClient

mBufferMapper


SurfaceClient

mClient:sf->createClientConnection()

*mControl:SharedClient

mControl:IMemoryHeap




SharedBufferStackSharedBufferClientSharedBufferServer,简称为SBTSBCSBS

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);
2android的图形系统中提供了两个显示BuffernativeSurface2GraphicBuffer2Buffer其中一个显示,称之为FrontBuffer,另外一个交给ViewRoot去绘制窗口,称之为BackBuffer。等BackBuffer绘制完成,SurfaceFlinger在将两者调换,这样就大大提高了显示的效率。
sharedBufferStack第二个很重要的作用就是提供了一套机制来实现这个调换的过程,以保证提供给ViewRootBuffer符合当前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 postSBC投递的脏缓冲个数)

volatile int32_t inUse; //buffer currently in use by SFSBS正在使用的缓冲编号)
    这几个变量的值来确定nativeSurfaceGraphicBuffer的索引,其中SharedBufferClient::tail记录的是BackBuffer的索引;SharedBufferStack::head记录的是FrontBuffer的索引。



SharedBufferServer

SharedBufferServer是在nativeSurfaceinit函数中间接创建的:

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也是在nativeSurfaceinit函数中创建的,来看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

}


这样,SBSSBC的创建就设置了tailBackBuffer)的索引为0headFrontBuffer)的索引为1


请看SBTSBCSBS的关系图


    客户端的一个Surface对应SF端的一个LayerSF端的SharedClient成员有一个包含31SBT元素的数组,客户端每申请创建一个Surface就会消耗一个SBTSF端对应的会创建一个Layer。而客户端的SurfacenativeSurface)包含一个SharedBufferClient对象,SF端的Layer包含一个SharedBufferServer对象。就这样,系统通过客户端的SBCSF端的SBS控制着作图缓冲区的交换,而具体的控制参数是保存在SBT中的。



SBCdequeuelockqueue

dequeue:根据tail计算本次应当使用的画图Buffer的编号

lock:确保dequeue返回的Buffer编号没有被SF当作FrontBuffer使用

queue:作图完毕后更新参数,以便下次能获取到另一块作图Buffer




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值