Loading services/surfaceflinger/SurfaceFlinger.cpp +33 −31 Original line number Diff line number Diff line Loading @@ -1044,53 +1044,44 @@ void SurfaceFlinger::desiredActiveConfigChangeDone() { mVSyncModulator->setPhaseOffsets(mPhaseConfiguration->getCurrentOffsets()); } bool SurfaceFlinger::performSetActiveConfig() { void SurfaceFlinger::performSetActiveConfig() { ATRACE_CALL(); ALOGV("performSetActiveConfig"); if (mCheckPendingFence) { if (previousFramePending()) { // fence has not signaled yet. wait for the next invalidate mEventQueue->invalidate(); return true; } // We received the present fence from the HWC, so we assume it successfully updated // the config, hence we update SF. mCheckPendingFence = false; setActiveConfigInternal(); } // Store the local variable to release the lock. ActiveConfigInfo desiredActiveConfig; { const auto desiredActiveConfig = [&]() -> std::optional<ActiveConfigInfo> { std::lock_guard<std::mutex> lock(mActiveConfigLock); if (!mDesiredActiveConfigChanged) { return false; if (mDesiredActiveConfigChanged) { return mDesiredActiveConfig; } desiredActiveConfig = mDesiredActiveConfig; return std::nullopt; }(); if (!desiredActiveConfig) { // No desired active config pending to be applied return; } auto& refreshRate = mRefreshRateConfigs->getRefreshRateFromConfigId(desiredActiveConfig.configId); mRefreshRateConfigs->getRefreshRateFromConfigId(desiredActiveConfig->configId); ALOGV("performSetActiveConfig changing active config to %d(%s)", refreshRate.getConfigId().value(), refreshRate.getName().c_str()); const auto display = getDefaultDisplayDeviceLocked(); if (!display || display->getActiveConfig() == desiredActiveConfig.configId) { if (!display || display->getActiveConfig() == desiredActiveConfig->configId) { // display is not valid or we are already in the requested mode // on both cases there is nothing left to do desiredActiveConfigChangeDone(); return false; return; } // Desired active config was set, it is different than the config currently in use, however // allowed configs might have change by the time we process the refresh. // Make sure the desired config is still allowed if (!isDisplayConfigAllowed(desiredActiveConfig.configId)) { if (!isDisplayConfigAllowed(desiredActiveConfig->configId)) { desiredActiveConfigChangeDone(); return false; return; } mUpcomingActiveConfig = desiredActiveConfig; mUpcomingActiveConfig = *desiredActiveConfig; const auto displayId = display->getId(); LOG_ALWAYS_FATAL_IF(!displayId); Loading @@ -1110,13 +1101,12 @@ bool SurfaceFlinger::performSetActiveConfig() { // setActiveConfigWithConstraints may fail if a hotplug event is just about // to be sent. We just log the error in this case. ALOGW("setActiveConfigWithConstraints failed: %d", status); return false; return; } mScheduler->onNewVsyncPeriodChangeTimeline(outTimeline); // Scheduler will submit an empty frame to HWC if needed. mCheckPendingFence = true; return false; mSetActiveConfigPending = true; } status_t SurfaceFlinger::getDisplayColorModes(const sp<IBinder>& displayToken, Loading Loading @@ -1901,6 +1891,20 @@ void SurfaceFlinger::onMessageReceived(int32_t what) NO_THREAD_SAFETY_ANALYSIS { mGpuFrameMissedCount++; } // If we are in the middle of a config change and the fence hasn't // fired yet just wait for the next invalidate if (mSetActiveConfigPending) { if (framePending) { mEventQueue->invalidate(); break; } // We received the present fence from the HWC, so we assume it successfully updated // the config, hence we update SF. mSetActiveConfigPending = false; setActiveConfigInternal(); } if (framePending && mPropagateBackpressure) { if ((hwcFrameMissed && !gpuFrameMissed) || mPropagateBackpressureClientComposition) { Loading Loading @@ -1970,9 +1974,7 @@ void SurfaceFlinger::onMessageReceived(int32_t what) NO_THREAD_SAFETY_ANALYSIS { mScheduler->chooseRefreshRateForContent(); } if (performSetActiveConfig()) { break; } performSetActiveConfig(); updateCursorAsync(); updateInputFlinger(); Loading services/surfaceflinger/SurfaceFlinger.h +4 −6 Original line number Diff line number Diff line Loading @@ -565,11 +565,9 @@ private: // Once HWC has returned the present fence, this sets the active config and a new refresh // rate in SF. void setActiveConfigInternal() REQUIRES(mStateLock); // Active config is updated on INVALIDATE call in a state machine-like manner. When the // desired config was set, HWC needs to update the panel on the next refresh, and when // we receive the fence back, we know that the process was complete. It returns whether // we need to wait for the next invalidate bool performSetActiveConfig() REQUIRES(mStateLock); // Calls to setActiveConfig on the main thread if there is a pending config // that needs to be applied. void performSetActiveConfig() REQUIRES(mStateLock); // Called when active config is no longer is progress void desiredActiveConfigChangeDone() REQUIRES(mStateLock); // called on the main thread in response to setPowerMode() Loading Loading @@ -1225,7 +1223,7 @@ private: // below flags are set by main thread only TracedOrdinal<bool> mDesiredActiveConfigChanged GUARDED_BY(mActiveConfigLock) = {"DesiredActiveConfigChanged", false}; bool mCheckPendingFence = false; bool mSetActiveConfigPending = false; bool mLumaSampling = true; sp<RegionSamplingThread> mRegionSamplingThread; Loading Loading
services/surfaceflinger/SurfaceFlinger.cpp +33 −31 Original line number Diff line number Diff line Loading @@ -1044,53 +1044,44 @@ void SurfaceFlinger::desiredActiveConfigChangeDone() { mVSyncModulator->setPhaseOffsets(mPhaseConfiguration->getCurrentOffsets()); } bool SurfaceFlinger::performSetActiveConfig() { void SurfaceFlinger::performSetActiveConfig() { ATRACE_CALL(); ALOGV("performSetActiveConfig"); if (mCheckPendingFence) { if (previousFramePending()) { // fence has not signaled yet. wait for the next invalidate mEventQueue->invalidate(); return true; } // We received the present fence from the HWC, so we assume it successfully updated // the config, hence we update SF. mCheckPendingFence = false; setActiveConfigInternal(); } // Store the local variable to release the lock. ActiveConfigInfo desiredActiveConfig; { const auto desiredActiveConfig = [&]() -> std::optional<ActiveConfigInfo> { std::lock_guard<std::mutex> lock(mActiveConfigLock); if (!mDesiredActiveConfigChanged) { return false; if (mDesiredActiveConfigChanged) { return mDesiredActiveConfig; } desiredActiveConfig = mDesiredActiveConfig; return std::nullopt; }(); if (!desiredActiveConfig) { // No desired active config pending to be applied return; } auto& refreshRate = mRefreshRateConfigs->getRefreshRateFromConfigId(desiredActiveConfig.configId); mRefreshRateConfigs->getRefreshRateFromConfigId(desiredActiveConfig->configId); ALOGV("performSetActiveConfig changing active config to %d(%s)", refreshRate.getConfigId().value(), refreshRate.getName().c_str()); const auto display = getDefaultDisplayDeviceLocked(); if (!display || display->getActiveConfig() == desiredActiveConfig.configId) { if (!display || display->getActiveConfig() == desiredActiveConfig->configId) { // display is not valid or we are already in the requested mode // on both cases there is nothing left to do desiredActiveConfigChangeDone(); return false; return; } // Desired active config was set, it is different than the config currently in use, however // allowed configs might have change by the time we process the refresh. // Make sure the desired config is still allowed if (!isDisplayConfigAllowed(desiredActiveConfig.configId)) { if (!isDisplayConfigAllowed(desiredActiveConfig->configId)) { desiredActiveConfigChangeDone(); return false; return; } mUpcomingActiveConfig = desiredActiveConfig; mUpcomingActiveConfig = *desiredActiveConfig; const auto displayId = display->getId(); LOG_ALWAYS_FATAL_IF(!displayId); Loading @@ -1110,13 +1101,12 @@ bool SurfaceFlinger::performSetActiveConfig() { // setActiveConfigWithConstraints may fail if a hotplug event is just about // to be sent. We just log the error in this case. ALOGW("setActiveConfigWithConstraints failed: %d", status); return false; return; } mScheduler->onNewVsyncPeriodChangeTimeline(outTimeline); // Scheduler will submit an empty frame to HWC if needed. mCheckPendingFence = true; return false; mSetActiveConfigPending = true; } status_t SurfaceFlinger::getDisplayColorModes(const sp<IBinder>& displayToken, Loading Loading @@ -1901,6 +1891,20 @@ void SurfaceFlinger::onMessageReceived(int32_t what) NO_THREAD_SAFETY_ANALYSIS { mGpuFrameMissedCount++; } // If we are in the middle of a config change and the fence hasn't // fired yet just wait for the next invalidate if (mSetActiveConfigPending) { if (framePending) { mEventQueue->invalidate(); break; } // We received the present fence from the HWC, so we assume it successfully updated // the config, hence we update SF. mSetActiveConfigPending = false; setActiveConfigInternal(); } if (framePending && mPropagateBackpressure) { if ((hwcFrameMissed && !gpuFrameMissed) || mPropagateBackpressureClientComposition) { Loading Loading @@ -1970,9 +1974,7 @@ void SurfaceFlinger::onMessageReceived(int32_t what) NO_THREAD_SAFETY_ANALYSIS { mScheduler->chooseRefreshRateForContent(); } if (performSetActiveConfig()) { break; } performSetActiveConfig(); updateCursorAsync(); updateInputFlinger(); Loading
services/surfaceflinger/SurfaceFlinger.h +4 −6 Original line number Diff line number Diff line Loading @@ -565,11 +565,9 @@ private: // Once HWC has returned the present fence, this sets the active config and a new refresh // rate in SF. void setActiveConfigInternal() REQUIRES(mStateLock); // Active config is updated on INVALIDATE call in a state machine-like manner. When the // desired config was set, HWC needs to update the panel on the next refresh, and when // we receive the fence back, we know that the process was complete. It returns whether // we need to wait for the next invalidate bool performSetActiveConfig() REQUIRES(mStateLock); // Calls to setActiveConfig on the main thread if there is a pending config // that needs to be applied. void performSetActiveConfig() REQUIRES(mStateLock); // Called when active config is no longer is progress void desiredActiveConfigChangeDone() REQUIRES(mStateLock); // called on the main thread in response to setPowerMode() Loading Loading @@ -1225,7 +1223,7 @@ private: // below flags are set by main thread only TracedOrdinal<bool> mDesiredActiveConfigChanged GUARDED_BY(mActiveConfigLock) = {"DesiredActiveConfigChanged", false}; bool mCheckPendingFence = false; bool mSetActiveConfigPending = false; bool mLumaSampling = true; sp<RegionSamplingThread> mRegionSamplingThread; Loading