Loading services/surfaceflinger/Display/DisplayModeRequest.h +3 −3 Original line number Diff line number Diff line Loading @@ -18,19 +18,19 @@ #include <ftl/non_null.h> #include "DisplayHardware/DisplayMode.h" #include <scheduler/FrameRateMode.h> namespace android::display { struct DisplayModeRequest { ftl::NonNull<DisplayModePtr> modePtr; scheduler::FrameRateMode mode; // Whether to emit DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE. bool emitEvent = false; }; inline bool operator==(const DisplayModeRequest& lhs, const DisplayModeRequest& rhs) { return lhs.modePtr == rhs.modePtr && lhs.emitEvent == rhs.emitEvent; return lhs.mode == rhs.mode && lhs.emitEvent == rhs.emitEvent; } } // namespace android::display services/surfaceflinger/DisplayDevice.cpp +31 −25 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs& args) mCompositionDisplay{args.compositionDisplay}, mActiveModeFPSTrace("ActiveModeFPS -" + to_string(getId())), mActiveModeFPSHwcTrace("ActiveModeFPS_HWC -" + to_string(getId())), mRenderFrameRateFPSTrace("RenderRateFPS -" + to_string(getId())), mPhysicalOrientation(args.physicalOrientation), mIsPrimary(args.isPrimary), mRefreshRateSelector(std::move(args.refreshRateSelector)) { Loading Loading @@ -195,35 +196,32 @@ bool DisplayDevice::isPoweredOn() const { return mPowerMode && *mPowerMode != hal::PowerMode::OFF; } void DisplayDevice::setActiveMode(DisplayModeId modeId, const display::DisplaySnapshot& snapshot) { const auto fpsOpt = snapshot.displayModes().get(modeId).transform( [](const DisplayModePtr& mode) { return mode->getFps(); }); void DisplayDevice::setActiveMode(DisplayModeId modeId, Fps displayFps, Fps renderFps) { ATRACE_INT(mActiveModeFPSTrace.c_str(), displayFps.getIntValue()); ATRACE_INT(mRenderFrameRateFPSTrace.c_str(), renderFps.getIntValue()); LOG_ALWAYS_FATAL_IF(!fpsOpt, "Unknown mode"); const Fps fps = *fpsOpt; ATRACE_INT(mActiveModeFPSTrace.c_str(), fps.getIntValue()); mRefreshRateSelector->setActiveModeId(modeId); mRefreshRateSelector->setActiveMode(modeId, renderFps); if (mRefreshRateOverlay) { mRefreshRateOverlay->changeRefreshRate(fps); mRefreshRateOverlay->changeRefreshRate(displayFps); } } status_t DisplayDevice::initiateModeChange(const ActiveModeInfo& info, const hal::VsyncPeriodChangeConstraints& constraints, hal::VsyncPeriodChangeTimeline* outTimeline) { if (!info.mode || info.mode->getPhysicalDisplayId() != getPhysicalId()) { if (!info.modeOpt || info.modeOpt->modePtr->getPhysicalDisplayId() != getPhysicalId()) { ALOGE("Trying to initiate a mode change to invalid mode %s on display %s", info.mode ? std::to_string(info.mode->getId().value()).c_str() : "null", info.modeOpt ? std::to_string(info.modeOpt->modePtr->getId().value()).c_str() : "null", to_string(getId()).c_str()); return BAD_VALUE; } mUpcomingActiveMode = info; ATRACE_INT(mActiveModeFPSHwcTrace.c_str(), info.mode->getFps().getIntValue()); return mHwComposer.setActiveModeWithConstraints(getPhysicalId(), info.mode->getHwcId(), constraints, outTimeline); ATRACE_INT(mActiveModeFPSHwcTrace.c_str(), info.modeOpt->modePtr->getFps().getIntValue()); return mHwComposer.setActiveModeWithConstraints(getPhysicalId(), info.modeOpt->modePtr->getHwcId(), constraints, outTimeline); } nsecs_t DisplayDevice::getVsyncPeriodFromHWC() const { Loading @@ -238,7 +236,7 @@ nsecs_t DisplayDevice::getVsyncPeriodFromHWC() const { return vsyncPeriod; } return refreshRateSelector().getActiveModePtr()->getVsyncPeriod(); return refreshRateSelector().getActiveMode().modePtr->getVsyncPeriod(); } ui::Dataspace DisplayDevice::getCompositionDataSpace() const { Loading Loading @@ -422,7 +420,7 @@ void DisplayDevice::enableRefreshRateOverlay(bool enable, bool showSpinnner) { mRefreshRateOverlay = std::make_unique<RefreshRateOverlay>(fpsRange, showSpinnner); mRefreshRateOverlay->setLayerStack(getLayerStack()); mRefreshRateOverlay->setViewport(getSize()); mRefreshRateOverlay->changeRefreshRate(getActiveMode().getFps()); mRefreshRateOverlay->changeRefreshRate(getActiveMode().modePtr->getFps()); } bool DisplayDevice::onKernelTimerChanged(std::optional<DisplayModeId> desiredModeId, Loading @@ -445,13 +443,14 @@ void DisplayDevice::animateRefreshRateOverlay() { } } bool DisplayDevice::setDesiredActiveMode(const ActiveModeInfo& info) { auto DisplayDevice::setDesiredActiveMode(const ActiveModeInfo& info) -> DesiredActiveModeAction { ATRACE_CALL(); LOG_ALWAYS_FATAL_IF(!info.mode, "desired mode not provided"); LOG_ALWAYS_FATAL_IF(getPhysicalId() != info.mode->getPhysicalDisplayId(), "DisplayId mismatch"); LOG_ALWAYS_FATAL_IF(!info.modeOpt, "desired mode not provided"); LOG_ALWAYS_FATAL_IF(getPhysicalId() != info.modeOpt->modePtr->getPhysicalDisplayId(), "DisplayId mismatch"); ALOGV("%s(%s)", __func__, to_string(*info.mode).c_str()); ALOGV("%s(%s)", __func__, to_string(*info.modeOpt->modePtr).c_str()); std::scoped_lock lock(mActiveModeLock); if (mDesiredActiveModeChanged) { Loading @@ -459,18 +458,25 @@ bool DisplayDevice::setDesiredActiveMode(const ActiveModeInfo& info) { const auto prevConfig = mDesiredActiveMode.event; mDesiredActiveMode = info; mDesiredActiveMode.event = mDesiredActiveMode.event | prevConfig; return false; return DesiredActiveModeAction::None; } const auto& desiredMode = *info.modeOpt->modePtr; // Check if we are already at the desired mode if (refreshRateSelector().getActiveModePtr()->getId() == info.mode->getId()) { return false; if (refreshRateSelector().getActiveMode().modePtr->getId() == desiredMode.getId()) { if (refreshRateSelector().getActiveMode() == info.modeOpt) { return DesiredActiveModeAction::None; } setActiveMode(desiredMode.getId(), desiredMode.getFps(), info.modeOpt->fps); return DesiredActiveModeAction::InitiateRenderRateSwitch; } // Initiate a mode change. mDesiredActiveModeChanged = true; mDesiredActiveMode = info; return true; return DesiredActiveModeAction::InitiateDisplayModeSwitch; } std::optional<DisplayDevice::ActiveModeInfo> DisplayDevice::getDesiredActiveMode() const { Loading services/surfaceflinger/DisplayDevice.h +14 −8 Original line number Diff line number Diff line Loading @@ -190,33 +190,38 @@ public: using Event = scheduler::DisplayModeEvent; ActiveModeInfo() = default; ActiveModeInfo(DisplayModePtr mode, Event event) : mode(std::move(mode)), event(event) {} ActiveModeInfo(scheduler::FrameRateMode mode, Event event) : modeOpt(std::move(mode)), event(event) {} explicit ActiveModeInfo(display::DisplayModeRequest&& request) : ActiveModeInfo(std::move(request.modePtr).take(), : ActiveModeInfo(std::move(request.mode), request.emitEvent ? Event::Changed : Event::None) {} DisplayModePtr mode; ftl::Optional<scheduler::FrameRateMode> modeOpt; Event event = Event::None; bool operator!=(const ActiveModeInfo& other) const { return mode != other.mode || event != other.event; return modeOpt != other.modeOpt || event != other.event; } }; bool setDesiredActiveMode(const ActiveModeInfo&) EXCLUDES(mActiveModeLock); enum class DesiredActiveModeAction { None, InitiateDisplayModeSwitch, InitiateRenderRateSwitch }; DesiredActiveModeAction setDesiredActiveMode(const ActiveModeInfo&) EXCLUDES(mActiveModeLock); std::optional<ActiveModeInfo> getDesiredActiveMode() const EXCLUDES(mActiveModeLock); void clearDesiredActiveModeState() EXCLUDES(mActiveModeLock); ActiveModeInfo getUpcomingActiveMode() const REQUIRES(kMainThreadContext) { return mUpcomingActiveMode; } const DisplayMode& getActiveMode() const REQUIRES(kMainThreadContext) { scheduler::FrameRateMode getActiveMode() const REQUIRES(kMainThreadContext) { return mRefreshRateSelector->getActiveMode(); } // Precondition: DisplaySnapshot must contain a mode with DisplayModeId. void setActiveMode(DisplayModeId, const display::DisplaySnapshot&) REQUIRES(kMainThreadContext); void setActiveMode(DisplayModeId, Fps displayFps, Fps renderFps); status_t initiateModeChange(const ActiveModeInfo&, const hal::VsyncPeriodChangeConstraints& constraints, Loading Loading @@ -254,6 +259,7 @@ private: std::string mDisplayName; std::string mActiveModeFPSTrace; std::string mActiveModeFPSHwcTrace; std::string mRenderFrameRateFPSTrace; const ui::Rotation mPhysicalOrientation; ui::Rotation mOrientation = ui::ROTATION_0; Loading services/surfaceflinger/Layer.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -3597,7 +3597,7 @@ void Layer::onPostComposition(const DisplayDevice* display, } if (display) { const Fps refreshRate = display->refreshRateSelector().getActiveModePtr()->getFps(); const Fps refreshRate = display->refreshRateSelector().getActiveMode().fps; const std::optional<Fps> renderRate = mFlinger->mScheduler->getFrameRateOverride(getOwnerUid()); Loading services/surfaceflinger/Scheduler/RefreshRateSelector.cpp +32 −35 Original line number Diff line number Diff line Loading @@ -213,7 +213,7 @@ auto RefreshRateSelector::createFrameRateModes( std::vector<FrameRateMode> frameRateModes; frameRateModes.reserve(ratesMap.size()); for (const auto& [key, mode] : ratesMap) { frameRateModes.emplace_back(FrameRateMode{key.fps, mode->second}); frameRateModes.emplace_back(FrameRateMode{key.fps, ftl::as_non_null(mode->second)}); } // We always want that the lowest frame rate will be corresponding to the Loading Loading @@ -409,7 +409,7 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi ATRACE_CALL(); ALOGV("%s: %zu layers", __func__, layers.size()); const auto& activeMode = *getActiveModeItLocked()->second; const auto& activeMode = *getActiveModeLocked().modePtr; // Keep the display at max frame rate for the duration of powering on the display. if (signals.powerOnImminent) { Loading Loading @@ -842,7 +842,7 @@ std::optional<Fps> RefreshRateSelector::onKernelTimerChanged( const DisplayModePtr& current = desiredActiveModeId ? mDisplayModes.get(*desiredActiveModeId)->get() : getActiveModeItLocked()->second; : getActiveModeLocked().modePtr.get(); const DisplayModePtr& min = mMinRefreshRateModeIt->second; if (current == min) { Loading @@ -854,11 +854,11 @@ std::optional<Fps> RefreshRateSelector::onKernelTimerChanged( } const DisplayModePtr& RefreshRateSelector::getMinRefreshRateByPolicyLocked() const { const auto& activeMode = *getActiveModeItLocked()->second; const auto& activeMode = *getActiveModeLocked().modePtr; for (const FrameRateMode& mode : mPrimaryFrameRates) { if (activeMode.getGroup() == mode.modePtr->getGroup()) { return mode.modePtr; return mode.modePtr.get(); } } Loading @@ -866,12 +866,12 @@ const DisplayModePtr& RefreshRateSelector::getMinRefreshRateByPolicyLocked() con to_string(activeMode).c_str()); // Default to the lowest refresh rate. return mPrimaryFrameRates.front().modePtr; return mPrimaryFrameRates.front().modePtr.get(); } const DisplayModePtr& RefreshRateSelector::getMaxRefreshRateByPolicyLocked(int anchorGroup) const { const DisplayModePtr* maxByAnchor = &mPrimaryFrameRates.back().modePtr; const DisplayModePtr* max = &mPrimaryFrameRates.back().modePtr; const ftl::NonNull<DisplayModePtr>* maxByAnchor = &mPrimaryFrameRates.back().modePtr; const ftl::NonNull<DisplayModePtr>* max = &mPrimaryFrameRates.back().modePtr; bool maxByAnchorFound = false; for (auto it = mPrimaryFrameRates.rbegin(); it != mPrimaryFrameRates.rend(); ++it) { Loading @@ -888,13 +888,13 @@ const DisplayModePtr& RefreshRateSelector::getMaxRefreshRateByPolicyLocked(int a } if (maxByAnchorFound) { return *maxByAnchor; return maxByAnchor->get(); } ALOGE("Can't find max refresh rate by policy with the same group %d", anchorGroup); // Default to the highest refresh rate. return *max; return max->get(); } auto RefreshRateSelector::rankFrameRates(std::optional<int> anchorGroupOpt, Loading Loading @@ -946,31 +946,26 @@ auto RefreshRateSelector::rankFrameRates(std::optional<int> anchorGroupOpt, return rankFrameRates(kNoAnchorGroup, refreshRateOrder, preferredDisplayModeOpt); } DisplayModePtr RefreshRateSelector::getActiveModePtr() const { FrameRateMode RefreshRateSelector::getActiveMode() const { std::lock_guard lock(mLock); return getActiveModeItLocked()->second; return getActiveModeLocked(); } const DisplayMode& RefreshRateSelector::getActiveMode() const { // Reads from kMainThreadContext do not require mLock. ftl::FakeGuard guard(mLock); return *mActiveModeIt->second; } DisplayModeIterator RefreshRateSelector::getActiveModeItLocked() const { // Reads under mLock do not require kMainThreadContext. return FTL_FAKE_GUARD(kMainThreadContext, mActiveModeIt); const FrameRateMode& RefreshRateSelector::getActiveModeLocked() const { return *mActiveModeOpt; } void RefreshRateSelector::setActiveModeId(DisplayModeId modeId) { void RefreshRateSelector::setActiveMode(DisplayModeId modeId, Fps renderFrameRate) { std::lock_guard lock(mLock); // Invalidate the cached invocation to getRankedFrameRates. This forces // the refresh rate to be recomputed on the next call to getRankedFrameRates. mGetRankedFrameRatesCache.reset(); mActiveModeIt = mDisplayModes.find(modeId); LOG_ALWAYS_FATAL_IF(mActiveModeIt == mDisplayModes.end()); const auto activeModeOpt = mDisplayModes.get(modeId); LOG_ALWAYS_FATAL_IF(!activeModeOpt); mActiveModeOpt.emplace(FrameRateMode{renderFrameRate, ftl::as_non_null(activeModeOpt->get())}); } RefreshRateSelector::RefreshRateSelector(DisplayModes modes, DisplayModeId activeModeId, Loading Loading @@ -1007,8 +1002,10 @@ void RefreshRateSelector::updateDisplayModes(DisplayModes modes, DisplayModeId a mGetRankedFrameRatesCache.reset(); mDisplayModes = std::move(modes); mActiveModeIt = mDisplayModes.find(activeModeId); LOG_ALWAYS_FATAL_IF(mActiveModeIt == mDisplayModes.end()); const auto activeModeOpt = mDisplayModes.get(activeModeId); LOG_ALWAYS_FATAL_IF(!activeModeOpt); mActiveModeOpt = FrameRateMode{activeModeOpt->get()->getFps(), ftl::as_non_null(activeModeOpt->get())}; const auto sortedModes = sortByRefreshRate(mDisplayModes); mMinRefreshRateModeIt = sortedModes.front(); Loading Loading @@ -1064,6 +1061,7 @@ bool RefreshRateSelector::isPolicyValidLocked(const Policy& policy) const { auto RefreshRateSelector::setPolicy(const PolicyVariant& policy) -> SetPolicyResult { Policy oldPolicy; PhysicalDisplayId displayId; { std::lock_guard lock(mLock); oldPolicy = *getCurrentPolicyLocked(); Loading Loading @@ -1103,9 +1101,10 @@ auto RefreshRateSelector::setPolicy(const PolicyVariant& policy) -> SetPolicyRes return SetPolicyResult::Unchanged; } constructAvailableRefreshRates(); displayId = getActiveModeLocked().modePtr->getPhysicalDisplayId(); } const auto displayId = getActiveMode().getPhysicalDisplayId(); const unsigned numModeChanges = std::exchange(mNumModeSwitchesInPolicy, 0u); ALOGI("Display %s policy changed\n" Loading @@ -1132,12 +1131,10 @@ auto RefreshRateSelector::getDisplayManagerPolicy() const -> Policy { return mDisplayManagerPolicy; } bool RefreshRateSelector::isModeAllowed(DisplayModeId modeId) const { bool RefreshRateSelector::isModeAllowed(const FrameRateMode& mode) const { std::lock_guard lock(mLock); return std::any_of(mAppRequestFrameRates.begin(), mAppRequestFrameRates.end(), [modeId](const FrameRateMode& frameRateMode) { return frameRateMode.modePtr->getId() == modeId; }); return std::find(mAppRequestFrameRates.begin(), mAppRequestFrameRates.end(), mode) != mAppRequestFrameRates.end(); } void RefreshRateSelector::constructAvailableRefreshRates() { Loading Loading @@ -1211,7 +1208,7 @@ auto RefreshRateSelector::getIdleTimerAction() const -> KernelIdleTimerAction { } const DisplayModePtr& maxByPolicy = getMaxRefreshRateByPolicyLocked(getActiveModeItLocked()->second->getGroup()); getMaxRefreshRateByPolicyLocked(getActiveModeLocked().modePtr->getGroup()); if (minByPolicy == maxByPolicy) { // Turn on the timer when the min of the primary range is below the device min. if (const Policy* currentPolicy = getCurrentPolicyLocked(); Loading Loading @@ -1257,8 +1254,8 @@ void RefreshRateSelector::dump(utils::Dumper& dumper) const { std::lock_guard lock(mLock); const auto activeModeId = getActiveModeItLocked()->first; dumper.dump("activeModeId"sv, std::to_string(activeModeId.value())); const auto activeMode = getActiveModeLocked(); dumper.dump("activeMode"sv, to_string(activeMode)); dumper.dump("displayModes"sv); { Loading Loading
services/surfaceflinger/Display/DisplayModeRequest.h +3 −3 Original line number Diff line number Diff line Loading @@ -18,19 +18,19 @@ #include <ftl/non_null.h> #include "DisplayHardware/DisplayMode.h" #include <scheduler/FrameRateMode.h> namespace android::display { struct DisplayModeRequest { ftl::NonNull<DisplayModePtr> modePtr; scheduler::FrameRateMode mode; // Whether to emit DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE. bool emitEvent = false; }; inline bool operator==(const DisplayModeRequest& lhs, const DisplayModeRequest& rhs) { return lhs.modePtr == rhs.modePtr && lhs.emitEvent == rhs.emitEvent; return lhs.mode == rhs.mode && lhs.emitEvent == rhs.emitEvent; } } // namespace android::display
services/surfaceflinger/DisplayDevice.cpp +31 −25 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs& args) mCompositionDisplay{args.compositionDisplay}, mActiveModeFPSTrace("ActiveModeFPS -" + to_string(getId())), mActiveModeFPSHwcTrace("ActiveModeFPS_HWC -" + to_string(getId())), mRenderFrameRateFPSTrace("RenderRateFPS -" + to_string(getId())), mPhysicalOrientation(args.physicalOrientation), mIsPrimary(args.isPrimary), mRefreshRateSelector(std::move(args.refreshRateSelector)) { Loading Loading @@ -195,35 +196,32 @@ bool DisplayDevice::isPoweredOn() const { return mPowerMode && *mPowerMode != hal::PowerMode::OFF; } void DisplayDevice::setActiveMode(DisplayModeId modeId, const display::DisplaySnapshot& snapshot) { const auto fpsOpt = snapshot.displayModes().get(modeId).transform( [](const DisplayModePtr& mode) { return mode->getFps(); }); void DisplayDevice::setActiveMode(DisplayModeId modeId, Fps displayFps, Fps renderFps) { ATRACE_INT(mActiveModeFPSTrace.c_str(), displayFps.getIntValue()); ATRACE_INT(mRenderFrameRateFPSTrace.c_str(), renderFps.getIntValue()); LOG_ALWAYS_FATAL_IF(!fpsOpt, "Unknown mode"); const Fps fps = *fpsOpt; ATRACE_INT(mActiveModeFPSTrace.c_str(), fps.getIntValue()); mRefreshRateSelector->setActiveModeId(modeId); mRefreshRateSelector->setActiveMode(modeId, renderFps); if (mRefreshRateOverlay) { mRefreshRateOverlay->changeRefreshRate(fps); mRefreshRateOverlay->changeRefreshRate(displayFps); } } status_t DisplayDevice::initiateModeChange(const ActiveModeInfo& info, const hal::VsyncPeriodChangeConstraints& constraints, hal::VsyncPeriodChangeTimeline* outTimeline) { if (!info.mode || info.mode->getPhysicalDisplayId() != getPhysicalId()) { if (!info.modeOpt || info.modeOpt->modePtr->getPhysicalDisplayId() != getPhysicalId()) { ALOGE("Trying to initiate a mode change to invalid mode %s on display %s", info.mode ? std::to_string(info.mode->getId().value()).c_str() : "null", info.modeOpt ? std::to_string(info.modeOpt->modePtr->getId().value()).c_str() : "null", to_string(getId()).c_str()); return BAD_VALUE; } mUpcomingActiveMode = info; ATRACE_INT(mActiveModeFPSHwcTrace.c_str(), info.mode->getFps().getIntValue()); return mHwComposer.setActiveModeWithConstraints(getPhysicalId(), info.mode->getHwcId(), constraints, outTimeline); ATRACE_INT(mActiveModeFPSHwcTrace.c_str(), info.modeOpt->modePtr->getFps().getIntValue()); return mHwComposer.setActiveModeWithConstraints(getPhysicalId(), info.modeOpt->modePtr->getHwcId(), constraints, outTimeline); } nsecs_t DisplayDevice::getVsyncPeriodFromHWC() const { Loading @@ -238,7 +236,7 @@ nsecs_t DisplayDevice::getVsyncPeriodFromHWC() const { return vsyncPeriod; } return refreshRateSelector().getActiveModePtr()->getVsyncPeriod(); return refreshRateSelector().getActiveMode().modePtr->getVsyncPeriod(); } ui::Dataspace DisplayDevice::getCompositionDataSpace() const { Loading Loading @@ -422,7 +420,7 @@ void DisplayDevice::enableRefreshRateOverlay(bool enable, bool showSpinnner) { mRefreshRateOverlay = std::make_unique<RefreshRateOverlay>(fpsRange, showSpinnner); mRefreshRateOverlay->setLayerStack(getLayerStack()); mRefreshRateOverlay->setViewport(getSize()); mRefreshRateOverlay->changeRefreshRate(getActiveMode().getFps()); mRefreshRateOverlay->changeRefreshRate(getActiveMode().modePtr->getFps()); } bool DisplayDevice::onKernelTimerChanged(std::optional<DisplayModeId> desiredModeId, Loading @@ -445,13 +443,14 @@ void DisplayDevice::animateRefreshRateOverlay() { } } bool DisplayDevice::setDesiredActiveMode(const ActiveModeInfo& info) { auto DisplayDevice::setDesiredActiveMode(const ActiveModeInfo& info) -> DesiredActiveModeAction { ATRACE_CALL(); LOG_ALWAYS_FATAL_IF(!info.mode, "desired mode not provided"); LOG_ALWAYS_FATAL_IF(getPhysicalId() != info.mode->getPhysicalDisplayId(), "DisplayId mismatch"); LOG_ALWAYS_FATAL_IF(!info.modeOpt, "desired mode not provided"); LOG_ALWAYS_FATAL_IF(getPhysicalId() != info.modeOpt->modePtr->getPhysicalDisplayId(), "DisplayId mismatch"); ALOGV("%s(%s)", __func__, to_string(*info.mode).c_str()); ALOGV("%s(%s)", __func__, to_string(*info.modeOpt->modePtr).c_str()); std::scoped_lock lock(mActiveModeLock); if (mDesiredActiveModeChanged) { Loading @@ -459,18 +458,25 @@ bool DisplayDevice::setDesiredActiveMode(const ActiveModeInfo& info) { const auto prevConfig = mDesiredActiveMode.event; mDesiredActiveMode = info; mDesiredActiveMode.event = mDesiredActiveMode.event | prevConfig; return false; return DesiredActiveModeAction::None; } const auto& desiredMode = *info.modeOpt->modePtr; // Check if we are already at the desired mode if (refreshRateSelector().getActiveModePtr()->getId() == info.mode->getId()) { return false; if (refreshRateSelector().getActiveMode().modePtr->getId() == desiredMode.getId()) { if (refreshRateSelector().getActiveMode() == info.modeOpt) { return DesiredActiveModeAction::None; } setActiveMode(desiredMode.getId(), desiredMode.getFps(), info.modeOpt->fps); return DesiredActiveModeAction::InitiateRenderRateSwitch; } // Initiate a mode change. mDesiredActiveModeChanged = true; mDesiredActiveMode = info; return true; return DesiredActiveModeAction::InitiateDisplayModeSwitch; } std::optional<DisplayDevice::ActiveModeInfo> DisplayDevice::getDesiredActiveMode() const { Loading
services/surfaceflinger/DisplayDevice.h +14 −8 Original line number Diff line number Diff line Loading @@ -190,33 +190,38 @@ public: using Event = scheduler::DisplayModeEvent; ActiveModeInfo() = default; ActiveModeInfo(DisplayModePtr mode, Event event) : mode(std::move(mode)), event(event) {} ActiveModeInfo(scheduler::FrameRateMode mode, Event event) : modeOpt(std::move(mode)), event(event) {} explicit ActiveModeInfo(display::DisplayModeRequest&& request) : ActiveModeInfo(std::move(request.modePtr).take(), : ActiveModeInfo(std::move(request.mode), request.emitEvent ? Event::Changed : Event::None) {} DisplayModePtr mode; ftl::Optional<scheduler::FrameRateMode> modeOpt; Event event = Event::None; bool operator!=(const ActiveModeInfo& other) const { return mode != other.mode || event != other.event; return modeOpt != other.modeOpt || event != other.event; } }; bool setDesiredActiveMode(const ActiveModeInfo&) EXCLUDES(mActiveModeLock); enum class DesiredActiveModeAction { None, InitiateDisplayModeSwitch, InitiateRenderRateSwitch }; DesiredActiveModeAction setDesiredActiveMode(const ActiveModeInfo&) EXCLUDES(mActiveModeLock); std::optional<ActiveModeInfo> getDesiredActiveMode() const EXCLUDES(mActiveModeLock); void clearDesiredActiveModeState() EXCLUDES(mActiveModeLock); ActiveModeInfo getUpcomingActiveMode() const REQUIRES(kMainThreadContext) { return mUpcomingActiveMode; } const DisplayMode& getActiveMode() const REQUIRES(kMainThreadContext) { scheduler::FrameRateMode getActiveMode() const REQUIRES(kMainThreadContext) { return mRefreshRateSelector->getActiveMode(); } // Precondition: DisplaySnapshot must contain a mode with DisplayModeId. void setActiveMode(DisplayModeId, const display::DisplaySnapshot&) REQUIRES(kMainThreadContext); void setActiveMode(DisplayModeId, Fps displayFps, Fps renderFps); status_t initiateModeChange(const ActiveModeInfo&, const hal::VsyncPeriodChangeConstraints& constraints, Loading Loading @@ -254,6 +259,7 @@ private: std::string mDisplayName; std::string mActiveModeFPSTrace; std::string mActiveModeFPSHwcTrace; std::string mRenderFrameRateFPSTrace; const ui::Rotation mPhysicalOrientation; ui::Rotation mOrientation = ui::ROTATION_0; Loading
services/surfaceflinger/Layer.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -3597,7 +3597,7 @@ void Layer::onPostComposition(const DisplayDevice* display, } if (display) { const Fps refreshRate = display->refreshRateSelector().getActiveModePtr()->getFps(); const Fps refreshRate = display->refreshRateSelector().getActiveMode().fps; const std::optional<Fps> renderRate = mFlinger->mScheduler->getFrameRateOverride(getOwnerUid()); Loading
services/surfaceflinger/Scheduler/RefreshRateSelector.cpp +32 −35 Original line number Diff line number Diff line Loading @@ -213,7 +213,7 @@ auto RefreshRateSelector::createFrameRateModes( std::vector<FrameRateMode> frameRateModes; frameRateModes.reserve(ratesMap.size()); for (const auto& [key, mode] : ratesMap) { frameRateModes.emplace_back(FrameRateMode{key.fps, mode->second}); frameRateModes.emplace_back(FrameRateMode{key.fps, ftl::as_non_null(mode->second)}); } // We always want that the lowest frame rate will be corresponding to the Loading Loading @@ -409,7 +409,7 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi ATRACE_CALL(); ALOGV("%s: %zu layers", __func__, layers.size()); const auto& activeMode = *getActiveModeItLocked()->second; const auto& activeMode = *getActiveModeLocked().modePtr; // Keep the display at max frame rate for the duration of powering on the display. if (signals.powerOnImminent) { Loading Loading @@ -842,7 +842,7 @@ std::optional<Fps> RefreshRateSelector::onKernelTimerChanged( const DisplayModePtr& current = desiredActiveModeId ? mDisplayModes.get(*desiredActiveModeId)->get() : getActiveModeItLocked()->second; : getActiveModeLocked().modePtr.get(); const DisplayModePtr& min = mMinRefreshRateModeIt->second; if (current == min) { Loading @@ -854,11 +854,11 @@ std::optional<Fps> RefreshRateSelector::onKernelTimerChanged( } const DisplayModePtr& RefreshRateSelector::getMinRefreshRateByPolicyLocked() const { const auto& activeMode = *getActiveModeItLocked()->second; const auto& activeMode = *getActiveModeLocked().modePtr; for (const FrameRateMode& mode : mPrimaryFrameRates) { if (activeMode.getGroup() == mode.modePtr->getGroup()) { return mode.modePtr; return mode.modePtr.get(); } } Loading @@ -866,12 +866,12 @@ const DisplayModePtr& RefreshRateSelector::getMinRefreshRateByPolicyLocked() con to_string(activeMode).c_str()); // Default to the lowest refresh rate. return mPrimaryFrameRates.front().modePtr; return mPrimaryFrameRates.front().modePtr.get(); } const DisplayModePtr& RefreshRateSelector::getMaxRefreshRateByPolicyLocked(int anchorGroup) const { const DisplayModePtr* maxByAnchor = &mPrimaryFrameRates.back().modePtr; const DisplayModePtr* max = &mPrimaryFrameRates.back().modePtr; const ftl::NonNull<DisplayModePtr>* maxByAnchor = &mPrimaryFrameRates.back().modePtr; const ftl::NonNull<DisplayModePtr>* max = &mPrimaryFrameRates.back().modePtr; bool maxByAnchorFound = false; for (auto it = mPrimaryFrameRates.rbegin(); it != mPrimaryFrameRates.rend(); ++it) { Loading @@ -888,13 +888,13 @@ const DisplayModePtr& RefreshRateSelector::getMaxRefreshRateByPolicyLocked(int a } if (maxByAnchorFound) { return *maxByAnchor; return maxByAnchor->get(); } ALOGE("Can't find max refresh rate by policy with the same group %d", anchorGroup); // Default to the highest refresh rate. return *max; return max->get(); } auto RefreshRateSelector::rankFrameRates(std::optional<int> anchorGroupOpt, Loading Loading @@ -946,31 +946,26 @@ auto RefreshRateSelector::rankFrameRates(std::optional<int> anchorGroupOpt, return rankFrameRates(kNoAnchorGroup, refreshRateOrder, preferredDisplayModeOpt); } DisplayModePtr RefreshRateSelector::getActiveModePtr() const { FrameRateMode RefreshRateSelector::getActiveMode() const { std::lock_guard lock(mLock); return getActiveModeItLocked()->second; return getActiveModeLocked(); } const DisplayMode& RefreshRateSelector::getActiveMode() const { // Reads from kMainThreadContext do not require mLock. ftl::FakeGuard guard(mLock); return *mActiveModeIt->second; } DisplayModeIterator RefreshRateSelector::getActiveModeItLocked() const { // Reads under mLock do not require kMainThreadContext. return FTL_FAKE_GUARD(kMainThreadContext, mActiveModeIt); const FrameRateMode& RefreshRateSelector::getActiveModeLocked() const { return *mActiveModeOpt; } void RefreshRateSelector::setActiveModeId(DisplayModeId modeId) { void RefreshRateSelector::setActiveMode(DisplayModeId modeId, Fps renderFrameRate) { std::lock_guard lock(mLock); // Invalidate the cached invocation to getRankedFrameRates. This forces // the refresh rate to be recomputed on the next call to getRankedFrameRates. mGetRankedFrameRatesCache.reset(); mActiveModeIt = mDisplayModes.find(modeId); LOG_ALWAYS_FATAL_IF(mActiveModeIt == mDisplayModes.end()); const auto activeModeOpt = mDisplayModes.get(modeId); LOG_ALWAYS_FATAL_IF(!activeModeOpt); mActiveModeOpt.emplace(FrameRateMode{renderFrameRate, ftl::as_non_null(activeModeOpt->get())}); } RefreshRateSelector::RefreshRateSelector(DisplayModes modes, DisplayModeId activeModeId, Loading Loading @@ -1007,8 +1002,10 @@ void RefreshRateSelector::updateDisplayModes(DisplayModes modes, DisplayModeId a mGetRankedFrameRatesCache.reset(); mDisplayModes = std::move(modes); mActiveModeIt = mDisplayModes.find(activeModeId); LOG_ALWAYS_FATAL_IF(mActiveModeIt == mDisplayModes.end()); const auto activeModeOpt = mDisplayModes.get(activeModeId); LOG_ALWAYS_FATAL_IF(!activeModeOpt); mActiveModeOpt = FrameRateMode{activeModeOpt->get()->getFps(), ftl::as_non_null(activeModeOpt->get())}; const auto sortedModes = sortByRefreshRate(mDisplayModes); mMinRefreshRateModeIt = sortedModes.front(); Loading Loading @@ -1064,6 +1061,7 @@ bool RefreshRateSelector::isPolicyValidLocked(const Policy& policy) const { auto RefreshRateSelector::setPolicy(const PolicyVariant& policy) -> SetPolicyResult { Policy oldPolicy; PhysicalDisplayId displayId; { std::lock_guard lock(mLock); oldPolicy = *getCurrentPolicyLocked(); Loading Loading @@ -1103,9 +1101,10 @@ auto RefreshRateSelector::setPolicy(const PolicyVariant& policy) -> SetPolicyRes return SetPolicyResult::Unchanged; } constructAvailableRefreshRates(); displayId = getActiveModeLocked().modePtr->getPhysicalDisplayId(); } const auto displayId = getActiveMode().getPhysicalDisplayId(); const unsigned numModeChanges = std::exchange(mNumModeSwitchesInPolicy, 0u); ALOGI("Display %s policy changed\n" Loading @@ -1132,12 +1131,10 @@ auto RefreshRateSelector::getDisplayManagerPolicy() const -> Policy { return mDisplayManagerPolicy; } bool RefreshRateSelector::isModeAllowed(DisplayModeId modeId) const { bool RefreshRateSelector::isModeAllowed(const FrameRateMode& mode) const { std::lock_guard lock(mLock); return std::any_of(mAppRequestFrameRates.begin(), mAppRequestFrameRates.end(), [modeId](const FrameRateMode& frameRateMode) { return frameRateMode.modePtr->getId() == modeId; }); return std::find(mAppRequestFrameRates.begin(), mAppRequestFrameRates.end(), mode) != mAppRequestFrameRates.end(); } void RefreshRateSelector::constructAvailableRefreshRates() { Loading Loading @@ -1211,7 +1208,7 @@ auto RefreshRateSelector::getIdleTimerAction() const -> KernelIdleTimerAction { } const DisplayModePtr& maxByPolicy = getMaxRefreshRateByPolicyLocked(getActiveModeItLocked()->second->getGroup()); getMaxRefreshRateByPolicyLocked(getActiveModeLocked().modePtr->getGroup()); if (minByPolicy == maxByPolicy) { // Turn on the timer when the min of the primary range is below the device min. if (const Policy* currentPolicy = getCurrentPolicyLocked(); Loading Loading @@ -1257,8 +1254,8 @@ void RefreshRateSelector::dump(utils::Dumper& dumper) const { std::lock_guard lock(mLock); const auto activeModeId = getActiveModeItLocked()->first; dumper.dump("activeModeId"sv, std::to_string(activeModeId.value())); const auto activeMode = getActiveModeLocked(); dumper.dump("activeMode"sv, to_string(activeMode)); dumper.dump("displayModes"sv); { Loading