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: [