Loading services/surfaceflinger/Scheduler/EventThread.cpp +2 −2 Original line number Original line Diff line number Diff line Loading @@ -421,7 +421,7 @@ void EventThread::setVsyncRate(uint32_t rate, const sp<EventThreadConnection>& c } } void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) { void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) { mCallback.resync(); mCallback.resync(IEventThreadCallback::ResyncCaller::RequestNextVsync); std::lock_guard<std::mutex> lock(mMutex); std::lock_guard<std::mutex> lock(mMutex); Loading @@ -437,7 +437,7 @@ VsyncEventData EventThread::getLatestVsyncEventData(const sp<EventThreadConnecti nsecs_t now) const { nsecs_t now) const { // Resync so that the vsync is accurate with hardware. getLatestVsyncEventData is an alternate // Resync so that the vsync is accurate with hardware. getLatestVsyncEventData is an alternate // way to get vsync data (instead of posting callbacks to Choreographer). // way to get vsync data (instead of posting callbacks to Choreographer). mCallback.resync(); mCallback.resync(IEventThreadCallback::ResyncCaller::RequestNextVsync); VsyncEventData vsyncEventData; VsyncEventData vsyncEventData; const Period frameInterval = mCallback.getVsyncPeriod(connection->mOwnerUid); const Period frameInterval = mCallback.getVsyncPeriod(connection->mOwnerUid); Loading services/surfaceflinger/Scheduler/EventThread.h +7 −1 Original line number Original line Diff line number Diff line Loading @@ -156,7 +156,13 @@ struct IEventThreadCallback { virtual bool throttleVsync(TimePoint, uid_t) = 0; virtual bool throttleVsync(TimePoint, uid_t) = 0; virtual Period getVsyncPeriod(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; virtual void onExpectedPresentTimePosted(TimePoint) = 0; }; }; Loading services/surfaceflinger/Scheduler/Scheduler.cpp +7 −3 Original line number Original line Diff line number Diff line Loading @@ -825,13 +825,17 @@ Fps Scheduler::getNextFrameInterval(PhysicalDisplayId id, return Fps::fromPeriodNsecs(frameInterval.ns()); return Fps::fromPeriodNsecs(frameInterval.ns()); } } void Scheduler::resync() { void Scheduler::resync(ResyncCaller caller) { static constexpr nsecs_t kIgnoreDelay = ms2ns(750); static constexpr nsecs_t kRequestNextVsyncIgnoreDelay = ms2ns(750); const nsecs_t now = systemTime(); const nsecs_t now = systemTime(); const nsecs_t last = mLastResyncTime.exchange(now); 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 */); resyncAllToHardwareVsync(false /* allowToEnable */); } } } } Loading services/surfaceflinger/Scheduler/Scheduler.h +2 −1 Original line number Original line Diff line number Diff line Loading @@ -246,7 +246,8 @@ public: ftl::FakeGuard guard(kMainThreadContext); ftl::FakeGuard guard(kMainThreadContext); resyncToHardwareVsyncLocked(id, allowToEnable, modePtr); resyncToHardwareVsyncLocked(id, allowToEnable, modePtr); } } void resync() override EXCLUDES(mDisplayLock); void resync(ResyncCaller) override EXCLUDES(mDisplayLock); void forceNextResync() { mLastResyncTime = 0; } void forceNextResync() { mLastResyncTime = 0; } // Passes a vsync sample to VsyncController. Returns true if // Passes a vsync sample to VsyncController. Returns true if Loading services/surfaceflinger/Scheduler/VSyncPredictor.cpp +15 −16 Original line number Original line Diff line number Diff line Loading @@ -66,7 +66,6 @@ VSyncPredictor::VSyncPredictor(std::unique_ptr<Clock> clock, ftl::NonNull<Displa kHistorySize(historySize), kHistorySize(historySize), kMinimumSamplesForPrediction(minimumSamplesForPrediction), kMinimumSamplesForPrediction(minimumSamplesForPrediction), kOutlierTolerancePercent(std::min(outlierTolerancePercent, kMaxPercent)), kOutlierTolerancePercent(std::min(outlierTolerancePercent, kMaxPercent)), kPredictorThreshold(ms2ns(200)), mDisplayModePtr(modePtr), mDisplayModePtr(modePtr), mNumVsyncsForFrame(numVsyncsPerFrame(mDisplayModePtr)) { mNumVsyncsForFrame(numVsyncsPerFrame(mDisplayModePtr)) { resetModel(); resetModel(); Loading Loading @@ -114,13 +113,13 @@ bool VSyncPredictor::validate(nsecs_t timestamp) const { const auto isThresholdEnabled = const auto isThresholdEnabled = FlagManager::getInstance().vsync_predictor_predicts_within_threshold() && FlagManager::getInstance().vsync_predictor_predicts_within_threshold() && mDisplayModePtr->getVrrConfig(); mDisplayModePtr->getVrrConfig(); const auto iter = std::min_element(mTimestamps.begin(), mTimestamps.end(), const auto iter = [=, this](nsecs_t a, nsecs_t b) { std::min_element(mTimestamps.begin(), mTimestamps.end(), [=](nsecs_t a, nsecs_t b) { nsecs_t diffA = std::abs(timestamp - a); nsecs_t diffA = std::abs(timestamp - a); nsecs_t diffB = std::abs(timestamp - b); nsecs_t diffB = std::abs(timestamp - b); if (isThresholdEnabled) { if (isThresholdEnabled) { bool withinThresholdA = diffA <= kPredictorThreshold; bool withinThresholdA = diffA <= kPredictorThreshold.ns(); bool withinThresholdB = diffB <= kPredictorThreshold; bool withinThresholdB = diffB <= kPredictorThreshold.ns(); if (withinThresholdA != withinThresholdB) { if (withinThresholdA != withinThresholdB) { return withinThresholdA; return withinThresholdA; } } Loading Loading @@ -340,7 +339,7 @@ bool VSyncPredictor::isVsyncWithinThreshold(nsecs_t currentTimestamp, nsecs_t previousTimestamp) const { nsecs_t previousTimestamp) const { if (FlagManager::getInstance().vsync_predictor_predicts_within_threshold() && if (FlagManager::getInstance().vsync_predictor_predicts_within_threshold() && mDisplayModePtr->getVrrConfig()) { mDisplayModePtr->getVrrConfig()) { return currentTimestamp - previousTimestamp <= kPredictorThreshold; return currentTimestamp - previousTimestamp <= kPredictorThreshold.ns(); } } return true; return true; } } Loading Loading @@ -369,7 +368,7 @@ size_t VSyncPredictor::getMinSamplesRequiredForPrediction() const { mDisplayModePtr->getVrrConfig() && mRenderRateOpt) { mDisplayModePtr->getVrrConfig() && mRenderRateOpt) { const size_t minimumSamplesForPrediction = const size_t minimumSamplesForPrediction = std::max(static_cast<size_t>(kAbsoluteMinSamplesForPrediction), std::max(static_cast<size_t>(kAbsoluteMinSamplesForPrediction), static_cast<size_t>(kPredictorThreshold / static_cast<size_t>(kPredictorThreshold.ns() / mRenderRateOpt->getPeriodNsecs())); mRenderRateOpt->getPeriodNsecs())); return std::min(kMinimumSamplesForPrediction, minimumSamplesForPrediction); return std::min(kMinimumSamplesForPrediction, minimumSamplesForPrediction); } } Loading Loading
services/surfaceflinger/Scheduler/EventThread.cpp +2 −2 Original line number Original line Diff line number Diff line Loading @@ -421,7 +421,7 @@ void EventThread::setVsyncRate(uint32_t rate, const sp<EventThreadConnection>& c } } void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) { void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) { mCallback.resync(); mCallback.resync(IEventThreadCallback::ResyncCaller::RequestNextVsync); std::lock_guard<std::mutex> lock(mMutex); std::lock_guard<std::mutex> lock(mMutex); Loading @@ -437,7 +437,7 @@ VsyncEventData EventThread::getLatestVsyncEventData(const sp<EventThreadConnecti nsecs_t now) const { nsecs_t now) const { // Resync so that the vsync is accurate with hardware. getLatestVsyncEventData is an alternate // Resync so that the vsync is accurate with hardware. getLatestVsyncEventData is an alternate // way to get vsync data (instead of posting callbacks to Choreographer). // way to get vsync data (instead of posting callbacks to Choreographer). mCallback.resync(); mCallback.resync(IEventThreadCallback::ResyncCaller::RequestNextVsync); VsyncEventData vsyncEventData; VsyncEventData vsyncEventData; const Period frameInterval = mCallback.getVsyncPeriod(connection->mOwnerUid); const Period frameInterval = mCallback.getVsyncPeriod(connection->mOwnerUid); Loading
services/surfaceflinger/Scheduler/EventThread.h +7 −1 Original line number Original line Diff line number Diff line Loading @@ -156,7 +156,13 @@ struct IEventThreadCallback { virtual bool throttleVsync(TimePoint, uid_t) = 0; virtual bool throttleVsync(TimePoint, uid_t) = 0; virtual Period getVsyncPeriod(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; virtual void onExpectedPresentTimePosted(TimePoint) = 0; }; }; Loading
services/surfaceflinger/Scheduler/Scheduler.cpp +7 −3 Original line number Original line Diff line number Diff line Loading @@ -825,13 +825,17 @@ Fps Scheduler::getNextFrameInterval(PhysicalDisplayId id, return Fps::fromPeriodNsecs(frameInterval.ns()); return Fps::fromPeriodNsecs(frameInterval.ns()); } } void Scheduler::resync() { void Scheduler::resync(ResyncCaller caller) { static constexpr nsecs_t kIgnoreDelay = ms2ns(750); static constexpr nsecs_t kRequestNextVsyncIgnoreDelay = ms2ns(750); const nsecs_t now = systemTime(); const nsecs_t now = systemTime(); const nsecs_t last = mLastResyncTime.exchange(now); 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 */); resyncAllToHardwareVsync(false /* allowToEnable */); } } } } Loading
services/surfaceflinger/Scheduler/Scheduler.h +2 −1 Original line number Original line Diff line number Diff line Loading @@ -246,7 +246,8 @@ public: ftl::FakeGuard guard(kMainThreadContext); ftl::FakeGuard guard(kMainThreadContext); resyncToHardwareVsyncLocked(id, allowToEnable, modePtr); resyncToHardwareVsyncLocked(id, allowToEnable, modePtr); } } void resync() override EXCLUDES(mDisplayLock); void resync(ResyncCaller) override EXCLUDES(mDisplayLock); void forceNextResync() { mLastResyncTime = 0; } void forceNextResync() { mLastResyncTime = 0; } // Passes a vsync sample to VsyncController. Returns true if // Passes a vsync sample to VsyncController. Returns true if Loading
services/surfaceflinger/Scheduler/VSyncPredictor.cpp +15 −16 Original line number Original line Diff line number Diff line Loading @@ -66,7 +66,6 @@ VSyncPredictor::VSyncPredictor(std::unique_ptr<Clock> clock, ftl::NonNull<Displa kHistorySize(historySize), kHistorySize(historySize), kMinimumSamplesForPrediction(minimumSamplesForPrediction), kMinimumSamplesForPrediction(minimumSamplesForPrediction), kOutlierTolerancePercent(std::min(outlierTolerancePercent, kMaxPercent)), kOutlierTolerancePercent(std::min(outlierTolerancePercent, kMaxPercent)), kPredictorThreshold(ms2ns(200)), mDisplayModePtr(modePtr), mDisplayModePtr(modePtr), mNumVsyncsForFrame(numVsyncsPerFrame(mDisplayModePtr)) { mNumVsyncsForFrame(numVsyncsPerFrame(mDisplayModePtr)) { resetModel(); resetModel(); Loading Loading @@ -114,13 +113,13 @@ bool VSyncPredictor::validate(nsecs_t timestamp) const { const auto isThresholdEnabled = const auto isThresholdEnabled = FlagManager::getInstance().vsync_predictor_predicts_within_threshold() && FlagManager::getInstance().vsync_predictor_predicts_within_threshold() && mDisplayModePtr->getVrrConfig(); mDisplayModePtr->getVrrConfig(); const auto iter = std::min_element(mTimestamps.begin(), mTimestamps.end(), const auto iter = [=, this](nsecs_t a, nsecs_t b) { std::min_element(mTimestamps.begin(), mTimestamps.end(), [=](nsecs_t a, nsecs_t b) { nsecs_t diffA = std::abs(timestamp - a); nsecs_t diffA = std::abs(timestamp - a); nsecs_t diffB = std::abs(timestamp - b); nsecs_t diffB = std::abs(timestamp - b); if (isThresholdEnabled) { if (isThresholdEnabled) { bool withinThresholdA = diffA <= kPredictorThreshold; bool withinThresholdA = diffA <= kPredictorThreshold.ns(); bool withinThresholdB = diffB <= kPredictorThreshold; bool withinThresholdB = diffB <= kPredictorThreshold.ns(); if (withinThresholdA != withinThresholdB) { if (withinThresholdA != withinThresholdB) { return withinThresholdA; return withinThresholdA; } } Loading Loading @@ -340,7 +339,7 @@ bool VSyncPredictor::isVsyncWithinThreshold(nsecs_t currentTimestamp, nsecs_t previousTimestamp) const { nsecs_t previousTimestamp) const { if (FlagManager::getInstance().vsync_predictor_predicts_within_threshold() && if (FlagManager::getInstance().vsync_predictor_predicts_within_threshold() && mDisplayModePtr->getVrrConfig()) { mDisplayModePtr->getVrrConfig()) { return currentTimestamp - previousTimestamp <= kPredictorThreshold; return currentTimestamp - previousTimestamp <= kPredictorThreshold.ns(); } } return true; return true; } } Loading Loading @@ -369,7 +368,7 @@ size_t VSyncPredictor::getMinSamplesRequiredForPrediction() const { mDisplayModePtr->getVrrConfig() && mRenderRateOpt) { mDisplayModePtr->getVrrConfig() && mRenderRateOpt) { const size_t minimumSamplesForPrediction = const size_t minimumSamplesForPrediction = std::max(static_cast<size_t>(kAbsoluteMinSamplesForPrediction), std::max(static_cast<size_t>(kAbsoluteMinSamplesForPrediction), static_cast<size_t>(kPredictorThreshold / static_cast<size_t>(kPredictorThreshold.ns() / mRenderRateOpt->getPeriodNsecs())); mRenderRateOpt->getPeriodNsecs())); return std::min(kMinimumSamplesForPrediction, minimumSamplesForPrediction); return std::min(kMinimumSamplesForPrediction, minimumSamplesForPrediction); } } Loading