[SurfaceFlinger] Add BT2100_PQ and BT2100_HLG color mode.

When hardware composer has native HDR10/HLG support, SurfaceFlinger will always
pass the layer to hardware composer. When hardware composer doesn't have native
HDR10/HLG support, but has BT2100_PQ or BT2100_HLG color mode with render
intent, SurfaceFlinger will always set the color mode to BT2100_PQ and
BT2100_HLG respectively, and set the render intent to TONE_MAP_ENHANCE if
supported, or TONE_MAP_COLORIMETRIC. Otherwise, SurfaceFlinger will set the
color mode to Display P3 and simulate PQ/HLG in RenderEngine.

Since SurfaceFlinger now can simulate HLG support in Display P3 mode, when apps
query HDR capability from platform, we also return HLG support.

BUG: 73825729
Test: build, flash
Change-Id: I53696360f2b3d986aa9191ff42866e275ba4fd0b
Merged-In: I53696360f2b3d986aa9191ff42866e275ba4fd0b
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 00f8cc9..2b1e577 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -80,6 +80,7 @@
         bool hasWideColorGamut,
         const HdrCapabilities& hdrCapabilities,
         const int32_t supportedPerFrameMetadata,
+        const std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>>& hdrAndRenderIntents,
         int initialPowerMode)
     : lastCompositionHadVisibleLayers(false),
       mFlinger(flinger),
@@ -105,7 +106,11 @@
       mHasHdr10(false),
       mHasHLG(false),
       mHasDolbyVision(false),
-      mSupportedPerFrameMetadata(supportedPerFrameMetadata)
+      mSupportedPerFrameMetadata(supportedPerFrameMetadata),
+      mHasBT2100PQColorimetric(false),
+      mHasBT2100PQEnhance(false),
+      mHasBT2100HLGColorimetric(false),
+      mHasBT2100HLGEnhance(false)
 {
     // clang-format on
     std::vector<Hdr> types = hdrCapabilities.getSupportedHdrTypes();
@@ -145,6 +150,18 @@
     }
     mHdrCapabilities = HdrCapabilities(types, maxLuminance, maxAverageLuminance, minLuminance);
 
+    auto iter = hdrAndRenderIntents.find(ColorMode::BT2100_PQ);
+    if (iter != hdrAndRenderIntents.end()) {
+        hasToneMapping(iter->second,
+                       &mHasBT2100PQColorimetric, &mHasBT2100PQEnhance);
+    }
+
+    iter = hdrAndRenderIntents.find(ColorMode::BT2100_HLG);
+    if (iter != hdrAndRenderIntents.end()) {
+        hasToneMapping(iter->second,
+                       &mHasBT2100HLGColorimetric, &mHasBT2100HLGEnhance);
+    }
+
     // initialize the display orientation transform.
     setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
 }
@@ -529,6 +546,22 @@
     result.append(surfaceDump);
 }
 
+void DisplayDevice::hasToneMapping(const std::vector<RenderIntent>& renderIntents,
+                                   bool* outColorimetric, bool *outEnhance) {
+    for (auto intent : renderIntents) {
+        switch (intent) {
+            case RenderIntent::TONE_MAP_COLORIMETRIC:
+                *outColorimetric = true;
+                break;
+            case RenderIntent::TONE_MAP_ENHANCE:
+                *outEnhance = true;
+                break;
+            default:
+                break;
+        }
+    }
+}
+
 std::atomic<int32_t> DisplayDeviceState::nextDisplayId(1);
 
 DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type, bool isSecure)
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 1df8c49..d051e33 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -20,6 +20,7 @@
 #include "Transform.h"
 
 #include <stdlib.h>
+#include <unordered_map>
 
 #include <math/mat4.h>
 
@@ -90,6 +91,7 @@
             bool hasWideColorGamut,
             const HdrCapabilities& hdrCapabilities,
             const int32_t supportedPerFrameMetadata,
+            const std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>>& hdrAndRenderIntents,
             int initialPowerMode);
     // clang-format on
 
@@ -142,6 +144,7 @@
     status_t beginFrame(bool mustRecompose) const;
     status_t prepareFrame(HWComposer& hwc);
     bool hasWideColorGamut() const { return mHasWideColorGamut; }
+    // Whether h/w composer has native support for specific HDR type.
     bool hasHDR10Support() const { return mHasHdr10; }
     bool hasHLGSupport() const { return mHasHLG; }
     bool hasDolbyVisionSupport() const { return mHasDolbyVision; }
