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

Commit d02015c7 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 6586393 from 680edcf1 to rvc-release

Change-Id: Ic63f911c0d61082bd806bda0a1945f0418dccee4
parents 7145c962 680edcf1
Loading
Loading
Loading
Loading
+22 −8
Original line number Original line Diff line number Diff line
@@ -115,12 +115,24 @@ std::pair<nsecs_t, nsecs_t> RefreshRateConfigs::getDisplayFrames(nsecs_t layerPe
}
}


const RefreshRate& RefreshRateConfigs::getBestRefreshRate(
const RefreshRate& RefreshRateConfigs::getBestRefreshRate(
        const std::vector<LayerRequirement>& layers, bool touchActive, bool idle,
        const std::vector<LayerRequirement>& layers, const GlobalSignals& globalSignals,
        bool* touchConsidered) const {
        GlobalSignals* outSignalsConsidered) const {
    ATRACE_CALL();
    ATRACE_CALL();
    ALOGV("getRefreshRateForContent %zu layers", layers.size());
    ALOGV("getRefreshRateForContent %zu layers", layers.size());


    if (touchConsidered) *touchConsidered = false;
    if (outSignalsConsidered) *outSignalsConsidered = {};
    const auto setTouchConsidered = [&] {
        if (outSignalsConsidered) {
            outSignalsConsidered->touch = true;
        }
    };

    const auto setIdleConsidered = [&] {
        if (outSignalsConsidered) {
            outSignalsConsidered->idle = true;
        }
    };

    std::lock_guard lock(mLock);
    std::lock_guard lock(mLock);


    int noVoteLayers = 0;
    int noVoteLayers = 0;
@@ -150,9 +162,9 @@ const RefreshRate& RefreshRateConfigs::getBestRefreshRate(


    // Consider the touch event if there are no Explicit* layers. Otherwise wait until after we've
    // Consider the touch event if there are no Explicit* layers. Otherwise wait until after we've
    // selected a refresh rate to see if we should apply touch boost.
    // selected a refresh rate to see if we should apply touch boost.
    if (touchActive && !hasExplicitVoteLayers) {
    if (globalSignals.touch && !hasExplicitVoteLayers) {
        ALOGV("TouchBoost - choose %s", getMaxRefreshRateByPolicyLocked().getName().c_str());
        ALOGV("TouchBoost - choose %s", getMaxRefreshRateByPolicyLocked().getName().c_str());
        if (touchConsidered) *touchConsidered = true;
        setTouchConsidered();
        return getMaxRefreshRateByPolicyLocked();
        return getMaxRefreshRateByPolicyLocked();
    }
    }


@@ -162,8 +174,10 @@ const RefreshRate& RefreshRateConfigs::getBestRefreshRate(
    const Policy* policy = getCurrentPolicyLocked();
    const Policy* policy = getCurrentPolicyLocked();
    const bool primaryRangeIsSingleRate = policy->primaryRange.min == policy->primaryRange.max;
    const bool primaryRangeIsSingleRate = policy->primaryRange.min == policy->primaryRange.max;


    if (!touchActive && idle && !(primaryRangeIsSingleRate && hasExplicitVoteLayers)) {
    if (!globalSignals.touch && globalSignals.idle &&
        !(primaryRangeIsSingleRate && hasExplicitVoteLayers)) {
        ALOGV("Idle - choose %s", getMinRefreshRateByPolicyLocked().getName().c_str());
        ALOGV("Idle - choose %s", getMinRefreshRateByPolicyLocked().getName().c_str());
        setIdleConsidered();
        return getMinRefreshRateByPolicyLocked();
        return getMinRefreshRateByPolicyLocked();
    }
    }


@@ -307,9 +321,9 @@ const RefreshRate& RefreshRateConfigs::getBestRefreshRate(
    // actually increase the refresh rate over the normal selection.
    // actually increase the refresh rate over the normal selection.
    const RefreshRate& touchRefreshRate = getMaxRefreshRateByPolicyLocked();
    const RefreshRate& touchRefreshRate = getMaxRefreshRateByPolicyLocked();


    if (touchActive && explicitDefaultVoteLayers == 0 &&
    if (globalSignals.touch && explicitDefaultVoteLayers == 0 &&
        bestRefreshRate->fps < touchRefreshRate.fps) {
        bestRefreshRate->fps < touchRefreshRate.fps) {
        if (touchConsidered) *touchConsidered = true;
        setTouchConsidered();
        ALOGV("TouchBoost - choose %s", touchRefreshRate.getName().c_str());
        ALOGV("TouchBoost - choose %s", touchRefreshRate.getName().c_str());
        return touchRefreshRate;
        return touchRefreshRate;
    }
    }
+13 −5
Original line number Original line Diff line number Diff line
@@ -211,14 +211,22 @@ public:
    const RefreshRate& getRefreshRateForContent(const std::vector<LayerRequirement>& layers) const
    const RefreshRate& getRefreshRateForContent(const std::vector<LayerRequirement>& layers) const
            EXCLUDES(mLock);
            EXCLUDES(mLock);


    // Global state describing signals that affect refresh rate choice.
    struct GlobalSignals {
        // Whether the user touched the screen recently. Used to apply touch boost.
        bool touch = false;
        // True if the system hasn't seen any buffers posted to layers recently.
        bool idle = false;
    };

    // Returns the refresh rate that fits best to the given layers.
    // Returns the refresh rate that fits best to the given layers.
    //   layers - The layer requirements to consider.
    //   layers - The layer requirements to consider.
    //   touchActive - Whether the user touched the screen recently. Used to apply touch boost.
    //   globalSignals - global state of touch and idle
    //   idle - True if the system hasn't seen any buffers posted to layers recently.
    //   outSignalsConsidered - An output param that tells the caller whether the refresh rate was
    //   touchConsidered - An output param that tells the caller whether the refresh rate was chosen
    //                          chosen based on touch boost and/or idle timer.
    //                     based on touch boost.
    const RefreshRate& getBestRefreshRate(const std::vector<LayerRequirement>& layers,
    const RefreshRate& getBestRefreshRate(const std::vector<LayerRequirement>& layers,
                                          bool touchActive, bool idle, bool* touchConsidered) const
                                          const GlobalSignals& globalSignals,
                                          GlobalSignals* outSignalsConsidered = nullptr) const
            EXCLUDES(mLock);
            EXCLUDES(mLock);


    // Returns all the refresh rates supported by the device. This won't change at runtime.
    // Returns all the refresh rates supported by the device. This won't change at runtime.
+63 −22
Original line number Original line Diff line number Diff line
@@ -228,7 +228,35 @@ void Scheduler::onScreenReleased(ConnectionHandle handle) {
    mConnections[handle].thread->onScreenReleased();
    mConnections[handle].thread->onScreenReleased();
}
}


void Scheduler::onConfigChanged(ConnectionHandle handle, PhysicalDisplayId displayId,
void Scheduler::onPrimaryDisplayConfigChanged(ConnectionHandle handle, PhysicalDisplayId displayId,
                                              HwcConfigIndexType configId, nsecs_t vsyncPeriod) {
    std::lock_guard<std::mutex> lock(mFeatureStateLock);
    // Cache the last reported config for primary display.
    mFeatures.cachedConfigChangedParams = {handle, displayId, configId, vsyncPeriod};
    onNonPrimaryDisplayConfigChanged(handle, displayId, configId, vsyncPeriod);
}

void Scheduler::dispatchCachedReportedConfig() {
    const auto configId = *mFeatures.configId;
    const auto vsyncPeriod =
            mRefreshRateConfigs.getRefreshRateFromConfigId(configId).getVsyncPeriod();

    // If there is no change from cached config, there is no need to dispatch an event
    if (configId == mFeatures.cachedConfigChangedParams->configId &&
        vsyncPeriod == mFeatures.cachedConfigChangedParams->vsyncPeriod) {
        return;
    }

    mFeatures.cachedConfigChangedParams->configId = configId;
    mFeatures.cachedConfigChangedParams->vsyncPeriod = vsyncPeriod;
    onNonPrimaryDisplayConfigChanged(mFeatures.cachedConfigChangedParams->handle,
                                     mFeatures.cachedConfigChangedParams->displayId,
                                     mFeatures.cachedConfigChangedParams->configId,
                                     mFeatures.cachedConfigChangedParams->vsyncPeriod);
}

void Scheduler::onNonPrimaryDisplayConfigChanged(ConnectionHandle handle,
                                                 PhysicalDisplayId displayId,
                                                 HwcConfigIndexType configId, nsecs_t vsyncPeriod) {
                                                 HwcConfigIndexType configId, nsecs_t vsyncPeriod) {
    RETURN_IF_INVALID_HANDLE(handle);
    RETURN_IF_INVALID_HANDLE(handle);
    mConnections[handle].thread->onConfigChanged(displayId, configId, vsyncPeriod);
    mConnections[handle].thread->onConfigChanged(displayId, configId, vsyncPeriod);
@@ -446,13 +474,21 @@ void Scheduler::chooseRefreshRateForContent() {
        mFeatures.contentDetectionV1 =
        mFeatures.contentDetectionV1 =
                !summary.empty() ? ContentDetectionState::On : ContentDetectionState::Off;
                !summary.empty() ? ContentDetectionState::On : ContentDetectionState::Off;


        newConfigId = calculateRefreshRateConfigIndexType();
        scheduler::RefreshRateConfigs::GlobalSignals consideredSignals;
        newConfigId = calculateRefreshRateConfigIndexType(&consideredSignals);
        if (mFeatures.configId == newConfigId) {
        if (mFeatures.configId == newConfigId) {
            // We don't need to change the config, but we might need to send an event
            // about a config change, since it was suppressed due to a previous idleConsidered
            if (!consideredSignals.idle) {
                dispatchCachedReportedConfig();
            }
            return;
            return;
        }
        }
        mFeatures.configId = newConfigId;
        mFeatures.configId = newConfigId;
        auto& newRefreshRate = mRefreshRateConfigs.getRefreshRateFromConfigId(newConfigId);
        auto& newRefreshRate = mRefreshRateConfigs.getRefreshRateFromConfigId(newConfigId);
        mSchedulerCallback.changeRefreshRate(newRefreshRate, ConfigEvent::Changed);
        mSchedulerCallback.changeRefreshRate(newRefreshRate,
                                             consideredSignals.idle ? ConfigEvent::None
                                                                    : ConfigEvent::Changed);
    }
    }
}
}


@@ -522,21 +558,20 @@ void Scheduler::kernelIdleTimerCallback(TimerState state) {
}
}


void Scheduler::idleTimerCallback(TimerState state) {
void Scheduler::idleTimerCallback(TimerState state) {
    handleTimerStateChanged(&mFeatures.idleTimer, state, false /* eventOnContentDetection */);
    handleTimerStateChanged(&mFeatures.idleTimer, state);
    ATRACE_INT("ExpiredIdleTimer", static_cast<int>(state));
    ATRACE_INT("ExpiredIdleTimer", static_cast<int>(state));
}
}


void Scheduler::touchTimerCallback(TimerState state) {
void Scheduler::touchTimerCallback(TimerState state) {
    const TouchState touch = state == TimerState::Reset ? TouchState::Active : TouchState::Inactive;
    const TouchState touch = state == TimerState::Reset ? TouchState::Active : TouchState::Inactive;
    if (handleTimerStateChanged(&mFeatures.touch, touch, true /* eventOnContentDetection */)) {
    if (handleTimerStateChanged(&mFeatures.touch, touch)) {
        mLayerHistory->clear();
        mLayerHistory->clear();
    }
    }
    ATRACE_INT("TouchState", static_cast<int>(touch));
    ATRACE_INT("TouchState", static_cast<int>(touch));
}
}


void Scheduler::displayPowerTimerCallback(TimerState state) {
void Scheduler::displayPowerTimerCallback(TimerState state) {
    handleTimerStateChanged(&mFeatures.displayPowerTimer, state,
    handleTimerStateChanged(&mFeatures.displayPowerTimer, state);
                            true /* eventOnContentDetection */);
    ATRACE_INT("ExpiredDisplayPowerTimer", static_cast<int>(state));
    ATRACE_INT("ExpiredDisplayPowerTimer", static_cast<int>(state));
}
}


@@ -553,33 +588,37 @@ void Scheduler::dump(std::string& result) const {
}
}


template <class T>
template <class T>
bool Scheduler::handleTimerStateChanged(T* currentState, T newState, bool eventOnContentDetection) {
bool Scheduler::handleTimerStateChanged(T* currentState, T newState) {
    ConfigEvent event = ConfigEvent::None;
    HwcConfigIndexType newConfigId;
    HwcConfigIndexType newConfigId;
    bool touchConsidered = false;
    scheduler::RefreshRateConfigs::GlobalSignals consideredSignals;
    {
    {
        std::lock_guard<std::mutex> lock(mFeatureStateLock);
        std::lock_guard<std::mutex> lock(mFeatureStateLock);
        if (*currentState == newState) {
        if (*currentState == newState) {
            return touchConsidered;
            return false;
        }
        }
        *currentState = newState;
        *currentState = newState;
        newConfigId = calculateRefreshRateConfigIndexType(&touchConsidered);
        newConfigId = calculateRefreshRateConfigIndexType(&consideredSignals);
        if (mFeatures.configId == newConfigId) {
        if (mFeatures.configId == newConfigId) {
            return touchConsidered;
            // We don't need to change the config, but we might need to send an event
            // about a config change, since it was suppressed due to a previous idleConsidered
            if (!consideredSignals.idle) {
                dispatchCachedReportedConfig();
            }
            }
        mFeatures.configId = newConfigId;
            return consideredSignals.touch;
        if (eventOnContentDetection && !mFeatures.contentRequirements.empty()) {
            event = ConfigEvent::Changed;
        }
        }
        mFeatures.configId = newConfigId;
    }
    }
    const RefreshRate& newRefreshRate = mRefreshRateConfigs.getRefreshRateFromConfigId(newConfigId);
    const RefreshRate& newRefreshRate = mRefreshRateConfigs.getRefreshRateFromConfigId(newConfigId);
    mSchedulerCallback.changeRefreshRate(newRefreshRate, event);
    mSchedulerCallback.changeRefreshRate(newRefreshRate,
    return touchConsidered;
                                         consideredSignals.idle ? ConfigEvent::None
                                                                : ConfigEvent::Changed);
    return consideredSignals.touch;
}
}


HwcConfigIndexType Scheduler::calculateRefreshRateConfigIndexType(bool* touchConsidered) {
HwcConfigIndexType Scheduler::calculateRefreshRateConfigIndexType(
        scheduler::RefreshRateConfigs::GlobalSignals* consideredSignals) {
    ATRACE_CALL();
    ATRACE_CALL();
    if (touchConsidered) *touchConsidered = false;
    if (consideredSignals) *consideredSignals = {};


    // If Display Power is not in normal operation we want to be in performance mode. When coming
    // If Display Power is not in normal operation we want to be in performance mode. When coming
    // back to normal mode, a grace period is given with DisplayPowerTimer.
    // back to normal mode, a grace period is given with DisplayPowerTimer.
@@ -600,6 +639,7 @@ HwcConfigIndexType Scheduler::calculateRefreshRateConfigIndexType(bool* touchCon


        // If timer has expired as it means there is no new content on the screen.
        // If timer has expired as it means there is no new content on the screen.
        if (idle) {
        if (idle) {
            if (consideredSignals) consideredSignals->idle = true;
            return mRefreshRateConfigs.getMinRefreshRateByPolicy().getConfigId();
            return mRefreshRateConfigs.getMinRefreshRateByPolicy().getConfigId();
        }
        }


@@ -615,7 +655,8 @@ HwcConfigIndexType Scheduler::calculateRefreshRateConfigIndexType(bool* touchCon
    }
    }


    return mRefreshRateConfigs
    return mRefreshRateConfigs
            .getBestRefreshRate(mFeatures.contentRequirements, touchActive, idle, touchConsidered)
            .getBestRefreshRate(mFeatures.contentRequirements, {.touch = touchActive, .idle = idle},
                                consideredSignals)
            .getConfigId();
            .getConfigId();
}
}


+20 −5
Original line number Original line Diff line number Diff line
@@ -81,9 +81,11 @@ public:
    sp<EventThreadConnection> getEventConnection(ConnectionHandle);
    sp<EventThreadConnection> getEventConnection(ConnectionHandle);


    void onHotplugReceived(ConnectionHandle, PhysicalDisplayId, bool connected);
    void onHotplugReceived(ConnectionHandle, PhysicalDisplayId, bool connected);
    void onConfigChanged(ConnectionHandle, PhysicalDisplayId, HwcConfigIndexType configId,
    void onPrimaryDisplayConfigChanged(ConnectionHandle, PhysicalDisplayId,
                         nsecs_t vsyncPeriod);
                                       HwcConfigIndexType configId, nsecs_t vsyncPeriod)

            EXCLUDES(mFeatureStateLock);
    void onNonPrimaryDisplayConfigChanged(ConnectionHandle, PhysicalDisplayId,
                                          HwcConfigIndexType configId, nsecs_t vsyncPeriod);
    void onScreenAcquired(ConnectionHandle);
    void onScreenAcquired(ConnectionHandle);
    void onScreenReleased(ConnectionHandle);
    void onScreenReleased(ConnectionHandle);


@@ -179,16 +181,19 @@ private:


    // handles various timer features to change the refresh rate.
    // handles various timer features to change the refresh rate.
    template <class T>
    template <class T>
    bool handleTimerStateChanged(T* currentState, T newState, bool eventOnContentDetection);
    bool handleTimerStateChanged(T* currentState, T newState);


    void setVsyncPeriod(nsecs_t period);
    void setVsyncPeriod(nsecs_t period);


    // This function checks whether individual features that are affecting the refresh rate
    // This function checks whether individual features that are affecting the refresh rate
    // selection were initialized, prioritizes them, and calculates the HwcConfigIndexType
    // selection were initialized, prioritizes them, and calculates the HwcConfigIndexType
    // for the suggested refresh rate.
    // for the suggested refresh rate.
    HwcConfigIndexType calculateRefreshRateConfigIndexType(bool* touchConsidered = nullptr)
    HwcConfigIndexType calculateRefreshRateConfigIndexType(
            scheduler::RefreshRateConfigs::GlobalSignals* consideredSignals = nullptr)
            REQUIRES(mFeatureStateLock);
            REQUIRES(mFeatureStateLock);


    void dispatchCachedReportedConfig() REQUIRES(mFeatureStateLock);

    // Stores EventThread associated with a given VSyncSource, and an initial EventThreadConnection.
    // Stores EventThread associated with a given VSyncSource, and an initial EventThreadConnection.
    struct Connection {
    struct Connection {
        sp<EventThreadConnection> connection;
        sp<EventThreadConnection> connection;
@@ -240,6 +245,16 @@ private:
        LayerHistory::Summary contentRequirements;
        LayerHistory::Summary contentRequirements;


        bool isDisplayPowerStateNormal = true;
        bool isDisplayPowerStateNormal = true;

        // Used to cache the last parameters of onPrimaryDisplayConfigChanged
        struct ConfigChangedParams {
            ConnectionHandle handle;
            PhysicalDisplayId displayId;
            HwcConfigIndexType configId;
            nsecs_t vsyncPeriod;
        };

        std::optional<ConfigChangedParams> cachedConfigChangedParams;
    } mFeatures GUARDED_BY(mFeatureStateLock);
    } mFeatures GUARDED_BY(mFeatureStateLock);


    const scheduler::RefreshRateConfigs& mRefreshRateConfigs;
    const scheduler::RefreshRateConfigs& mRefreshRateConfigs;
+8 −8
Original line number Original line Diff line number Diff line
@@ -1077,7 +1077,7 @@ void SurfaceFlinger::setActiveConfigInternal() {
        const nsecs_t vsyncPeriod =
        const nsecs_t vsyncPeriod =
                mRefreshRateConfigs->getRefreshRateFromConfigId(mUpcomingActiveConfig.configId)
                mRefreshRateConfigs->getRefreshRateFromConfigId(mUpcomingActiveConfig.configId)
                        .getVsyncPeriod();
                        .getVsyncPeriod();
        mScheduler->onConfigChanged(mAppConnectionHandle, display->getId()->value,
        mScheduler->onPrimaryDisplayConfigChanged(mAppConnectionHandle, display->getId()->value,
                                                  mUpcomingActiveConfig.configId, vsyncPeriod);
                                                  mUpcomingActiveConfig.configId, vsyncPeriod);
    }
    }
}
}
@@ -2995,8 +2995,8 @@ void SurfaceFlinger::initScheduler(DisplayId primaryDisplayId) {
    // anyway since there are no connected apps at this point.
    // anyway since there are no connected apps at this point.
    const nsecs_t vsyncPeriod =
    const nsecs_t vsyncPeriod =
            mRefreshRateConfigs->getRefreshRateFromConfigId(currentConfig).getVsyncPeriod();
            mRefreshRateConfigs->getRefreshRateFromConfigId(currentConfig).getVsyncPeriod();
    mScheduler->onConfigChanged(mAppConnectionHandle, primaryDisplayId.value, currentConfig,
    mScheduler->onPrimaryDisplayConfigChanged(mAppConnectionHandle, primaryDisplayId.value,
                                vsyncPeriod);
                                              currentConfig, vsyncPeriod);
}
}


