Loading services/surfaceflinger/Display/DisplayModeRequest.h +3 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,9 @@ struct DisplayModeRequest { // Whether to emit DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE. bool emitEvent = false; // Whether to force the request to be applied, even if the mode is unchanged. bool force = false; }; inline bool operator==(const DisplayModeRequest& lhs, const DisplayModeRequest& rhs) { Loading services/surfaceflinger/DisplayDevice.cpp +21 −4 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #define ATRACE_TAG ATRACE_TAG_GRAPHICS #include <common/FlagManager.h> #include <compositionengine/CompositionEngine.h> #include <compositionengine/Display.h> #include <compositionengine/DisplayColorProfile.h> Loading Loading @@ -214,6 +215,17 @@ void DisplayDevice::setActiveMode(DisplayModeId modeId, Fps vsyncRate, Fps rende bool DisplayDevice::initiateModeChange(display::DisplayModeRequest&& desiredMode, const hal::VsyncPeriodChangeConstraints& constraints, hal::VsyncPeriodChangeTimeline& outTimeline) { // TODO(b/255635711): Flow the DisplayModeRequest through the desired/pending/active states. For // now, `desiredMode` and `mDesiredModeOpt` are one and the same, but the latter is not cleared // until the next `SF::initiateDisplayModeChanges`. However, the desired mode has been consumed // at this point, so clear the `force` flag to prevent an endless loop of `initiateModeChange`. if (FlagManager::getInstance().connected_display()) { std::scoped_lock lock(mDesiredModeLock); if (mDesiredModeOpt) { mDesiredModeOpt->force = false; } } mPendingModeOpt = std::move(desiredMode); mIsModeSetPending = true; Loading Loading @@ -517,8 +529,7 @@ void DisplayDevice::animateOverlay() { } } auto DisplayDevice::setDesiredMode(display::DisplayModeRequest&& desiredMode, bool force) -> DesiredModeAction { auto DisplayDevice::setDesiredMode(display::DisplayModeRequest&& desiredMode) -> DesiredModeAction { ATRACE_CALL(); const auto& desiredModePtr = desiredMode.mode.modePtr; Loading @@ -526,20 +537,26 @@ auto DisplayDevice::setDesiredMode(display::DisplayModeRequest&& desiredMode, bo LOG_ALWAYS_FATAL_IF(getPhysicalId() != desiredModePtr->getPhysicalDisplayId(), "DisplayId mismatch"); ALOGV("%s(%s)", __func__, to_string(*desiredModePtr).c_str()); // TODO (b/318533819): Stringize DisplayModeRequest. ALOGD("%s(%s, force=%s)", __func__, to_string(*desiredModePtr).c_str(), desiredMode.force ? "true" : "false"); std::scoped_lock lock(mDesiredModeLock); if (mDesiredModeOpt) { // A mode transition was already scheduled, so just override the desired mode. const bool emitEvent = mDesiredModeOpt->emitEvent; const bool force = mDesiredModeOpt->force; mDesiredModeOpt = std::move(desiredMode); mDesiredModeOpt->emitEvent |= emitEvent; if (FlagManager::getInstance().connected_display()) { mDesiredModeOpt->force |= force; } return DesiredModeAction::None; } // If the desired mode is already active... const auto activeMode = refreshRateSelector().getActiveMode(); if (!force && activeMode.modePtr->getId() == desiredModePtr->getId()) { if (!desiredMode.force && activeMode.modePtr->getId() == desiredModePtr->getId()) { if (activeMode == desiredMode.mode) { return DesiredModeAction::None; } Loading services/surfaceflinger/DisplayDevice.h +1 −2 Original line number Diff line number Diff line Loading @@ -189,8 +189,7 @@ public: enum class DesiredModeAction { None, InitiateDisplayModeSwitch, InitiateRenderRateSwitch }; DesiredModeAction setDesiredMode(display::DisplayModeRequest&&, bool force = false) EXCLUDES(mDesiredModeLock); DesiredModeAction setDesiredMode(display::DisplayModeRequest&&) EXCLUDES(mDesiredModeLock); using DisplayModeRequestOpt = ftl::Optional<display::DisplayModeRequest>; Loading services/surfaceflinger/DisplayHardware/HWC2.cpp +14 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include "HWC2.h" #include <android/configuration.h> #include <common/FlagManager.h> #include <ui/Fence.h> #include <ui/FloatRect.h> #include <ui/GraphicBuffer.h> Loading Loading @@ -416,7 +417,19 @@ Error Display::setActiveConfigWithConstraints(hal::HWConfigId configId, VsyncPeriodChangeTimeline* outTimeline) { ALOGV("[%" PRIu64 "] setActiveConfigWithConstraints", mId); if (isVsyncPeriodSwitchSupported()) { // FIXME (b/319505580): At least the first config set on an external display must be // `setActiveConfig`, so skip over the block that calls `setActiveConfigWithConstraints` // for simplicity. ui::DisplayConnectionType type = ui::DisplayConnectionType::Internal; const bool connected_display = FlagManager::getInstance().connected_display(); if (connected_display) { // Do not bail out on error, since the underlying API may return UNSUPPORTED on older HWCs. // TODO: b/323905961 - Remove this AIDL call. getConnectionType(&type); } if (isVsyncPeriodSwitchSupported() && (!connected_display || type != ui::DisplayConnectionType::External)) { Hwc2::IComposerClient::VsyncPeriodChangeConstraints hwc2Constraints; hwc2Constraints.desiredTimeNanos = constraints.desiredTimeNanos; hwc2Constraints.seamlessRequired = constraints.seamlessRequired; Loading services/surfaceflinger/SurfaceFlinger.cpp +110 −8 Original line number Diff line number Diff line Loading @@ -1230,8 +1230,10 @@ status_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& displayToken, return NO_ERROR; } void SurfaceFlinger::setDesiredMode(display::DisplayModeRequest&& request, bool force) { const auto displayId = request.mode.modePtr->getPhysicalDisplayId(); void SurfaceFlinger::setDesiredMode(display::DisplayModeRequest&& desiredMode) { const auto mode = desiredMode.mode; const auto displayId = mode.modePtr->getPhysicalDisplayId(); ATRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str()); const auto display = getDisplayDeviceLocked(displayId); Loading @@ -1240,10 +1242,9 @@ void SurfaceFlinger::setDesiredMode(display::DisplayModeRequest&& request, bool return; } const auto mode = request.mode; const bool emitEvent = request.emitEvent; const bool emitEvent = desiredMode.emitEvent; switch (display->setDesiredMode(std::move(request), force)) { switch (display->setDesiredMode(std::move(desiredMode))) { case DisplayDevice::DesiredModeAction::InitiateDisplayModeSwitch: // DisplayDevice::setDesiredMode updated the render rate, so inform Scheduler. mScheduler->setRenderRate(displayId, Loading Loading @@ -1429,7 +1430,8 @@ void SurfaceFlinger::initiateDisplayModeChanges() { to_string(displayModePtrOpt->get()->getVsyncRate()).c_str(), to_string(display->getId()).c_str()); if (display->getActiveMode() == desiredModeOpt->mode) { if ((!FlagManager::getInstance().connected_display() || !desiredModeOpt->force) && display->getActiveMode() == desiredModeOpt->mode) { applyActiveMode(display); continue; } Loading Loading @@ -3284,13 +3286,88 @@ std::pair<DisplayModes, DisplayModePtr> SurfaceFlinger::loadDisplayModes( std::vector<HWComposer::HWCDisplayMode> hwcModes; std::optional<hal::HWConfigId> activeModeHwcIdOpt; const bool isExternalDisplay = FlagManager::getInstance().connected_display() && getHwComposer().getDisplayConnectionType(displayId) == ui::DisplayConnectionType::External; int attempt = 0; constexpr int kMaxAttempts = 3; do { hwcModes = getHwComposer().getModes(displayId, scheduler::RefreshRateSelector::kMinSupportedFrameRate .getPeriodNsecs()); activeModeHwcIdOpt = getHwComposer().getActiveMode(displayId).value_opt(); const auto activeModeHwcIdExp = getHwComposer().getActiveMode(displayId); activeModeHwcIdOpt = activeModeHwcIdExp.value_opt(); if (isExternalDisplay && activeModeHwcIdExp.has_error([](status_t error) { return error == NO_INIT; })) { constexpr nsecs_t k59HzVsyncPeriod = 16949153; constexpr nsecs_t k60HzVsyncPeriod = 16666667; // DM sets the initial mode for an external display to 1080p@60, but // this comes after SF creates its own state (including the // DisplayDevice). For now, pick the same mode in order to avoid // inconsistent state and unnecessary mode switching. // TODO (b/318534874): Let DM decide the initial mode. // // Try to find 1920x1080 @ 60 Hz if (const auto iter = std::find_if(hwcModes.begin(), hwcModes.end(), [](const auto& mode) { return mode.width == 1920 && mode.height == 1080 && mode.vsyncPeriod == k60HzVsyncPeriod; }); iter != hwcModes.end()) { activeModeHwcIdOpt = iter->hwcId; break; } // Try to find 1920x1080 @ 59-60 Hz if (const auto iter = std::find_if(hwcModes.begin(), hwcModes.end(), [](const auto& mode) { return mode.width == 1920 && mode.height == 1080 && mode.vsyncPeriod >= k60HzVsyncPeriod && mode.vsyncPeriod <= k59HzVsyncPeriod; }); iter != hwcModes.end()) { activeModeHwcIdOpt = iter->hwcId; break; } // The display does not support 1080p@60, and this is the last attempt to pick a display // mode. Prefer 60 Hz if available, with the closest resolution to 1080p. if (attempt + 1 == kMaxAttempts) { std::vector<HWComposer::HWCDisplayMode> hwcModeOpts; for (const auto& mode : hwcModes) { if (mode.width <= 1920 && mode.height <= 1080 && mode.vsyncPeriod >= k60HzVsyncPeriod && mode.vsyncPeriod <= k59HzVsyncPeriod) { hwcModeOpts.push_back(mode); } } if (const auto iter = std::max_element(hwcModeOpts.begin(), hwcModeOpts.end(), [](const auto& a, const auto& b) { const auto aSize = a.width * a.height; const auto bSize = b.width * b.height; if (aSize < bSize) return true; else if (aSize == bSize) return a.vsyncPeriod > b.vsyncPeriod; else return false; }); iter != hwcModeOpts.end()) { activeModeHwcIdOpt = iter->hwcId; break; } // hwcModeOpts was empty, use hwcModes[0] as the last resort activeModeHwcIdOpt = hwcModes[0].hwcId; } } const auto isActiveMode = [activeModeHwcIdOpt](const HWComposer::HWCDisplayMode& mode) { return mode.hwcId == activeModeHwcIdOpt; Loading Loading @@ -3351,6 +3428,10 @@ std::pair<DisplayModes, DisplayModePtr> SurfaceFlinger::loadDisplayModes( return pair.second->getHwcId() == activeModeHwcIdOpt; })->second; if (isExternalDisplay) { ALOGI("External display %s initial mode: {%s}", to_string(displayId).c_str(), to_string(*activeMode).c_str()); } return {modes, activeMode}; } Loading Loading @@ -3659,6 +3740,27 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken, } mDisplays.try_emplace(displayToken, std::move(display)); // For an external display, loadDisplayModes already attempted to select the same mode // as DM, but SF still needs to be updated to match. // TODO (b/318534874): Let DM decide the initial mode. if (const auto& physical = state.physical; mScheduler && physical && FlagManager::getInstance().connected_display()) { const bool isInternalDisplay = mPhysicalDisplays.get(physical->id) .transform(&PhysicalDisplay::isInternal) .value_or(false); if (!isInternalDisplay) { auto activeModePtr = physical->activeMode; const auto fps = activeModePtr->getPeakFps(); setDesiredMode( {.mode = scheduler::FrameRateMode{fps, ftl::as_non_null(std::move(activeModePtr))}, .emitEvent = false, .force = true}); } } } void SurfaceFlinger::processDisplayRemoved(const wp<IBinder>& displayToken) { Loading Loading @@ -8383,7 +8485,7 @@ status_t SurfaceFlinger::applyRefreshRateSelectorPolicy( return INVALID_OPERATION; } setDesiredMode({std::move(preferredMode), .emitEvent = true}, force); setDesiredMode({std::move(preferredMode), .emitEvent = true, .force = force}); // Update the frameRateOverride list as the display render rate might have changed if (mScheduler->updateFrameRateOverrides(scheduler::GlobalSignals{}, preferredFps)) { Loading Loading
services/surfaceflinger/Display/DisplayModeRequest.h +3 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,9 @@ struct DisplayModeRequest { // Whether to emit DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE. bool emitEvent = false; // Whether to force the request to be applied, even if the mode is unchanged. bool force = false; }; inline bool operator==(const DisplayModeRequest& lhs, const DisplayModeRequest& rhs) { Loading
services/surfaceflinger/DisplayDevice.cpp +21 −4 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #define ATRACE_TAG ATRACE_TAG_GRAPHICS #include <common/FlagManager.h> #include <compositionengine/CompositionEngine.h> #include <compositionengine/Display.h> #include <compositionengine/DisplayColorProfile.h> Loading Loading @@ -214,6 +215,17 @@ void DisplayDevice::setActiveMode(DisplayModeId modeId, Fps vsyncRate, Fps rende bool DisplayDevice::initiateModeChange(display::DisplayModeRequest&& desiredMode, const hal::VsyncPeriodChangeConstraints& constraints, hal::VsyncPeriodChangeTimeline& outTimeline) { // TODO(b/255635711): Flow the DisplayModeRequest through the desired/pending/active states. For // now, `desiredMode` and `mDesiredModeOpt` are one and the same, but the latter is not cleared // until the next `SF::initiateDisplayModeChanges`. However, the desired mode has been consumed // at this point, so clear the `force` flag to prevent an endless loop of `initiateModeChange`. if (FlagManager::getInstance().connected_display()) { std::scoped_lock lock(mDesiredModeLock); if (mDesiredModeOpt) { mDesiredModeOpt->force = false; } } mPendingModeOpt = std::move(desiredMode); mIsModeSetPending = true; Loading Loading @@ -517,8 +529,7 @@ void DisplayDevice::animateOverlay() { } } auto DisplayDevice::setDesiredMode(display::DisplayModeRequest&& desiredMode, bool force) -> DesiredModeAction { auto DisplayDevice::setDesiredMode(display::DisplayModeRequest&& desiredMode) -> DesiredModeAction { ATRACE_CALL(); const auto& desiredModePtr = desiredMode.mode.modePtr; Loading @@ -526,20 +537,26 @@ auto DisplayDevice::setDesiredMode(display::DisplayModeRequest&& desiredMode, bo LOG_ALWAYS_FATAL_IF(getPhysicalId() != desiredModePtr->getPhysicalDisplayId(), "DisplayId mismatch"); ALOGV("%s(%s)", __func__, to_string(*desiredModePtr).c_str()); // TODO (b/318533819): Stringize DisplayModeRequest. ALOGD("%s(%s, force=%s)", __func__, to_string(*desiredModePtr).c_str(), desiredMode.force ? "true" : "false"); std::scoped_lock lock(mDesiredModeLock); if (mDesiredModeOpt) { // A mode transition was already scheduled, so just override the desired mode. const bool emitEvent = mDesiredModeOpt->emitEvent; const bool force = mDesiredModeOpt->force; mDesiredModeOpt = std::move(desiredMode); mDesiredModeOpt->emitEvent |= emitEvent; if (FlagManager::getInstance().connected_display()) { mDesiredModeOpt->force |= force; } return DesiredModeAction::None; } // If the desired mode is already active... const auto activeMode = refreshRateSelector().getActiveMode(); if (!force && activeMode.modePtr->getId() == desiredModePtr->getId()) { if (!desiredMode.force && activeMode.modePtr->getId() == desiredModePtr->getId()) { if (activeMode == desiredMode.mode) { return DesiredModeAction::None; } Loading
services/surfaceflinger/DisplayDevice.h +1 −2 Original line number Diff line number Diff line Loading @@ -189,8 +189,7 @@ public: enum class DesiredModeAction { None, InitiateDisplayModeSwitch, InitiateRenderRateSwitch }; DesiredModeAction setDesiredMode(display::DisplayModeRequest&&, bool force = false) EXCLUDES(mDesiredModeLock); DesiredModeAction setDesiredMode(display::DisplayModeRequest&&) EXCLUDES(mDesiredModeLock); using DisplayModeRequestOpt = ftl::Optional<display::DisplayModeRequest>; Loading
services/surfaceflinger/DisplayHardware/HWC2.cpp +14 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include "HWC2.h" #include <android/configuration.h> #include <common/FlagManager.h> #include <ui/Fence.h> #include <ui/FloatRect.h> #include <ui/GraphicBuffer.h> Loading Loading @@ -416,7 +417,19 @@ Error Display::setActiveConfigWithConstraints(hal::HWConfigId configId, VsyncPeriodChangeTimeline* outTimeline) { ALOGV("[%" PRIu64 "] setActiveConfigWithConstraints", mId); if (isVsyncPeriodSwitchSupported()) { // FIXME (b/319505580): At least the first config set on an external display must be // `setActiveConfig`, so skip over the block that calls `setActiveConfigWithConstraints` // for simplicity. ui::DisplayConnectionType type = ui::DisplayConnectionType::Internal; const bool connected_display = FlagManager::getInstance().connected_display(); if (connected_display) { // Do not bail out on error, since the underlying API may return UNSUPPORTED on older HWCs. // TODO: b/323905961 - Remove this AIDL call. getConnectionType(&type); } if (isVsyncPeriodSwitchSupported() && (!connected_display || type != ui::DisplayConnectionType::External)) { Hwc2::IComposerClient::VsyncPeriodChangeConstraints hwc2Constraints; hwc2Constraints.desiredTimeNanos = constraints.desiredTimeNanos; hwc2Constraints.seamlessRequired = constraints.seamlessRequired; Loading
services/surfaceflinger/SurfaceFlinger.cpp +110 −8 Original line number Diff line number Diff line Loading @@ -1230,8 +1230,10 @@ status_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& displayToken, return NO_ERROR; } void SurfaceFlinger::setDesiredMode(display::DisplayModeRequest&& request, bool force) { const auto displayId = request.mode.modePtr->getPhysicalDisplayId(); void SurfaceFlinger::setDesiredMode(display::DisplayModeRequest&& desiredMode) { const auto mode = desiredMode.mode; const auto displayId = mode.modePtr->getPhysicalDisplayId(); ATRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str()); const auto display = getDisplayDeviceLocked(displayId); Loading @@ -1240,10 +1242,9 @@ void SurfaceFlinger::setDesiredMode(display::DisplayModeRequest&& request, bool return; } const auto mode = request.mode; const bool emitEvent = request.emitEvent; const bool emitEvent = desiredMode.emitEvent; switch (display->setDesiredMode(std::move(request), force)) { switch (display->setDesiredMode(std::move(desiredMode))) { case DisplayDevice::DesiredModeAction::InitiateDisplayModeSwitch: // DisplayDevice::setDesiredMode updated the render rate, so inform Scheduler. mScheduler->setRenderRate(displayId, Loading Loading @@ -1429,7 +1430,8 @@ void SurfaceFlinger::initiateDisplayModeChanges() { to_string(displayModePtrOpt->get()->getVsyncRate()).c_str(), to_string(display->getId()).c_str()); if (display->getActiveMode() == desiredModeOpt->mode) { if ((!FlagManager::getInstance().connected_display() || !desiredModeOpt->force) && display->getActiveMode() == desiredModeOpt->mode) { applyActiveMode(display); continue; } Loading Loading @@ -3284,13 +3286,88 @@ std::pair<DisplayModes, DisplayModePtr> SurfaceFlinger::loadDisplayModes( std::vector<HWComposer::HWCDisplayMode> hwcModes; std::optional<hal::HWConfigId> activeModeHwcIdOpt; const bool isExternalDisplay = FlagManager::getInstance().connected_display() && getHwComposer().getDisplayConnectionType(displayId) == ui::DisplayConnectionType::External; int attempt = 0; constexpr int kMaxAttempts = 3; do { hwcModes = getHwComposer().getModes(displayId, scheduler::RefreshRateSelector::kMinSupportedFrameRate .getPeriodNsecs()); activeModeHwcIdOpt = getHwComposer().getActiveMode(displayId).value_opt(); const auto activeModeHwcIdExp = getHwComposer().getActiveMode(displayId); activeModeHwcIdOpt = activeModeHwcIdExp.value_opt(); if (isExternalDisplay && activeModeHwcIdExp.has_error([](status_t error) { return error == NO_INIT; })) { constexpr nsecs_t k59HzVsyncPeriod = 16949153; constexpr nsecs_t k60HzVsyncPeriod = 16666667; // DM sets the initial mode for an external display to 1080p@60, but // this comes after SF creates its own state (including the // DisplayDevice). For now, pick the same mode in order to avoid // inconsistent state and unnecessary mode switching. // TODO (b/318534874): Let DM decide the initial mode. // // Try to find 1920x1080 @ 60 Hz if (const auto iter = std::find_if(hwcModes.begin(), hwcModes.end(), [](const auto& mode) { return mode.width == 1920 && mode.height == 1080 && mode.vsyncPeriod == k60HzVsyncPeriod; }); iter != hwcModes.end()) { activeModeHwcIdOpt = iter->hwcId; break; } // Try to find 1920x1080 @ 59-60 Hz if (const auto iter = std::find_if(hwcModes.begin(), hwcModes.end(), [](const auto& mode) { return mode.width == 1920 && mode.height == 1080 && mode.vsyncPeriod >= k60HzVsyncPeriod && mode.vsyncPeriod <= k59HzVsyncPeriod; }); iter != hwcModes.end()) { activeModeHwcIdOpt = iter->hwcId; break; } // The display does not support 1080p@60, and this is the last attempt to pick a display // mode. Prefer 60 Hz if available, with the closest resolution to 1080p. if (attempt + 1 == kMaxAttempts) { std::vector<HWComposer::HWCDisplayMode> hwcModeOpts; for (const auto& mode : hwcModes) { if (mode.width <= 1920 && mode.height <= 1080 && mode.vsyncPeriod >= k60HzVsyncPeriod && mode.vsyncPeriod <= k59HzVsyncPeriod) { hwcModeOpts.push_back(mode); } } if (const auto iter = std::max_element(hwcModeOpts.begin(), hwcModeOpts.end(), [](const auto& a, const auto& b) { const auto aSize = a.width * a.height; const auto bSize = b.width * b.height; if (aSize < bSize) return true; else if (aSize == bSize) return a.vsyncPeriod > b.vsyncPeriod; else return false; }); iter != hwcModeOpts.end()) { activeModeHwcIdOpt = iter->hwcId; break; } // hwcModeOpts was empty, use hwcModes[0] as the last resort activeModeHwcIdOpt = hwcModes[0].hwcId; } } const auto isActiveMode = [activeModeHwcIdOpt](const HWComposer::HWCDisplayMode& mode) { return mode.hwcId == activeModeHwcIdOpt; Loading Loading @@ -3351,6 +3428,10 @@ std::pair<DisplayModes, DisplayModePtr> SurfaceFlinger::loadDisplayModes( return pair.second->getHwcId() == activeModeHwcIdOpt; })->second; if (isExternalDisplay) { ALOGI("External display %s initial mode: {%s}", to_string(displayId).c_str(), to_string(*activeMode).c_str()); } return {modes, activeMode}; } Loading Loading @@ -3659,6 +3740,27 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken, } mDisplays.try_emplace(displayToken, std::move(display)); // For an external display, loadDisplayModes already attempted to select the same mode // as DM, but SF still needs to be updated to match. // TODO (b/318534874): Let DM decide the initial mode. if (const auto& physical = state.physical; mScheduler && physical && FlagManager::getInstance().connected_display()) { const bool isInternalDisplay = mPhysicalDisplays.get(physical->id) .transform(&PhysicalDisplay::isInternal) .value_or(false); if (!isInternalDisplay) { auto activeModePtr = physical->activeMode; const auto fps = activeModePtr->getPeakFps(); setDesiredMode( {.mode = scheduler::FrameRateMode{fps, ftl::as_non_null(std::move(activeModePtr))}, .emitEvent = false, .force = true}); } } } void SurfaceFlinger::processDisplayRemoved(const wp<IBinder>& displayToken) { Loading Loading @@ -8383,7 +8485,7 @@ status_t SurfaceFlinger::applyRefreshRateSelectorPolicy( return INVALID_OPERATION; } setDesiredMode({std::move(preferredMode), .emitEvent = true}, force); setDesiredMode({std::move(preferredMode), .emitEvent = true, .force = force}); // Update the frameRateOverride list as the display render rate might have changed if (mScheduler->updateFrameRateOverrides(scheduler::GlobalSignals{}, preferredFps)) { Loading