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