1 /*
2  * Copyright (C) 2017 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 "Color.h"
18 
19 
20 #include <utils/Log.h>
21 #include <cmath>
22 
23 namespace android {
24 namespace uirenderer {
25 
almostEqual(float a,float b)26 static inline bool almostEqual(float a, float b) {
27     return std::abs(a - b) < 1e-2f;
28 }
29 
transferFunctionCloseToSRGB(const SkColorSpace * colorSpace)30 bool transferFunctionCloseToSRGB(const SkColorSpace* colorSpace) {
31     if (colorSpace == nullptr) return true;
32     if (colorSpace->isSRGB()) return true;
33 
34     SkColorSpaceTransferFn transferFunction;
35     if (colorSpace->isNumericalTransferFn(&transferFunction)) {
36         // sRGB transfer function params:
37         const float sRGBParamA = 1 / 1.055f;
38         const float sRGBParamB = 0.055f / 1.055f;
39         const float sRGBParamC = 1 / 12.92f;
40         const float sRGBParamD = 0.04045f;
41         const float sRGBParamE = 0.0f;
42         const float sRGBParamF = 0.0f;
43         const float sRGBParamG = 2.4f;
44 
45         // This comparison will catch Display P3
46         return almostEqual(sRGBParamA, transferFunction.fA) &&
47                almostEqual(sRGBParamB, transferFunction.fB) &&
48                almostEqual(sRGBParamC, transferFunction.fC) &&
49                almostEqual(sRGBParamD, transferFunction.fD) &&
50                almostEqual(sRGBParamE, transferFunction.fE) &&
51                almostEqual(sRGBParamF, transferFunction.fF) &&
52                almostEqual(sRGBParamG, transferFunction.fG);
53     }
54 
55     return false;
56 }
57 
DataSpaceToColorSpace(android_dataspace dataspace)58 sk_sp<SkColorSpace> DataSpaceToColorSpace(android_dataspace dataspace) {
59 
60     SkColorSpace::Gamut gamut;
61     switch (dataspace & HAL_DATASPACE_STANDARD_MASK) {
62         case HAL_DATASPACE_STANDARD_BT709:
63             gamut = SkColorSpace::kSRGB_Gamut;
64             break;
65         case HAL_DATASPACE_STANDARD_BT2020:
66             gamut = SkColorSpace::kRec2020_Gamut;
67             break;
68         case HAL_DATASPACE_STANDARD_DCI_P3:
69             gamut = SkColorSpace::kDCIP3_D65_Gamut;
70             break;
71         case HAL_DATASPACE_STANDARD_ADOBE_RGB:
72             gamut = SkColorSpace::kAdobeRGB_Gamut;
73             break;
74         case HAL_DATASPACE_STANDARD_UNSPECIFIED:
75             return nullptr;
76         case HAL_DATASPACE_STANDARD_BT601_625:
77         case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED:
78         case HAL_DATASPACE_STANDARD_BT601_525:
79         case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED:
80         case HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE:
81         case HAL_DATASPACE_STANDARD_BT470M:
82         case HAL_DATASPACE_STANDARD_FILM:
83         default:
84             ALOGW("Unsupported Gamut: %d", dataspace);
85             return nullptr;
86     }
87 
88     switch (dataspace & HAL_DATASPACE_TRANSFER_MASK) {
89         case HAL_DATASPACE_TRANSFER_LINEAR:
90             return SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma, gamut);
91         case HAL_DATASPACE_TRANSFER_SRGB:
92             return SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma, gamut);
93         case HAL_DATASPACE_TRANSFER_GAMMA2_2:
94             return SkColorSpace::MakeRGB({2.2f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, gamut);
95         case HAL_DATASPACE_TRANSFER_GAMMA2_6:
96             return SkColorSpace::MakeRGB({2.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, gamut);
97         case HAL_DATASPACE_TRANSFER_GAMMA2_8:
98             return SkColorSpace::MakeRGB({2.8f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, gamut);
99         case HAL_DATASPACE_TRANSFER_UNSPECIFIED:
100             return nullptr;
101         case HAL_DATASPACE_TRANSFER_SMPTE_170M:
102         case HAL_DATASPACE_TRANSFER_ST2084:
103         case HAL_DATASPACE_TRANSFER_HLG:
104         default:
105             ALOGW("Unsupported Gamma: %d", dataspace);
106             return nullptr;
107     }
108 }
109 
110 };  // namespace uirenderer
111 };  // namespace android
112