一. 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