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

Commit 78ecde5c authored by Rachel Lee's avatar Rachel Lee Committed by Android (Google) Code Review
Browse files

Merge "Set frame rate GTE to Max for MRR" into main

parents f4782de4 8f2eea4c
Loading
Loading
Loading
Loading
+14 −4
Original line number Original line Diff line number Diff line
@@ -280,9 +280,18 @@ void LayerHistory::partitionLayers(nsecs_t now, bool isVrrDevice) {
                    case Layer::FrameRateCompatibility::Exact:
                    case Layer::FrameRateCompatibility::Exact:
                        return LayerVoteType::ExplicitExact;
                        return LayerVoteType::ExplicitExact;
                    case Layer::FrameRateCompatibility::Gte:
                    case Layer::FrameRateCompatibility::Gte:
                        if (isVrrDevice) {
                            return LayerVoteType::ExplicitGte;
                            return LayerVoteType::ExplicitGte;
                        } else {
                            // For MRR, treat GTE votes as Max because it is used for animations and
                            // scroll. MRR cannot change frame rate without jank, so it should
                            // prefer smoothness.
                            return LayerVoteType::Max;
                        }
                }
                }
            }();
            }();
            const bool isValuelessVote = voteType == LayerVoteType::NoVote ||
                    voteType == LayerVoteType::Min || voteType == LayerVoteType::Max;


            if (FlagManager::getInstance().game_default_frame_rate()) {
            if (FlagManager::getInstance().game_default_frame_rate()) {
                // Determine the layer frame rate considering the following priorities:
                // Determine the layer frame rate considering the following priorities:
@@ -307,7 +316,8 @@ void LayerHistory::partitionLayers(nsecs_t now, bool isVrrDevice) {
                              gameModeFrameRateOverride.getIntValue());
                              gameModeFrameRateOverride.getIntValue());
                    }
                    }
                } else if (frameRate.isValid() && frameRate.isVoteValidForMrr(isVrrDevice)) {
                } else if (frameRate.isValid() && frameRate.isVoteValidForMrr(isVrrDevice)) {
                    info->setLayerVote({setFrameRateVoteType, frameRate.vote.rate,
                    info->setLayerVote({setFrameRateVoteType,
                                        isValuelessVote ? 0_Hz : frameRate.vote.rate,
                                        frameRate.vote.seamlessness, frameRate.category});
                                        frameRate.vote.seamlessness, frameRate.category});
                    if (CC_UNLIKELY(mTraceEnabled)) {
                    if (CC_UNLIKELY(mTraceEnabled)) {
                        trace(*info, gameFrameRateOverrideVoteType,
                        trace(*info, gameFrameRateOverrideVoteType,
@@ -335,8 +345,8 @@ void LayerHistory::partitionLayers(nsecs_t now, bool isVrrDevice) {
            } else {
            } else {
                if (frameRate.isValid() && frameRate.isVoteValidForMrr(isVrrDevice)) {
                if (frameRate.isValid() && frameRate.isVoteValidForMrr(isVrrDevice)) {
                    const auto type = info->isVisible() ? voteType : LayerVoteType::NoVote;
                    const auto type = info->isVisible() ? voteType : LayerVoteType::NoVote;
                    info->setLayerVote({type, frameRate.vote.rate, frameRate.vote.seamlessness,
                    info->setLayerVote({type, isValuelessVote ? 0_Hz : frameRate.vote.rate,
                                        frameRate.category});
                                        frameRate.vote.seamlessness, frameRate.category});
                } else {
                } else {
                    if (!frameRate.isVoteValidForMrr(isVrrDevice)) {
                    if (!frameRate.isVoteValidForMrr(isVrrDevice)) {
                        ATRACE_FORMAT_INSTANT("Reset layer to ignore explicit vote on MRR %s: %s "
                        ATRACE_FORMAT_INSTANT("Reset layer to ignore explicit vote on MRR %s: %s "
+19 −2
Original line number Original line Diff line number Diff line
@@ -563,8 +563,25 @@ bool LayerInfo::FrameRate::isNoVote() const {
    return vote.type == FrameRateCompatibility::NoVote;
    return vote.type == FrameRateCompatibility::NoVote;
}
}


bool LayerInfo::FrameRate::isValuelessType() const {
    // For a valueless frame rate compatibility (type), the frame rate should be unspecified (0 Hz).
    if (!isApproxEqual(vote.rate, 0_Hz)) {
        return false;
    }
    switch (vote.type) {
        case FrameRateCompatibility::Min:
        case FrameRateCompatibility::NoVote:
            return true;
        case FrameRateCompatibility::Default:
        case FrameRateCompatibility::ExactOrMultiple:
        case FrameRateCompatibility::Exact:
        case FrameRateCompatibility::Gte:
            return false;
    }
}

bool LayerInfo::FrameRate::isValid() const {
bool LayerInfo::FrameRate::isValid() const {
    return isNoVote() || vote.rate.isValid() || category != FrameRateCategory::Default;
    return isValuelessType() || vote.rate.isValid() || category != FrameRateCategory::Default;
}
}


bool LayerInfo::FrameRate::isVoteValidForMrr(bool isVrrDevice) const {
bool LayerInfo::FrameRate::isVoteValidForMrr(bool isVrrDevice) const {
@@ -572,7 +589,7 @@ bool LayerInfo::FrameRate::isVoteValidForMrr(bool isVrrDevice) const {
        return true;
        return true;
    }
    }


    if (category == FrameRateCategory::Default && vote.type != FrameRateCompatibility::Gte) {
    if (category == FrameRateCategory::Default) {
        return true;
        return true;
    }
    }


+3 −0
Original line number Original line Diff line number Diff line
@@ -146,6 +146,9 @@ public:
        // selection.
        // selection.
        bool isNoVote() const;
        bool isNoVote() const;


        // Returns true if the FrameRate has a valid valueless (0 Hz) frame rate type.
        bool isValuelessType() const;

        // Checks whether the given FrameRate's vote specifications is valid for MRR devices
        // Checks whether the given FrameRate's vote specifications is valid for MRR devices
        // given the current flagging.
        // given the current flagging.
        bool isVoteValidForMrr(bool isVrrDevice) const;
        bool isVoteValidForMrr(bool isVrrDevice) const;
+90 −6
Original line number Original line Diff line number Diff line
@@ -46,6 +46,7 @@ namespace android::scheduler {
using MockLayer = android::mock::MockLayer;
using MockLayer = android::mock::MockLayer;


using android::mock::createDisplayMode;
using android::mock::createDisplayMode;
using android::mock::createVrrDisplayMode;


// WARNING: LEGACY TESTS FOR LEGACY FRONT END
// WARNING: LEGACY TESTS FOR LEGACY FRONT END
// Update LayerHistoryIntegrationTest instead
// Update LayerHistoryIntegrationTest instead
@@ -138,11 +139,13 @@ protected:
        ASSERT_EQ(desiredRefreshRate, summary[0].desiredRefreshRate);
        ASSERT_EQ(desiredRefreshRate, summary[0].desiredRefreshRate);
    }
    }


    std::shared_ptr<RefreshRateSelector> mSelector =
    static constexpr auto kVrrModeId = DisplayModeId(2);
            std::make_shared<RefreshRateSelector>(makeModes(createDisplayMode(DisplayModeId(0),
    std::shared_ptr<RefreshRateSelector> mSelector = std::make_shared<RefreshRateSelector>(
                                                                              LO_FPS),
            makeModes(createDisplayMode(DisplayModeId(0), LO_FPS),
                                                            createDisplayMode(DisplayModeId(1),
                      createDisplayMode(DisplayModeId(1), HI_FPS),
                                                                              HI_FPS)),
                      createVrrDisplayMode(kVrrModeId, HI_FPS,
                                           hal::VrrConfig{.minFrameIntervalNs =
                                                                  HI_FPS.getPeriodNsecs()})),
            DisplayModeId(0));
            DisplayModeId(0));


    mock::SchedulerCallback mSchedulerCallback;
    mock::SchedulerCallback mSchedulerCallback;
@@ -548,6 +551,87 @@ TEST_F(LayerHistoryTest, oneLayerExplicitExactVote) {
    EXPECT_EQ(0, frequentLayerCount(time));
    EXPECT_EQ(0, frequentLayerCount(time));
}
}


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

    auto layer = createLayer();
    EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(true));
    EXPECT_CALL(*layer, getFrameRateForLayerTree())
            .WillRepeatedly(Return(Layer::FrameRate(33_Hz, Layer::FrameRateCompatibility::Gte,
                                                    Seamlessness::OnlySeamless,
                                                    FrameRateCategory::Default)));

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

    nsecs_t time = systemTime();
    for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
        history().record(layer->getSequence(), layer->getLayerProps(), time, time,
                         LayerHistory::LayerUpdateType::Buffer);
        time += HI_FPS_PERIOD;
    }

    ASSERT_EQ(1, summarizeLayerHistory(time).size());
    EXPECT_EQ(1, activeLayerCount());
    EXPECT_EQ(1, frequentLayerCount(time));
    EXPECT_EQ(LayerHistory::LayerVoteType::ExplicitGte, summarizeLayerHistory(time)[0].vote);
    EXPECT_EQ(33_Hz, summarizeLayerHistory(time)[0].desiredRefreshRate);
    EXPECT_EQ(FrameRateCategory::Default, summarizeLayerHistory(time)[0].frameRateCategory);

    // layer became inactive, but the vote stays
    setDefaultLayerVote(layer.get(), LayerHistory::LayerVoteType::Heuristic);
    time += MAX_ACTIVE_LAYER_PERIOD_NS.count();
    ASSERT_EQ(1, summarizeLayerHistory(time).size());
    EXPECT_EQ(1, activeLayerCount());
    EXPECT_EQ(0, frequentLayerCount(time));
    EXPECT_EQ(LayerHistory::LayerVoteType::ExplicitGte, summarizeLayerHistory(time)[0].vote);
    EXPECT_EQ(33_Hz, summarizeLayerHistory(time)[0].desiredRefreshRate);
    EXPECT_EQ(FrameRateCategory::Default, summarizeLayerHistory(time)[0].frameRateCategory);
}

// Test for MRR device with VRR features enabled.
TEST_F(LayerHistoryTest, oneLayerExplicitGte_nonVrr) {
    SET_FLAG_FOR_TEST(flags::frame_rate_category_mrr, true);
    // The vrr_config flag is explicitly not set false because this test for an MRR device
    // should still work in a VRR-capable world.

    auto layer = createLayer();
    EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(true));
    EXPECT_CALL(*layer, getFrameRateForLayerTree())
            .WillRepeatedly(Return(Layer::FrameRate(33_Hz, Layer::FrameRateCompatibility::Gte,
                                                    Seamlessness::OnlySeamless,
                                                    FrameRateCategory::Default)));

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

    nsecs_t time = systemTime();
    for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
        history().record(layer->getSequence(), layer->getLayerProps(), time, time,
                         LayerHistory::LayerUpdateType::Buffer);
        time += HI_FPS_PERIOD;
    }

    ASSERT_EQ(1, summarizeLayerHistory(time).size());
    EXPECT_EQ(1, activeLayerCount());
    EXPECT_EQ(1, frequentLayerCount(time));
    EXPECT_EQ(LayerHistory::LayerVoteType::Max, summarizeLayerHistory(time)[0].vote);
    EXPECT_EQ(0_Hz, summarizeLayerHistory(time)[0].desiredRefreshRate);
    EXPECT_EQ(FrameRateCategory::Default, summarizeLayerHistory(time)[0].frameRateCategory);

    // layer became infrequent, but the vote stays
    setDefaultLayerVote(layer.get(), LayerHistory::LayerVoteType::Heuristic);
    time += MAX_ACTIVE_LAYER_PERIOD_NS.count();
    ASSERT_EQ(1, summarizeLayerHistory(time).size());
    EXPECT_EQ(1, activeLayerCount());
    EXPECT_EQ(0, frequentLayerCount(time));
    EXPECT_EQ(LayerHistory::LayerVoteType::Max, summarizeLayerHistory(time)[0].vote);
    EXPECT_EQ(0_Hz, summarizeLayerHistory(time)[0].desiredRefreshRate);
    EXPECT_EQ(FrameRateCategory::Default, summarizeLayerHistory(time)[0].frameRateCategory);
}

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