1 /*
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 "LibSurfaceFlingerUnittests"
19
20 #include <scheduler/Fps.h>
21
22 #include "DisplayTransactionTestHelpers.h"
23 #include "FpsOps.h"
24
25 namespace android {
26 namespace {
27
28 class CreateDisplayTest : public DisplayTransactionTest {
29 public:
createDisplayWithRequestedRefreshRate(const String8 & name,uint64_t displayId,float pacesetterDisplayRefreshRate,float requestedRefreshRate,float expectedAdjustedRefreshRate)30 void createDisplayWithRequestedRefreshRate(const String8& name, uint64_t displayId,
31 float pacesetterDisplayRefreshRate,
32 float requestedRefreshRate,
33 float expectedAdjustedRefreshRate) {
34 // --------------------------------------------------------------------
35 // Call Expectations
36
37 // --------------------------------------------------------------------
38 // Invocation
39
40 sp<IBinder> displayToken = mFlinger.createDisplay(name, false, requestedRefreshRate);
41
42 // --------------------------------------------------------------------
43 // Postconditions
44
45 // The display should have been added to the current state
46 ASSERT_TRUE(hasCurrentDisplayState(displayToken));
47 const auto& display = getCurrentDisplayState(displayToken);
48 EXPECT_TRUE(display.isVirtual());
49 EXPECT_EQ(display.requestedRefreshRate, Fps::fromValue(requestedRefreshRate));
50 EXPECT_EQ(name.string(), display.displayName);
51
52 std::optional<VirtualDisplayId> vid =
53 DisplayId::fromValue<VirtualDisplayId>(displayId | DisplayId::FLAG_VIRTUAL);
54 ASSERT_TRUE(vid.has_value());
55
56 sp<DisplayDevice> device =
57 mFlinger.createVirtualDisplayDevice(displayToken, *vid, requestedRefreshRate);
58 EXPECT_TRUE(device->isVirtual());
59 device->adjustRefreshRate(Fps::fromValue(pacesetterDisplayRefreshRate));
60 // verifying desired value
61 EXPECT_EQ(device->getAdjustedRefreshRate(), Fps::fromValue(expectedAdjustedRefreshRate));
62 // verifying rounding up
63 if (requestedRefreshRate < pacesetterDisplayRefreshRate) {
64 EXPECT_GE(device->getAdjustedRefreshRate(), Fps::fromValue(requestedRefreshRate));
65 } else {
66 EXPECT_EQ(device->getAdjustedRefreshRate(),
67 Fps::fromValue(pacesetterDisplayRefreshRate));
68 }
69
70 // --------------------------------------------------------------------
71 // Cleanup conditions
72 }
73 };
74
TEST_F(CreateDisplayTest,createDisplaySetsCurrentStateForNonsecureDisplay)75 TEST_F(CreateDisplayTest, createDisplaySetsCurrentStateForNonsecureDisplay) {
76 const String8 name("virtual.test");
77
78 // --------------------------------------------------------------------
79 // Call Expectations
80
81 // --------------------------------------------------------------------
82 // Invocation
83
84 sp<IBinder> displayToken = mFlinger.createDisplay(name, false);
85
86 // --------------------------------------------------------------------
87 // Postconditions
88
89 // The display should have been added to the current state
90 ASSERT_TRUE(hasCurrentDisplayState(displayToken));
91 const auto& display = getCurrentDisplayState(displayToken);
92 EXPECT_TRUE(display.isVirtual());
93 EXPECT_FALSE(display.isSecure);
94 EXPECT_EQ(name.string(), display.displayName);
95
96 // --------------------------------------------------------------------
97 // Cleanup conditions
98
99 // Creating the display commits a display transaction.
100 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
101 }
102
TEST_F(CreateDisplayTest,createDisplaySetsCurrentStateForSecureDisplay)103 TEST_F(CreateDisplayTest, createDisplaySetsCurrentStateForSecureDisplay) {
104 const String8 name("virtual.test");
105
106 // --------------------------------------------------------------------
107 // Call Expectations
108
109 // --------------------------------------------------------------------
110 // Invocation
111 int64_t oldId = IPCThreadState::self()->clearCallingIdentity();
112 // Set the calling identity to graphics so captureDisplay with secure is allowed.
113 IPCThreadState::self()->restoreCallingIdentity(static_cast<int64_t>(AID_GRAPHICS) << 32 |
114 AID_GRAPHICS);
115 sp<IBinder> displayToken = mFlinger.createDisplay(name, true);
116 IPCThreadState::self()->restoreCallingIdentity(oldId);
117
118 // --------------------------------------------------------------------
119 // Postconditions
120
121 // The display should have been added to the current state
122 ASSERT_TRUE(hasCurrentDisplayState(displayToken));
123 const auto& display = getCurrentDisplayState(displayToken);
124 EXPECT_TRUE(display.isVirtual());
125 EXPECT_TRUE(display.isSecure);
126 EXPECT_EQ(name.string(), display.displayName);
127
128 // --------------------------------------------------------------------
129 // Cleanup conditions
130
131 // Creating the display commits a display transaction.
132 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
133 }
134
135 // Requesting 0 tells SF not to do anything, i.e., default to refresh as physical displays
TEST_F(CreateDisplayTest,createDisplayWithRequestedRefreshRate0)136 TEST_F(CreateDisplayTest, createDisplayWithRequestedRefreshRate0) {
137 const String8 displayName("virtual.test");
138 const uint64_t displayId = 123ull;
139 const float kPacesetterDisplayRefreshRate = 60.f;
140 const float kRequestedRefreshRate = 0.f;
141 const float kExpectedAdjustedRefreshRate = 0.f;
142 createDisplayWithRequestedRefreshRate(displayName, displayId, kPacesetterDisplayRefreshRate,
143 kRequestedRefreshRate, kExpectedAdjustedRefreshRate);
144 }
145
146 // Requesting negative refresh rate, will be ignored, same as requesting 0
TEST_F(CreateDisplayTest,createDisplayWithRequestedRefreshRateNegative)147 TEST_F(CreateDisplayTest, createDisplayWithRequestedRefreshRateNegative) {
148 const String8 displayName("virtual.test");
149 const uint64_t displayId = 123ull;
150 const float kPacesetterDisplayRefreshRate = 60.f;
151 const float kRequestedRefreshRate = -60.f;
152 const float kExpectedAdjustedRefreshRate = 0.f;
153 createDisplayWithRequestedRefreshRate(displayName, displayId, kPacesetterDisplayRefreshRate,
154 kRequestedRefreshRate, kExpectedAdjustedRefreshRate);
155 }
156
157 // Requesting a higher refresh rate than the pacesetter
TEST_F(CreateDisplayTest,createDisplayWithRequestedRefreshRateHigh)158 TEST_F(CreateDisplayTest, createDisplayWithRequestedRefreshRateHigh) {
159 const String8 displayName("virtual.test");
160 const uint64_t displayId = 123ull;
161 const float kPacesetterDisplayRefreshRate = 60.f;
162 const float kRequestedRefreshRate = 90.f;
163 const float kExpectedAdjustedRefreshRate = 60.f;
164 createDisplayWithRequestedRefreshRate(displayName, displayId, kPacesetterDisplayRefreshRate,
165 kRequestedRefreshRate, kExpectedAdjustedRefreshRate);
166 }
167
168 // Requesting the same refresh rate as the pacesetter
TEST_F(CreateDisplayTest,createDisplayWithRequestedRefreshRateSame)169 TEST_F(CreateDisplayTest, createDisplayWithRequestedRefreshRateSame) {
170 const String8 displayName("virtual.test");
171 const uint64_t displayId = 123ull;
172 const float kPacesetterDisplayRefreshRate = 60.f;
173 const float kRequestedRefreshRate = 60.f;
174 const float kExpectedAdjustedRefreshRate = 60.f;
175 createDisplayWithRequestedRefreshRate(displayName, displayId, kPacesetterDisplayRefreshRate,
176 kRequestedRefreshRate, kExpectedAdjustedRefreshRate);
177 }
178
179 // Requesting a divisor (30) of the pacesetter (60) should be honored
TEST_F(CreateDisplayTest,createDisplayWithRequestedRefreshRateDivisor)180 TEST_F(CreateDisplayTest, createDisplayWithRequestedRefreshRateDivisor) {
181 const String8 displayName("virtual.test");
182 const uint64_t displayId = 123ull;
183 const float kPacesetterDisplayRefreshRate = 60.f;
184 const float kRequestedRefreshRate = 30.f;
185 const float kExpectedAdjustedRefreshRate = 30.f;
186 createDisplayWithRequestedRefreshRate(displayName, displayId, kPacesetterDisplayRefreshRate,
187 kRequestedRefreshRate, kExpectedAdjustedRefreshRate);
188 }
189
190 // Requesting a non divisor (45) of the pacesetter (120) should round up to a divisor (60)
TEST_F(CreateDisplayTest,createDisplayWithRequestedRefreshRateNoneDivisor)191 TEST_F(CreateDisplayTest, createDisplayWithRequestedRefreshRateNoneDivisor) {
192 const String8 displayName("virtual.test");
193 const uint64_t displayId = 123ull;
194 const float kPacesetterDisplayRefreshRate = 120.f;
195 const float kRequestedRefreshRate = 45.f;
196 const float kExpectedAdjustedRefreshRate = 60.f;
197 createDisplayWithRequestedRefreshRate(displayName, displayId, kPacesetterDisplayRefreshRate,
198 kRequestedRefreshRate, kExpectedAdjustedRefreshRate);
199 }
200
201 // Requesting a non divisor (75) of the pacesetter (120) should round up to pacesetter (120)
TEST_F(CreateDisplayTest,createDisplayWithRequestedRefreshRateNoneDivisorMax)202 TEST_F(CreateDisplayTest, createDisplayWithRequestedRefreshRateNoneDivisorMax) {
203 const String8 displayName("virtual.test");
204 const uint64_t displayId = 123ull;
205 const float kPacesetterDisplayRefreshRate = 120.f;
206 const float kRequestedRefreshRate = 75.f;
207 const float kExpectedAdjustedRefreshRate = 120.f;
208 createDisplayWithRequestedRefreshRate(displayName, displayId, kPacesetterDisplayRefreshRate,
209 kRequestedRefreshRate, kExpectedAdjustedRefreshRate);
210 }
211
212 } // namespace
213 } // namespace android
214