@@ -153,6 +156,14 @@
     // respectively if hardware composer doesn't return meaningful values.
     const HdrCapabilities& getHdrCapabilities() const { return mHdrCapabilities; }
 
+    // Whether h/w composer has BT2100_PQ color mode.
+    bool hasBT2100PQColorimetricSupport() const { return mHasBT2100PQColorimetric; }
+    bool hasBT2100PQEnhanceSupport() const { return mHasBT2100PQEnhance; }
+
+    // Whether h/w composer has BT2100_HLG color mode.
+    bool hasBT2100HLGColorimetricSupport() const { return mHasBT2100HLGColorimetric; }
+    bool hasBT2100HLGEnhanceSupport() const { return mHasBT2100HLGEnhance; }
+
     void swapBuffers(HWComposer& hwc) const;
 
     // called after h/w composer has completed its set() call
@@ -203,6 +214,9 @@
     void dump(String8& result) const;
 
 private:
+    void hasToneMapping(const std::vector<ui::RenderIntent>& renderIntents,
+                        bool* outColorimetric, bool *outEnhance);
+
     /*
      *  Constants, set during initialization
      */
@@ -274,6 +288,12 @@
     bool mHasDolbyVision;
     HdrCapabilities mHdrCapabilities;
     const int32_t mSupportedPerFrameMetadata;
+    // Whether h/w composer has BT2100_PQ and BT2100_HLG color mode with
+    // colorimetrical tone mapping or enhanced tone mapping.
+    bool mHasBT2100PQColorimetric;
+    bool mHasBT2100PQEnhance;
+    bool mHasBT2100HLGColorimetric;
+    bool mHasBT2100HLGEnhance;
 };
 
 struct DisplayDeviceState {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index be70244..588d24c 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1019,27 +1019,13 @@
 }
 
 void SurfaceFlinger::setActiveColorModeInternal(const sp<DisplayDevice>& hw,
-                                                ColorMode mode, Dataspace dataSpace) {
+                                                ColorMode mode, Dataspace dataSpace,
+                                                RenderIntent renderIntent) {
     int32_t type = hw->getDisplayType();
     ColorMode currentMode = hw->getActiveColorMode();
     Dataspace currentDataSpace = hw->getCompositionDataSpace();
     RenderIntent currentRenderIntent = hw->getActiveRenderIntent();
 
-    // Natural Mode means it's color managed and the color must be right,
-    // thus we pick RenderIntent::COLORIMETRIC as render intent.
-    // Native Mode means the display is not color managed, and whichever
-    // render intent is picked doesn't matter, thus return
-    // RenderIntent::COLORIMETRIC as default here.
-    RenderIntent renderIntent = RenderIntent::COLORIMETRIC;
-
-    // In Auto Color Mode, we want to strech to panel color space, right now
-    // only the built-in display supports it.
-    if (mDisplayColorSetting == DisplayColorSetting::ENHANCED &&
-        mBuiltinDisplaySupportsEnhance &&
-        hw->getDisplayType() == DisplayDevice::DISPLAY_PRIMARY) {
-        renderIntent = RenderIntent::ENHANCE;
-    }
-
     if (mode == currentMode && dataSpace == currentDataSpace &&
         renderIntent == currentRenderIntent) {
         return;
@@ -1089,7 +1075,8 @@
                 ALOGW("Attempt to set active color mode %s %d for virtual display",
                       decodeColorMode(mMode).c_str(), mMode);
             } else {
-                mFlinger.setActiveColorModeInternal(hw, mMode, Dataspace::UNKNOWN);
+                mFlinger.setActiveColorModeInternal(hw, mMode, Dataspace::UNKNOWN,
+                                                    RenderIntent::COLORIMETRIC);
             }
             return true;
         }
@@ -1869,38 +1856,41 @@
     }
 }
 
-// Returns a dataspace that fits all visible layers.  The returned dataspace
+// Returns a data space that fits all visible layers.  The returned data space
 // can only be one of
-//
 //  - Dataspace::SRGB (use legacy dataspace and let HWC saturate when colors are enhanced)
 //  - Dataspace::DISPLAY_P3
 //  - Dataspace::V0_SCRGB_LINEAR
