Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android4.2.2 SurfaceFlinger之Layer和Bufferqueue的創建過程

Android4.2.2 SurfaceFlinger之Layer和Bufferqueue的創建過程

編輯:關於Android編程

本文均屬自己閱讀源碼的點滴總結,轉賬請注明出處謝謝。

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

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

之前的博文在BootAnimation的基礎上來到了SurfaceFlinger端的Surface的創建過程,具體實現由Client的createSurface來完成。其實所謂在客戶端的Surface在服務端是以Layer圖層的名字存在。

sp 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 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 getResult() const { return result; }
        virtual bool handler() {
            result = flinger->createLayer(params, name, client,
                    w, h, format, flags);//消息處理時創建一個layer
            return true;
        }
    };

    sp msg = new MessageCreateLayer(mFlinger.get(),
            params, name, this, w, h, format, flags);//新建一個MessageCreateLayer對象,賦值給基類
    mFlinger->postMessageSync(msg);//創建layer的消息由SF來完成
    return static_cast( msg.get() )->getResult();
}

該函數的實現看上去貌似有一些復雜,首先創建一個繼承與MessageBase的創建圖層Layer消息類,我們從構造函數分析一步步的入手。

step1:說道SurfaceFlinger側的消息處理機制,即可用回想到之前的博文Android4.2.2 SurfaceFlinger的相關事件和消息處理機制一文,是否知道最終都提交給SF來完成消息的處理。看這個函數mFlinger->postMessageSync(msg),看著就知道是發出一個同步的消息。

status_t SurfaceFlinger::postMessageSync(const sp& 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& 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& 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 SurfaceFlinger::createLayer(
        ISurfaceComposerClient::surface_data_t* params,
        const String8& name,
        const sp& client,
       uint32_t w, uint32_t h, PixelFormat format,
        uint32_t flags)
{
    sp layer;
    sp 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 mLayer;
        virtual void onFrameAvailable() {
            sp that(mLayer.promote());
            if (that != 0) {
                that->onFrameQueued();//調用Layer的onFrameQueued
            }
        }
    };

    // Creates a custom BufferQueue for SurfaceTexture to use
    sp 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 hw(mFlinger->getDefaultDisplayDevice());
    updateTransformHint(hw);
}

在這個函數裡面有個內部結構體FrameQueuedListener,幀隊列監聽。這裡先關注SurfaceTextureLayer和SurfaceTexture兩個類對象,分別代表著BufferQueue和ConsumerBase兩個對象,這裡先直接提出Layer相關的UML圖,幫助下面的分析吧。

\

step4:先來看看SurfaceTextureLayer的構造過程吧:

SurfaceTextureLayer的構造其實是為BufferQueue而服務的,這裡繼續看BufferQueue這個核心類的構造過程吧。

BufferQueue::BufferQueue(bool allowSynchronousMode,
        const sp& 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 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 SurfaceFlinger::createGraphicBufferAlloc()
{
    sp gba(new GraphicBufferAlloc());//圖形緩存的申請
    return gba;
}

由SF創建的圖像緩存被保存在BufferQueue的成員變量裡面。

step5:接著看SurfaceTexture類,即所謂的表面紋理。該類繼承了ConsumerBase,所謂的消費者模式,這裡主要指的是對圖形緩存的渲染。

ConsumerBase::ConsumerBase(const sp& 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 listener;
    sp proxy;
    listener = static_cast(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) :
    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 LayerBaseClient::getSurface()
{
    sp 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 Layer::createSurface()
{
    class BSurface : public BnSurface, public LayerCleaner {
        wp mOwner;
        virtual sp getSurfaceTexture() const {
            sp res;
            sp that( mOwner.promote() );
            if (that != NULL) {
                res = that->mSurfaceTexture->getBufferQueue();//調用類SurfaceTexture的基類ConsumerBase
            }
            return res;//返回的是mBufferQueue,類為SurfaceTexturelayer
        }
    public:
        BSurface(const sp& flinger,
                const sp& layer)
            : LayerCleaner(flinger, layer), mOwner(layer) { }
    };
    sp sur(new BSurface(mFlinger, this));
    return sur;
}

最終返回的實際是一個內部類BSurface,繼承了BnSurface,故也是一個本地的BBinder。後面一定會用他來進行Binder間的通信。

step7:到這裡就返回到了BootAnimation的readyToRun函數:

        sp surface = mClient->createSurface(&data, name,
                w, h, format, flags);//對應的由SF側的錍lient來完成, BpSurface

最終返回的可以看到是一個BpSurface類對象,和上面說的Binder通信相呼應起來。surface對象的創建最終都提交給了SurfaceControl,都交給他來進行進一步的界面操作。


step8:接著看 sp s = control->getSurface();通過上面新建的sufacecontrol類對象,來獲得Surface

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

那麼這個Surface類到底做了什麼呢?看構造函數:

Surface::Surface(const sp& surface)
    : SurfaceTextureClient(),//父類調用SurfaceTextureClient::init();完成ANativeWindow的初始化
      mSurface(surface->mSurface),
      mIdentity(surface->mIdentity)
{
    sp st;
    if (mSurface != NULL) {
        st = mSurface->getSurfaceTexture();//調用BpSurface,獲得遠程的Bnsurface處理後的BpSurfaceTexture
    }
    init(st);//Surface初始化
}

看到這個SurfaceTexture是否有些熟悉,的確剛才在step5裡講到SF側在Layer對象創建是會創建相關的表面紋理對象,這應該是在客戶端側的一個操作類對象,看看其初始化過程:

class SurfaceTextureClient
    : public ANativeObjectBase
{
public:

    SurfaceTextureClient(const sp& 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 getSurfaceTexture() const {
            sp res;
            sp 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 getBufferQueue() const {
        return mBufferQueue;
    }

即最終getSurfaceTexture,所謂的表面紋理獲取就是直接返回了BufferQueue。而BufferQueue剛好繼承了BpSurfaceTexture,且以匿名Binder對象返回到應用程序的客戶端。

    BpSurface(const sp& impl)
        : BpInterface(impl)
    {
    }

    virtual sp getSurfaceTexture() const {
        Parcel data, reply;
        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
        remote()->transact(GET_SURFACE_TEXTURE, data, &reply);
        return interface_cast(reply.readStrongBinder());//在客戶端是BpSurfaceTexture,服務端是SurfaceTextureLayer
    }
};

即返回的是一個BpSurfaceTexture,而會最終在init(st)裡實現,維護到SurfaceTextureClient中去:

void Surface::init(const sp& 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的天下。






						
		
	
				
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved