blob: f25994e39951cc59bb3ddaeec1f4788d8d9817f9 [file] [log] [blame]
Marin Shalamanov2045d5b2020-12-28 18:11:41 +01001/*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#undef LOG_TAG
18#define LOG_TAG "LayerInfoTest"
19
20#include <gtest/gtest.h>
21
22#include "Fps.h"
Dominik Laskowski6eab42d2021-09-13 14:34:13 -070023#include "FpsOps.h"
Marin Shalamanov2045d5b2020-12-28 18:11:41 +010024#include "Scheduler/LayerHistory.h"
25#include "Scheduler/LayerInfo.h"
26
27namespace android::scheduler {
28
29class LayerInfoTest : public testing::Test {
30protected:
31 using FrameTimeData = LayerInfo::FrameTimeData;
32
33 void setFrameTimes(const std::deque<FrameTimeData>& frameTimes) {
34 layerInfo.mFrameTimes = frameTimes;
35 }
36
37 void setLastRefreshRate(Fps fps) {
38 layerInfo.mLastRefreshRate.reported = fps;
39 layerInfo.mLastRefreshRate.calculated = fps;
40 }
41
42 auto calculateAverageFrameTime() { return layerInfo.calculateAverageFrameTime(); }
43
Ady Abrahambdda8f02021-04-01 16:06:11 -070044 LayerInfo layerInfo{"TestLayerInfo", 0, LayerHistory::LayerVoteType::Heuristic};
Marin Shalamanov2045d5b2020-12-28 18:11:41 +010045};
46
47namespace {
48
49TEST_F(LayerInfoTest, prefersPresentTime) {
50 std::deque<FrameTimeData> frameTimes;
Dominik Laskowski6eab42d2021-09-13 14:34:13 -070051 constexpr auto kExpectedFps = 50_Hz;
Marin Shalamanov2045d5b2020-12-28 18:11:41 +010052 constexpr auto kPeriod = kExpectedFps.getPeriodNsecs();
53 constexpr int kNumFrames = 10;
54 for (int i = 1; i <= kNumFrames; i++) {
55 frameTimes.push_back(FrameTimeData{.presentTime = kPeriod * i,
56 .queueTime = 0,
Marin Shalamanova7fe3042021-01-29 21:02:08 +010057 .pendingModeChange = false});
Marin Shalamanov2045d5b2020-12-28 18:11:41 +010058 }
59 setFrameTimes(frameTimes);
60 const auto averageFrameTime = calculateAverageFrameTime();
61 ASSERT_TRUE(averageFrameTime.has_value());
Dominik Laskowski6eab42d2021-09-13 14:34:13 -070062 ASSERT_EQ(kExpectedFps, Fps::fromPeriodNsecs(*averageFrameTime));
Marin Shalamanov2045d5b2020-12-28 18:11:41 +010063}
64
65TEST_F(LayerInfoTest, fallbacksToQueueTimeIfNoPresentTime) {
66 std::deque<FrameTimeData> frameTimes;
Dominik Laskowski6eab42d2021-09-13 14:34:13 -070067 constexpr auto kExpectedFps = 50_Hz;
Marin Shalamanov2045d5b2020-12-28 18:11:41 +010068 constexpr auto kPeriod = kExpectedFps.getPeriodNsecs();
69 constexpr int kNumFrames = 10;
70 for (int i = 1; i <= kNumFrames; i++) {
71 frameTimes.push_back(FrameTimeData{.presentTime = 0,
72 .queueTime = kPeriod * i,
Marin Shalamanova7fe3042021-01-29 21:02:08 +010073 .pendingModeChange = false});
Marin Shalamanov2045d5b2020-12-28 18:11:41 +010074 }
75 setFrameTimes(frameTimes);
Dominik Laskowski6eab42d2021-09-13 14:34:13 -070076 setLastRefreshRate(20_Hz); // Set to some valid value.
Marin Shalamanov2045d5b2020-12-28 18:11:41 +010077 const auto averageFrameTime = calculateAverageFrameTime();
78 ASSERT_TRUE(averageFrameTime.has_value());
Dominik Laskowski6eab42d2021-09-13 14:34:13 -070079 ASSERT_EQ(kExpectedFps, Fps::fromPeriodNsecs(*averageFrameTime));
Marin Shalamanov2045d5b2020-12-28 18:11:41 +010080}
81
82TEST_F(LayerInfoTest, returnsNulloptIfThereWasConfigChange) {
83 std::deque<FrameTimeData> frameTimesWithoutConfigChange;
Dominik Laskowski6eab42d2021-09-13 14:34:13 -070084 const auto period = (50_Hz).getPeriodNsecs();
Marin Shalamanov2045d5b2020-12-28 18:11:41 +010085 constexpr int kNumFrames = 10;
86 for (int i = 1; i <= kNumFrames; i++) {
87 frameTimesWithoutConfigChange.push_back(FrameTimeData{.presentTime = period * i,
88 .queueTime = period * i,
Marin Shalamanova7fe3042021-01-29 21:02:08 +010089 .pendingModeChange = false});
Marin Shalamanov2045d5b2020-12-28 18:11:41 +010090 }
91
92 setFrameTimes(frameTimesWithoutConfigChange);
93 ASSERT_TRUE(calculateAverageFrameTime().has_value());
94
95 {
96 // Config change in the first record
97 auto frameTimes = frameTimesWithoutConfigChange;
Marin Shalamanova7fe3042021-01-29 21:02:08 +010098 frameTimes[0].pendingModeChange = true;
Marin Shalamanov2045d5b2020-12-28 18:11:41 +010099 setFrameTimes(frameTimes);
100 ASSERT_FALSE(calculateAverageFrameTime().has_value());
101 }
102
103 {
104 // Config change in the last record
105 auto frameTimes = frameTimesWithoutConfigChange;
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100106 frameTimes[frameTimes.size() - 1].pendingModeChange = true;
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100107 setFrameTimes(frameTimes);
108 ASSERT_FALSE(calculateAverageFrameTime().has_value());
109 }
110
111 {
112 // Config change in the middle
113 auto frameTimes = frameTimesWithoutConfigChange;
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100114 frameTimes[frameTimes.size() / 2].pendingModeChange = true;
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100115 setFrameTimes(frameTimes);
116 ASSERT_FALSE(calculateAverageFrameTime().has_value());
117 }
118}
119
120// A frame can be recorded twice with very close presentation or queue times.
121// Make sure that this doesn't influence the calculated average FPS.
122TEST_F(LayerInfoTest, ignoresSmallPeriods) {
123 std::deque<FrameTimeData> frameTimes;
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700124 constexpr auto kExpectedFps = 50_Hz;
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100125 constexpr auto kExpectedPeriod = kExpectedFps.getPeriodNsecs();
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700126 constexpr auto kSmallPeriod = (250_Hz).getPeriodNsecs();
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100127 constexpr int kNumIterations = 10;
128 for (int i = 1; i <= kNumIterations; i++) {
129 frameTimes.push_back(FrameTimeData{.presentTime = kExpectedPeriod * i,
130 .queueTime = 0,
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100131 .pendingModeChange = false});
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100132
133 // A duplicate frame
134 frameTimes.push_back(FrameTimeData{.presentTime = kExpectedPeriod * i + kSmallPeriod,
135 .queueTime = 0,
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100136 .pendingModeChange = false});
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100137 }
138 setFrameTimes(frameTimes);
139 const auto averageFrameTime = calculateAverageFrameTime();
140 ASSERT_TRUE(averageFrameTime.has_value());
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700141 ASSERT_EQ(kExpectedFps, Fps::fromPeriodNsecs(*averageFrameTime));
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100142}
143
144// There may be a big period of time between two frames. Make sure that
145// this doesn't influence the calculated average FPS.
146TEST_F(LayerInfoTest, ignoresLargePeriods) {
147 std::deque<FrameTimeData> frameTimes;
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700148 constexpr auto kExpectedFps = 50_Hz;
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100149 constexpr auto kExpectedPeriod = kExpectedFps.getPeriodNsecs();
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700150 constexpr auto kLargePeriod = (9_Hz).getPeriodNsecs();
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100151
152 auto record = [&](nsecs_t time) {
153 frameTimes.push_back(
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100154 FrameTimeData{.presentTime = time, .queueTime = 0, .pendingModeChange = false});
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100155 };
156
157 auto time = kExpectedPeriod; // Start with non-zero time.
158 record(time);
159 time += kLargePeriod;
160 record(time);
161 constexpr int kNumIterations = 10;
162 for (int i = 1; i <= kNumIterations; i++) {
163 time += kExpectedPeriod;
164 record(time);
165 }
166
167 setFrameTimes(frameTimes);
168 const auto averageFrameTime = calculateAverageFrameTime();
169 ASSERT_TRUE(averageFrameTime.has_value());
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700170 ASSERT_EQ(kExpectedFps, Fps::fromPeriodNsecs(*averageFrameTime));
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100171}
172
173} // namespace
174} // namespace android::scheduler