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

Commit e5514a7b authored by Rachel Lee's avatar Rachel Lee
Browse files

Add frame rate compatibility GTE logic

Bug: 306080972
Test: atest libsurfaceflinger_unittest
Test: atest SetFrameRateTest
Change-Id: I65551be0f96fd7d4137e49259436e1a9c74bfe90
parent 791b234c
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -1057,7 +1057,12 @@ enum {
    /**
     * This surface will vote for the minimum refresh rate.
     */
    ANATIVEWINDOW_FRAME_RATE_MIN
    ANATIVEWINDOW_FRAME_RATE_MIN,

    /**
     * The surface requests a frame rate that is greater than or equal to `frameRate`.
     */
    ANATIVEWINDOW_FRAME_RATE_GTE
};

/*
+2 −0
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@ enum class FrameRateCompatibility {
    ExactOrMultiple, // Layer needs the exact frame rate (or a multiple of it) to present the
                     // content properly. Any other value will result in a pull down.

    Gte, // Layer needs greater than or equal to the frame rate.

    NoVote, // Layer doesn't have any requirements for the refresh rate and
            // should not be considered when the display refresh rate is determined.

+2 −0
Original line number Diff line number Diff line
@@ -278,6 +278,8 @@ void LayerHistory::partitionLayers(nsecs_t now) {
                        return LayerVoteType::NoVote;
                    case Layer::FrameRateCompatibility::Exact:
                        return LayerVoteType::ExplicitExact;
                    case Layer::FrameRateCompatibility::Gte:
                        return LayerVoteType::ExplicitGte;
                }
            }();

+2 −0
Original line number Diff line number Diff line
@@ -485,6 +485,8 @@ FrameRateCompatibility LayerInfo::FrameRate::convertCompatibility(int8_t compati
            return FrameRateCompatibility::Exact;
        case ANATIVEWINDOW_FRAME_RATE_MIN:
            return FrameRateCompatibility::Min;
        case ANATIVEWINDOW_FRAME_RATE_GTE:
            return FrameRateCompatibility::Gte;
        case ANATIVEWINDOW_FRAME_RATE_NO_VOTE:
            return FrameRateCompatibility::NoVote;
        default:
+28 −7
Original line number Diff line number Diff line
@@ -332,6 +332,15 @@ float RefreshRateSelector::calculateNonExactMatchingLayerScoreLocked(const Layer
        return calculateNonExactMatchingDefaultLayerScoreLocked(displayPeriod, layerPeriod);
    }

    if (layer.vote == LayerVoteType::ExplicitGte) {
        using fps_approx_ops::operator>=;
        if (refreshRate >= layer.desiredRefreshRate) {
            return 1.0f;
        } else {
            return calculateDistanceScoreLocked(layer.desiredRefreshRate, refreshRate);
        }
    }

    if (layer.vote == LayerVoteType::ExplicitExactOrMultiple ||
        layer.vote == LayerVoteType::Heuristic) {
        using fps_approx_ops::operator<;
@@ -390,13 +399,20 @@ float RefreshRateSelector::calculateNonExactMatchingLayerScoreLocked(const Layer
    return 0;
}

float RefreshRateSelector::calculateDistanceScoreFromMax(Fps refreshRate) const {
    const auto& maxFps = mAppRequestFrameRates.back().fps;
    const float ratio = refreshRate.getValue() / maxFps.getValue();
    // Use ratio^2 to get a lower score the more we get further from peak
float RefreshRateSelector::calculateDistanceScoreLocked(Fps referenceRate, Fps refreshRate) const {
    using fps_approx_ops::operator>=;
    const float ratio = referenceRate >= refreshRate
            ? refreshRate.getValue() / referenceRate.getValue()
            : referenceRate.getValue() / refreshRate.getValue();
    // Use ratio^2 to get a lower score the more we get further from the reference rate.
    return ratio * ratio;
}

float RefreshRateSelector::calculateDistanceScoreFromMaxLocked(Fps refreshRate) const {
    const auto& maxFps = mAppRequestFrameRates.back().fps;
    return calculateDistanceScoreLocked(maxFps, refreshRate);
}

float RefreshRateSelector::calculateLayerScoreLocked(const LayerRequirement& layer, Fps refreshRate,
                                                     bool isSeamlessSwitch) const {
    // Slightly prefer seamless switches.
@@ -421,7 +437,7 @@ float RefreshRateSelector::calculateLayerScoreLocked(const LayerRequirement& lay

    // If the layer wants Max, give higher score to the higher refresh rate
    if (layer.vote == LayerVoteType::Max) {
        return calculateDistanceScoreFromMax(refreshRate);
        return calculateDistanceScoreFromMaxLocked(refreshRate);
    }

    if (layer.vote == LayerVoteType::ExplicitExact) {
@@ -489,6 +505,7 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi
    int explicitDefaultVoteLayers = 0;
    int explicitExactOrMultipleVoteLayers = 0;
    int explicitExact = 0;
    int explicitGteLayers = 0;
    int explicitCategoryVoteLayers = 0;
    int seamedFocusedLayers = 0;
    int categorySmoothSwitchOnlyLayers = 0;
@@ -513,6 +530,9 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi
            case LayerVoteType::ExplicitExact:
                explicitExact++;
                break;
            case LayerVoteType::ExplicitGte:
                explicitGteLayers++;
                break;
            case LayerVoteType::ExplicitCategory:
                explicitCategoryVoteLayers++;
                if (layer.frameRateCategory == FrameRateCategory::NoPreference) {
@@ -535,7 +555,7 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi
    }

    const bool hasExplicitVoteLayers = explicitDefaultVoteLayers > 0 ||
            explicitExactOrMultipleVoteLayers > 0 || explicitExact > 0 ||
            explicitExactOrMultipleVoteLayers > 0 || explicitExact > 0 || explicitGteLayers > 0 ||
            explicitCategoryVoteLayers > 0;

    const Policy* policy = getCurrentPolicyLocked();
@@ -688,6 +708,7 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi
                    case LayerVoteType::Max:
                    case LayerVoteType::ExplicitDefault:
                    case LayerVoteType::ExplicitExact:
                    case LayerVoteType::ExplicitGte:
                    case LayerVoteType::ExplicitCategory:
                        return false;
                }
@@ -1081,7 +1102,7 @@ auto RefreshRateSelector::rankFrameRates(std::optional<int> anchorGroupOpt,
            return;
        }

        float score = calculateDistanceScoreFromMax(frameRateMode.fps);
        float score = calculateDistanceScoreFromMaxLocked(frameRateMode.fps);

        if (ascending) {
            score = 1.0f / score;
Loading