SurfaceFlinger中Layer的合成 - 安卓R

1 等待任意Layer的buffer准备好

当BufferQueueLayer有新的buffer到来时,会调用之前在SurfaceFlinger中Layer的创建时注册的ContentsChangedListener的onFrameAvailable方法(frameworks/native/services/surfaceflinger/BufferQueueLayer.cpp):

void BufferQueueLayer::ContentsChangedListener::onFrameAvailable(const BufferItem& item) {
   
    Mutex::Autolock lock(mMutex);
    if (mBufferQueueLayer != nullptr) {
   
        mBufferQueueLayer->onFrameAvailable(item);
    }
}

直接调用了BufferQueueLayer的onFrameAvailable方法:

void BufferQueueLayer::onFrameAvailable(const BufferItem& item) {
   
    const int32_t layerId = getSequence();
    const uint64_t bufferId = item.mGraphicBuffer->getId();
    mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, item.mFrameNumber, systemTime(),
                                           FrameTracer::FrameEvent::QUEUE);
    mFlinger->mFrameTracer->traceFence(layerId, bufferId, item.mFrameNumber,
                                       std::make_shared<FenceTime>(item.mFence),
                                       FrameTracer::FrameEvent::ACQUIRE_FENCE);

    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);
        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();
    mConsumer->onBufferAvailable(item);
}

最后调用了frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp的signalLayerUpdate方法:

void SurfaceFlinger::signalLayerUpdate() {
   
    mScheduler->resetIdleTimer();
    mPowerAdvisor.notifyDisplayUpdateImminent();
    mEventQueue->invalidate();
}

2 通过acquireBuffer方法锁定buffer

EventQueue的invalidate方法会导致SurfaceFlinger的onMessageInvalidate方法被调用:

void SurfaceFlinger::onMessageInvalidate(nsecs_t expectedVSyncTime) {
   
    ATRACE_CALL();

    const nsecs_t frameStart = systemTime();
    // calculate the expected present time once and use the cached
    // value throughout this frame to make sure all layers are
    // seeing this same value.
    if (expectedVSyncTime >= frameStart) {
   
        mExpectedPresentTime = expectedVSyncTime;
    } else {
   
        mExpectedPresentTime = mScheduler->getDispSyncExpectedPresentTime(frameStart);
    }

    const nsecs_t lastScheduledPresentTime = mScheduledPresentTime;
    mScheduledPresentTime = expectedVSyncTime;

    // When Backpressure propagation is enabled we want to give a small grace period
    // for the present fence to fire instead of just giving up on this frame to handle cases
    // where present fence is just about to get signaled.
    const int graceTimeForPresentFenceMs =
            (mPropagateBackpressure &&
             (mPropagateBackpressureClientComposition || !mHadClientComposition))
            ? 1
            : 0;

    // Pending frames may trigger backpressure propagation.
    const TracedOrdinal<bool> framePending = {
   "PrevFramePending",
                                              previousFramePending(graceTimeForPresentFenceMs)};

    // Frame missed counts for metrics tracking.
    // A frame is missed if the prior frame is still pending. If no longer pending,
    // then we still count the frame as missed if the predicted present time
    // was further in the past than when the fence actually fired.

    // Add some slop to correct for drift. This should generally be
    // smaller than a typical frame duration, but should not be so small
    // that it reports reasonable drift as a missed frame.
    DisplayStatInfo stats;
    mScheduler->getDisplayStatInfo(&stats);
    const nsecs_t frameMissedSlop = stats.vsyncPeriod / 2;
    const nsecs_t previousPresentTime = previousFramePresentTime();
    const TracedOrdinal<bool> frameMissed = {
   "PrevFrameMissed",
                                             framePending ||
                                                     (previousPresentTime >= 0 &&
                                                      (lastScheduledPresentTime <
                                                       previousPresentTime - frameMissedSlop))};
    const TracedOrdinal<bool> hwcFrameMissed = {
   "PrevHwcFrameMissed",
                                                mHadDeviceComposition && frameMissed};
    const TracedOrdinal<bool> gpuFrameMissed = {
   "PrevGpuFrameMissed",
                                                mHadClientComposition && frameMissed};

    if (frameMissed) {
   
        mFrameMissedCount++;
        mTimeStats->incrementMissedFrames();
        if (mMissedFrameJankCount == 0) {
   
            mMissedFrameJankStart = systemTime();
        }
        mMissedFrameJankCount++;
    }

    if (hwcFrameMissed) {
   
        mHwcFrameMissedCount++;
    }

    if (gpuFrameMissed) {
   
        mGpuFrameMissedCount++;
    }

    // If we are in the middle of a config change and the fence hasn't
    // fired yet just wait for the next invalidate
    if (mSetActiveConfigPending) {
   
        if (framePending) {
   
            mEventQueue->invalidate();
            return;
        }

        // We received the present fence from the HWC, so we assume it successfully updated
        // the config, hence we update SF.
        mSetActiveConfigPending = false;
        ON_MAIN_THREAD(setActiveConfigInternal());
    }

    if (framePending && mPropagateBackpressure) {
   
        if ((hwcFrameMissed && !gpuFrameMissed) || mPropagateBackpressureClientComposition) {
   
            signalLayerUpdate();
            return;
        }
    }

    // Our jank window is always at least 100ms since we missed a
    // frame...
    static constexpr nsecs_t kMinJankyDuration =
            std::chrono::duration_cast<std::chrono::nanoseconds>(100ms).count();
    // ...but if it's larger than 1s then we missed the trace cutoff.
    static constexpr nsecs_t kMaxJankyDuration =
            std::chrono::duration_cast<std::chrono::nanoseconds>(1s).count();
    nsecs_t jankDurationToUpload = -1;
    // If we're in a user build then don't push any atoms
    if (!mIsUserBuild && mMissedFrameJankCount > 0) {
   
        const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked());
        // Only report jank when the display is on, as displays in DOZE
        // power mode may operate at a different frame rate than is
        // reported in their config, which causes noticeable (but less
        // severe) jank.
        if (display && display->getPowerMode() == hal::PowerMode::ON) {
   
            const nsecs_t currentTime = systemTime();
            const nsecs_t jankDuration = currentTime - mMissedFrameJankStart;
            if (jankDuration > kMinJankyDuration && jankDuration < kMaxJankyDuration) {
   
                jankDurationToUpload = jankDuration;
            }

            // We either reported a jank event or we missed the trace
            // window, so clear counters here.
            if (jankDuration > kMinJankyDuration) {
   
                mMissedFrameJankCount = 0;
                mMissedFrameJankStart = 0;
            }
        }
    }

    if (mTracingEnabledChanged) {
   
        mTracingEnabled = mTracing.isEnabled();
        mTracingEnabledChanged = false;
    }

    bool refreshNeeded;
    {
   
        ConditionalLockGuard<std::mutex> lock(mTracingLock, mTracingEnabled);

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

    // Layers need to get updated (in the previous line) before we can use them for
    // choosing the refresh rate.
    // Hold mStateLock as chooseRefreshRateForContent promotes wp to sp
    // and may eventually call to ~Layer() if it holds the last reference
    {
   
        Mutex::Autolock _l(mStateLock);
        mScheduler->chooseRefreshRateForContent();
    }

    ON_MAIN_THREAD(performSetActiveConfig());

    updateCursorAsync();
    updateInputFlinger();

    refreshNeeded |= mRepaintEverything;
    if (refreshNeeded && CC_LIKELY(mBootStage != BootStage::BOOTLOADER)) {
   
        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();
    }
}

