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

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

欢迎和大家交流。qq:1037701636 email:gzzaigcn2012@gmail.com

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图,帮助下面的分析吧。

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

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的天下。


 


 

 

 

 

 

 

 

 

 


 

 


 


 

 


Android4.2.2 SurfaceFlinger之Layer和Bufferqueue的创建过程,布布扣,bubuko.com

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

上一篇:从Android Bootanimation理解SurfaceFlinger的客户端建立


下一篇:openerp7微信支付开发