-// TODO(b/73825729) Add BT2020 data space.
-ui::Dataspace SurfaceFlinger::getBestDataspace(
-        const sp<const DisplayDevice>& displayDevice) const {
-    Dataspace bestDataspace = Dataspace::SRGB;
+// The returned HDR data space is one of
+//  - Dataspace::UNKNOWN
+//  - Dataspace::BT2020_HLG
+//  - Dataspace::BT2020_PQ
+Dataspace SurfaceFlinger::getBestDataspace(
+    const sp<const DisplayDevice>& displayDevice, Dataspace* outHdrDataSpace) const {
+    Dataspace bestDataSpace = Dataspace::SRGB;
+    *outHdrDataSpace = Dataspace::UNKNOWN;
+
     for (const auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
         switch (layer->getDataSpace()) {
             case Dataspace::V0_SCRGB:
             case Dataspace::V0_SCRGB_LINEAR:
-                // return immediately
-                return Dataspace::V0_SCRGB_LINEAR;
-            case Dataspace::DISPLAY_P3:
-                bestDataspace = Dataspace::DISPLAY_P3;
+                bestDataSpace = Dataspace::V0_SCRGB_LINEAR;
                 break;
-            // Historically, HDR dataspaces are ignored by SurfaceFlinger. But
-            // since SurfaceFlinger simulates HDR support now, it should honor
-            // them unless there is also native support.
+            case Dataspace::DISPLAY_P3:
+                if (bestDataSpace == Dataspace::SRGB) {
+                    bestDataSpace = Dataspace::DISPLAY_P3;
+                }
+                break;
             case Dataspace::BT2020_PQ:
             case Dataspace::BT2020_ITU_PQ:
-                if (!displayDevice->hasHDR10Support()) {
-                    return Dataspace::V0_SCRGB_LINEAR;
-                }
+                *outHdrDataSpace = Dataspace::BT2020_PQ;
                 break;
             case Dataspace::BT2020_HLG:
             case Dataspace::BT2020_ITU_HLG:
-                if (!displayDevice->hasHLGSupport()) {
-                    return Dataspace::V0_SCRGB_LINEAR;
+                // When there's mixed PQ content and HLG content, we set the HDR
+                // data space to be BT2020_PQ and convert HLG to PQ.
+                if (*outHdrDataSpace == Dataspace::UNKNOWN) {
+                    *outHdrDataSpace = Dataspace::BT2020_HLG;
                 }
                 break;
             default:
@@ -1908,29 +1898,120 @@
         }
     }
 
-    return bestDataspace;
+    return bestDataSpace;
 }
 
 // Pick the ColorMode / Dataspace for the display device.
-// TODO(b/73825729) Add BT2020 color mode.
 void SurfaceFlinger::pickColorMode(const sp<DisplayDevice>& displayDevice,
-        ColorMode* outMode, Dataspace* outDataSpace) const {
+                                   ColorMode* outMode, Dataspace* outDataSpace,
+                                   RenderIntent* outRenderIntent) const {
     if (mDisplayColorSetting == DisplayColorSetting::UNMANAGED) {
         *outMode = ColorMode::NATIVE;
         *outDataSpace = Dataspace::UNKNOWN;
+        *outRenderIntent = RenderIntent::COLORIMETRIC;
         return;
     }
 
-    switch (getBestDataspace(displayDevice)) {
-        case Dataspace::DISPLAY_P3:
-        case Dataspace::V0_SCRGB_LINEAR:
+    Dataspace hdrDataSpace;
+    Dataspace bestDataSpace = getBestDataspace(displayDevice, &hdrDataSpace);
+
+    if (hdrDataSpace == Dataspace::BT2020_PQ) {
+        // Hardware composer can handle BT2100 ColorMode only when
+        // - colorimetrical tone mapping is supported, or
+        // - Auto mode is turned on and enhanced tone mapping is supported.
+        if (displayDevice->hasBT2100PQColorimetricSupport() ||
+            (mDisplayColorSetting == DisplayColorSetting::ENHANCED &&
+             displayDevice->hasBT2100PQEnhanceSupport())) {
+            *outMode = ColorMode::BT2100_PQ;
+            *outDataSpace = Dataspace::BT2020_PQ;
+        } else if (displayDevice->hasHDR10Support()) {
+            // Legacy HDR support.  HDR layers are treated as UNKNOWN layers.
+            hdrDataSpace = Dataspace::UNKNOWN;
+        } else {
+            // Simulate PQ through RenderEngine, pick DISPLAY_P3 color mode.
             *outMode = ColorMode::DISPLAY_P3;
             *outDataSpace = Dataspace::DISPLAY_P3;
-            break;
+        }
+    } else if (hdrDataSpace == Dataspace::BT2020_HLG) {
+        if (displayDevice->hasBT2100HLGColorimetricSupport() ||
+            (mDisplayColorSetting == DisplayColorSetting::ENHANCED &&
+             displayDevice->hasBT2100HLGEnhanceSupport())) {
+            *outMode = ColorMode::BT2100_HLG;
+            *outDataSpace = Dataspace::BT2020_HLG;
+        } else if (displayDevice->hasHLGSupport()) {
+            // Legacy HDR support.  HDR layers are treated as UNKNOWN layers.
+            hdrDataSpace = Dataspace::UNKNOWN;
+        } else {
+            // Simulate HLG through RenderEngine, pick DISPLAY_P3 color mode.
+            *outMode = ColorMode::DISPLAY_P3;
+            *outDataSpace = Dataspace::DISPLAY_P3;
+        }
+    }
+
+    // At this point, there's no HDR layer.
+    if (hdrDataSpace == Dataspace::UNKNOWN) {
+        switch (bestDataSpace) {
+            case Dataspace::DISPLAY_P3:
+            case Dataspace::V0_SCRGB_LINEAR:
+                *outMode = ColorMode::DISPLAY_P3;
+                *outDataSpace = Dataspace::DISPLAY_P3;
+                break;
+            default:
+                *outMode = ColorMode::SRGB;
+                *outDataSpace = Dataspace::SRGB;
+                break;
+        }
+    }
+    *outRenderIntent = pickRenderIntent(displayDevice, *outMode);
+}
+
+RenderIntent SurfaceFlinger::pickRenderIntent(const sp<DisplayDevice>& displayDevice,
+                                              ColorMode colorMode) const {
+    // Native Mode means the display is not color managed, and whichever
+    // render intent is picked doesn't matter, thus return
+    // RenderIntent::COLORIMETRIC as default here.
+    if (mDisplayColorSetting == DisplayColorSetting::UNMANAGED) {
+        return RenderIntent::COLORIMETRIC;
+    }
+
+    // In Auto Color Mode, we want to strech to panel color space, right now
+    // only the built-in display supports it.
+    if (mDisplayColorSetting == DisplayColorSetting::ENHANCED &&
+        mBuiltinDisplaySupportsEnhance &&
+        displayDevice->getDisplayType() == DisplayDevice::DISPLAY_PRIMARY) {
+        switch (colorMode) {
+            case ColorMode::DISPLAY_P3:
+            case ColorMode::SRGB:
+                return RenderIntent::ENHANCE;
+            // In Auto Color Mode, BT2100_PQ and BT2100_HLG will only be picked
+            // when TONE_MAP_ENHANCE or TONE_MAP_COLORIMETRIC is supported.
+            // If TONE_MAP_ENHANCE is not supported, fall back to TONE_MAP_COLORIMETRIC.
+            case ColorMode::BT2100_PQ:
+                return displayDevice->hasBT2100PQEnhanceSupport() ?
+                    RenderIntent::TONE_MAP_ENHANCE : RenderIntent::TONE_MAP_COLORIMETRIC;
+            case ColorMode::BT2100_HLG:
+                return displayDevice->hasBT2100HLGEnhanceSupport() ?
+                    RenderIntent::TONE_MAP_ENHANCE : RenderIntent::TONE_MAP_COLORIMETRIC;
+            // This statement shouldn't be reached, switch cases will always
+            // cover all possible ColorMode returned by pickColorMode.
+            default:
+                return RenderIntent::COLORIMETRIC;
+        }
+    }
+
+    // Either enhance is not supported or we are in natural mode.
+
+    // Natural Mode means it's color managed and the color must be right,
+    // thus we pick RenderIntent::COLORIMETRIC as render intent for non-HDR
+    // content and pick RenderIntent::TONE_MAP_COLORIMETRIC for HDR content.
+    switch (colorMode) {
+        // In Natural Color Mode, BT2100_PQ and BT2100_HLG will only be picked
+        // when TONE_MAP_COLORIMETRIC is supported.
+        case ColorMode::BT2100_PQ:
+        case ColorMode::BT2100_HLG:
+            return RenderIntent::TONE_MAP_COLORIMETRIC;
         default:
-            *outMode = ColorMode::SRGB;
-            *outDataSpace = Dataspace::SRGB;
-            break;
+            return RenderIntent::COLORIMETRIC;
     }
 }
 
@@ -2032,8 +2113,9 @@
         if (hasWideColorDisplay) {
             ColorMode colorMode;
             Dataspace dataSpace;
-            pickColorMode(displayDevice, &colorMode, &dataSpace);
-            setActiveColorModeInternal(displayDevice, colorMode, dataSpace);
+            RenderIntent renderIntent;
+            pickColorMode(displayDevice, &colorMode, &dataSpace, &renderIntent);
+            setActiveColorModeInternal(displayDevice, colorMode, dataSpace, renderIntent);
         }
     }
 
@@ -2242,6 +2324,8 @@
         const wp<IBinder>& display, int hwcId, const DisplayDeviceState& state,
         const sp<DisplaySurface>& dispSurface, const sp<IGraphicBufferProducer>& producer) {
     bool hasWideColorGamut = false;
+    std::unordered_map<ColorMode, std::vector<RenderIntent>> hdrAndRenderIntents;
+
     if (hasWideColorDisplay) {
         std::vector<ColorMode> modes = getHwComposer().getColorModes(hwcId);
         for (ColorMode colorMode : modes) {
@@ -2251,7 +2335,6 @@
                 case ColorMode::DCI_P3:
                     hasWideColorGamut = true;
                     break;
-                // TODO(lpy) Handle BT2020, BT2100_PQ and BT2100_HLG properly.
                 default:
                     break;
             }
@@ -2266,6 +2349,10 @@
                     }
                 }
             }
