androidP Surface到SurfaceFlinger -->surface -> BufferQueue(一)

androidP Surface到SurfaceFlinger -->surface -> BufferQueue(一)

BufferQueue
  • 前言
  • 介绍
  • 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::createBufferQueue

frameworks/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();
}

待续

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5683873.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存