Support RenderIntents in libtonemap.

Add RenderIntent as a supported uniform which is needed as some devices
may perform contrast enhancements intended for SDR content which must be
compensated for pre-blend for HDR content.

Bug: 227779465
Test: builds
Change-Id: Id74277e727d73cb9e371c37a83bef805e66271f4
diff --git a/libs/renderengine/include/renderengine/DisplaySettings.h b/libs/renderengine/include/renderengine/DisplaySettings.h
index bf50644..a5e0879 100644
--- a/libs/renderengine/include/renderengine/DisplaySettings.h
+++ b/libs/renderengine/include/renderengine/DisplaySettings.h
@@ -17,6 +17,7 @@
 #pragma once
 
 #include <aidl/android/hardware/graphics/composer3/DimmingStage.h>
+#include <aidl/android/hardware/graphics/composer3/RenderIntent.h>
 #include <iosfwd>
 
 #include <math/mat4.h>
@@ -73,6 +74,10 @@
     // Configures when dimming should be applied for each layer.
     aidl::android::hardware::graphics::composer3::DimmingStage dimmingStage =
             aidl::android::hardware::graphics::composer3::DimmingStage::NONE;
+
+    // Configures the rendering intent of the output display. This is used for tonemapping.
+    aidl::android::hardware::graphics::composer3::RenderIntent renderIntent =
+            aidl::android::hardware::graphics::composer3::RenderIntent::TONE_MAP_COLORIMETRIC;
 };
 
 static inline bool operator==(const DisplaySettings& lhs, const DisplaySettings& rhs) {
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index a77a798..76ae2fc 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -662,7 +662,7 @@
                                         parameters.display.maxLuminance,
                                         parameters.display.currentLuminanceNits,
                                         parameters.layer.source.buffer.maxLuminanceNits,
-                                        hardwareBuffer);
+                                        hardwareBuffer, parameters.display.renderIntent);
     }
     return parameters.shader;
 }
diff --git a/libs/renderengine/skia/filters/LinearEffect.cpp b/libs/renderengine/skia/filters/LinearEffect.cpp
index d479606..f7dcd3a 100644
--- a/libs/renderengine/skia/filters/LinearEffect.cpp
+++ b/libs/renderengine/skia/filters/LinearEffect.cpp
@@ -40,12 +40,11 @@
     return shader;
 }
 
-sk_sp<SkShader> createLinearEffectShader(sk_sp<SkShader> shader,
-                                         const shaders::LinearEffect& linearEffect,
-                                         sk_sp<SkRuntimeEffect> runtimeEffect,
-                                         const mat4& colorTransform, float maxDisplayLuminance,
-                                         float currentDisplayLuminanceNits, float maxLuminance,
-                                         AHardwareBuffer* buffer) {
+sk_sp<SkShader> createLinearEffectShader(
+        sk_sp<SkShader> shader, const shaders::LinearEffect& linearEffect,
+        sk_sp<SkRuntimeEffect> runtimeEffect, const mat4& colorTransform, float maxDisplayLuminance,
+        float currentDisplayLuminanceNits, float maxLuminance, AHardwareBuffer* buffer,
+        aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
     ATRACE_CALL();
     SkRuntimeShaderBuilder effectBuilder(runtimeEffect);
 
@@ -53,7 +52,8 @@
 
     const auto uniforms =
             shaders::buildLinearEffectUniforms(linearEffect, colorTransform, maxDisplayLuminance,
-                                               currentDisplayLuminanceNits, maxLuminance, buffer);
+                                               currentDisplayLuminanceNits, maxLuminance, buffer,
+                                               renderIntent);
 
     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 26bae3b..3c66c51 100644
--- a/libs/renderengine/skia/filters/LinearEffect.h
+++ b/libs/renderengine/skia/filters/LinearEffect.h
@@ -42,12 +42,13 @@
 // or as the max light level from the CTA 861.3 standard.
 // * An AHardwareBuffer for implementations that support gralloc4 metadata for
 // communicating any HDR metadata.
-sk_sp<SkShader> createLinearEffectShader(sk_sp<SkShader> inputShader,
-                                         const shaders::LinearEffect& linearEffect,
-                                         sk_sp<SkRuntimeEffect> runtimeEffect,
-                                         const mat4& colorTransform, float maxDisplayLuminance,
-                                         float currentDisplayLuminanceNits, float maxLuminance,
-                                         AHardwareBuffer* buffer);
+// * A RenderIntent that communicates the downstream renderintent for a physical display, for image
+// quality compensation.
+sk_sp<SkShader> createLinearEffectShader(
+        sk_sp<SkShader> inputShader, const shaders::LinearEffect& linearEffect,
+        sk_sp<SkRuntimeEffect> runtimeEffect, const mat4& colorTransform, float maxDisplayLuminance,
+        float currentDisplayLuminanceNits, float maxLuminance, AHardwareBuffer* buffer,
+        aidl::android::hardware::graphics::composer3::RenderIntent renderIntent);
 } // namespace skia
 } // namespace renderengine
 } // namespace android
