graphics: add RenderIntent and better HDR support

This adds

  ColorMode::BT2020
  ColorMode::BT2100_PQ
  ColorMode::BT2100_HLG
  Dataspace::BT2020_HLG
  Dataspace::BT2020_ITU_HLG
  RenderIntent::COLORIMETRIC
  RenderIntent::ENHANCE
  RenderIntent::TONE_MAP_COLORIMETRIC
  RenderIntent::TONE_MAP_ENHANCE

and fixes per-frame metadata to be per-layer.  It also clarifies how
the composer should treat certain dataspaces and makes the
corresponding composer changes.

Bug: 73824924
Bug: 32148660
Test: manual
Change-Id: I5d12f50190522103c2ac97ee8dc2d5f6a2dabffe
diff --git a/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h b/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h
index c803d3c..b499ca9 100644
--- a/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h
+++ b/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h
@@ -72,8 +72,9 @@
         endCommand();
     }
 
-    void setPerFrameMetadata(const hidl_vec<IComposerClient::PerFrameMetadata>& metadataVec) {
-        beginCommand_2_2(IComposerClient::Command::SET_PER_FRAME_METADATA, metadataVec.size() * 2);
+    void setLayerPerFrameMetadata(const hidl_vec<IComposerClient::PerFrameMetadata>& metadataVec) {
+        beginCommand_2_2(IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA,
+                         metadataVec.size() * 2);
         for (const auto& metadata : metadataVec) {
             writeSigned(static_cast<int32_t>(metadata.key));
             writeFloat(metadata.value);
diff --git a/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerClient.h b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerClient.h
index d550f83..ba6723d 100644
--- a/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerClient.h
+++ b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerClient.h
@@ -103,6 +103,64 @@
         return mHal->setPowerMode_2_2(display, mode);
     }
 
+    Return<void> getColorModes_2_2(Display display,
+                                   IComposerClient::getColorModes_2_2_cb hidl_cb) override {
+        hidl_vec<ColorMode> modes;
+        Error err = mHal->getColorModes_2_2(display, &modes);
+        hidl_cb(err, modes);
+        return Void();
+    }
+
+    Return<void> getRenderIntents(Display display, ColorMode mode,
+                                  IComposerClient::getRenderIntents_cb hidl_cb) override {
+#ifdef USES_DISPLAY_RENDER_INTENTS
+        std::vector<RenderIntent> intents;
+        Error err = mHal->getRenderIntents(display, mode, &intents);
+        hidl_cb(err, intents);
+#else
+        (void)display;
+        (void)mode;
+        hidl_cb(Error::NONE, hidl_vec<RenderIntent>({RenderIntent::COLORIMETRIC}));
+#endif
+        return Void();
+    }
+
+    Return<Error> setColorMode_2_2(Display display, ColorMode mode, RenderIntent intent) override {
+#ifndef USES_DISPLAY_RENDER_INTENTS
+        if (intent != RenderIntent::COLORIMETRIC) {
+            return Error::BAD_PARAMETER;
+        }
+#endif
+        return mHal->setColorMode_2_2(display, mode, intent);
+    }
+
+    Return<void> getDataspaceSaturationMatrix(
+        Dataspace dataspace, IComposerClient::getDataspaceSaturationMatrix_cb hidl_cb) override {
+        if (dataspace != Dataspace::SRGB_LINEAR) {
+            hidl_cb(Error::BAD_PARAMETER, std::array<float, 16>{0.0f}.data());
+            return Void();
+        }
+
+        hidl_cb(Error::NONE, mHal->getDataspaceSaturationMatrix(dataspace).data());
+        return Void();
+    }
+
+    Return<void> executeCommands_2_2(uint32_t inLength, const hidl_vec<hidl_handle>& inHandles,
+                                     IComposerClient::executeCommands_2_2_cb hidl_cb) override {
+        std::lock_guard<std::mutex> lock(mCommandEngineMutex);
+        bool outChanged = false;
+        uint32_t outLength = 0;
+        hidl_vec<hidl_handle> outHandles;
+        Error error =
+            mCommandEngine->execute(inLength, inHandles, &outChanged, &outLength, &outHandles);
+
+        hidl_cb(error, outChanged, outLength, outHandles);
+
+        mCommandEngine->reset();
+
+        return Void();
+    }
+
    protected:
     std::unique_ptr<V2_1::hal::ComposerResources> createResources() override {
         return ComposerResources::create();
@@ -146,6 +204,8 @@
 
    private:
     using BaseType2_1 = V2_1::hal::detail::ComposerClientImpl<Interface, Hal>;
+    using BaseType2_1::mCommandEngine;
+    using BaseType2_1::mCommandEngineMutex;
     using BaseType2_1::mHal;
     using BaseType2_1::mResources;
 };
diff --git a/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerCommandEngine.h b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerCommandEngine.h
index adcac46..97e3a9e 100644
--- a/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerCommandEngine.h
+++ b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerCommandEngine.h
@@ -40,8 +40,8 @@
    protected:
     bool executeCommand(V2_1::IComposerClient::Command command, uint16_t length) override {
         switch (static_cast<IComposerClient::Command>(command)) {
-            case IComposerClient::Command::SET_PER_FRAME_METADATA:
-                return executeSetPerFrameMetadata(length);
+            case IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA:
+                return executeSetLayerPerFrameMetadata(length);
             case IComposerClient::Command::SET_LAYER_FLOAT_COLOR:
                 return executeSetLayerFloatColor(length);
             default:
@@ -49,7 +49,7 @@
         }
     }
 
-    bool executeSetPerFrameMetadata(uint16_t length) {
+    bool executeSetLayerPerFrameMetadata(uint16_t length) {
         // (key, value) pairs
         if (length % 2 != 0) {
             return false;
@@ -63,7 +63,7 @@
             length -= 2;
         }
 
-        auto err = mHal->setPerFrameMetadata(mCurrentDisplay, metadata);
+        auto err = mHal->setLayerPerFrameMetadata(mCurrentDisplay, mCurrentLayer, metadata);
         if (err != Error::NONE) {
             mWriter.setError(getCommandLoc(), err);
         }
diff --git a/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerHal.h b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerHal.h
index 30b3643..12191be 100644
--- a/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerHal.h
+++ b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerHal.h
@@ -30,6 +30,8 @@
 
 using common::V1_0::Dataspace;
 using common::V1_0::PixelFormat;
+using common::V1_1::ColorMode;
+using common::V1_1::RenderIntent;
 using V2_1::Display;
 using V2_1::Error;
 using V2_1::Layer;
@@ -41,10 +43,21 @@
         return setPowerMode_2_2(display, static_cast<IComposerClient::PowerMode>(mode));
     }
 
+    // superceded by getColorModes_2_2
+    Error getColorModes(Display display, hidl_vec<common::V1_0::ColorMode>* outModes) override {
+        return getColorModes_2_2(display, reinterpret_cast<hidl_vec<ColorMode>*>(outModes));
+    }
+
+    // superceded by setColorMode_2_2
+    Error setColorMode(Display display, common::V1_0::ColorMode mode) override {
+        return setColorMode_2_2(display, static_cast<ColorMode>(mode), RenderIntent::COLORIMETRIC);
+    }
+
     virtual Error getPerFrameMetadataKeys(
         Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) = 0;
-    virtual Error setPerFrameMetadata(
-        Display display, const std::vector<IComposerClient::PerFrameMetadata>& metadata) = 0;
+    virtual Error setLayerPerFrameMetadata(
+        Display display, Layer layer,
+        const std::vector<IComposerClient::PerFrameMetadata>& metadata) = 0;
 
     virtual Error getReadbackBufferAttributes(Display display, PixelFormat* outFormat,
                                               Dataspace* outDataspace) = 0;
@@ -56,6 +69,13 @@
 
     virtual Error setLayerFloatColor(Display display, Layer layer,
                                      IComposerClient::FloatColor color) = 0;
+
+    virtual Error getColorModes_2_2(Display display, hidl_vec<ColorMode>* outModes) = 0;
+    virtual Error getRenderIntents(Display display, ColorMode mode,
+                                   std::vector<RenderIntent>* outIntents) = 0;
+    virtual Error setColorMode_2_2(Display display, ColorMode mode, RenderIntent intent) = 0;
+
+    virtual std::array<float, 16> getDataspaceSaturationMatrix(Dataspace dataspace) = 0;
 };
 
 }  // namespace hal
diff --git a/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h b/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h
index b251351..7e38a79 100644
--- a/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h
+++ b/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h
@@ -36,6 +36,8 @@
 
 using common::V1_0::Dataspace;
 using common::V1_0::PixelFormat;
+using common::V1_1::ColorMode;
+using common::V1_1::RenderIntent;
 using V2_1::Display;
 using V2_1::Error;
 using V2_1::Layer;
@@ -72,9 +74,10 @@
         return Error::NONE;
     }
 
