1 /*
2 * Copyright 2019 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 #include <compositionengine/DisplayColorProfileCreationArgs.h>
18 #include <compositionengine/impl/DisplayColorProfile.h>
19 #include <compositionengine/mock/CompositionEngine.h>
20 #include <gtest/gtest.h>
21
22 namespace android::compositionengine {
23 namespace {
24
25 using testing::_;
26 using testing::Contains;
27 using testing::IsEmpty;
28 using testing::Ref;
29 using testing::Return;
30 using testing::ReturnRef;
31 using testing::SizeIs;
32 using testing::StrictMock;
33
34 using ui::ColorMode;
35 using ui::Dataspace;
36 using ui::Hdr;
37 using ui::RenderIntent;
38
39 // This allows us to simulate a vendor-specified intent being used.
40 constexpr RenderIntent VendorRenderIntent = static_cast<RenderIntent>(0x100);
41
42 class DisplayColorProfileTest : public testing::Test {
43 public:
44 ~DisplayColorProfileTest() override = default;
45
46 StrictMock<mock::CompositionEngine> mCompositionEngine;
47 };
48
49 class ProfileFactory {
50 public:
build() const51 impl::DisplayColorProfile build() const {
52 return impl::DisplayColorProfile{DisplayColorProfileCreationArgs{
53 mHasWideColorGamut,
54 HdrCapabilities(mSupportedHdrTypes, mMaxLuminance, mMaxAverageLuminance,
55 mMinLuminance),
56 mSupportedPerFrameMetadata,
57 mSupportedColorModes,
58 }};
59 }
60
setHasWideColorGamut(bool value)61 ProfileFactory& setHasWideColorGamut(bool value) {
62 mHasWideColorGamut = value;
63 return *this;
64 }
65
setPerFrameMetadata(int32_t value)66 ProfileFactory& setPerFrameMetadata(int32_t value) {
67 mSupportedPerFrameMetadata = value;
68 return *this;
69 }
70
addHdrType(Hdr value)71 ProfileFactory& addHdrType(Hdr value) {
72 mSupportedHdrTypes.emplace_back(value);
73 return *this;
74 }
75
addHdrTypes(std::initializer_list<Hdr> values)76 ProfileFactory& addHdrTypes(std::initializer_list<Hdr> values) {
77 for (auto value : values) {
78 mSupportedHdrTypes.emplace_back(value);
79 }
80 return *this;
81 }
82
setMaxLuminance(float value)83 ProfileFactory& setMaxLuminance(float value) {
84 mMaxLuminance = value;
85 return *this;
86 }
87
setMaxAverageLuminance(float value)88 ProfileFactory& setMaxAverageLuminance(float value) {
89 mMaxAverageLuminance = value;
90 return *this;
91 }
92
setMinLuminance(float value)93 ProfileFactory& setMinLuminance(float value) {
94 mMinLuminance = value;
95 return *this;
96 }
97
addColorModeRenderIntent(ColorMode colorMode,RenderIntent renderIntent)98 ProfileFactory& addColorModeRenderIntent(ColorMode colorMode, RenderIntent renderIntent) {
99 mSupportedColorModes[colorMode].emplace_back(renderIntent);
100 return *this;
101 }
102
addColorModeRenderIntents(ColorMode colorMode,std::initializer_list<RenderIntent> renderIntents)103 ProfileFactory& addColorModeRenderIntents(ColorMode colorMode,
104 std::initializer_list<RenderIntent> renderIntents) {
105 auto& profileedRenderIntents = mSupportedColorModes[colorMode];
106 for (auto renderIntent : renderIntents) {
107 profileedRenderIntents.emplace_back(renderIntent);
108 }
109 return *this;
110 }
111
createProfileWithNoColorModeSupport()112 static impl::DisplayColorProfile createProfileWithNoColorModeSupport() {
113 return ProfileFactory().build();
114 }
115
createProfileWithBT2020ColorModeSupport()116 static impl::DisplayColorProfile createProfileWithBT2020ColorModeSupport() {
117 return ProfileFactory()
118 .setHasWideColorGamut(true)
119 .addHdrType(Hdr::HDR10)
120 .addColorModeRenderIntent(ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC)
121 .addColorModeRenderIntent(ColorMode::DISPLAY_BT2020, RenderIntent::ENHANCE)
122 .addColorModeRenderIntent(ColorMode::DISPLAY_BT2020, VendorRenderIntent)
123 .build();
124 }
125
createProfileWithSRGBColorModeSupport()126 static impl::DisplayColorProfile createProfileWithSRGBColorModeSupport() {
127 return ProfileFactory()
128 .setHasWideColorGamut(true)
129 .addHdrType(Hdr::HDR10)
130 .addColorModeRenderIntent(ColorMode::SRGB, RenderIntent::COLORIMETRIC)
131 .addColorModeRenderIntent(ColorMode::SRGB, RenderIntent::ENHANCE)
132 .addColorModeRenderIntent(ColorMode::SRGB, VendorRenderIntent)
133 .build();
134 }
135
createProfileWithBT2100PQSupport()136 static impl::DisplayColorProfile createProfileWithBT2100PQSupport() {
137 return ProfileFactory()
138 .setHasWideColorGamut(true)
139 .addHdrType(Hdr::HLG)
140 .addColorModeRenderIntent(ColorMode::BT2100_PQ, VendorRenderIntent)
141 .build();
142 }
143
createProfileWithDisplayP3ColorModeSupport()144 static impl::DisplayColorProfile createProfileWithDisplayP3ColorModeSupport() {
145 return ProfileFactory()
146 .setHasWideColorGamut(true)
147 .addHdrType(Hdr::HLG)
148 .addColorModeRenderIntent(ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC)
149 .addColorModeRenderIntent(ColorMode::DISPLAY_P3, RenderIntent::ENHANCE)
150 .addColorModeRenderIntent(ColorMode::DISPLAY_P3, VendorRenderIntent)
151 .build();
152 }
153
154 private:
155 bool mHasWideColorGamut = false;
156 std::vector<Hdr> mSupportedHdrTypes;
157 float mMaxLuminance = -1.f;
158 float mMaxAverageLuminance = -1.f;
159 float mMinLuminance = -1.f;
160 int32_t mSupportedPerFrameMetadata = 0;
161 std::unordered_map<ColorMode, std::vector<RenderIntent>> mSupportedColorModes;
162 };
163
164 /* ------------------------------------------------------------------------
165 * RenderSurface Construction
166 */
167
TEST_F(DisplayColorProfileTest,ctorSetsHasWideColorGamutFromInputArgs)168 TEST_F(DisplayColorProfileTest, ctorSetsHasWideColorGamutFromInputArgs) {
169 {
170 auto profile = ProfileFactory().setHasWideColorGamut(false).build();
171
172 EXPECT_FALSE(profile.hasWideColorGamut());
173 }
174
175 {
176 auto profile = ProfileFactory().setHasWideColorGamut(true).build();
177
178 EXPECT_TRUE(profile.hasWideColorGamut());
179 }
180 }
181
TEST_F(DisplayColorProfileTest,ctorSetsSupportedPerFrameMetadataFromInputArgs)182 TEST_F(DisplayColorProfileTest, ctorSetsSupportedPerFrameMetadataFromInputArgs) {
183 {
184 auto profile = ProfileFactory().setPerFrameMetadata(0).build();
185
186 EXPECT_EQ(0, profile.getSupportedPerFrameMetadata());
187 }
188
189 {
190 impl::DisplayColorProfile profile = ProfileFactory().setPerFrameMetadata(123).build();
191
192 EXPECT_EQ(123, profile.getSupportedPerFrameMetadata());
193 }
194 }
195
TEST_F(DisplayColorProfileTest,ctorDetectsSupportedHdrTypesFromInputArgs)196 TEST_F(DisplayColorProfileTest, ctorDetectsSupportedHdrTypesFromInputArgs) {
197 {
198 // The constructor will set the internal state to not indicate any
199 // profile for HDR modes if none are profileed.
200 auto profile = ProfileFactory().build();
201
202 EXPECT_FALSE(profile.hasHDR10PlusSupport());
203 EXPECT_FALSE(profile.hasHDR10Support());
204 EXPECT_FALSE(profile.hasHLGSupport());
205 EXPECT_FALSE(profile.hasDolbyVisionSupport());
206 }
207
208 {
209 // The constructor will set the intenral state to indicate HDR10Plus
210 // profile if the input arguments indicate it is profileed.
211 auto profile = ProfileFactory().addHdrType(Hdr::HDR10_PLUS).build();
212
213 EXPECT_TRUE(profile.hasHDR10PlusSupport());
214 EXPECT_FALSE(profile.hasHDR10Support());
215 EXPECT_FALSE(profile.hasHLGSupport());
216 EXPECT_FALSE(profile.hasDolbyVisionSupport());
217 }
218
219 {
220 // The constructor will set the intenral state to indicate HDR10 profile
221 // if the input arguments indicate it is profileed.
222 auto profile = ProfileFactory().addHdrType(Hdr::HDR10).build();
223
224 EXPECT_FALSE(profile.hasHDR10PlusSupport());
225 EXPECT_TRUE(profile.hasHDR10Support());
226 EXPECT_FALSE(profile.hasHLGSupport());
227 EXPECT_FALSE(profile.hasDolbyVisionSupport());
228 }
229
230 {
231 // The constructor will set the intenral state to indicate HLG profile
232 // if the input arguments indicate it is profileed.
233 auto profile = ProfileFactory().addHdrType(Hdr::HLG).build();
234
235 EXPECT_FALSE(profile.hasHDR10PlusSupport());
236 EXPECT_FALSE(profile.hasHDR10Support());
237 EXPECT_TRUE(profile.hasHLGSupport());
238 EXPECT_FALSE(profile.hasDolbyVisionSupport());
239 }
240
241 {
242 // The constructor will set the intenral state to indicate Dolbyvision profile
243 // if the input arguments indicate it is profileed.
244 auto profile = ProfileFactory().addHdrType(Hdr::DOLBY_VISION).build();
245
246 EXPECT_FALSE(profile.hasHDR10Support());
247 EXPECT_FALSE(profile.hasHLGSupport());
248 EXPECT_TRUE(profile.hasDolbyVisionSupport());
249 }
250 }
251
TEST_F(DisplayColorProfileTest,ctorUsesOrDefaultsLuminanceValuesFromInputArgs)252 TEST_F(DisplayColorProfileTest, ctorUsesOrDefaultsLuminanceValuesFromInputArgs) {
253 {
254 // The constructor will use a default value for each luminance setting
255 // that is negative.
256 auto profile = ProfileFactory()
257 .setMaxLuminance(-1.f)
258 .setMaxAverageLuminance(-1.f)
259 .setMinLuminance(-1.f)
260 .build();
261
262 EXPECT_EQ(DisplayColorProfile::sDefaultMaxLumiance,
263 profile.getHdrCapabilities().getDesiredMaxLuminance());
264 EXPECT_EQ(DisplayColorProfile::sDefaultMaxLumiance,
265 profile.getHdrCapabilities().getDesiredMaxAverageLuminance());
266 EXPECT_EQ(DisplayColorProfile::sDefaultMinLumiance,
267 profile.getHdrCapabilities().getDesiredMinLuminance());
268 }
269
270 {
271 // The constructor will otherwise take and use a positive value for each
272 // of the luminance settings.
273 auto profile = ProfileFactory()
274 .setMaxLuminance(1001.f)
275 .setMaxAverageLuminance(1002.f)
276 .setMinLuminance(1003.f)
277 .build();
278
279 EXPECT_EQ(1001.f, profile.getHdrCapabilities().getDesiredMaxLuminance());
280 EXPECT_EQ(1002.f, profile.getHdrCapabilities().getDesiredMaxAverageLuminance());
281 EXPECT_EQ(1003.f, profile.getHdrCapabilities().getDesiredMinLuminance());
282 }
283 }
284
TEST_F(DisplayColorProfileTest,ctorSignalsHdrSupportForAnyWideColorGamutDevice)285 TEST_F(DisplayColorProfileTest, ctorSignalsHdrSupportForAnyWideColorGamutDevice) {
286 {
287 // If the output does not profile wide color gamut, then no HDR modes
288 // will be profileed in the generated HDR capabilities.
289 auto profile = ProfileFactory().setHasWideColorGamut(false).build();
290
291 EXPECT_THAT(profile.getHdrCapabilities().getSupportedHdrTypes(), IsEmpty());
292 }
293
294 {
295 // If the HWC does not show profile for certain HDR modes, then the
296 // generated HDR capabilities will indicate profile anyway.
297 auto profile = ProfileFactory().setHasWideColorGamut(true).build();
298
299 EXPECT_THAT(profile.getHdrCapabilities().getSupportedHdrTypes(), SizeIs(2));
300 EXPECT_THAT(profile.getHdrCapabilities().getSupportedHdrTypes(), Contains(Hdr::HDR10));
301 EXPECT_THAT(profile.getHdrCapabilities().getSupportedHdrTypes(), Contains(Hdr::HLG));
302 }
303
304 {
305 // If the HWC profiles the HDR modes, then the generated capabilities
306 // still has one entry for each HDR type.
307 auto profile = ProfileFactory()
308 .setHasWideColorGamut(true)
309 .addHdrTypes({Hdr::HLG, Hdr::HDR10})
310 .build();
311
312 EXPECT_THAT(profile.getHdrCapabilities().getSupportedHdrTypes(), SizeIs(2));
313 EXPECT_THAT(profile.getHdrCapabilities().getSupportedHdrTypes(), Contains(Hdr::HDR10));
314 EXPECT_THAT(profile.getHdrCapabilities().getSupportedHdrTypes(), Contains(Hdr::HLG));
315 }
316 }
317
318 /* ------------------------------------------------------------------------
319 * DisplayColorProfile::hasRenderIntent
320 */
321
TEST_F(DisplayColorProfileTest,hasRenderIntentReturnsExpectedValueWhenOutputHasNoSupport)322 TEST_F(DisplayColorProfileTest, hasRenderIntentReturnsExpectedValueWhenOutputHasNoSupport) {
323 auto profile = ProfileFactory::createProfileWithNoColorModeSupport();
324
325 EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::COLORIMETRIC));
326 EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::ENHANCE));
327 EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_COLORIMETRIC));
328 EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_ENHANCE));
329 EXPECT_FALSE(profile.hasRenderIntent(VendorRenderIntent));
330 }
331
TEST_F(DisplayColorProfileTest,hasRenderIntentReturnsExpectedValueWhenOutputHasBT2020upport)332 TEST_F(DisplayColorProfileTest, hasRenderIntentReturnsExpectedValueWhenOutputHasBT2020upport) {
333 auto profile = ProfileFactory::createProfileWithBT2020ColorModeSupport();
334
335 EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::COLORIMETRIC));
336 EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::ENHANCE));
337 EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_COLORIMETRIC));
338 EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_ENHANCE));
339 EXPECT_FALSE(profile.hasRenderIntent(VendorRenderIntent));
340 }
341
TEST_F(DisplayColorProfileTest,hasRenderIntentReturnsExpectedValueWhenOutputHasSRGBSupport)342 TEST_F(DisplayColorProfileTest, hasRenderIntentReturnsExpectedValueWhenOutputHasSRGBSupport) {
343 auto profile = ProfileFactory::createProfileWithSRGBColorModeSupport();
344
345 EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::COLORIMETRIC));
346 EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::ENHANCE));
347 EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_COLORIMETRIC));
348 EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_ENHANCE));
349 EXPECT_TRUE(profile.hasRenderIntent(VendorRenderIntent));
350 }
351
TEST_F(DisplayColorProfileTest,hasRenderIntentReturnsExpectedValueWhenOutputHasBTG2100PQSupport)352 TEST_F(DisplayColorProfileTest, hasRenderIntentReturnsExpectedValueWhenOutputHasBTG2100PQSupport) {
353 auto profile = ProfileFactory::createProfileWithBT2100PQSupport();
354
355 EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::COLORIMETRIC));
356 EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::ENHANCE));
357 EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_COLORIMETRIC));
358 EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_ENHANCE));
359 EXPECT_FALSE(profile.hasRenderIntent(VendorRenderIntent));
360 }
361
362 /* ------------------------------------------------------------------------
363 * DisplayColorProfile::hasLegacyHdrSupport
364 */
365
TEST_F(DisplayColorProfileTest,hasLegacyHdrSupport)366 TEST_F(DisplayColorProfileTest, hasLegacyHdrSupport) {
367 {
368 auto profile = ProfileFactory::createProfileWithNoColorModeSupport();
369
370 EXPECT_FALSE(profile.hasLegacyHdrSupport(Dataspace::BT2020_PQ));
371 EXPECT_FALSE(profile.hasLegacyHdrSupport(Dataspace::BT2020_HLG));
372 }
373
374 {
375 auto profile = ProfileFactory::createProfileWithBT2020ColorModeSupport();
376
377 EXPECT_TRUE(profile.hasLegacyHdrSupport(Dataspace::BT2020_PQ));
378 EXPECT_FALSE(profile.hasLegacyHdrSupport(Dataspace::BT2020_HLG));
379 }
380
381 {
382 auto profile = ProfileFactory::createProfileWithSRGBColorModeSupport();
383
384 EXPECT_TRUE(profile.hasLegacyHdrSupport(Dataspace::BT2020_PQ));
385 EXPECT_FALSE(profile.hasLegacyHdrSupport(Dataspace::BT2020_HLG));
386 }
387
388 {
389 auto profile = ProfileFactory::createProfileWithBT2100PQSupport();
390
391 EXPECT_FALSE(profile.hasLegacyHdrSupport(Dataspace::BT2020_PQ));
392 EXPECT_TRUE(profile.hasLegacyHdrSupport(Dataspace::BT2020_HLG));
393 }
394 }
395
396 /* ------------------------------------------------------------------------
397 * RenderSurface::getBestColorMode()
398 */
399
checkGetBestColorMode(DisplayColorProfile & profile,const std::array<std::tuple<Dataspace,ColorMode,RenderIntent>,15> & expected)400 void checkGetBestColorMode(
401 DisplayColorProfile& profile,
402 const std::array<std::tuple<Dataspace, ColorMode, RenderIntent>, 15>& expected) {
403 using ArgsType = std::tuple<Dataspace, RenderIntent>;
404
405 // These are the combinations of dataspaces and render intents that could be
406 // passed to RenderSurface::getBestColorMode()
407 const std::array<std::tuple<Dataspace, RenderIntent>, 15> kArgs = {
408 /* clang-format off */
409
410 // Non-HDR combinations
411
412 /* 0 */ ArgsType{Dataspace::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
413 /* 1 */ ArgsType{Dataspace::DISPLAY_BT2020, RenderIntent::ENHANCE},
414 /* 2 */ ArgsType{Dataspace::DISPLAY_BT2020, VendorRenderIntent}, // Vendor explicit setting
415
416 /* 3 */ ArgsType{Dataspace::DISPLAY_P3, RenderIntent::COLORIMETRIC},
417 /* 4 */ ArgsType{Dataspace::DISPLAY_P3, RenderIntent::ENHANCE},
418 /* 5 */ ArgsType{Dataspace::DISPLAY_P3, VendorRenderIntent}, // Vendor explicit setting
419
420 /* 6 */ ArgsType{Dataspace::V0_SRGB, RenderIntent::COLORIMETRIC},
421 /* 7 */ ArgsType{Dataspace::V0_SRGB, RenderIntent::ENHANCE},
422 /* 8 */ ArgsType{Dataspace::V0_SRGB, VendorRenderIntent}, // Vendor explicit setting
423
424 // HDR combinations
425
426 /* 9 */ ArgsType{Dataspace::BT2020_PQ, RenderIntent::TONE_MAP_COLORIMETRIC},
427 /* 10 */ ArgsType{Dataspace::BT2020_PQ, RenderIntent::TONE_MAP_ENHANCE},
428 /* 11 */ ArgsType{Dataspace::BT2020_PQ, VendorRenderIntent}, // Vendor explicit setting
429
430 /* 12 */ ArgsType{Dataspace::BT2020_HLG, RenderIntent::TONE_MAP_COLORIMETRIC},
431 /* 13 */ ArgsType{Dataspace::BT2020_HLG, RenderIntent::TONE_MAP_ENHANCE},
432 /* 14 */ ArgsType{Dataspace::BT2020_HLG, VendorRenderIntent}, // Vendor explicit setting
433 /* clang-format on */
434 };
435
436 for (size_t i = 0; i < kArgs.size(); i++) {
437 std::tuple<Dataspace, ColorMode, RenderIntent> actual;
438 profile.getBestColorMode(std::get<0>(kArgs[i]), std::get<1>(kArgs[i]), &std::get<0>(actual),
439 &std::get<1>(actual), &std::get<2>(actual));
440
441 EXPECT_EQ(expected[i], actual) << " for index " << i;
442 }
443 }
444
TEST_F(DisplayColorProfileTest,getBestColorModeReturnsExpectedModesWhenOutputHasNoSupport)445 TEST_F(DisplayColorProfileTest, getBestColorModeReturnsExpectedModesWhenOutputHasNoSupport) {
446 auto profile = ProfileFactory::createProfileWithNoColorModeSupport();
447
448 // Note: This table of expected values goes with the table of arguments
449 // used in checkGetBestColorMode.
450 using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
451 std::array<Result, 15> expectedResults = {
452 /* clang-format off */
453 /* 0 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
454 /* 1 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
455 /* 2 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
456
457 /* 3 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
458 /* 4 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
459 /* 5 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
460
461 /* 6 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
462 /* 7 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
463 /* 8 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
464
465 /* 9 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
466 /* 10 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
467 /* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
468
469 /* 12 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
470 /* 13 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
471 /* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
472
473 /* clang-format on */
474 };
475
476 checkGetBestColorMode(profile, expectedResults);
477 }
478
TEST_F(DisplayColorProfileTest,getBestColorModeReturnsExpectedModesWhenOutputHasBT2020Support)479 TEST_F(DisplayColorProfileTest, getBestColorModeReturnsExpectedModesWhenOutputHasBT2020Support) {
480 auto profile = ProfileFactory::createProfileWithBT2020ColorModeSupport();
481
482 // Note: This table of expected values goes with the table of arguments
483 // used in checkGetBestColorMode.
484 using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
485 std::array<Result, 15> expectedResults = {
486 /* clang-format off */
487 /* 0 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
488 /* 1 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::ENHANCE},
489 /* 2 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
490
491 /* 3 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
492 /* 4 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::ENHANCE},
493 /* 5 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
494
495 /* 6 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
496 /* 7 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::ENHANCE},
497 /* 8 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
498
499 /* 9 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
500 /* 10 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
501 /* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
502
503 /* 12 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
504 /* 13 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
505 /* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
506 /* clang-format on */
507 };
508
509 checkGetBestColorMode(profile, expectedResults);
510 }
511
TEST_F(DisplayColorProfileTest,getBestColorModeReturnsExpectedModesWhenOutputHasSRGBSupport)512 TEST_F(DisplayColorProfileTest, getBestColorModeReturnsExpectedModesWhenOutputHasSRGBSupport) {
513 auto profile = ProfileFactory::createProfileWithSRGBColorModeSupport();
514
515 // Note: This table of expected values goes with the table of arguments
516 // used in checkGetBestColorMode.
517 using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
518 std::array<Result, 15> expectedResults = {
519 /* clang-format off */
520 /* 0 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
521 /* 1 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::ENHANCE},
522 /* 2 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
523
524 /* 3 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
525 /* 4 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::ENHANCE},
526 /* 5 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
527
528 /* 6 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
529 /* 7 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::ENHANCE},
530 /* 8 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
531
532 /* 9 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
533 /* 10 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
534 /* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
535
536 /* 12 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
537 /* 13 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
538 /* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
539 /* clang-format on */
540 };
541
542 checkGetBestColorMode(profile, expectedResults);
543 }
544
TEST_F(DisplayColorProfileTest,getBestColorModeReturnsExpectedModesWhenOutputHasDisplayP3Support)545 TEST_F(DisplayColorProfileTest, getBestColorModeReturnsExpectedModesWhenOutputHasDisplayP3Support) {
546 auto profile = ProfileFactory::createProfileWithDisplayP3ColorModeSupport();
547
548 // Note: This table of expected values goes with the table of arguments
549 // used in checkGetBestColorMode.
550 using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
551 std::array<Result, 15> expectedResults = {
552 /* clang-format off */
553 /* 0 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
554 /* 1 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::ENHANCE},
555 // TODO(b/124317977): There is bug here.
556 /* 2 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
557
558 /* 3 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
559 /* 4 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::ENHANCE},
560 /* 5 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
561
562 /* 6 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
563 /* 7 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::ENHANCE},
564 /* 8 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
565
566 /* 9 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
567 /* 10 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
568 /* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
569
570 /* 12 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
571 /* 13 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
572 /* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
573 /* clang-format on */
574 };
575
576 checkGetBestColorMode(profile, expectedResults);
577 }
578
TEST_F(DisplayColorProfileTest,getBestColorModeReturnsExpectedModesWhenOutputHasBT2100PQSupport)579 TEST_F(DisplayColorProfileTest, getBestColorModeReturnsExpectedModesWhenOutputHasBT2100PQSupport) {
580 auto profile = ProfileFactory::createProfileWithBT2100PQSupport();
581
582 // Note: This table of expected values goes with the table of arguments
583 // used in checkGetBestColorMode.
584 using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
585 std::array<Result, 15> expectedResults = {
586 /* clang-format off */
587 /* 0 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
588 /* 1 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
589 /* 2 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
590
591 /* 3 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
592 /* 4 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
593 /* 5 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
594
595 /* 6 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
596 /* 7 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
597 /* 8 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
598
599 /* 9 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
600 /* 10 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
601 /* 11 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, VendorRenderIntent},
602
603 /* 12 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
604 /* 13 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
605 /* 14 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, VendorRenderIntent},
606 /* clang-format on */
607 };
608
609 checkGetBestColorMode(profile, expectedResults);
610 }
611
612 /*
613 * RenderSurface::isDataspaceSupported()
614 */
615
TEST_F(DisplayColorProfileTest,isDataspaceSupportedWorksForProfileWithNoHdrSupport)616 TEST_F(DisplayColorProfileTest, isDataspaceSupportedWorksForProfileWithNoHdrSupport) {
617 auto profile = ProfileFactory::createProfileWithNoColorModeSupport();
618
619 EXPECT_TRUE(profile.isDataspaceSupported(Dataspace::UNKNOWN));
620 EXPECT_TRUE(profile.isDataspaceSupported(Dataspace::V0_SRGB));
621 EXPECT_FALSE(profile.isDataspaceSupported(Dataspace::BT2020_PQ));
622 EXPECT_FALSE(profile.isDataspaceSupported(Dataspace::BT2020_ITU_PQ));
623 EXPECT_FALSE(profile.isDataspaceSupported(Dataspace::BT2020_HLG));
624 EXPECT_FALSE(profile.isDataspaceSupported(Dataspace::BT2020_ITU_HLG));
625 }
626
TEST_F(DisplayColorProfileTest,isDataspaceSupportedWorksForProfileWithHdr10Support)627 TEST_F(DisplayColorProfileTest, isDataspaceSupportedWorksForProfileWithHdr10Support) {
628 auto profile = ProfileFactory::createProfileWithSRGBColorModeSupport();
629
630 EXPECT_TRUE(profile.isDataspaceSupported(Dataspace::UNKNOWN));
631 EXPECT_TRUE(profile.isDataspaceSupported(Dataspace::V0_SRGB));
632 EXPECT_TRUE(profile.isDataspaceSupported(Dataspace::BT2020_PQ));
633 EXPECT_TRUE(profile.isDataspaceSupported(Dataspace::BT2020_ITU_PQ));
634 EXPECT_FALSE(profile.isDataspaceSupported(Dataspace::BT2020_HLG));
635 EXPECT_FALSE(profile.isDataspaceSupported(Dataspace::BT2020_ITU_HLG));
636 }
637
TEST_F(DisplayColorProfileTest,isDataspaceSupportedWorksForProfileWithHlgSupport)638 TEST_F(DisplayColorProfileTest, isDataspaceSupportedWorksForProfileWithHlgSupport) {
639 auto profile = ProfileFactory::createProfileWithBT2100PQSupport();
640
641 EXPECT_TRUE(profile.isDataspaceSupported(Dataspace::UNKNOWN));
642 EXPECT_TRUE(profile.isDataspaceSupported(Dataspace::V0_SRGB));
643 EXPECT_FALSE(profile.isDataspaceSupported(Dataspace::BT2020_PQ));
644 EXPECT_FALSE(profile.isDataspaceSupported(Dataspace::BT2020_ITU_PQ));
645 EXPECT_TRUE(profile.isDataspaceSupported(Dataspace::BT2020_HLG));
646 EXPECT_TRUE(profile.isDataspaceSupported(Dataspace::BT2020_ITU_HLG));
647 }
648
649 /*
650 * RenderSurface::getTargetDataspace()
651 */
652
TEST_F(DisplayColorProfileTest,getTargetDataspaceWorks)653 TEST_F(DisplayColorProfileTest, getTargetDataspaceWorks) {
654 auto profile = ProfileFactory::createProfileWithNoColorModeSupport();
655
656 // For a non-HDR colorspace with no colorSpaceAgnosticDataspace override,
657 // the input dataspace should be returned.
658 EXPECT_EQ(Dataspace::DISPLAY_P3,
659 profile.getTargetDataspace(ColorMode::DISPLAY_P3, Dataspace::DISPLAY_P3,
660 Dataspace::UNKNOWN));
661
662 // If colorSpaceAgnosticDataspace is set, its value should be returned
663 EXPECT_EQ(Dataspace::V0_SRGB,
664 profile.getTargetDataspace(ColorMode::DISPLAY_P3, Dataspace::DISPLAY_P3,
665 Dataspace::V0_SRGB));
666
667 // For an HDR colorspace, Dataspace::UNKNOWN should be returned.
668 EXPECT_EQ(Dataspace::UNKNOWN,
669 profile.getTargetDataspace(ColorMode::BT2100_PQ, Dataspace::BT2020_PQ,
670 Dataspace::UNKNOWN));
671 }
672
673 } // namespace
674 } // namespace android::compositionengine
675