diff --git a/libs/shaders/Android.bp b/libs/shaders/Android.bp
index 2f8bf49..6b936de 100644
--- a/libs/shaders/Android.bp
+++ b/libs/shaders/Android.bp
@@ -29,6 +29,7 @@
 
     shared_libs: [
         "android.hardware.graphics.common-V3-ndk",
+        "android.hardware.graphics.composer3-V1-ndk",
         "android.hardware.graphics.common@1.2",
         "libnativewindow",
     ],
diff --git a/libs/shaders/include/shaders/shaders.h b/libs/shaders/include/shaders/shaders.h
index 4ec7594..2a4a370 100644
--- a/libs/shaders/include/shaders/shaders.h
+++ b/libs/shaders/include/shaders/shaders.h
@@ -97,11 +97,10 @@
 std::string buildLinearEffectSkSL(const LinearEffect& linearEffect);
 
 // Generates a list of uniforms to set on the LinearEffect shader above.
-std::vector<tonemap::ShaderUniform> buildLinearEffectUniforms(const LinearEffect& linearEffect,
-                                                              const mat4& colorTransform,
-                                                              float maxDisplayLuminance,
-                                                              float currentDisplayLuminanceNits,
-                                                              float maxLuminance,
-                                                              AHardwareBuffer* buffer = nullptr);
+std::vector<tonemap::ShaderUniform> buildLinearEffectUniforms(
+        const LinearEffect& linearEffect, const mat4& colorTransform, float maxDisplayLuminance,
+        float currentDisplayLuminanceNits, float maxLuminance, AHardwareBuffer* buffer = nullptr,
+        aidl::android::hardware::graphics::composer3::RenderIntent renderIntent =
+                aidl::android::hardware::graphics::composer3::RenderIntent::TONE_MAP_COLORIMETRIC);
 
 } // namespace android::shaders
diff --git a/libs/shaders/shaders.cpp b/libs/shaders/shaders.cpp
index 5935589..f0d45c2 100644
--- a/libs/shaders/shaders.cpp
+++ b/libs/shaders/shaders.cpp
@@ -464,12 +464,10 @@
 }
 
 // Generates a list of uniforms to set on the LinearEffect shader above.
