当前位置: 代码迷 >> Android >> Android4.2.2 SurfaceFlinger之Layer跟Bufferqueue的创建过程
  详细解决方案

Android4.2.2 SurfaceFlinger之Layer跟Bufferqueue的创建过程

热度:74   发布时间:2016-04-28 06:27:46.0
Android4.2.2 SurfaceFlinger之Layer和Bufferqueue的创建过程

本文均属自己阅读源码的点滴总结,转账请注明出处谢谢。

欢迎和大家交流。qq:1037701636 email:[email protected]

Android源码版本Version:4.2.2; 硬件平台 全志A31

 

之前的博文在BootAnimation的基础上来到了SurfaceFlinger端的Surface的创建过程,具体实现由Client的createSurface来完成。其实所谓在客户端的Surface在服务端是以Layer图层的名字存在。

sp<ISurface> Client::createSurface(        ISurfaceComposerClient::surface_data_t* params,        const String8& name,        uint32_t w, uint32_t h, PixelFormat format,        uint32_t flags){    /*     * createSurface must be called from the GL thread so that it can     * have access to the GL context.     */    class MessageCreateLayer : public MessageBase {        sp<ISurface> result;        SurfaceFlinger* flinger;        ISurfaceComposerClient::surface_data_t* params;        Client* client;        const String8& name;        uint32_t w, h;        PixelFormat format;        uint32_t flags;    public:        MessageCreateLayer(SurfaceFlinger* flinger,                ISurfaceComposerClient::surface_data_t* params,                const String8& name, Client* client,                uint32_t w, uint32_t h, PixelFormat format,                uint32_t flags)            : flinger(flinger), params(params), client(client), name(name),              w(w), h(h), format(format), flags(flags)        {        }        sp<ISurface> getResult() const { return result; }        virtual bool handler() {            result = flinger->createLayer(params, name, client,                    w, h, format, flags);//消息处理时创建一个layer            return true;        }    };    sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),            params, name, this, w, h, format, flags);//新建一个MessageCreateLayer对象,赋值给基类    mFlinger->postMessageSync(msg);//创建layer的消息由SF来完成    return static_cast<MessageCreateLayer*>( msg.get() )->getResult();}

该函数的实现看上去貌似有一些复杂,首先创建一个继承与MessageBase的创建图层Layer消息类,我们从构造函数分析一步步的入手。

 

step1:说道SurfaceFlinger侧的消息处理机制,即可用回想到之前的博文Android4.2.2 SurfaceFlinger的相关事件和消息处理机制一文,是否知道最终都提交给SF来完成消息的处理。看这个函数mFlinger->postMessageSync(msg),看着就知道是发出一个同步的消息。

status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,        nsecs_t reltime, uint32_t flags) {    status_t res = mEventQueue.postMessage(msg, reltime);    if (res == NO_ERROR) {        msg->wait();    }    return res;}

果然这里使用了SF的成员变量MessageQueue mEventQueue来发送消息

status_t MessageQueue::postMessage(        const sp<MessageBase>& messageHandler, nsecs_t relTime){    const Message dummyMessage;    if (relTime > 0) {        mLooper->sendMessageDelayed(relTime, messageHandler, dummyMessage);    } else {        mLooper->sendMessage(messageHandler, dummyMessage);//使用looper发送消息,向消息队列发送消息    }    return NO_ERROR;}
void Looper::sendMessage(const sp<MessageHandler>& handler, const Message& message) {    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);    sendMessageAtTime(now, handler, message); //及时发送消息}

这里传入的重点是messageHanler这个变量理解为消息句柄,按照这个调用流程实际是MessageCreateLayer这个对象。

到了这里基本就和之前的SF消息处理机制的RefreshEvent相似起来了,可以查看我对SF的消息和事件处理机制总结出来的图,最终还是回到

handler->handleMessage(message);//MessageHandler消息的handle处理,那么这里对应的这个handle是什么呢,又如何调用handleMessage呢,我们发现在这里:

void MessageBase::handleMessage(const Message&) {    this->handler();//调用继承类的多态的handle,this指向最初的对象,基类指针访问派生类对象时,调用派生类的函数    barrier.open();};

上述的msg传入分别转为MessageBase,在转为MessageHandle。而我们知道他处于这个逐级继承的关系,而MessageBase的成员函数MessageHandle并没有被继承重载故这个MessageCreateLayer对象msg实际调用的是MessageBase的handleMessage,而这个函数的实现内部调用了this->handle,容易知道这个handleMessage实际是被继承到了MessageCreateLayer类的msg这个对象中。因此最终回到了MessageCreateLayer的handle之中。

 

step2.转了这么多弯路,从Client侧调用createSurface再打发送消息让SurfaceFlinger进行消息处理,再回到MessageCreateLayer的handle,而handle处理中却发现实际还是把处理提交给了SurfaceFlinger。

        virtual bool handler() {            result = flinger->createLayer(params, name, client,                    w, h, format, flags);//消息处理时创建一个layer            return true;        }

接着看SurfaceFlinger的createLayer函数:

sp<ISurface> SurfaceFlinger::createLayer(        ISurfaceComposerClient::surface_data_t* params,        const String8& name,        const sp<Client>& client,       uint32_t w, uint32_t h, PixelFormat format,        uint32_t flags){    sp<LayerBaseClient> layer;    sp<ISurface> surfaceHandle;    if (int32_t(w|h) < 0) {        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",                int(w), int(h));        return surfaceHandle;    }    //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {        case ISurfaceComposerClient::eFXSurfaceNormal:            layer = createNormalLayer(client, w, h, flags, format);//new创建一个layer,指向layer            break;        case ISurfaceComposerClient::eFXSurfaceBlur:        case ISurfaceComposerClient::eFXSurfaceDim:            layer = createDimLayer(client, w, h, flags);            break;        case ISurfaceComposerClient::eFXSurfaceScreenshot:            layer = createScreenshotLayer(client, w, h, flags);            break;    }    if (layer != 0) {        layer->initStates(w, h, flags);        layer->setName(name);        ssize_t token = addClientLayer(client, layer);//把这个layer层添加到client中并加入Z轴        surfaceHandle = layer->getSurface();//通过Layer        if (surfaceHandle != 0) {            params->token = token;            params->identity = layer->getIdentity();//layer图层的id        }        setTransactionFlags(eTransactionNeeded);    }    return surfaceHandle;}


 step3 : createNormalLayer函数处理,实际的Layer图层对象建立所在。

 里看Layer的成员函数onFirstRef():

void Layer::onFirstRef(){    LayerBaseClient::onFirstRef();//基类LayerBaseClient    struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener {//内部类继承FrameAvailableListener        FrameQueuedListener(Layer* layer) : mLayer(layer) { }    private:        wp<Layer> mLayer;        virtual void onFrameAvailable() {            sp<Layer> that(mLayer.promote());            if (that != 0) {                that->onFrameQueued();//调用Layer的onFrameQueued            }        }    };    // Creates a custom BufferQueue for SurfaceTexture to use    sp<BufferQueue> bq = new SurfaceTextureLayer();//新建一个SurfaceTextureLayer,即BufferQueue    mSurfaceTexture = new SurfaceTexture(mTextureName, true,            GL_TEXTURE_EXTERNAL_OES, false, bq);    mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));    mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));//新建立一个帧队列监听    mSurfaceTexture->setSynchronousMode(true);//支持同步模式#ifdef TARGET_DISABLE_TRIPLE_BUFFERING#warning "disabling triple buffering"    mSurfaceTexture->setDefaultMaxBufferCount(2);#else    mSurfaceTexture->setDefaultMaxBufferCount(3);#endif    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());    updateTransformHint(hw);}

在这个函数里面有个内部结构体FrameQueuedListener,帧队列监听。这里先关注SurfaceTextureLayer和SurfaceTexture两个类对象,分别代表着BufferQueue和ConsumerBase两个对象,这里先直接提出Layer相关的UML图,帮助下面的分析吧。

step4:先来看看SurfaceTextureLayer的构造过程吧:

SurfaceTextureLayer的构造其实是为BufferQueue而服务的,这里继续看BufferQueue这个核心类的构造过程吧。

BufferQueue::BufferQueue(bool allowSynchronousMode,        const sp<IGraphicBufferAlloc>& allocator) :  .......    mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888),    mConsumerUsageBits(0),    mTransformHint(0){    // Choose a name using the PID and a process-unique ID.    mConsumerName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());    ST_LOGV("BufferQueue");    if (allocator == NULL) {        sp<ISurfaceComposer> composer(ComposerService::getComposerService());        mGraphicBufferAlloc = composer->createGraphicBufferAlloc();//创建GraphicBuffer        if (mGraphicBufferAlloc == 0) {            ST_LOGE("createGraphicBufferAlloc() failed in BufferQueue()");        }    } else {        mGraphicBufferAlloc = allocator;    }}

BufferQueue缓存队列的创建在于又一次调用SF(ComposerService::getComposerService是熟悉的BpSurfaceComposer,即SF在客户端的代理)来完成图形缓冲区的申请和分配,通过SF端的GraphicBufferAllocation来完成。实现如下:

sp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc(){    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());//图形缓存的申请    return gba;}

由SF创建的图像缓存被保存在BufferQueue的成员变量里面。

 

step5:接着看SurfaceTexture类,即所谓的表面纹理。该类继承了ConsumerBase,所谓的消费者模式,这里主要指的是对图形缓存的渲染。

ConsumerBase::ConsumerBase(const sp<BufferQueue>& bufferQueue) :        mAbandoned(false),        mBufferQueue(bufferQueue) {    // Choose a name using the PID and a process-unique ID.    mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());    // Note that we can't create an sp<...>(this) in a ctor that will not keep a    // reference once the ctor ends, as that would cause the refcount of 'this'    // dropping to 0 at the end of the ctor.  Since all we need is a wp<...>    // that's what we create.    wp<BufferQueue::ConsumerListener> listener;    sp<BufferQueue::ConsumerListener> proxy;    listener = static_cast<BufferQueue::ConsumerListener*>(this);    proxy = new BufferQueue::ProxyConsumerListener(listener);//新建一个监听代理    status_t err = mBufferQueue->consumerConnect(proxy);//创建一个ConsumerListener代理    if (err != NO_ERROR) {        CB_LOGE("SurfaceTexture: error connecting to BufferQueue: %s (%d)",                strerror(-err), err);    } else {        mBufferQueue->setConsumerName(mName);    }}

看到这里有监听和代理两个变量,listener直接从之前创建的Bufferqueue转换过来,而proxy这里是创建一个监听的远程代理,并保存在BufferQueue的mConsumerListener变量中。

 

接着看SurfaceTexture类的构造函数:

SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode,        GLenum texTarget, bool useFenceSync, const sp<BufferQueue> &bufferQueue) :    ConsumerBase(bufferQueue == 0 ? new BufferQueue(allowSynchronousMode) : bufferQueue),    mCurrentTransform(0),    mCurrentTimestamp(0),    mFilteringEnabled(true),    mTexName(tex),#ifdef USE_FENCE_SYNC    mUseFenceSync(useFenceSync),#else    mUseFenceSync(false),#endif    mTexTarget(texTarget),    mEglDisplay(EGL_NO_DISPLAY),    mEglContext(EGL_NO_CONTEXT),    mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT),    mAttached(true){    ST_LOGV("SurfaceTexture");    memcpy(mCurrentTransformMatrix, mtxIdentity,            sizeof(mCurrentTransformMatrix));    mBufferQueue->setConsumerUsageBits(DEFAULT_USAGE_FLAGS);}

 回到Layer类的构造函数,mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this))分析这个处理过程,新建一个帧队列监听保存到Layer对象的mFrameAvailableListener中。

 

step6:在完成Layer对象的初始化后,调用了这个status_t err = layer->setBuffers(w, h, format, flags);设置相关Buffer的信息。再回到SurfaceFlinger::createLayer这个最初的Layer调用函数这里,分析下面几个函数:

        ssize_t token = addClientLayer(client, layer);//把这个layer层添加到client中并加入Z轴        surfaceHandle = layer->getSurface();//通过Layer

将上面创建好的Layer对象和当前在和客户端交互的Client关联在一起。而这个surfaceHandle是最终返回给客户端请求的Surface对象,这里需要注意的是getSurface的对象layer是Layer派生类,继承了LayerBaseClient,发现getSuface没有被重载,则如下调用

sp<ISurface> LayerBaseClient::getSurface(){    sp<ISurface> s;    Mutex::Autolock _l(mLock);    LOG_ALWAYS_FATAL_IF(mHasSurface,            "LayerBaseClient::getSurface() has already been called");    mHasSurface = true;    s = createSurface();//调用派生类的createSurface函数    mClientSurfaceBinder = s->asBinder();//BBinder    return s;}

而这里的createSurface其实是this->createSurface,故重载后基类函数调用成员函数时调用的是派生类的该成员函数createSurface

sp<ISurface> Layer::createSurface(){    class BSurface : public BnSurface, public LayerCleaner {        wp<const Layer> mOwner;        virtual sp<ISurfaceTexture> getSurfaceTexture() const {            sp<ISurfaceTexture> res;            sp<const Layer> that( mOwner.promote() );            if (that != NULL) {                res = that->mSurfaceTexture->getBufferQueue();//调用类SurfaceTexture的基类ConsumerBase            }            return res;//返回的是mBufferQueue,类为SurfaceTexturelayer        }    public:        BSurface(const sp<SurfaceFlinger>& flinger,                const sp<Layer>& layer)            : LayerCleaner(flinger, layer), mOwner(layer) { }    };    sp<ISurface> sur(new BSurface(mFlinger, this));    return sur;}

最终返回的实际是一个内部类BSurface,继承了BnSurface,故也是一个本地的BBinder。后面一定会用他来进行Binder间的通信。

 

step7:到这里就返回到了BootAnimation的readyToRun函数:

        sp<ISurface> surface = mClient->createSurface(&data, name,                w, h, format, flags);//对应的由SF侧的錍lient来完成, BpSurface

最终返回的可以看到是一个BpSurface类对象,和上面说的Binder通信相呼应起来。surface对象的创建最终都提交给了SurfaceControl,都交给他来进行进一步的界面操作。


 step8:接着看 sp<Surface> s = control->getSurface();通过上面新建的sufacecontrol类对象,来获得Surface

sp<Surface> SurfaceControl::getSurface() const{    Mutex::Autolock _l(mLock);    if (mSurfaceData == 0) {        sp<SurfaceControl> surface_control(const_cast<SurfaceControl*>(this));        mSurfaceData = new Surface(surface_control);    }    return mSurfaceData;}

那么这个Surface类到底做了什么呢?看构造函数:

Surface::Surface(const sp<SurfaceControl>& surface)    : SurfaceTextureClient(),//父类调用SurfaceTextureClient::init();完成ANativeWindow的初始化      mSurface(surface->mSurface),      mIdentity(surface->mIdentity){    sp<ISurfaceTexture> st;    if (mSurface != NULL) {        st = mSurface->getSurfaceTexture();//调用BpSurface,获得远程的Bnsurface处理后的BpSurfaceTexture    }    init(st);//Surface初始化}

看到这个SurfaceTexture是否有些熟悉,的确刚才在step5里讲到SF侧在Layer对象创建是会创建相关的表面纹理对象,这应该是在客户端侧的一个操作类对象,看看其初始化过程:

class SurfaceTextureClient    : public ANativeObjectBase<ANativeWindow, SurfaceTextureClient, RefBase>{public:    SurfaceTextureClient(const sp<ISurfaceTexture>& surfaceTexture);

这个类继承了一个ANativeWindow,理解为本地的窗口,也就是说在客户端这边将直接对其进行相关的操作。

SurfaceTextureClient::SurfaceTextureClient() {    SurfaceTextureClient::init();}
void SurfaceTextureClient::init() {    // Initialize the ANativeWindow function pointers.    ANativeWindow::setSwapInterval  = hook_setSwapInterval;    ANativeWindow::dequeueBuffer    = hook_dequeueBuffer;    ANativeWindow::cancelBuffer     = hook_cancelBuffer;    ANativeWindow::queueBuffer      = hook_queueBuffer;    ANativeWindow::query            = hook_query;    ANativeWindow::perform          = hook_perform;    ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;    ANativeWindow::cancelBuffer_DEPRECATED  = hook_cancelBuffer_DEPRECATED;    ANativeWindow::lockBuffer_DEPRECATED    = hook_lockBuffer_DEPRECATED;    ANativeWindow::queueBuffer_DEPRECATED   = hook_queueBuffer_DEPRECATED;//本地窗口ANativeWindow函数的回调初始化......}

上述是整个构造函数,只是完成了本地窗口ANativeWindow的回调初始化,后续对缓冲区等的操作都是在这些函数中。

接着看mSurface->getSurfaceTexture():这里的mSurface就是之前在调用SurfaceComposerClient::createSurface完成的,之前分析的是服务端在本地的一个BSurface匿名服务代理,故这里会由BnSurface来完成。

status_t BnSurface::onTransact(    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){    switch(code) {        case GET_SURFACE_TEXTURE: {            CHECK_INTERFACE(ISurface, data, reply);            reply->writeStrongBinder( getSurfaceTexture()->asBinder() );            return NO_ERROR;        }        default:            return BBinder::onTransact(code, data, reply, flags);    }}

他的意义在于最终返回是的BpSurfaceTexture,使得客户端也有了自己的表面纹理对象。

virtual sp<ISurfaceTexture> getSurfaceTexture() const {            sp<ISurfaceTexture> res;            sp<const Layer> that( mOwner.promote() );            if (that != NULL) {                res = that->mSurfaceTexture->getBufferQueue();//调用类SurfaceTexture的基类ConsumerBase            }            return res;//返回的是mBufferQueue,类为SurfaceTexturelayer        }

可以看到这个that->mSurfaceTexture->getBufferQueue(),that是之前创建的Layer对象,而mSUrfaceTexture是在SurfaceTextureLayer(BufferQueue所在)

    sp<BufferQueue> getBufferQueue() const {        return mBufferQueue;    }

即最终getSurfaceTexture,所谓的表面纹理获取就是直接返回了BufferQueue。而BufferQueue刚好继承了BpSurfaceTexture,且以匿名Binder对象返回到应用程序的客户端。
 

    BpSurface(const sp<IBinder>& impl)        : BpInterface<ISurface>(impl)    {    }    virtual sp<ISurfaceTexture> getSurfaceTexture() const {        Parcel data, reply;        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());        remote()->transact(GET_SURFACE_TEXTURE, data, &reply);        return interface_cast<ISurfaceTexture>(reply.readStrongBinder());//在客户端是BpSurfaceTexture,服务端是SurfaceTextureLayer    }};

即返回的是一个BpSurfaceTexture,而会最终在init(st)里实现,维护到SurfaceTextureClient中去:

void Surface::init(const sp<ISurfaceTexture>& surfaceTexture){    if (mSurface != NULL || surfaceTexture != NULL) {        ALOGE_IF(surfaceTexture==0, "got a NULL ISurfaceTexture from ISurface");        if (surfaceTexture != NULL) {            setISurfaceTexture(surfaceTexture);//mSurfaceTexture = surfaceTexture;            setUsage(GraphicBuffer::USAGE_HW_RENDER);        }......}

经过上面的分析可以知道,这个BpSurfaceTexture匿名的Binder客户端将又回请求BnSurfaceTexture去完成一些任务了,实际上将会是BufferQueue的天下。


 


 

 

 

 

 

 

 

 

 


 

 


 


 

 

  相关解决方案