SF: Separate out display color handling
This creates a new class for the purpose of holding all the
functionality related to how colors are handled on the output display.
Test: atest libsurfaceflinger_unittest libcompositionengine_test
Bug: 121291683
Change-Id: Idcd4808c42d17ca37656993131d280ead3137a52
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
index 9ba6671..dbcd3bd 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
@@ -26,6 +26,7 @@
namespace android::compositionengine {
struct RenderSurfaceCreationArgs;
+struct DisplayColorProfileCreationArgs;
/**
* A display is a composition target which may be backed by a hardware composer
@@ -45,6 +46,10 @@
// Releases the use of the HWC display, if any
virtual void disconnect() = 0;
+ // Creates a render color mode for the display
+ virtual void createDisplayColorProfile(DisplayColorProfileCreationArgs&&) = 0;
+
+ // Creates a render surface for the display
virtual void createRenderSurface(RenderSurfaceCreationArgs&&) = 0;
protected:
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayColorProfile.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayColorProfile.h
new file mode 100644
index 0000000..e2a0d42
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayColorProfile.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <cstdint>
+
+#include <ui/GraphicTypes.h>
+
+namespace android {
+
+class HdrCapabilities;
+
+namespace compositionengine {
+
+/**
+ * Encapsulates all the state and functionality for how colors should be
+ * transformed for a display
+ */
+class DisplayColorProfile {
+public:
+ constexpr static float sDefaultMinLumiance = 0.0;
+ constexpr static float sDefaultMaxLumiance = 500.0;
+
+ virtual ~DisplayColorProfile();
+
+ // Returns true if the profile is valid. This is meant to be checked post-
+ // construction and prior to use, as not everything is set up by the
+ // constructor.
+ virtual bool isValid() const = 0;
+
+ // Returns true if the profile supports the indicated render intent
+ virtual bool hasRenderIntent(ui::RenderIntent) const = 0;
+
+ // Returns true if the profile supports the indicated dataspace
+ virtual bool hasLegacyHdrSupport(ui::Dataspace) const = 0;
+
+ // Obtains the best combination of color mode and render intent for the
+ // input values
+ virtual void getBestColorMode(ui::Dataspace dataspace, ui::RenderIntent intent,
+ ui::Dataspace* outDataspace, ui::ColorMode* outMode,
+ ui::RenderIntent* outIntent) const = 0;
+
+ // Returns true if the profile supports a wide color gamut
+ virtual bool hasWideColorGamut() const = 0;
+
+ // Returns the per-frame metadata value for this profile
+ virtual int32_t getSupportedPerFrameMetadata() const = 0;
+
+ // Returns true if HWC for this profile supports HDR10Plus
+ virtual bool hasHDR10PlusSupport() const = 0;
+
+ // Returns true if HWC for this profile supports HDR10
+ virtual bool hasHDR10Support() const = 0;
+
+ // Returns true if HWC for this profile supports HLG
+ virtual bool hasHLGSupport() const = 0;
+
+ // Returns true if HWC for this profile supports DolbyVision
+ virtual bool hasDolbyVisionSupport() const = 0;
+
+ // Gets the supported HDR capabilities for the profile
+ virtual const HdrCapabilities& getHdrCapabilities() const = 0;
+
+ // Debugging
+ virtual void dump(std::string&) const = 0;
+};
+
+} // namespace compositionengine
+} // namespace android
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayColorProfileCreationArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayColorProfileCreationArgs.h
new file mode 100644
index 0000000..ef0f925
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayColorProfileCreationArgs.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <unordered_map>
+#include <vector>
+
+#include <ui/GraphicTypes.h>
+#include <ui/HdrCapabilities.h>
+
+namespace android::compositionengine {
+
+/**
+ * A parameter object for creating DisplayColorProfile instances
+ */
+struct DisplayColorProfileCreationArgs {
+ using HwcColorModes = std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>>;
+
+ // True if this display supports a wide color gamut
+ bool hasWideColorGamut;
+
+ // The HDR capabilities supported by the HWC
+ HdrCapabilities hdrCapabilities;
+
+ // The per-frame metadata supported by the HWC
+ int32_t supportedPerFrameMetadata;
+
+ // The mapping of color modes and render intents supported by the HWC
+ HwcColorModes hwcColorModes;
+};
+
+/**
+ * A helper for setting up a DisplayColorProfileCreationArgs value in-line.
+ *
+ * Prefer this builder over raw structure initialization.
+ *
+ * Instead of:
+ *
+ * DisplayColorProfileCreationArgs{false, HdrCapabilities(), 0,
+ * HwcColorModes()}
+ *
+ * Prefer:
+ *
+ * DisplayColorProfileCreationArgsBuilder().setHasWideColorGamut(false)
+ * .setIsVirtual(false).setDisplayId(displayId).Build();
+ */
+class DisplayColorProfileCreationArgsBuilder {
+public:
+ DisplayColorProfileCreationArgs Build() { return std::move(mArgs); }
+
+ DisplayColorProfileCreationArgsBuilder& setHasWideColorGamut(bool hasWideColorGamut) {
+ mArgs.hasWideColorGamut = hasWideColorGamut;
+ return *this;
+ }
+ DisplayColorProfileCreationArgsBuilder& setHdrCapabilities(HdrCapabilities&& hdrCapabilities) {
+ mArgs.hdrCapabilities = std::move(hdrCapabilities);
+ return *this;
+ }
+ DisplayColorProfileCreationArgsBuilder& setSupportedPerFrameMetadata(
+ int32_t supportedPerFrameMetadata) {
+ mArgs.supportedPerFrameMetadata = supportedPerFrameMetadata;
+ return *this;
+ }
+ DisplayColorProfileCreationArgsBuilder& setHwcColorModes(
+ DisplayColorProfileCreationArgs::HwcColorModes&& hwcColorModes) {
+ mArgs.hwcColorModes = std::move(hwcColorModes);
+ return *this;
+ }
+
+private:
+ DisplayColorProfileCreationArgs mArgs;
+};
+
+} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
index 7814bcb..2d00f0c 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
@@ -26,6 +26,7 @@
namespace android::compositionengine {
+class DisplayColorProfile;
class RenderSurface;
namespace impl {
@@ -72,6 +73,9 @@
// Sets a debug name for the output
virtual void setName(const std::string&) = 0;
+ // Gets the current render color mode for the output
+ virtual DisplayColorProfile* getDisplayColorProfile() const = 0;
+
// Gets the current render surface for the output
virtual RenderSurface* getRenderSurface() const = 0;
@@ -98,7 +102,8 @@
protected:
~Output() = default;
- virtual void setRenderSurface(std::unique_ptr<RenderSurface> surface) = 0;
+ virtual void setDisplayColorProfile(std::unique_ptr<DisplayColorProfile>) = 0;
+ virtual void setRenderSurface(std::unique_ptr<RenderSurface>) = 0;
};
} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
index 5609382..0e20c43 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
@@ -46,6 +46,7 @@
bool isSecure() const override;
bool isVirtual() const override;
void disconnect() override;
+ void createDisplayColorProfile(compositionengine::DisplayColorProfileCreationArgs&&) override;
void createRenderSurface(compositionengine::RenderSurfaceCreationArgs&&) override;
private:
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/DisplayColorProfile.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/DisplayColorProfile.h
new file mode 100644
index 0000000..49c2d2c
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/DisplayColorProfile.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <unordered_map>
+#include <vector>
+
+#include <compositionengine/DisplayColorProfile.h>
+#include <compositionengine/DisplayColorProfileCreationArgs.h>
+#include <ui/HdrCapabilities.h>
+
+namespace android::compositionengine {
+
+class CompositionEngine;
+class Display;
+
+namespace impl {
+
+class DisplayColorProfile : public compositionengine::DisplayColorProfile {
+public:
+ DisplayColorProfile(DisplayColorProfileCreationArgs&&);
+ ~DisplayColorProfile() override;
+
+ bool isValid() const override;
+
+ bool hasRenderIntent(ui::RenderIntent intent) const override;
+ bool hasLegacyHdrSupport(ui::Dataspace dataspace) const override;
+ void getBestColorMode(ui::Dataspace dataspace, ui::RenderIntent intent,
+ ui::Dataspace* outDataspace, ui::ColorMode* outMode,
+ ui::RenderIntent* outIntent) const override;
+
+ bool hasWideColorGamut() const override;
+ int32_t getSupportedPerFrameMetadata() const override;
+
+ // Whether h/w composer has native support for specific HDR type.
+ bool hasHDR10PlusSupport() const override;
+ bool hasHDR10Support() const override;
+ bool hasHLGSupport() const override;
+ bool hasDolbyVisionSupport() const override;
+
+ const HdrCapabilities& getHdrCapabilities() const override;
+
+ void dump(std::string&) const override;
+
+private:
+ void populateColorModes(const DisplayColorProfileCreationArgs::HwcColorModes& hwcColorModes);
+ void addColorMode(const DisplayColorProfileCreationArgs::HwcColorModes& hwcColorModes,
+ const ui::ColorMode mode, const ui::RenderIntent intent);
+
+ // Mappings from desired Dataspace/RenderIntent to the supported
+ // Dataspace/ColorMode/RenderIntent.
+ using ColorModeKey = uint64_t;
+ struct ColorModeValue {
+ ui::Dataspace dataspace;
+ ui::ColorMode colorMode;
+ ui::RenderIntent renderIntent;
+ };
+
+ static ColorModeKey getColorModeKey(ui::Dataspace dataspace, ui::RenderIntent intent) {
+ return (static_cast<uint64_t>(dataspace) << 32) | static_cast<uint32_t>(intent);
+ }
+
+ // Need to know if display is wide-color capable or not.
+ // Initialized by SurfaceFlinger when the DisplayDevice is created.
+ // Fed to RenderEngine during composition.
+ bool mHasWideColorGamut{false};
+ int32_t mSupportedPerFrameMetadata{0};
+ bool mHasHdr10Plus{false};
+ bool mHasHdr10{false};
+ bool mHasHLG{false};
+ bool mHasDolbyVision{false};
+ HdrCapabilities mHdrCapabilities;
+ std::unordered_map<ColorModeKey, ColorModeValue> mColorModes;
+};
+
+std::unique_ptr<compositionengine::DisplayColorProfile> createDisplayColorProfile(
+ DisplayColorProfileCreationArgs&&);
+
+} // namespace impl
+} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
index 86a1662..521e1d7 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
@@ -48,6 +48,9 @@
const std::string& getName() const override;
void setName(const std::string&) override;
+ compositionengine::DisplayColorProfile* getDisplayColorProfile() const override;
+ void setDisplayColorProfile(std::unique_ptr<compositionengine::DisplayColorProfile>) override;
+
compositionengine::RenderSurface* getRenderSurface() const override;
void setRenderSurface(std::unique_ptr<compositionengine::RenderSurface>) override;
@@ -58,6 +61,7 @@
bool belongsInOutput(uint32_t) const override;
// Testing
+ void setDisplayColorProfileForTest(std::unique_ptr<compositionengine::DisplayColorProfile>);
void setRenderSurfaceForTest(std::unique_ptr<compositionengine::RenderSurface>);
protected:
@@ -73,6 +77,7 @@
OutputCompositionState mState;
+ std::unique_ptr<compositionengine::DisplayColorProfile> mDisplayColorProfile;
std::unique_ptr<compositionengine::RenderSurface> mRenderSurface;
};
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h
index e4adfc5..d763aa6 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h
@@ -17,7 +17,7 @@
#pragma once
#include <compositionengine/Display.h>
-#include <compositionengine/DisplaySurface.h>
+#include <compositionengine/DisplayColorProfileCreationArgs.h>
#include <compositionengine/RenderSurfaceCreationArgs.h>
#include <compositionengine/mock/Output.h>
#include <gmock/gmock.h>
@@ -38,6 +38,7 @@
MOCK_METHOD0(disconnect, void());
+ MOCK_METHOD1(createDisplayColorProfile, void(DisplayColorProfileCreationArgs&&));
MOCK_METHOD1(createRenderSurface, void(RenderSurfaceCreationArgs&&));
};
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/DisplayColorProfile.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/DisplayColorProfile.h
new file mode 100644
index 0000000..8056c9d
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/DisplayColorProfile.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <compositionengine/DisplayColorProfile.h>
+#include <gmock/gmock.h>
+#include <ui/HdrCapabilities.h>
+
+namespace android::compositionengine::mock {
+
+class DisplayColorProfile : public compositionengine::DisplayColorProfile {
+public:
+ DisplayColorProfile();
+ ~DisplayColorProfile() override;
+
+ MOCK_CONST_METHOD0(isValid, bool());
+
+ MOCK_CONST_METHOD1(hasRenderIntent, bool(ui::RenderIntent));
+ MOCK_CONST_METHOD1(hasLegacyHdrSupport, bool(ui::Dataspace));
+ MOCK_CONST_METHOD5(getBestColorMode,
+ void(ui::Dataspace, ui::RenderIntent, ui::Dataspace*, ui::ColorMode*,
+ ui::RenderIntent*));
+ MOCK_CONST_METHOD0(hasWideColorGamut, bool());
+ MOCK_CONST_METHOD0(getSupportedPerFrameMetadata, int32_t());
+ MOCK_CONST_METHOD0(hasHDR10PlusSupport, bool());
+ MOCK_CONST_METHOD0(hasHDR10Support, bool());
+ MOCK_CONST_METHOD0(hasHLGSupport, bool());
+ MOCK_CONST_METHOD0(hasDolbyVisionSupport, bool());
+
+ MOCK_CONST_METHOD0(getHdrCapabilities, const HdrCapabilities&());
+
+ MOCK_CONST_METHOD1(dump, void(std::string&));
+};
+
+} // namespace android::compositionengine::mock
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
index 3f2cc05..37f7007 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
@@ -16,6 +16,7 @@
#pragma once
+#include <compositionengine/DisplayColorProfile.h>
#include <compositionengine/Output.h>
#include <compositionengine/RenderSurface.h>
#include <compositionengine/impl/OutputCompositionState.h>
@@ -43,6 +44,9 @@
MOCK_CONST_METHOD0(getName, const std::string&());
MOCK_METHOD1(setName, void(const std::string&));
+ MOCK_CONST_METHOD0(getDisplayColorProfile, DisplayColorProfile*());
+ MOCK_METHOD1(setDisplayColorProfile, void(std::unique_ptr<DisplayColorProfile>));
+
MOCK_CONST_METHOD0(getRenderSurface, RenderSurface*());
MOCK_METHOD1(setRenderSurface, void(std::unique_ptr<RenderSurface>));