-std::vector<tonemap::ShaderUniform> buildLinearEffectUniforms(const LinearEffect& linearEffect,
-                                                              const mat4& colorTransform,
-                                                              float maxDisplayLuminance,
-                                                              float currentDisplayLuminanceNits,
-                                                              float maxLuminance,
-                                                              AHardwareBuffer* buffer) {
+std::vector<tonemap::ShaderUniform> buildLinearEffectUniforms(
+        const LinearEffect& linearEffect, const mat4& colorTransform, float maxDisplayLuminance,
+        float currentDisplayLuminanceNits, float maxLuminance, AHardwareBuffer* buffer,
+        aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
     std::vector<tonemap::ShaderUniform> uniforms;
     if (linearEffect.inputDataspace == linearEffect.outputDataspace) {
         uniforms.push_back({.name = "in_rgbToXyz", .value = buildUniformValue<mat4>(mat4())});
@@ -495,7 +493,8 @@
                                .currentDisplayLuminance = currentDisplayLuminanceNits > 0
                                        ? currentDisplayLuminanceNits
                                        : maxDisplayLuminance,
-                               .buffer = buffer};
+                               .buffer = buffer,
+                               .renderIntent = renderIntent};
 
     for (const auto uniform : tonemap::getToneMapper()->generateShaderSkSLUniforms(metadata)) {
         uniforms.push_back(uniform);
diff --git a/libs/tonemap/Android.bp b/libs/tonemap/Android.bp
index dc55586..37c9824 100644
--- a/libs/tonemap/Android.bp
+++ b/libs/tonemap/Android.bp
@@ -29,6 +29,7 @@
 
     shared_libs: [
         "android.hardware.graphics.common-V3-ndk",
+        "android.hardware.graphics.composer3-V1-ndk",
         "liblog",
         "libnativewindow",
     ],
diff --git a/libs/tonemap/include/tonemap/tonemap.h b/libs/tonemap/include/tonemap/tonemap.h
index c51016d..852fc87 100644
--- a/libs/tonemap/include/tonemap/tonemap.h
+++ b/libs/tonemap/include/tonemap/tonemap.h
@@ -17,6 +17,7 @@
 #pragma once
 
 #include <aidl/android/hardware/graphics/common/Dataspace.h>
+#include <aidl/android/hardware/graphics/composer3/RenderIntent.h>
 #include <android/hardware_buffer.h>
 #include <math/vec3.h>
 
@@ -41,7 +42,7 @@
 
 // Describes metadata which may be used for constructing the shader uniforms.
 // 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.
+// as otherwise caching by other parts of the system using these shaders may break.
 struct Metadata {
     // The maximum luminance of the display in nits
     float displayMaxLuminance = 0.0;
@@ -61,6 +62,17 @@
     // texture that does not have associated metadata. As such, implementations
     // must support nullptr.
     AHardwareBuffer* buffer = nullptr;
+
+    // RenderIntent of the destination display.
+    // Non-colorimetric render-intents may be defined in order to take advantage of the full display
+    // gamut. Various contrast-enhancement mechanisms may be employed on SDR content as a result,
+    // which means that HDR content may need to be compensated in order to achieve correct blending
+    // behavior. This default is effectively optional - the display render intent may not be
+    // available to clients such as HWUI which are display-agnostic. For those clients, tone-map
+    // colorimetric may be assumed so that the luminance range may be converted to the correct range
+    // based on the output dataspace.
+    aidl::android::hardware::graphics::composer3::RenderIntent renderIntent =
+            aidl::android::hardware::graphics::composer3::RenderIntent::TONE_MAP_COLORIMETRIC;
 };
 
 // Utility class containing pre-processed conversions for a particular color
diff --git a/libs/tonemap/tests/Android.bp b/libs/tonemap/tests/Android.bp
index 26a1d79..58851b4 100644
--- a/libs/tonemap/tests/Android.bp
+++ b/libs/tonemap/tests/Android.bp
@@ -32,6 +32,7 @@
     ],
     shared_libs: [
         "android.hardware.graphics.common-V3-ndk",
+        "android.hardware.graphics.composer3-V1-ndk",
         "libnativewindow",
     ],
     static_libs: [
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index e99b70f..004e071 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -1177,6 +1177,9 @@
     clientCompositionDisplay.targetLuminanceNits =
             outputState.clientTargetBrightness * outputState.displayBrightnessNits;
     clientCompositionDisplay.dimmingStage = outputState.clientTargetDimmingStage;
+    clientCompositionDisplay.renderIntent =
+            static_cast<aidl::android::hardware::graphics::composer3::RenderIntent>(
+                    outputState.renderIntent);
 
     // Compute the global color transform matrix.
     clientCompositionDisplay.colorTransform = outputState.colorTransformMatrix;
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index 31a89af..42c8b37 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -3711,6 +3711,16 @@
         auto withDimmingStage(
                 aidl::android::hardware::graphics::composer3::DimmingStage dimmingStage) {
             getInstance()->mOutput.mState.clientTargetDimmingStage = dimmingStage;
+            return nextState<OutputWithRenderIntent>();
+        }
+    };
+
+    struct OutputWithRenderIntent
+          : public CallOrderStateMachineHelper<TestType, OutputWithRenderIntent> {
+        auto withRenderIntent(
+                aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
+            getInstance()->mOutput.mState.renderIntent =
+                    static_cast<ui::RenderIntent>(renderIntent);
             return nextState<SkipColorTransformState>();
         }
     };
@@ -3744,6 +3754,8 @@
             .andIfUsesHdr(true)
             .withDisplayBrightnessNits(kUnknownLuminance)
             .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
+            .withRenderIntent(
+                    aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
             .andIfSkipColorTransform(false)
             .thenExpectDisplaySettingsUsed(
                     {.physicalDisplay = kDefaultOutputDestinationClip,
@@ -3756,7 +3768,9 @@
                      .orientation = kDefaultOutputOrientationFlags,
                      .targetLuminanceNits = kClientTargetLuminanceNits,
                      .dimmingStage =
-                             aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
+                             aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
+                     .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
+                             COLORIMETRIC})
             .execute()
             .expectAFenceWasReturned();
 }
@@ -3767,7 +3781,8 @@
             .andIfUsesHdr(true)
             .withDisplayBrightnessNits(kDisplayLuminance)
             .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
-
+            .withRenderIntent(
+                    aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
             .andIfSkipColorTransform(false)
             .thenExpectDisplaySettingsUsed(
                     {.physicalDisplay = kDefaultOutputDestinationClip,
@@ -3780,7 +3795,9 @@
                      .orientation = kDefaultOutputOrientationFlags,
                      .targetLuminanceNits = kClientTargetLuminanceNits,
                      .dimmingStage =
-                             aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
+                             aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
+                     .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
+                             COLORIMETRIC})
             .execute()
             .expectAFenceWasReturned();
 }
@@ -3792,29 +3809,8 @@
             .withDisplayBrightnessNits(kUnknownLuminance)
             .withDimmingStage(
                     aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF)
-
-            .andIfSkipColorTransform(false)
-            .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
-                                            .clip = kDefaultOutputViewport,
-                                            .maxLuminance = kDefaultMaxLuminance,
-                                            .currentLuminanceNits = kDefaultMaxLuminance,
-                                            .outputDataspace = kDefaultOutputDataspace,
-                                            .colorTransform = kDefaultColorTransformMat,
-                                            .deviceHandlesColorTransform = true,
-                                            .orientation = kDefaultOutputOrientationFlags,
-                                            .targetLuminanceNits = kClientTargetLuminanceNits,
-                                            .dimmingStage = aidl::android::hardware::graphics::
-                                                    composer3::DimmingStage::GAMMA_OETF})
-            .execute()
-            .expectAFenceWasReturned();
-}
-
-TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
-    verify().ifMixedCompositionIs(true)
-            .andIfUsesHdr(false)
-            .withDisplayBrightnessNits(kUnknownLuminance)
-            .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
-
+            .withRenderIntent(
+                    aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
             .andIfSkipColorTransform(false)
             .thenExpectDisplaySettingsUsed(
                     {.physicalDisplay = kDefaultOutputDestinationClip,
@@ -3827,7 +3823,61 @@
                      .orientation = kDefaultOutputOrientationFlags,
                      .targetLuminanceNits = kClientTargetLuminanceNits,
                      .dimmingStage =
-                             aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
+                             aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
+                     .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
+                             COLORIMETRIC})
+            .execute()
+            .expectAFenceWasReturned();
+}
+
+TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
+       forHdrMixedCompositionWithRenderIntent) {
+    verify().ifMixedCompositionIs(true)
+            .andIfUsesHdr(true)
+            .withDisplayBrightnessNits(kUnknownLuminance)
+            .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
+            .withRenderIntent(aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE)
+            .andIfSkipColorTransform(false)
+            .thenExpectDisplaySettingsUsed(
+                    {.physicalDisplay = kDefaultOutputDestinationClip,
+                     .clip = kDefaultOutputViewport,
+                     .maxLuminance = kDefaultMaxLuminance,
+                     .currentLuminanceNits = kDefaultMaxLuminance,
+                     .outputDataspace = kDefaultOutputDataspace,
+                     .colorTransform = kDefaultColorTransformMat,
+                     .deviceHandlesColorTransform = true,
+                     .orientation = kDefaultOutputOrientationFlags,
+                     .targetLuminanceNits = kClientTargetLuminanceNits,
+                     .dimmingStage =
+                             aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
+                     .renderIntent =
+                             aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE})
+            .execute()
+            .expectAFenceWasReturned();
+}
+
+TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
+    verify().ifMixedCompositionIs(true)
+            .andIfUsesHdr(false)
+            .withDisplayBrightnessNits(kUnknownLuminance)
+            .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
+            .withRenderIntent(
+                    aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
+            .andIfSkipColorTransform(false)
+            .thenExpectDisplaySettingsUsed(
+                    {.physicalDisplay = kDefaultOutputDestinationClip,
+                     .clip = kDefaultOutputViewport,
+                     .maxLuminance = kDefaultMaxLuminance,
+                     .currentLuminanceNits = kDefaultMaxLuminance,
+                     .outputDataspace = kDefaultOutputDataspace,
+                     .colorTransform = kDefaultColorTransformMat,
+                     .deviceHandlesColorTransform = true,
+                     .orientation = kDefaultOutputOrientationFlags,
+                     .targetLuminanceNits = kClientTargetLuminanceNits,
+                     .dimmingStage =
+                             aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
+                     .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
+                             COLORIMETRIC})
             .execute()
             .expectAFenceWasReturned();
 }
