blob: 5c2d2e1f4351e6fe2ee98af0d28ff4078f2e1006 [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
Dominik Laskowskif6b4ba62021-11-09 12:46:10 -080022#include <scheduler/Fps.h>
23
Dominik Laskowski6eab42d2021-09-13 14:34:13 -070024#include "FpsOps.h"
Marin Shalamanov2045d5b2020-12-28 18:11:41 +010025#include "Scheduler/LayerHistory.h"
26#include "Scheduler/LayerInfo.h"
27
28namespace android::scheduler {
29
30class LayerInfoTest : public testing::Test {
31protected:
32 using FrameTimeData = LayerInfo::FrameTimeData;
33
34 void setFrameTimes(const std::deque<FrameTimeData>& frameTimes) {
35 layerInfo.mFrameTimes = frameTimes;
36 }
37
38 void setLastRefreshRate(Fps fps) {
39 layerInfo.mLastRefreshRate.reported = fps;
40 layerInfo.mLastRefreshRate.calculated = fps;
41 }
42
43 auto calculateAverageFrameTime() { return layerInfo.calculateAverageFrameTime(); }
44
Ady Abrahambdda8f02021-04-01 16:06:11 -070045 LayerInfo layerInfo{"TestLayerInfo", 0, LayerHistory::LayerVoteType::Heuristic};
Marin Shalamanov2045d5b2020-12-28 18:11:41 +010046};
47
48namespace {
49
50TEST_F(LayerInfoTest, prefersPresentTime) {
51 std::deque<FrameTimeData> frameTimes;
Dominik Laskowski6eab42d2021-09-13 14:34:13 -070052 constexpr auto kExpectedFps = 50_Hz;
Marin Shalamanov2045d5b2020-12-28 18:11:41 +010053 constexpr auto kPeriod = kExpectedFps.getPeriodNsecs();
54 constexpr int kNumFrames = 10;
55 for (int i = 1; i <= kNumFrames; i++) {
56 frameTimes.push_back(FrameTimeData{.presentTime = kPeriod * i,
57 .queueTime = 0,
Marin Shalamanova7fe3042021-01-29 21:02:08 +010058 .pendingModeChange = false});
Marin Shalamanov2045d5b2020-12-28 18:11:41 +010059 }
60 setFrameTimes(frameTimes);
61 const auto averageFrameTime = calculateAverageFrameTime();
62 ASSERT_TRUE(averageFrameTime.has_value());
Dominik Laskowski6eab42d2021-09-13 14:34:13 -070063 ASSERT_EQ(kExpectedFps, Fps::fromPeriodNsecs(*averageFrameTime));
Marin Shalamanov2045d5b2020-12-28 18:11:41 +010064}
65
66TEST_F(LayerInfoTest, fallbacksToQueueTimeIfNoPresentTime) {
67 std::deque<FrameTimeData> frameTimes;
Dominik Laskowski6eab42d2021-09-13 14:34:13 -070068 constexpr auto kExpectedFps = 50_Hz;
Marin Shalamanov2045d5b2020-12-28 18:11:41 +010069 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);
Dominik Laskowski6eab42d2021-09-13 14:34:13 -070077 setLastRefreshRate(20_Hz); // Set to some valid value.
Marin Shalamanov2045d5b2020-12-28 18:11:41 +010078 const auto averageFrameTime = calculateAverageFrameTime();
79 ASSERT_TRUE(averageFrameTime.has_value());
Dominik Laskowski6eab42d2021-09-13 14:34:13 -070080 ASSERT_EQ(kExpectedFps, Fps::fromPeriodNsecs(*averageFrameTime));
Marin Shalamanov2045d5b2020-12-28 18:11:41 +010081}
82
83TEST_F(LayerInfoTest, returnsNulloptIfThereWasConfigChange) {
84 std::deque<FrameTimeData> frameTimesWithoutConfigChange;
Dominik Laskowski6eab42d2021-09-13 14:34:13 -070085 const auto period = (50_Hz).getPeriodNsecs();
Marin Shalamanov2045d5b2020-12-28 18:11:41 +010086 constexpr int kNumFrames = 10;
87 for (int i = 1; i <= kNumFrames; i++) {
88 frameTimesWithoutConfigChange.push_back(FrameTimeData{.presentTime = period * i,
89 .queueTime = period * i,
Marin Shalamanova7fe3042021-01-29 21:02:08 +010090 .pendingModeChange = false});
Marin Shalamanov2045d5b2020-12-28 18:11:41 +010091 }
92
93 setFrameTimes(frameTimesWithoutConfigChange);
94 ASSERT_TRUE(calculateAverageFrameTime().has_value());
95
96 {
97 // Config change in the first record
98 auto frameTimes = frameTimesWithoutConfigChange;
Marin Shalamanova7fe3042021-01-29 21:02:08 +010099 frameTimes[0].pendingModeChange = true;
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100100 setFrameTimes(frameTimes);
101 ASSERT_FALSE(calculateAverageFrameTime().has_value());
102 }
103
104 {
105 // Config change in the last record
106 auto frameTimes = frameTimesWithoutConfigChange;
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100107 frameTimes[frameTimes.size() - 1].pendingModeChange = true;
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100108 setFrameTimes(frameTimes);
109 ASSERT_FALSE(calculateAverageFrameTime().has_value());
110 }
111
112 {
113 // Config change in the middle
114 auto frameTimes = frameTimesWithoutConfigChange;
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100115 frameTimes[frameTimes.size() / 2].pendingModeChange = true;
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100116 setFrameTimes(frameTimes);
117 ASSERT_FALSE(calculateAverageFrameTime().has_value());
118 }
119}
120
121// A frame can be recorded twice with very close presentation or queue times.
122// Make sure that this doesn't influence the calculated average FPS.
123TEST_F(LayerInfoTest, ignoresSmallPeriods) {
124 std::deque<FrameTimeData> frameTimes;
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700125 constexpr auto kExpectedFps = 50_Hz;
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100126 constexpr auto kExpectedPeriod = kExpectedFps.getPeriodNsecs();
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700127 constexpr auto kSmallPeriod = (250_Hz).getPeriodNsecs();
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100128 constexpr int kNumIterations = 10;
129 for (int i = 1; i <= kNumIterations; i++) {
130 frameTimes.push_back(FrameTimeData{.presentTime = kExpectedPeriod * i,
131 .queueTime = 0,
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100132 .pendingModeChange = false});
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100133
134 // A duplicate frame
135 frameTimes.push_back(FrameTimeData{.presentTime = kExpectedPeriod * i + kSmallPeriod,
136 .queueTime = 0,
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100137 .pendingModeChange = false});
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100138 }
139 setFrameTimes(frameTimes);
140 const auto averageFrameTime = calculateAverageFrameTime();
141 ASSERT_TRUE(averageFrameTime.has_value());
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700142 ASSERT_EQ(kExpectedFps, Fps::fromPeriodNsecs(*averageFrameTime));
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100143}
144
145// There may be a big period of time between two frames. Make sure that
146// this doesn't influence the calculated average FPS.
147TEST_F(LayerInfoTest, ignoresLargePeriods) {
148 std::deque<FrameTimeData> frameTimes;
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700149 constexpr auto kExpectedFps = 50_Hz;
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100150 constexpr auto kExpectedPeriod = kExpectedFps.getPeriodNsecs();
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700151 constexpr auto kLargePeriod = (9_Hz).getPeriodNsecs();
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100152
153 auto record = [&](nsecs_t time) {
154 frameTimes.push_back(
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100155 FrameTimeData{.presentTime = time, .queueTime = 0, .pendingModeChange = false});
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100156 };
157
158 auto time = kExpectedPeriod; // Start with non-zero time.
159 record(time);
160 time += kLargePeriod;
161 record(time);
162 constexpr int kNumIterations = 10;
163 for (int i = 1; i <= kNumIterations; i++) {
164 time += kExpectedPeriod;
165 record(time);
166 }
167
168 setFrameTimes(frameTimes);
169 const auto averageFrameTime = calculateAverageFrameTime();
170 ASSERT_TRUE(averageFrameTime.has_value());
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700171 ASSERT_EQ(kExpectedFps, Fps::fromPeriodNsecs(*averageFrameTime));
Marin Shalamanov2045d5b2020-12-28 18:11:41 +0100172}
173
174} // namespace
175} // namespace android::scheduler