-    Error setPerFrameMetadata(
-        Display display, const std::vector<IComposerClient::PerFrameMetadata>& metadata) override {
-        if (!mDispatch.setPerFrameMetadata) {
+    Error setLayerPerFrameMetadata(
+        Display display, Layer layer,
+        const std::vector<IComposerClient::PerFrameMetadata>& metadata) override {
+        if (!mDispatch.setLayerPerFrameMetadata) {
             return Error::UNSUPPORTED;
         }
 
@@ -87,8 +90,8 @@
             values.push_back(m.value);
         }
 
-        int32_t error = mDispatch.setPerFrameMetadata(mDevice, display, metadata.size(),
-                                                      keys.data(), values.data());
+        int32_t error = mDispatch.setLayerPerFrameMetadata(mDevice, display, layer, metadata.size(),
+                                                           keys.data(), values.data());
         return static_cast<Error>(error);
     }
 
@@ -149,6 +152,69 @@
         return static_cast<Error>(error);
     }
 
+    Error getColorModes_2_2(Display display, hidl_vec<ColorMode>* outModes) override {
+        return getColorModes(display,
+                             reinterpret_cast<hidl_vec<common::V1_0::ColorMode>*>(outModes));
+    }
+
+    Error getRenderIntents(Display display, ColorMode mode,
+                           std::vector<RenderIntent>* outIntents) override {
+        if (!mDispatch.getRenderIntents) {
+            *outIntents = std::vector<RenderIntent>({RenderIntent::COLORIMETRIC});
+            return Error::NONE;
+        }
+
+        uint32_t count = 0;
+        int32_t error =
+            mDispatch.getRenderIntents(mDevice, display, int32_t(mode), &count, nullptr);
+        if (error != HWC2_ERROR_NONE) {
+            return static_cast<Error>(error);
+        }
+
+        std::vector<RenderIntent> intents(count);
+        error = mDispatch.getRenderIntents(
+            mDevice, display, int32_t(mode), &count,
+            reinterpret_cast<std::underlying_type<RenderIntent>::type*>(intents.data()));
+        if (error != HWC2_ERROR_NONE) {
+            return static_cast<Error>(error);
+        }
+        intents.resize(count);
+
+        *outIntents = std::move(intents);
+        return Error::NONE;
+    }
+
+    Error setColorMode_2_2(Display display, ColorMode mode, RenderIntent intent) override {
+        if (!mDispatch.setColorModeWithRenderIntent) {
+            if (intent != RenderIntent::COLORIMETRIC) {
+                return Error::UNSUPPORTED;
+            }
+            return setColorMode(display, static_cast<common::V1_0::ColorMode>(mode));
+        }
+
+        int32_t err = mDispatch.setColorModeWithRenderIntent(
+            mDevice, display, static_cast<int32_t>(mode), static_cast<int32_t>(intent));
+        return static_cast<Error>(err);
+    }
+
+    std::array<float, 16> getDataspaceSaturationMatrix(Dataspace dataspace) override {
+        std::array<float, 16> matrix;
+
+        int32_t error = HWC2_ERROR_UNSUPPORTED;
+        if (mDispatch.getDataspaceSaturationMatrix) {
+            error = mDispatch.getDataspaceSaturationMatrix(mDevice, static_cast<int32_t>(dataspace),
+                                                           matrix.data());
+        }
+        if (error != HWC2_ERROR_NONE) {
+            return std::array<float, 16>{
+                1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
+                0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
+            };
+        }
+
+        return matrix;
+    }
+
    protected:
     template <typename T>
     bool initOptionalDispatch(hwc2_function_descriptor_t desc, T* outPfn) {
@@ -168,7 +234,8 @@
 
         initOptionalDispatch(HWC2_FUNCTION_SET_LAYER_FLOAT_COLOR, &mDispatch.setLayerFloatColor);
 
-        initOptionalDispatch(HWC2_FUNCTION_SET_PER_FRAME_METADATA, &mDispatch.setPerFrameMetadata);
+        initOptionalDispatch(HWC2_FUNCTION_SET_LAYER_PER_FRAME_METADATA,
+                             &mDispatch.setLayerPerFrameMetadata);
         initOptionalDispatch(HWC2_FUNCTION_GET_PER_FRAME_METADATA_KEYS,
                              &mDispatch.getPerFrameMetadataKeys);
 
@@ -178,21 +245,32 @@
         initOptionalDispatch(HWC2_FUNCTION_GET_READBACK_BUFFER_FENCE,
                              &mDispatch.getReadbackBufferFence);
 
+        initOptionalDispatch(HWC2_FUNCTION_GET_RENDER_INTENTS, &mDispatch.getRenderIntents);
+        initOptionalDispatch(HWC2_FUNCTION_SET_COLOR_MODE_WITH_RENDER_INTENT,
+                             &mDispatch.setColorModeWithRenderIntent);
+        initOptionalDispatch(HWC2_FUNCTION_GET_DATASPACE_SATURATION_MATRIX,
+                             &mDispatch.getDataspaceSaturationMatrix);
+
         return true;
     }
 
     struct {
         HWC2_PFN_SET_LAYER_FLOAT_COLOR setLayerFloatColor;
-        HWC2_PFN_SET_PER_FRAME_METADATA setPerFrameMetadata;
+        HWC2_PFN_SET_LAYER_PER_FRAME_METADATA setLayerPerFrameMetadata;
         HWC2_PFN_GET_PER_FRAME_METADATA_KEYS getPerFrameMetadataKeys;
         HWC2_PFN_SET_READBACK_BUFFER setReadbackBuffer;
         HWC2_PFN_GET_READBACK_BUFFER_ATTRIBUTES getReadbackBufferAttributes;
         HWC2_PFN_GET_READBACK_BUFFER_FENCE getReadbackBufferFence;
+        HWC2_PFN_GET_RENDER_INTENTS getRenderIntents;
+        HWC2_PFN_SET_COLOR_MODE_WITH_RENDER_INTENT setColorModeWithRenderIntent;
+        HWC2_PFN_GET_DATASPACE_SATURATION_MATRIX getDataspaceSaturationMatrix;
     } mDispatch = {};
 
    private:
     using BaseType2_1 = V2_1::passthrough::detail::HwcHalImpl<Hal>;
