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 <ftl/fake_guard.h>
21
22 #include "DisplayHardware/DisplayMode.h"
23
24 #include "DisplayTransactionTestHelpers.h"
25
26 namespace android {
27 namespace {
28
29 using hal::RenderIntent;
30
31 // For this variant, SurfaceFlinger should configure itself with wide display
32 // support, and the display should respond with an non-empty list of supported
33 // color modes. Wide-color support should be configured.
34 template <typename Display>
35 struct WideColorP3ColorimetricSupportedVariant {
36 static constexpr bool WIDE_COLOR_SUPPORTED = true;
37
injectConfigChangeandroid::__anon89ba961e0111::WideColorP3ColorimetricSupportedVariant38 static void injectConfigChange(DisplayTransactionTest* test) {
39 test->mFlinger.mutableSupportsWideColor() = true;
40 test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::kUnmanaged;
41 }
42
setupComposerCallExpectationsandroid::__anon89ba961e0111::WideColorP3ColorimetricSupportedVariant43 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
44 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_DATASPACE)).Times(1);
45
46 EXPECT_CALL(*test->mComposer,
47 getRenderIntents(Display::HWC_DISPLAY_ID, ColorMode::DISPLAY_P3, _))
48 .WillOnce(DoAll(SetArgPointee<2>(
49 std::vector<RenderIntent>({RenderIntent::COLORIMETRIC})),
50 Return(Error::NONE)));
51 EXPECT_CALL(*test->mComposer,
52 setColorMode(Display::HWC_DISPLAY_ID, ColorMode::SRGB,
53 RenderIntent::COLORIMETRIC))
54 .WillOnce(Return(Error::NONE));
55 }
56 };
57
58 template <typename Display>
59 struct Hdr10PlusSupportedVariant {
60 static constexpr bool HDR10_PLUS_SUPPORTED = true;
61 static constexpr bool HDR10_SUPPORTED = true;
62 static constexpr bool HDR_HLG_SUPPORTED = false;
63 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
setupComposerCallExpectationsandroid::__anon89ba961e0111::Hdr10PlusSupportedVariant64 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
65 EXPECT_CALL(*test->mComposer, getHdrCapabilities(_, _, _, _, _))
66 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>({
67 Hdr::HDR10_PLUS,
68 Hdr::HDR10,
69 })),
70 Return(Error::NONE)));
71 }
72 };
73
74 // For this variant, the composer should respond with a non-empty list of HDR
75 // modes containing HDR10, so HDR10 support should be configured.
76 template <typename Display>
77 struct Hdr10SupportedVariant {
78 static constexpr bool HDR10_PLUS_SUPPORTED = false;
79 static constexpr bool HDR10_SUPPORTED = true;
80 static constexpr bool HDR_HLG_SUPPORTED = false;
81 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
setupComposerCallExpectationsandroid::__anon89ba961e0111::Hdr10SupportedVariant82 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
83 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
84 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>({Hdr::HDR10})),
85 Return(Error::NONE)));
86 }
87 };
88
89 // For this variant, the composer should respond with a non-empty list of HDR
90 // modes containing HLG, so HLG support should be configured.
91 template <typename Display>
92 struct HdrHlgSupportedVariant {
93 static constexpr bool HDR10_PLUS_SUPPORTED = false;
94 static constexpr bool HDR10_SUPPORTED = false;
95 static constexpr bool HDR_HLG_SUPPORTED = true;
96 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
setupComposerCallExpectationsandroid::__anon89ba961e0111::HdrHlgSupportedVariant97 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
98 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
99 .WillOnce(
100 DoAll(SetArgPointee<1>(std::vector<Hdr>({Hdr::HLG})), Return(Error::NONE)));
101 }
102 };
103
104 // For this variant, the composer should respond with a non-empty list of HDR
105 // modes containing DOLBY_VISION, so DOLBY_VISION support should be configured.
106 template <typename Display>
107 struct HdrDolbyVisionSupportedVariant {
108 static constexpr bool HDR10_PLUS_SUPPORTED = false;
109 static constexpr bool HDR10_SUPPORTED = false;
110 static constexpr bool HDR_HLG_SUPPORTED = false;
111 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = true;
setupComposerCallExpectationsandroid::__anon89ba961e0111::HdrDolbyVisionSupportedVariant112 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
113 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
114 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>({Hdr::DOLBY_VISION})),
115 Return(Error::NONE)));
116 }
117 };
118
119 template <typename Display>
120 struct Smpte2086PerFrameMetadataSupportVariant {
121 static constexpr int PER_FRAME_METADATA_KEYS = HdrMetadata::Type::SMPTE2086;
setupComposerCallExpectationsandroid::__anon89ba961e0111::Smpte2086PerFrameMetadataSupportVariant122 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
123 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID))
124 .WillOnce(Return(std::vector<PerFrameMetadataKey>({
125 PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X,
126 PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y,
127 PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X,
128 PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y,
129 PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X,
130 PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y,
131 PerFrameMetadataKey::WHITE_POINT_X,
132 PerFrameMetadataKey::WHITE_POINT_Y,
133 PerFrameMetadataKey::MAX_LUMINANCE,
134 PerFrameMetadataKey::MIN_LUMINANCE,
135 })));
136 }
137 };
138
139 template <typename Display>
140 struct Cta861_3_PerFrameMetadataSupportVariant {
141 static constexpr int PER_FRAME_METADATA_KEYS = HdrMetadata::Type::CTA861_3;
setupComposerCallExpectationsandroid::__anon89ba961e0111::Cta861_3_PerFrameMetadataSupportVariant142 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
143 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID))
144 .WillOnce(Return(std::vector<PerFrameMetadataKey>({
145 PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL,
146 PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL,
147 })));
148 }
149 };
150
151 template <typename Display>
152 struct Hdr10_Plus_PerFrameMetadataSupportVariant {
153 static constexpr int PER_FRAME_METADATA_KEYS = HdrMetadata::Type::HDR10PLUS;
setupComposerCallExpectationsandroid::__anon89ba961e0111::Hdr10_Plus_PerFrameMetadataSupportVariant154 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
155 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID))
156 .WillOnce(Return(std::vector<PerFrameMetadataKey>({
157 PerFrameMetadataKey::HDR10_PLUS_SEI,
158 })));
159 }
160 };
161
162 using WideColorP3ColorimetricDisplayCase =
163 Case<PrimaryDisplayVariant, WideColorP3ColorimetricSupportedVariant<PrimaryDisplayVariant>,
164 HdrNotSupportedVariant<PrimaryDisplayVariant>,
165 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
166 using Hdr10PlusDisplayCase =
167 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
168 Hdr10SupportedVariant<PrimaryDisplayVariant>,
169 Hdr10_Plus_PerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
170 using Hdr10DisplayCase =
171 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
172 Hdr10SupportedVariant<PrimaryDisplayVariant>,
173 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
174 using HdrHlgDisplayCase =
175 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
176 HdrHlgSupportedVariant<PrimaryDisplayVariant>,
177 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
178 using HdrDolbyVisionDisplayCase =
179 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
180 HdrDolbyVisionSupportedVariant<PrimaryDisplayVariant>,
181 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
182 using HdrSmpte2086DisplayCase =
183 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
184 HdrNotSupportedVariant<PrimaryDisplayVariant>,
185 Smpte2086PerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
186 using HdrCta861_3_DisplayCase =
187 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
188 HdrNotSupportedVariant<PrimaryDisplayVariant>,
189 Cta861_3_PerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
190
191 class SetupNewDisplayDeviceInternalTest : public DisplayTransactionTest {
192 public:
193 template <typename T>
194 void setupNewDisplayDeviceInternalTest();
195 };
196
197 template <typename Case>
setupNewDisplayDeviceInternalTest()198 void SetupNewDisplayDeviceInternalTest::setupNewDisplayDeviceInternalTest() {
199 const sp<BBinder> displayToken = sp<BBinder>::make();
200 const sp<compositionengine::mock::DisplaySurface> displaySurface =
201 sp<compositionengine::mock::DisplaySurface>::make();
202 const auto producer = sp<mock::GraphicBufferProducer>::make();
203
204 // --------------------------------------------------------------------
205 // Preconditions
206
207 // Wide color displays support is configured appropriately
208 Case::WideColorSupport::injectConfigChange(this);
209
210 // The display is setup with the HWC.
211 Case::Display::injectHwcDisplay(this);
212
213 // SurfaceFlinger will use a test-controlled factory for native window
214 // surfaces.
215 injectFakeNativeWindowSurfaceFactory();
216
217 // A compositionengine::Display has already been created
218 auto compositionDisplay = Case::Display::injectCompositionDisplay(this);
219
220 // --------------------------------------------------------------------
221 // Call Expectations
222
223 // Various native window calls will be made.
224 Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
225 Case::Display::setupHwcGetActiveConfigCallExpectations(this);
226 Case::Display::setupHwcGetConfigsCallExpectations(this);
227 Case::WideColorSupport::setupComposerCallExpectations(this);
228 Case::HdrSupport::setupComposerCallExpectations(this);
229 Case::PerFrameMetadataSupport::setupComposerCallExpectations(this);
230
231 // --------------------------------------------------------------------
232 // Invocation
233
234 DisplayDeviceState state;
235 if constexpr (constexpr auto connectionType = Case::Display::CONNECTION_TYPE::value) {
236 const auto displayId = PhysicalDisplayId::tryCast(Case::Display::DISPLAY_ID::get());
237 ASSERT_TRUE(displayId);
238 const auto hwcDisplayId = Case::Display::HWC_DISPLAY_ID_OPT::value;
239 ASSERT_TRUE(hwcDisplayId);
240 mFlinger.getHwComposer().allocatePhysicalDisplay(*hwcDisplayId, *displayId);
241 DisplayModePtr activeMode = DisplayMode::Builder(Case::Display::HWC_ACTIVE_CONFIG_ID)
242 .setResolution(Case::Display::RESOLUTION)
243 .setVsyncPeriod(DEFAULT_VSYNC_PERIOD)
244 .setDpiX(DEFAULT_DPI)
245 .setDpiY(DEFAULT_DPI)
246 .setGroup(0)
247 .build();
248
249 state.physical = {.id = *displayId,
250 .hwcDisplayId = *hwcDisplayId,
251 .activeMode = activeMode};
252
253 ui::ColorModes colorModes;
254 if constexpr (Case::WideColorSupport::WIDE_COLOR_SUPPORTED) {
255 colorModes.push_back(ColorMode::DISPLAY_P3);
256 }
257
258 mFlinger.mutablePhysicalDisplays().emplace_or_replace(*displayId, displayToken, *displayId,
259 *connectionType,
260 makeModes(activeMode),
261 std::move(colorModes), std::nullopt);
262 }
263
264 state.isSecure = static_cast<bool>(Case::Display::SECURE);
265 state.flags = Case::Display::DISPLAY_FLAGS;
266
267 auto device = mFlinger.setupNewDisplayDeviceInternal(displayToken, compositionDisplay, state,
268 displaySurface, producer);
269
270 // --------------------------------------------------------------------
271 // Postconditions
272
273 ASSERT_NE(nullptr, device);
274 EXPECT_EQ(Case::Display::DISPLAY_ID::get(), device->getId());
275 EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL), device->isVirtual());
276 EXPECT_EQ(static_cast<bool>(Case::Display::SECURE), device->isSecure());
277 EXPECT_EQ(static_cast<bool>(Case::Display::PRIMARY), device->isPrimary());
278 EXPECT_EQ(Case::Display::RESOLUTION, device->getSize());
279 EXPECT_EQ(Case::WideColorSupport::WIDE_COLOR_SUPPORTED, device->hasWideColorGamut());
280 EXPECT_EQ(Case::HdrSupport::HDR10_PLUS_SUPPORTED, device->hasHDR10PlusSupport());
281 EXPECT_EQ(Case::HdrSupport::HDR10_SUPPORTED, device->hasHDR10Support());
282 EXPECT_EQ(Case::HdrSupport::HDR_HLG_SUPPORTED, device->hasHLGSupport());
283 EXPECT_EQ(Case::HdrSupport::HDR_DOLBY_VISION_SUPPORTED, device->hasDolbyVisionSupport());
284 EXPECT_EQ(Case::PerFrameMetadataSupport::PER_FRAME_METADATA_KEYS,
285 device->getSupportedPerFrameMetadata());
286 EXPECT_EQ(Case::Display::DISPLAY_FLAGS & DisplayDevice::eReceivesInput,
287 device->receivesInput());
288
289 if constexpr (Case::Display::CONNECTION_TYPE::value) {
290 ftl::FakeGuard guard(kMainThreadContext);
291 EXPECT_EQ(Case::Display::HWC_ACTIVE_CONFIG_ID, device->getActiveMode().modePtr->getHwcId());
292 }
293 }
294
TEST_F(SetupNewDisplayDeviceInternalTest,createSimplePrimaryDisplay)295 TEST_F(SetupNewDisplayDeviceInternalTest, createSimplePrimaryDisplay) {
296 setupNewDisplayDeviceInternalTest<SimplePrimaryDisplayCase>();
297 }
298
TEST_F(SetupNewDisplayDeviceInternalTest,createSimpleExternalDisplay)299 TEST_F(SetupNewDisplayDeviceInternalTest, createSimpleExternalDisplay) {
300 // External displays must be secondary, as the primary display cannot be disconnected.
301 EXPECT_EXIT(setupNewDisplayDeviceInternalTest<SimpleExternalDisplayCase>(),
302 testing::KilledBySignal(SIGABRT), "Missing primary display");
303 }
304
TEST_F(SetupNewDisplayDeviceInternalTest,createNonHwcVirtualDisplay)305 TEST_F(SetupNewDisplayDeviceInternalTest, createNonHwcVirtualDisplay) {
306 setupNewDisplayDeviceInternalTest<NonHwcVirtualDisplayCase>();
307 }
308
TEST_F(SetupNewDisplayDeviceInternalTest,createHwcVirtualDisplay)309 TEST_F(SetupNewDisplayDeviceInternalTest, createHwcVirtualDisplay) {
310 setupNewDisplayDeviceInternalTest<HwcVirtualDisplayCase>();
311 }
312
TEST_F(SetupNewDisplayDeviceInternalTest,createWideColorP3Display)313 TEST_F(SetupNewDisplayDeviceInternalTest, createWideColorP3Display) {
314 setupNewDisplayDeviceInternalTest<WideColorP3ColorimetricDisplayCase>();
315 }
316
TEST_F(SetupNewDisplayDeviceInternalTest,createHdr10PlusDisplay)317 TEST_F(SetupNewDisplayDeviceInternalTest, createHdr10PlusDisplay) {
318 setupNewDisplayDeviceInternalTest<Hdr10PlusDisplayCase>();
319 }
320
TEST_F(SetupNewDisplayDeviceInternalTest,createHdr10Display)321 TEST_F(SetupNewDisplayDeviceInternalTest, createHdr10Display) {
322 setupNewDisplayDeviceInternalTest<Hdr10DisplayCase>();
323 }
324
TEST_F(SetupNewDisplayDeviceInternalTest,createHdrHlgDisplay)325 TEST_F(SetupNewDisplayDeviceInternalTest, createHdrHlgDisplay) {
326 setupNewDisplayDeviceInternalTest<HdrHlgDisplayCase>();
327 }
328
TEST_F(SetupNewDisplayDeviceInternalTest,createHdrDolbyVisionDisplay)329 TEST_F(SetupNewDisplayDeviceInternalTest, createHdrDolbyVisionDisplay) {
330 setupNewDisplayDeviceInternalTest<HdrDolbyVisionDisplayCase>();
331 }
332
TEST_F(SetupNewDisplayDeviceInternalTest,createHdrSmpte2086DisplayCase)333 TEST_F(SetupNewDisplayDeviceInternalTest, createHdrSmpte2086DisplayCase) {
334 setupNewDisplayDeviceInternalTest<HdrSmpte2086DisplayCase>();
335 }
336
TEST_F(SetupNewDisplayDeviceInternalTest,createHdrCta816_3_DisplayCase)337 TEST_F(SetupNewDisplayDeviceInternalTest, createHdrCta816_3_DisplayCase) {
338 setupNewDisplayDeviceInternalTest<HdrCta861_3_DisplayCase>();
339 }
340
341 } // namespace
342 } // namespace android
343