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(bool wcg=true)126 static impl::DisplayColorProfile createProfileWithSRGBColorModeSupport(bool wcg = true) {
127 return ProfileFactory()
128 .addHdrType(Hdr::HDR10)
129 .setHasWideColorGamut(wcg)
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
285 /* ------------------------------------------------------------------------
286 * DisplayColorProfile::hasRenderIntent
287 */
288
TEST_F(DisplayColorProfileTest,hasRenderIntentReturnsExpectedValueWhenOutputHasNoSupport)289 TEST_F(DisplayColorProfileTest, hasRenderIntentReturnsExpectedValueWhenOutputHasNoSupport) {
290 auto profile = ProfileFactory::createProfileWithNoColorModeSupport();
291
292 EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::COLORIMETRIC));
293 EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::ENHANCE));
294 EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_COLORIMETRIC));
295 EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_ENHANCE));
296 EXPECT_FALSE(profile.hasRenderIntent(VendorRenderIntent));
297 }
298
TEST_F(DisplayColorProfileTest,hasRenderIntentReturnsExpectedValueWhenOutputHasBT2020upport)299 TEST_F(DisplayColorProfileTest, hasRenderIntentReturnsExpectedValueWhenOutputHasBT2020upport) {
300 auto profile = ProfileFactory::createProfileWithBT2020ColorModeSupport();
301
302 EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::COLORIMETRIC));
303 EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::ENHANCE));
304 EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_COLORIMETRIC));
305 EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_ENHANCE));
306 EXPECT_FALSE(profile.hasRenderIntent(VendorRenderIntent));
307 }
308
TEST_F(DisplayColorProfileTest,hasRenderIntentReturnsExpectedValueWhenOutputHasSRGBSupport_NoWCG)309 TEST_F(DisplayColorProfileTest, hasRenderIntentReturnsExpectedValueWhenOutputHasSRGBSupport_NoWCG) {
310 auto profile = ProfileFactory::createProfileWithSRGBColorModeSupport(false);
311
312 EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::COLORIMETRIC));
313 EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::ENHANCE));
314 EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_COLORIMETRIC));
315 EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_ENHANCE));
316 EXPECT_TRUE(profile.hasRenderIntent(VendorRenderIntent));
317 }
318
TEST_F(DisplayColorProfileTest,hasRenderIntentReturnsExpectedValueWhenOutputHasSRGBSupport)319 TEST_F(DisplayColorProfileTest, hasRenderIntentReturnsExpectedValueWhenOutputHasSRGBSupport) {
320 auto profile = ProfileFactory::createProfileWithSRGBColorModeSupport();
321
322 EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::COLORIMETRIC));
323 EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::ENHANCE));
324 EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_COLORIMETRIC));
325 EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_ENHANCE));
326 EXPECT_TRUE(profile.hasRenderIntent(VendorRenderIntent));
327 }
328
TEST_F(DisplayColorProfileTest,hasRenderIntentReturnsExpectedValueWhenOutputHasBTG2100PQSupport)329 TEST_F(DisplayColorProfileTest, hasRenderIntentReturnsExpectedValueWhenOutputHasBTG2100PQSupport) {
330 auto profile = ProfileFactory::createProfileWithBT2100PQSupport();
331
332 EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::COLORIMETRIC));
333 EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::ENHANCE));
334 EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_COLORIMETRIC));
335 EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_ENHANCE));
336 EXPECT_FALSE(profile.hasRenderIntent(VendorRenderIntent));
337 }
338
339 /* ------------------------------------------------------------------------
340 * DisplayColorProfile::hasLegacyHdrSupport
341 */
342
TEST_F(DisplayColorProfileTest,hasLegacyHdrSupport)343 TEST_F(DisplayColorProfileTest, hasLegacyHdrSupport) {
344 {
345 auto profile = ProfileFactory::createProfileWithNoColorModeSupport();
346
347 EXPECT_FALSE(profile.hasLegacyHdrSupport(Dataspace::BT2020_PQ));
348 EXPECT_FALSE(profile.hasLegacyHdrSupport(Dataspace::BT2020_HLG));
349 }
350
351 {
352 auto profile = ProfileFactory::createProfileWithBT2020ColorModeSupport();
353
354 EXPECT_TRUE(profile.hasLegacyHdrSupport(Dataspace::BT2020_PQ));
355 EXPECT_FALSE(profile.hasLegacyHdrSupport(Dataspace::BT2020_HLG));
356 }
357
358 {
359 auto profile = ProfileFactory::createProfileWithSRGBColorModeSupport();
360
361 EXPECT_TRUE(profile.hasLegacyHdrSupport(Dataspace::BT2020_PQ));
362 EXPECT_FALSE(profile.hasLegacyHdrSupport(Dataspace::BT2020_HLG));
363 }
364
365 {
366 auto profile = ProfileFactory::createProfileWithBT2100PQSupport();
367
368 EXPECT_FALSE(profile.hasLegacyHdrSupport(Dataspace::BT2020_PQ));
369 EXPECT_TRUE(profile.hasLegacyHdrSupport(Dataspace::BT2020_HLG));
370 }
371 }
372
373 /* ------------------------------------------------------------------------
374 * RenderSurface::getBestColorMode()
375 */
376
checkGetBestColorMode(DisplayColorProfile & profile,const std::array<std::tuple<Dataspace,ColorMode,RenderIntent>,15> & expected)377 void checkGetBestColorMode(
378 DisplayColorProfile& profile,
379 const std::array<std::tuple<Dataspace, ColorMode, RenderIntent>, 15>& expected) {
380 using ArgsType = std::tuple<Dataspace, RenderIntent>;
381
382 // These are the combinations of dataspaces and render intents that could be
383 // passed to RenderSurface::getBestColorMode()
384 const std::array<std::tuple<Dataspace, RenderIntent>, 15> kArgs = {
385 /* clang-format off */
386
387 // Non-HDR combinations
388
389 /* 0 */ ArgsType{Dataspace::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
390 /* 1 */ ArgsType{Dataspace::DISPLAY_BT2020, RenderIntent::ENHANCE},
391 /* 2 */ ArgsType{Dataspace::DISPLAY_BT2020, VendorRenderIntent}, // Vendor explicit setting
392
393 /* 3 */ ArgsType{Dataspace::DISPLAY_P3, RenderIntent::COLORIMETRIC},
394 /* 4 */ ArgsType{Dataspace::DISPLAY_P3, RenderIntent::ENHANCE},
395 /* 5 */ ArgsType{Dataspace::DISPLAY_P3, VendorRenderIntent}, // Vendor explicit setting
396
397 /* 6 */ ArgsType{Dataspace::V0_SRGB, RenderIntent::COLORIMETRIC},
398 /* 7 */ ArgsType{Dataspace::V0_SRGB, RenderIntent::ENHANCE},
399 /* 8 */ ArgsType{Dataspace::V0_SRGB, VendorRenderIntent}, // Vendor explicit setting
400
401 // HDR combinations
402
403 /* 9 */ ArgsType{Dataspace::BT2020_PQ, RenderIntent::TONE_MAP_COLORIMETRIC},
404 /* 10 */ ArgsType{Dataspace::BT2020_PQ, RenderIntent::TONE_MAP_ENHANCE},
405 /* 11 */ ArgsType{Dataspace::BT2020_PQ, VendorRenderIntent}, // Vendor explicit setting
406
407 /* 12 */ ArgsType{Dataspace::BT2020_HLG, RenderIntent::TONE_MAP_COLORIMETRIC},
408 /* 13 */ ArgsType{Dataspace::BT2020_HLG, RenderIntent::TONE_MAP_ENHANCE},
409 /* 14 */ ArgsType{Dataspace::BT2020_HLG, VendorRenderIntent}, // Vendor explicit setting
410 /* clang-format on */
411 };
412
413 for (size_t i = 0; i < kArgs.size(); i++) {
414 std::tuple<Dataspace, ColorMode, RenderIntent> actual;
415 profile.getBestColorMode(std::get<0>(kArgs[i]), std::get<1>(kArgs[i]), &std::get<0>(actual),
416 &std::get<1>(actual), &std::get<2>(actual));
417
418 EXPECT_EQ(expected[i], actual) << " for index " << i;
419 }
420 }
421
TEST_F(DisplayColorProfileTest,getBestColorModeReturnsExpectedModesWhenOutputHasNoSupport)422 TEST_F(DisplayColorProfileTest, getBestColorModeReturnsExpectedModesWhenOutputHasNoSupport) {
423 auto profile = ProfileFactory::createProfileWithNoColorModeSupport();
424
425 // Note: This table of expected values goes with the table of arguments
426 // used in checkGetBestColorMode.
427 using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
428 std::array<Result, 15> expectedResults = {
429 /* clang-format off */
430 /* 0 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
431 /* 1 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
432 /* 2 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
433
434 /* 3 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
435 /* 4 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
436 /* 5 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
437
438 /* 6 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
439 /* 7 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
440 /* 8 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
441
442 /* 9 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
443 /* 10 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
444 /* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
445
446 /* 12 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
447 /* 13 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
448 /* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
449
450 /* clang-format on */
451 };
452
453 checkGetBestColorMode(profile, expectedResults);
454 }
455
TEST_F(DisplayColorProfileTest,getBestColorModeReturnsExpectedModesWhenOutputHasBT2020Support)456 TEST_F(DisplayColorProfileTest, getBestColorModeReturnsExpectedModesWhenOutputHasBT2020Support) {
457 auto profile = ProfileFactory::createProfileWithBT2020ColorModeSupport();
458
459 // Note: This table of expected values goes with the table of arguments
460 // used in checkGetBestColorMode.
461 using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
462 std::array<Result, 15> expectedResults = {
463 /* clang-format off */
464 /* 0 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
465 /* 1 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::ENHANCE},
466 /* 2 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
467
468 /* 3 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
469 /* 4 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::ENHANCE},
470 /* 5 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
471
472 /* 6 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
473 /* 7 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::ENHANCE},
474 /* 8 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
475
476 /* 9 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
477 /* 10 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
478 /* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
479
480 /* 12 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
481 /* 13 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
482 /* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
483 /* clang-format on */
484 };
485
486 checkGetBestColorMode(profile, expectedResults);
487 }
488
TEST_F(DisplayColorProfileTest,getBestColorModeReturnsExpectedModesWhenOutputHasSRGBSupport_NoWCG)489 TEST_F(DisplayColorProfileTest,
490 getBestColorModeReturnsExpectedModesWhenOutputHasSRGBSupport_NoWCG) {
491 auto profile = ProfileFactory::createProfileWithSRGBColorModeSupport(false);
492
493 // Note: This table of expected values goes with the table of arguments
494 // used in checkGetBestColorMode.
495 using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
496 std::array<Result, 15> expectedResults = {
497 /* clang-format off */
498 /* 0 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
499 /* 1 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::ENHANCE},
500 /* 2 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
501
502 /* 3 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
503 /* 4 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::ENHANCE},
504 /* 5 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
505
506 /* 6 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
507 /* 7 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::ENHANCE},
508 /* 8 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
509
510 /* 9 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
511 /* 10 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
512 /* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
513
514 /* 12 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
515 /* 13 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
516 /* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
517 /* clang-format on */
518 };
519
520 checkGetBestColorMode(profile, expectedResults);
521 }
522
TEST_F(DisplayColorProfileTest,getBestColorModeReturnsExpectedModesWhenOutputHasSRGBSupport)523 TEST_F(DisplayColorProfileTest, getBestColorModeReturnsExpectedModesWhenOutputHasSRGBSupport) {
524 auto profile = ProfileFactory::createProfileWithSRGBColorModeSupport();
525
526 // Note: This table of expected values goes with the table of arguments
527 // used in checkGetBestColorMode.
528 using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
529 std::array<Result, 15> expectedResults = {
530 /* clang-format off */
531 /* 0 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
532 /* 1 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::ENHANCE},
533 /* 2 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
534
535 /* 3 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
536 /* 4 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::ENHANCE},
537 /* 5 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
538
539 /* 6 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
540 /* 7 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::ENHANCE},
541 /* 8 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
542
543 /* 9 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
544 /* 10 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
545 /* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
546
547 /* 12 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
548 /* 13 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
549 /* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
550 /* clang-format on */
551 };
552
553 checkGetBestColorMode(profile, expectedResults);
554 }
555
TEST_F(DisplayColorProfileTest,getBestColorModeReturnsExpectedModesWhenOutputHasDisplayP3Support)556 TEST_F(DisplayColorProfileTest, getBestColorModeReturnsExpectedModesWhenOutputHasDisplayP3Support) {
557 auto profile = ProfileFactory::createProfileWithDisplayP3ColorModeSupport();
558
559 // Note: This table of expected values goes with the table of arguments
560 // used in checkGetBestColorMode.
561 using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
562 std::array<Result, 15> expectedResults = {
563 /* clang-format off */
564 /* 0 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
565 /* 1 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::ENHANCE},
566 // TODO(b/124317977): There is bug here.
567 /* 2 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
568
569 /* 3 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
570 /* 4 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::ENHANCE},
571 /* 5 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
572
573 /* 6 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
574 /* 7 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::ENHANCE},
575 /* 8 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
576
577 /* 9 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
578 /* 10 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
579 /* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
580
581 /* 12 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
582 /* 13 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
583 /* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
584 /* clang-format on */
585 };
586
587 checkGetBestColorMode(profile, expectedResults);
588 }
589
TEST_F(DisplayColorProfileTest,getBestColorModeReturnsExpectedModesWhenOutputHasBT2100PQSupport)590 TEST_F(DisplayColorProfileTest, getBestColorModeReturnsExpectedModesWhenOutputHasBT2100PQSupport) {
591 auto profile = ProfileFactory::createProfileWithBT2100PQSupport();
592
593 // Note: This table of expected values goes with the table of arguments
594 // used in checkGetBestColorMode.
595 using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
596 std::array<Result, 15> expectedResults = {
597 /* clang-format off */
598 /* 0 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
599 /* 1 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
600 /* 2 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
601
602 /* 3 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
603 /* 4 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
604 /* 5 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
605
606 /* 6 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
607 /* 7 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
608 /* 8 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
609
610 /* 9 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
611 /* 10 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
612 /* 11 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, VendorRenderIntent},
613
614 /* 12 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
615 /* 13 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
616 /* 14 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, VendorRenderIntent},
617 /* clang-format on */
618 };
619
620 checkGetBestColorMode(profile, expectedResults);
621 }
622
623 /*
624 * RenderSurface::isDataspaceSupported()
625 */
626
TEST_F(DisplayColorProfileTest,isDataspaceSupportedWorksForProfileWithNoHdrSupport)627 TEST_F(DisplayColorProfileTest, isDataspaceSupportedWorksForProfileWithNoHdrSupport) {
628 auto profile = ProfileFactory::createProfileWithNoColorModeSupport();
629
630 EXPECT_TRUE(profile.isDataspaceSupported(Dataspace::UNKNOWN));
631 EXPECT_TRUE(profile.isDataspaceSupported(Dataspace::V0_SRGB));
632 EXPECT_FALSE(profile.isDataspaceSupported(Dataspace::BT2020_PQ));
633 EXPECT_FALSE(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,isDataspaceSupportedWorksForProfileWithHdr10Support)638 TEST_F(DisplayColorProfileTest, isDataspaceSupportedWorksForProfileWithHdr10Support) {
639 auto profile = ProfileFactory::createProfileWithSRGBColorModeSupport();
640
641 EXPECT_TRUE(profile.isDataspaceSupported(Dataspace::UNKNOWN));
642 EXPECT_TRUE(profile.isDataspaceSupported(Dataspace::V0_SRGB));
643 EXPECT_TRUE(profile.isDataspaceSupported(Dataspace::BT2020_PQ));
644 EXPECT_TRUE(profile.isDataspaceSupported(Dataspace::BT2020_ITU_PQ));
645 EXPECT_FALSE(profile.isDataspaceSupported(Dataspace::BT2020_HLG));
646 EXPECT_FALSE(profile.isDataspaceSupported(Dataspace::BT2020_ITU_HLG));
647 }
648
TEST_F(DisplayColorProfileTest,isDataspaceSupportedWorksForProfileWithHlgSupport)649 TEST_F(DisplayColorProfileTest, isDataspaceSupportedWorksForProfileWithHlgSupport) {
650 auto profile = ProfileFactory::createProfileWithBT2100PQSupport();
651
652 EXPECT_TRUE(profile.isDataspaceSupported(Dataspace::UNKNOWN));
653 EXPECT_TRUE(profile.isDataspaceSupported(Dataspace::V0_SRGB));
654 EXPECT_FALSE(profile.isDataspaceSupported(Dataspace::BT2020_PQ));
655 EXPECT_FALSE(profile.isDataspaceSupported(Dataspace::BT2020_ITU_PQ));
656 EXPECT_TRUE(profile.isDataspaceSupported(Dataspace::BT2020_HLG));
657 EXPECT_TRUE(profile.isDataspaceSupported(Dataspace::BT2020_ITU_HLG));
658 }
659
660 } // namespace
661 } // namespace android::compositionengine
662