Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d73cc026 authored by Alec Mouri's avatar Alec Mouri Committed by Automerger Merge Worker
Browse files

Merge "[SurfaceFlinger] Adjust missed frame tracking" into rvc-dev am: c6f22ca1 am: ea46a40c

Change-Id: I5ed59f8e393917f67ae7922395fdc00021e22bd8
parents 3f7c86d9 ea46a40c
Loading
Loading
Loading
Loading
+46 −11
Original line number Diff line number Diff line
@@ -1028,7 +1028,7 @@ bool SurfaceFlinger::performSetActiveConfig() {
    ATRACE_CALL();
    ALOGV("performSetActiveConfig");
    if (mCheckPendingFence) {
        if (previousFrameMissed()) {
        if (previousFramePending()) {
            // fence has not signaled yet. wait for the next invalidate
            mEventQueue->invalidate();
            return true;
@@ -1775,13 +1775,17 @@ void SurfaceFlinger::updateVrFlinger() {
    setTransactionFlags(eDisplayTransactionNeeded);
}

bool SurfaceFlinger::previousFrameMissed(int graceTimeMs) NO_THREAD_SAFETY_ANALYSIS {
    ATRACE_CALL();
sp<Fence> SurfaceFlinger::previousFrameFence() NO_THREAD_SAFETY_ANALYSIS {
    // We are storing the last 2 present fences. If sf's phase offset is to be
    // woken up before the actual vsync but targeting the next vsync, we need to check
    // fence N-2
    const sp<Fence>& fence = mVSyncModulator->getOffsets().sf > 0 ? mPreviousPresentFences[0]
    return mVSyncModulator->getOffsets().sf > 0 ? mPreviousPresentFences[0]
                                                : mPreviousPresentFences[1];
}

bool SurfaceFlinger::previousFramePending(int graceTimeMs) NO_THREAD_SAFETY_ANALYSIS {
    ATRACE_CALL();
    const sp<Fence>& fence = previousFrameFence();

    if (fence == Fence::NO_FENCE) {
        return false;
@@ -1794,6 +1798,16 @@ bool SurfaceFlinger::previousFrameMissed(int graceTimeMs) NO_THREAD_SAFETY_ANALY
    return (fence->getStatus() == Fence::Status::Unsignaled);
}

nsecs_t SurfaceFlinger::previousFramePresentTime() NO_THREAD_SAFETY_ANALYSIS {
    const sp<Fence>& fence = previousFrameFence();

    if (fence == Fence::NO_FENCE) {
        return Fence::SIGNAL_TIME_INVALID;
    }

    return fence->getSignalTime();
}

void SurfaceFlinger::populateExpectedPresentTime() {
    DisplayStatInfo stats;
    mScheduler->getDisplayStatInfo(&stats);
@@ -1811,6 +1825,7 @@ void SurfaceFlinger::onMessageReceived(int32_t what) NO_THREAD_SAFETY_ANALYSIS {
            // calculate the expected present time once and use the cached
            // value throughout this frame to make sure all layers are
            // seeing this same value.
            const nsecs_t lastExpectedPresentTime = mExpectedPresentTime.load();
            populateExpectedPresentTime();

            // When Backpressure propagation is enabled we want to give a small grace period
@@ -1821,12 +1836,32 @@ void SurfaceFlinger::onMessageReceived(int32_t what) NO_THREAD_SAFETY_ANALYSIS {
                     (mPropagateBackpressureClientComposition || !mHadClientComposition))
                    ? 1
                    : 0;
            const TracedOrdinal<bool> frameMissed = {"FrameMissed",
                                                     previousFrameMissed(

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

            // 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 &&
                              (lastExpectedPresentTime < previousPresentTime - frameMissedSlop))};
            const TracedOrdinal<bool> hwcFrameMissed = {"PrevHwcFrameMissed",
                                                        mHadDeviceComposition && frameMissed};
            const TracedOrdinal<bool> gpuFrameMissed = {"GpuFrameMissed",
            const TracedOrdinal<bool> gpuFrameMissed = {"PrevGpuFrameMissed",
                                                        mHadClientComposition && frameMissed};

            if (frameMissed) {
@@ -1846,7 +1881,7 @@ void SurfaceFlinger::onMessageReceived(int32_t what) NO_THREAD_SAFETY_ANALYSIS {
                mGpuFrameMissedCount++;
            }

            if (frameMissed && mPropagateBackpressure) {
            if (framePending && mPropagateBackpressure) {
                if ((hwcFrameMissed && !gpuFrameMissed) ||
                    mPropagateBackpressureClientComposition) {
                    signalLayerUpdate();
+15 −1
Original line number Diff line number Diff line
@@ -844,7 +844,21 @@ private:

    bool isDisplayConfigAllowed(HwcConfigIndexType configId) const REQUIRES(mStateLock);

    bool previousFrameMissed(int graceTimeMs = 0);
    // Gets the fence for the previous frame.
    // Must be called on the main thread.
    sp<Fence> previousFrameFence();

    // Whether the previous frame has not yet been presented to the display.
    // If graceTimeMs is positive, this method waits for at most the provided
    // grace period before reporting if the frame missed.
    // Must be called on the main thread.
    bool previousFramePending(int graceTimeMs = 0);

    // Returns the previous time that the frame was presented. If the frame has
    // not been presented yet, then returns Fence::SIGNAL_TIME_PENDING. If there
    // is no pending frame, then returns Fence::SIGNAL_TIME_INVALID.
    // Must be called on the main thread.
    nsecs_t previousFramePresentTime();

    // Populates the expected present time for this frame. For negative offsets, performs a
    // correction using the predicted vsync for the next frame instead.