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

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

Snap for 6544675 from 983e568b to rvc-release

Change-Id: Ib9a1188210584362abd75b3df1696e086f44422e
parents c3594a07 983e568b
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -192,7 +192,7 @@ void LayerHistoryV2::partitionLayers(nsecs_t now) {
            trace(weak, LayerHistory::LayerVoteType::NoVote, 0);
        }

        info->clearHistory();
        info->onLayerInactive(now);
        std::swap(mLayerInfos[i], mLayerInfos[--mActiveLayersEnd]);
    }

@@ -213,7 +213,7 @@ void LayerHistoryV2::clear() {
    std::lock_guard lock(mLock);

    for (const auto& [layer, info] : activeLayers()) {
        info->clearHistory();
        info->clearHistory(systemTime());
    }
}
} // namespace android::scheduler::impl
+2 −9
Original line number Diff line number Diff line
@@ -57,21 +57,14 @@ bool LayerInfoV2::isFrameTimeValid(const FrameTimeData& frameTime) const {
}

bool LayerInfoV2::isFrequent(nsecs_t now) const {
    // Find the first valid frame time
    auto it = mFrameTimes.begin();
    for (; it != mFrameTimes.end(); ++it) {
        if (isFrameTimeValid(*it)) {
            break;
        }
    }

    // If we know nothing about this layer we consider it as frequent as it might be the start
    // of an animation.
    if (std::distance(it, mFrameTimes.end()) < FREQUENT_LAYER_WINDOW_SIZE) {
    if (mFrameTimes.size() < FREQUENT_LAYER_WINDOW_SIZE) {
        return true;
    }

    // Find the first active frame
    auto it = mFrameTimes.begin();
    for (; it != mFrameTimes.end(); ++it) {
        if (it->queueTime >= getActiveLayerThreshold(now)) {
            break;
+8 −2
Original line number Diff line number Diff line
@@ -83,15 +83,21 @@ public:
    // updated time, the updated time is the present time.
    nsecs_t getLastUpdatedTime() const { return mLastUpdatedTime; }

    void clearHistory() {
    void onLayerInactive(nsecs_t now) {
        // Mark mFrameTimeValidSince to now to ignore all previous frame times.
        // We are not deleting the old frame to keep track of whether we should treat the first
        // buffer as Max as we don't know anything about this layer or Min as this layer is
        // posting infrequent updates.
        mFrameTimeValidSince = std::chrono::steady_clock::now();
        const auto timePoint = std::chrono::nanoseconds(now);
        mFrameTimeValidSince = std::chrono::time_point<std::chrono::steady_clock>(timePoint);
        mLastReportedRefreshRate = 0.0f;
    }

    void clearHistory(nsecs_t now) {
        onLayerInactive(now);
        mFrameTimes.clear();
    }

private:
    // Used to store the layer timestamps
    struct FrameTimeData {
+74 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ protected:
    static constexpr auto PRESENT_TIME_HISTORY_SIZE = LayerInfoV2::HISTORY_SIZE;
    static constexpr auto MAX_FREQUENT_LAYER_PERIOD_NS = LayerInfoV2::MAX_FREQUENT_LAYER_PERIOD_NS;
    static constexpr auto FREQUENT_LAYER_WINDOW_SIZE = LayerInfoV2::FREQUENT_LAYER_WINDOW_SIZE;
    static constexpr auto PRESENT_TIME_HISTORY_TIME = LayerInfoV2::HISTORY_TIME;

    static constexpr float LO_FPS = 30.f;
    static constexpr auto LO_FPS_PERIOD = static_cast<nsecs_t>(1e9f / LO_FPS);
@@ -71,6 +72,9 @@ protected:
    }

    auto createLayer() { return sp<mock::MockLayer>(new mock::MockLayer(mFlinger.flinger())); }
    auto createLayer(std::string name) {
        return sp<mock::MockLayer>(new mock::MockLayer(mFlinger.flinger(), std::move(name)));
    }

    Hwc2::mock::Display mDisplay;
    RefreshRateConfigs mConfigs{{HWC2::Display::Config::Builder(mDisplay, 0)
@@ -541,5 +545,75 @@ TEST_F(LayerHistoryTestV2, invisibleExplicitLayer) {
    EXPECT_EQ(2, frequentLayerCount(time));
}

class LayerHistoryTestV2Parameterized
      : public LayerHistoryTestV2,
        public testing::WithParamInterface<std::chrono::nanoseconds> {};

TEST_P(LayerHistoryTestV2Parameterized, HeuristicLayerWithInfrequentLayer) {
    std::chrono::nanoseconds infrequentUpdateDelta = GetParam();
    auto heuristicLayer = createLayer("HeuristicLayer");

    EXPECT_CALL(*heuristicLayer, isVisible()).WillRepeatedly(Return(true));
    EXPECT_CALL(*heuristicLayer, getFrameRateForLayerTree())
            .WillRepeatedly(Return(Layer::FrameRate()));

    auto infrequentLayer = createLayer("InfrequentLayer");
    EXPECT_CALL(*infrequentLayer, isVisible()).WillRepeatedly(Return(true));
    EXPECT_CALL(*infrequentLayer, getFrameRateForLayerTree())
            .WillRepeatedly(Return(Layer::FrameRate()));

    const nsecs_t startTime = systemTime();

    const std::chrono::nanoseconds heuristicUpdateDelta = 41'666'667ns;
    history().record(heuristicLayer.get(), startTime, startTime);
    history().record(infrequentLayer.get(), startTime, startTime);

    nsecs_t time = startTime;
    nsecs_t lastInfrequentUpdate = startTime;
    const int totalInfrequentLayerUpdates = FREQUENT_LAYER_WINDOW_SIZE * 5;
    int infrequentLayerUpdates = 0;
    while (infrequentLayerUpdates <= totalInfrequentLayerUpdates) {
        time += heuristicUpdateDelta.count();
        history().record(heuristicLayer.get(), time, time);

        if (time - lastInfrequentUpdate >= infrequentUpdateDelta.count()) {
            ALOGI("submitting infrequent frame [%d/%d]", infrequentLayerUpdates,
                  totalInfrequentLayerUpdates);
            lastInfrequentUpdate = time;
            history().record(infrequentLayer.get(), time, time);
            infrequentLayerUpdates++;
        }

        if (time - startTime > PRESENT_TIME_HISTORY_TIME.count()) {
            ASSERT_NE(0, history().summarize(time).size());
            ASSERT_GE(2, history().summarize(time).size());

            bool max = false;
            bool min = false;
            float heuristic = 0;
            for (const auto& layer : history().summarize(time)) {
                if (layer.vote == LayerHistory::LayerVoteType::Heuristic) {
                    heuristic = layer.desiredRefreshRate;
                } else if (layer.vote == LayerHistory::LayerVoteType::Max) {
                    max = true;
                } else if (layer.vote == LayerHistory::LayerVoteType::Min) {
                    min = true;
                }
            }

            if (infrequentLayerUpdates > FREQUENT_LAYER_WINDOW_SIZE) {
                EXPECT_FLOAT_EQ(24.0f, heuristic);
                EXPECT_FALSE(max);
                if (history().summarize(time).size() == 2) {
                    EXPECT_TRUE(min);
                }
            }
        }
    }
}

INSTANTIATE_TEST_CASE_P(LeapYearTests, LayerHistoryTestV2Parameterized,
                        ::testing::Values(1s, 2s, 3s, 4s, 5s));

} // namespace
} // namespace android::scheduler
+3 −2
Original line number Diff line number Diff line
@@ -24,8 +24,9 @@ namespace android::mock {

class MockLayer : public Layer {
public:
    explicit MockLayer(SurfaceFlinger* flinger)
          : Layer(LayerCreationArgs(flinger, nullptr, "TestLayer", 800, 600, 0, {})) {}
    MockLayer(SurfaceFlinger* flinger, std::string name)
          : Layer(LayerCreationArgs(flinger, nullptr, std::move(name), 800, 600, 0, {})) {}
    explicit MockLayer(SurfaceFlinger* flinger) : MockLayer(flinger, "TestLayer") {}

    MOCK_CONST_METHOD0(getType, const char*());
    MOCK_METHOD0(getFrameSelectionPriority, int32_t());