Supply extra brightness parameters to RenderEngine

A future CL will update the HLG->SDR tonemapping algorithm to consider
current display brightness, as recommended by BT2100.

In preparation for this:
* Fix an issue where maxLuminance was using the current display
brightness if supplied from DisplayManager instead of the max luminance
* Add currentDisplayBrightnessNits to the RenderEngine interface to
support the current brightness
* Plumb current display brightness all the way to libtonemap, where
nothing uses it (yet)

Bug: 206035964
Test: libcompositionengine_test

Change-Id: I3e9f0fdb23fbb08c50e4733e5a16bcd20948d750
diff --git a/libs/renderengine/include/renderengine/DisplaySettings.h b/libs/renderengine/include/renderengine/DisplaySettings.h
index b4cab39..2c51ccd 100644
--- a/libs/renderengine/include/renderengine/DisplaySettings.h
+++ b/libs/renderengine/include/renderengine/DisplaySettings.h
@@ -43,6 +43,9 @@
     // Maximum luminance pulled from the display's HDR capabilities.
     float maxLuminance = 1.0f;
 
+    // Current luminance of the display
+    float currentLuminanceNits = -1.f;
+
     // Output dataspace that will be populated if wide color gamut is used, or
     // DataSpace::UNKNOWN otherwise.
     ui::Dataspace outputDataspace = ui::Dataspace::UNKNOWN;
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index cc90946..063ce67 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -656,6 +656,7 @@
                                  parameters.layerDimmingRatio, 1.f));
         return createLinearEffectShader(parameters.shader, effect, runtimeEffect, colorTransform,
                                         parameters.display.maxLuminance,
+                                        parameters.display.currentLuminanceNits,
                                         parameters.layer.source.buffer.maxLuminanceNits);
     }
     return parameters.shader;
diff --git a/libs/renderengine/skia/filters/LinearEffect.cpp b/libs/renderengine/skia/filters/LinearEffect.cpp
index 36305ae..6077c2e 100644
--- a/libs/renderengine/skia/filters/LinearEffect.cpp
+++ b/libs/renderengine/skia/filters/LinearEffect.cpp
@@ -44,14 +44,15 @@
                                          const shaders::LinearEffect& linearEffect,
                                          sk_sp<SkRuntimeEffect> runtimeEffect,
                                          const mat4& colorTransform, float maxDisplayLuminance,
-                                         float maxLuminance) {
+                                         float currentDisplayLuminanceNits, float maxLuminance) {
     ATRACE_CALL();
     SkRuntimeShaderBuilder effectBuilder(runtimeEffect);
 
     effectBuilder.child("child") = shader;
 
-    const auto uniforms = shaders::buildLinearEffectUniforms(linearEffect, colorTransform,
-                                                             maxDisplayLuminance, maxLuminance);
+    const auto uniforms =
+            shaders::buildLinearEffectUniforms(linearEffect, colorTransform, maxDisplayLuminance,
+                                               currentDisplayLuminanceNits, maxLuminance);
 
     for (const auto& uniform : uniforms) {
         effectBuilder.uniform(uniform.name.c_str()).set(uniform.value.data(), uniform.value.size());
diff --git a/libs/renderengine/skia/filters/LinearEffect.h b/libs/renderengine/skia/filters/LinearEffect.h
index 8eb6670..e0a556b 100644
--- a/libs/renderengine/skia/filters/LinearEffect.h
+++ b/libs/renderengine/skia/filters/LinearEffect.h
@@ -37,13 +37,14 @@
 // matrix transforming from linear XYZ to linear RGB immediately before OETF.
 // We also provide additional HDR metadata upon creating the shader:
 // * The max display luminance is the max luminance of the physical display in nits
+// * The current luminance of the physical display in nits
 // * The max luminance is provided as the max luminance for the buffer, either from the SMPTE 2086
 // or as the max light level from the CTA 861.3 standard.
 sk_sp<SkShader> createLinearEffectShader(sk_sp<SkShader> inputShader,
                                          const shaders::LinearEffect& linearEffect,
                                          sk_sp<SkRuntimeEffect> runtimeEffect,
                                          const mat4& colorTransform, float maxDisplayLuminance,
-                                         float maxLuminance);
+                                         float currentDisplayLuminanceNits, float maxLuminance);
 } // namespace skia
 } // namespace renderengine
 } // namespace android
diff --git a/libs/shaders/include/shaders/shaders.h b/libs/shaders/include/shaders/shaders.h
index 712a27a..43828cc 100644
--- a/libs/shaders/include/shaders/shaders.h
+++ b/libs/shaders/include/shaders/shaders.h
@@ -100,6 +100,7 @@
 std::vector<tonemap::ShaderUniform> buildLinearEffectUniforms(const LinearEffect& linearEffect,
                                                               const mat4& colorTransform,
                                                               float maxDisplayLuminance,
+                                                              float currentDisplayLuminanceNits,
                                                               float maxLuminance);
 
 } // namespace android::shaders
