上一篇文章分析了上层Window创建之后,native层会创建对应的Surface
,以及SurfaceFlinger
进程会创建对应Layer
,所以应用层的窗口对应到SurfaceFlinger
进程其实就是Layer
。
AndroidQ上SurfaceFlinger
能够创建四种类型的Layer
,BufferQueueLayer
,BufferStateLayer
,ColorLayer
,ContainerLayer
,最常用的就是BufferQueueLayer
在创建BufferQueueLayer
同时会创建一套生产者-消费者模型架构,核心是三个类:IGraphicBufferProducer
(生产者),IGraphicBufferConsumer
(消费者),BufferQueue
(buffer队列),
生产者提供图形数据,放入BufferQueue
,消费者拿到图形数据进行合成,通常认为生产者为Surface
,消费者为SurfaceFlinger
,这篇文章就来分析一下生产者-消费者模型架构的搭建。
我们以BufferQueueLayer
的创建为入口分析
BufferQueueLayer::onFirstRef
void BufferQueueLayer::onFirstRef() {
BufferLayer::onFirstRef();
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
//步骤1
BufferQueue::createBufferQueue(&producer, &consumer, true);
//步骤2
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);
//步骤3
mConsumer =
new BufferLayerConsumer(consumer, mFlinger->getRenderEngine(), mTextureName, this);
}
//步骤4
mConsumer->setConsumerUsageBits(getEffectiveUsage(0));
//步骤5
mConsumer->setContentsChangedListener(this);
mConsumer->setName(mName);
// BufferQueueCore::mMaxDequeuedBufferCount is default to 1
if (!mFlinger->isLayerTripleBufferingDisabled()) {
mProducer->setMaxDequeuedBufferCount(2);
}
if (const auto display = mFlinger->getDefaultDisplayDevice()) {
updateTransformHint(display);
}
if (mFlinger->mLayerExt) {
mLayerType = mFlinger->mLayerExt->getLayerClass(mName.string());
}
}
上面这个函数就是创建SurfaceFlinger生产者-消费者模型的核心代码,先看步骤1:createBufferQueue
,从名字看就能知道是创建BufferQueue
,并且将生产者producer
和消费者consumer
的地址传了过去,显然这两个对象也会在createBufferQueue
中创建
createBufferQueue
void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
sp<IGraphicBufferConsumer>* outConsumer,
bool consumerIsSurfaceFlinger) {
sp<BufferQueueCore> core(new BufferQueueCore());
sp<IGraphicBufferProducer> producer(new BufferQueueProducer(core, consumerIsSurfaceFlinger));
sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core));
*outProducer = producer;
*outConsumer = consumer;
}
可以看到这个函数中并没有创建BufferQueue
,而是创建的BufferQueueCore
,可见BufferQueue
的核心实现其实是依靠BufferQueueCore
的,接着又创建了生产者的具体实现类BufferQueueProducer
,消费者的具体实现类BufferQueueConsumer
,并且这两个类都持有BufferQueueCore
的引用,最后outProducer
,outConsumer
分别指向创建的生产者-消费者
我们再来看看BufferQueue
中有一个很重要的监听器ProxyConsumerListener
,
class ProxyConsumerListener : public BnConsumerListener {
public:
explicit ProxyConsumerListener(const wp<ConsumerListener>& consumerListener);
~ProxyConsumerListener() override;
void onDisconnect() override;
void onFrameAvailable(const BufferItem& item) override;
void onFrameReplaced(const BufferItem& item) override;
void onBuffersReleased() override;
void onSidebandStreamChanged() override;
void addAndGetFrameTimestamps(
const NewFrameEventsEntry* newTimestamps,
FrameEventHistoryDelta* outDelta) override;
private:
// mConsumerListener is a weak reference to the IConsumerListener. This is
// the raison d'etre of ProxyConsumerListener.
wp<ConsumerListener> mConsumerListener;
};
ProxyConsumerListener
的最终父类是ConsumerListener
,从名字能看出来ProxyConsumerListener
是一个代理端,那么ConsumerListener
的具体实现端在哪里呢?这个问题我们接着分析代码再看
步骤1的createBufferQueue
函数已经看完了,接着看看步骤2:
mProducer = new MonitoredProducer(producer, mFlinger, this);
为生产者对象创建一个MonitoredProducer
,这个类完全就是生产者的封装类,它里面的所有函数几乎都是通过传递进去的producer
来完成的:
status_t MonitoredProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
return mProducer->cancelBuffer(slot, fence);
}
int MonitoredProducer::query(int what, int* value) {
return mProducer->query(what, value);
}
status_t MonitoredProducer::connect(const sp<IProducerListener>& listener,
int api, bool producerControlledByApp, QueueBufferOutput* output) {
return mProducer->connect(listener, api, producerControlledByApp, output);
}
status_t MonitoredProducer::disconnect(int api, DisconnectMode mode) {
return mProducer->disconnect(api, mode);
}
status_t MonitoredProducer::setSidebandStream(const sp<NativeHandle>& stream) {
return mProducer->setSidebandStream(stream);
}
void MonitoredProducer::allocateBuffers(uint32_t width, uint32_t height,
PixelFormat format, uint64_t usage) {
mProducer->allocateBuffers(width, height, format, usage);
}
status_t MonitoredProducer::allowAllocation(bool allow) {
return mProducer->allowAllocation(allow);
}
再接着看看步骤3:
mConsumer =
new BufferLayerConsumer(consumer, mFlinger->getRenderEngine(), mTextureName, this);
这是为消费者创建包装类,先来看看BufferLayerConsumer
这个类,继承ConsumerBase
class BufferLayerConsumer : public ConsumerBase
同时在初始化BufferLayerConsumer
时调用了父类ConsumerBase
的构造函数,将消费者对象传递了过去
BufferLayerConsumer::BufferLayerConsumer(const sp<IGraphicBufferConsumer>& bq,
renderengine::RenderEngine& engine, uint32_t tex,
Layer* layer)
: ConsumerBase(bq, false),
......
}
ConsumerBase
是个重点,来看看:
class ConsumerBase : public virtual RefBase,
protected ConsumerListener {
看到没有,继承ConsumerListener
,前面我们说ProxyConsumerListener
的最终父类是ConsumerListener
,是作为代理端,那么ConsumerBase
很可能就是具体实现端了,而ConsumerBase
中又有BufferQueueConsumer
消费者对象,所以ConsumerListener
的一些具体实现是需要依靠BufferQueueConsumer
的,比如onBuffersReleased
函数,ConsumerBase
中还有一个比较重要的结构体监听器FrameAvailableListener
struct FrameAvailableListener : public virtual RefBase {
// See IConsumerListener::onFrame{Available,Replaced}
virtual void onFrameAvailable(const BufferItem& item) = 0;
virtual void onFrameReplaced(const BufferItem& /* item */) {}
};
这个监听器中有两个和ConsumerListener
同名的函数,我们看看ConsumerBase
对这两个函数的实现:
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 != nullptr) {
CB_LOGV("actually calling onFrameAvailable");
listener->onFrameAvailable(item);
}
}
void ConsumerBase::onFrameReplaced(const BufferItem &item) {
CB_LOGV("onFrameReplaced");
sp<FrameAvailableListener> listener;
{
Mutex::Autolock lock(mFrameAvailableMutex);
listener = mFrameAvailableListener.promote();
}
if (listener != nullptr) {
CB_LOGV("actually calling onFrameReplaced");
listener->onFrameReplaced(item);
}
}
可以看到,ConsumerBase
中这个两个函数具体实现就是调用FrameAvailableListener
的这两个函数,但现在暂时还不知道ConsumerBase
的FrameAvailableListener
从哪里传递过来的,以及FrameAvailableListener
是由哪个类实现的
我们继续看看ConsumerBase
的构造函数:
ConsumerBase::ConsumerBase(const sp<IGraphicBufferConsumer>& bufferQueue, bool controlledByApp) :
mAbandoned(false),
mConsumer(bufferQueue),
mPrevFinalReleaseFence(Fence::NO_FENCE) {
...
wp<ConsumerListener> listener = static_cast<ConsumerListener*>(this);
sp<IConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener);
status_t err = mConsumer->consumerConnect(proxy, controlledByApp);
...
}
这里面创建了一个 BufferQueue::ProxyConsumerListener
对象,并将ConsumerBase
传递了过去,所以这里我们能确定了代理端 BufferQueue::ProxyConsumerListener
的具体实现端就是ConsumerBase
,接着调用了BufferQueueConsumer
消费者的consumerConnect
函数,又将BufferQueue::ProxyConsumerListener
传递了过去,consumerConnect
实现在BufferQueueConsumer.h
中:
virtual status_t consumerConnect(const sp<IConsumerListener>& consumer,
bool controlledByApp) {
return connect(consumer, controlledByApp);
}
又调用了自己的connect
函数,这个函数实现在BufferQueueConsumer.cpp
中:
status_t BufferQueueConsumer::connect(
const sp<IConsumerListener>& consumerListener, bool controlledByApp) {
ATRACE_CALL();
if (consumerListener == nullptr) {
BQ_LOGE("connect: consumerListener may not be NULL");
return BAD_VALUE;
}
BQ_LOGV("connect: controlledByApp=%s",
controlledByApp ? "true" : "false");
std::lock_guard<std::mutex> lock(mCore->mMutex);
if (mCore->mIsAbandoned) {
BQ_LOGE("connect: BufferQueue has been abandoned");
return NO_INIT;
}
mCore->mConsumerListener = consumerListener;
mCore->mConsumerControlledByApp = controlledByApp;
return NO_ERROR;
}
看到了吗,从ConsumerBase
传递过来的 BufferQueue::ProxyConsumerListener
最终赋值给了BufferQueueCore
的mConsumerListener
,由此可知BufferQueue
果然是一个空壳
监听器传来传去确实容易混乱,我们来总结一下监听器的调用流程,前面createBufferQueue
中创建了BufferQueueCore
,BufferQueueProducer
,BufferQueueConsumer
,并且生产者-消费者都持有BufferQueueCore
的引用,那么当生产者有消息需要通知消费者时流程就是这样:
生产者调用BufferQueueCore
的mConsumerListener
某个监听函数,mConsumerListener
调到了 BufferQueue::ProxyConsumerListener
的同名监听函数, BufferQueue::ProxyConsumerListener
这个类创建时接收了ConsumerListener
的具体实现类ConsumerBase
,所以调到了ConsumerBase
的同名监听函数,ConsumerBase
中又有消费者对象,所以又可以根据情况调到消费者中去,这样就实现了消费者对生产者的监听
到这里还剩下FrameAvailableListener
监听器的具体实现类没有看到
接着分析代码,步骤1,2,3已经分析完了,步骤4没什么分析的,我们看看步骤5:
mConsumer->setContentsChangedListener(this);
通过setContentsChangedListener
给消费者设置一个监听器,并且传递的是this
,我们先看看当前类继承了哪个监听器,当前类是BufferQueueLayer
别忘了:
class BufferQueueLayer : public BufferLayer,
public BufferLayerConsumer::ContentsChangedListener {}
继承的是BufferLayerConsumer::ContentsChangedListener
,继续看:
class BufferLayerConsumer : public ConsumerBase {
public:
......
struct ContentsChangedListener : public FrameAvailableListener {
virtual void onSidebandStreamChanged() = 0;
};
看到这里应该恍然大悟了,原来FrameAvailableListener
的具体实现类是BufferQueueLayer
,再回到setContentsChangedListener
函数:
void BufferLayerConsumer::setContentsChangedListener(const wp<ContentsChangedListener>& listener) {
setFrameAvailableListener(listener);
Mutex::Autolock lock(mMutex);
mContentsChangedListener = listener;
}
调用setFrameAvailableListener
将这个监听器继续传递,这个函数BufferLayerConsumer
并没有实现,调用的还是父类ConsumerBase
的:
void ConsumerBase::setFrameAvailableListener(
const wp<FrameAvailableListener>& listener) {
CB_LOGV("setFrameAvailableListener");
Mutex::Autolock lock(mFrameAvailableMutex);
mFrameAvailableListener = listener;
}
这个函数仅仅是将传递过来的监听器保存在自己的成员变量mFrameAvailableListener
中,以便由生产者那边进行调用,另外setContentsChangedListener
中同样将监听器保存在了BufferLayerConsumer
的成员变量mContentsChangedListener
中,
我们再来总结一下FrameAvailableListener
中的onFrameAvailable
函数的回调流程:
生产者dequeue
一块buffer
,应用程序进行绘制,绘制完成后queue
此块buffer
,此时生产者调用BufferQueueCore
的mConsumerListener
的onFrameAvailable
回调函数,mConsumerListener
其实是BufferQueue::ProxyConsumerListener
,BufferQueue::ProxyConsumerListener
在创建时又接收了ConsumerBase
,所以调用到了ConsumerBase
的onFrameAvailable
中,ConsumerBase
这里面又有一个成员变量mFrameAvailableListener
,类型为BufferQueueLayer
,所以最终是调用到了BufferQueueLayer
的具体实现onFrameAvailable
中,对这块已经绘制好的buffer
进一步处理
到此生产者-消费者模型结构已经大致分析完毕,除了创建最重要的BufferQueueCore
,BufferQueueProducer
,BufferQueueConsumer
,另外就是两个重要的监听器了ConsumerListener
,FrameAvailableListener
,这两个监听器传过来传过去的,有点容易混乱,需要多看代码。