Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7d089caa authored by Dominik Laskowski's avatar Dominik Laskowski Committed by Android (Google) Code Review
Browse files

Merge "SF: Fix display mode transitions for multi-display"

parents 39a3197b fc378b0b
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -452,7 +452,8 @@ void DisplayDevice::animateRefreshRateOverlay() {
    }
}

auto DisplayDevice::setDesiredActiveMode(const ActiveModeInfo& info) -> DesiredActiveModeAction {
auto DisplayDevice::setDesiredActiveMode(const ActiveModeInfo& info, bool force)
        -> DesiredActiveModeAction {
    ATRACE_CALL();

    LOG_ALWAYS_FATAL_IF(!info.modeOpt, "desired mode not provided");
@@ -473,7 +474,7 @@ auto DisplayDevice::setDesiredActiveMode(const ActiveModeInfo& info) -> DesiredA
    const auto& desiredMode = *info.modeOpt->modePtr;

    // Check if we are already at the desired mode
    if (refreshRateSelector().getActiveMode().modePtr->getId() == desiredMode.getId()) {
    if (!force && refreshRateSelector().getActiveMode().modePtr->getId() == desiredMode.getId()) {
        if (refreshRateSelector().getActiveMode() == info.modeOpt) {
            return DesiredActiveModeAction::None;
        }
+2 −1
Original line number Diff line number Diff line
@@ -210,7 +210,8 @@ public:
        InitiateDisplayModeSwitch,
        InitiateRenderRateSwitch
    };
    DesiredActiveModeAction setDesiredActiveMode(const ActiveModeInfo&) EXCLUDES(mActiveModeLock);
    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) {
+9 −9
Original line number Diff line number Diff line
@@ -815,18 +815,18 @@ GlobalSignals Scheduler::makeGlobalSignals() const {
            .powerOnImminent = powerOnImminent};
}

ftl::Optional<FrameRateMode> Scheduler::getPreferredDisplayMode() {
FrameRateMode Scheduler::getPreferredDisplayMode() {
    std::lock_guard<std::mutex> lock(mPolicyLock);
    // Make sure the stored mode is up to date.
    if (mPolicy.modeOpt) {
        const auto ranking =
    const auto frameRateMode =
            leaderSelectorPtr()
                    ->getRankedFrameRates(mPolicy.contentRequirements, makeGlobalSignals())
                        .ranking;
                    .ranking.front()
                    .frameRateMode;

        mPolicy.modeOpt = ranking.front().frameRateMode;
    }
    return mPolicy.modeOpt;
    // Make sure the stored mode is up to date.
    mPolicy.modeOpt = frameRateMode;

    return frameRateMode;
}

void Scheduler::onNewVsyncPeriodChangeTimeline(const hal::VsyncPeriodChangeTimeline& timeline) {
+2 −2
Original line number Diff line number Diff line
@@ -209,8 +209,8 @@ public:
    void dump(ConnectionHandle, std::string&) const;
    void dumpVsync(std::string&) const;

    // Get the appropriate refresh for current conditions.
    ftl::Optional<FrameRateMode> getPreferredDisplayMode();
    // Returns the preferred refresh rate and frame rate for the leader display.
    FrameRateMode getPreferredDisplayMode();

    // Notifies the scheduler about a refresh rate timeline change.
    void onNewVsyncPeriodChangeTimeline(const hal::VsyncPeriodChangeTimeline& timeline);
+33 −8
Original line number Diff line number Diff line
@@ -1132,7 +1132,7 @@ status_t SurfaceFlinger::getDisplayStats(const sp<IBinder>&, DisplayStatInfo* ou
    return NO_ERROR;
}

void SurfaceFlinger::setDesiredActiveMode(display::DisplayModeRequest&& request) {
void SurfaceFlinger::setDesiredActiveMode(display::DisplayModeRequest&& request, bool force) {
    ATRACE_CALL();

    auto display = getDisplayDeviceLocked(request.mode.modePtr->getPhysicalDisplayId());
@@ -1144,7 +1144,8 @@ void SurfaceFlinger::setDesiredActiveMode(display::DisplayModeRequest&& request)
    const auto mode = request.mode;
    const bool emitEvent = request.emitEvent;

    switch (display->setDesiredActiveMode(DisplayDevice::ActiveModeInfo(std::move(request)))) {
    switch (display->setDesiredActiveMode(DisplayDevice::ActiveModeInfo(std::move(request)),
                                          force)) {
        case DisplayDevice::DesiredActiveModeAction::InitiateDisplayModeSwitch:
            scheduleComposite(FrameHint::kNone);

@@ -3457,10 +3458,21 @@ void SurfaceFlinger::requestDisplayModes(std::vector<display::DisplayModeRequest

    for (auto& request : modeRequests) {
        const auto& modePtr = request.mode.modePtr;
        const auto display = getDisplayDeviceLocked(modePtr->getPhysicalDisplayId());

        const auto displayId = modePtr->getPhysicalDisplayId();
        const auto display = getDisplayDeviceLocked(displayId);

        if (!display) continue;

        const bool isInternalDisplay = mPhysicalDisplays.get(displayId)
                                               .transform(&PhysicalDisplay::isInternal)
                                               .value_or(false);

        if (isInternalDisplay && displayId != mActiveDisplayId) {
            ALOGV("%s(%s): Inactive display", __func__, to_string(displayId).c_str());
            continue;
        }

        if (display->refreshRateSelector().isModeAllowed(request.mode)) {
            setDesiredActiveMode(std::move(request));
        } else {
@@ -6725,7 +6737,7 @@ void SurfaceFlinger::traverseLayersInLayerStack(ui::LayerStack layerStack, const
ftl::Optional<scheduler::FrameRateMode> SurfaceFlinger::getPreferredDisplayMode(
        PhysicalDisplayId displayId, DisplayModeId defaultModeId) const {
    if (const auto schedulerMode = mScheduler->getPreferredDisplayMode();
        schedulerMode && schedulerMode->modePtr->getPhysicalDisplayId() == displayId) {
        schedulerMode.modePtr->getPhysicalDisplayId() == displayId) {
        return schedulerMode;
    }

@@ -6760,12 +6772,24 @@ status_t SurfaceFlinger::setDesiredDisplayModeSpecsInternal(
        case SetPolicyResult::Unchanged:
            return NO_ERROR;
        case SetPolicyResult::Changed:
            return applyRefreshRateSelectorPolicy(displayId, selector);
            break;
    }

    const bool isInternalDisplay = mPhysicalDisplays.get(displayId)
                                           .transform(&PhysicalDisplay::isInternal)
                                           .value_or(false);

    if (isInternalDisplay && displayId != mActiveDisplayId) {
        // The policy will be be applied when the display becomes active.
        ALOGV("%s(%s): Inactive display", __func__, to_string(displayId).c_str());
        return NO_ERROR;
    }

    return applyRefreshRateSelectorPolicy(displayId, selector);
}

status_t SurfaceFlinger::applyRefreshRateSelectorPolicy(
        PhysicalDisplayId displayId, const scheduler::RefreshRateSelector& selector) {
        PhysicalDisplayId displayId, const scheduler::RefreshRateSelector& selector, bool force) {
    const scheduler::RefreshRateSelector::Policy currentPolicy = selector.getCurrentPolicy();
    ALOGV("Setting desired display mode specs: %s", currentPolicy.toString().c_str());

@@ -6795,7 +6819,7 @@ status_t SurfaceFlinger::applyRefreshRateSelectorPolicy(
        return INVALID_OPERATION;
    }

    setDesiredActiveMode({std::move(preferredMode), .emitEvent = true});
    setDesiredActiveMode({std::move(preferredMode), .emitEvent = true}, force);
    return NO_ERROR;
}

@@ -7099,7 +7123,8 @@ void SurfaceFlinger::onActiveDisplayChangedLocked(const sp<DisplayDevice>& inact
    // 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.
    applyRefreshRateSelectorPolicy(mActiveDisplayId, activeDisplay->refreshRateSelector());
    constexpr bool kForce = true;
    applyRefreshRateSelectorPolicy(mActiveDisplayId, activeDisplay->refreshRateSelector(), kForce);
}

status_t SurfaceFlinger::addWindowInfosListener(
Loading