SurfaceFlinger: Consider resolution when switching refresh rate
Do not change refresh rate across configs with multiple resolutions
Bug: 150237118
Test: adb shell /data/nativetest64/libsurfaceflinger_unittest/libsurfaceflinger_unittest
Change-Id: I9b0f355a72343cf120229b98e6ad082ea75d3080
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index cd6075f..9a9523f 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -332,7 +332,7 @@
const nsecs_t last = mLastResyncTime.exchange(now);
if (now - last > kIgnoreDelay) {
- resyncToHardwareVsync(false, mRefreshRateConfigs.getCurrentRefreshRate().vsyncPeriod);
+ resyncToHardwareVsync(false, mRefreshRateConfigs.getCurrentRefreshRate().getVsyncPeriod());
}
}
@@ -389,34 +389,34 @@
// keep the layer history, since we use it for other features (like Frame Rate API), so layers
// still need to be registered.
if (!mUseContentDetection) {
- mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().fps,
- mRefreshRateConfigs.getMaxRefreshRate().fps,
+ mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().getFps(),
+ mRefreshRateConfigs.getMaxRefreshRate().getFps(),
scheduler::LayerHistory::LayerVoteType::NoVote);
return;
}
// In V1 of content detection, all layers are registered as Heuristic (unless it's wallpaper).
if (!mUseContentDetectionV2) {
- const auto lowFps = mRefreshRateConfigs.getMinRefreshRate().fps;
+ const auto lowFps = mRefreshRateConfigs.getMinRefreshRate().getFps();
const auto highFps = layer->getWindowType() == InputWindowInfo::TYPE_WALLPAPER
? lowFps
- : mRefreshRateConfigs.getMaxRefreshRate().fps;
+ : mRefreshRateConfigs.getMaxRefreshRate().getFps();
mLayerHistory->registerLayer(layer, lowFps, highFps,
scheduler::LayerHistory::LayerVoteType::Heuristic);
} else {
if (layer->getWindowType() == InputWindowInfo::TYPE_WALLPAPER) {
// Running Wallpaper at Min is considered as part of content detection.
- mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().fps,
- mRefreshRateConfigs.getMaxRefreshRate().fps,
+ mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().getFps(),
+ mRefreshRateConfigs.getMaxRefreshRate().getFps(),
scheduler::LayerHistory::LayerVoteType::Min);
} else if (layer->getWindowType() == InputWindowInfo::TYPE_STATUS_BAR) {
- mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().fps,
- mRefreshRateConfigs.getMaxRefreshRate().fps,
+ mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().getFps(),
+ mRefreshRateConfigs.getMaxRefreshRate().getFps(),
scheduler::LayerHistory::LayerVoteType::NoVote);
} else {
- mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().fps,
- mRefreshRateConfigs.getMaxRefreshRate().fps,
+ mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().getFps(),
+ mRefreshRateConfigs.getMaxRefreshRate().getFps(),
scheduler::LayerHistory::LayerVoteType::Heuristic);
}
}
@@ -503,12 +503,13 @@
// magic number
const auto& refreshRate = mRefreshRateConfigs.getCurrentRefreshRate();
constexpr float FPS_THRESHOLD_FOR_KERNEL_TIMER = 65.0f;
- if (state == TimerState::Reset && refreshRate.fps > FPS_THRESHOLD_FOR_KERNEL_TIMER) {
+ if (state == TimerState::Reset && refreshRate.getFps() > FPS_THRESHOLD_FOR_KERNEL_TIMER) {
// If we're not in performance mode then the kernel timer shouldn't do
// anything, as the refresh rate during DPU power collapse will be the
// same.
- resyncToHardwareVsync(true /* makeAvailable */, refreshRate.vsyncPeriod);
- } else if (state == TimerState::Expired && refreshRate.fps <= FPS_THRESHOLD_FOR_KERNEL_TIMER) {
+ resyncToHardwareVsync(true /* makeAvailable */, refreshRate.getVsyncPeriod());
+ } else if (state == TimerState::Expired &&
+ refreshRate.getFps() <= FPS_THRESHOLD_FOR_KERNEL_TIMER) {
// Disable HW VSYNC if the timer expired, as we don't need it enabled if
// we're not pushing frames, and if we're in PERFORMANCE mode then we'll
// need to update the DispSync model anyway.
@@ -580,30 +581,31 @@
if (mDisplayPowerTimer &&
(!mFeatures.isDisplayPowerStateNormal ||
mFeatures.displayPowerTimer == TimerState::Reset)) {
- return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId;
+ return mRefreshRateConfigs.getMaxRefreshRateByPolicy().getConfigId();
}
if (!mUseContentDetectionV2) {
// As long as touch is active we want to be in performance mode.
if (mTouchTimer && mFeatures.touch == TouchState::Active) {
- return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId;
+ return mRefreshRateConfigs.getMaxRefreshRateByPolicy().getConfigId();
}
}
// If timer has expired as it means there is no new content on the screen.
if (mIdleTimer && mFeatures.idleTimer == TimerState::Expired) {
- return mRefreshRateConfigs.getMinRefreshRateByPolicy().configId;
+ return mRefreshRateConfigs.getMinRefreshRateByPolicy().getConfigId();
}
if (!mUseContentDetectionV2) {
// If content detection is off we choose performance as we don't know the content fps.
if (mFeatures.contentDetectionV1 == ContentDetectionState::Off) {
// NOTE: V1 always calls this, but this is not a default behavior for V2.
- return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId;
+ return mRefreshRateConfigs.getMaxRefreshRateByPolicy().getConfigId();
}
// Content detection is on, find the appropriate refresh rate with minimal error
- return mRefreshRateConfigs.getRefreshRateForContent(mFeatures.contentRequirements).configId;
+ return mRefreshRateConfigs.getRefreshRateForContent(mFeatures.contentRequirements)
+ .getConfigId();
}
bool touchConsidered;
@@ -613,7 +615,7 @@
mTouchTimer &&
mFeatures.touch == TouchState::Active,
&touchConsidered)
- .configId;
+ .getConfigId();
if (touchConsidered) {
// Clear layer history if refresh rate was selected based on touch to allow
// the hueristic to pick up with the new rate.