Enable more ColorSpaces in RenderEngine

Bug: 200307628
Test: librenderengine_test pass
Change-Id: I81d9e86e8a826a74d65ce378d01ab55496cdd944
diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp
index 5bc08ac..8259063 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -504,6 +504,18 @@
     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();
 
     template <typename SourceVariant>
@@ -881,12 +893,104 @@
 }
 
 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;
     settings.physicalDisplay = fullscreenRect();
@@ -1427,6 +1531,36 @@
     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>();
@@ -1507,6 +1641,36 @@
     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>>();
@@ -1587,6 +1751,36 @@
     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>>();