Android-Fk:BufferQueue學(xué)習(xí)整理

一. BufferQueue概述

BufferQueue可以理解為一個(gè)生產(chǎn)者-消費(fèi)者”模型,對(duì)GraphicBuffer管理的一種機(jī)制。
需注意的是,可以將BufferQueue當(dāng)作是一個(gè)算法結(jié)構(gòu),并不是只有Surfaceflinger會(huì)使用到,其他進(jìn)程只要有GraphicBuffer的消費(fèi)地方都會(huì)使用到。

二. BufferQueue結(jié)構(gòu)

在這里插入圖片描述

一般是在消費(fèi)者進(jìn)程調(diào)用BufferQueue的createBufferQueue創(chuàng)建BufferQueueCore,BufferQueueProducer和BufferQueueConsumer對(duì)象。
對(duì)應(yīng)著三個(gè)重要部分,數(shù)據(jù),生產(chǎn)者,消費(fèi)者,三者關(guān)系:
在這里插入圖片描述

圖形生產(chǎn)者(如相機(jī),View繪制等)先向BufferQueue申請(qǐng)GraphicBuffer,填充完GraphicBuffer后,將GraphicBuffer移交給BufferQueue,BufferQueue會(huì)通知圖形消費(fèi)者(如Surfaceflinger,ImageReader,GLConsumer等)

BufferQueue采用了binder和共享內(nèi)存機(jī)制,因此可以高效地在進(jìn)程間傳遞圖形數(shù)據(jù),Producer和Consumer可能不在同一進(jìn)程,GraphicBurffer可以看作是一塊共享內(nèi)存。

BufferQueueProducer和BufferQueueConsumer分別實(shí)現(xiàn)了IGraphicBufferProducer和IGraphicBufferConsumer binder接口,

在消費(fèi)者進(jìn)程調(diào)用consumerConnect向BufferQueueCore注冊(cè)IConsumerListener,這樣有新數(shù)據(jù)的時(shí)候就可以通過IConsumerListener的onFrameAvailable()回調(diào)通知對(duì)應(yīng)的消費(fèi)者,
收到通知后,消費(fèi)者通過IGraphicBufferConsumer從BufferQueueCore取出GraphicBuffer,使用完之后將GraphicBuffer放回到BufferQueueCore。

在生產(chǎn)者進(jìn)程獲取到IGraphicBufferProducer接口后,可以通過connect向BufferQueueCore注冊(cè)IProducerListener,這樣在消費(fèi)者將GraphicBuffer放回BufferQueueCore時(shí)可以通知生產(chǎn)者,生產(chǎn)者可以通過IGraphicBufferProducer向BufferQueueCore申請(qǐng)GraphicBuffer,填充完GraphicBuffer后,將GraphicBuffer提交給BufferQueueCore,然后由BufferQueueCore來通知消費(fèi)者。

通過如下接口實(shí)現(xiàn)通知:

void BufferQueue::ProxyConsumerListener::onFrameAvailable(
        const BufferItem& item) {
    sp<ConsumerListener> listener(mConsumerListener.promote());
    if (listener != NULL) {
        listener->onFrameAvailable(item);
    }
}
void BufferQueue::ProxyConsumerListener::onBuffersReleased() {
    sp<ConsumerListener> listener(mConsumerListener.promote());
    if (listener != NULL) {
        listener->onBuffersReleased();
    }
}

三.使用到BufferQueue的場(chǎng)景

3.1 Activity View的顯示

應(yīng)用Activity View界面顯示,界面的Window是GraphicBuffer生產(chǎn)者,不斷dequeue buffer出來往其中寫數(shù)據(jù),SurfaceFlinger是GraphicBuffer的消費(fèi)者,不斷acqure buffer出來合成顯示。


在這里插入圖片描述

BufferLayer創(chuàng)建時(shí):

frameworks/native/services/surfaceflinger/BufferLayer.cpp
void BufferLayer::onFirstRef() {
    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
    sp<IGraphicBufferProducer> producer;//生產(chǎn)者
    sp<IGraphicBufferConsumer> consumer;//消費(fèi)者
    BufferQueue::createBufferQueue(&producer, &consumer, true);//創(chuàng)建Queue
    mProducer = new MonitoredProducer(producer, mFlinger, this);
    mConsumer = new BufferLayerConsumer(consumer,
            mFlinger->getRenderEngine(), mTextureName, this);
    mConsumer->setConsumerUsageBits(getEffectiveUsage(0));
    mConsumer->setContentsChangedListener(this);
    mConsumer->setName(mName);

    if (mFlinger->isLayerTripleBufferingDisabled()) {
        mProducer->setMaxDequeuedBufferCount(2);
    }

    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
    updateTransformHint(hw);
}

3.2 SurfaceTexture

相機(jī)中preview使用到的TextureView中的成員SurfaceTexture就是個(gè)自帶BufferQueue的組建,在消費(fèi)者進(jìn)程,具體之后會(huì)詳細(xì)講述SurfaceTexture。