其中调用了SurfaceFlinger的handleMessageInvalidate方法:

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

    if (mVisibleRegionsDirty) {
   
        computeLayerBounds();
    }

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

调用了SurfaceFlinger的handlePageFlip方法:

bool SurfaceFlinger::handlePageFlip()
{
   
    ATRACE_CALL();
    ALOGV("handlePageFlip");

    nsecs_t latchTime = systemTime();

    bool visibleRegions = false;
    bool frameQueued = false;
    bool newDataLatched = false;

    const nsecs_t expectedPresentTime = mExpectedPresentTime.load();

    // Store the set of layers that need updates. This set must not change as
    // buffers are being latched, as this could result in a deadlock.
    // Example: Two producers share the same command stream and:
    // 1.) Layer 0 is latched
    // 2.) Layer 0 gets a new frame
    // 2.) Layer 1 gets a new frame
    // 3.) Layer 1 is latched.
    // Display is now waiting on Layer 1's frame, which is behind layer 0's
    // second frame. But layer 0's second frame could be waiting on display.
    mDrawingState.traverse([&](Layer* layer) {
   
        if (layer->hasReadyFrame()) {
   
            frameQueued = true;
            if (layer->shouldPresentNow(expectedPresentTime)) {
   
                mLayersWithQueuedFrames.push_back(layer);
            } 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) {
   
        offscreenLayer->traverse(LayerVector::StateSet::Drawing,
                                         [&](Layer* l) {
    l->latchAndReleaseBuffer(); });
    }

    if (!mLayersWithQueuedFrames.empty()) {
   
        // 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)) {
   
                mLayersPendingRefresh.push_back(layer);
            }
            layer->useSurfaceDamage();
            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(); });

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

对所有有准备好了的buffer的Layer调用了latchBuffer方法,具体是调用了frameworks/native/services/surfaceflinger/BufferLayer.cpp的latchBuffer方法:

bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime,
                              nsecs_t expectedPresentTime) {
   
    ATRACE_CALL();

    bool refreshRequired = latchSidebandStream(recomputeVisibleRegions);

    if (refreshRequired) {
   
        return refreshRequired;
    }

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

    // if we've already called updateTexImage() without going through
    // a composition step, we have to skip this layer at this point
    // because we cannot call updateTeximage() without a corresponding
    // compositionComplete() call.
    // we'll trigger an update in onPreComposition().
    if (mRefreshPending) {
   
        return false;
    }

    // If the head buffer's acquire fence hasn't signaled yet, return and
    // try again later
    if (!fenceHasSignaled()) {
   
        ATRACE_NAME("!fenceHasSignaled()");
        mFlinger->signalLayerUpdate();
        return false;
    }

    // Capture the old state of the layer for comparisons later
    const State& s(getDrawingState());
    const bool oldOpacity = isOpaque(s);

    BufferInfo oldBufferInfo = mBufferInfo;

    if (!allTransactionsSignaled(expectedPresentTime)) 

你可能感兴趣的:(安卓Framework,android,安卓)