+
+            if (colorMode == ColorMode::BT2100_PQ || colorMode == ColorMode::BT2100_HLG) {
+                hdrAndRenderIntents.emplace(colorMode, renderIntents);
+            }
         }
     }
 
@@ -2305,7 +2392,7 @@
                               dispSurface, std::move(renderSurface), displayWidth, displayHeight,
                               hasWideColorGamut, hdrCapabilities,
                               getHwComposer().getSupportedPerFrameMetadata(hwcId),
-                              initialPowerMode);
+                              hdrAndRenderIntents, initialPowerMode);
 
     if (maxFrameBufferAcquiredBuffers >= 3) {
         nativeWindowSurface->preallocateBuffers();
@@ -2317,7 +2404,8 @@
         defaultColorMode = ColorMode::SRGB;
         defaultDataSpace = Dataspace::V0_SRGB;
     }
-    setActiveColorModeInternal(hw, defaultColorMode, defaultDataSpace);
+    setActiveColorModeInternal(hw, defaultColorMode, defaultDataSpace,
+                               RenderIntent::COLORIMETRIC);
     hw->setLayerStack(state.layerStack);
     hw->setProjection(state.orientation, state.viewport, state.frame);
     hw->setDisplayName(state.displayName);
@@ -2999,6 +3087,8 @@
                     // switch color matrices lazily
                     if (layer->isLegacyDataSpace()) {
                         if (applyLegacyColorMatrix && currentColorMatrix != &legacyColorMatrix) {
+                            // TODO(b/78891890) Legacy sRGB saturation matrix should be set
+                            // separately.
                             getRenderEngine().setupColorTransform(legacyColorMatrix);
                             currentColorMatrix = &legacyColorMatrix;
                         }
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 54cf63c..d9cf946 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -481,7 +481,8 @@
     // Called on the main thread in response to setActiveColorMode()
     void setActiveColorModeInternal(const sp<DisplayDevice>& hw,
                                     ui::ColorMode colorMode,
-                                    ui::Dataspace dataSpace);
+                                    ui::Dataspace dataSpace,
+                                    ui::RenderIntent renderIntent);
 
     // Returns whether the transaction actually modified any state
     bool handleMessageTransaction();
