- 前言
- 介绍
- BufferQueue::createBufferQueue
结合前面的一篇文章创建Surface, 我们知道最后会调用到SurfaceFlinger的CreateLayer() 方法,然后会层层调用到 BufferQueue::createBufferQueue(),今天我们就来理理BufferQueue。
介绍首先我们要知道BufferQueue的大致工作原理,一个surface会和一个Producer及生产者App进行绑定去产生view数据,然后会通过onframeAvailable的监听通知Consumer及SurfaceFlinger进行合成消费掉。
大致流程如下:
1、生产者这里假定是App(相机的模式是App是消费者),App持有的Surface会先dequeue一块buffer,此时改Buffer的状态是DEQUEUE, App就可以对这块buffer进行数据填充了,在没有dequeue的时候,改buffer的持有者是bufferQueue;
2、app进行了数据填充之后,调用producerBuffer的queueBuffer方法,进行queue操作,此时buffer的状态由DEQUEUE 变为了 QUEUE, buffer的持有者又回到了BufferQueue;
注意:这个时候app通过producer代理对象进行queue操作后,producer本地对象会回调BufferQueue的onframeAvailable函数,通知消费者有可用的buffer已经就绪了,你可以拿去用了。
3、消费者surfaceFlinger 收到onframeAvailable之后, 这个时候surfaceFlinger就进行acquire操作将buffer拿过来,此时buffer的状态由QUEUED->ACQUIRED转变,buffer的拥有者由BufferQueue变成surfaceFlinger.
4、当surfaceFlinger已经消费了这块buffer(已经合成,已经编码等),就进行release操作释放buffer,将buffer归还给BufferQueue,buffer状态由ACQUIRED变成FREE.buffer拥有者由surfaceFlinger变成BufferQueue.
BufferQueue::createBufferQueueframeworks/native/services/surfaceflinger/BufferLayer.cpp
void BufferLayer::onFirstRef() {
Layer::onFirstRef();
// Creates a custom BufferQueue for SurfaceFlingerConsumer to use
// 这里producer consumer分别会在createBufferQueue中进行赋值
sp producer;
sp consumer;
BufferQueue::createBufferQueue(&producer, &consumer, true);
mProducer = new MonitoredProducer(producer, mFlinger, this);
{
// Grab the SF state lock during this since it's the only safe way to access RenderEngine
Mutex::Autolock lock(mFlinger->mStateLock);
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 hw(mFlinger->getDefaultDisplayDevice());
updateTransformHint(hw);
}
frameworks/native/libs/gui/BufferQueue.cpp
void BufferQueue::createBufferQueue(sp* outProducer, sp * outConsumer, bool consumerIsSurfaceFlinger) { LOG_ALWAYS_FATAL_IF(outProducer == NULL, "BufferQueue: outProducer must not be NULL"); LOG_ALWAYS_FATAL_IF(outConsumer == NULL, "BufferQueue: outConsumer must not be NULL"); // 这里会先new 一个 BufferQueueCore,这个BufferQueueCore就是producer和consumer之间一个重要的桥梁 sp core(new BufferQueueCore()); LOG_ALWAYS_FATAL_IF(core == NULL, "BufferQueue: failed to create BufferQueueCore"); // new producer sp producer(new BufferQueueProducer(core, consumerIsSurfaceFlinger)); LOG_ALWAYS_FATAL_IF(producer == NULL, "BufferQueue: failed to create BufferQueueProducer"); // new consumer sp consumer(new BufferQueueConsumer(core)); LOG_ALWAYS_FATAL_IF(consumer == NULL, "BufferQueue: failed to create BufferQueueConsumer"); // 之后分别赋值 *outProducer = producer; *outConsumer = consumer; }
从上面我们目前得到了producer 和 consumer的对象,在返回到 BufferLayer::onFirstRef的方法中。
BufferQueue::createBufferQueue(&producer, &consumer, true);
// 之后将 producer对象给到了 MonitoredProducer,而将mProducer提供给了Surface进行操作,这里的
// MonitoredProducer其实是producer对象的代理类,以便在销毁时通知SurfaceFlinger。
mProducer = new MonitoredProducer(producer, mFlinger, this);
{
// Grab the SF state lock during this since it's the only safe way to access RenderEngine
Mutex::Autolock lock(mFlinger->mStateLock);
// BufferLayerConsumer继承自 Consumerbase,Consumerbase持有IGraphicBufferConsumer的对象,
// 所以最后的方法调用都会通知到IGraphicBufferConsumer,我们继续跟一下 BufferLayerConsumer的构造
mConsumer = new BufferLayerConsumer(consumer, mFlinger->getRenderEngine(), mTextureName,
this);
}
frameworks/native/services/surfaceflinger/BufferLayerConsumer.cpp
BufferLayerConsumer::BufferLayerConsumer(const sp& bq, RE::RenderEngine& engine, uint32_t tex, Layer* layer) // 调用到了父类 : Consumerbase(bq, false), ... ... }
frameworks/native/libs/gui/Consumerbase.cpp
Consumerbase::Consumerbase(const sp& bufferQueue, bool controlledByApp) : mAbandoned(false), // 在bufferLayer中得到的Consumer对象给了mConsumer mConsumer(bufferQueue), mPrevFinalReleaseFence(Fence::NO_FENCE) { // 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 = static_cast (this); sp proxy = new BufferQueue::ProxyConsumerListener(listener); // Consumerbase继承自ConsumerListener,而ProxyConsumerListener持有 Consumerbase的对象 // BufferQueueConsumer中又持有BufferQueueCore, 而BufferQueueCore又持有IConsumerListener,那就意 // 味者后面proxy这个监听最后给到了BufferQueueCore的listen中,我知道大家还有点糊涂,我先摆明这个监听的最后接受者是BufferQueueCore中的mConsumerListener。 status_t err = mConsumer->consumerConnect(proxy, controlledByApp); if (err != NO_ERROR) { CB_LOGE("Consumerbase: error connecting to BufferQueue: %s (%d)", strerror(-err), err); } else { mConsumer->setConsumerName(mName); } }
/frameworks/native/libs/gui/BufferQueueCore.cpp
// 这个方法是在头文件里面BufferQueueCore.h
virtual status_t consumerConnect(const sp& consumer,
bool controlledByApp) {
return connect(consumer, controlledByApp);
}
status_t BufferQueueConsumer::connect(
const sp& consumerListener, bool controlledByApp) {
ATRACE_CALL();
if (consumerListener == NULL) {
BQ_LOGE("connect: consumerListener may not be NULL");
return BAD_VALUE;
}
BQ_LOGV("connect: controlledByApp=%s",
controlledByApp ? "true" : "false");
Mutex::Autolock lock(mCore->mMutex);
if (mCore->mIsAbandoned) {
BQ_LOGE("connect: BufferQueue has been abandoned");
return NO_INIT;
}
// 这里看到了吧,当又人来调用,mCore->mConsumerListener的方法的时候,最后就会调到Consumerbase
// 而我们前面都知道mCore分别给到了producer和consumer中,那就意味BufferQueueCore是producer和consumer之间的桥梁。
mCore->mConsumerListener = consumerListener;
mCore->mConsumerControlledByApp = controlledByApp;
return NO_ERROR;
}
我们再往回推一下,当producer调用到onframeAvailable的时候就会调用到Consumerbase的onframeAvailable方法。
void Consumerbase::onframeAvailable(const BufferItem& item) {
CB_LOGV("onframeAvailable");
sp listener;
{ // scope for the lock
Mutex::Autolock lock(mframeAvailableMutex);
listener = mframeAvailableListener.promote();
}
if (listener != NULL) {
CB_LOGV("actually calling onframeAvailable");
// 这个listen来自哪里呢?我们看看mframeAvailableListener在哪里赋值
listener->onframeAvailable(item);
}
}
void Consumerbase::setframeAvailableListener(
const wp& listener) {
CB_LOGV("setframeAvailableListener");
Mutex::Autolock lock(mframeAvailableMutex);
mframeAvailableListener = listener;
}
frameworks/native/services/surfaceflinger/BufferLayerConsumer.cpp
// BufferLayerConsumer 继承自 Consumerbase, 那么只要调到setContentsChangedListener就会调到setframeAvailableListener void BufferLayerConsumer::setContentsChangedListener(const wp& listener) { setframeAvailableListener(listener); Mutex::Autolock lock(mMutex); mContentsChangedListener = listener; }
frameworks/native/services/surfaceflinger/BufferLayer.cpp
void BufferLayer::onFirstRef() {
Layer::onFirstRef();
// Creates a custom BufferQueue for SurfaceFlingerConsumer to use
sp producer;
sp consumer;
BufferQueue::createBufferQueue(&producer, &consumer, true);
mProducer = new MonitoredProducer(producer, mFlinger, this);
{
// Grab the SF state lock during this since it's the only safe way to access RenderEngine
Mutex::Autolock lock(mFlinger->mStateLock);
mConsumer = new BufferLayerConsumer(consumer, mFlinger->getRenderEngine(), mTextureName,
this);
}
mConsumer->setConsumerUsageBits(getEffectiveUsage(0));
// BufferLayer 把自己注册给了 Consumerbase, 那么当BufferQueueCore的onframeAvailable的通知过来时就会调到 BufferLayer的onframeAvailable
mConsumer->setContentsChangedListener(this);
mConsumer->setName(mName);
if (mFlinger->isLayerTripleBufferingDisabled()) {
mProducer->setMaxDequeuedBufferCount(2);
}
const sp hw(mFlinger->getDefaultDisplayDevice());
updateTransformHint(hw);
}
void BufferLayer::onframeAvailable(const BufferItem& item) {
// Add this buffer from our internal queue tracker
{ // Autolock scope
Mutex::Autolock lock(mQueueItemLock);
// BufferLayer 继承自 Layer , 而在new BufferLayer的时候,随便new layer了,前面知道new
// BufferLayer是在surfaceFlinger中,然后将surfaceFlinger的this给了BufferLayer,就保存在 layer里面了,这里就掉到了 surfaceFlinger中
mFlinger->mInterceptor->saveBufferUpdate(this, item.mGraphicBuffer->getWidth(),
item.mGraphicBuffer->getHeight(),
item.mframeNumber);
// Reset the frame number tracker when we receive the first buffer after
// a frame number reset
if (item.mframeNumber == 1) {
mLastframeNumberReceived = 0;
}
// Ensure that callbacks are handled in order
while (item.mframeNumber != mLastframeNumberReceived + 1) {
status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
ms2ns(500));
if (result != NO_ERROR) {
ALOGE("[%s] Timed out waiting on callback", mName.string());
}
}
mQueueItems.push_back(item);
android_atomic_inc(&mQueuedframes);
// Wake up any pending callbacks
mLastframeNumberReceived = item.mframeNumber;
mQueueItemCondition.broadcast();
}
mFlinger->signalLayerUpdate();
}
待续