@@ -3837,7 +3887,8 @@
             .andIfUsesHdr(true)
             .withDisplayBrightnessNits(kUnknownLuminance)
             .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
-
+            .withRenderIntent(
+                    aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
             .andIfSkipColorTransform(false)
             .thenExpectDisplaySettingsUsed(
                     {.physicalDisplay = kDefaultOutputDestinationClip,
@@ -3850,7 +3901,9 @@
                      .orientation = kDefaultOutputOrientationFlags,
                      .targetLuminanceNits = kClientTargetLuminanceNits,
                      .dimmingStage =
-                             aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
+                             aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
+                     .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
+                             COLORIMETRIC})
             .execute()
             .expectAFenceWasReturned();
 }
@@ -3860,7 +3913,8 @@
             .andIfUsesHdr(false)
             .withDisplayBrightnessNits(kUnknownLuminance)
             .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
-
+            .withRenderIntent(
+                    aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
             .andIfSkipColorTransform(false)
             .thenExpectDisplaySettingsUsed(
                     {.physicalDisplay = kDefaultOutputDestinationClip,
@@ -3873,7 +3927,9 @@
                      .orientation = kDefaultOutputOrientationFlags,
                      .targetLuminanceNits = kClientTargetLuminanceNits,
                      .dimmingStage =
-                             aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
+                             aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
+                     .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
+                             COLORIMETRIC})
             .execute()
             .expectAFenceWasReturned();
 }