void SurfaceFlinger::commitTransaction()
void SurfaceFlinger::commitTransaction()
@@ -5943,7 +5943,7 @@ status_t SurfaceFlinger::setDesiredDisplayConfigSpecsInternal(
        const nsecs_t vsyncPeriod = getHwComposer()
        const nsecs_t vsyncPeriod = getHwComposer()
                                            .getConfigs(*displayId)[policy->defaultConfig.value()]
                                            .getConfigs(*displayId)[policy->defaultConfig.value()]
                                            ->getVsyncPeriod();
                                            ->getVsyncPeriod();
        mScheduler->onConfigChanged(mAppConnectionHandle, display->getId()->value,
        mScheduler->onNonPrimaryDisplayConfigChanged(mAppConnectionHandle, display->getId()->value,
                                                     policy->defaultConfig, vsyncPeriod);
                                                     policy->defaultConfig, vsyncPeriod);
        return NO_ERROR;
        return NO_ERROR;
    }
    }
@@ -5976,7 +5976,7 @@ status_t SurfaceFlinger::setDesiredDisplayConfigSpecsInternal(
    const nsecs_t vsyncPeriod =
    const nsecs_t vsyncPeriod =
            mRefreshRateConfigs->getRefreshRateFromConfigId(display->getActiveConfig())
            mRefreshRateConfigs->getRefreshRateFromConfigId(display->getActiveConfig())
                    .getVsyncPeriod();
                    .getVsyncPeriod();
    mScheduler->onConfigChanged(mAppConnectionHandle, display->getId()->value,
    mScheduler->onPrimaryDisplayConfigChanged(mAppConnectionHandle, display->getId()->value,
                                              display->getActiveConfig(), vsyncPeriod);
                                              display->getActiveConfig(), vsyncPeriod);


    auto configId = mScheduler->getPreferredConfigId();
    auto configId = mScheduler->getPreferredConfigId();
Loading