Loading services/surfaceflinger/DisplayDevice.cpp +36 −36 Original line number Diff line number Diff line Loading @@ -63,14 +63,14 @@ DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs& args) mDisplayToken(args.displayToken), mSequenceId(args.sequenceId), mCompositionDisplay{args.compositionDisplay}, mActiveModeFPSTrace(concatId("ActiveModeFPS")), mActiveModeFPSHwcTrace(concatId("ActiveModeFPS_HWC")), mRenderFrameRateFPSTrace(concatId("RenderRateFPS")), mPendingModeFpsTrace(concatId("PendingModeFps")), mActiveModeFpsTrace(concatId("ActiveModeFps")), mRenderRateFpsTrace(concatId("RenderRateFps")), mPhysicalOrientation(args.physicalOrientation), mIsPrimary(args.isPrimary), mRequestedRefreshRate(args.requestedRefreshRate), mRefreshRateSelector(std::move(args.refreshRateSelector)), mDesiredActiveModeChanged(concatId("DesiredActiveModeChanged"), false) { mDesiredModeChanged(concatId("DesiredModeChanged"), false) { mCompositionDisplay->editState().isSecure = args.isSecure; mCompositionDisplay->createRenderSurface( compositionengine::RenderSurfaceCreationArgsBuilder() Loading Loading @@ -210,8 +210,8 @@ bool DisplayDevice::isPoweredOn() const { } void DisplayDevice::setActiveMode(DisplayModeId modeId, Fps vsyncRate, Fps renderFps) { ATRACE_INT(mActiveModeFPSTrace.c_str(), vsyncRate.getIntValue()); ATRACE_INT(mRenderFrameRateFPSTrace.c_str(), renderFps.getIntValue()); ATRACE_INT(mActiveModeFpsTrace.c_str(), vsyncRate.getIntValue()); ATRACE_INT(mRenderRateFpsTrace.c_str(), renderFps.getIntValue()); mRefreshRateSelector->setActiveMode(modeId, renderFps); updateRefreshRateOverlayRate(vsyncRate, renderFps); Loading @@ -227,11 +227,11 @@ status_t DisplayDevice::initiateModeChange(const ActiveModeInfo& info, to_string(getId()).c_str()); return BAD_VALUE; } mUpcomingActiveMode = info; mPendingMode = info; mIsModeSetPending = true; const auto& pendingMode = *info.modeOpt->modePtr; ATRACE_INT(mActiveModeFPSHwcTrace.c_str(), pendingMode.getVsyncRate().getIntValue()); ATRACE_INT(mPendingModeFpsTrace.c_str(), pendingMode.getVsyncRate().getIntValue()); return mHwComposer.setActiveModeWithConstraints(getPhysicalId(), pendingMode.getHwcId(), constraints, outTimeline); Loading Loading @@ -524,8 +524,7 @@ void DisplayDevice::animateOverlay() { } } auto DisplayDevice::setDesiredActiveMode(const ActiveModeInfo& info, bool force) -> DesiredActiveModeAction { auto DisplayDevice::setDesiredMode(const ActiveModeInfo& info, bool force) -> DesiredModeAction { ATRACE_CALL(); LOG_ALWAYS_FATAL_IF(!info.modeOpt, "desired mode not provided"); Loading @@ -534,49 +533,50 @@ auto DisplayDevice::setDesiredActiveMode(const ActiveModeInfo& info, bool force) ALOGV("%s(%s)", __func__, to_string(*info.modeOpt->modePtr).c_str()); std::scoped_lock lock(mActiveModeLock); if (mDesiredActiveModeChanged) { // If a mode change is pending, just cache the latest request in mDesiredActiveMode const auto prevConfig = mDesiredActiveMode.event; mDesiredActiveMode = info; mDesiredActiveMode.event = mDesiredActiveMode.event | prevConfig; return DesiredActiveModeAction::None; std::scoped_lock lock(mDesiredModeLock); if (mDesiredModeChanged) { // A mode transition was already scheduled, so just override the desired mode. const auto event = mDesiredMode.event; mDesiredMode = info; mDesiredMode.event = mDesiredMode.event | event; return DesiredModeAction::None; } const auto& desiredMode = *info.modeOpt->modePtr; // Check if we are already at the desired mode const auto currentMode = refreshRateSelector().getActiveMode(); if (!force && currentMode.modePtr->getId() == desiredMode.getId()) { if (currentMode == info.modeOpt) { return DesiredActiveModeAction::None; // If the desired mode is already active... const auto activeMode = refreshRateSelector().getActiveMode(); if (!force && activeMode.modePtr->getId() == desiredMode.getId()) { if (activeMode == info.modeOpt) { return DesiredModeAction::None; } // ...but the render rate changed: setActiveMode(desiredMode.getId(), desiredMode.getVsyncRate(), info.modeOpt->fps); return DesiredActiveModeAction::InitiateRenderRateSwitch; return DesiredModeAction::InitiateRenderRateSwitch; } // Set the render frame rate to the current physical refresh rate to schedule the next // Set the render frame rate to the active physical refresh rate to schedule the next // frame as soon as possible. setActiveMode(currentMode.modePtr->getId(), currentMode.modePtr->getVsyncRate(), currentMode.modePtr->getVsyncRate()); setActiveMode(activeMode.modePtr->getId(), activeMode.modePtr->getVsyncRate(), activeMode.modePtr->getVsyncRate()); // Initiate a mode change. mDesiredActiveModeChanged = true; mDesiredActiveMode = info; return DesiredActiveModeAction::InitiateDisplayModeSwitch; mDesiredModeChanged = true; mDesiredMode = info; return DesiredModeAction::InitiateDisplayModeSwitch; } std::optional<DisplayDevice::ActiveModeInfo> DisplayDevice::getDesiredActiveMode() const { std::scoped_lock lock(mActiveModeLock); if (mDesiredActiveModeChanged) return mDesiredActiveMode; auto DisplayDevice::getDesiredMode() const -> ftl::Optional<ActiveModeInfo> { std::scoped_lock lock(mDesiredModeLock); if (mDesiredModeChanged) return mDesiredMode; return std::nullopt; } void DisplayDevice::clearDesiredActiveModeState() { std::scoped_lock lock(mActiveModeLock); mDesiredActiveMode.event = scheduler::DisplayModeEvent::None; mDesiredActiveModeChanged = false; void DisplayDevice::clearDesiredMode() { std::scoped_lock lock(mDesiredModeLock); mDesiredMode.event = scheduler::DisplayModeEvent::None; mDesiredModeChanged = false; } void DisplayDevice::adjustRefreshRate(Fps pacesetterDisplayRefreshRate) { Loading services/surfaceflinger/DisplayDevice.h +17 −20 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ #pragma once #include <memory> #include <optional> #include <string> #include <unordered_map> Loading @@ -25,6 +24,7 @@ #include <android/native_window.h> #include <binder/IBinder.h> #include <ftl/concat.h> #include <ftl/optional.h> #include <gui/LayerState.h> #include <math/mat4.h> #include <renderengine/RenderEngine.h> Loading @@ -51,6 +51,7 @@ #include "ThreadContext.h" #include "TracedOrdinal.h" #include "Utils/Dumper.h" namespace android { class Fence; Loading Loading @@ -205,19 +206,15 @@ public: } }; enum class DesiredActiveModeAction { None, InitiateDisplayModeSwitch, InitiateRenderRateSwitch }; DesiredActiveModeAction setDesiredActiveMode(const ActiveModeInfo&, bool force = false) EXCLUDES(mActiveModeLock); std::optional<ActiveModeInfo> getDesiredActiveMode() const EXCLUDES(mActiveModeLock); void clearDesiredActiveModeState() EXCLUDES(mActiveModeLock); ActiveModeInfo getUpcomingActiveMode() const REQUIRES(kMainThreadContext) { return mUpcomingActiveMode; } enum class DesiredModeAction { None, InitiateDisplayModeSwitch, InitiateRenderRateSwitch }; DesiredModeAction setDesiredMode(const ActiveModeInfo&, bool force = false) EXCLUDES(mDesiredModeLock); ftl::Optional<ActiveModeInfo> getDesiredMode() const EXCLUDES(mDesiredModeLock); void clearDesiredMode() EXCLUDES(mDesiredModeLock); ActiveModeInfo getPendingMode() const REQUIRES(kMainThreadContext) { return mPendingMode; } bool isModeSetPending() const REQUIRES(kMainThreadContext) { return mIsModeSetPending; } scheduler::FrameRateMode getActiveMode() const REQUIRES(kMainThreadContext) { Loading Loading @@ -282,9 +279,9 @@ private: const std::shared_ptr<compositionengine::Display> mCompositionDisplay; std::string mDisplayName; std::string mActiveModeFPSTrace; std::string mActiveModeFPSHwcTrace; std::string mRenderFrameRateFPSTrace; std::string mPendingModeFpsTrace; std::string mActiveModeFpsTrace; std::string mRenderRateFpsTrace; const ui::Rotation mPhysicalOrientation; ui::Rotation mOrientation = ui::ROTATION_0; Loading Loading @@ -319,11 +316,11 @@ private: // This parameter is only used for hdr/sdr ratio overlay float mHdrSdrRatio = 1.0f; mutable std::mutex mActiveModeLock; ActiveModeInfo mDesiredActiveMode GUARDED_BY(mActiveModeLock); TracedOrdinal<bool> mDesiredActiveModeChanged GUARDED_BY(mActiveModeLock); mutable std::mutex mDesiredModeLock; ActiveModeInfo mDesiredMode GUARDED_BY(mDesiredModeLock); TracedOrdinal<bool> mDesiredModeChanged GUARDED_BY(mDesiredModeLock); ActiveModeInfo mUpcomingActiveMode GUARDED_BY(kMainThreadContext); ActiveModeInfo mPendingMode GUARDED_BY(kMainThreadContext); bool mIsModeSetPending GUARDED_BY(kMainThreadContext) = false; }; Loading services/surfaceflinger/Scheduler/RefreshRateSelector.cpp +3 −4 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ #include <scheduler/FrameRateMode.h> #include <utils/Trace.h> #include "../SurfaceFlingerProperties.h" #include "RefreshRateSelector.h" #include <com_android_graphics_surfaceflinger_flags.h> Loading Loading @@ -971,12 +970,12 @@ auto RefreshRateSelector::getFrameRateOverrides(const std::vector<LayerRequireme } ftl::Optional<FrameRateMode> RefreshRateSelector::onKernelTimerChanged( std::optional<DisplayModeId> desiredActiveModeId, bool timerExpired) const { ftl::Optional<DisplayModeId> desiredModeIdOpt, bool timerExpired) const { std::lock_guard lock(mLock); const auto current = [&]() REQUIRES(mLock) -> FrameRateMode { if (desiredActiveModeId) { const auto& modePtr = mDisplayModes.get(*desiredActiveModeId)->get(); if (desiredModeIdOpt) { const auto& modePtr = mDisplayModes.get(*desiredModeIdOpt)->get(); return FrameRateMode{modePtr->getPeakFps(), ftl::as_non_null(modePtr)}; } Loading services/surfaceflinger/Scheduler/RefreshRateSelector.h +2 −6 Original line number Diff line number Diff line Loading @@ -16,9 +16,6 @@ #pragma once #include <algorithm> #include <numeric> #include <set> #include <type_traits> #include <utility> #include <variant> Loading Loading @@ -258,9 +255,8 @@ public: mMaxRefreshRateModeIt->second->getPeakFps()}; } ftl::Optional<FrameRateMode> onKernelTimerChanged( std::optional<DisplayModeId> desiredActiveModeId, bool timerExpired) const EXCLUDES(mLock); ftl::Optional<FrameRateMode> onKernelTimerChanged(ftl::Optional<DisplayModeId> desiredModeIdOpt, bool timerExpired) const EXCLUDES(mLock); void setActiveMode(DisplayModeId, Fps renderFrameRate) EXCLUDES(mLock); Loading services/surfaceflinger/SurfaceFlinger.cpp +45 −51 Original line number Diff line number Diff line Loading @@ -1177,7 +1177,7 @@ status_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& displayToken, return NO_ERROR; } void SurfaceFlinger::setDesiredActiveMode(display::DisplayModeRequest&& request, bool force) { void SurfaceFlinger::setDesiredMode(display::DisplayModeRequest&& request, bool force) { const auto displayId = request.mode.modePtr->getPhysicalDisplayId(); ATRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str()); Loading @@ -1190,10 +1190,9 @@ void SurfaceFlinger::setDesiredActiveMode(display::DisplayModeRequest&& request, const auto mode = request.mode; const bool emitEvent = request.emitEvent; switch (display->setDesiredActiveMode(DisplayDevice::ActiveModeInfo(std::move(request)), force)) { case DisplayDevice::DesiredActiveModeAction::InitiateDisplayModeSwitch: // Set the render rate as setDesiredActiveMode updated it. switch (display->setDesiredMode(DisplayDevice::ActiveModeInfo(std::move(request)), force)) { case DisplayDevice::DesiredModeAction::InitiateDisplayModeSwitch: // DisplayDevice::setDesiredMode updated the render rate, so inform Scheduler. mScheduler->setRenderRate(displayId, display->refreshRateSelector().getActiveMode().fps); Loading @@ -1215,7 +1214,7 @@ void SurfaceFlinger::setDesiredActiveMode(display::DisplayModeRequest&& request, mScheduler->setModeChangePending(true); break; case DisplayDevice::DesiredActiveModeAction::InitiateRenderRateSwitch: case DisplayDevice::DesiredModeAction::InitiateRenderRateSwitch: mScheduler->setRenderRate(displayId, mode.fps); if (displayId == mActiveDisplayId) { Loading @@ -1227,7 +1226,7 @@ void SurfaceFlinger::setDesiredActiveMode(display::DisplayModeRequest&& request, dispatchDisplayModeChangeEvent(displayId, mode); } break; case DisplayDevice::DesiredActiveModeAction::None: case DisplayDevice::DesiredModeAction::None: break; } } Loading Loading @@ -1287,27 +1286,27 @@ void SurfaceFlinger::finalizeDisplayModeChange(DisplayDevice& display) { const auto displayId = display.getPhysicalId(); ATRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str()); const auto upcomingModeInfo = display.getUpcomingActiveMode(); if (!upcomingModeInfo.modeOpt) { const auto pendingMode = display.getPendingMode(); if (!pendingMode.modeOpt) { // There is no pending mode change. This can happen if the active // display changed and the mode change happened on a different display. return; } if (display.getActiveMode().modePtr->getResolution() != upcomingModeInfo.modeOpt->modePtr->getResolution()) { pendingMode.modeOpt->modePtr->getResolution()) { auto& state = mCurrentState.displays.editValueFor(display.getDisplayToken()); // We need to generate new sequenceId in order to recreate the display (and this // way the framebuffer). state.sequenceId = DisplayDeviceState{}.sequenceId; state.physical->activeMode = upcomingModeInfo.modeOpt->modePtr.get(); state.physical->activeMode = pendingMode.modeOpt->modePtr.get(); processDisplayChangesLocked(); // processDisplayChangesLocked will update all necessary components so we're done here. return; } const auto& activeMode = *upcomingModeInfo.modeOpt; const auto& activeMode = *pendingMode.modeOpt; display.finalizeModeChange(activeMode.modePtr->getId(), activeMode.modePtr->getVsyncRate(), activeMode.fps); Loading @@ -1316,26 +1315,26 @@ void SurfaceFlinger::finalizeDisplayModeChange(DisplayDevice& display) { updatePhaseConfiguration(activeMode.fps); } if (upcomingModeInfo.event != scheduler::DisplayModeEvent::None) { if (pendingMode.event != scheduler::DisplayModeEvent::None) { dispatchDisplayModeChangeEvent(displayId, activeMode); } } void SurfaceFlinger::clearDesiredActiveModeState(const sp<DisplayDevice>& display) { display->clearDesiredActiveModeState(); void SurfaceFlinger::dropModeRequest(const sp<DisplayDevice>& display) { display->clearDesiredMode(); if (display->getPhysicalId() == mActiveDisplayId) { // TODO(b/255635711): Check for pending mode changes on other displays. mScheduler->setModeChangePending(false); } } void SurfaceFlinger::desiredActiveModeChangeDone(const sp<DisplayDevice>& display) { const auto desiredActiveMode = display->getDesiredActiveMode(); const auto& modeOpt = desiredActiveMode->modeOpt; void SurfaceFlinger::applyActiveMode(const sp<DisplayDevice>& display) { const auto desiredModeOpt = display->getDesiredMode(); const auto& modeOpt = desiredModeOpt->modeOpt; const auto displayId = modeOpt->modePtr->getPhysicalDisplayId(); const auto vsyncRate = modeOpt->modePtr->getVsyncRate(); const auto renderFps = modeOpt->fps; clearDesiredActiveModeState(display); dropModeRequest(display); mScheduler->resyncToHardwareVsync(displayId, true /* allowToEnable */, vsyncRate); mScheduler->setRenderRate(displayId, renderFps); Loading @@ -1353,25 +1352,23 @@ void SurfaceFlinger::initiateDisplayModeChanges() { const auto display = getDisplayDeviceLocked(id); if (!display) continue; // Store the local variable to release the lock. const auto desiredActiveMode = display->getDesiredActiveMode(); if (!desiredActiveMode) { // No desired active mode pending to be applied. const auto desiredModeOpt = display->getDesiredMode(); if (!desiredModeOpt) { continue; } if (!shouldApplyRefreshRateSelectorPolicy(*display)) { clearDesiredActiveModeState(display); dropModeRequest(display); continue; } const auto desiredModeId = desiredActiveMode->modeOpt->modePtr->getId(); const auto desiredModeId = desiredModeOpt->modeOpt->modePtr->getId(); const auto displayModePtrOpt = physical.snapshot().displayModes().get(desiredModeId); if (!displayModePtrOpt) { ALOGW("Desired display mode is no longer supported. Mode ID = %d", desiredModeId.value()); clearDesiredActiveModeState(display); dropModeRequest(display); continue; } Loading @@ -1379,9 +1376,8 @@ void SurfaceFlinger::initiateDisplayModeChanges() { to_string(displayModePtrOpt->get()->getVsyncRate()).c_str(), to_string(display->getId()).c_str()); if (display->getActiveMode() == desiredActiveMode->modeOpt) { // we are already in the requested mode, there is nothing left to do desiredActiveModeChangeDone(display); if (display->getActiveMode() == desiredModeOpt->modeOpt) { applyActiveMode(display); continue; } Loading @@ -1389,9 +1385,9 @@ void SurfaceFlinger::initiateDisplayModeChanges() { // allowed modes might have changed by the time we process the refresh. // Make sure the desired mode is still allowed const auto displayModeAllowed = display->refreshRateSelector().isModeAllowed(*desiredActiveMode->modeOpt); display->refreshRateSelector().isModeAllowed(*desiredModeOpt->modeOpt); if (!displayModeAllowed) { clearDesiredActiveModeState(display); dropModeRequest(display); continue; } Loading @@ -1401,9 +1397,7 @@ void SurfaceFlinger::initiateDisplayModeChanges() { constraints.seamlessRequired = false; hal::VsyncPeriodChangeTimeline outTimeline; const auto status = display->initiateModeChange(*desiredActiveMode, constraints, &outTimeline); const auto status = display->initiateModeChange(*desiredModeOpt, constraints, &outTimeline); if (status != NO_ERROR) { // initiateModeChange may fail if a hotplug event is just about // to be sent. We just log the error in this case. Loading @@ -1428,9 +1422,9 @@ void SurfaceFlinger::initiateDisplayModeChanges() { const auto display = getDisplayDeviceLocked(*displayToUpdateImmediately); finalizeDisplayModeChange(*display); const auto desiredActiveMode = display->getDesiredActiveMode(); if (desiredActiveMode && display->getActiveMode() == desiredActiveMode->modeOpt) { desiredActiveModeChangeDone(display); const auto desiredModeOpt = display->getDesiredMode(); if (desiredModeOpt && display->getActiveMode() == desiredModeOpt->modeOpt) { applyActiveMode(display); } } } Loading Loading @@ -4016,7 +4010,7 @@ void SurfaceFlinger::requestDisplayModes(std::vector<display::DisplayModeRequest } if (display->refreshRateSelector().isModeAllowed(request.mode)) { setDesiredActiveMode(std::move(request)); setDesiredMode(std::move(request)); } else { ALOGV("%s: Mode %d is disallowed for display %s", __func__, modePtr->getId().value(), to_string(displayId).c_str()); Loading Loading @@ -7283,15 +7277,14 @@ void SurfaceFlinger::kernelTimerChanged(bool expired) { } if (!display->isRefreshRateOverlayEnabled()) return; const auto desiredActiveMode = display->getDesiredActiveMode(); const std::optional<DisplayModeId> desiredModeId = desiredActiveMode ? std::make_optional(desiredActiveMode->modeOpt->modePtr->getId()) : std::nullopt; const auto desiredModeIdOpt = display->getDesiredMode().transform([](const DisplayDevice::ActiveModeInfo& info) { return info.modeOpt->modePtr->getId(); }); const bool timerExpired = mKernelIdleTimerEnabled && expired; if (display->onKernelTimerChanged(desiredModeId, timerExpired)) { if (display->onKernelTimerChanged(desiredModeIdOpt, timerExpired)) { mScheduler->scheduleFrame(); } })); Loading Loading @@ -8239,18 +8232,19 @@ status_t SurfaceFlinger::applyRefreshRateSelectorPolicy( auto preferredMode = std::move(*preferredModeOpt); const auto preferredModeId = preferredMode.modePtr->getId(); const Fps preferredFps = preferredMode.fps; ALOGV("Switching to Scheduler preferred mode %d (%s)", preferredModeId.value(), to_string(preferredMode.fps).c_str()); to_string(preferredFps).c_str()); if (!selector.isModeAllowed(preferredMode)) { ALOGE("%s: Preferred mode %d is disallowed", __func__, preferredModeId.value()); return INVALID_OPERATION; } setDesiredActiveMode({preferredMode, .emitEvent = true}, force); setDesiredMode({std::move(preferredMode), .emitEvent = true}, force); // Update the frameRateOverride list as the display render rate might have changed if (mScheduler->updateFrameRateOverrides(/*consideredSignals*/ {}, preferredMode.fps)) { if (mScheduler->updateFrameRateOverrides(scheduler::GlobalSignals{}, preferredFps)) { triggerOnFrameRateOverridesChanged(); } Loading Loading @@ -8587,7 +8581,7 @@ void SurfaceFlinger::onActiveDisplayChangedLocked(const DisplayDevice* inactiveD const DisplayDevice& activeDisplay) { ATRACE_CALL(); // For the first display activated during boot, there is no need to force setDesiredActiveMode, // For the first display activated during boot, there is no need to force setDesiredMode, // because DM is about to send its policy via setDesiredDisplayModeSpecs. bool forceApplyPolicy = false; Loading @@ -8611,9 +8605,9 @@ void SurfaceFlinger::onActiveDisplayChangedLocked(const DisplayDevice* inactiveD sActiveDisplayRotationFlags = ui::Transform::toRotationFlags(activeDisplay.getOrientation()); // The policy of the new active/pacesetter display may have changed while it was inactive. In // that case, its preferred mode has not been propagated to HWC (via setDesiredActiveMode). In // either case, the Scheduler's cachedModeChangedParams must be initialized to the newly active // mode, and the kernel idle timer of the newly active display must be toggled. // that case, its preferred mode has not been propagated to HWC (via setDesiredMode). In either // case, the Scheduler's cachedModeChangedParams must be initialized to the newly active mode, // and the kernel idle timer of the newly active display must be toggled. applyRefreshRateSelectorPolicy(mActiveDisplayId, activeDisplay.refreshRateSelector(), forceApplyPolicy); } Loading Loading
services/surfaceflinger/DisplayDevice.cpp +36 −36 Original line number Diff line number Diff line Loading @@ -63,14 +63,14 @@ DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs& args) mDisplayToken(args.displayToken), mSequenceId(args.sequenceId), mCompositionDisplay{args.compositionDisplay}, mActiveModeFPSTrace(concatId("ActiveModeFPS")), mActiveModeFPSHwcTrace(concatId("ActiveModeFPS_HWC")), mRenderFrameRateFPSTrace(concatId("RenderRateFPS")), mPendingModeFpsTrace(concatId("PendingModeFps")), mActiveModeFpsTrace(concatId("ActiveModeFps")), mRenderRateFpsTrace(concatId("RenderRateFps")), mPhysicalOrientation(args.physicalOrientation), mIsPrimary(args.isPrimary), mRequestedRefreshRate(args.requestedRefreshRate), mRefreshRateSelector(std::move(args.refreshRateSelector)), mDesiredActiveModeChanged(concatId("DesiredActiveModeChanged"), false) { mDesiredModeChanged(concatId("DesiredModeChanged"), false) { mCompositionDisplay->editState().isSecure = args.isSecure; mCompositionDisplay->createRenderSurface( compositionengine::RenderSurfaceCreationArgsBuilder() Loading Loading @@ -210,8 +210,8 @@ bool DisplayDevice::isPoweredOn() const { } void DisplayDevice::setActiveMode(DisplayModeId modeId, Fps vsyncRate, Fps renderFps) { ATRACE_INT(mActiveModeFPSTrace.c_str(), vsyncRate.getIntValue()); ATRACE_INT(mRenderFrameRateFPSTrace.c_str(), renderFps.getIntValue()); ATRACE_INT(mActiveModeFpsTrace.c_str(), vsyncRate.getIntValue()); ATRACE_INT(mRenderRateFpsTrace.c_str(), renderFps.getIntValue()); mRefreshRateSelector->setActiveMode(modeId, renderFps); updateRefreshRateOverlayRate(vsyncRate, renderFps); Loading @@ -227,11 +227,11 @@ status_t DisplayDevice::initiateModeChange(const ActiveModeInfo& info, to_string(getId()).c_str()); return BAD_VALUE; } mUpcomingActiveMode = info; mPendingMode = info; mIsModeSetPending = true; const auto& pendingMode = *info.modeOpt->modePtr; ATRACE_INT(mActiveModeFPSHwcTrace.c_str(), pendingMode.getVsyncRate().getIntValue()); ATRACE_INT(mPendingModeFpsTrace.c_str(), pendingMode.getVsyncRate().getIntValue()); return mHwComposer.setActiveModeWithConstraints(getPhysicalId(), pendingMode.getHwcId(), constraints, outTimeline); Loading Loading @@ -524,8 +524,7 @@ void DisplayDevice::animateOverlay() { } } auto DisplayDevice::setDesiredActiveMode(const ActiveModeInfo& info, bool force) -> DesiredActiveModeAction { auto DisplayDevice::setDesiredMode(const ActiveModeInfo& info, bool force) -> DesiredModeAction { ATRACE_CALL(); LOG_ALWAYS_FATAL_IF(!info.modeOpt, "desired mode not provided"); Loading @@ -534,49 +533,50 @@ auto DisplayDevice::setDesiredActiveMode(const ActiveModeInfo& info, bool force) ALOGV("%s(%s)", __func__, to_string(*info.modeOpt->modePtr).c_str()); std::scoped_lock lock(mActiveModeLock); if (mDesiredActiveModeChanged) { // If a mode change is pending, just cache the latest request in mDesiredActiveMode const auto prevConfig = mDesiredActiveMode.event; mDesiredActiveMode = info; mDesiredActiveMode.event = mDesiredActiveMode.event | prevConfig; return DesiredActiveModeAction::None; std::scoped_lock lock(mDesiredModeLock); if (mDesiredModeChanged) { // A mode transition was already scheduled, so just override the desired mode. const auto event = mDesiredMode.event; mDesiredMode = info; mDesiredMode.event = mDesiredMode.event | event; return DesiredModeAction::None; } const auto& desiredMode = *info.modeOpt->modePtr; // Check if we are already at the desired mode const auto currentMode = refreshRateSelector().getActiveMode(); if (!force && currentMode.modePtr->getId() == desiredMode.getId()) { if (currentMode == info.modeOpt) { return DesiredActiveModeAction::None; // If the desired mode is already active... const auto activeMode = refreshRateSelector().getActiveMode(); if (!force && activeMode.modePtr->getId() == desiredMode.getId()) { if (activeMode == info.modeOpt) { return DesiredModeAction::None; } // ...but the render rate changed: setActiveMode(desiredMode.getId(), desiredMode.getVsyncRate(), info.modeOpt->fps); return DesiredActiveModeAction::InitiateRenderRateSwitch; return DesiredModeAction::InitiateRenderRateSwitch; } // Set the render frame rate to the current physical refresh rate to schedule the next // Set the render frame rate to the active physical refresh rate to schedule the next // frame as soon as possible. setActiveMode(currentMode.modePtr->getId(), currentMode.modePtr->getVsyncRate(), currentMode.modePtr->getVsyncRate()); setActiveMode(activeMode.modePtr->getId(), activeMode.modePtr->getVsyncRate(), activeMode.modePtr->getVsyncRate()); // Initiate a mode change. mDesiredActiveModeChanged = true; mDesiredActiveMode = info; return DesiredActiveModeAction::InitiateDisplayModeSwitch; mDesiredModeChanged = true; mDesiredMode = info; return DesiredModeAction::InitiateDisplayModeSwitch; } std::optional<DisplayDevice::ActiveModeInfo> DisplayDevice::getDesiredActiveMode() const { std::scoped_lock lock(mActiveModeLock); if (mDesiredActiveModeChanged) return mDesiredActiveMode; auto DisplayDevice::getDesiredMode() const -> ftl::Optional<ActiveModeInfo> { std::scoped_lock lock(mDesiredModeLock); if (mDesiredModeChanged) return mDesiredMode; return std::nullopt; } void DisplayDevice::clearDesiredActiveModeState() { std::scoped_lock lock(mActiveModeLock); mDesiredActiveMode.event = scheduler::DisplayModeEvent::None; mDesiredActiveModeChanged = false; void DisplayDevice::clearDesiredMode() { std::scoped_lock lock(mDesiredModeLock); mDesiredMode.event = scheduler::DisplayModeEvent::None; mDesiredModeChanged = false; } void DisplayDevice::adjustRefreshRate(Fps pacesetterDisplayRefreshRate) { Loading
services/surfaceflinger/DisplayDevice.h +17 −20 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ #pragma once #include <memory> #include <optional> #include <string> #include <unordered_map> Loading @@ -25,6 +24,7 @@ #include <android/native_window.h> #include <binder/IBinder.h> #include <ftl/concat.h> #include <ftl/optional.h> #include <gui/LayerState.h> #include <math/mat4.h> #include <renderengine/RenderEngine.h> Loading @@ -51,6 +51,7 @@ #include "ThreadContext.h" #include "TracedOrdinal.h" #include "Utils/Dumper.h" namespace android { class Fence; Loading Loading @@ -205,19 +206,15 @@ public: } }; enum class DesiredActiveModeAction { None, InitiateDisplayModeSwitch, InitiateRenderRateSwitch }; DesiredActiveModeAction setDesiredActiveMode(const ActiveModeInfo&, bool force = false) EXCLUDES(mActiveModeLock); std::optional<ActiveModeInfo> getDesiredActiveMode() const EXCLUDES(mActiveModeLock); void clearDesiredActiveModeState() EXCLUDES(mActiveModeLock); ActiveModeInfo getUpcomingActiveMode() const REQUIRES(kMainThreadContext) { return mUpcomingActiveMode; } enum class DesiredModeAction { None, InitiateDisplayModeSwitch, InitiateRenderRateSwitch }; DesiredModeAction setDesiredMode(const ActiveModeInfo&, bool force = false) EXCLUDES(mDesiredModeLock); ftl::Optional<ActiveModeInfo> getDesiredMode() const EXCLUDES(mDesiredModeLock); void clearDesiredMode() EXCLUDES(mDesiredModeLock); ActiveModeInfo getPendingMode() const REQUIRES(kMainThreadContext) { return mPendingMode; } bool isModeSetPending() const REQUIRES(kMainThreadContext) { return mIsModeSetPending; } scheduler::FrameRateMode getActiveMode() const REQUIRES(kMainThreadContext) { Loading Loading @@ -282,9 +279,9 @@ private: const std::shared_ptr<compositionengine::Display> mCompositionDisplay; std::string mDisplayName; std::string mActiveModeFPSTrace; std::string mActiveModeFPSHwcTrace; std::string mRenderFrameRateFPSTrace; std::string mPendingModeFpsTrace; std::string mActiveModeFpsTrace; std::string mRenderRateFpsTrace; const ui::Rotation mPhysicalOrientation; ui::Rotation mOrientation = ui::ROTATION_0; Loading Loading @@ -319,11 +316,11 @@ private: // This parameter is only used for hdr/sdr ratio overlay float mHdrSdrRatio = 1.0f; mutable std::mutex mActiveModeLock; ActiveModeInfo mDesiredActiveMode GUARDED_BY(mActiveModeLock); TracedOrdinal<bool> mDesiredActiveModeChanged GUARDED_BY(mActiveModeLock); mutable std::mutex mDesiredModeLock; ActiveModeInfo mDesiredMode GUARDED_BY(mDesiredModeLock); TracedOrdinal<bool> mDesiredModeChanged GUARDED_BY(mDesiredModeLock); ActiveModeInfo mUpcomingActiveMode GUARDED_BY(kMainThreadContext); ActiveModeInfo mPendingMode GUARDED_BY(kMainThreadContext); bool mIsModeSetPending GUARDED_BY(kMainThreadContext) = false; }; Loading
services/surfaceflinger/Scheduler/RefreshRateSelector.cpp +3 −4 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ #include <scheduler/FrameRateMode.h> #include <utils/Trace.h> #include "../SurfaceFlingerProperties.h" #include "RefreshRateSelector.h" #include <com_android_graphics_surfaceflinger_flags.h> Loading Loading @@ -971,12 +970,12 @@ auto RefreshRateSelector::getFrameRateOverrides(const std::vector<LayerRequireme } ftl::Optional<FrameRateMode> RefreshRateSelector::onKernelTimerChanged( std::optional<DisplayModeId> desiredActiveModeId, bool timerExpired) const { ftl::Optional<DisplayModeId> desiredModeIdOpt, bool timerExpired) const { std::lock_guard lock(mLock); const auto current = [&]() REQUIRES(mLock) -> FrameRateMode { if (desiredActiveModeId) { const auto& modePtr = mDisplayModes.get(*desiredActiveModeId)->get(); if (desiredModeIdOpt) { const auto& modePtr = mDisplayModes.get(*desiredModeIdOpt)->get(); return FrameRateMode{modePtr->getPeakFps(), ftl::as_non_null(modePtr)}; } Loading
services/surfaceflinger/Scheduler/RefreshRateSelector.h +2 −6 Original line number Diff line number Diff line Loading @@ -16,9 +16,6 @@ #pragma once #include <algorithm> #include <numeric> #include <set> #include <type_traits> #include <utility> #include <variant> Loading Loading @@ -258,9 +255,8 @@ public: mMaxRefreshRateModeIt->second->getPeakFps()}; } ftl::Optional<FrameRateMode> onKernelTimerChanged( std::optional<DisplayModeId> desiredActiveModeId, bool timerExpired) const EXCLUDES(mLock); ftl::Optional<FrameRateMode> onKernelTimerChanged(ftl::Optional<DisplayModeId> desiredModeIdOpt, bool timerExpired) const EXCLUDES(mLock); void setActiveMode(DisplayModeId, Fps renderFrameRate) EXCLUDES(mLock); Loading
services/surfaceflinger/SurfaceFlinger.cpp +45 −51 Original line number Diff line number Diff line Loading @@ -1177,7 +1177,7 @@ status_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& displayToken, return NO_ERROR; } void SurfaceFlinger::setDesiredActiveMode(display::DisplayModeRequest&& request, bool force) { void SurfaceFlinger::setDesiredMode(display::DisplayModeRequest&& request, bool force) { const auto displayId = request.mode.modePtr->getPhysicalDisplayId(); ATRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str()); Loading @@ -1190,10 +1190,9 @@ void SurfaceFlinger::setDesiredActiveMode(display::DisplayModeRequest&& request, const auto mode = request.mode; const bool emitEvent = request.emitEvent; switch (display->setDesiredActiveMode(DisplayDevice::ActiveModeInfo(std::move(request)), force)) { case DisplayDevice::DesiredActiveModeAction::InitiateDisplayModeSwitch: // Set the render rate as setDesiredActiveMode updated it. switch (display->setDesiredMode(DisplayDevice::ActiveModeInfo(std::move(request)), force)) { case DisplayDevice::DesiredModeAction::InitiateDisplayModeSwitch: // DisplayDevice::setDesiredMode updated the render rate, so inform Scheduler. mScheduler->setRenderRate(displayId, display->refreshRateSelector().getActiveMode().fps); Loading @@ -1215,7 +1214,7 @@ void SurfaceFlinger::setDesiredActiveMode(display::DisplayModeRequest&& request, mScheduler->setModeChangePending(true); break; case DisplayDevice::DesiredActiveModeAction::InitiateRenderRateSwitch: case DisplayDevice::DesiredModeAction::InitiateRenderRateSwitch: mScheduler->setRenderRate(displayId, mode.fps); if (displayId == mActiveDisplayId) { Loading @@ -1227,7 +1226,7 @@ void SurfaceFlinger::setDesiredActiveMode(display::DisplayModeRequest&& request, dispatchDisplayModeChangeEvent(displayId, mode); } break; case DisplayDevice::DesiredActiveModeAction::None: case DisplayDevice::DesiredModeAction::None: break; } } Loading Loading @@ -1287,27 +1286,27 @@ void SurfaceFlinger::finalizeDisplayModeChange(DisplayDevice& display) { const auto displayId = display.getPhysicalId(); ATRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str()); const auto upcomingModeInfo = display.getUpcomingActiveMode(); if (!upcomingModeInfo.modeOpt) { const auto pendingMode = display.getPendingMode(); if (!pendingMode.modeOpt) { // There is no pending mode change. This can happen if the active // display changed and the mode change happened on a different display. return; } if (display.getActiveMode().modePtr->getResolution() != upcomingModeInfo.modeOpt->modePtr->getResolution()) { pendingMode.modeOpt->modePtr->getResolution()) { auto& state = mCurrentState.displays.editValueFor(display.getDisplayToken()); // We need to generate new sequenceId in order to recreate the display (and this // way the framebuffer). state.sequenceId = DisplayDeviceState{}.sequenceId; state.physical->activeMode = upcomingModeInfo.modeOpt->modePtr.get(); state.physical->activeMode = pendingMode.modeOpt->modePtr.get(); processDisplayChangesLocked(); // processDisplayChangesLocked will update all necessary components so we're done here. return; } const auto& activeMode = *upcomingModeInfo.modeOpt; const auto& activeMode = *pendingMode.modeOpt; display.finalizeModeChange(activeMode.modePtr->getId(), activeMode.modePtr->getVsyncRate(), activeMode.fps); Loading @@ -1316,26 +1315,26 @@ void SurfaceFlinger::finalizeDisplayModeChange(DisplayDevice& display) { updatePhaseConfiguration(activeMode.fps); } if (upcomingModeInfo.event != scheduler::DisplayModeEvent::None) { if (pendingMode.event != scheduler::DisplayModeEvent::None) { dispatchDisplayModeChangeEvent(displayId, activeMode); } } void SurfaceFlinger::clearDesiredActiveModeState(const sp<DisplayDevice>& display) { display->clearDesiredActiveModeState(); void SurfaceFlinger::dropModeRequest(const sp<DisplayDevice>& display) { display->clearDesiredMode(); if (display->getPhysicalId() == mActiveDisplayId) { // TODO(b/255635711): Check for pending mode changes on other displays. mScheduler->setModeChangePending(false); } } void SurfaceFlinger::desiredActiveModeChangeDone(const sp<DisplayDevice>& display) { const auto desiredActiveMode = display->getDesiredActiveMode(); const auto& modeOpt = desiredActiveMode->modeOpt; void SurfaceFlinger::applyActiveMode(const sp<DisplayDevice>& display) { const auto desiredModeOpt = display->getDesiredMode(); const auto& modeOpt = desiredModeOpt->modeOpt; const auto displayId = modeOpt->modePtr->getPhysicalDisplayId(); const auto vsyncRate = modeOpt->modePtr->getVsyncRate(); const auto renderFps = modeOpt->fps; clearDesiredActiveModeState(display); dropModeRequest(display); mScheduler->resyncToHardwareVsync(displayId, true /* allowToEnable */, vsyncRate); mScheduler->setRenderRate(displayId, renderFps); Loading @@ -1353,25 +1352,23 @@ void SurfaceFlinger::initiateDisplayModeChanges() { const auto display = getDisplayDeviceLocked(id); if (!display) continue; // Store the local variable to release the lock. const auto desiredActiveMode = display->getDesiredActiveMode(); if (!desiredActiveMode) { // No desired active mode pending to be applied. const auto desiredModeOpt = display->getDesiredMode(); if (!desiredModeOpt) { continue; } if (!shouldApplyRefreshRateSelectorPolicy(*display)) { clearDesiredActiveModeState(display); dropModeRequest(display); continue; } const auto desiredModeId = desiredActiveMode->modeOpt->modePtr->getId(); const auto desiredModeId = desiredModeOpt->modeOpt->modePtr->getId(); const auto displayModePtrOpt = physical.snapshot().displayModes().get(desiredModeId); if (!displayModePtrOpt) { ALOGW("Desired display mode is no longer supported. Mode ID = %d", desiredModeId.value()); clearDesiredActiveModeState(display); dropModeRequest(display); continue; } Loading @@ -1379,9 +1376,8 @@ void SurfaceFlinger::initiateDisplayModeChanges() { to_string(displayModePtrOpt->get()->getVsyncRate()).c_str(), to_string(display->getId()).c_str()); if (display->getActiveMode() == desiredActiveMode->modeOpt) { // we are already in the requested mode, there is nothing left to do desiredActiveModeChangeDone(display); if (display->getActiveMode() == desiredModeOpt->modeOpt) { applyActiveMode(display); continue; } Loading @@ -1389,9 +1385,9 @@ void SurfaceFlinger::initiateDisplayModeChanges() { // allowed modes might have changed by the time we process the refresh. // Make sure the desired mode is still allowed const auto displayModeAllowed = display->refreshRateSelector().isModeAllowed(*desiredActiveMode->modeOpt); display->refreshRateSelector().isModeAllowed(*desiredModeOpt->modeOpt); if (!displayModeAllowed) { clearDesiredActiveModeState(display); dropModeRequest(display); continue; } Loading @@ -1401,9 +1397,7 @@ void SurfaceFlinger::initiateDisplayModeChanges() { constraints.seamlessRequired = false; hal::VsyncPeriodChangeTimeline outTimeline; const auto status = display->initiateModeChange(*desiredActiveMode, constraints, &outTimeline); const auto status = display->initiateModeChange(*desiredModeOpt, constraints, &outTimeline); if (status != NO_ERROR) { // initiateModeChange may fail if a hotplug event is just about // to be sent. We just log the error in this case. Loading @@ -1428,9 +1422,9 @@ void SurfaceFlinger::initiateDisplayModeChanges() { const auto display = getDisplayDeviceLocked(*displayToUpdateImmediately); finalizeDisplayModeChange(*display); const auto desiredActiveMode = display->getDesiredActiveMode(); if (desiredActiveMode && display->getActiveMode() == desiredActiveMode->modeOpt) { desiredActiveModeChangeDone(display); const auto desiredModeOpt = display->getDesiredMode(); if (desiredModeOpt && display->getActiveMode() == desiredModeOpt->modeOpt) { applyActiveMode(display); } } } Loading Loading @@ -4016,7 +4010,7 @@ void SurfaceFlinger::requestDisplayModes(std::vector<display::DisplayModeRequest } if (display->refreshRateSelector().isModeAllowed(request.mode)) { setDesiredActiveMode(std::move(request)); setDesiredMode(std::move(request)); } else { ALOGV("%s: Mode %d is disallowed for display %s", __func__, modePtr->getId().value(), to_string(displayId).c_str()); Loading Loading @@ -7283,15 +7277,14 @@ void SurfaceFlinger::kernelTimerChanged(bool expired) { } if (!display->isRefreshRateOverlayEnabled()) return; const auto desiredActiveMode = display->getDesiredActiveMode(); const std::optional<DisplayModeId> desiredModeId = desiredActiveMode ? std::make_optional(desiredActiveMode->modeOpt->modePtr->getId()) : std::nullopt; const auto desiredModeIdOpt = display->getDesiredMode().transform([](const DisplayDevice::ActiveModeInfo& info) { return info.modeOpt->modePtr->getId(); }); const bool timerExpired = mKernelIdleTimerEnabled && expired; if (display->onKernelTimerChanged(desiredModeId, timerExpired)) { if (display->onKernelTimerChanged(desiredModeIdOpt, timerExpired)) { mScheduler->scheduleFrame(); } })); Loading Loading @@ -8239,18 +8232,19 @@ status_t SurfaceFlinger::applyRefreshRateSelectorPolicy( auto preferredMode = std::move(*preferredModeOpt); const auto preferredModeId = preferredMode.modePtr->getId(); const Fps preferredFps = preferredMode.fps; ALOGV("Switching to Scheduler preferred mode %d (%s)", preferredModeId.value(), to_string(preferredMode.fps).c_str()); to_string(preferredFps).c_str()); if (!selector.isModeAllowed(preferredMode)) { ALOGE("%s: Preferred mode %d is disallowed", __func__, preferredModeId.value()); return INVALID_OPERATION; } setDesiredActiveMode({preferredMode, .emitEvent = true}, force); setDesiredMode({std::move(preferredMode), .emitEvent = true}, force); // Update the frameRateOverride list as the display render rate might have changed if (mScheduler->updateFrameRateOverrides(/*consideredSignals*/ {}, preferredMode.fps)) { if (mScheduler->updateFrameRateOverrides(scheduler::GlobalSignals{}, preferredFps)) { triggerOnFrameRateOverridesChanged(); } Loading Loading @@ -8587,7 +8581,7 @@ void SurfaceFlinger::onActiveDisplayChangedLocked(const DisplayDevice* inactiveD const DisplayDevice& activeDisplay) { ATRACE_CALL(); // For the first display activated during boot, there is no need to force setDesiredActiveMode, // For the first display activated during boot, there is no need to force setDesiredMode, // because DM is about to send its policy via setDesiredDisplayModeSpecs. bool forceApplyPolicy = false; Loading @@ -8611,9 +8605,9 @@ void SurfaceFlinger::onActiveDisplayChangedLocked(const DisplayDevice* inactiveD sActiveDisplayRotationFlags = ui::Transform::toRotationFlags(activeDisplay.getOrientation()); // The policy of the new active/pacesetter display may have changed while it was inactive. In // that case, its preferred mode has not been propagated to HWC (via setDesiredActiveMode). In // either case, the Scheduler's cachedModeChangedParams must be initialized to the newly active // mode, and the kernel idle timer of the newly active display must be toggled. // that case, its preferred mode has not been propagated to HWC (via setDesiredMode). In either // case, the Scheduler's cachedModeChangedParams must be initialized to the newly active mode, // and the kernel idle timer of the newly active display must be toggled. applyRefreshRateSelectorPolicy(mActiveDisplayId, activeDisplay.refreshRateSelector(), forceApplyPolicy); } Loading