@@ -3884,7 +3940,8 @@
             .andIfUsesHdr(true)
             .withDisplayBrightnessNits(kUnknownLuminance)
             .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
-
+            .withRenderIntent(
+                    aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
             .andIfSkipColorTransform(true)
             .thenExpectDisplaySettingsUsed(
                     {.physicalDisplay = kDefaultOutputDestinationClip,
@@ -3897,7 +3954,9 @@
                      .orientation = kDefaultOutputOrientationFlags,
                      .targetLuminanceNits = kClientTargetLuminanceNits,
                      .dimmingStage =
-                             aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
+                             aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
+                     .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
+                             COLORIMETRIC})
             .execute()
             .expectAFenceWasReturned();
 }
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 115dc64..498f37c 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -146,6 +146,7 @@
 
 #include <aidl/android/hardware/graphics/common/DisplayDecorationSupport.h>
 #include <aidl/android/hardware/graphics/composer3/DisplayCapability.h>
+#include <aidl/android/hardware/graphics/composer3/RenderIntent.h>
 
 #undef NO_THREAD_SAFETY_ANALYSIS
 #define NO_THREAD_SAFETY_ANALYSIS \
@@ -6668,6 +6669,7 @@
     captureResults.buffer = buffer->getBuffer();
     auto dataspace = renderArea.getReqDataSpace();
     auto parent = renderArea.getParentLayer();
+    auto renderIntent = RenderIntent::TONE_MAP_COLORIMETRIC;
     if ((dataspace == ui::Dataspace::UNKNOWN) && (parent != nullptr)) {
         Mutex::Autolock lock(mStateLock);
         auto display = findDisplay([layerStack = parent->getLayerStack()](const auto& display) {
@@ -6680,6 +6682,7 @@
 
         const ui::ColorMode colorMode = display->getCompositionDisplay()->getState().colorMode;
         dataspace = pickDataspaceFromColorMode(colorMode);
+        renderIntent = display->getCompositionDisplay()->getState().renderIntent;
     }
     captureResults.capturedDataspace = dataspace;
 
@@ -6701,6 +6704,8 @@
 
     clientCompositionDisplay.outputDataspace = dataspace;
     clientCompositionDisplay.maxLuminance = DisplayDevice::sDefaultMaxLumiance;
+    clientCompositionDisplay.renderIntent =
+            static_cast<aidl::android::hardware::graphics::composer3::RenderIntent>(renderIntent);
 
     const float colorSaturation = grayscale ? 0 : 1;
     clientCompositionDisplay.colorTransform = calculateColorMatrix(colorSaturation);