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

Commit 76eb78fe authored by Rachel Lee's avatar Rachel Lee
Browse files

Add GTE compatibility logic for NoVote

setFrameRate with GTE compatibility and 0 `frameRate` will be counted as NoVote.

Test: atest libsurfaceflinger_unittest
Test: atest LayerHistoryIntegrationTest
Bug: 380949716
Flag: com.android.graphics.surfaceflinger.flags.arr_setframerate_gte_enum
Change-Id: I5ffcd4a09b1661c516c11d2f04b80303af215c3a
parent ee81a84b
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -280,6 +280,9 @@ void LayerHistory::partitionLayers(nsecs_t now, bool isVrrDevice) {
                    case Layer::FrameRateCompatibility::Exact:
                        return LayerVoteType::ExplicitExact;
                    case Layer::FrameRateCompatibility::Gte:
                        if (frameRate.isNoVote()) {
                            return LayerVoteType::NoVote;
                        }
                        if (isVrrDevice) {
                            return LayerVoteType::ExplicitGte;
                        } else {
+9 −1
Original line number Diff line number Diff line
@@ -562,7 +562,10 @@ LayerInfo::FrameRateSelectionStrategy LayerInfo::convertFrameRateSelectionStrate
}

bool LayerInfo::FrameRate::isNoVote() const {
    return vote.type == FrameRateCompatibility::NoVote;
    // A desired frame rate greater than or equal to 0 is treated as NoVote.
    bool isNoVoteGte = FlagManager::getInstance().arr_setframerate_gte_enum() &&
            vote.type == FrameRateCompatibility::Gte && !vote.rate.isValid();
    return vote.type == FrameRateCompatibility::NoVote || isNoVoteGte;
}

bool LayerInfo::FrameRate::isValuelessType() const {
@@ -577,7 +580,12 @@ bool LayerInfo::FrameRate::isValuelessType() const {
        case FrameRateCompatibility::Default:
        case FrameRateCompatibility::ExactOrMultiple:
        case FrameRateCompatibility::Exact:
            return false;
        case FrameRateCompatibility::Gte:
            if (isNoVote()) {
                // Special case: GTE 0 is same as NoVote.
                return true;
            }
            return false;
    }
}
+66 −0
Original line number Diff line number Diff line
@@ -654,6 +654,72 @@ TEST_F(LayerHistoryIntegrationTest, oneLayerExplicitGte_nonVrr) {
    EXPECT_EQ(FrameRateCategory::Default, summarizeLayerHistory(time)[0].frameRateCategory);
}

TEST_F(LayerHistoryIntegrationTest, oneLayerGteNoVote_arr) {
    SET_FLAG_FOR_TEST(flags::arr_setframerate_gte_enum, true);
    // Set the test to be on a vrr mode.
    SET_FLAG_FOR_TEST(flags::vrr_config, true);
    mSelector->setActiveMode(kVrrModeId, HI_FPS);

    auto layer = createLegacyAndFrontedEndLayer(1);
    showLayer(1);
    setFrameRate(1, (0_Hz).getValue(), ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_GTE,
                 ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);

    EXPECT_EQ(1u, layerCount());
    EXPECT_EQ(0u, activeLayerCount());

    nsecs_t time = systemTime();
    for (size_t i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
        setBufferWithPresentTime(layer, time);
        time += HI_FPS_PERIOD;
    }

    // Layer is active but GTE with 0 should be considered NoVote, thus nothing from summarize.
    ASSERT_EQ(0u, summarizeLayerHistory(time).size());
    EXPECT_EQ(1u, activeLayerCount());
    EXPECT_EQ(1, frequentLayerCount(time));

    // layer became inactive.
    setDefaultLayerVote(layer.get(), LayerHistory::LayerVoteType::Heuristic);
    time += MAX_ACTIVE_LAYER_PERIOD_NS.count();
    ASSERT_EQ(0u, summarizeLayerHistory(time).size());
    EXPECT_EQ(0u, activeLayerCount());
    EXPECT_EQ(0, frequentLayerCount(time));
}

TEST_F(LayerHistoryIntegrationTest, oneLayerGteNoVote_mrr) {
    SET_FLAG_FOR_TEST(flags::arr_setframerate_gte_enum, true);
    // True by default on MRR devices as well, but the device is not set to VRR mode.
    SET_FLAG_FOR_TEST(flags::vrr_config, true);

    auto layer = createLegacyAndFrontedEndLayer(1);
    showLayer(1);
    setFrameRate(1, (0_Hz).getValue(), ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_GTE,
                 ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
    setFrameRateCategory(1, 0);

    EXPECT_EQ(1u, layerCount());
    EXPECT_EQ(0u, activeLayerCount());

    nsecs_t time = systemTime();
    for (size_t i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
        setBufferWithPresentTime(layer, time);
        time += HI_FPS_PERIOD;
    }

    // Layer is active but GTE with 0 should be considered NoVote, thus nothing from summarize.
    ASSERT_EQ(0u, summarizeLayerHistory(time).size());
    EXPECT_EQ(1u, activeLayerCount());
    EXPECT_EQ(1, frequentLayerCount(time));

    // layer became inactive.
    setDefaultLayerVote(layer.get(), LayerHistory::LayerVoteType::Heuristic);
    time += MAX_ACTIVE_LAYER_PERIOD_NS.count();
    ASSERT_EQ(0u, summarizeLayerHistory(time).size());
    EXPECT_EQ(0u, activeLayerCount());
    EXPECT_EQ(0, frequentLayerCount(time));
}

TEST_F(LayerHistoryIntegrationTest, oneLayerExplicitVoteWithCategory_vrrFeatureOff) {
    SET_FLAG_FOR_TEST(flags::frame_rate_category_mrr, false);