+    using BaseType2_1::getColorModes;
     using BaseType2_1::mDevice;
+    using BaseType2_1::setColorMode;
     using BaseType2_1::setPowerMode;
 };
 
diff --git a/graphics/composer/2.2/utils/vts/Android.bp b/graphics/composer/2.2/utils/vts/Android.bp
index 641fdcb..c6b524d 100644
--- a/graphics/composer/2.2/utils/vts/Android.bp
+++ b/graphics/composer/2.2/utils/vts/Android.bp
@@ -26,10 +26,17 @@
         "android.hardware.graphics.composer@2.1-vts",
         "android.hardware.graphics.composer@2.2",
     ],
+    export_static_lib_headers: [
+        "android.hardware.graphics.composer@2.1-vts",
+    ],
     header_libs: [
         "android.hardware.graphics.composer@2.1-command-buffer",
         "android.hardware.graphics.composer@2.2-command-buffer",
     ],
+    export_header_lib_headers: [
+        "android.hardware.graphics.composer@2.1-command-buffer",
+        "android.hardware.graphics.composer@2.2-command-buffer",
+    ],
     cflags: [
         "-O0",
         "-g",
diff --git a/graphics/composer/2.2/utils/vts/ComposerVts.cpp b/graphics/composer/2.2/utils/vts/ComposerVts.cpp
index b536f67..9a035f6 100644
--- a/graphics/composer/2.2/utils/vts/ComposerVts.cpp
+++ b/graphics/composer/2.2/utils/vts/ComposerVts.cpp
@@ -119,6 +119,41 @@
     *outFence = 0;
 }
 
