Merge "SF: Mutable RefreshRateConfigs"
diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp
index 32110e9..9230e72 100644
--- a/services/surfaceflinger/RefreshRateOverlay.cpp
+++ b/services/surfaceflinger/RefreshRateOverlay.cpp
@@ -233,8 +233,8 @@
mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
}
-void RefreshRateOverlay::changeRefreshRate(const RefreshRate& refreshRate) {
- mCurrentFps = refreshRate.getFps().getIntValue();
+void RefreshRateOverlay::changeRefreshRate(const Fps& fps) {
+ mCurrentFps = fps.getIntValue();
auto buffer = getOrCreateBuffers(*mCurrentFps)[mFrame];
mLayer->setBuffer(buffer, Fence::NO_FENCE, 0, 0, true, {},
mLayer->getHeadFrameNumber(-1 /* expectedPresentTime */),
@@ -258,8 +258,9 @@
void RefreshRateOverlay::reset() {
mBufferCache.clear();
- mLowFps = mFlinger.mRefreshRateConfigs->getMinRefreshRate().getFps().getIntValue();
- mHighFps = mFlinger.mRefreshRateConfigs->getMaxRefreshRate().getFps().getIntValue();
+ const auto range = mFlinger.mRefreshRateConfigs->getSupportedRefreshRateRange();
+ mLowFps = range.min.getIntValue();
+ mHighFps = range.max.getIntValue();
}
} // namespace android
diff --git a/services/surfaceflinger/RefreshRateOverlay.h b/services/surfaceflinger/RefreshRateOverlay.h
index 4ca1337..c16cfa0 100644
--- a/services/surfaceflinger/RefreshRateOverlay.h
+++ b/services/surfaceflinger/RefreshRateOverlay.h
@@ -23,7 +23,7 @@
#include <ui/Size.h>
#include <utils/StrongPointer.h>
-#include "Scheduler/RefreshRateConfigs.h"
+#include "Fps.h"
namespace android {
@@ -34,14 +34,12 @@
class Layer;
class SurfaceFlinger;
-using RefreshRate = scheduler::RefreshRateConfigs::RefreshRate;
-
class RefreshRateOverlay {
public:
RefreshRateOverlay(SurfaceFlinger&, bool showSpinner);
void setViewport(ui::Size);
- void changeRefreshRate(const RefreshRate&);
+ void changeRefreshRate(const Fps&);
void onInvalidate();
void reset();
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index c42c812..975754b 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -39,6 +39,26 @@
toString(layer.seamlessness).c_str(),
to_string(layer.desiredRefreshRate).c_str());
}
+
+std::vector<Fps> constructKnownFrameRates(
+ const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs) {
+ std::vector<Fps> knownFrameRates = {Fps(24.0f), Fps(30.0f), Fps(45.0f), Fps(60.0f), Fps(72.0f)};
+ knownFrameRates.reserve(knownFrameRates.size() + configs.size());
+
+ // Add all supported refresh rates to the set
+ for (const auto& config : configs) {
+ const auto refreshRate = Fps::fromPeriodNsecs(config->getVsyncPeriod());
+ knownFrameRates.emplace_back(refreshRate);
+ }
+
+ // Sort and remove duplicates
+ std::sort(knownFrameRates.begin(), knownFrameRates.end(), Fps::comparesLess);
+ knownFrameRates.erase(std::unique(knownFrameRates.begin(), knownFrameRates.end(),
+ Fps::EqualsWithMargin()),
+ knownFrameRates.end());
+ return knownFrameRates;
+}
+
} // namespace
using AllRefreshRatesMapType = RefreshRateConfigs::AllRefreshRatesMapType;
@@ -154,9 +174,9 @@
float score;
};
-const RefreshRate& RefreshRateConfigs::getBestRefreshRate(
- const std::vector<LayerRequirement>& layers, const GlobalSignals& globalSignals,
- GlobalSignals* outSignalsConsidered) const {
+RefreshRate RefreshRateConfigs::getBestRefreshRate(const std::vector<LayerRequirement>& layers,
+ const GlobalSignals& globalSignals,
+ GlobalSignals* outSignalsConsidered) const {
ATRACE_CALL();
ALOGV("getBestRefreshRate %zu layers", layers.size());
@@ -469,9 +489,20 @@
return bestRefreshRate;
}
-const RefreshRate& RefreshRateConfigs::getMinRefreshRateByPolicy() const {
+std::optional<Fps> RefreshRateConfigs::onKernelTimerChanged(
+ std::optional<HwcConfigIndexType> desiredActiveConfigId, bool timerExpired) const {
std::lock_guard lock(mLock);
- return getMinRefreshRateByPolicyLocked();
+
+ const auto& current = desiredActiveConfigId ? *mRefreshRates.at(*desiredActiveConfigId)
+ : *mCurrentRefreshRate;
+ const auto& min = *mMinSupportedRefreshRate;
+
+ if (current != min) {
+ const auto& refreshRate = timerExpired ? min : current;
+ return refreshRate.getFps();
+ }
+
+ return {};
}
const RefreshRate& RefreshRateConfigs::getMinRefreshRateByPolicyLocked() const {
@@ -487,7 +518,7 @@
return *mPrimaryRefreshRates.front();
}
-const RefreshRate& RefreshRateConfigs::getMaxRefreshRateByPolicy() const {
+RefreshRate RefreshRateConfigs::getMaxRefreshRateByPolicy() const {
std::lock_guard lock(mLock);
return getMaxRefreshRateByPolicyLocked();
}
@@ -506,12 +537,12 @@
return *mPrimaryRefreshRates.back();
}
-const RefreshRate& RefreshRateConfigs::getCurrentRefreshRate() const {
+RefreshRate RefreshRateConfigs::getCurrentRefreshRate() const {
std::lock_guard lock(mLock);
return *mCurrentRefreshRate;
}
-const RefreshRate& RefreshRateConfigs::getCurrentRefreshRateByPolicy() const {
+RefreshRate RefreshRateConfigs::getCurrentRefreshRateByPolicy() const {
std::lock_guard lock(mLock);
return getCurrentRefreshRateByPolicyLocked();
}
@@ -533,16 +564,23 @@
const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs,
HwcConfigIndexType currentConfigId)
: mKnownFrameRates(constructKnownFrameRates(configs)) {
+ updateDisplayConfigs(configs, currentConfigId);
+}
+
+void RefreshRateConfigs::updateDisplayConfigs(
+ const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs,
+ HwcConfigIndexType currentConfigId) {
+ std::lock_guard lock(mLock);
LOG_ALWAYS_FATAL_IF(configs.empty());
LOG_ALWAYS_FATAL_IF(currentConfigId.value() < 0);
LOG_ALWAYS_FATAL_IF(currentConfigId.value() >= configs.size());
+ mRefreshRates.clear();
for (auto configId = HwcConfigIndexType(0); configId.value() < configs.size(); configId++) {
const auto& config = configs.at(static_cast<size_t>(configId.value()));
+ const auto fps = Fps::fromPeriodNsecs(config->getVsyncPeriod());
mRefreshRates.emplace(configId,
- std::make_unique<RefreshRate>(configId, config,
- Fps::fromPeriodNsecs(
- config->getVsyncPeriod()),
+ std::make_unique<RefreshRate>(configId, config, fps,
RefreshRate::ConstructorTag(0)));
if (configId == currentConfigId) {
mCurrentRefreshRate = mRefreshRates.at(configId).get();
@@ -550,7 +588,7 @@
}
std::vector<const RefreshRate*> sortedConfigs;
- getSortedRefreshRateList([](const RefreshRate&) { return true; }, &sortedConfigs);
+ getSortedRefreshRateListLocked([](const RefreshRate&) { return true; }, &sortedConfigs);
mDisplayManagerPolicy.defaultConfig = currentConfigId;
mMinSupportedRefreshRate = sortedConfigs.front();
mMaxSupportedRefreshRate = sortedConfigs.back();
@@ -570,7 +608,7 @@
constructAvailableRefreshRates();
}
-bool RefreshRateConfigs::isPolicyValid(const Policy& policy) {
+bool RefreshRateConfigs::isPolicyValidLocked(const Policy& policy) const {
// defaultConfig must be a valid config, and within the given refresh rate range.
auto iter = mRefreshRates.find(policy.defaultConfig);
if (iter == mRefreshRates.end()) {
@@ -588,7 +626,7 @@
status_t RefreshRateConfigs::setDisplayManagerPolicy(const Policy& policy) {
std::lock_guard lock(mLock);
- if (!isPolicyValid(policy)) {
+ if (!isPolicyValidLocked(policy)) {
ALOGE("Invalid refresh rate policy: %s", policy.toString().c_str());
return BAD_VALUE;
}
@@ -603,7 +641,7 @@
status_t RefreshRateConfigs::setOverridePolicy(const std::optional<Policy>& policy) {
std::lock_guard lock(mLock);
- if (policy && !isPolicyValid(*policy)) {
+ if (policy && !isPolicyValidLocked(*policy)) {
return BAD_VALUE;
}
Policy previousPolicy = *getCurrentPolicyLocked();
@@ -639,14 +677,14 @@
return false;
}
-void RefreshRateConfigs::getSortedRefreshRateList(
+void RefreshRateConfigs::getSortedRefreshRateListLocked(
const std::function<bool(const RefreshRate&)>& shouldAddRefreshRate,
std::vector<const RefreshRate*>* outRefreshRates) {
outRefreshRates->clear();
outRefreshRates->reserve(mRefreshRates.size());
for (const auto& [type, refreshRate] : mRefreshRates) {
if (shouldAddRefreshRate(*refreshRate)) {
- ALOGV("getSortedRefreshRateList: config %d added to list policy",
+ ALOGV("getSortedRefreshRateListLocked: config %d added to list policy",
refreshRate->configId.value());
outRefreshRates->push_back(refreshRate.get());
}
@@ -672,8 +710,9 @@
ALOGV("constructAvailableRefreshRates: %s ", policy->toString().c_str());
auto filterRefreshRates = [&](Fps min, Fps max, const char* listName,
- std::vector<const RefreshRate*>* outRefreshRates) {
- getSortedRefreshRateList(
+ std::vector<const RefreshRate*>*
+ outRefreshRates) REQUIRES(mLock) {
+ getSortedRefreshRateListLocked(
[&](const RefreshRate& refreshRate) REQUIRES(mLock) {
const auto& hwcConfig = refreshRate.hwcConfig;
@@ -706,25 +745,6 @@
&mAppRequestRefreshRates);
}
-std::vector<Fps> RefreshRateConfigs::constructKnownFrameRates(
- const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs) {
- std::vector<Fps> knownFrameRates = {Fps(24.0f), Fps(30.0f), Fps(45.0f), Fps(60.0f), Fps(72.0f)};
- knownFrameRates.reserve(knownFrameRates.size() + configs.size());
-
- // Add all supported refresh rates to the set
- for (const auto& config : configs) {
- const auto refreshRate = Fps::fromPeriodNsecs(config->getVsyncPeriod());
- knownFrameRates.emplace_back(refreshRate);
- }
-
- // Sort and remove duplicates
- std::sort(knownFrameRates.begin(), knownFrameRates.end(), Fps::comparesLess);
- knownFrameRates.erase(std::unique(knownFrameRates.begin(), knownFrameRates.end(),
- Fps::EqualsWithMargin()),
- knownFrameRates.end());
- return knownFrameRates;
-}
-
Fps RefreshRateConfigs::findClosestKnownFrameRate(Fps frameRate) const {
if (frameRate.lessThanOrEqualWithMargin(*mKnownFrameRates.begin())) {
return *mKnownFrameRates.begin();
@@ -744,7 +764,7 @@
RefreshRateConfigs::KernelIdleTimerAction RefreshRateConfigs::getIdleTimerAction() const {
std::lock_guard lock(mLock);
- const auto& deviceMin = getMinRefreshRate();
+ const auto& deviceMin = *mMinSupportedRefreshRate;
const auto& minByPolicy = getMinRefreshRateByPolicyLocked();
const auto& maxByPolicy = getMaxRefreshRateByPolicyLocked();
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index e4bbf7f..4b99145 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -68,8 +68,6 @@
std::shared_ptr<const HWC2::Display::Config> config, Fps fps, ConstructorTag)
: configId(configId), hwcConfig(config), fps(std::move(fps)) {}
- RefreshRate(const RefreshRate&) = delete;
-
HwcConfigIndexType getConfigId() const { return configId; }
nsecs_t getVsyncPeriod() const { return hwcConfig->getVsyncPeriod(); }
int32_t getConfigGroup() const { return hwcConfig->getConfigGroup(); }
@@ -111,27 +109,26 @@
using AllRefreshRatesMapType =
std::unordered_map<HwcConfigIndexType, std::unique_ptr<const RefreshRate>>;
+ struct FpsRange {
+ Fps min{0.0f};
+ Fps max{std::numeric_limits<float>::max()};
+
+ bool operator==(const FpsRange& other) const {
+ return min.equalsWithMargin(other.min) && max.equalsWithMargin(other.max);
+ }
+
+ bool operator!=(const FpsRange& other) const { return !(*this == other); }
+
+ std::string toString() const {
+ return base::StringPrintf("[%s %s]", to_string(min).c_str(), to_string(max).c_str());
+ }
+ };
+
struct Policy {
private:
static constexpr int kAllowGroupSwitchingDefault = false;
public:
- struct Range {
- Fps min{0.0f};
- Fps max{std::numeric_limits<float>::max()};
-
- bool operator==(const Range& other) const {
- return min.equalsWithMargin(other.min) && max.equalsWithMargin(other.max);
- }
-
- bool operator!=(const Range& other) const { return !(*this == other); }
-
- std::string toString() const {
- return base::StringPrintf("[%s %s]", to_string(min).c_str(),
- to_string(max).c_str());
- }
- };
-
// The default config, used to ensure we only initiate display config switches within the
// same config group as defaultConfigId's group.
HwcConfigIndexType defaultConfig;
@@ -140,29 +137,29 @@
// The primary refresh rate range represents display manager's general guidance on the
// display configs we'll consider when switching refresh rates. Unless we get an explicit
// signal from an app, we should stay within this range.
- Range primaryRange;
+ FpsRange primaryRange;
// The app request refresh rate range allows us to consider more display configs when
// switching refresh rates. Although we should generally stay within the primary range,
// specific considerations, such as layer frame rate settings specified via the
// setFrameRate() api, may cause us to go outside the primary range. We never go outside the
// app request range. The app request range will be greater than or equal to the primary
// refresh rate range, never smaller.
- Range appRequestRange;
+ FpsRange appRequestRange;
Policy() = default;
- Policy(HwcConfigIndexType defaultConfig, const Range& range)
+ Policy(HwcConfigIndexType defaultConfig, const FpsRange& range)
: Policy(defaultConfig, kAllowGroupSwitchingDefault, range, range) {}
- Policy(HwcConfigIndexType defaultConfig, bool allowGroupSwitching, const Range& range)
+ Policy(HwcConfigIndexType defaultConfig, bool allowGroupSwitching, const FpsRange& range)
: Policy(defaultConfig, allowGroupSwitching, range, range) {}
- Policy(HwcConfigIndexType defaultConfig, const Range& primaryRange,
- const Range& appRequestRange)
+ Policy(HwcConfigIndexType defaultConfig, const FpsRange& primaryRange,
+ const FpsRange& appRequestRange)
: Policy(defaultConfig, kAllowGroupSwitchingDefault, primaryRange, appRequestRange) {}
Policy(HwcConfigIndexType defaultConfig, bool allowGroupSwitching,
- const Range& primaryRange, const Range& appRequestRange)
+ const FpsRange& primaryRange, const FpsRange& appRequestRange)
: defaultConfig(defaultConfig),
allowGroupSwitching(allowGroupSwitching),
primaryRange(primaryRange),
@@ -258,35 +255,35 @@
// globalSignals - global state of touch and idle
// outSignalsConsidered - An output param that tells the caller whether the refresh rate was
// chosen based on touch boost and/or idle timer.
- const RefreshRate& getBestRefreshRate(const std::vector<LayerRequirement>& layers,
- const GlobalSignals& globalSignals,
- GlobalSignals* outSignalsConsidered = nullptr) const
+ RefreshRate getBestRefreshRate(const std::vector<LayerRequirement>& layers,
+ const GlobalSignals& globalSignals,
+ GlobalSignals* outSignalsConsidered = nullptr) const
EXCLUDES(mLock);
- // Returns the lowest refresh rate supported by the device. This won't change at runtime.
- const RefreshRate& getMinRefreshRate() const { return *mMinSupportedRefreshRate; }
+ FpsRange getSupportedRefreshRateRange() const EXCLUDES(mLock) {
+ std::lock_guard lock(mLock);
+ return {mMinSupportedRefreshRate->getFps(), mMaxSupportedRefreshRate->getFps()};
+ }
- // Returns the lowest refresh rate according to the current policy. May change at runtime. Only
- // uses the primary range, not the app request range.
- const RefreshRate& getMinRefreshRateByPolicy() const EXCLUDES(mLock);
-
- // Returns the highest refresh rate supported by the device. This won't change at runtime.
- const RefreshRate& getMaxRefreshRate() const { return *mMaxSupportedRefreshRate; }
+ std::optional<Fps> onKernelTimerChanged(std::optional<HwcConfigIndexType> desiredActiveConfigId,
+ bool timerExpired) const EXCLUDES(mLock);
// Returns the highest refresh rate according to the current policy. May change at runtime. Only
// uses the primary range, not the app request range.
- const RefreshRate& getMaxRefreshRateByPolicy() const EXCLUDES(mLock);
+ RefreshRate getMaxRefreshRateByPolicy() const EXCLUDES(mLock);
// Returns the current refresh rate
- const RefreshRate& getCurrentRefreshRate() const EXCLUDES(mLock);
+ RefreshRate getCurrentRefreshRate() const EXCLUDES(mLock);
// Returns the current refresh rate, if allowed. Otherwise the default that is allowed by
// the policy.
- const RefreshRate& getCurrentRefreshRateByPolicy() const;
+ RefreshRate getCurrentRefreshRateByPolicy() const;
- // Returns the refresh rate that corresponds to a HwcConfigIndexType. This won't change at
+ // Returns the refresh rate that corresponds to a HwcConfigIndexType. This may change at
// runtime.
- const RefreshRate& getRefreshRateFromConfigId(HwcConfigIndexType configId) const {
+ // TODO(b/159590486) An invalid config id may be given here if the dipslay configs have changed.
+ RefreshRate getRefreshRateFromConfigId(HwcConfigIndexType configId) const EXCLUDES(mLock) {
+ std::lock_guard lock(mLock);
return *mRefreshRates.at(configId);
};
@@ -302,10 +299,17 @@
RefreshRateConfigs(const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs,
HwcConfigIndexType currentConfigId);
+ void updateDisplayConfigs(
+ const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs,
+ HwcConfigIndexType currentConfig) EXCLUDES(mLock);
+
// Returns whether switching configs (refresh rate or resolution) is possible.
// TODO(b/158780872): Consider HAL support, and skip frame rate detection if the configs only
// differ in resolution.
- bool canSwitch() const { return mRefreshRates.size() > 1; }
+ bool canSwitch() const EXCLUDES(mLock) {
+ std::lock_guard lock(mLock);
+ return mRefreshRates.size() > 1;
+ }
// Class to enumerate options around toggling the kernel timer on and off. We have an option
// for no change to avoid extra calls to kernel.
@@ -334,12 +338,10 @@
friend class RefreshRateConfigsTest;
void constructAvailableRefreshRates() REQUIRES(mLock);
- static std::vector<Fps> constructKnownFrameRates(
- const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs);
- void getSortedRefreshRateList(
+ void getSortedRefreshRateListLocked(
const std::function<bool(const RefreshRate&)>& shouldAddRefreshRate,
- std::vector<const RefreshRate*>* outRefreshRates);
+ std::vector<const RefreshRate*>* outRefreshRates) REQUIRES(mLock);
// Returns the refresh rate with the highest score in the collection specified from begin
// to end. If there are more than one with the same highest refresh rate, the first one is
@@ -364,7 +366,7 @@
const RefreshRate& getCurrentRefreshRateByPolicyLocked() const REQUIRES(mLock);
const Policy* getCurrentPolicyLocked() const REQUIRES(mLock);
- bool isPolicyValid(const Policy& policy);
+ bool isPolicyValidLocked(const Policy& policy) const REQUIRES(mLock);
// Return the display refresh rate divider to match the layer
// frame rate, or 0 if the display refresh rate is not a multiple of the
@@ -376,9 +378,9 @@
float calculateLayerScoreLocked(const LayerRequirement&, const RefreshRate&,
bool isSeamlessSwitch) const REQUIRES(mLock);
- // The list of refresh rates, indexed by display config ID. This must not change after this
+ // The list of refresh rates, indexed by display config ID. This may change after this
// object is initialized.
- AllRefreshRatesMapType mRefreshRates;
+ AllRefreshRatesMapType mRefreshRates GUARDED_BY(mLock);
// The list of refresh rates in the primary range of the current policy, ordered by vsyncPeriod
// (the first element is the lowest refresh rate).
@@ -398,9 +400,9 @@
std::optional<Policy> mOverridePolicy GUARDED_BY(mLock);
// The min and max refresh rates supported by the device.
- // This will not change at runtime.
- const RefreshRate* mMinSupportedRefreshRate;
- const RefreshRate* mMaxSupportedRefreshRate;
+ // This may change at runtime.
+ const RefreshRate* mMinSupportedRefreshRate GUARDED_BY(mLock);
+ const RefreshRate* mMaxSupportedRefreshRate GUARDED_BY(mLock);
mutable std::mutex mLock;
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 18c899b..49e3903 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -612,7 +612,7 @@
mFeatures.contentRequirements = summary;
newConfigId = calculateRefreshRateConfigIndexType(&consideredSignals);
- auto& newRefreshRate = mRefreshRateConfigs.getRefreshRateFromConfigId(newConfigId);
+ auto newRefreshRate = mRefreshRateConfigs.getRefreshRateFromConfigId(newConfigId);
frameRateOverridesChanged =
updateFrameRateOverrides(consideredSignals, newRefreshRate.getFps());
@@ -629,7 +629,7 @@
}
}
if (frameRateChanged) {
- auto& newRefreshRate = mRefreshRateConfigs.getRefreshRateFromConfigId(newConfigId);
+ auto newRefreshRate = mRefreshRateConfigs.getRefreshRateFromConfigId(newConfigId);
mSchedulerCallback.changeRefreshRate(newRefreshRate,
consideredSignals.idle ? ConfigEvent::None
: ConfigEvent::Changed);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 59b3824..2e00ca8 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -995,7 +995,7 @@
void SurfaceFlinger::setDesiredActiveConfig(const ActiveConfigInfo& info) {
ATRACE_CALL();
- auto& refreshRate = mRefreshRateConfigs->getRefreshRateFromConfigId(info.configId);
+ auto refreshRate = mRefreshRateConfigs->getRefreshRateFromConfigId(info.configId);
ALOGV("setDesiredActiveConfig(%s)", refreshRate.getName().c_str());
std::lock_guard<std::mutex> lock(mActiveConfigLock);
@@ -1030,7 +1030,7 @@
}
if (mRefreshRateOverlay) {
- mRefreshRateOverlay->changeRefreshRate(refreshRate);
+ mRefreshRateOverlay->changeRefreshRate(refreshRate.getFps());
}
}
@@ -1076,14 +1076,14 @@
return;
}
- auto& oldRefreshRate =
+ auto oldRefreshRate =
mRefreshRateConfigs->getRefreshRateFromConfigId(display->getActiveConfig());
std::lock_guard<std::mutex> lock(mActiveConfigLock);
mRefreshRateConfigs->setCurrentConfigId(mUpcomingActiveConfig.configId);
display->setActiveConfig(mUpcomingActiveConfig.configId);
- auto& refreshRate =
+ auto refreshRate =
mRefreshRateConfigs->getRefreshRateFromConfigId(mUpcomingActiveConfig.configId);
mRefreshRateStats->setRefreshRate(refreshRate.getFps());
@@ -1126,7 +1126,7 @@
return;
}
- auto& refreshRate =
+ auto refreshRate =
mRefreshRateConfigs->getRefreshRateFromConfigId(desiredActiveConfig->configId);
ALOGV("performSetActiveConfig changing active config to %d(%s)",
refreshRate.getConfigId().value(), refreshRate.getName().c_str());
@@ -2620,6 +2620,9 @@
if (currentState.physical->hwcDisplayId == getHwComposer().getInternalHwcDisplayId()) {
const auto displayId = currentState.physical->id;
const auto configs = getHwComposer().getConfigs(displayId);
+ const auto currentConfig =
+ HwcConfigIndexType(getHwComposer().getActiveConfigIndex(displayId));
+ mRefreshRateConfigs->updateDisplayConfigs(configs, currentConfig);
mVsyncConfiguration->reset();
updatePhaseConfiguration(mRefreshRateConfigs->getCurrentRefreshRate());
if (mRefreshRateOverlay) {
@@ -5411,16 +5414,16 @@
// mRefreshRateConfigs->getCurrentRefreshRate()
static_cast<void>(schedule([=] {
const auto desiredActiveConfig = getDesiredActiveConfig();
- const auto& current = desiredActiveConfig
- ? mRefreshRateConfigs->getRefreshRateFromConfigId(desiredActiveConfig->configId)
- : mRefreshRateConfigs->getCurrentRefreshRate();
- const auto& min = mRefreshRateConfigs->getMinRefreshRate();
+ const std::optional<HwcConfigIndexType> desiredConfigId = desiredActiveConfig
+ ? std::make_optional(desiredActiveConfig->configId)
+ : std::nullopt;
- if (current != min) {
- const bool timerExpired = mKernelIdleTimerEnabled && expired;
-
+ const bool timerExpired = mKernelIdleTimerEnabled && expired;
+ const auto newRefreshRate =
+ mRefreshRateConfigs->onKernelTimerChanged(desiredConfigId, timerExpired);
+ if (newRefreshRate) {
if (Mutex::Autolock lock(mStateLock); mRefreshRateOverlay) {
- mRefreshRateOverlay->changeRefreshRate(timerExpired ? min : current);
+ mRefreshRateOverlay->changeRefreshRate(*newRefreshRate);
}
mEventQueue->invalidate();
}
@@ -6070,7 +6073,7 @@
toggleKernelIdleTimer();
auto configId = mScheduler->getPreferredConfigId();
- auto& preferredRefreshRate = configId
+ auto preferredRefreshRate = configId
? mRefreshRateConfigs->getRefreshRateFromConfigId(*configId)
// NOTE: Choose the default config ID, if Scheduler doesn't have one in mind.
: mRefreshRateConfigs->getRefreshRateFromConfigId(currentPolicy.defaultConfig);
@@ -6376,7 +6379,8 @@
mRefreshRateOverlay->setViewport(display->getSize());
}
- mRefreshRateOverlay->changeRefreshRate(mRefreshRateConfigs->getCurrentRefreshRate());
+ mRefreshRateOverlay->changeRefreshRate(
+ mRefreshRateConfigs->getCurrentRefreshRate().getFps());
}
}));
}
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index 45f0ee6..0813968 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -56,6 +56,21 @@
return refreshRateConfigs.mKnownFrameRates;
}
+ RefreshRate getMinRefreshRateByPolicy(const RefreshRateConfigs& refreshRateConfigs) {
+ std::lock_guard lock(refreshRateConfigs.mLock);
+ return refreshRateConfigs.getMinRefreshRateByPolicyLocked();
+ }
+
+ RefreshRate getMinSupportedRefreshRate(const RefreshRateConfigs& refreshRateConfigs) {
+ std::lock_guard lock(refreshRateConfigs.mLock);
+ return *refreshRateConfigs.mMinSupportedRefreshRate;
+ }
+
+ RefreshRate getMaxSupportedRefreshRate(const RefreshRateConfigs& refreshRateConfigs) {
+ std::lock_guard lock(refreshRateConfigs.mLock);
+ return *refreshRateConfigs.mMaxSupportedRefreshRate;
+ }
+
// Test config IDs
static inline const HwcConfigIndexType HWC_CONFIG_ID_60 = HwcConfigIndexType(0);
static inline const HwcConfigIndexType HWC_CONFIG_ID_90 = HwcConfigIndexType(1);
@@ -209,13 +224,13 @@
std::make_unique<RefreshRateConfigs>(m60_90Device,
/*currentConfigId=*/HWC_CONFIG_ID_60);
- const auto& minRate = refreshRateConfigs->getMinRefreshRate();
- const auto& performanceRate = refreshRateConfigs->getMaxRefreshRate();
+ const auto& minRate = getMinSupportedRefreshRate(*refreshRateConfigs);
+ const auto& performanceRate = getMaxSupportedRefreshRate(*refreshRateConfigs);
ASSERT_EQ(mExpected60Config, minRate);
ASSERT_EQ(mExpected90Config, performanceRate);
- const auto& minRateByPolicy = refreshRateConfigs->getMinRefreshRateByPolicy();
+ const auto& minRateByPolicy = getMinRefreshRateByPolicy(*refreshRateConfigs);
const auto& performanceRateByPolicy = refreshRateConfigs->getMaxRefreshRateByPolicy();
ASSERT_EQ(minRateByPolicy, minRate);
ASSERT_EQ(performanceRateByPolicy, performanceRate);
@@ -226,9 +241,9 @@
std::make_unique<RefreshRateConfigs>(m60_90DeviceWithDifferentGroups,
/*currentConfigId=*/HWC_CONFIG_ID_60);
- const auto& minRate = refreshRateConfigs->getMinRefreshRateByPolicy();
- const auto& performanceRate = refreshRateConfigs->getMaxRefreshRate();
- const auto& minRate60 = refreshRateConfigs->getMinRefreshRateByPolicy();
+ const auto& minRate = getMinRefreshRateByPolicy(*refreshRateConfigs);
+ const auto& performanceRate = getMaxSupportedRefreshRate(*refreshRateConfigs);
+ const auto& minRate60 = getMinRefreshRateByPolicy(*refreshRateConfigs);
const auto& performanceRate60 = refreshRateConfigs->getMaxRefreshRateByPolicy();
ASSERT_EQ(mExpected60Config, minRate);
@@ -239,7 +254,7 @@
0);
refreshRateConfigs->setCurrentConfigId(HWC_CONFIG_ID_90);
- const auto& minRate90 = refreshRateConfigs->getMinRefreshRateByPolicy();
+ const auto& minRate90 = getMinRefreshRateByPolicy(*refreshRateConfigs);
const auto& performanceRate90 = refreshRateConfigs->getMaxRefreshRateByPolicy();
ASSERT_EQ(mExpected90DifferentGroupConfig, performanceRate);
@@ -252,9 +267,9 @@
std::make_unique<RefreshRateConfigs>(m60_90DeviceWithDifferentResolutions,
/*currentConfigId=*/HWC_CONFIG_ID_60);
- const auto& minRate = refreshRateConfigs->getMinRefreshRateByPolicy();
- const auto& performanceRate = refreshRateConfigs->getMaxRefreshRate();
- const auto& minRate60 = refreshRateConfigs->getMinRefreshRateByPolicy();
+ const auto& minRate = getMinRefreshRateByPolicy(*refreshRateConfigs);
+ const auto& performanceRate = getMaxSupportedRefreshRate(*refreshRateConfigs);
+ const auto& minRate60 = getMinRefreshRateByPolicy(*refreshRateConfigs);
const auto& performanceRate60 = refreshRateConfigs->getMaxRefreshRateByPolicy();
ASSERT_EQ(mExpected60Config, minRate);
@@ -265,7 +280,7 @@
0);
refreshRateConfigs->setCurrentConfigId(HWC_CONFIG_ID_90);
- const auto& minRate90 = refreshRateConfigs->getMinRefreshRateByPolicy();
+ const auto& minRate90 = getMinRefreshRateByPolicy(*refreshRateConfigs);
const auto& performanceRate90 = refreshRateConfigs->getMaxRefreshRateByPolicy();
ASSERT_EQ(mExpected90DifferentResolutionConfig, performanceRate);
@@ -278,8 +293,8 @@
std::make_unique<RefreshRateConfigs>(m60_90Device,
/*currentConfigId=*/HWC_CONFIG_ID_60);
- auto& minRate = refreshRateConfigs->getMinRefreshRateByPolicy();
- auto& performanceRate = refreshRateConfigs->getMaxRefreshRateByPolicy();
+ auto minRate = getMinRefreshRateByPolicy(*refreshRateConfigs);
+ auto performanceRate = refreshRateConfigs->getMaxRefreshRateByPolicy();
ASSERT_EQ(mExpected60Config, minRate);
ASSERT_EQ(mExpected90Config, performanceRate);
@@ -287,8 +302,8 @@
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {Fps(60), Fps(60)}}),
0);
- auto& minRate60 = refreshRateConfigs->getMinRefreshRateByPolicy();
- auto& performanceRate60 = refreshRateConfigs->getMaxRefreshRateByPolicy();
+ auto minRate60 = getMinRefreshRateByPolicy(*refreshRateConfigs);
+ auto performanceRate60 = refreshRateConfigs->getMaxRefreshRateByPolicy();
ASSERT_EQ(mExpected60Config, minRate60);
ASSERT_EQ(mExpected60Config, performanceRate60);
}
@@ -298,20 +313,20 @@
std::make_unique<RefreshRateConfigs>(m60_90Device,
/*currentConfigId=*/HWC_CONFIG_ID_60);
{
- auto& current = refreshRateConfigs->getCurrentRefreshRate();
+ auto current = refreshRateConfigs->getCurrentRefreshRate();
EXPECT_EQ(current.getConfigId(), HWC_CONFIG_ID_60);
}
refreshRateConfigs->setCurrentConfigId(HWC_CONFIG_ID_90);
{
- auto& current = refreshRateConfigs->getCurrentRefreshRate();
+ auto current = refreshRateConfigs->getCurrentRefreshRate();
EXPECT_EQ(current.getConfigId(), HWC_CONFIG_ID_90);
}
ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_90, {Fps(90), Fps(90)}}),
0);
{
- auto& current = refreshRateConfigs->getCurrentRefreshRate();
+ auto current = refreshRateConfigs->getCurrentRefreshRate();
EXPECT_EQ(current.getConfigId(), HWC_CONFIG_ID_90);
}
}