Loading libs/renderengine/skia/ColorSpaces.cpp +21 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ namespace android { namespace renderengine { namespace skia { // please keep in sync with hwui/utils/Color.cpp sk_sp<SkColorSpace> toSkColorSpace(ui::Dataspace dataspace) { skcms_Matrix3x3 gamut; switch (dataspace & HAL_DATASPACE_STANDARD_MASK) { Loading @@ -32,6 +33,17 @@ sk_sp<SkColorSpace> toSkColorSpace(ui::Dataspace dataspace) { case HAL_DATASPACE_STANDARD_DCI_P3: gamut = SkNamedGamut::kDisplayP3; break; case HAL_DATASPACE_STANDARD_ADOBE_RGB: gamut = SkNamedGamut::kAdobeRGB; break; case HAL_DATASPACE_STANDARD_BT601_625: case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED: case HAL_DATASPACE_STANDARD_BT601_525: case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED: case HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE: case HAL_DATASPACE_STANDARD_BT470M: case HAL_DATASPACE_STANDARD_FILM: case HAL_DATASPACE_STANDARD_UNSPECIFIED: default: gamut = SkNamedGamut::kSRGB; break; Loading @@ -42,10 +54,19 @@ sk_sp<SkColorSpace> toSkColorSpace(ui::Dataspace dataspace) { return SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear, gamut); case HAL_DATASPACE_TRANSFER_SRGB: return SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, gamut); case HAL_DATASPACE_TRANSFER_GAMMA2_2: return SkColorSpace::MakeRGB({2.2f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, gamut); case HAL_DATASPACE_TRANSFER_GAMMA2_6: return SkColorSpace::MakeRGB({2.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, gamut); case HAL_DATASPACE_TRANSFER_GAMMA2_8: return SkColorSpace::MakeRGB({2.8f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, gamut); case HAL_DATASPACE_TRANSFER_ST2084: return SkColorSpace::MakeRGB(SkNamedTransferFn::kPQ, gamut); case HAL_DATASPACE_TRANSFER_SMPTE_170M: return SkColorSpace::MakeRGB(SkNamedTransferFn::kRec2020, gamut); case HAL_DATASPACE_TRANSFER_HLG: return SkColorSpace::MakeRGB(SkNamedTransferFn::kHLG, gamut); case HAL_DATASPACE_TRANSFER_UNSPECIFIED: default: return SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, gamut); } Loading libs/renderengine/tests/RenderEngineTest.cpp +194 −0 Original line number Diff line number Diff line Loading @@ -503,6 +503,18 @@ public: template <typename SourceVariant> void fillBufferColorTransform(); template <typename SourceVariant> void fillBufferWithColorTransformAndSourceDataspace(const ui::Dataspace sourceDataspace); template <typename SourceVariant> void fillBufferColorTransformAndSourceDataspace(); template <typename SourceVariant> void fillBufferWithColorTransformAndOutputDataspace(const ui::Dataspace outputDataspace); template <typename SourceVariant> void fillBufferColorTransformAndOutputDataspace(); template <typename SourceVariant> void fillBufferWithColorTransformZeroLayerAlpha(); Loading Loading @@ -880,12 +892,104 @@ void RenderEngineTest::fillBufferWithColorTransform() { invokeDraw(settings, layers); } template <typename SourceVariant> void RenderEngineTest::fillBufferWithColorTransformAndSourceDataspace( const ui::Dataspace sourceDataspace) { renderengine::DisplaySettings settings; settings.physicalDisplay = fullscreenRect(); settings.clip = Rect(1, 1); settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR; std::vector<renderengine::LayerSettings> layers; renderengine::LayerSettings layer; layer.sourceDataspace = sourceDataspace; layer.geometry.boundaries = Rect(1, 1).toFloatRect(); SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this); layer.alpha = 1.0f; // construct a fake color matrix // annihilate green and blue channels settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1)); // set red channel to red + green layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); layer.alpha = 1.0f; layer.geometry.boundaries = Rect(1, 1).toFloatRect(); layers.push_back(layer); invokeDraw(settings, layers); } template <typename SourceVariant> void RenderEngineTest::fillBufferColorTransform() { fillBufferWithColorTransform<SourceVariant>(); expectBufferColor(fullscreenRect(), 172, 0, 0, 255, 1); } template <typename SourceVariant> void RenderEngineTest::fillBufferColorTransformAndSourceDataspace() { unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap; dataspaceToColorMap[ui::Dataspace::V0_BT709] = {172, 0, 0, 255}; dataspaceToColorMap[ui::Dataspace::BT2020] = {172, 0, 0, 255}; dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {172, 0, 0, 255}; ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>( ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_2 | ui::Dataspace::RANGE_FULL); dataspaceToColorMap[customizedDataspace] = {172, 0, 0, 255}; for (const auto& [sourceDataspace, color] : dataspaceToColorMap) { fillBufferWithColorTransformAndSourceDataspace<SourceVariant>(sourceDataspace); expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1); } } template <typename SourceVariant> void RenderEngineTest::fillBufferWithColorTransformAndOutputDataspace( const ui::Dataspace outputDataspace) { renderengine::DisplaySettings settings; settings.physicalDisplay = fullscreenRect(); settings.clip = Rect(1, 1); settings.outputDataspace = outputDataspace; std::vector<renderengine::LayerSettings> layers; renderengine::LayerSettings layer; layer.sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR; layer.geometry.boundaries = Rect(1, 1).toFloatRect(); SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this); layer.alpha = 1.0f; // construct a fake color matrix // annihilate green and blue channels settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1)); // set red channel to red + green layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); layer.alpha = 1.0f; layer.geometry.boundaries = Rect(1, 1).toFloatRect(); layers.push_back(layer); invokeDraw(settings, layers); } template <typename SourceVariant> void RenderEngineTest::fillBufferColorTransformAndOutputDataspace() { unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap; dataspaceToColorMap[ui::Dataspace::V0_BT709] = {202, 0, 0, 255}; dataspaceToColorMap[ui::Dataspace::BT2020] = {192, 0, 0, 255}; dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {202, 0, 0, 255}; ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>( ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_6 | ui::Dataspace::RANGE_FULL); dataspaceToColorMap[customizedDataspace] = {202, 0, 0, 255}; for (const auto& [outputDataspace, color] : dataspaceToColorMap) { fillBufferWithColorTransformAndOutputDataspace<SourceVariant>(outputDataspace); expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1); } } template <typename SourceVariant> void RenderEngineTest::fillBufferWithColorTransformZeroLayerAlpha() { renderengine::DisplaySettings settings; Loading Loading @@ -1427,6 +1531,36 @@ TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_colorSource) { fillBufferColorTransform<ColorSourceVariant>(); } TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_sourceDataspace) { const auto& renderEngineFactory = GetParam(); // skip for non color management if (!renderEngineFactory->useColorManagement()) { return; } // skip for GLESRenderEngine if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) { return; } initializeRenderEngine(); fillBufferColorTransformAndSourceDataspace<ColorSourceVariant>(); } TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_outputDataspace) { const auto& renderEngineFactory = GetParam(); // skip for non color management if (!renderEngineFactory->useColorManagement()) { return; } // skip for GLESRenderEngine if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) { return; } initializeRenderEngine(); fillBufferColorTransformAndOutputDataspace<ColorSourceVariant>(); } TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) { initializeRenderEngine(); fillBufferWithRoundedCorners<ColorSourceVariant>(); Loading Loading @@ -1507,6 +1641,36 @@ TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_opaqueBufferSource) fillBufferColorTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>(); } TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_opaqueBufferSource) { const auto& renderEngineFactory = GetParam(); // skip for non color management if (!renderEngineFactory->useColorManagement()) { return; } // skip for GLESRenderEngine if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) { return; } initializeRenderEngine(); fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>(); } TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_opaqueBufferSource) { const auto& renderEngineFactory = GetParam(); // skip for non color management if (!renderEngineFactory->useColorManagement()) { return; } // skip for GLESRenderEngine if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) { return; } initializeRenderEngine(); fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>(); } TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) { initializeRenderEngine(); fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>(); Loading Loading @@ -1587,6 +1751,36 @@ TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_bufferSource) { fillBufferColorTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>(); } TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_bufferSource) { const auto& renderEngineFactory = GetParam(); // skip for non color management if (!renderEngineFactory->useColorManagement()) { return; } // skip for GLESRenderEngine if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) { return; } initializeRenderEngine(); fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>(); } TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_bufferSource) { const auto& renderEngineFactory = GetParam(); // skip for non color management if (!renderEngineFactory->useColorManagement()) { return; } // skip for GLESRenderEngine if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) { return; } initializeRenderEngine(); fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>(); } TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) { initializeRenderEngine(); fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>(); Loading libs/shaders/shaders.cpp +140 −4 Original line number Diff line number Diff line Loading @@ -72,6 +72,70 @@ static void generateEOTF(ui::Dataspace dataspace, std::string& shader) { } )"); break; case HAL_DATASPACE_TRANSFER_SMPTE_170M: shader.append(R"( float EOTF_sRGB(float srgb) { return srgb <= 0.08125 ? srgb / 4.50 : pow((srgb + 0.099) / 1.099, 0.45); } float3 EOTF_sRGB(float3 srgb) { return float3(EOTF_sRGB(srgb.r), EOTF_sRGB(srgb.g), EOTF_sRGB(srgb.b)); } float3 EOTF(float3 srgb) { return sign(srgb.rgb) * EOTF_sRGB(abs(srgb.rgb)); } )"); break; case HAL_DATASPACE_TRANSFER_GAMMA2_2: shader.append(R"( float EOTF_sRGB(float srgb) { return pow(srgb, 2.2); } float3 EOTF_sRGB(float3 srgb) { return float3(EOTF_sRGB(srgb.r), EOTF_sRGB(srgb.g), EOTF_sRGB(srgb.b)); } float3 EOTF(float3 srgb) { return sign(srgb.rgb) * EOTF_sRGB(abs(srgb.rgb)); } )"); break; case HAL_DATASPACE_TRANSFER_GAMMA2_6: shader.append(R"( float EOTF_sRGB(float srgb) { return pow(srgb, 2.6); } float3 EOTF_sRGB(float3 srgb) { return float3(EOTF_sRGB(srgb.r), EOTF_sRGB(srgb.g), EOTF_sRGB(srgb.b)); } float3 EOTF(float3 srgb) { return sign(srgb.rgb) * EOTF_sRGB(abs(srgb.rgb)); } )"); break; case HAL_DATASPACE_TRANSFER_GAMMA2_8: shader.append(R"( float EOTF_sRGB(float srgb) { return pow(srgb, 2.8); } float3 EOTF_sRGB(float3 srgb) { return float3(EOTF_sRGB(srgb.r), EOTF_sRGB(srgb.g), EOTF_sRGB(srgb.b)); } float3 EOTF(float3 srgb) { return sign(srgb.rgb) * EOTF_sRGB(abs(srgb.rgb)); } )"); break; case HAL_DATASPACE_TRANSFER_SRGB: default: shader.append(R"( Loading Loading @@ -239,6 +303,67 @@ static void generateOETF(ui::Dataspace dataspace, std::string& shader) { } )"); break; case HAL_DATASPACE_TRANSFER_SMPTE_170M: shader.append(R"( float OETF_sRGB(float linear) { return linear <= 0.018 ? linear * 4.50 : (pow(linear, 0.45) * 1.099) - 0.099; } float3 OETF_sRGB(float3 linear) { return float3(OETF_sRGB(linear.r), OETF_sRGB(linear.g), OETF_sRGB(linear.b)); } float3 OETF(float3 linear) { return sign(linear.rgb) * OETF_sRGB(abs(linear.rgb)); } )"); break; case HAL_DATASPACE_TRANSFER_GAMMA2_2: shader.append(R"( float OETF_sRGB(float linear) { return pow(linear, (1.0 / 2.2)); } float3 OETF_sRGB(float3 linear) { return float3(OETF_sRGB(linear.r), OETF_sRGB(linear.g), OETF_sRGB(linear.b)); } float3 OETF(float3 linear) { return sign(linear.rgb) * OETF_sRGB(abs(linear.rgb)); } )"); break; case HAL_DATASPACE_TRANSFER_GAMMA2_6: shader.append(R"( float OETF_sRGB(float linear) { return pow(linear, (1.0 / 2.6)); } float3 OETF_sRGB(float3 linear) { return float3(OETF_sRGB(linear.r), OETF_sRGB(linear.g), OETF_sRGB(linear.b)); } float3 OETF(float3 linear) { return sign(linear.rgb) * OETF_sRGB(abs(linear.rgb)); } )"); break; case HAL_DATASPACE_TRANSFER_GAMMA2_8: shader.append(R"( float OETF_sRGB(float linear) { return pow(linear, (1.0 / 2.8)); } float3 OETF_sRGB(float3 linear) { return float3(OETF_sRGB(linear.r), OETF_sRGB(linear.g), OETF_sRGB(linear.b)); } float3 OETF(float3 linear) { return sign(linear.rgb) * OETF_sRGB(abs(linear.rgb)); } )"); break; case HAL_DATASPACE_TRANSFER_SRGB: default: shader.append(R"( Loading Loading @@ -285,20 +410,31 @@ static void generateEffectiveOOTF(bool undoPremultipliedAlpha, std::string& shad } )"); } // please keep in sync with toSkColorSpace function in renderengine/skia/ColorSpaces.cpp static ColorSpace toColorSpace(ui::Dataspace dataspace) { switch (dataspace & HAL_DATASPACE_STANDARD_MASK) { case HAL_DATASPACE_STANDARD_BT709: return ColorSpace::sRGB(); break; case HAL_DATASPACE_STANDARD_DCI_P3: return ColorSpace::DisplayP3(); break; case HAL_DATASPACE_STANDARD_BT2020: case HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE: return ColorSpace::BT2020(); break; case HAL_DATASPACE_STANDARD_ADOBE_RGB: return ColorSpace::AdobeRGB(); // TODO(b/208290320): BT601 format and variants return different primaries case HAL_DATASPACE_STANDARD_BT601_625: case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED: case HAL_DATASPACE_STANDARD_BT601_525: case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED: // TODO(b/208290329): BT407M format returns different primaries case HAL_DATASPACE_STANDARD_BT470M: // TODO(b/208290904): FILM format returns different primaries case HAL_DATASPACE_STANDARD_FILM: case HAL_DATASPACE_STANDARD_UNSPECIFIED: default: return ColorSpace::sRGB(); break; } } Loading Loading
libs/renderengine/skia/ColorSpaces.cpp +21 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ namespace android { namespace renderengine { namespace skia { // please keep in sync with hwui/utils/Color.cpp sk_sp<SkColorSpace> toSkColorSpace(ui::Dataspace dataspace) { skcms_Matrix3x3 gamut; switch (dataspace & HAL_DATASPACE_STANDARD_MASK) { Loading @@ -32,6 +33,17 @@ sk_sp<SkColorSpace> toSkColorSpace(ui::Dataspace dataspace) { case HAL_DATASPACE_STANDARD_DCI_P3: gamut = SkNamedGamut::kDisplayP3; break; case HAL_DATASPACE_STANDARD_ADOBE_RGB: gamut = SkNamedGamut::kAdobeRGB; break; case HAL_DATASPACE_STANDARD_BT601_625: case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED: case HAL_DATASPACE_STANDARD_BT601_525: case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED: case HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE: case HAL_DATASPACE_STANDARD_BT470M: case HAL_DATASPACE_STANDARD_FILM: case HAL_DATASPACE_STANDARD_UNSPECIFIED: default: gamut = SkNamedGamut::kSRGB; break; Loading @@ -42,10 +54,19 @@ sk_sp<SkColorSpace> toSkColorSpace(ui::Dataspace dataspace) { return SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear, gamut); case HAL_DATASPACE_TRANSFER_SRGB: return SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, gamut); case HAL_DATASPACE_TRANSFER_GAMMA2_2: return SkColorSpace::MakeRGB({2.2f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, gamut); case HAL_DATASPACE_TRANSFER_GAMMA2_6: return SkColorSpace::MakeRGB({2.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, gamut); case HAL_DATASPACE_TRANSFER_GAMMA2_8: return SkColorSpace::MakeRGB({2.8f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, gamut); case HAL_DATASPACE_TRANSFER_ST2084: return SkColorSpace::MakeRGB(SkNamedTransferFn::kPQ, gamut); case HAL_DATASPACE_TRANSFER_SMPTE_170M: return SkColorSpace::MakeRGB(SkNamedTransferFn::kRec2020, gamut); case HAL_DATASPACE_TRANSFER_HLG: return SkColorSpace::MakeRGB(SkNamedTransferFn::kHLG, gamut); case HAL_DATASPACE_TRANSFER_UNSPECIFIED: default: return SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, gamut); } Loading
libs/renderengine/tests/RenderEngineTest.cpp +194 −0 Original line number Diff line number Diff line Loading @@ -503,6 +503,18 @@ public: template <typename SourceVariant> void fillBufferColorTransform(); template <typename SourceVariant> void fillBufferWithColorTransformAndSourceDataspace(const ui::Dataspace sourceDataspace); template <typename SourceVariant> void fillBufferColorTransformAndSourceDataspace(); template <typename SourceVariant> void fillBufferWithColorTransformAndOutputDataspace(const ui::Dataspace outputDataspace); template <typename SourceVariant> void fillBufferColorTransformAndOutputDataspace(); template <typename SourceVariant> void fillBufferWithColorTransformZeroLayerAlpha(); Loading Loading @@ -880,12 +892,104 @@ void RenderEngineTest::fillBufferWithColorTransform() { invokeDraw(settings, layers); } template <typename SourceVariant> void RenderEngineTest::fillBufferWithColorTransformAndSourceDataspace( const ui::Dataspace sourceDataspace) { renderengine::DisplaySettings settings; settings.physicalDisplay = fullscreenRect(); settings.clip = Rect(1, 1); settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR; std::vector<renderengine::LayerSettings> layers; renderengine::LayerSettings layer; layer.sourceDataspace = sourceDataspace; layer.geometry.boundaries = Rect(1, 1).toFloatRect(); SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this); layer.alpha = 1.0f; // construct a fake color matrix // annihilate green and blue channels settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1)); // set red channel to red + green layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); layer.alpha = 1.0f; layer.geometry.boundaries = Rect(1, 1).toFloatRect(); layers.push_back(layer); invokeDraw(settings, layers); } template <typename SourceVariant> void RenderEngineTest::fillBufferColorTransform() { fillBufferWithColorTransform<SourceVariant>(); expectBufferColor(fullscreenRect(), 172, 0, 0, 255, 1); } template <typename SourceVariant> void RenderEngineTest::fillBufferColorTransformAndSourceDataspace() { unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap; dataspaceToColorMap[ui::Dataspace::V0_BT709] = {172, 0, 0, 255}; dataspaceToColorMap[ui::Dataspace::BT2020] = {172, 0, 0, 255}; dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {172, 0, 0, 255}; ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>( ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_2 | ui::Dataspace::RANGE_FULL); dataspaceToColorMap[customizedDataspace] = {172, 0, 0, 255}; for (const auto& [sourceDataspace, color] : dataspaceToColorMap) { fillBufferWithColorTransformAndSourceDataspace<SourceVariant>(sourceDataspace); expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1); } } template <typename SourceVariant> void RenderEngineTest::fillBufferWithColorTransformAndOutputDataspace( const ui::Dataspace outputDataspace) { renderengine::DisplaySettings settings; settings.physicalDisplay = fullscreenRect(); settings.clip = Rect(1, 1); settings.outputDataspace = outputDataspace; std::vector<renderengine::LayerSettings> layers; renderengine::LayerSettings layer; layer.sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR; layer.geometry.boundaries = Rect(1, 1).toFloatRect(); SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this); layer.alpha = 1.0f; // construct a fake color matrix // annihilate green and blue channels settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1)); // set red channel to red + green layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); layer.alpha = 1.0f; layer.geometry.boundaries = Rect(1, 1).toFloatRect(); layers.push_back(layer); invokeDraw(settings, layers); } template <typename SourceVariant> void RenderEngineTest::fillBufferColorTransformAndOutputDataspace() { unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap; dataspaceToColorMap[ui::Dataspace::V0_BT709] = {202, 0, 0, 255}; dataspaceToColorMap[ui::Dataspace::BT2020] = {192, 0, 0, 255}; dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {202, 0, 0, 255}; ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>( ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_6 | ui::Dataspace::RANGE_FULL); dataspaceToColorMap[customizedDataspace] = {202, 0, 0, 255}; for (const auto& [outputDataspace, color] : dataspaceToColorMap) { fillBufferWithColorTransformAndOutputDataspace<SourceVariant>(outputDataspace); expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1); } } template <typename SourceVariant> void RenderEngineTest::fillBufferWithColorTransformZeroLayerAlpha() { renderengine::DisplaySettings settings; Loading Loading @@ -1427,6 +1531,36 @@ TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_colorSource) { fillBufferColorTransform<ColorSourceVariant>(); } TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_sourceDataspace) { const auto& renderEngineFactory = GetParam(); // skip for non color management if (!renderEngineFactory->useColorManagement()) { return; } // skip for GLESRenderEngine if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) { return; } initializeRenderEngine(); fillBufferColorTransformAndSourceDataspace<ColorSourceVariant>(); } TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_outputDataspace) { const auto& renderEngineFactory = GetParam(); // skip for non color management if (!renderEngineFactory->useColorManagement()) { return; } // skip for GLESRenderEngine if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) { return; } initializeRenderEngine(); fillBufferColorTransformAndOutputDataspace<ColorSourceVariant>(); } TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) { initializeRenderEngine(); fillBufferWithRoundedCorners<ColorSourceVariant>(); Loading Loading @@ -1507,6 +1641,36 @@ TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_opaqueBufferSource) fillBufferColorTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>(); } TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_opaqueBufferSource) { const auto& renderEngineFactory = GetParam(); // skip for non color management if (!renderEngineFactory->useColorManagement()) { return; } // skip for GLESRenderEngine if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) { return; } initializeRenderEngine(); fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>(); } TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_opaqueBufferSource) { const auto& renderEngineFactory = GetParam(); // skip for non color management if (!renderEngineFactory->useColorManagement()) { return; } // skip for GLESRenderEngine if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) { return; } initializeRenderEngine(); fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>(); } TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) { initializeRenderEngine(); fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>(); Loading Loading @@ -1587,6 +1751,36 @@ TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_bufferSource) { fillBufferColorTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>(); } TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_bufferSource) { const auto& renderEngineFactory = GetParam(); // skip for non color management if (!renderEngineFactory->useColorManagement()) { return; } // skip for GLESRenderEngine if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) { return; } initializeRenderEngine(); fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>(); } TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_bufferSource) { const auto& renderEngineFactory = GetParam(); // skip for non color management if (!renderEngineFactory->useColorManagement()) { return; } // skip for GLESRenderEngine if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) { return; } initializeRenderEngine(); fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>(); } TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) { initializeRenderEngine(); fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>(); Loading
libs/shaders/shaders.cpp +140 −4 Original line number Diff line number Diff line Loading @@ -72,6 +72,70 @@ static void generateEOTF(ui::Dataspace dataspace, std::string& shader) { } )"); break; case HAL_DATASPACE_TRANSFER_SMPTE_170M: shader.append(R"( float EOTF_sRGB(float srgb) { return srgb <= 0.08125 ? srgb / 4.50 : pow((srgb + 0.099) / 1.099, 0.45); } float3 EOTF_sRGB(float3 srgb) { return float3(EOTF_sRGB(srgb.r), EOTF_sRGB(srgb.g), EOTF_sRGB(srgb.b)); } float3 EOTF(float3 srgb) { return sign(srgb.rgb) * EOTF_sRGB(abs(srgb.rgb)); } )"); break; case HAL_DATASPACE_TRANSFER_GAMMA2_2: shader.append(R"( float EOTF_sRGB(float srgb) { return pow(srgb, 2.2); } float3 EOTF_sRGB(float3 srgb) { return float3(EOTF_sRGB(srgb.r), EOTF_sRGB(srgb.g), EOTF_sRGB(srgb.b)); } float3 EOTF(float3 srgb) { return sign(srgb.rgb) * EOTF_sRGB(abs(srgb.rgb)); } )"); break; case HAL_DATASPACE_TRANSFER_GAMMA2_6: shader.append(R"( float EOTF_sRGB(float srgb) { return pow(srgb, 2.6); } float3 EOTF_sRGB(float3 srgb) { return float3(EOTF_sRGB(srgb.r), EOTF_sRGB(srgb.g), EOTF_sRGB(srgb.b)); } float3 EOTF(float3 srgb) { return sign(srgb.rgb) * EOTF_sRGB(abs(srgb.rgb)); } )"); break; case HAL_DATASPACE_TRANSFER_GAMMA2_8: shader.append(R"( float EOTF_sRGB(float srgb) { return pow(srgb, 2.8); } float3 EOTF_sRGB(float3 srgb) { return float3(EOTF_sRGB(srgb.r), EOTF_sRGB(srgb.g), EOTF_sRGB(srgb.b)); } float3 EOTF(float3 srgb) { return sign(srgb.rgb) * EOTF_sRGB(abs(srgb.rgb)); } )"); break; case HAL_DATASPACE_TRANSFER_SRGB: default: shader.append(R"( Loading Loading @@ -239,6 +303,67 @@ static void generateOETF(ui::Dataspace dataspace, std::string& shader) { } )"); break; case HAL_DATASPACE_TRANSFER_SMPTE_170M: shader.append(R"( float OETF_sRGB(float linear) { return linear <= 0.018 ? linear * 4.50 : (pow(linear, 0.45) * 1.099) - 0.099; } float3 OETF_sRGB(float3 linear) { return float3(OETF_sRGB(linear.r), OETF_sRGB(linear.g), OETF_sRGB(linear.b)); } float3 OETF(float3 linear) { return sign(linear.rgb) * OETF_sRGB(abs(linear.rgb)); } )"); break; case HAL_DATASPACE_TRANSFER_GAMMA2_2: shader.append(R"( float OETF_sRGB(float linear) { return pow(linear, (1.0 / 2.2)); } float3 OETF_sRGB(float3 linear) { return float3(OETF_sRGB(linear.r), OETF_sRGB(linear.g), OETF_sRGB(linear.b)); } float3 OETF(float3 linear) { return sign(linear.rgb) * OETF_sRGB(abs(linear.rgb)); } )"); break; case HAL_DATASPACE_TRANSFER_GAMMA2_6: shader.append(R"( float OETF_sRGB(float linear) { return pow(linear, (1.0 / 2.6)); } float3 OETF_sRGB(float3 linear) { return float3(OETF_sRGB(linear.r), OETF_sRGB(linear.g), OETF_sRGB(linear.b)); } float3 OETF(float3 linear) { return sign(linear.rgb) * OETF_sRGB(abs(linear.rgb)); } )"); break; case HAL_DATASPACE_TRANSFER_GAMMA2_8: shader.append(R"( float OETF_sRGB(float linear) { return pow(linear, (1.0 / 2.8)); } float3 OETF_sRGB(float3 linear) { return float3(OETF_sRGB(linear.r), OETF_sRGB(linear.g), OETF_sRGB(linear.b)); } float3 OETF(float3 linear) { return sign(linear.rgb) * OETF_sRGB(abs(linear.rgb)); } )"); break; case HAL_DATASPACE_TRANSFER_SRGB: default: shader.append(R"( Loading Loading @@ -285,20 +410,31 @@ static void generateEffectiveOOTF(bool undoPremultipliedAlpha, std::string& shad } )"); } // please keep in sync with toSkColorSpace function in renderengine/skia/ColorSpaces.cpp static ColorSpace toColorSpace(ui::Dataspace dataspace) { switch (dataspace & HAL_DATASPACE_STANDARD_MASK) { case HAL_DATASPACE_STANDARD_BT709: return ColorSpace::sRGB(); break; case HAL_DATASPACE_STANDARD_DCI_P3: return ColorSpace::DisplayP3(); break; case HAL_DATASPACE_STANDARD_BT2020: case HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE: return ColorSpace::BT2020(); break; case HAL_DATASPACE_STANDARD_ADOBE_RGB: return ColorSpace::AdobeRGB(); // TODO(b/208290320): BT601 format and variants return different primaries case HAL_DATASPACE_STANDARD_BT601_625: case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED: case HAL_DATASPACE_STANDARD_BT601_525: case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED: // TODO(b/208290329): BT407M format returns different primaries case HAL_DATASPACE_STANDARD_BT470M: // TODO(b/208290904): FILM format returns different primaries case HAL_DATASPACE_STANDARD_FILM: case HAL_DATASPACE_STANDARD_UNSPECIFIED: default: return ColorSpace::sRGB(); break; } } Loading