diff --git a/libs/shaders/shaders.cpp b/libs/shaders/shaders.cpp
index 6019c4a..4d88d5d 100644
--- a/libs/shaders/shaders.cpp
+++ b/libs/shaders/shaders.cpp
@@ -463,6 +463,7 @@
 std::vector<tonemap::ShaderUniform> buildLinearEffectUniforms(const LinearEffect& linearEffect,
                                                               const mat4& colorTransform,
                                                               float maxDisplayLuminance,
+                                                              float currentDisplayLuminanceNits,
                                                               float maxLuminance) {
     std::vector<tonemap::ShaderUniform> uniforms;
     if (linearEffect.inputDataspace == linearEffect.outputDataspace) {
@@ -480,6 +481,7 @@
     }
 
     tonemap::Metadata metadata{.displayMaxLuminance = maxDisplayLuminance,
+                               .currentDisplayLuminanceNits = currentDisplayLuminanceNits,
                                // If the input luminance is unknown, use display luminance (aka,
                                // no-op any luminance changes)
                                // This will be the case for eg screenshots in addition to
diff --git a/libs/tonemap/include/tonemap/tonemap.h b/libs/tonemap/include/tonemap/tonemap.h
index bd7b72d..6233e6c 100644
--- a/libs/tonemap/include/tonemap/tonemap.h
+++ b/libs/tonemap/include/tonemap/tonemap.h
@@ -42,7 +42,11 @@
 // This metadata should not be used for manipulating the source code of the shader program directly,
 // as otherwise caching by other system of these shaders may break.
 struct Metadata {
+    // The maximum luminance of the display in nits
     float displayMaxLuminance = 0.0;
+    // The current luminance of the display in nits
+    float currentDisplayLuminanceNits = 0.0;
+    // The maximum luminance of the content in nits
     float contentMaxLuminance = 0.0;
 };
 
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 192ee04..162d84e 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -1059,9 +1059,11 @@
 
     // If we have a valid current display brightness use that, otherwise fall back to the
     // display's max desired
-    clientCompositionDisplay.maxLuminance = outputState.displayBrightnessNits > 0.f
+    clientCompositionDisplay.currentLuminanceNits = outputState.displayBrightnessNits > 0.f
             ? outputState.displayBrightnessNits
             : mDisplayColorProfile->getHdrCapabilities().getDesiredMaxLuminance();
+    clientCompositionDisplay.maxLuminance =
+            mDisplayColorProfile->getHdrCapabilities().getDesiredMaxLuminance();
     clientCompositionDisplay.targetLuminanceNits = outputState.clientTargetWhitePointNits;
 
     // Compute the global color transform matrix.
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index f7c7533..c2235a2 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -3069,6 +3069,8 @@
     static constexpr float kDefaultMaxLuminance = 0.9f;
     static constexpr float kDefaultAvgLuminance = 0.7f;
     static constexpr float kDefaultMinLuminance = 0.1f;
+    static constexpr float kUnknownLuminance = -1.f;
+    static constexpr float kDisplayLuminance = 80.f;
     static constexpr float kClientTargetLuminanceNits = 200.f;
 
     static const Rect kDefaultOutputFrame;
@@ -3101,6 +3103,7 @@
 const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
 const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
 const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
+
 const HdrCapabilities OutputComposeSurfacesTest::
         kHdrCapabilities{{},
                          OutputComposeSurfacesTest::kDefaultMaxLuminance,
@@ -3403,6 +3406,14 @@
         auto andIfUsesHdr(bool used) {
             EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
                     .WillOnce(Return(used));
+            return nextState<OutputWithDisplayBrightnessNits>();
+        }
+    };
+
+    struct OutputWithDisplayBrightnessNits
+          : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
+        auto withDisplayBrightnessNits(float nits) {
+            getInstance()->mOutput.mState.displayBrightnessNits = nits;
             return nextState<SkipColorTransformState>();
         }
     };
@@ -3434,11 +3445,34 @@
 TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
     verify().ifMixedCompositionIs(true)
             .andIfUsesHdr(true)
+            .withDisplayBrightnessNits(kUnknownLuminance)
             .andIfSkipColorTransform(false)
-            .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
-                                            kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
-                                            kDefaultOutputOrientationFlags,
-                                            kClientTargetLuminanceNits})
+            .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
+                                            .clip = kDefaultOutputViewport,
+                                            .maxLuminance = kDefaultMaxLuminance,
+                                            .currentLuminanceNits = kDefaultMaxLuminance,
+                                            .outputDataspace = kDefaultOutputDataspace,
+                                            .colorTransform = mat4(),
+                                            .orientation = kDefaultOutputOrientationFlags,
+                                            .targetLuminanceNits = kClientTargetLuminanceNits})
+            .execute()
+            .expectAFenceWasReturned();
+}
+
+TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
+       forHdrMixedCompositionWithDisplayBrightness) {
+    verify().ifMixedCompositionIs(true)
+            .andIfUsesHdr(true)
+            .withDisplayBrightnessNits(kDisplayLuminance)
+            .andIfSkipColorTransform(false)
+            .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
+                                            .clip = kDefaultOutputViewport,
+                                            .maxLuminance = kDefaultMaxLuminance,
+                                            .currentLuminanceNits = kDisplayLuminance,
+                                            .outputDataspace = kDefaultOutputDataspace,
+                                            .colorTransform = mat4(),
+                                            .orientation = kDefaultOutputOrientationFlags,
+                                            .targetLuminanceNits = kClientTargetLuminanceNits})
             .execute()
             .expectAFenceWasReturned();
 }
