上一篇文章分析了上层Window创建之后,native层会创建对应的 AndroidQ上 在创建 上面这个函数就是创建SurfaceFlinger生产者-消费者模型的核心代码,先看步骤1: 可以看到这个函数中并没有创建 我们再来看看 步骤1的 为生产者对象创建一个 再接着看看步骤3: 这是为消费者创建包装类,先来看看 同时在初始化 看到没有,继承 这个监听器中有两个和 可以看到, 我们继续看看 这里面创建了一个 又调用了自己的 看到了吗,从 监听器传来传去确实容易混乱,我们来总结一下监听器的调用流程,前面 到这里还剩下 接着分析代码,步骤1,2,3已经分析完了,步骤4没什么分析的,我们看看步骤5: 通过 继承的是 看到这里应该恍然大悟了,原来 调用 这个函数仅仅是将传递过来的监听器保存在自己的成员变量 到此生产者-消费者模型结构已经大致分析完毕,除了创建最重要的Surface,以及SurfaceFlinger进程会创建对应Layer,所以应用层的窗口对应到SurfaceFlinger进程其实就是Layer。SurfaceFlinger能够创建四种类型的Layer,BufferQueueLayer,BufferStateLayer,ColorLayer,ContainerLayer,最常用的就是BufferQueueLayerBufferQueueLayer同时会创建一套生产者-消费者模型架构,核心是三个类:
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()); } } 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的具体实现端在哪里呢?这个问题我们接着分析代码再看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); } mConsumer = new BufferLayerConsumer(consumer, mFlinger->getRenderEngine(), mTextureName, this); BufferLayerConsumer这个类,继承ConsumerBaseclass 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中还有一个比较重要的结构体监听器FrameAvailableListenerstruct 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监听器的具体实现类没有看到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,这两个监听器传过来传过去的,有点容易混乱,需要多看代码。
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算
官方软件产品操作指南 (170)