@@ -653,12 +654,18 @@
             nsecs_t compositeToPresentLatency);
     void rebuildLayerStacks();
 
-    // Given a dataSpace, returns the appropriate color_mode to use
-    // to display that dataSpace.
-    ui::Dataspace getBestDataspace(const sp<const DisplayDevice>& displayDevice) const;
+    ui::Dataspace getBestDataspace(const sp<const DisplayDevice>& displayDevice,
+                                   ui::Dataspace* outHdrDataSpace) const;
+
+    // Returns the appropriate ColorMode, Dataspace and RenderIntent for the
+    // DisplayDevice. The function only returns the supported ColorMode,
+    // Dataspace and RenderIntent.
     void pickColorMode(const sp<DisplayDevice>& displayDevice,
                        ui::ColorMode* outMode,
-                       ui::Dataspace* outDataSpace) const;
+                       ui::Dataspace* outDataSpace,
+                       ui::RenderIntent* outRenderIntent) const;
+    ui::RenderIntent pickRenderIntent(const sp<DisplayDevice>& displayDevice,
+                                      ui::ColorMode colorMode) const;
 
     void setUpHWComposer();
     void doComposition();
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index bb6ca39..08da1a2 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -47,10 +47,10 @@
 
 using android::hardware::graphics::common::V1_0::Hdr;
 using android::hardware::graphics::common::V1_1::ColorMode;