@@ -3446,11 +3480,16 @@
 TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
     verify().ifMixedCompositionIs(true)
             .andIfUsesHdr(false)
+            .withDisplayBrightnessNits(kUnknownLuminance)
             .andIfSkipColorTransform(false)
-            .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
-                                            kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
-                                            kDefaultOutputOrientationFlags,
-                                            kClientTargetLuminanceNits})
+            .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
+                                            .clip = kDefaultOutputViewport,
+                                            .maxLuminance = kDefaultMaxLuminance,
+                                            .currentLuminanceNits = kDefaultMaxLuminance,
+                                            .outputDataspace = kDefaultOutputDataspace,
+                                            .colorTransform = mat4(),
+                                            .orientation = kDefaultOutputOrientationFlags,
+                                            .targetLuminanceNits = kClientTargetLuminanceNits})
             .execute()
             .expectAFenceWasReturned();
 }
@@ -3458,11 +3497,16 @@
 TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
     verify().ifMixedCompositionIs(false)
             .andIfUsesHdr(true)
+            .withDisplayBrightnessNits(kUnknownLuminance)
             .andIfSkipColorTransform(false)
-            .thenExpectDisplaySettingsUsed(
-                    {kDefaultOutputDestinationClip, kDefaultOutputViewport, kDefaultMaxLuminance,
-                     kDefaultOutputDataspace, kDefaultColorTransformMat,
-                     kDefaultOutputOrientationFlags, kClientTargetLuminanceNits})
+            .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
+                                            .clip = kDefaultOutputViewport,
+                                            .maxLuminance = kDefaultMaxLuminance,
+                                            .currentLuminanceNits = kDefaultMaxLuminance,
+                                            .outputDataspace = kDefaultOutputDataspace,
+                                            .colorTransform = kDefaultColorTransformMat,
+                                            .orientation = kDefaultOutputOrientationFlags,
+                                            .targetLuminanceNits = kClientTargetLuminanceNits})
             .execute()
             .expectAFenceWasReturned();
 }
@@ -3470,11 +3514,16 @@
 TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
     verify().ifMixedCompositionIs(false)
             .andIfUsesHdr(false)
+            .withDisplayBrightnessNits(kUnknownLuminance)
             .andIfSkipColorTransform(false)
-            .thenExpectDisplaySettingsUsed(
-                    {kDefaultOutputDestinationClip, kDefaultOutputViewport, kDefaultMaxLuminance,
-                     kDefaultOutputDataspace, kDefaultColorTransformMat,
-                     kDefaultOutputOrientationFlags, kClientTargetLuminanceNits})
+            .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
+                                            .clip = kDefaultOutputViewport,
+                                            .maxLuminance = kDefaultMaxLuminance,
+                                            .currentLuminanceNits = kDefaultMaxLuminance,
+                                            .outputDataspace = kDefaultOutputDataspace,
+                                            .colorTransform = kDefaultColorTransformMat,
+                                            .orientation = kDefaultOutputOrientationFlags,
+                                            .targetLuminanceNits = kClientTargetLuminanceNits})
             .execute()
             .expectAFenceWasReturned();
 }
@@ -3483,11 +3532,16 @@
        usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
     verify().ifMixedCompositionIs(false)
             .andIfUsesHdr(true)
+            .withDisplayBrightnessNits(kUnknownLuminance)
             .andIfSkipColorTransform(true)
-            .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
-                                            kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
-                                            kDefaultOutputOrientationFlags,
-                                            kClientTargetLuminanceNits})
+            .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
+                                            .clip = kDefaultOutputViewport,
+                                            .maxLuminance = kDefaultMaxLuminance,
+                                            .currentLuminanceNits = kDefaultMaxLuminance,
+                                            .outputDataspace = kDefaultOutputDataspace,
+                                            .colorTransform = mat4(),
+                                            .orientation = kDefaultOutputOrientationFlags,
+                                            .targetLuminanceNits = kClientTargetLuminanceNits})
             .execute()
             .expectAFenceWasReturned();
 }