With content detection off, prefer default frame rate

When content detection is off, or when we have no layer information to
make a decision, prefer the default frame rate.

Bug: 154648391

Test: - Modified a Pixel 4 to turn off content detection, idle, touch,
        and power boost. Confirmed that, without this CL, we have bad
        behavior where calls to setFrameRate() persist after the layer
        goes away, and that this CL fixes that behavior.

- Modified and enhanced the "no layers" unit test in
  RefreshRateConfigsTest.cpp.

Change-Id: I2fd0d64a6ad369580cbb2ebf91cbbed7c31e0281
This commit is contained in:
Steven Thomas 2020-05-18 17:30:35 -07:00
parent 9b5bf0f42d
commit debafed2c7
3 changed files with 25 additions and 31 deletions

View file

@ -139,8 +139,8 @@ const RefreshRate& RefreshRateConfigs::getBestRefreshRate(
return getMinRefreshRateByPolicyLocked();
}
if (layers.empty()) {
return getCurrentRefreshRateByPolicyLocked();
if (layers.empty() || noVoteLayers == layers.size()) {
return getMaxRefreshRateByPolicyLocked();
}
// Only if all layers want Min we should return Min

View file

@ -385,38 +385,33 @@ nsecs_t Scheduler::getDispSyncExpectedPresentTime(nsecs_t now) {
void Scheduler::registerLayer(Layer* layer) {
if (!mLayerHistory) return;
// If the content detection feature is off, all layers are registered at NoVote. We still
// 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().getFps(),
mRefreshRateConfigs.getMaxRefreshRate().getFps(),
const auto minFps = mRefreshRateConfigs.getMinRefreshRate().getFps();
const auto maxFps = mRefreshRateConfigs.getMaxRefreshRate().getFps();
if (layer->getWindowType() == InputWindowInfo::TYPE_STATUS_BAR) {
mLayerHistory->registerLayer(layer, minFps, maxFps,
scheduler::LayerHistory::LayerVoteType::NoVote);
return;
}
} else if (!mUseContentDetection) {
// If the content detection feature is off, all layers are registered at Max. We still keep
// the layer history, since we use it for other features (like Frame Rate API), so layers
// still need to be registered.
mLayerHistory->registerLayer(layer, minFps, maxFps,
scheduler::LayerHistory::LayerVoteType::Max);
} else if (!mUseContentDetectionV2) {
// In V1 of content detection, all layers are registered as Heuristic (unless it's
// wallpaper).
const auto highFps =
layer->getWindowType() == InputWindowInfo::TYPE_WALLPAPER ? minFps : maxFps;
// In V1 of content detection, all layers are registered as Heuristic (unless it's wallpaper).
if (!mUseContentDetectionV2) {
const auto lowFps = mRefreshRateConfigs.getMinRefreshRate().getFps();
const auto highFps = layer->getWindowType() == InputWindowInfo::TYPE_WALLPAPER
? lowFps
: mRefreshRateConfigs.getMaxRefreshRate().getFps();
mLayerHistory->registerLayer(layer, lowFps, highFps,
mLayerHistory->registerLayer(layer, minFps, 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().getFps(),
mRefreshRateConfigs.getMaxRefreshRate().getFps(),
mLayerHistory->registerLayer(layer, minFps, maxFps,
scheduler::LayerHistory::LayerVoteType::Min);
} else if (layer->getWindowType() == InputWindowInfo::TYPE_STATUS_BAR) {
mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().getFps(),
mRefreshRateConfigs.getMaxRefreshRate().getFps(),
scheduler::LayerHistory::LayerVoteType::NoVote);
} else {
mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().getFps(),
mRefreshRateConfigs.getMaxRefreshRate().getFps(),
mLayerHistory->registerLayer(layer, minFps, maxFps,
scheduler::LayerHistory::LayerVoteType::Heuristic);
}
}

View file

@ -340,15 +340,14 @@ TEST_F(RefreshRateConfigsTest, getBestRefreshRate_noLayers) {
std::make_unique<RefreshRateConfigs>(m60_72_90Device, /*currentConfigId=*/
HWC_CONFIG_ID_72);
// If there are not layers, there is not content detection, so return the current
// refresh rate.
// If there are no layers we select the default frame rate, which is the max of the primary
// range.
auto layers = std::vector<LayerRequirement>{};
EXPECT_EQ(mExpected72Config,
EXPECT_EQ(mExpected90Config,
refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/
false, /*idle*/ false, &ignored));
// Current refresh rate can always be changed.
refreshRateConfigs->setCurrentConfigId(HWC_CONFIG_ID_60);
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {60, 60}}), 0);
EXPECT_EQ(mExpected60Config,
refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/
false, /*idle*/ false, &ignored));