android_display

SurfaceFlinger合成二

2021-08-05  本文已影响0人  欣兄

onMessageInvalidate过程

/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::onMessageInvalidate(nsecs_t expectedVSyncTime) {
......
bool refreshNeeded;//@1
{
        ConditionalLockGuard<std::mutex> lock(mTracingLock, mTracingEnabled);

        refreshNeeded = handleMessageTransaction();//@2
        refreshNeeded |= handleMessageInvalidate();//@3
        if (mTracingEnabled) {
            mAddCompositionStateToTrace =
                    mTracing.flagIsSetLocked(SurfaceTracing::TRACE_COMPOSITION);
            if (mVisibleRegionsDirty && !mAddCompositionStateToTrace) {
                mTracing.notifyLocked("visibleRegionsDirty");
            }
        }
    }
......

    refreshNeeded |= mRepaintEverything; //@4
    if (refreshNeeded && CC_LIKELY(mBootStage != BootStage::BOOTLOADER)) { //@5
        mLastJankDuration = jankDurationToUpload;
        // Signal a refresh if a transaction modified the window state,
        // a new buffer was latched, or if HWC has requested a full
        // repaint
        if (mFrameStartTime <= 0) {
            // We should only use the time of the first invalidate
            // message that signals a refresh as the beginning of the
            // frame. Otherwise the real frame time will be
            // underestimated.
            mFrameStartTime = frameStart;
        }
        signalRefresh();  //@6
    }
}

@1处refreshNeeded这个变量的值最后会用来判定是否执行 @6处,是否需要刷新
@2处handleMessageTransaction 有要处理的transaction则返回true;
@3处handleMessageInvalidate 总体意思就是layer latch到了buffer,则返回true,且结果和之前的refreshNeeded进行或操作。
@4 refreshNeeded 和mRepaintEverything 进行或操作,mRepaintEverything在updateVrFlinger的时候会置为true。
@5处进行判断符合条件后执行到@6处
@6处就会申请再一次的刷新最后执行到SurfaceFlinger.cpp的onMessageRefresh。

主要关心一下 handleMessageTransaction、handleMessageInvalidate,其他内容先忽略。

一、handleMessageTransaction处理

bool SurfaceFlinger::handleMessageTransaction() {
    ATRACE_CALL();
    uint32_t transactionFlags = peekTransactionFlags();

    bool flushedATransaction = flushTransactionQueues();

    bool runHandleTransaction =
            (transactionFlags && (transactionFlags != eTransactionFlushNeeded)) ||
            flushedATransaction ||
            mForceTraversal;

    if (runHandleTransaction) {
        handleTransaction(eTransactionMask);\\@1
    } else {
        getTransactionFlags(eTransactionFlushNeeded);
    }

    if (transactionFlushNeeded()) {
        setTransactionFlags(eTransactionFlushNeeded);
    }

    return runHandleTransaction;
}

这个过程就是处理应用传过来的各种Transition。
@1处 handleTransaction处理

void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
{
    ATRACE_CALL();

    // here we keep a copy of the drawing state (that is the state that's
    // going to be overwritten by handleTransactionLocked()) outside of
    // mStateLock so that the side-effects of the State assignment
    // don't happen with mStateLock held (which can cause deadlocks).
    State drawingState(mDrawingState);

    Mutex::Autolock _l(mStateLock);@1
    mDebugInTransaction = systemTime();

    // Here we're guaranteed that some transaction flags are set
    // so we can call handleTransactionLocked() unconditionally.
    // We call getTransactionFlags(), which will also clear the flags,
    // with mStateLock held to guarantee that mCurrentState won't change
    // until the transaction is committed.

    mVSyncModulator->onTransactionHandled();
    transactionFlags = getTransactionFlags(eTransactionMask);@2
    handleTransactionLocked(transactionFlags);@3

    mDebugInTransaction = 0;
    invalidateHwcGeometry();
    // here the transaction has been committed
}

@1处 获取mStateLock锁,才能继续执行。
@2处会获取一个transactionFlags, 分为以下几种类别

enum {
    eTransactionNeeded = 0x01,
    eTraversalNeeded = 0x02,
    eDisplayTransactionNeeded = 0x04,
    eTransformHintUpdateNeeded = 0x08,
    eTransactionFlushNeeded = 0x10,
    eTransactionMask = 0x1f,
};

各个Flag处理过程基本上相似,我们会看下eTraversalNeeded的处理。
@3处会执行 handleTransactionLocked(transactionFlags);

void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
{
......
    if ((transactionFlags & eTraversalNeeded) || mForceTraversal) { @1
        mForceTraversal = false;
        mCurrentState.traverse([&](Layer* layer) {
            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);@2
            if (!trFlags) return; @3

            const uint32_t flags = layer->doTransaction(0);@4
            if (flags & Layer::eVisibleRegion) @5
                mVisibleRegionsDirty = true; @6

            if (flags & Layer::eInputInfoChanged) {
                mInputInfoChanged = true;
            }
        });
    }

@1处满足条件,@2处遍历所有的layer,看这个layer是否需要doTransaction。
@3处如果不需要的话,进入到下一个循环,
@4处执行layer的doTransaction
@5个layer计算可见区域是否发生变化
@6可见区域发生变化

执行getTransactionFlags, trFlags不为0则会继续执行。
显然,不是每个Layer在每次handleTransactionLocked中都需要调用doTransaction,判断标准就是Layer::getTransactionFlags返回的标志中是否指明了eTransactionNeeded

二、handleMessageInvalidate

