Merge "SurfaceFlinger: tune number of buffers for low activity layers" into qt-qpr1-dev
diff --git a/libs/dumputils/dump_utils.cpp b/libs/dumputils/dump_utils.cpp
index 8e762f1..250f902 100644
--- a/libs/dumputils/dump_utils.cpp
+++ b/libs/dumputils/dump_utils.cpp
@@ -46,6 +46,7 @@
static const char* hal_interfaces_to_dump[] {
"android.hardware.audio@2.0::IDevicesFactory",
"android.hardware.audio@4.0::IDevicesFactory",
+ "android.hardware.audio@5.0::IDevicesFactory",
"android.hardware.biometrics.face@1.0::IBiometricsFace",
"android.hardware.bluetooth@1.0::IBluetoothHci",
"android.hardware.camera.provider@2.4::ICameraProvider",
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index d6e86eb..fdf9da3 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -2048,7 +2048,7 @@
InputWindowInfo info = mDrawingState.inputInfo;
if (info.displayId == ADISPLAY_ID_NONE) {
- info.displayId = mDrawingState.layerStack;
+ info.displayId = getLayerStack();
}
ui::Transform t = getTransform();
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index a194106..f8bd958 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -274,7 +274,7 @@
}
void Scheduler::VsyncState::resync(const GetVsyncPeriod& getVsyncPeriod) {
- static constexpr nsecs_t kIgnoreDelay = ms2ns(500);
+ static constexpr nsecs_t kIgnoreDelay = ms2ns(750);
const nsecs_t now = systemTime();
const nsecs_t last = lastResyncTime.exchange(now);
@@ -567,8 +567,13 @@
}
// Content detection is on, find the appropriate refresh rate with minimal error
- auto iter = min_element(mRefreshRateConfigs.getRefreshRates().cbegin(),
- mRefreshRateConfigs.getRefreshRates().cend(),
+ auto begin = mRefreshRateConfigs.getRefreshRates().cbegin();
+
+ // Skip POWER_SAVING config as it is not a real config
+ if (begin->first == RefreshRateType::POWER_SAVING) {
+ ++begin;
+ }
+ auto iter = min_element(begin, mRefreshRateConfigs.getRefreshRates().cend(),
[rate = mContentRefreshRate](const auto& l, const auto& r) -> bool {
return std::abs(l.second->fps - static_cast<float>(rate)) <
std::abs(r.second->fps - static_cast<float>(rate));
@@ -596,6 +601,11 @@
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 5d8bb4c..3818457 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -189,6 +189,9 @@
// 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 ab22cd9..23b399f 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1681,7 +1681,8 @@
setTransactionFlags(eDisplayTransactionNeeded);
}
-bool SurfaceFlinger::previousFrameMissed() NO_THREAD_SAFETY_ANALYSIS {
+bool SurfaceFlinger::previousFrameMissed(int graceTimeMs) NO_THREAD_SAFETY_ANALYSIS {
+ ATRACE_CALL();
// We are storing the last 2 present fences. If sf's phase offset is to be
// woken up before the actual vsync but targeting the next vsync, we need to check
// fence N-2
@@ -1690,7 +1691,15 @@
? mPreviousPresentFences[0]
: mPreviousPresentFences[1];
- return fence != Fence::NO_FENCE && (fence->getStatus() == Fence::Status::Unsignaled);
+ if (fence == Fence::NO_FENCE) {
+ return false;
+ }
+
+ if (graceTimeMs > 0 && fence->getStatus() == Fence::Status::Unsignaled) {
+ fence->wait(graceTimeMs);
+ }
+
+ return (fence->getStatus() == Fence::Status::Unsignaled);
}
void SurfaceFlinger::populateExpectedPresentTime() NO_THREAD_SAFETY_ANALYSIS {
@@ -1713,7 +1722,15 @@
// seeing this same value.
populateExpectedPresentTime();
- bool frameMissed = previousFrameMissed();
+ // When Backpressure propagation is enabled we want to give a small grace period
+ // for the present fence to fire instead of just giving up on this frame to handle cases
+ // where present fence is just about to get signaled.
+ const int graceTimeForPresentFenceMs =
+ (mPropagateBackpressure &&
+ (mPropagateBackpressureClientComposition || !mHadClientComposition))
+ ? 1
+ : 0;
+ bool frameMissed = previousFrameMissed(graceTimeForPresentFenceMs);
bool hwcFrameMissed = mHadDeviceComposition && frameMissed;
bool gpuFrameMissed = mHadClientComposition && frameMissed;
ATRACE_INT("FrameMissed", static_cast<int>(frameMissed));
@@ -6169,6 +6186,25 @@
}
}
+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 +6226,7 @@
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 0c6da00..2718e0e 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -534,6 +534,9 @@
// 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)
@@ -848,7 +851,7 @@
return hwcDisplayId ? getHwComposer().toPhysicalDisplayId(*hwcDisplayId) : std::nullopt;
}
- bool previousFrameMissed();
+ bool previousFrameMissed(int graceTimeMs = 0);
void setVsyncEnabledInHWC(DisplayId displayId, HWC2::Vsync enabled);
/*