SF: move RefreshRateOverlay to DisplayDevice
Test: SF unit tests
Test: refresh rate overlay is visible on all displays
Bug: 187539899
Change-Id: I3bfa3749dcd5bbd7d6238a60332b98bba954ca53
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 5c33428..60f2408 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -40,6 +40,7 @@
#include "DisplayDevice.h"
#include "Layer.h"
+#include "RefreshRateOverlay.h"
#include "SurfaceFlinger.h"
namespace android {
@@ -159,6 +160,9 @@
if (mRefreshRateConfigs) {
mRefreshRateConfigs->setCurrentModeId(mActiveMode->getId());
}
+ if (mRefreshRateOverlay) {
+ mRefreshRateOverlay->changeRefreshRate(mActiveMode->getFps());
+ }
}
status_t DisplayDevice::initiateModeChange(DisplayModeId modeId,
@@ -222,6 +226,9 @@
void DisplayDevice::setLayerStack(ui::LayerStack stack) {
mCompositionDisplay->setLayerStackFilter(stack, isInternal());
+ if (mRefreshRateOverlay) {
+ mRefreshRateOverlay->setLayerStack(stack);
+ }
}
void DisplayDevice::setFlags(uint32_t flags) {
@@ -230,7 +237,11 @@
void DisplayDevice::setDisplaySize(int width, int height) {
LOG_FATAL_IF(!isVirtual(), "Changing the display size is supported only for virtual displays.");
- mCompositionDisplay->setDisplaySize(ui::Size(width, height));
+ const auto size = ui::Size(width, height);
+ mCompositionDisplay->setDisplaySize(size);
+ if (mRefreshRateOverlay) {
+ mRefreshRateOverlay->setViewport(size);
+ }
}
void DisplayDevice::setProjection(ui::Rotation orientation, Rect layerStackSpaceRect,
@@ -390,6 +401,40 @@
capabilities.getDesiredMinLuminance());
}
+void DisplayDevice::enableRefreshRateOverlay(bool enable, bool showSpinnner) {
+ if (!enable) {
+ mRefreshRateOverlay.reset();
+ return;
+ }
+
+ const auto [lowFps, highFps] = mRefreshRateConfigs->getSupportedRefreshRateRange();
+ mRefreshRateOverlay = std::make_unique<RefreshRateOverlay>(*mFlinger, lowFps.getIntValue(),
+ highFps.getIntValue(), showSpinnner);
+ mRefreshRateOverlay->setLayerStack(getLayerStack());
+ mRefreshRateOverlay->setViewport(getSize());
+ mRefreshRateOverlay->changeRefreshRate(getActiveMode()->getFps());
+}
+
+bool DisplayDevice::onKernelTimerChanged(std::optional<DisplayModeId> desiredModeId,
+ bool timerExpired) {
+ if (mRefreshRateConfigs && mRefreshRateOverlay) {
+ const auto newRefreshRate =
+ mRefreshRateConfigs->onKernelTimerChanged(desiredModeId, timerExpired);
+ if (newRefreshRate) {
+ mRefreshRateOverlay->changeRefreshRate(*newRefreshRate);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void DisplayDevice::onInvalidate() {
+ if (mRefreshRateOverlay) {
+ mRefreshRateOverlay->onInvalidate();
+ }
+}
+
std::atomic<int32_t> DisplayDeviceState::sNextSequenceId(1);
} // namespace android
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 5a20a43..7db2def 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -52,6 +52,7 @@
class HWComposer;
class IGraphicBufferProducer;
class Layer;
+class RefreshRateOverlay;
class SurfaceFlinger;
struct CompositionInfo;
@@ -205,6 +206,12 @@
return mRefreshRateConfigs;
}
+ // Enables an overlay to be displayed with the current refresh rate
+ void enableRefreshRateOverlay(bool enable, bool showSpinner);
+ bool isRefreshRateOverlayEnabled() const { return mRefreshRateOverlay != nullptr; }
+ bool onKernelTimerChanged(std::optional<DisplayModeId>, bool timerExpired);
+ void onInvalidate();
+
void onVsync(nsecs_t timestamp);
nsecs_t getVsyncPeriodFromHWC() const;
nsecs_t getRefreshTimestamp() const;
@@ -252,6 +259,7 @@
std::vector<ui::Hdr> mOverrideHdrTypes;
std::shared_ptr<scheduler::RefreshRateConfigs> mRefreshRateConfigs;
+ std::unique_ptr<RefreshRateOverlay> mRefreshRateOverlay;
};
struct DisplayDeviceState {
diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp
index 9657a9f..b0d76e6 100644
--- a/services/surfaceflinger/RefreshRateOverlay.cpp
+++ b/services/surfaceflinger/RefreshRateOverlay.cpp
@@ -175,10 +175,14 @@
return buffers;
}
-RefreshRateOverlay::RefreshRateOverlay(SurfaceFlinger& flinger, bool showSpinner)
- : mFlinger(flinger), mClient(new Client(&mFlinger)), mShowSpinner(showSpinner) {
+RefreshRateOverlay::RefreshRateOverlay(SurfaceFlinger& flinger, uint32_t lowFps, uint32_t highFps,
+ bool showSpinner)
+ : mFlinger(flinger),
+ mClient(new Client(&mFlinger)),
+ mShowSpinner(showSpinner),
+ mLowFps(lowFps),
+ mHighFps(highFps) {
createLayer();
- reset();
}
bool RefreshRateOverlay::createLayer() {
@@ -194,7 +198,6 @@
return false;
}
- Mutex::Autolock _l(mFlinger.mStateLock);
mLayer = mClient->getLayerUser(mIBinder);
mLayer->setFrameRate(Layer::FrameRate(Fps(0.0f), Layer::FrameRateCompatibility::NoVote));
@@ -256,6 +259,11 @@
mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
}
+void RefreshRateOverlay::setLayerStack(uint32_t stack) {
+ mLayer->setLayerStack(stack);
+ mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
+}
+
void RefreshRateOverlay::changeRefreshRate(const Fps& fps) {
mCurrentFps = fps.getIntValue();
auto buffer = getOrCreateBuffers(*mCurrentFps)[mFrame];
@@ -281,22 +289,6 @@
mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
}
-void RefreshRateOverlay::reset() {
- mBufferCache.clear();
- // TODO: this is a temp hack that would be removed in the next CL
- const auto range = [&]() NO_THREAD_SAFETY_ANALYSIS {
- constexpr auto defaultFps = Fps(60);
- const auto display = mFlinger.getDefaultDisplayDeviceLocked();
- if (display) {
- return display->refreshRateConfigs().getSupportedRefreshRateRange();
- }
- ALOGW("%s: default display is null", __func__);
- return scheduler::RefreshRateConfigs::FpsRange{defaultFps, defaultFps};
- }();
- mLowFps = range.min.getIntValue();
- mHighFps = range.max.getIntValue();
-}
-
} // namespace android
// TODO(b/129481165): remove the #pragma below and fix conversion issues
diff --git a/services/surfaceflinger/RefreshRateOverlay.h b/services/surfaceflinger/RefreshRateOverlay.h
index aa8329c..f9baa89 100644
--- a/services/surfaceflinger/RefreshRateOverlay.h
+++ b/services/surfaceflinger/RefreshRateOverlay.h
@@ -37,12 +37,12 @@
class RefreshRateOverlay {
public:
- RefreshRateOverlay(SurfaceFlinger&, bool showSpinner);
+ RefreshRateOverlay(SurfaceFlinger&, uint32_t lowFps, uint32_t highFps, bool showSpinner);
+ void setLayerStack(uint32_t stack);
void setViewport(ui::Size);
void changeRefreshRate(const Fps&);
void onInvalidate();
- void reset();
private:
class SevenSegmentDrawer {
@@ -91,8 +91,8 @@
const bool mShowSpinner;
// Interpolate the colors between these values.
- uint32_t mLowFps;
- uint32_t mHighFps;
+ const uint32_t mLowFps;
+ const uint32_t mHighFps;
};
} // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 40e0ed6..8dd1e14 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -726,7 +726,7 @@
mBootStage = BootStage::FINISHED;
if (property_get_bool("sf.debug.show_refresh_rate_overlay", false)) {
- enableRefreshRateOverlay(true);
+ ON_MAIN_THREAD(enableRefreshRateOverlay(true));
}
}));
}
@@ -1192,10 +1192,6 @@
updatePhaseConfiguration(refreshRate);
ATRACE_INT("ActiveConfigFPS", refreshRate.getValue());
- if (mRefreshRateOverlay) {
- mRefreshRateOverlay->changeRefreshRate(upcomingMode->getFps());
- }
-
if (mUpcomingActiveMode.event != Scheduler::ModeEvent::None) {
const nsecs_t vsyncPeriod = refreshRate.getPeriodNsecs();
const auto physicalId = display->getPhysicalId();
@@ -1969,8 +1965,13 @@
}
if (mRefreshRateOverlaySpinner) {
- if (Mutex::Autolock lock(mStateLock); mRefreshRateOverlay) {
- mRefreshRateOverlay->onInvalidate();
+ if (Mutex::Autolock lock(mStateLock);
+ const auto display = getDefaultDisplayDeviceLocked()) {
+ if (display) {
+ display->onInvalidate();
+ } else {
+ ALOGW("%s: default display is null", __func__);
+ }
}
}
@@ -2890,10 +2891,6 @@
if (isDisplayActiveLocked(display)) {
onActiveDisplaySizeChanged(display);
}
-
- if (mRefreshRateOverlay) {
- mRefreshRateOverlay->setViewport(display->getSize());
- }
}
}
}
@@ -2902,9 +2899,6 @@
const Fps refreshRate = activeDisplay->refreshRateConfigs().getCurrentRefreshRate().getFps();
updatePhaseConfiguration(refreshRate);
mRefreshRateStats->setRefreshRate(refreshRate);
- if (mRefreshRateOverlay) {
- mRefreshRateOverlay->reset();
- }
}
void SurfaceFlinger::processDisplayChangesLocked() {
@@ -5659,16 +5653,17 @@
return NO_ERROR;
}
case 1034: {
- switch (n = data.readInt32()) {
- case 0:
- case 1:
- enableRefreshRateOverlay(static_cast<bool>(n));
- break;
- default: {
- Mutex::Autolock lock(mStateLock);
- reply->writeBool(mRefreshRateOverlay != nullptr);
+ schedule([&] {
+ switch (n = data.readInt32()) {
+ case 0:
+ case 1:
+ ON_MAIN_THREAD(enableRefreshRateOverlay(static_cast<bool>(n)));
+ break;
+ default: {
+ reply->writeBool(ON_MAIN_THREAD(isRefreshRateOverlayEnabled()));
+ }
}
- }
+ }).get();
return NO_ERROR;
}
case 1035: {
@@ -5814,7 +5809,7 @@
static bool updateOverlay =
property_get_bool("debug.sf.kernel_idle_timer_update_overlay", true);
if (!updateOverlay) return;
- if (Mutex::Autolock lock(mStateLock); !mRefreshRateOverlay) return;
+ if (Mutex::Autolock lock(mStateLock); !isRefreshRateOverlayEnabled()) return;
// Update the overlay on the main thread to avoid race conditions with
// mRefreshRateConfigs->getCurrentRefreshRate()
@@ -5829,12 +5824,7 @@
ALOGW("%s: default display is null", __func__);
return;
}
- const auto newRefreshRate =
- display->refreshRateConfigs().onKernelTimerChanged(desiredModeId, timerExpired);
- if (newRefreshRate) {
- if (Mutex::Autolock lock(mStateLock); mRefreshRateOverlay) {
- mRefreshRateOverlay->changeRefreshRate(*newRefreshRate);
- }
+ if (display->onKernelTimerChanged(desiredModeId, timerExpired)) {
mEventQueue->invalidate();
}
}));
@@ -6816,25 +6806,11 @@
}
void SurfaceFlinger::enableRefreshRateOverlay(bool enable) {
- static_cast<void>(schedule([=] {
- std::unique_ptr<RefreshRateOverlay> overlay;
- if (enable) {
- overlay = std::make_unique<RefreshRateOverlay>(*this, mRefreshRateOverlaySpinner);
+ for (const auto& [ignored, display] : mDisplays) {
+ if (display->isInternal()) {
+ display->enableRefreshRateOverlay(enable, mRefreshRateOverlaySpinner);
}
-
- {
- Mutex::Autolock lock(mStateLock);
-
- // Destroy the layer of the current overlay, if any, outside the lock.
- mRefreshRateOverlay.swap(overlay);
- if (!mRefreshRateOverlay) return;
-
- if (const auto display = getDefaultDisplayDeviceLocked()) {
- mRefreshRateOverlay->setViewport(display->getSize());
- mRefreshRateOverlay->changeRefreshRate(display->getActiveMode()->getFps());
- }
- }
- }));
+ }
}
status_t SurfaceFlinger::addTransactionTraceListener(
@@ -7018,10 +6994,6 @@
updateInternalDisplayVsyncLocked(activeDisplay);
mScheduler->setRefreshRateConfigs(activeDisplay->holdRefreshRateConfigs());
onActiveDisplaySizeChanged(activeDisplay);
- if (mRefreshRateOverlay) {
- mRefreshRateOverlay->setViewport(activeDisplay->getSize());
- mRefreshRateOverlay->changeRefreshRate(activeDisplay->getActiveMode()->getFps());
- }
}
} // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 1271596..4c554bc 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -1449,8 +1449,7 @@
// This should only be accessed on the main thread.
nsecs_t mFrameStartTime = 0;
- void enableRefreshRateOverlay(bool enable);
- std::unique_ptr<RefreshRateOverlay> mRefreshRateOverlay GUARDED_BY(mStateLock);
+ void enableRefreshRateOverlay(bool enable) REQUIRES(mStateLock);
// Flag used to set override desired display mode from backdoor
bool mDebugDisplayModeSetByBackdoor = false;
@@ -1502,6 +1501,13 @@
void scheduleRegionSamplingThread();
void notifyRegionSamplingThread();
+ bool isRefreshRateOverlayEnabled() const REQUIRES(mStateLock) {
+ return std::any_of(mDisplays.begin(), mDisplays.end(),
+ [](std::pair<wp<IBinder>, sp<DisplayDevice>> display) {
+ return display.second->isRefreshRateOverlayEnabled();
+ });
+ }
+
wp<IBinder> mActiveDisplayToken GUARDED_BY(mStateLock);
};