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

Commit 692337e1 authored by Ady Abraham's avatar Ady Abraham
Browse files

SF: use a lower time to resync based on transaction

We currenly use 750ms threshold for resync to vsync based.
This value is too high for an accurate prediction, but we use
it to prevent severe power drain on apps use Choreographer without
rendering (like the case of a leaking animators). For transactions,
since we anyway wakeup SF main thread, there is less changes for a
misbehaved to wakeup SF without the intention to render.

Bug: 425994753
Test: ABTD (see bug for details)
Flag: com.android.graphics.surfaceflinger.flags.resync_on_tx
Change-Id: Icdd2c6755708e5ad934b7e240ddbceb20d7d8e23
parent 2a1d2126
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -421,7 +421,7 @@ void EventThread::setVsyncRate(uint32_t rate, const sp<EventThreadConnection>& c
}

void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) {
    mCallback.resync();
    mCallback.resync(IEventThreadCallback::ResyncCaller::RequestNextVsync);

    std::lock_guard<std::mutex> lock(mMutex);

@@ -437,7 +437,7 @@ VsyncEventData EventThread::getLatestVsyncEventData(const sp<EventThreadConnecti
                                                    nsecs_t now) const {
    // Resync so that the vsync is accurate with hardware. getLatestVsyncEventData is an alternate
    // way to get vsync data (instead of posting callbacks to Choreographer).
    mCallback.resync();
    mCallback.resync(IEventThreadCallback::ResyncCaller::RequestNextVsync);

    VsyncEventData vsyncEventData;
    const Period frameInterval = mCallback.getVsyncPeriod(connection->mOwnerUid);
+7 −1
Original line number Diff line number Diff line
@@ -156,7 +156,13 @@ struct IEventThreadCallback {

    virtual bool throttleVsync(TimePoint, uid_t) = 0;
    virtual Period getVsyncPeriod(uid_t) = 0;
    virtual void resync() = 0;

    enum class ResyncCaller {
        RequestNextVsync,
        Transaction,
    };
    virtual void resync(ResyncCaller) = 0;

    virtual void onExpectedPresentTimePosted(TimePoint) = 0;
};

+7 −3
Original line number Diff line number Diff line
@@ -792,13 +792,17 @@ Fps Scheduler::getNextFrameInterval(PhysicalDisplayId id,
    return Fps::fromPeriodNsecs(frameInterval.ns());
}

void Scheduler::resync() {
    static constexpr nsecs_t kIgnoreDelay = ms2ns(750);
void Scheduler::resync(ResyncCaller caller) {
    static constexpr nsecs_t kRequestNextVsyncIgnoreDelay = ms2ns(750);

    const nsecs_t now = systemTime();
    const nsecs_t last = mLastResyncTime.exchange(now);

    if (now - last > kIgnoreDelay) {
    const auto ignoreDelay = caller == ResyncCaller::Transaction
            ? VSyncTracker::kPredictorThreshold.ns()
            : kRequestNextVsyncIgnoreDelay;

    if (now - last > ignoreDelay) {
        resyncAllToHardwareVsync(false /* allowToEnable */);
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -234,7 +234,8 @@ public:
        ftl::FakeGuard guard(kMainThreadContext);
        resyncToHardwareVsyncLocked(id, allowToEnable, modePtr);
    }
    void resync() override EXCLUDES(mDisplayLock);

    void resync(ResyncCaller) override EXCLUDES(mDisplayLock);
    void forceNextResync() { mLastResyncTime = 0; }

    // Passes a vsync sample to VsyncController. Returns true if
+15 −16
Original line number Diff line number Diff line
@@ -66,7 +66,6 @@ VSyncPredictor::VSyncPredictor(std::unique_ptr<Clock> clock, ftl::NonNull<Displa
        kHistorySize(historySize),
        kMinimumSamplesForPrediction(minimumSamplesForPrediction),
        kOutlierTolerancePercent(std::min(outlierTolerancePercent, kMaxPercent)),
        kPredictorThreshold(ms2ns(200)),
        mDisplayModePtr(modePtr),
        mNumVsyncsForFrame(numVsyncsPerFrame(mDisplayModePtr)) {
    resetModel();
@@ -114,13 +113,13 @@ bool VSyncPredictor::validate(nsecs_t timestamp) const {
    const auto isThresholdEnabled =
            FlagManager::getInstance().vsync_predictor_predicts_within_threshold() &&
            mDisplayModePtr->getVrrConfig();
    const auto iter = std::min_element(mTimestamps.begin(), mTimestamps.end(),
                                       [=, this](nsecs_t a, nsecs_t b) {
    const auto iter =
            std::min_element(mTimestamps.begin(), mTimestamps.end(), [=](nsecs_t a, nsecs_t b) {
                nsecs_t diffA = std::abs(timestamp - a);
                nsecs_t diffB = std::abs(timestamp - b);
                if (isThresholdEnabled) {
                                               bool withinThresholdA = diffA <= kPredictorThreshold;
                                               bool withinThresholdB = diffB <= kPredictorThreshold;
                    bool withinThresholdA = diffA <= kPredictorThreshold.ns();
                    bool withinThresholdB = diffB <= kPredictorThreshold.ns();
                    if (withinThresholdA != withinThresholdB) {
                        return withinThresholdA;
                    }
@@ -340,7 +339,7 @@ bool VSyncPredictor::isVsyncWithinThreshold(nsecs_t currentTimestamp,
                                            nsecs_t previousTimestamp) const {
    if (FlagManager::getInstance().vsync_predictor_predicts_within_threshold() &&
        mDisplayModePtr->getVrrConfig()) {
        return currentTimestamp - previousTimestamp <= kPredictorThreshold;
        return currentTimestamp - previousTimestamp <= kPredictorThreshold.ns();
    }
    return true;
}
@@ -369,7 +368,7 @@ size_t VSyncPredictor::getMinSamplesRequiredForPrediction() const {
        mDisplayModePtr->getVrrConfig() && mRenderRateOpt) {
        const size_t minimumSamplesForPrediction =
                std::max(static_cast<size_t>(kAbsoluteMinSamplesForPrediction),
                         static_cast<size_t>(kPredictorThreshold /
                         static_cast<size_t>(kPredictorThreshold.ns() /
                                             mRenderRateOpt->getPeriodNsecs()));
        return std::min(kMinimumSamplesForPrediction, minimumSamplesForPrediction);
    }
Loading