• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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