Loading services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp +10 −10 Original line number Diff line number Diff line Loading @@ -202,24 +202,24 @@ float RefreshRateConfigs::calculateLayerScoreLocked(const LayerRequirement& laye } if (layer.vote == LayerVoteType::ExplicitExact) { const int divider = getFrameRateDivider(refreshRate.getFps(), layer.desiredRefreshRate); const int divisor = getFrameRateDivisor(refreshRate.getFps(), layer.desiredRefreshRate); if (mSupportsFrameRateOverrideByContent) { // Since we support frame rate override, allow refresh rates which are // multiples of the layer's request, as those apps would be throttled // down to run at the desired refresh rate. return divider > 0; return divisor > 0; } return divider == 1; return divisor == 1; } // If the layer frame rate is a divider of the refresh rate it should score // If the layer frame rate is a divisor of the refresh rate it should score // the highest score. if (getFrameRateDivider(refreshRate.getFps(), layer.desiredRefreshRate) > 0) { if (getFrameRateDivisor(refreshRate.getFps(), layer.desiredRefreshRate) > 0) { return 1.0f * seamlessness; } // The layer frame rate is not a divider of the refresh rate, // The layer frame rate is not a divisor of the refresh rate, // there is a small penalty attached to the score to favor the frame rates // the exactly matches the display refresh rate or a multiple. constexpr float kNonExactMatchingPenalty = 0.95f; Loading Loading @@ -543,11 +543,11 @@ RefreshRateConfigs::UidToFrameRateOverride RefreshRateConfigs::getFrameRateOverr } } // We just care about the refresh rates which are a divider of the // We just care about the refresh rates which are a divisor of the // display refresh rate auto iter = std::remove_if(scores.begin(), scores.end(), [&](const RefreshRateScore& score) { return getFrameRateDivider(displayFrameRate, score.refreshRate->getFps()) == 0; return getFrameRateDivisor(displayFrameRate, score.refreshRate->getFps()) == 0; }); scores.erase(iter, scores.end()); Loading Loading @@ -723,7 +723,7 @@ void RefreshRateConfigs::updateDisplayModes(const DisplayModes& modes, if (mConfig.enableFrameRateOverride) { for (const auto& mode1 : sortedModes) { for (const auto& mode2 : sortedModes) { if (getFrameRateDivider(mode1->getFps(), mode2->getFps()) >= 2) { if (getFrameRateDivisor(mode1->getFps(), mode2->getFps()) >= 2) { mSupportsFrameRateOverrideByContent = true; break; } Loading Loading @@ -915,7 +915,7 @@ RefreshRateConfigs::KernelIdleTimerAction RefreshRateConfigs::getIdleTimerAction return RefreshRateConfigs::KernelIdleTimerAction::TurnOn; } int RefreshRateConfigs::getFrameRateDivider(Fps displayFrameRate, Fps layerFrameRate) { int RefreshRateConfigs::getFrameRateDivisor(Fps displayFrameRate, Fps layerFrameRate) { // This calculation needs to be in sync with the java code // in DisplayManagerService.getDisplayInfoForFrameRateOverride Loading services/surfaceflinger/Scheduler/RefreshRateConfigs.h +2 −2 Original line number Diff line number Diff line Loading @@ -316,10 +316,10 @@ public: bool supportsFrameRateOverrideByContent() const { return mSupportsFrameRateOverrideByContent; } // Return the display refresh rate divider to match the layer // Return the display refresh rate divisor to match the layer // frame rate, or 0 if the display refresh rate is not a multiple of the // layer refresh rate. static int getFrameRateDivider(Fps displayFrameRate, Fps layerFrameRate); static int getFrameRateDivisor(Fps displayFrameRate, Fps layerFrameRate); // Returns if the provided frame rates have a ratio t*1000/1001 or t*1001/1000 // for an integer t. Loading services/surfaceflinger/Scheduler/Scheduler.cpp +4 −4 Original line number Diff line number Diff line Loading @@ -173,15 +173,15 @@ impl::EventThread::GetVsyncPeriodFunction Scheduler::makeGetVsyncPeriodFunction( return basePeriod; } const auto divider = scheduler::RefreshRateConfigs::getFrameRateDivider(refreshRateConfigs const auto divisor = scheduler::RefreshRateConfigs::getFrameRateDivisor(refreshRateConfigs ->getCurrentRefreshRate() .getFps(), *frameRate); if (divider <= 1) { if (divisor <= 1) { return basePeriod; } return basePeriod * divider; return basePeriod * divisor; }; } Loading services/surfaceflinger/Scheduler/VSyncPredictor.cpp +14 −14 Original line number Diff line number Diff line Loading @@ -256,7 +256,7 @@ nsecs_t VSyncPredictor::nextAnticipatedVSyncTimeFrom(nsecs_t timePoint) const { /* * Returns whether a given vsync timestamp is in phase with a frame rate. * If the frame rate is not a divider of the refresh rate, it is always considered in phase. * If the frame rate is not a divisor of the refresh rate, it is always considered in phase. * For example, if the vsync timestamps are (16.6,33.3,50.0,66.6): * isVSyncInPhase(16.6, 30) = true * isVSyncInPhase(33.3, 30) = false Loading @@ -271,42 +271,42 @@ bool VSyncPredictor::isVSyncInPhase(nsecs_t timePoint, Fps frameRate) const { }; std::lock_guard lock(mMutex); const auto divider = RefreshRateConfigs::getFrameRateDivider(Fps::fromPeriodNsecs(mIdealPeriod), frameRate); if (divider <= 1 || timePoint == 0) { const auto divisor = RefreshRateConfigs::getFrameRateDivisor(Fps::fromPeriodNsecs(mIdealPeriod), frameRate); if (divisor <= 1 || timePoint == 0) { return true; } const nsecs_t period = mRateMap[mIdealPeriod].slope; const nsecs_t justBeforeTimePoint = timePoint - period / 2; const nsecs_t dividedPeriod = mIdealPeriod / divider; const nsecs_t dividedPeriod = mIdealPeriod / divisor; // If this is the first time we have asked about this divider with the // If this is the first time we have asked about this divisor with the // current vsync period, it is considered in phase and we store the closest // vsync timestamp const auto knownTimestampIter = mRateDividerKnownTimestampMap.find(dividedPeriod); if (knownTimestampIter == mRateDividerKnownTimestampMap.end()) { const auto knownTimestampIter = mRateDivisorKnownTimestampMap.find(dividedPeriod); if (knownTimestampIter == mRateDivisorKnownTimestampMap.end()) { const auto vsync = nextAnticipatedVSyncTimeFromLocked(justBeforeTimePoint); mRateDividerKnownTimestampMap[dividedPeriod] = vsync; mRateDivisorKnownTimestampMap[dividedPeriod] = vsync; return true; } // Find the next N vsync timestamp where N is the divider. // Find the next N vsync timestamp where N is the divisor. // One of these vsyncs will be in phase. We return the one which is // the most aligned with the last known in phase vsync std::vector<VsyncError> vsyncs(static_cast<size_t>(divider)); std::vector<VsyncError> vsyncs(static_cast<size_t>(divisor)); const nsecs_t knownVsync = knownTimestampIter->second; nsecs_t point = justBeforeTimePoint; for (size_t i = 0; i < divider; i++) { for (size_t i = 0; i < divisor; i++) { const nsecs_t vsync = nextAnticipatedVSyncTimeFromLocked(point); const auto numPeriods = static_cast<float>(vsync - knownVsync) / (period * divider); const auto numPeriods = static_cast<float>(vsync - knownVsync) / (period * divisor); const auto error = std::abs(std::round(numPeriods) - numPeriods); vsyncs[i] = {vsync, error}; point = vsync + 1; } const auto minVsyncError = std::min_element(vsyncs.begin(), vsyncs.end()); mRateDividerKnownTimestampMap[dividedPeriod] = minVsyncError->vsyncTimestamp; mRateDivisorKnownTimestampMap[dividedPeriod] = minVsyncError->vsyncTimestamp; return std::abs(minVsyncError->vsyncTimestamp - timePoint) < period / 2; } Loading services/surfaceflinger/Scheduler/VSyncPredictor.h +1 −1 Original line number Diff line number Diff line Loading @@ -96,7 +96,7 @@ private: std::unordered_map<nsecs_t, Model> mutable mRateMap GUARDED_BY(mMutex); // Map between the divided vsync period and the last known vsync timestamp std::unordered_map<nsecs_t, nsecs_t> mutable mRateDividerKnownTimestampMap GUARDED_BY(mMutex); std::unordered_map<nsecs_t, nsecs_t> mutable mRateDivisorKnownTimestampMap GUARDED_BY(mMutex); size_t mLastTimestampIndex GUARDED_BY(mMutex) = 0; std::vector<nsecs_t> mTimestamps GUARDED_BY(mMutex); Loading Loading
services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp +10 −10 Original line number Diff line number Diff line Loading @@ -202,24 +202,24 @@ float RefreshRateConfigs::calculateLayerScoreLocked(const LayerRequirement& laye } if (layer.vote == LayerVoteType::ExplicitExact) { const int divider = getFrameRateDivider(refreshRate.getFps(), layer.desiredRefreshRate); const int divisor = getFrameRateDivisor(refreshRate.getFps(), layer.desiredRefreshRate); if (mSupportsFrameRateOverrideByContent) { // Since we support frame rate override, allow refresh rates which are // multiples of the layer's request, as those apps would be throttled // down to run at the desired refresh rate. return divider > 0; return divisor > 0; } return divider == 1; return divisor == 1; } // If the layer frame rate is a divider of the refresh rate it should score // If the layer frame rate is a divisor of the refresh rate it should score // the highest score. if (getFrameRateDivider(refreshRate.getFps(), layer.desiredRefreshRate) > 0) { if (getFrameRateDivisor(refreshRate.getFps(), layer.desiredRefreshRate) > 0) { return 1.0f * seamlessness; } // The layer frame rate is not a divider of the refresh rate, // The layer frame rate is not a divisor of the refresh rate, // there is a small penalty attached to the score to favor the frame rates // the exactly matches the display refresh rate or a multiple. constexpr float kNonExactMatchingPenalty = 0.95f; Loading Loading @@ -543,11 +543,11 @@ RefreshRateConfigs::UidToFrameRateOverride RefreshRateConfigs::getFrameRateOverr } } // We just care about the refresh rates which are a divider of the // We just care about the refresh rates which are a divisor of the // display refresh rate auto iter = std::remove_if(scores.begin(), scores.end(), [&](const RefreshRateScore& score) { return getFrameRateDivider(displayFrameRate, score.refreshRate->getFps()) == 0; return getFrameRateDivisor(displayFrameRate, score.refreshRate->getFps()) == 0; }); scores.erase(iter, scores.end()); Loading Loading @@ -723,7 +723,7 @@ void RefreshRateConfigs::updateDisplayModes(const DisplayModes& modes, if (mConfig.enableFrameRateOverride) { for (const auto& mode1 : sortedModes) { for (const auto& mode2 : sortedModes) { if (getFrameRateDivider(mode1->getFps(), mode2->getFps()) >= 2) { if (getFrameRateDivisor(mode1->getFps(), mode2->getFps()) >= 2) { mSupportsFrameRateOverrideByContent = true; break; } Loading Loading @@ -915,7 +915,7 @@ RefreshRateConfigs::KernelIdleTimerAction RefreshRateConfigs::getIdleTimerAction return RefreshRateConfigs::KernelIdleTimerAction::TurnOn; } int RefreshRateConfigs::getFrameRateDivider(Fps displayFrameRate, Fps layerFrameRate) { int RefreshRateConfigs::getFrameRateDivisor(Fps displayFrameRate, Fps layerFrameRate) { // This calculation needs to be in sync with the java code // in DisplayManagerService.getDisplayInfoForFrameRateOverride Loading
services/surfaceflinger/Scheduler/RefreshRateConfigs.h +2 −2 Original line number Diff line number Diff line Loading @@ -316,10 +316,10 @@ public: bool supportsFrameRateOverrideByContent() const { return mSupportsFrameRateOverrideByContent; } // Return the display refresh rate divider to match the layer // Return the display refresh rate divisor to match the layer // frame rate, or 0 if the display refresh rate is not a multiple of the // layer refresh rate. static int getFrameRateDivider(Fps displayFrameRate, Fps layerFrameRate); static int getFrameRateDivisor(Fps displayFrameRate, Fps layerFrameRate); // Returns if the provided frame rates have a ratio t*1000/1001 or t*1001/1000 // for an integer t. Loading
services/surfaceflinger/Scheduler/Scheduler.cpp +4 −4 Original line number Diff line number Diff line Loading @@ -173,15 +173,15 @@ impl::EventThread::GetVsyncPeriodFunction Scheduler::makeGetVsyncPeriodFunction( return basePeriod; } const auto divider = scheduler::RefreshRateConfigs::getFrameRateDivider(refreshRateConfigs const auto divisor = scheduler::RefreshRateConfigs::getFrameRateDivisor(refreshRateConfigs ->getCurrentRefreshRate() .getFps(), *frameRate); if (divider <= 1) { if (divisor <= 1) { return basePeriod; } return basePeriod * divider; return basePeriod * divisor; }; } Loading
services/surfaceflinger/Scheduler/VSyncPredictor.cpp +14 −14 Original line number Diff line number Diff line Loading @@ -256,7 +256,7 @@ nsecs_t VSyncPredictor::nextAnticipatedVSyncTimeFrom(nsecs_t timePoint) const { /* * Returns whether a given vsync timestamp is in phase with a frame rate. * If the frame rate is not a divider of the refresh rate, it is always considered in phase. * If the frame rate is not a divisor of the refresh rate, it is always considered in phase. * For example, if the vsync timestamps are (16.6,33.3,50.0,66.6): * isVSyncInPhase(16.6, 30) = true * isVSyncInPhase(33.3, 30) = false Loading @@ -271,42 +271,42 @@ bool VSyncPredictor::isVSyncInPhase(nsecs_t timePoint, Fps frameRate) const { }; std::lock_guard lock(mMutex); const auto divider = RefreshRateConfigs::getFrameRateDivider(Fps::fromPeriodNsecs(mIdealPeriod), frameRate); if (divider <= 1 || timePoint == 0) { const auto divisor = RefreshRateConfigs::getFrameRateDivisor(Fps::fromPeriodNsecs(mIdealPeriod), frameRate); if (divisor <= 1 || timePoint == 0) { return true; } const nsecs_t period = mRateMap[mIdealPeriod].slope; const nsecs_t justBeforeTimePoint = timePoint - period / 2; const nsecs_t dividedPeriod = mIdealPeriod / divider; const nsecs_t dividedPeriod = mIdealPeriod / divisor; // If this is the first time we have asked about this divider with the // If this is the first time we have asked about this divisor with the // current vsync period, it is considered in phase and we store the closest // vsync timestamp const auto knownTimestampIter = mRateDividerKnownTimestampMap.find(dividedPeriod); if (knownTimestampIter == mRateDividerKnownTimestampMap.end()) { const auto knownTimestampIter = mRateDivisorKnownTimestampMap.find(dividedPeriod); if (knownTimestampIter == mRateDivisorKnownTimestampMap.end()) { const auto vsync = nextAnticipatedVSyncTimeFromLocked(justBeforeTimePoint); mRateDividerKnownTimestampMap[dividedPeriod] = vsync; mRateDivisorKnownTimestampMap[dividedPeriod] = vsync; return true; } // Find the next N vsync timestamp where N is the divider. // Find the next N vsync timestamp where N is the divisor. // One of these vsyncs will be in phase. We return the one which is // the most aligned with the last known in phase vsync std::vector<VsyncError> vsyncs(static_cast<size_t>(divider)); std::vector<VsyncError> vsyncs(static_cast<size_t>(divisor)); const nsecs_t knownVsync = knownTimestampIter->second; nsecs_t point = justBeforeTimePoint; for (size_t i = 0; i < divider; i++) { for (size_t i = 0; i < divisor; i++) { const nsecs_t vsync = nextAnticipatedVSyncTimeFromLocked(point); const auto numPeriods = static_cast<float>(vsync - knownVsync) / (period * divider); const auto numPeriods = static_cast<float>(vsync - knownVsync) / (period * divisor); const auto error = std::abs(std::round(numPeriods) - numPeriods); vsyncs[i] = {vsync, error}; point = vsync + 1; } const auto minVsyncError = std::min_element(vsyncs.begin(), vsyncs.end()); mRateDividerKnownTimestampMap[dividedPeriod] = minVsyncError->vsyncTimestamp; mRateDivisorKnownTimestampMap[dividedPeriod] = minVsyncError->vsyncTimestamp; return std::abs(minVsyncError->vsyncTimestamp - timePoint) < period / 2; } Loading
services/surfaceflinger/Scheduler/VSyncPredictor.h +1 −1 Original line number Diff line number Diff line Loading @@ -96,7 +96,7 @@ private: std::unordered_map<nsecs_t, Model> mutable mRateMap GUARDED_BY(mMutex); // Map between the divided vsync period and the last known vsync timestamp std::unordered_map<nsecs_t, nsecs_t> mutable mRateDividerKnownTimestampMap GUARDED_BY(mMutex); std::unordered_map<nsecs_t, nsecs_t> mutable mRateDivisorKnownTimestampMap GUARDED_BY(mMutex); size_t mLastTimestampIndex GUARDED_BY(mMutex) = 0; std::vector<nsecs_t> mTimestamps GUARDED_BY(mMutex); Loading