SF: Enforce thread safety of active mode access
Provide two RefreshRateConfigs APIs for retrieving the active mode:
getActiveMode for access from the main thread (which does not need
to lock nor copy), and getActiveModePtr for other threads.
Bug: 241285191
Test: Build (-Wthread-safety)
Change-Id: If156d85861ec2d82a394ba181314a6ba3048974f
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index ca578e1..78eaa14 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1157,9 +1157,7 @@
return;
}
- const auto upcomingModeInfo =
- FTL_FAKE_GUARD(kMainThreadContext, display->getUpcomingActiveMode());
-
+ const auto upcomingModeInfo = display->getUpcomingActiveMode();
if (!upcomingModeInfo.mode) {
// There is no pending mode change. This can happen if the active
// display changed and the mode change happened on a different display.
@@ -1273,9 +1271,8 @@
constraints.seamlessRequired = false;
hal::VsyncPeriodChangeTimeline outTimeline;
- const auto status = FTL_FAKE_GUARD(kMainThreadContext,
- display->initiateModeChange(*desiredActiveMode,
- constraints, &outTimeline));
+ const auto status =
+ display->initiateModeChange(*desiredActiveMode, constraints, &outTimeline);
if (status != NO_ERROR) {
// initiateModeChange may fail if a hotplug event is just about
@@ -2161,7 +2158,7 @@
// Hold mStateLock as chooseRefreshRateForContent promotes wp<Layer> to sp<Layer>
// and may eventually call to ~Layer() if it holds the last reference
{
- Mutex::Autolock _l(mStateLock);
+ Mutex::Autolock lock(mStateLock);
mScheduler->chooseRefreshRateForContent();
setActiveModeInHwcIfNeeded();
}
@@ -3060,9 +3057,10 @@
}
}
}
+
void SurfaceFlinger::updateInternalDisplayVsyncLocked(const sp<DisplayDevice>& activeDisplay) {
mVsyncConfiguration->reset();
- const Fps refreshRate = activeDisplay->refreshRateConfigs().getActiveMode()->getFps();
+ const Fps refreshRate = activeDisplay->refreshRateConfigs().getActiveMode().getFps();
updatePhaseConfiguration(refreshRate);
mRefreshRateStats->setRefreshRate(refreshRate);
}
@@ -4724,8 +4722,6 @@
}
}
-// ---------------------------------------------------------------------------
-
void SurfaceFlinger::onInitializeDisplays() {
const auto display = getDefaultDisplayDeviceLocked();
if (!display) return;
@@ -4763,8 +4759,9 @@
void SurfaceFlinger::initializeDisplays() {
// Async since we may be called from the main thread.
- static_cast<void>(
- mScheduler->schedule([this]() FTL_FAKE_GUARD(mStateLock) { onInitializeDisplays(); }));
+ static_cast<void>(mScheduler->schedule(
+ [this]() FTL_FAKE_GUARD(mStateLock)
+ FTL_FAKE_GUARD(kMainThreadContext) { onInitializeDisplays(); }));
}
void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal::PowerMode mode) {
@@ -4796,7 +4793,7 @@
if (mInterceptor->isEnabled()) {
mInterceptor->savePowerModeUpdate(display->getSequenceId(), static_cast<int32_t>(mode));
}
- const auto refreshRate = display->refreshRateConfigs().getActiveMode()->getFps();
+ const auto refreshRate = display->refreshRateConfigs().getActiveMode().getFps();
if (*currentMode == hal::PowerMode::OFF) {
// Turn on the display
if (isInternalDisplay && (!activeDisplay || !activeDisplay->isPoweredOn())) {
@@ -4870,7 +4867,8 @@
}
void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) {
- auto future = mScheduler->schedule([=]() FTL_FAKE_GUARD(mStateLock) {
+ auto future = mScheduler->schedule([=]() FTL_FAKE_GUARD(mStateLock) FTL_FAKE_GUARD(
+ kMainThreadContext) {
const auto display = getDisplayDeviceLocked(displayToken);
if (!display) {
ALOGE("Attempt to set power mode %d for invalid display token %p", mode,
@@ -7021,7 +7019,7 @@
refreshRate = *frameRateOverride;
} else if (!getHwComposer().isHeadless()) {
if (const auto display = FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked())) {
- refreshRate = display->refreshRateConfigs().getActiveMode()->getFps();
+ refreshRate = display->refreshRateConfigs().getActiveModePtr()->getFps();
}
}