Plumb through dimming stage into RenderEngine.

If HWC is requesting that dimming happens after OETF is applied, then
apply the dimming matrix as part of the display color transform

Bug: 218954037
Test: Toggle client composition in adaptive color mode during HDR
playback

Change-Id: Ib72f3f4b6dfcced02fc330e64fa72546a18fb608
Merged-In: Ib72f3f4b6dfcced02fc330e64fa72546a18fb608
diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp
index 38ae2fd..2493242 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -2405,15 +2405,18 @@
 
 TEST_P(RenderEngineTest, testDimming) {
     if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
-        return;
+        GTEST_SKIP();
     }
+
     initializeRenderEngine();
 
+    const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB_LINEAR;
+
     const auto displayRect = Rect(3, 1);
     const renderengine::DisplaySettings display{
             .physicalDisplay = displayRect,
             .clip = displayRect,
-            .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
+            .outputDataspace = dataspace,
             .targetLuminanceNits = 1000.f,
     };
 
@@ -2432,7 +2435,7 @@
                                     },
                     },
             .alpha = 1.0f,
-            .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
+            .sourceDataspace = dataspace,
             .whitePointNits = 200.f,
     };
 
@@ -2447,7 +2450,7 @@
                                     },
                     },
             .alpha = 1.0f,
-            .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
+            .sourceDataspace = dataspace,
             .whitePointNits = 1000.f / 51.f,
     };
 
@@ -2462,7 +2465,7 @@
                                     },
                     },
             .alpha = 1.0f,
-            .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
+            .sourceDataspace = dataspace,
             // When the white point is not set for a layer, just ignore it and treat it as the same
             // as the max layer
             .whitePointNits = -1.f,
@@ -2476,6 +2479,84 @@
     expectBufferColor(Rect(2, 0, 3, 1), 51, 0, 0, 255, 1);
 }
 
+TEST_P(RenderEngineTest, testDimming_inGammaSpace) {
+    if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
+        GTEST_SKIP();
+    }
+    initializeRenderEngine();
+
+    const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
+                                                               ui::Dataspace::TRANSFER_GAMMA2_2 |
+                                                               ui::Dataspace::RANGE_FULL);
+
+    const auto displayRect = Rect(3, 1);
+    const renderengine::DisplaySettings display{
+            .physicalDisplay = displayRect,
+            .clip = displayRect,
+            .outputDataspace = dataspace,
+            .targetLuminanceNits = 1000.f,
+            .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
+    };
+
+    const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
+    const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
+    const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
+
+    const renderengine::LayerSettings greenLayer{
+            .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
+            .source =
+                    renderengine::PixelSource{
+                            .buffer =
+                                    renderengine::Buffer{
+                                            .buffer = greenBuffer,
+                                            .usePremultipliedAlpha = true,
+                                    },
+                    },
+            .alpha = 1.0f,
+            .sourceDataspace = dataspace,
+            .whitePointNits = 200.f,
+    };
+
+    const renderengine::LayerSettings blueLayer{
+            .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
+            .source =
+                    renderengine::PixelSource{
+                            .buffer =
+                                    renderengine::Buffer{
+                                            .buffer = blueBuffer,
+                                            .usePremultipliedAlpha = true,
+                                    },
+                    },
+            .alpha = 1.0f,
+            .sourceDataspace = dataspace,
+            .whitePointNits = 1000.f / 51.f,
+    };
+
+    const renderengine::LayerSettings redLayer{
+            .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
+            .source =
+                    renderengine::PixelSource{
+                            .buffer =
+                                    renderengine::Buffer{
+                                            .buffer = redBuffer,
+                                            .usePremultipliedAlpha = true,
+                                    },
+                    },
+            .alpha = 1.0f,
+            .sourceDataspace = dataspace,
+            // When the white point is not set for a layer, just ignore it and treat it as the same
+            // as the max layer
+            .whitePointNits = -1.f,
+    };
+
+    std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
+    invokeDraw(display, layers);
+
+    expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
+    expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 42, 255, 1);
+    expectBufferColor(Rect(2, 0, 3, 1), 122, 0, 0, 255, 1);
+}
+
 TEST_P(RenderEngineTest, testDimming_withoutTargetLuminance) {
     initializeRenderEngine();
     if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {