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

Commit 41aeaf82 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes I40d73e79,I99debb33,Id3807764 into main

* changes:
  SF: Merge on{,Non}PrimaryDisplayModeChanged
  SF: Clean up emitting of mode change event
  SF: Add test for emitting of mode change event
parents 504d250d bda5236d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -210,6 +210,8 @@ public:
        // within the timeout of DisplayPowerTimer.
        bool powerOnImminent = false;

        bool shouldEmitEvent() const { return !idle; }

        bool operator==(GlobalSignals other) const {
            return touch == other.touch && idle == other.idle &&
                    powerOnImminent == other.powerOnImminent;
+30 −32
Original line number Diff line number Diff line
@@ -424,50 +424,49 @@ void Scheduler::onHdcpLevelsChanged(Cycle cycle, PhysicalDisplayId displayId,
    eventThreadFor(cycle).onHdcpLevelsChanged(displayId, connectedLevel, maxLevel);
}

void Scheduler::onPrimaryDisplayModeChanged(Cycle cycle, const FrameRateMode& mode) {
    {
bool Scheduler::onDisplayModeChanged(PhysicalDisplayId displayId, const FrameRateMode& mode) {
    const bool isPacesetter =
            FTL_FAKE_GUARD(kMainThreadContext,
                           (std::scoped_lock(mDisplayLock), displayId == mPacesetterDisplayId));

    if (isPacesetter) {
        std::lock_guard<std::mutex> lock(mPolicyLock);
        // Cache the last reported modes for primary display.
        mPolicy.cachedModeChangedParams = {cycle, mode};
        mPolicy.emittedModeOpt = mode;

        // Invalidate content based refresh rate selection so it could be calculated
        // again for the new refresh rate.
        mPolicy.contentRequirements.clear();
    }
    onNonPrimaryDisplayModeChanged(cycle, mode);

    if (hasEventThreads()) {
        eventThreadFor(Cycle::Render).onModeChanged(mode);
    }

void Scheduler::dispatchCachedReportedMode() {
    // Check optional fields first.
    if (!mPolicy.modeOpt) {
        ALOGW("No mode ID found, not dispatching cached mode.");
        return;
    return isPacesetter;
}
    if (!mPolicy.cachedModeChangedParams) {
        ALOGW("No mode changed params found, not dispatching cached mode.");

void Scheduler::emitModeChangeIfNeeded() {
    if (!mPolicy.modeOpt || !mPolicy.emittedModeOpt) {
        ALOGW("No mode change to emit");
        return;
    }

    // If the mode is not the current mode, this means that a
    // mode change is in progress. In that case we shouldn't dispatch an event
    // as it will be dispatched when the current mode changes.
    if (pacesetterSelectorPtr()->getActiveMode() != mPolicy.modeOpt) {
    const auto& mode = *mPolicy.modeOpt;

    if (mode != pacesetterSelectorPtr()->getActiveMode()) {
        // A mode change is pending. The event will be emitted when the mode becomes active.
        return;
    }

    // If there is no change from cached mode, there is no need to dispatch an event
    if (*mPolicy.modeOpt == mPolicy.cachedModeChangedParams->mode) {
    if (mode == *mPolicy.emittedModeOpt) {
        // The event was already emitted.
        return;
    }

    mPolicy.cachedModeChangedParams->mode = *mPolicy.modeOpt;
    onNonPrimaryDisplayModeChanged(mPolicy.cachedModeChangedParams->cycle,
                                   mPolicy.cachedModeChangedParams->mode);
}
    mPolicy.emittedModeOpt = mode;

void Scheduler::onNonPrimaryDisplayModeChanged(Cycle cycle, const FrameRateMode& mode) {
    if (hasEventThreads()) {
        eventThreadFor(cycle).onModeChanged(mode);
        eventThreadFor(Cycle::Render).onModeChanged(mode);
    }
}

@@ -1139,7 +1138,8 @@ auto Scheduler::applyPolicy(S Policy::*statePtr, T&& newState) -> GlobalSignals
        for (auto& [id, choice] : modeChoices) {
            modeRequests.emplace_back(
                    display::DisplayModeRequest{.mode = std::move(choice.mode),
                                                .emitEvent = !choice.consideredSignals.idle});
                                                .emitEvent = choice.consideredSignals
                                                                     .shouldEmitEvent()});
        }

        if (!FlagManager::getInstance().vrr_bugfix_dropped_frame()) {
@@ -1149,12 +1149,10 @@ auto Scheduler::applyPolicy(S Policy::*statePtr, T&& newState) -> GlobalSignals
        if (mPolicy.modeOpt != modeOpt) {
            mPolicy.modeOpt = modeOpt;
            refreshRateChanged = true;
        } else {
            // We don't need to change the display mode, but we might need to send an event
            // about a mode change, since it was suppressed if previously considered idle.
            if (!consideredSignals.idle) {
                dispatchCachedReportedMode();
            }
        } else if (consideredSignals.shouldEmitEvent()) {
            // The mode did not change, but we may need to emit if DisplayModeRequest::emitEvent was
            // previously false.
            emitModeChangeIfNeeded();
        }
    }
    if (refreshRateChanged) {
+5 −10
Original line number Diff line number Diff line
@@ -154,8 +154,8 @@ public:

    void dispatchHotplugError(int32_t errorCode);

    void onPrimaryDisplayModeChanged(Cycle, const FrameRateMode&) EXCLUDES(mPolicyLock);
    void onNonPrimaryDisplayModeChanged(Cycle, const FrameRateMode&);
    // Returns true if the PhysicalDisplayId is the pacesetter.
    bool onDisplayModeChanged(PhysicalDisplayId, const FrameRateMode&) EXCLUDES(mPolicyLock);

    void enableSyntheticVsync(bool = true) REQUIRES(kMainThreadContext);

@@ -458,7 +458,7 @@ private:
    void updateAttachedChoreographersFrameRate(const surfaceflinger::frontend::RequestedLayerState&,
                                               Fps fps) EXCLUDES(mChoreographerLock);

    void dispatchCachedReportedMode() REQUIRES(mPolicyLock) EXCLUDES(mDisplayLock);
    void emitModeChangeIfNeeded() REQUIRES(mPolicyLock) EXCLUDES(mDisplayLock);

    // IEventThreadCallback overrides
    bool throttleVsync(TimePoint, uid_t) override;
@@ -584,13 +584,8 @@ private:
        // Chosen display mode.
        ftl::Optional<FrameRateMode> modeOpt;

        struct ModeChangedParams {
            Cycle cycle;
            FrameRateMode mode;
        };

        // Parameters for latest dispatch of mode change event.
        std::optional<ModeChangedParams> cachedModeChangedParams;
        // Display mode of latest emitted event.
        std::optional<FrameRateMode> emittedModeOpt;
    } mPolicy GUARDED_BY(mPolicyLock);

    std::mutex mChoreographerLock;
+4 −18
Original line number Diff line number Diff line
@@ -1358,7 +1358,7 @@ void SurfaceFlinger::setDesiredMode(display::DisplayModeRequest&& desiredMode) {
            }

            if (emitEvent) {
                dispatchDisplayModeChangeEvent(displayId, mode);
                mScheduler->onDisplayModeChanged(displayId, mode);
            }
            break;
        case DesiredModeAction::None:
@@ -1455,7 +1455,7 @@ void SurfaceFlinger::finalizeDisplayModeChange(PhysicalDisplayId displayId) {
    }

    if (pendingModeOpt->emitEvent) {
        dispatchDisplayModeChangeEvent(displayId, activeMode);
        mScheduler->onDisplayModeChanged(displayId, activeMode);
    }
}

@@ -3589,16 +3589,6 @@ void SurfaceFlinger::processHotplugDisconnect(PhysicalDisplayId displayId,
    mPhysicalDisplays.erase(displayId);
}

void SurfaceFlinger::dispatchDisplayModeChangeEvent(PhysicalDisplayId displayId,
                                                    const scheduler::FrameRateMode& mode) {
    // TODO(b/255635821): Merge code paths and move to Scheduler.
    const auto onDisplayModeChanged = displayId == mActiveDisplayId
            ? &scheduler::Scheduler::onPrimaryDisplayModeChanged
            : &scheduler::Scheduler::onNonPrimaryDisplayModeChanged;

    ((*mScheduler).*onDisplayModeChanged)(scheduler::Cycle::Render, mode);
}

sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
        const wp<IBinder>& displayToken,
        std::shared_ptr<compositionengine::Display> compositionDisplay,
@@ -7959,13 +7949,9 @@ status_t SurfaceFlinger::applyRefreshRateSelectorPolicy(
    const scheduler::RefreshRateSelector::Policy currentPolicy = selector.getCurrentPolicy();
    ALOGV("Setting desired display mode specs: %s", currentPolicy.toString().c_str());

    // TODO(b/140204874): Leave the event in until we do proper testing with all apps that might
    // be depending in this callback.
    if (const auto activeMode = selector.getActiveMode(); displayId == mActiveDisplayId) {
        mScheduler->onPrimaryDisplayModeChanged(scheduler::Cycle::Render, activeMode);
    if (const bool isPacesetter =
                mScheduler->onDisplayModeChanged(displayId, selector.getActiveMode())) {
        toggleKernelIdleTimer();
    } else {
        mScheduler->onNonPrimaryDisplayModeChanged(scheduler::Cycle::Render, activeMode);
    }

    auto preferredModeOpt = getPreferredDisplayMode(displayId, currentPolicy.defaultMode);
+0 −2
Original line number Diff line number Diff line
@@ -1067,8 +1067,6 @@ private:
                               const DisplayDeviceState& drawingState)
            REQUIRES(mStateLock, kMainThreadContext);

    void dispatchDisplayModeChangeEvent(PhysicalDisplayId, const scheduler::FrameRateMode&);

    /*
     * VSYNC
     */
Loading