Improve tonemapping utilities

* Add util for getting buffer dataspace from metadata, since some
  ANativeWindow queries are unreliable when Surface endpoints are passed
  between processes, e.g., camera
* Let libshaders generate SkSL for SkColorFilters

Bug: 238395777
Test: Switching HDR cameras don't color shift
Change-Id: I7c3b917eeafcf8d028f8f52f38aa1389025bc607
diff --git a/libs/nativewindow/AHardwareBuffer.cpp b/libs/nativewindow/AHardwareBuffer.cpp
index 180dce9..bbafbff 100644
--- a/libs/nativewindow/AHardwareBuffer.cpp
+++ b/libs/nativewindow/AHardwareBuffer.cpp
@@ -702,6 +702,14 @@
     return ahardwarebuffer_format;
 }
 
+int32_t AHardwareBuffer_getDataSpace(AHardwareBuffer* buffer) {
+    GraphicBuffer* gb = AHardwareBuffer_to_GraphicBuffer(buffer);
+    auto& mapper = GraphicBufferMapper::get();
+    ui::Dataspace dataspace = ui::Dataspace::UNKNOWN;
+    mapper.getDataspace(gb->handle, &dataspace);
+    return static_cast<int32_t>(dataspace);
+}
+
 uint64_t AHardwareBuffer_convertToGrallocUsageBits(uint64_t usage) {
     using android::hardware::graphics::common::V1_1::BufferUsage;
     static_assert(AHARDWAREBUFFER_USAGE_CPU_READ_NEVER == (uint64_t)BufferUsage::CPU_READ_NEVER,
diff --git a/libs/nativewindow/include-private/private/android/AHardwareBufferHelpers.h b/libs/nativewindow/include-private/private/android/AHardwareBufferHelpers.h
index ddfd1d1..6d3d295 100644
--- a/libs/nativewindow/include-private/private/android/AHardwareBufferHelpers.h
+++ b/libs/nativewindow/include-private/private/android/AHardwareBufferHelpers.h
@@ -52,6 +52,11 @@
 // convert HAL format to AHardwareBuffer format (note: this is a no-op)
 uint32_t AHardwareBuffer_convertToPixelFormat(uint32_t format);
 
+// retrieves a dataspace from the AHardwareBuffer metadata, if the device
+// support gralloc metadata. Returns UNKNOWN if gralloc metadata is not
+// supported.
+int32_t AHardwareBuffer_getDataSpace(AHardwareBuffer* buffer);
+
 // convert AHardwareBuffer usage bits to HAL usage bits (note: this is a no-op)
 uint64_t AHardwareBuffer_convertFromGrallocUsageBits(uint64_t usage);
 
diff --git a/libs/nativewindow/libnativewindow.map.txt b/libs/nativewindow/libnativewindow.map.txt
index 76d23fa..e1ee490 100644
--- a/libs/nativewindow/libnativewindow.map.txt
+++ b/libs/nativewindow/libnativewindow.map.txt
@@ -71,6 +71,7 @@
       android::AHardwareBuffer_convertToPixelFormat*;
       android::AHardwareBuffer_convertFromGrallocUsageBits*;
       android::AHardwareBuffer_convertToGrallocUsageBits*;
+      android::AHardwareBuffer_getDataSpace*;
       android::AHardwareBuffer_to_GraphicBuffer*;
       android::AHardwareBuffer_to_ANativeWindowBuffer*;
       android::AHardwareBuffer_from_GraphicBuffer*;
diff --git a/libs/shaders/include/shaders/shaders.h b/libs/shaders/include/shaders/shaders.h
index 2a4a370..42b0cc1 100644
--- a/libs/shaders/include/shaders/shaders.h
+++ b/libs/shaders/include/shaders/shaders.h
@@ -68,6 +68,9 @@
     // fakeInputDataspace is used to essentially masquerade the input dataspace to be the output
     // dataspace for correct conversion to linear colors.
     ui::Dataspace fakeInputDataspace = ui::Dataspace::UNKNOWN;
+
+    enum SkSLType { Shader, ColorFilter };
+    SkSLType type = Shader;
 };
 
 static inline bool operator==(const LinearEffect& lhs, const LinearEffect& rhs) {
@@ -96,6 +99,10 @@
 // 2. Apply color transform matrices in linear space
 std::string buildLinearEffectSkSL(const LinearEffect& linearEffect);
 
+// Generates a shader string that applies color transforms in linear space.
+// This is intended to be plugged into an SkColorFilter
+std::string buildLinearEffectSkSLForColorFilter(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,
diff --git a/libs/shaders/shaders.cpp b/libs/shaders/shaders.cpp
index f80e93f..a3c403e 100644
--- a/libs/shaders/shaders.cpp
+++ b/libs/shaders/shaders.cpp
@@ -386,12 +386,23 @@
     }
 }
 
-void generateEffectiveOOTF(bool undoPremultipliedAlpha, std::string& shader) {
-    shader.append(R"(
-        uniform shader child;
-        half4 main(float2 xy) {
-            float4 c = float4(child.eval(xy));
-    )");
+void generateEffectiveOOTF(bool undoPremultipliedAlpha, LinearEffect::SkSLType type,
+                           std::string& shader) {
+    switch (type) {
+        case LinearEffect::SkSLType::ColorFilter:
+            shader.append(R"(
+                half4 main(half4 inputColor) {
+                    float4 c = float4(inputColor);
+            )");
+            break;
+        case LinearEffect::SkSLType::Shader:
+            shader.append(R"(
+                uniform shader child;
+                half4 main(float2 xy) {
+                    float4 c = float4(child.eval(xy));
+            )");
+            break;
+    }
     if (undoPremultipliedAlpha) {
         shader.append(R"(
             c.rgb = c.rgb / (c.a + 0.0019);
@@ -459,7 +470,7 @@
     generateXYZTransforms(shaderString);
     generateOOTF(linearEffect.inputDataspace, linearEffect.outputDataspace, shaderString);
     generateOETF(linearEffect.outputDataspace, shaderString);
-    generateEffectiveOOTF(linearEffect.undoPremultipliedAlpha, shaderString);
+    generateEffectiveOOTF(linearEffect.undoPremultipliedAlpha, linearEffect.type, shaderString);
     return shaderString;
 }