+using android::hardware::graphics::common::V1_1::RenderIntent;
 using android::Hwc2::Error;
 using android::Hwc2::IComposer;
 using android::Hwc2::IComposerClient;
-using android::Hwc2::RenderIntent;
 
 using FakeDisplayDeviceInjector = TestableSurfaceFlinger::FakeDisplayDeviceInjector;
 using FakeHwcDisplayInjector = TestableSurfaceFlinger::FakeHwcDisplayInjector;
@@ -494,33 +494,6 @@
     }
 };
 
-// For this variant, SurfaceFlinger should configure itself with wide color
-// display support, and the display should respond with an non-empty list of
-// supported color modes.
-template <typename Display>
-struct WideColorP3EnhanceSupportedVariant {
-    static constexpr bool WIDE_COLOR_SUPPORTED = true;
-
-    static void injectConfigChange(DisplayTransactionTest* test) {
-        test->mFlinger.mutableHasWideColorDisplay() = true;
-        test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::ENHANCED;
-    }
-
-    static void setupComposerCallExpectations(DisplayTransactionTest* test) {
-        EXPECT_CALL(*test->mComposer, getColorModes(Display::HWC_DISPLAY_ID, _))
-                .WillOnce(DoAll(SetArgPointee<1>(std::vector<ColorMode>({ColorMode::DISPLAY_P3})),
-                                Return(Error::NONE)));
-        EXPECT_CALL(*test->mComposer,
-                    getRenderIntents(Display::HWC_DISPLAY_ID, ColorMode::DISPLAY_P3, _))
-                .WillOnce(
-                        DoAll(SetArgPointee<2>(std::vector<RenderIntent>({RenderIntent::ENHANCE})),
-                              Return(Error::NONE)));
-        EXPECT_CALL(*test->mComposer,
-                    setColorMode(Display::HWC_DISPLAY_ID, ColorMode::SRGB, RenderIntent::ENHANCE))
-                .WillOnce(Return(Error::NONE));
-    }
-};
-
 // For this variant, SurfaceFlinger should configure itself with wide display
 // support, but the display should respond with an empty list of supported color
 // modes. Wide-color support for the display should not be configured.
@@ -638,9 +611,6 @@
 using WideColorP3ColorimetricDisplayCase =
         Case<PrimaryDisplayVariant, WideColorP3ColorimetricSupportedVariant<PrimaryDisplayVariant>,
              HdrNotSupportedVariant<PrimaryDisplayVariant>>;
-using WideColorP3EnhanceDisplayCase =
-        Case<PrimaryDisplayVariant, WideColorP3EnhanceSupportedVariant<PrimaryDisplayVariant>,
-             HdrNotSupportedVariant<PrimaryDisplayVariant>>;
 using Hdr10DisplayCase =
         Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
              Hdr10SupportedVariant<PrimaryDisplayVariant>>;
@@ -1043,10 +1013,6 @@
     setupNewDisplayDeviceInternalTest<WideColorP3ColorimetricDisplayCase>();
 }
 
-TEST_F(SetupNewDisplayDeviceInternalTest, createWideColorP3EnhanceDisplay) {
-    setupNewDisplayDeviceInternalTest<WideColorP3EnhanceDisplayCase>();
-}
-
 TEST_F(SetupNewDisplayDeviceInternalTest, createHdr10Display) {
     setupNewDisplayDeviceInternalTest<Hdr10DisplayCase>();
 }
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index f689537..a4e7361 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -289,10 +289,12 @@
         }
 
         sp<DisplayDevice> inject() {
+            std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>> hdrAndRenderIntents;
             sp<DisplayDevice> device =
                     new DisplayDevice(mFlinger.mFlinger.get(), mType, mHwcId, mSecure, mDisplayToken,
                                       mNativeWindow, mDisplaySurface, std::move(mRenderSurface), 0,
-                                      0, false, HdrCapabilities(), 0, HWC_POWER_MODE_NORMAL);
+                                      0, false, HdrCapabilities(), 0, hdrAndRenderIntents,
+                                      HWC_POWER_MODE_NORMAL);
             mFlinger.mutableDisplays().add(mDisplayToken, device);
 
             DisplayDeviceState state(mType, mSecure);