diff --git a/libs/hwui/utils/Color.cpp b/libs/hwui/utils/Color.cpp index 2293ace0bd16b..28f547703dde0 100644 --- a/libs/hwui/utils/Color.cpp +++ b/libs/hwui/utils/Color.cpp @@ -165,6 +165,14 @@ android_dataspace ColorSpaceToADataSpace(SkColorSpace* colorSpace, SkColorType c if (SkColorSpace::Equals(colorSpace, rec2020PQ.get())) { return HAL_DATASPACE_BT2020_PQ; } + // HLG + const auto hlgFn = GetHLGScaleTransferFunction(); + if (hlgFn.has_value()) { + auto rec2020HLG = SkColorSpace::MakeRGB(hlgFn.value(), SkNamedGamut::kRec2020); + if (SkColorSpace::Equals(colorSpace, rec2020HLG.get())) { + return static_cast(HAL_DATASPACE_BT2020_HLG); + } + } LOG_ALWAYS_FATAL("Only select non-numerical transfer functions are supported"); } @@ -247,6 +255,14 @@ sk_sp DataSpaceToColorSpace(android_dataspace dataspace) { return nullptr; } + // HLG + if ((dataspace & HAL_DATASPACE_TRANSFER_MASK) == HAL_DATASPACE_TRANSFER_HLG) { + const auto hlgFn = GetHLGScaleTransferFunction(); + if (hlgFn.has_value()) { + return SkColorSpace::MakeRGB(hlgFn.value(), gamut); + } + } + switch (dataspace & HAL_DATASPACE_TRANSFER_MASK) { case HAL_DATASPACE_TRANSFER_LINEAR: return SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear, gamut); @@ -264,7 +280,6 @@ sk_sp DataSpaceToColorSpace(android_dataspace dataspace) { return SkColorSpace::MakeRGB(SkNamedTransferFn::kRec2020, gamut); case HAL_DATASPACE_TRANSFER_UNSPECIFIED: return nullptr; - case HAL_DATASPACE_TRANSFER_HLG: default: ALOGV("Unsupported Gamma: %d", dataspace); return nullptr; @@ -381,5 +396,14 @@ skcms_TransferFunction GetPQSkTransferFunction(float sdr_white_level) { return fn; } +// Skia skcms' default HLG maps encoded [0, 1] to linear [1, 12] in order to follow ARIB +// but LinearEffect expects a decoded [0, 1] range instead to follow Rec 2100. +std::optional GetHLGScaleTransferFunction() { + std::optional hlgFn = {}; + skcms_TransferFunction_makeScaledHLGish(&hlgFn.value(), 1.f / 12.f, 2.f, 2.f, 1.f / 0.17883277f, + 0.28466892f, 0.55991073f); + return hlgFn; +} + } // namespace uirenderer } // namespace android diff --git a/libs/hwui/utils/Color.h b/libs/hwui/utils/Color.h index 1654072fd2643..00f910f45c382 100644 --- a/libs/hwui/utils/Color.h +++ b/libs/hwui/utils/Color.h @@ -23,6 +23,8 @@ #include #include +#include + struct ANativeWindow_Buffer; struct AHardwareBuffer_Desc; @@ -127,6 +129,7 @@ struct Lab { Lab sRGBToLab(SkColor color); SkColor LabToSRGB(const Lab& lab, SkAlpha alpha); skcms_TransferFunction GetPQSkTransferFunction(float sdr_white_level = 0.f); +std::optional GetHLGScaleTransferFunction(); } /* namespace uirenderer */ } /* namespace android */