diff options
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 18 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 2 |
2 files changed, 11 insertions, 9 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 6f30eb2cd2..d00e762606 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -4259,11 +4259,6 @@ void SurfaceFlinger::requestHardwareVsync(PhysicalDisplayId displayId, bool enab getHwComposer().setVsyncEnabled(displayId, enable ? hal::Vsync::ENABLE : hal::Vsync::DISABLE); } -// This callback originates from Scheduler::applyPolicy, whose thread context may be the main thread -// (via Scheduler::chooseRefreshRateForContent) or a OneShotTimer thread. The latter case imposes a -// deadlock prevention rule: If the main thread is processing hotplug, then mStateLock is locked as -// the main thread stops the OneShotTimer and joins with its thread. Hence, the OneShotTimer thread -// must not lock mStateLock in this callback, which would deadlock with the join. void SurfaceFlinger::requestDisplayModes(std::vector<display::DisplayModeRequest> modeRequests) { if (mBootStage != BootStage::FINISHED) { ALOGV("Currently in the boot stage, skipping display mode changes"); @@ -4272,14 +4267,21 @@ void SurfaceFlinger::requestDisplayModes(std::vector<display::DisplayModeRequest SFTRACE_CALL(); + // If this is called from the main thread mStateLock must be locked before + // Currently the only way to call this function from the main thread is from + // Scheduler::chooseRefreshRateForContent + + ConditionalLock lock(mStateLock, std::this_thread::get_id() != mMainThreadId); + for (auto& request : modeRequests) { const auto& modePtr = request.mode.modePtr; + const auto displayId = modePtr->getPhysicalDisplayId(); + const auto display = getDisplayDeviceLocked(displayId); - const auto selectorPtr = mDisplayModeController.selectorPtrFor(displayId); - if (!selectorPtr) continue; + if (!display) continue; - if (selectorPtr->isModeAllowed(request.mode)) { + if (display->refreshRateSelector().isModeAllowed(request.mode)) { setDesiredMode(std::move(request)); } else { ALOGV("%s: Mode %d is disallowed for display %s", __func__, diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 65bfce2c55..8242844b03 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -733,7 +733,7 @@ private: // Show hdr sdr ratio overlay bool mHdrSdrRatioOverlay = false; - void setDesiredMode(display::DisplayModeRequest&&); + void setDesiredMode(display::DisplayModeRequest&&) REQUIRES(mStateLock); status_t setActiveModeFromBackdoor(const sp<display::DisplayToken>&, DisplayModeId, Fps minFps, Fps maxFps); |