android_display

SurfaceFlinger合成一

2021-05-28  本文已影响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;
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读