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

Commit 38601a9b authored by Ady Abraham's avatar Ady Abraham
Browse files

SurfaceFlinger: refresh rate calculation when no timestamps

Frames without presentation timestamp should be excluded from refresh
rate calculation. This changes skips these frames instead of just
declaring refresh rate unknown. This impacts scenarios that we get few
frames without presentation timestamps where the majority does include
them.

Bug: 155710271
Test: Facebook feed videos
Change-Id: Id79f4d6cb87b2fd6fb787fab2d863f50be99cac5
parent 42649171
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -111,21 +111,28 @@ std::optional<float> LayerInfoV2::calculateRefreshRateIfPossible() {

    // Calculate the refresh rate by finding the average delta between frames
    nsecs_t totalPresentTimeDeltas = 0;
    int numFrames = 0;
    for (auto it = mFrameTimes.begin(); it != mFrameTimes.end() - 1; ++it) {
        // If there are no presentation timestamp provided we can't calculate the refresh rate
        if (it->presetTime == 0 || (it + 1)->presetTime == 0) {
            return std::nullopt;
            continue;
        }

        totalPresentTimeDeltas +=
                std::max(((it + 1)->presetTime - it->presetTime), mHighRefreshRatePeriod);
        numFrames++;
    }
    if (numFrames == 0) {
        return std::nullopt;
    }
    const float averageFrameTime =
            static_cast<float>(totalPresentTimeDeltas) / (mFrameTimes.size() - 1);
    const float averageFrameTime = static_cast<float>(totalPresentTimeDeltas) / numFrames;

    // Now once we calculated the refresh rate we need to make sure that all the frames we captured
    // are evenly distributed and we don't calculate the average across some burst of frames.
    for (auto it = mFrameTimes.begin(); it != mFrameTimes.end() - 1; ++it) {
        if (it->presetTime == 0 || (it + 1)->presetTime == 0) {
            continue;
        }
        const nsecs_t presentTimeDeltas =
                std::max(((it + 1)->presetTime - it->presetTime), mHighRefreshRatePeriod);
        if (std::abs(presentTimeDeltas - averageFrameTime) > 2 * averageFrameTime) {
+41 −0
Original line number Diff line number Diff line
@@ -512,5 +512,46 @@ TEST_F(LayerHistoryTestV2, inactiveLayers) {
    EXPECT_EQ(1, frequentLayerCount(time));
}

TEST_F(LayerHistoryTestV2, calculateRefreshRate30Hz) {
    const auto layer = createLayer();
    EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(true));
    EXPECT_CALL(*layer, getFrameRateForLayerTree()).WillRepeatedly(Return(Layer::FrameRate()));

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

    nsecs_t time = systemTime();
    const nsecs_t frameTime = 33'333'333;

    for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
        time += frameTime;
        history().record(layer.get(), time, time);
    }
    ASSERT_EQ(1, history().summarize(time).size());
    EXPECT_EQ(LayerHistory::LayerVoteType::Heuristic, history().summarize(time)[0].vote);
    EXPECT_FLOAT_EQ(30.f, history().summarize(time)[0].desiredRefreshRate);
}

TEST_F(LayerHistoryTestV2, calculateRefreshRate30HzSkipTimestamp) {
    const auto layer = createLayer();
    EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(true));
    EXPECT_CALL(*layer, getFrameRateForLayerTree()).WillRepeatedly(Return(Layer::FrameRate()));

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

    nsecs_t time = systemTime();
    const nsecs_t frameTime = 33'333'333;

    for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
        time += frameTime;
        const auto timestamp = (i == PRESENT_TIME_HISTORY_SIZE / 2) ? 0 : time;
        history().record(layer.get(), timestamp, time);
    }
    ASSERT_EQ(1, history().summarize(time).size());
    EXPECT_EQ(LayerHistory::LayerVoteType::Heuristic, history().summarize(time)[0].vote);
    EXPECT_FLOAT_EQ(30.f, history().summarize(time)[0].desiredRefreshRate);
}

} // namespace
} // namespace android::scheduler