blob: be76e8fd2f12b02f81bdcdb4afeb2cdb44d22ab0 [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"
23#include "Scheduler/LayerHistory.h"
24#include "Scheduler/LayerInfo.h"
25
26namespace android::scheduler {
27
28class LayerInfoTest : public testing::Test {
29protected:
30 using FrameTimeData = LayerInfo::FrameTimeData;
31
32 void setFrameTimes(const std::deque<FrameTimeData>& frameTimes) {
33 layerInfo.mFrameTimes = frameTimes;
34 }
35
36 void setLastRefreshRate(Fps fps) {
37 layerInfo.mLastRefreshRate.reported = fps;
38 layerInfo.mLastRefreshRate.calculated = fps;
39 }
40
41 auto calculateAverageFrameTime() { return layerInfo.calculateAverageFrameTime(); }
42
43 LayerInfo layerInfo{"TestLayerInfo", LayerHistory::LayerVoteType::Heuristic};
44};
45
46namespace {
47
48TEST_F(LayerInfoTest, prefersPresentTime) {
49 std::deque<FrameTimeData> frameTimes;
50 constexpr auto kExpectedFps = Fps(50.0f);
51 constexpr auto kPeriod = kExpectedFps.getPeriodNsecs();
52 constexpr int kNumFrames = 10;
53 for (int i = 1; i <= kNumFrames; i++) {
54 frameTimes.push_back(FrameTimeData{.presentTime = kPeriod * i,
55 .queueTime = 0,
Marin Shalamanova7fe3042021-01-29 21:02:08 +010056 .pendingModeChange = false});
Marin Shalamanov2045d5b2020-12-28 18:11:41 +010057 }
58 setFrameTimes(frameTimes);
59 const auto averageFrameTime = calculateAverageFrameTime();
60 ASSERT_TRUE(averageFrameTime.has_value());
61 const auto averageFps = Fps::fromPeriodNsecs(*averageFrameTime);
62 ASSERT_TRUE(kExpectedFps.equalsWithMargin(averageFps))
63 << "Expected " << averageFps << " to be equal to " << kExpectedFps;
64}
65
66TEST_F(LayerInfoTest, fallbacksToQueueTimeIfNoPresentTime) {
67 std::deque<FrameTimeData> frameTimes;
68 constexpr auto kExpectedFps = Fps(50.0f);
69 constexpr auto kPeriod = kExpectedFps.getPeriodNsecs();
70 constexpr int kNumFrames = 10;
71 for (int i = 1; i <= kNumFrames; i++) {
72 frameTimes.push_back(FrameTimeData{.presentTime = 0,
73 .queueTime = kPeriod * i,
Marin Shalamanova7fe3042021-01-29 21:02:08 +010074 .pendingModeChange = false});
Marin Shalamanov2045d5b2020-12-28 18:11:41 +010075 }
76 setFrameTimes(frameTimes);
77 setLastRefreshRate(Fps(20.0f)); // Set to some valid value
78 const auto averageFrameTime = calculateAverageFrameTime();
79 ASSERT_TRUE(averageFrameTime.has_value());
80 const auto averageFps = Fps::fromPeriodNsecs(*averageFrameTime);
81 ASSERT_TRUE(kExpectedFps.equalsWithMargin(averageFps))
82 << "Expected " << averageFps << " to be equal to " << kExpectedFps;
83}
84
85TEST_F(LayerInfoTest, returnsNulloptIfThereWasConfigChange) {
86 std::deque<FrameTimeData> frameTimesWithoutConfigChange;
87 const auto period = Fps(50.0f).getPeriodNsecs();
88 constexpr int kNumFrames = 10;
89 for (int i = 1; i <= kNumFrames; i++) {
90 frameTimesWithoutConfigChange.push_back(FrameTimeData{.presentTime = period * i,
91 .queueTime = period * i,
Marin Shalamanova7fe3042021-01-29 21:02:08 +010092 .pendingModeChange = false});
Marin Shalamanov2045d5b2020-12-28 18:11:41 +010093 }
94
95 setFrameTimes(frameTimesWithoutConfigChange);
96 ASSERT_TRUE(calculateAverageFrameTime().has_value());
97
98 {
99 // Config change in the first record
100 auto frameTimes = frameTimesWithoutConfigChange;
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100101 frameTimes[0].pendingModeChange = true;
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100102 setFrameTimes(frameTimes);
103 ASSERT_FALSE(calculateAverageFrameTime().has_value());
104 }
105
106 {
107 // Config change in the last record
108 auto frameTimes = frameTimesWithoutConfigChange;
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100109 frameTimes[frameTimes.size() - 1].pendingModeChange = true;
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100110 setFrameTimes(frameTimes);
111 ASSERT_FALSE(calculateAverageFrameTime().has_value());
112 }
113
114 {
115 // Config change in the middle
116 auto frameTimes = frameTimesWithoutConfigChange;
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100117 frameTimes[frameTimes.size() / 2].pendingModeChange = true;
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100118 setFrameTimes(frameTimes);
119 ASSERT_FALSE(calculateAverageFrameTime().has_value());
120 }
121}
122
123// A frame can be recorded twice with very close presentation or queue times.
124// Make sure that this doesn't influence the calculated average FPS.
125TEST_F(LayerInfoTest, ignoresSmallPeriods) {
126 std::deque<FrameTimeData> frameTimes;
127 constexpr auto kExpectedFps = Fps(50.0f);
128 constexpr auto kExpectedPeriod = kExpectedFps.getPeriodNsecs();
129 constexpr auto kSmallPeriod = Fps(150.0f).getPeriodNsecs();
130 constexpr int kNumIterations = 10;
131 for (int i = 1; i <= kNumIterations; i++) {
132 frameTimes.push_back(FrameTimeData{.presentTime = kExpectedPeriod * i,
133 .queueTime = 0,
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100134 .pendingModeChange = false});
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100135
136 // A duplicate frame
137 frameTimes.push_back(FrameTimeData{.presentTime = kExpectedPeriod * i + kSmallPeriod,
138 .queueTime = 0,
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100139 .pendingModeChange = false});
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100140 }
141 setFrameTimes(frameTimes);
142 const auto averageFrameTime = calculateAverageFrameTime();
143 ASSERT_TRUE(averageFrameTime.has_value());
144 const auto averageFps = Fps::fromPeriodNsecs(*averageFrameTime);
145 ASSERT_TRUE(kExpectedFps.equalsWithMargin(averageFps))
146 << "Expected " << averageFps << " to be equal to " << kExpectedFps;
147}
148
149// There may be a big period of time between two frames. Make sure that
150// this doesn't influence the calculated average FPS.
151TEST_F(LayerInfoTest, ignoresLargePeriods) {
152 std::deque<FrameTimeData> frameTimes;
153 constexpr auto kExpectedFps = Fps(50.0f);
154 constexpr auto kExpectedPeriod = kExpectedFps.getPeriodNsecs();
155 constexpr auto kLargePeriod = Fps(9.0f).getPeriodNsecs();
156
157 auto record = [&](nsecs_t time) {
158 frameTimes.push_back(
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100159 FrameTimeData{.presentTime = time, .queueTime = 0, .pendingModeChange = false});
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100160 };
161
162 auto time = kExpectedPeriod; // Start with non-zero time.
163 record(time);
164 time += kLargePeriod;
165 record(time);
166 constexpr int kNumIterations = 10;
167 for (int i = 1; i <= kNumIterations; i++) {
168 time += kExpectedPeriod;
169 record(time);
170 }
171
172 setFrameTimes(frameTimes);
173 const auto averageFrameTime = calculateAverageFrameTime();
174 ASSERT_TRUE(averageFrameTime.has_value());
175 const auto averageFps = Fps::fromPeriodNsecs(*averageFrameTime);
176 ASSERT_TRUE(kExpectedFps.equalsWithMargin(averageFps))
177 << "Expected " << averageFps << " to be equal to " << kExpectedFps;
178}
179
180} // namespace
181} // namespace android::scheduler