diff options
| -rw-r--r-- | services/surfaceflinger/Scheduler/LayerInfoV2.cpp | 13 | ||||
| -rw-r--r-- | services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp | 41 |
2 files changed, 51 insertions, 3 deletions
diff --git a/services/surfaceflinger/Scheduler/LayerInfoV2.cpp b/services/surfaceflinger/Scheduler/LayerInfoV2.cpp index bf1fb88de7..44b4264f20 100644 --- a/services/surfaceflinger/Scheduler/LayerInfoV2.cpp +++ b/services/surfaceflinger/Scheduler/LayerInfoV2.cpp @@ -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) { diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp index 6fca673f6b..15207c94a3 100644 --- a/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp +++ b/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp @@ -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 |