+std::vector<ColorMode> ComposerClient_v2_2::getColorModes(Display display) {
+    std::vector<ColorMode> modes;
+    mClient_v2_2->getColorModes_2_2(display, [&](const auto& tmpError, const auto& tmpModes) {
+        ASSERT_EQ(Error::NONE, tmpError) << "failed to get color modes";
+        modes = tmpModes;
+    });
+    return modes;
+}
+
+std::vector<RenderIntent> ComposerClient_v2_2::getRenderIntents(Display display, ColorMode mode) {
+    std::vector<RenderIntent> intents;
+    mClient_v2_2->getRenderIntents(
+        display, mode, [&](const auto& tmpError, const auto& tmpIntents) {
+            ASSERT_EQ(Error::NONE, tmpError) << "failed to get render intents";
+            intents = tmpIntents;
+        });
+    return intents;
+}
+
+void ComposerClient_v2_2::setColorMode(Display display, ColorMode mode, RenderIntent intent) {
+    Error error = mClient_v2_2->setColorMode_2_2(display, mode, intent);
+    ASSERT_TRUE(error == Error::NONE || error == Error::UNSUPPORTED) << "failed to set color mode";
+}
+
+std::array<float, 16> ComposerClient_v2_2::getDataspaceSaturationMatrix(Dataspace dataspace) {
+    std::array<float, 16> matrix;
+    mClient_v2_2->getDataspaceSaturationMatrix(
+        dataspace, [&](const auto& tmpError, const auto& tmpMatrix) {
+            ASSERT_EQ(Error::NONE, tmpError) << "failed to get datasapce saturation matrix";
+            std::copy_n(tmpMatrix.data(), matrix.size(), matrix.begin());
+        });
+
+    return matrix;
+}
+
 }  // namespace vts
 }  // namespace V2_2
 }  // namespace composer
diff --git a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h
index eced69f..5467011 100644
--- a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h
+++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h
@@ -36,10 +36,11 @@
 namespace V2_2 {
 namespace vts {
 
-using android::hardware::graphics::common::V1_0::ColorMode;
 using android::hardware::graphics::common::V1_0::Dataspace;
 using android::hardware::graphics::common::V1_0::Hdr;
 using android::hardware::graphics::common::V1_0::PixelFormat;
+using android::hardware::graphics::common::V1_1::ColorMode;
+using android::hardware::graphics::common::V1_1::RenderIntent;
 using android::hardware::graphics::composer::V2_2::IComposer;
 using android::hardware::graphics::composer::V2_2::IComposerClient;
 
@@ -72,6 +73,12 @@
                                      Dataspace* outDataspace);
     void getReadbackBufferFence(Display display, int32_t* outFence);
 
+    std::vector<ColorMode> getColorModes(Display display);
+    std::vector<RenderIntent> getRenderIntents(Display display, ColorMode mode);
+    void setColorMode(Display display, ColorMode mode, RenderIntent intent);
+
+    std::array<float, 16> getDataspaceSaturationMatrix(Dataspace dataspace);
+
    private:
     sp<V2_2::IComposerClient> mClient_v2_2;
 };