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