BufferQueue
前言
结合前面的一篇文章创建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::createBufferQueue
frameworks/native/services/surfaceflinger/BufferLayer.cpp
void BufferLayer::onFirstRef() {
Layer::onFirstRef();
// Creates a custom BufferQueue for SurfaceFlingerConsumer to use
// 这里producer consumer分别会在createBufferQueue中进行赋值
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> 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<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
updateTransformHint(hw);
}
frameworks/native/libs/gui/BufferQueue.cpp
void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
sp<IGraphicBufferConsumer>* 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<BufferQueueCore> core(new BufferQueueCore());
LOG_ALWAYS_FATAL_IF(core == NULL,
"BufferQueue: failed to create BufferQueueCore");
// new producer
sp<IGraphicBufferProducer> producer(new BufferQueueProducer(core, consumerIsSurfaceFlinger));
LOG_ALWAYS_FATAL_IF(producer == NULL,
"BufferQueue: failed to create BufferQueueProducer");
// new consumer
sp<IGraphicBufferConsumer> 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<IGraphicBufferConsumer>& bq,
RE::RenderEngine& engine, uint32_t tex, Layer* layer)
// 调用到了父类
: ConsumerBase(bq, false),
... ...
}
frameworks/native/libs/gui/ConsumerBase.cpp
ConsumerBase::ConsumerBase(const sp<IGraphicBufferConsumer>& 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<ConsumerListener> listener = static_cast<ConsumerListener*>(this);
sp<IConsumerListener> 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<IConsumerListener>& consumer,
bool controlledByApp) {
return connect(consumer, controlledByApp);
}
status_t BufferQueueConsumer::connect(
const sp<IConsumerListener>& 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<FrameAvailableListener> 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<FrameAvailableListener>& 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<ContentsChangedListener>& 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<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> 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<const DisplayDevice> 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();
}
待续