美文网首页android_display
SurfaceFlinger合成一

SurfaceFlinger合成一

作者: 欣兄 | 来源:发表于2021-05-28 16:01 被阅读0次

    一、Producer生产完GraphicBuffer,会通知SurfaceFlinger进行合成逻辑。

    BuffeQueueProducer 中queueBuffer在完成GraphicBuffer相关操作后,会通知到SurfaceFlinger去执行合成逻辑。下来看下具体过程
    继承关系:


    sf12.png

    时序图:


    sf11.png

    1、先来看第一步,为什么是执行ProxyConsumerListener中的onFrameAvailable。(注意继承关系)

    我们知道在BufferQueueProducer的queueBuffer方法中。

    status_t BufferQueueProducer::queueBuffer(int slot,
            const QueueBufferInput &input, QueueBufferOutput *output) {
     sp<IConsumerListener> frameAvailableListener;
    ......
     frameAvailableListener->onFrameAvailable(item);
    ......
    }
    

    frameAvailableListener->onFrameAvailable(item) 把BufferItem通知下去。
    这个frameAvailableListener是什么?
    frameAvailableListener = mCore->mConsumerListener;
    那mCore中的mConsumerListener又是谁赋的值,
    可以看到在BufferQueueConsumer中的connect方法里面

    /frameworks/native/libs/gui/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;
        }
      ...
        mCore->mConsumerListener = consumerListener; //@1
     ...
        return NO_ERROR;
    }
    

    在@1处进行了赋值。
    那connect方法中的consumerListener又是谁,

    /frameworks/native/libs/gui/include/gui/BufferQueueConsumer.h
        virtual status_t consumerConnect(const sp<IConsumerListener>& consumer,
                bool controlledByApp) {
            return connect(consumer, controlledByApp);
    }
    

    consumerConnect方法,其会调用connect,传入consumer。
    那consumerConnect哪块调用,在ConsumerBase的构造方法里面有

    ConsumerBase::ConsumerBase(const sp<IGraphicBufferConsumer>& bufferQueue, bool controlledByApp) :
            mAbandoned(false),
            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);
    
        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);
        }
    }
    

    可以看到proxy就是源头。我们从后再往前回顾一下,发现这个listener 就是BufferQueueConsumer和BufferQueue的一个连接。
    那第一步就是回调ProxyConsumerListener的 onFrameAvailable。

    /frameworks/native/libs/gui/BufferQueue.cpp
    void BufferQueue::ProxyConsumerListener::onFrameAvailable(
            const BufferItem& item) {
        sp<ConsumerListener> listener(mConsumerListener.promote());
        if (listener != nullptr) {
            listener->onFrameAvailable(item);
        }
    }
    
    ####2、第二步执行的是ConsumerBase中的onFrameAvailable方法,
    上一步在ConsumerBase构造方法中我们也看到
     wp<ConsumerListener> listener = static_cast<ConsumerListener*>(this);
     sp<IConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener);
    
    /frameworks/native/libs/gui/BufferQueue.cpp
    BufferQueue::ProxyConsumerListener::ProxyConsumerListener(
            const wp<ConsumerListener>& consumerListener):
            mConsumerListener(consumerListener) {}
    
    /frameworks/native/libs/gui/BufferQueue.cpp
    void BufferQueue::ProxyConsumerListener::onFrameAvailable(
            const BufferItem& item) {
        sp<ConsumerListener> listener(mConsumerListener.promote());
        if (listener != nullptr) {
            listener->onFrameAvailable(item);//@1
        }
    }
    

    ProxyConsumerListener构造方法中传入的就是 ConsumerBase,所以@1处的listener就是ConsumerBase

    3、第三步执行ContentsChangedListener

    /frameworks/native/libs/gui/ConsumerBase.cpp
    void ConsumerBase::onFrameAvailable(const BufferItem& item) {
        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);
        }
    }
    

    在ConsumerBase的onFrameAvailable方法中,会调用 listener->onFrameAvailable(item);
    那这个listener是谁呢,

    /frameworks/native/libs/gui/ConsumerBase.cpp
    void ConsumerBase::setFrameAvailableListener(
            const wp<FrameAvailableListener>& listener) {
        CB_LOGV("setFrameAvailableListener");
        Mutex::Autolock lock(mFrameAvailableMutex);
        mFrameAvailableListener = listener;
    }
    

    setFrameAvailableListener的调用者在BufferLayerConsumer中的setContentsChangedListene中,

    /frameworks/native/services/surfaceflinger/BufferLayerConsumer.cpp
    void BufferLayerConsumer::setContentsChangedListener(const wp<ContentsChangedListener>& listener) {
        setFrameAvailableListener(listener);
        Mutex::Autolock lock(mMutex);
        mContentsChangedListener = listener;
    }
    

    setContentsChangedListener在哪调用呢

    /frameworks/native/services/surfaceflinger/BufferQueueLayer.cpp
    void BufferQueueLayer::onFirstRef() {
           BufferLayer::onFirstRef();
    
        // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
        sp<IGraphicBufferProducer> producer;
        sp<IGraphicBufferConsumer> consumer;
        mFlinger->getFactory().createBufferQueue(&producer, &consumer, true);
        mProducer = mFlinger->getFactory().createMonitoredProducer(producer, mFlinger, this);
        mConsumer =
                mFlinger->getFactory().createBufferLayerConsumer(consumer, mFlinger->getRenderEngine(),
                                                                 mTextureName, this);    
      mContentsChangedListener = new ContentsChangedListener(this);
        mConsumer->setContentsChangedListener(mContentsChangedListener);//@1
        mConsumer->setName(String8(mName.data(), mName.size()));
    
        // BufferQueueCore::mMaxDequeuedBufferCount is default to 1
        if (!mFlinger->isLayerTripleBufferingDisabled()) {
            mProducer->setMaxDequeuedBufferCount(2);
        }
    }
    

    @1可以明显的看到一路传的listener 为 ContentsChangedListener,
    它的继承关系

    /frameworks/native/services/surfaceflinger/BufferQueueLayer.h
    class ContentsChangedListener : public BufferLayerConsumer::ContentsChangedListener
     
    /frameworks/native/services/surfaceflinger/BufferLayerConsumer.h
    struct ContentsChangedListener : public FrameAvailableListener 
    

    所以第三步的onFrameAvailable是调用的ContentsChangedListener的。

    /frameworks/native/services/surfaceflinger/BufferQueueLayer.cpp
    void BufferQueueLayer::ContentsChangedListener::onFrameAvailable(const BufferItem& item) {
        Mutex::Autolock lock(mMutex);
        if (mBufferQueueLayer != nullptr) {
            mBufferQueueLayer->onFrameAvailable(item); //@1
     }
    }
    

    @1处 很明显调用的是类BufferQueueLayer中的onFrameAvailable方法

    void BufferQueueLayer::onFrameAvailable(const BufferItem& item) {
     ......
        ATRACE_CALL();
        // Add this buffer from our internal queue tracker
        { // Autolock scope
            const nsecs_t presentTime = item.mIsAutoTimestamp ? 0 : item.mTimestamp;
            mFlinger->mScheduler->recordLayerHistory(this, presentTime,                                                 LayerHistory::LayerUpdateType::Buffer);
    
            Mutex::Autolock lock(mQueueItemLock);
            // 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", getDebugName());
                    break;
                }
            }
    
            mQueueItems.push_back(item);//@1
            mQueuedFrames++;
    
            // Wake up any pending callbacks
            mLastFrameNumberReceived = item.mFrameNumber;
            mQueueItemCondition.broadcast();
        }
    
        mFlinger->mInterceptor->saveBufferUpdate(layerId, item.mGraphicBuffer->getWidth(),
                                                 item.mGraphicBuffer->getHeight(), item.mFrameNumber);
    
        mFlinger->signalLayerUpdate(); //@2
        mConsumer->onBufferAvailable(item);
    }
    

    @1处 把一路传过来的 item存储到mQueueItems,后面合成的时候在执行updateTextImage时候能用到,
    @2处 去通知SurfaceFlinger进行合成。到这里,应用端(Producer)生产完Buffer这件事,就通知到了SurfaceFlinger中了。

    /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
    void SurfaceFlinger::signalLayerUpdate() {
        mScheduler->resetIdleTimer();
        mPowerAdvisor.notifyDisplayUpdateImminent();
        mEventQueue->invalidate();
    }
    

    SurfaceFlinger的signalLayerUpdate,是通过MessageQueue来处理的,有一点需要注意的是上面这一些列操作是在binder线程里面执行的。通知到了当然就要请求vsync 进行刷新了。通过调用mEventQueue->invalidate() 来请求vsync信号。

    二、surfaceFlinger vsync信号的申请

    在Vsync与app、SurfaceFlinger关系(2)里面说过app vsyn信号的申请,surfaceFlinger vsync申请基本类似。这里大致说一下。

    /frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp
    void MessageQueue::invalidate() {
        mEvents->requestNextVsync();
    }
    

    接着上一步,会调用到MessageQueue 的invalidate,然后调用EventThreadConnection的requestNextVsync,

    /frameworks/native/services/surfaceflinger/Scheduler/EventThread.cpp
    void EventThreadConnection::requestNextVsync() {
        ATRACE_NAME("requestNextVsync");
        mEventThread->requestNextVsync(this);
    }
    

    再调用EventThread 的requestNextVsync

    void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) {
        if (connection->resyncCallback) {
            connection->resyncCallback();
        }
        std::lock_guard<std::mutex> lock(mMutex);
        if (connection->vsyncRequest == VSyncRequest::None) {
            connection->vsyncRequest = VSyncRequest::Single;
            mCondition.notify_all(); @1
        }
    }
    

    EventThread 在创建的时候会执行其threadMain方法,其里面是一个while循环。主要内容是申请Vsync信号、Vsync信号申请到后进行分发。

    void EventThread::threadMain(std::unique_lock<std::mutex>& lock) {
    DisplayEventConsumers consumers;
            // Find connections that should consume this event.
            auto it = mDisplayEventConnections.begin();
            while (it != mDisplayEventConnections.end()) {
                if (const auto connection = it->promote()) {
                    vsyncRequested |= connection->vsyncRequest != VSyncRequest::None;
    
                    if (event && shouldConsumeEvent(*event, connection)) {
                        consumers.push_back(connection); //@1
                    }
    
                    ++it;
                } else {
                    it = mDisplayEventConnections.erase(it);
                }
            }
    ......
            if (!consumers.empty()) {
                dispatchEvent(*event, consumers); //@2
                consumers.clear();
            }
    ......
            if (mState != nextState) {
               if (mState == State::VSync) {
                       mVSyncSource->setVSyncEnabled(false);
               } else if (nextState == State::VSync) {
                    mVSyncSource->setVSyncEnabled(true);//@3
                }
    
                mState = nextState;
           }
    ......
    }
    

    @1处 把mDisplayEventConnections又存入了DisplayEventConsumers 中,为后面的分发做准备。
    @2处 对注册了connection 其Vsync 信号的分发。
    @3处是要进行vsync的申请。可参考Vsync与app、SurfaceFlinger关系(1)。
    请求到了后,Vsync经过DispSync.cpp 、 DispSyncSource.cpp 到EventThread的onVSyncEvent

    /frameworks/native/services/surfaceflinger/Scheduler/EventThread.cpp
    void EventThread::onVSyncEvent(nsecs_t timestamp, nsecs_t expectedVSyncTimestamp) {
        std::lock_guard<std::mutex> lock(mMutex);
    
        LOG_FATAL_IF(!mVSyncState);
        mPendingEvents.push_back(makeVSync(mVSyncState->displayId, timestamp, ++mVSyncState->count,
                                           expectedVSyncTimestamp));
        mCondition.notify_all(); @4
    }
    

    在@4处就会唤起threadMain里面的锁,继续进行下一轮的循环,然后会执行到@2处,进行vsync信号的分发。已经说过,再简单介绍一下过程

    /frameworks/native/services/surfaceflinger/Scheduler/EventThread.cpp
    void EventThread::dispatchEvent(const DisplayEventReceiver::Event& event,
                                    const DisplayEventConsumers& consumers) {
        for (const auto& consumer : consumers) {
            switch (consumer->postEvent(event)) {  @1
                case NO_ERROR:
                    break;
    
                case -EAGAIN:
                    // TODO: Try again if pipe is full.
                    ALOGW("Failed dispatching %s for %s", toString(event).c_str(),
                          toString(*consumer).c_str());
                    break;
    
                default:
                    // Treat EPIPE and other errors as fatal.
                    removeDisplayEventConnectionLocked(consumer);  @2;
            }
        }
    }
    
    status_t EventThreadConnection::postEvent(const DisplayEventReceiver::Event& event) {
        ssize_t size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
        return size < 0 ? status_t(size) : status_t(NO_ERROR);
    }
    
    /frameworks/native/libs/gui/DisplayEventReceiver.cpp
    ssize_t DisplayEventReceiver::sendEvents(gui::BitTube* dataChannel,
            Event const* events, size_t count)
    {
        return gui::BitTube::sendObjects(dataChannel, events, count);
    }
    

    最后就到达了 MessageQueue 的 eventReceiver

    int MessageQueue::eventReceiver(int /*fd*/, int /*events*/) {
        ssize_t n;
        DisplayEventReceiver::Event buffer[8];
        while ((n = DisplayEventReceiver::getEvents(&mEventTube, buffer, 8)) > 0) {
            for (int i = 0; i < n; i++) {
                if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
                    mHandler->dispatchInvalidate(buffer[i].vsync.expectedVSyncTimestamp);
                    break;
                }
            }
        }
        return 1;
    }
    

    DisplayEventReceiver::getEvents 接收到消息,满足条件执行下面的mHandler->dispatchInvalidate

    /frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp
    void MessageQueue::Handler::dispatchInvalidate(nsecs_t expectedVSyncTimestamp) {
        if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {
            mExpectedVSyncTime = expectedVSyncTimestamp;
            mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));
        }
    }
    
    void MessageQueue::Handler::handleMessage(const Message& message) {
        switch (message.what) {
            case INVALIDATE:
                android_atomic_and(~eventMaskInvalidate, &mEventMask);
                mQueue.mFlinger->onMessageReceived(message.what, mExpectedVSyncTime);
                break;
            case REFRESH:
                android_atomic_and(~eventMaskRefresh, &mEventMask);
                mQueue.mFlinger->onMessageReceived(message.what, mExpectedVSyncTime);
                break;
        }
    }
    

    一路操作,终于到surfaceFlinger了。合成的两大重要方法,onMessageInvalidate、onMessageRefresh;

    /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
    void SurfaceFlinger::onMessageReceived(int32_t what, nsecs_t expectedVSyncTime) {
        ATRACE_CALL();
        switch (what) {
            case MessageQueue::INVALIDATE: {
                onMessageInvalidate(expectedVSyncTime);
                break;
            }
            case MessageQueue::REFRESH: {
                onMessageRefresh();
                break;
            }
        }
    }
    

    相关文章

      网友评论

        本文标题:SurfaceFlinger合成一

        本文链接:https://www.haomeiwen.com/subject/nhmssltx.html