AndroidQ 图形系统(2)生产者-消费者模型

上一篇文章分析了上层Window创建之后,native层会创建对应的Surface,以及SurfaceFlinger进程会创建对应Layer,所以应用层的窗口对应到SurfaceFlinger进程其实就是Layer

AndroidQ上SurfaceFlinger能够创建四种类型的LayerBufferQueueLayerBufferStateLayerColorLayerContainerLayer,最常用的就是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的引用,最后outProduceroutConsumer分别指向创建的生产者-消费者

我们再来看看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的这两个函数,但现在暂时还不知道ConsumerBaseFrameAvailableListener从哪里传递过来的,以及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最终赋值给了
BufferQueueCoremConsumerListener,由此可知BufferQueue果然是一个空壳

监听器传来传去确实容易混乱,我们来总结一下监听器的调用流程,前面createBufferQueue中创建了BufferQueueCoreBufferQueueProducerBufferQueueConsumer,并且生产者-消费者都持有BufferQueueCore的引用,那么当生产者有消息需要通知消费者时流程就是这样:
生产者调用BufferQueueCoremConsumerListener某个监听函数,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,此时生产者调用BufferQueueCoremConsumerListeneronFrameAvailable回调函数,mConsumerListener其实是BufferQueue::ProxyConsumerListenerBufferQueue::ProxyConsumerListener在创建时又接收了ConsumerBase,所以调用到了ConsumerBaseonFrameAvailable中,ConsumerBase这里面又有一个成员变量mFrameAvailableListener,类型为BufferQueueLayer,所以最终是调用到了BufferQueueLayer的具体实现onFrameAvailable中,对这块已经绘制好的buffer进一步处理

到此生产者-消费者模型结构已经大致分析完毕,除了创建最重要的BufferQueueCoreBufferQueueProducerBufferQueueConsumer,另外就是两个重要的监听器了ConsumerListenerFrameAvailableListener,这两个监听器传过来传过去的,有点容易混乱,需要多看代码。

上一篇:java动态注册Filter,Servlet,Listener


下一篇:js 脏检测