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

Commit 3645e64d authored by Ady Abraham's avatar Ady Abraham
Browse files

SF: wait instead of presenting early

If SurfaceFlinger duration is configured to a larger value
than the vsync period, there might be a chance that SF would
present the frame too early, if its actual duration is much shorter
than anticipating. To prevent this, we wait until the vsync occurs
before calling to hwc::present.

Bug: 185949581
Test: Configure large SF duration and observe systrace
Change-Id: Ic0c112a2808036d0f2e14a345c401fa56c2d29ab
parent a8bfb932
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -79,6 +79,9 @@ struct CompositionRefreshArgs {

    // If set, causes the dirty regions to flash with the delay
    std::optional<std::chrono::microseconds> devOptFlashDirtyRegionsDelay;

    // The earliest time to send the present command to the HAL
    std::chrono::steady_clock::time_point earliestPresentTime;
};

} // namespace android::compositionengine
+3 −0
Original line number Diff line number Diff line
@@ -115,6 +115,9 @@ struct OutputCompositionState {
    // Current target dataspace
    ui::Dataspace targetDataspace{ui::Dataspace::UNKNOWN};

    // The earliest time to send the present command to the HAL
    std::chrono::steady_clock::time_point earliestPresentTime;

    // Debugging
    void dump(std::string& result) const;
};
+5 −0
Original line number Diff line number Diff line
@@ -367,6 +367,11 @@ compositionengine::Output::FrameFences Display::presentAndGetFrameFences() {
        return fences;
    }

    {
        ATRACE_NAME("wait for earliest present time");
        std::this_thread::sleep_until(getState().earliestPresentTime);
    }

    auto& hwc = getCompositionEngine().getHwComposer();
    hwc.presentAndGetReleaseFences(*halDisplayIdOpt);

+2 −0
Original line number Diff line number Diff line
@@ -711,6 +711,8 @@ void Output::writeCompositionState(const compositionengine::CompositionRefreshAr
        return;
    }

    editState().earliestPresentTime = refreshArgs.earliestPresentTime;

    sp<GraphicBuffer> previousOverride = nullptr;
    for (auto* layer : getOutputLayersOrderedByZ()) {
        bool skipLayer = false;
+7 −0
Original line number Diff line number Diff line
@@ -927,4 +927,11 @@ void Scheduler::setPreferredRefreshRateForUid(FrameRateOverride frameRateOverrid
    }
}

std::chrono::steady_clock::time_point Scheduler::getPreviousVsyncFrom(
        nsecs_t expectedPresentTime) const {
    const auto presentTime = std::chrono::nanoseconds(expectedPresentTime);
    const auto vsyncPeriod = std::chrono::nanoseconds(mVsyncSchedule.tracker->currentPeriod());
    return std::chrono::steady_clock::time_point(presentTime - vsyncPeriod);
}

} // namespace android
Loading