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 26 static inline bool almostEqual(float a, float b) { 27 return std::abs(a - b) < 1e-2f; 28 } 29 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 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