在這里插入圖片描述

SurfaceTexture初始化:

frameworks/base/core/jni/android/graphics/SurfaceTexture.cpp
static void SurfaceTexture_init(JNIEnv* env, jobject thiz, jboolean isDetached,
        jint texName, jboolean singleBufferMode, jobject weakThiz)
{
    sp<IGraphicBufferProducer> producer;//生產(chǎn)者
    sp<IGraphicBufferConsumer> consumer;//消費(fèi)者
    BufferQueue::createBufferQueue(&producer, &consumer);
    sp<GLConsumer> surfaceTexture;
    ...
        //看出來SurfaceTexture中歐的BufferQueue的消費(fèi)者是一個(gè)GLConsumer
        surfaceTexture = new GLConsumer(consumer, texName,
                GL_TEXTURE_EXTERNAL_OES, true, !singleBufferMode);
    ...


    SurfaceTexture_setSurfaceTexture(env, thiz, surfaceTexture);
    SurfaceTexture_setProducer(env, thiz, producer);

    jclass clazz = env->GetObjectClass(thiz);
    
    sp<JNISurfaceTextureContext> ctx(new JNISurfaceTextureContext(env, weakThiz,
            clazz));
     //設(shè)置監(jiān)聽
    surfaceTexture->setFrameAvailableListener(ctx);
    SurfaceTexture_setFrameAvailableListener(env, thiz, ctx);
}

3.3 ImageReader

相機(jī)中保存圖片的使用的ImageReader也是在消費(fèi)者進(jìn)程,初始化時(shí)及自己創(chuàng)建了BufferQueue,在消費(fèi)者進(jìn)程,及相機(jī)應(yīng)用是消費(fèi)者,具體之后會(huì)詳細(xì)講述ImageReader。


在這里插入圖片描述

ImageReader初始化,如上類似:

frameworks/native/libs/gui/BufferQueueConsumer.cpp
static void ImageReader_init(JNIEnv* env, jobject thiz, jobject weakThiz, jint width, jint height,
                             jint format, jint maxImages, jlong ndkUsage)
{
    sp<JNIImageReaderContext> ctx(new JNIImageReaderContext(env, weakThiz, clazz, maxImages));

    sp<IGraphicBufferProducer> gbProducer;
    sp<IGraphicBufferConsumer> gbConsumer;
    BufferQueue::createBufferQueue(&gbProducer, &gbConsumer);
    sp<BufferItemConsumer> bufferConsumer;
  
    bufferConsumer = new BufferItemConsumer(gbConsumer, consumerUsage, maxImages,
            /*controlledByApp*/true);

    ctx->setBufferConsumer(bufferConsumer);
    bufferConsumer->setName(consumerName);

    ctx->setProducer(gbProducer);
    bufferConsumer->setFrameAvailableListener(ctx);
  
}

四. 總結(jié)

使用BufferQueue的地方還有很多,可以在AOSP代碼里搜"BufferQueue::createBufferQueue",一般創(chuàng)建BufferQueue的是在消費(fèi)者進(jìn)程,GraphicBuffer是在消費(fèi)者進(jìn)程里分配,而一系列的調(diào)用邏輯,無非就是將BufferQueue在初始化時(shí)創(chuàng)建的Producer指針和Consumer指針關(guān)聯(lián)到對(duì)應(yīng)進(jìn)程中的生產(chǎn)者和消費(fèi)者上,這一點(diǎn)下面會(huì)詳述,本篇主要為后面學(xué)習(xí)Surface鋪墊。

參考博客:
http://www.itdecent.cn/p/edd7d264be73
https://blog.csdn.net/u014409795/article/details/51276468

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本篇文章是基于谷歌有關(guān)Graphic的一篇概覽文章的翻譯:http://source.android.com/de...
    lee_3do閱讀 7,433評(píng)論 2 21
  • Android Surface的創(chuàng)建 已經(jīng)大致說了下Surface在三個(gè)進(jìn)程中創(chuàng)建的過程,但是并沒有詳細(xì)的說Sur...
    wbo4958閱讀 15,007評(píng)論 4 36
  • Android系統(tǒng)圖形框架 Android系統(tǒng)圖形框架由下往上主要的包括HAL(HWComposer和Grallo...
    xiabodan閱讀 5,617評(píng)論 0 10
  • 參考:【Android6.0 顯示系統(tǒng)(一) Surface創(chuàng)建】https://blog.csdn.net/kc...
    zZ小菜鳥閱讀 4,556評(píng)論 0 4
  • 敏兒,一直覺得你不夠聰明,既然沒有好的先天,那就認(rèn)真踏實(shí)點(diǎn)來吧。 雖然你的年紀(jì)比較大,但是經(jīng)歷的都差不多呀,不能光...
    小夭ing閱讀 209評(píng)論 0 0

友情鏈接更多精彩內(nèi)容