summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Solomon <solomondaniel@google.com>2019-08-19 19:31:09 -0700
committerandroid-build-team Robot <android-build-team-robot@google.com>2019-09-20 02:58:06 +0000
commitd1490b2aa2f44b2832e8a16ec6f84c62291dd098 (patch)
tree6003dddab62e66df29afb767bdc088d10f6d09b1
parentea4916be070a48e6f28e14c71d41fa0658fde2ce (diff)
downloadnative-d1490b2aa2f44b2832e8a16ec6f84c62291dd098.tar.gz
SurfaceFlinger: Query Scheduler when updating allowed display configs
Currently two entities in SurfaceFlinger can set a new display refresh rate: (1) SurfaceFlinger core, and (2) Scheduler. It's possible for these two entities to get out of sync in the following way: 1) Scheduler updates the refresh rate to some rate 2) Upper layers call into SurfaceFlinger to update allowed display configs 3) SurfaceFlinger always sets display rate to max If the refresh rate from #1 and #3 don't match, it can leave the system in an inconsistent state, potentially causing visual and power issues. This change fixes this problem by changing step #3: Instead of always choosing the max refresh rate, SurfaceFlinger queries the optimal refresh rate from Scheduler. If that rate isn't available, only then does SurfaceFlinger default to the maximum rate. Bug: 139557239 Test: atest libsurfaceflinger_unittest Test: Manual: 1) Start with SurfaceFlinger idling (Scheduler selected RefreshRateType::DEFAULT) 2) Trigger a change in allowed display configs from DisplayModeDirector 3) Make sure the RefreshRateType SurfaceFlinger sets is DEFAULT instead of PERFORMANCE Change-Id: Ia85a60fde55afaed5106462942e0bb77652ec737 Merged-In: Ia85a60fde55afaed5106462942e0bb77652ec737 (cherry picked from commit d916d941d89ec8fdcbc2bbe0bfdf0b0db1ad08b5)
-rw-r--r--services/surfaceflinger/Scheduler/Scheduler.cpp6
-rw-r--r--services/surfaceflinger/Scheduler/Scheduler.h3
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp30
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h3
4 files changed, 32 insertions, 10 deletions
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index a194106112..edb58f7a75 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -567,6 +567,7 @@ Scheduler::RefreshRateType Scheduler::calculateRefreshRateType() {
}
// Content detection is on, find the appropriate refresh rate with minimal error
+ // TODO(b/139751853): Scan allowed refresh rates only (SurfaceFlinger::mAllowedDisplayConfigs)
auto iter = min_element(mRefreshRateConfigs.getRefreshRates().cbegin(),
mRefreshRateConfigs.getRefreshRates().cend(),
[rate = mContentRefreshRate](const auto& l, const auto& r) -> bool {
@@ -596,6 +597,11 @@ Scheduler::RefreshRateType Scheduler::calculateRefreshRateType() {
return currRefreshRateType;
}
+Scheduler::RefreshRateType Scheduler::getPreferredRefreshRateType() {
+ std::lock_guard<std::mutex> lock(mFeatureStateLock);
+ return mRefreshRateType;
+}
+
void Scheduler::changeRefreshRate(RefreshRateType refreshRateType, ConfigEvent configEvent) {
std::lock_guard<std::mutex> lock(mCallbackLock);
if (mChangeRefreshRateCallback) {
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 5d8bb4cd2f..38184570c1 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -189,6 +189,9 @@ public:
// calls DispSync::dump() on primary disp sync
void dumpPrimaryDispSync(std::string& result) const;
+ // Get the appropriate refresh type for current conditions.
+ RefreshRateType getPreferredRefreshRateType();
+
protected:
virtual std::unique_ptr<EventThread> makeEventThread(
const char* connectionName, DispSync* dispSync, nsecs_t phaseOffsetNs,
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index ab22cd9016..ffb7012bb3 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -6169,6 +6169,25 @@ void SurfaceFlinger::traverseLayersInDisplay(const sp<const DisplayDevice>& disp
}
}
+void SurfaceFlinger::setPreferredDisplayConfig() {
+ const auto& type = mScheduler->getPreferredRefreshRateType();
+ const auto& config = mRefreshRateConfigs.getRefreshRate(type);
+ if (config && isDisplayConfigAllowed(config->configId)) {
+ ALOGV("switching to Scheduler preferred config %d", config->configId);
+ setDesiredActiveConfig({type, config->configId, Scheduler::ConfigEvent::Changed});
+ } else {
+ // Set the highest allowed config by iterating backwards on available refresh rates
+ const auto& refreshRates = mRefreshRateConfigs.getRefreshRates();
+ for (auto iter = refreshRates.crbegin(); iter != refreshRates.crend(); ++iter) {
+ if (iter->second && isDisplayConfigAllowed(iter->second->configId)) {
+ ALOGV("switching to allowed config %d", iter->second->configId);
+ setDesiredActiveConfig({iter->first, iter->second->configId,
+ Scheduler::ConfigEvent::Changed});
+ }
+ }
+ }
+}
+
void SurfaceFlinger::setAllowedDisplayConfigsInternal(const sp<DisplayDevice>& display,
const std::vector<int32_t>& allowedConfigs) {
if (!display->isPrimary()) {
@@ -6190,16 +6209,7 @@ void SurfaceFlinger::setAllowedDisplayConfigsInternal(const sp<DisplayDevice>& d
mScheduler->onConfigChanged(mAppConnectionHandle, display->getId()->value,
display->getActiveConfig());
- // Set the highest allowed config by iterating backwards on available refresh rates
- const auto& refreshRates = mRefreshRateConfigs.getRefreshRates();
- for (auto iter = refreshRates.crbegin(); iter != refreshRates.crend(); ++iter) {
- if (iter->second && isDisplayConfigAllowed(iter->second->configId)) {
- ALOGV("switching to config %d", iter->second->configId);
- setDesiredActiveConfig(
- {iter->first, iter->second->configId, Scheduler::ConfigEvent::Changed});
- break;
- }
- }
+ setPreferredDisplayConfig();
}
status_t SurfaceFlinger::setAllowedDisplayConfigs(const sp<IBinder>& displayToken,
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 0c6da0077f..a59a1e0086 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -534,6 +534,9 @@ private:
// called on the main thread in response to setPowerMode()
void setPowerModeInternal(const sp<DisplayDevice>& display, int mode) REQUIRES(mStateLock);
+ // Query the Scheduler or allowed display configs list for a matching config, and set it
+ void setPreferredDisplayConfig() REQUIRES(mStateLock);
+
// called on the main thread in response to setAllowedDisplayConfigs()
void setAllowedDisplayConfigsInternal(const sp<DisplayDevice>& display,
const std::vector<int32_t>& allowedConfigs)