bool SurfaceFlinger::handleMessageInvalidate() {
    ATRACE_CALL();
    bool refreshNeeded = handlePageFlip();//@1

    if (mVisibleRegionsDirty) {
        computeLayerBounds();
    }

    for (auto& layer : mLayersPendingRefresh) {
        Region visibleReg;
        visibleReg.set(layer->getScreenBounds());
        invalidateLayerStack(layer, visibleReg);
    }
    mLayersPendingRefresh.clear();
    return refreshNeeded;
}

handlePageFlip

/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
bool SurfaceFlinger::handlePageFlip()
{
    ATRACE_CALL();
......
    mDrawingState.traverse([&](Layer* layer) {   @1
        if (layer->hasReadyFrame()) {           @2
            frameQueued = true;
            if (layer->shouldPresentNow(expectedPresentTime)) {     @3
                mLayersWithQueuedFrames.push_back(layer);       @4
            } else {
                ATRACE_NAME("!layer->shouldPresentNow()");
                layer->useEmptyDamage();
            }
        } else {
            layer->useEmptyDamage();
        }
    });

    // The client can continue submitting buffers for offscreen layers, but they will not
    // be shown on screen. Therefore, we need to latch and release buffers of offscreen
    // layers to ensure dequeueBuffer doesn't block indefinitely.
    for (Layer* offscreenLayer : mOffscreenLayers) {  @5
        offscreenLayer->traverse(LayerVector::StateSet::Drawing,
                                         [&](Layer* l) { l->latchAndReleaseBuffer(); });
    }

    if (!mLayersWithQueuedFrames.empty()) {  @6
        // mStateLock is needed for latchBuffer as LayerRejecter::reject()
        // writes to Layer current state. See also b/119481871
        Mutex::Autolock lock(mStateLock);

        for (auto& layer : mLayersWithQueuedFrames) {
            if (layer->latchBuffer(visibleRegions, latchTime, expectedPresentTime)) { @7
                mLayersPendingRefresh.push_back(layer);
            }
            layer->useSurfaceDamage();   @8
            if (layer->isBufferLatched()) {
                newDataLatched = true;
            }
        }
    }

    mVisibleRegionsDirty |= visibleRegions;

    // If we will need to wake up at some time in the future to deal with a
    // queued frame that shouldn't be displayed during this vsync period, wake
    // up during the next vsync period to check again.
    if (frameQueued && (mLayersWithQueuedFrames.empty() || !newDataLatched)) {
        signalLayerUpdate();
    }

    // enter boot animation on first buffer latch
    if (CC_UNLIKELY(mBootStage == BootStage::BOOTLOADER && newDataLatched)) {
        ALOGI("Enter boot animation");
        mBootStage = BootStage::BOOTANIMATION;
    }

    mDrawingState.traverse([&](Layer* layer) { layer->updateCloneBufferInfo(); }); @9

    // Only continue with the refresh if there is actually new work to do
    return !mLayersWithQueuedFrames.empty() && newDataLatched;
}

@1处 需要进行合成的数据保存在mDrawingState中。遍历获取到的Layer列表,并且把layer作为参数传给语句块。
@2处 判断layer是不是有Queued的Frame,
@3处 如果shouldPresentNow返回true,@4该Layer标记为mLayersWithQueuedFrames;否则,Layer使用空的DamageRegion。
@5处遍历mOffscreenLayers(mOffscreenLayers是一组没有父层的图层,不在屏幕上面绘制,只被主线程访问)。主要是调用layer的latchAndReleaseBuffer方法,作用注释描述很明确。
@6 mLayersWithQueuedFrames不为空,说明存有适合的layer,接下来获取mStateLock锁,进行遍历mLayersWithQueuedFrames。
@7处 latchBuffer,获取buffer成功后,把此layer 存入mLayersPendingRefresh中,注意传入了一个visibleRegions参数。
@8处 Layer使用空的DamageRegion。DamageRegion后面研究。
@9处 保存此layer的BufferInfo,下一次BufferLayer latchBuffer时候会比较上次buffer的状态,那个时候会用到。

接着看一下handlePageFlip中重要子方法:shouldPresentNow 和latchBuffer

1、shouldPresentNow

/frameworks/native/services/surfaceflinger/BufferQueueLayer.cpp
bool BufferQueueLayer::shouldPresentNow(nsecs_t expectedPresentTime) const {
    if (getSidebandStreamChanged() || getAutoRefresh()) {
        return true;
    }

    if (!hasFrameUpdate()) {
        return false;
    }

    Mutex::Autolock lock(mQueueItemLock);

    const int64_t addedTime = mQueueItems[0].mTimestamp; //@1

    // Ignore timestamps more than a second in the future
    const bool isPlausible = addedTime < (expectedPresentTime + s2ns(1)); @2
    ALOGW_IF(!isPlausible,
             "[%s] Timestamp %" PRId64 " seems implausible "
             "relative to expectedPresent %" PRId64,
             getDebugName(), addedTime, expectedPresentTime);

    if (!isPlausible) {
        mFlinger->mTimeStats->incrementBadDesiredPresent(getSequence());
    }

    const bool isDue = addedTime < expectedPresentTime;  @3
    return isDue || !isPlausible;
}

可以看到影响返回值的就是isDue 和 isPlausible两个值
@1处获取Buffer的时间戳,
@2处判断 Buffer的时间戳 和 期望显示时间再加1秒 之间的关系。注释很明确,忽略超过一秒的时间戳。
@3处 如果Buffer的时间戳小于期望的时间,则为true。

上一篇下一篇

猜你喜欢

热点阅读