Merge "[SurfaceFlinger] Decouple color management from wide color display property."
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index efaeaa2..ee69b83 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -23,6 +23,7 @@
         "android.hardware.configstore-utils",
         "android.hardware.configstore@1.0",
         "android.hardware.configstore@1.1",
+        "android.hardware.configstore@1.2",
         "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.composer@2.1",
         "android.hardware.graphics.composer@2.2",
@@ -175,6 +176,7 @@
         "android.frameworks.displayservice@1.0",
         "android.hardware.configstore-utils",
         "android.hardware.configstore@1.0",
+        "android.hardware.configstore@1.2",
         "android.hardware.graphics.allocator@2.0",
         "libbinder",
         "libcutils",
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
index 2186594..136d12f 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
@@ -114,7 +114,7 @@
       : RenderEngine(featureFlags),
         mVpWidth(0),
         mVpHeight(0),
-        mPlatformHasWideColor((featureFlags & WIDE_COLOR_SUPPORT) != 0) {
+        mUseColorManagement(featureFlags & USE_COLOR_MANAGEMENT) {
     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
     glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
 
@@ -132,7 +132,7 @@
 
     // mColorBlindnessCorrection = M;
 
-    if (mPlatformHasWideColor) {
+    if (mUseColorManagement) {
         ColorSpace srgb(ColorSpace::sRGB());
         ColorSpace displayP3(ColorSpace::DisplayP3());
         ColorSpace bt2020(ColorSpace::BT2020());
@@ -322,8 +322,8 @@
     // BT2020 data space, in that case, the output data space is set to be
     // BT2020_HLG or BT2020_PQ respectively. In GPU fall back we need
     // to respect this and convert non-HDR content to HDR format.
-    if (mPlatformHasWideColor) {
-        Description wideColorState = mState;
+    if (mUseColorManagement) {
+        Description managedState = mState;
         Dataspace inputStandard = static_cast<Dataspace>(mDataSpace & Dataspace::STANDARD_MASK);
         Dataspace inputTransfer = static_cast<Dataspace>(mDataSpace & Dataspace::TRANSFER_MASK);
         Dataspace outputStandard = static_cast<Dataspace>(mOutputDataSpace &
@@ -336,26 +336,26 @@
             // The supported input color spaces are standard RGB, Display P3 and BT2020.
             switch (inputStandard) {
                 case Dataspace::STANDARD_DCI_P3:
-                    wideColorState.setInputTransformMatrix(mDisplayP3ToXyz);
+                    managedState.setInputTransformMatrix(mDisplayP3ToXyz);
                     break;
                 case Dataspace::STANDARD_BT2020:
-                    wideColorState.setInputTransformMatrix(mBt2020ToXyz);
+                    managedState.setInputTransformMatrix(mBt2020ToXyz);
                     break;
                 default:
-                    wideColorState.setInputTransformMatrix(mSrgbToXyz);
+                    managedState.setInputTransformMatrix(mSrgbToXyz);
                     break;
             }
 
             // The supported output color spaces are BT2020, Display P3 and standard RGB.
             switch (outputStandard) {
                 case Dataspace::STANDARD_BT2020:
-                    wideColorState.setOutputTransformMatrix(mXyzToBt2020);
+                    managedState.setOutputTransformMatrix(mXyzToBt2020);
                     break;
                 case Dataspace::STANDARD_DCI_P3:
-                    wideColorState.setOutputTransformMatrix(mXyzToDisplayP3);
+                    managedState.setOutputTransformMatrix(mXyzToDisplayP3);
                     break;
                 default:
-                    wideColorState.setOutputTransformMatrix(mXyzToSrgb);
+                    managedState.setOutputTransformMatrix(mXyzToSrgb);
                     break;
             }
         } else if (inputStandard != outputStandard) {
@@ -370,9 +370,9 @@
             // - sRGB
             // - Display P3
             if (outputStandard == Dataspace::STANDARD_BT709) {
-                wideColorState.setOutputTransformMatrix(mDisplayP3ToSrgb);
+                managedState.setOutputTransformMatrix(mDisplayP3ToSrgb);
             } else if (outputStandard == Dataspace::STANDARD_DCI_P3) {
-                wideColorState.setOutputTransformMatrix(mSrgbToDisplayP3);
+                managedState.setOutputTransformMatrix(mSrgbToDisplayP3);
             }
         }
 
@@ -380,44 +380,44 @@
         // - there is a color matrix that is not an identity matrix, or
         // - there is an output transform matrix that is not an identity matrix, or
         // - the input transfer function doesn't match the output transfer function.
-        if (wideColorState.hasColorMatrix() || wideColorState.hasOutputTransformMatrix() ||
+        if (managedState.hasColorMatrix() || managedState.hasOutputTransformMatrix() ||
             inputTransfer != outputTransfer) {
             switch (inputTransfer) {
                 case Dataspace::TRANSFER_ST2084:
-                    wideColorState.setInputTransferFunction(Description::TransferFunction::ST2084);
+                    managedState.setInputTransferFunction(Description::TransferFunction::ST2084);
                     break;
                 case Dataspace::TRANSFER_HLG:
-                    wideColorState.setInputTransferFunction(Description::TransferFunction::HLG);
+                    managedState.setInputTransferFunction(Description::TransferFunction::HLG);
                     break;
                 case Dataspace::TRANSFER_LINEAR:
-                    wideColorState.setInputTransferFunction(Description::TransferFunction::LINEAR);
+                    managedState.setInputTransferFunction(Description::TransferFunction::LINEAR);
                     break;
                 default:
-                    wideColorState.setInputTransferFunction(Description::TransferFunction::SRGB);
+                    managedState.setInputTransferFunction(Description::TransferFunction::SRGB);
                     break;
             }
 
             switch (outputTransfer) {
                 case Dataspace::TRANSFER_ST2084:
-                    wideColorState.setOutputTransferFunction(Description::TransferFunction::ST2084);
+                    managedState.setOutputTransferFunction(Description::TransferFunction::ST2084);
                     break;
                 case Dataspace::TRANSFER_HLG:
-                    wideColorState.setOutputTransferFunction(Description::TransferFunction::HLG);
+                    managedState.setOutputTransferFunction(Description::TransferFunction::HLG);
                     break;
                 default:
-                    wideColorState.setOutputTransferFunction(Description::TransferFunction::SRGB);
+                    managedState.setOutputTransferFunction(Description::TransferFunction::SRGB);
                     break;
             }
         }
 
-        ProgramCache::getInstance().useProgram(wideColorState);
+        ProgramCache::getInstance().useProgram(managedState);
 
         glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
 
         if (outputDebugPPMs) {
-            static uint64_t wideColorFrameCount = 0;
+            static uint64_t managedColorFrameCount = 0;
             std::ostringstream out;
-            out << "/data/texture_out" << wideColorFrameCount++;
+            out << "/data/texture_out" << managedColorFrameCount++;
             writePPM(out.str().c_str(), mVpWidth, mVpHeight);
         }
     } else {
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
index f682225..d8cb73b 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
@@ -94,8 +94,9 @@
     // Current output dataspace of the render engine
     ui::Dataspace mOutputDataSpace = ui::Dataspace::UNKNOWN;
 
-    // Currently only supporting sRGB, BT2020 and DisplayP3 color spaces
-    const bool mPlatformHasWideColor = false;
+    // Whether device supports color management, currently color management
+    // supports sRGB, DisplayP3 color spaces.
+    const bool mUseColorManagement = false;
     mat4 mSrgbToDisplayP3;
     mat4 mDisplayP3ToSrgb;
     mat3 mSrgbToXyz;
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.cpp b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
index 9dc6858..a1d0561 100644
--- a/services/surfaceflinger/RenderEngine/ProgramCache.cpp
+++ b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
@@ -82,7 +82,7 @@
 
 ProgramCache::~ProgramCache() {}
 
-void ProgramCache::primeCache(bool hasWideColor) {
+void ProgramCache::primeCache(bool useColorManagement) {
     uint32_t shaderCount = 0;
     uint32_t keyMask = Key::BLEND_MASK | Key::OPACITY_MASK | Key::ALPHA_MASK | Key::TEXTURE_MASK;
     // Prime the cache for all combinations of the above masks,
@@ -105,7 +105,7 @@
     }
 
     // Prime for sRGB->P3 conversion
-    if (hasWideColor) {
+    if (useColorManagement) {
         Key shaderKey;
         shaderKey.set(Key::BLEND_MASK | Key::TEXTURE_MASK | Key::OUTPUT_TRANSFORM_MATRIX_MASK |
                               Key::INPUT_TF_MASK | Key::OUTPUT_TF_MASK,
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.h b/services/surfaceflinger/RenderEngine/ProgramCache.h
index 983e7ba..424633e 100644
--- a/services/surfaceflinger/RenderEngine/ProgramCache.h
+++ b/services/surfaceflinger/RenderEngine/ProgramCache.h
@@ -161,7 +161,7 @@
     ~ProgramCache();
 
     // Generate shaders to populate the cache
-    void primeCache(bool hasWideColor);
+    void primeCache(bool useColorManagement);
 
     // useProgram lookup a suitable program in the cache or generates one
     // if none can be found.
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
index 39f7e30..e5dbe2f 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
@@ -596,7 +596,7 @@
 }
 
 void RenderEngine::primeCache() const {
-    ProgramCache::getInstance().primeCache(mFeatureFlags & WIDE_COLOR_SUPPORT);
+    ProgramCache::getInstance().primeCache(mFeatureFlags & USE_COLOR_MANAGEMENT);
 }
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h
index 2ed2cc7..6213784 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.h
@@ -56,7 +56,7 @@
 class RenderEngine {
 public:
     enum FeatureFlag {
-        WIDE_COLOR_SUPPORT = 1 << 0 // Platform has a wide color display
+        USE_COLOR_MANAGEMENT = 1 << 0, // Device manages color
     };
 
     virtual ~RenderEngine() = 0;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index eeb74ec..0181664 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -93,6 +93,7 @@
 
 #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
 #include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h>
+#include <android/hardware/configstore/1.2/ISurfaceFlingerConfigs.h>
 #include <android/hardware/configstore/1.1/types.h>
 #include <configstore/Utils.h>
 
@@ -176,6 +177,7 @@
 int64_t SurfaceFlinger::maxFrameBufferAcquiredBuffers;
 // TODO(courtneygo): Rename hasWideColorDisplay to clarify its actual meaning.
 bool SurfaceFlinger::hasWideColorDisplay;
+bool SurfaceFlinger::useColorManagement;
 
 
 std::string getHwcServiceName() {
@@ -302,6 +304,8 @@
 
     hasWideColorDisplay =
             getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(false);
+    useColorManagement =
+            getBool<V1_2::ISurfaceFlingerConfigs, &V1_2::ISurfaceFlingerConfigs::useColorManagement>(false);
 
     V1_1::DisplayOrientation primaryDisplayOrientation =
         getDisplayOrientation< V1_1::ISurfaceFlingerConfigs, &V1_1::ISurfaceFlingerConfigs::primaryDisplayOrientation>(
@@ -597,11 +601,10 @@
     mVsyncModulator.setEventThreads(mSFEventThread.get(), mEventThread.get());
 
     // Get a RenderEngine for the given display / config (can't fail)
+    int32_t renderEngineFeature = 0;
+    renderEngineFeature |= (useColorManagement ? RE::RenderEngine::USE_COLOR_MANAGEMENT : 0);
     getBE().mRenderEngine =
-            RE::impl::RenderEngine::create(HAL_PIXEL_FORMAT_RGBA_8888,
-                                           hasWideColorDisplay
-                                                   ? RE::RenderEngine::WIDE_COLOR_SUPPORT
-                                                   : 0);
+            RE::impl::RenderEngine::create(HAL_PIXEL_FORMAT_RGBA_8888, renderEngineFeature);
     LOG_ALWAYS_FATAL_IF(getBE().mRenderEngine == nullptr, "couldn't create RenderEngine");
 
     LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,
@@ -1556,7 +1559,7 @@
             layer->setPerFrameData(display);
         }
 
-        if (hasWideColorDisplay) {
+        if (useColorManagement) {
             ColorMode  colorMode;
             Dataspace dataSpace;
             RenderIntent renderIntent;
@@ -2214,7 +2217,7 @@
     HdrCapabilities hdrCapabilities;
     int32_t supportedPerFrameMetadata = 0;
 
-    if (hasWideColorDisplay && displayId >= 0) {
+    if (useColorManagement && displayId >= 0) {
         std::vector<ColorMode> modes = getHwComposer().getColorModes(displayId);
         for (ColorMode colorMode : modes) {
             if (isWideColorMode(colorMode)) {
@@ -4152,7 +4155,8 @@
 }
 
 void SurfaceFlinger::dumpWideColorInfo(String8& result) const {
-    result.appendFormat("hasWideColorDisplay: %d\n", hasWideColorDisplay);
+    result.appendFormat("Device has wide color display: %d\n", hasWideColorDisplay);
+    result.appendFormat("Device uses color management: %d\n", useColorManagement);
     result.appendFormat("DisplayColorSetting: %s\n",
             decodeDisplayColorSetting(mDisplayColorSetting).c_str());
 
@@ -4727,7 +4731,9 @@
                 repaintEverything();
                 return NO_ERROR;
             }
-            case 1024: { // Is wide color gamut rendering/color management supported?
+            // TODO(b/111505327): Find out whether the usage of 1024 can switch to 1030,
+            // deprecate 1024 if they can.
+            case 1024: { // Does device have wide color gamut display?
                 reply->writeBool(hasWideColorDisplay);
                 return NO_ERROR;
             }
@@ -4759,7 +4765,7 @@
                 DisplayColorSetting setting = static_cast<DisplayColorSetting>(data.readInt32());
                 switch (setting) {
                     case DisplayColorSetting::MANAGED:
-                        reply->writeBool(hasWideColorDisplay);
+                        reply->writeBool(useColorManagement);
                         break;
                     case DisplayColorSetting::UNMANAGED:
                         reply->writeBool(true);
@@ -4807,6 +4813,11 @@
                 ATRACE_INT("PeriodDivisor", divisor);
                 return NO_ERROR;
             }
+            // Is device color managed?
+            case 1030: {
+                reply->writeBool(useColorManagement);
+                return NO_ERROR;
+            }
         }
     }
     return err;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index c95356e..9ef0d59 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -283,13 +283,13 @@
     // FramebufferSurface
     static int64_t maxFrameBufferAcquiredBuffers;
 
-    // Indicate if platform supports color management on its
-    // wide-color display. This is typically found on devices
-    // with wide gamut (e.g. Display-P3) display.
-    // This also allows devices with wide-color displays that don't
-    // want to support color management to disable color management.
+    // Indicate if a device has wide color gamut display. This is typically
+    // found on devices with wide color gamut (e.g. Display-P3) display.
     static bool hasWideColorDisplay;
 
+    // Indicate if device wants color management on its display.
+    static bool useColorManagement;
+
     static char const* getServiceName() ANDROID_API {
         return "SurfaceFlinger";
     }
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index b4aec36..1f57b8e 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -137,6 +137,7 @@
 
     // Default to no wide color display support configured
     mFlinger.mutableHasWideColorDisplay() = false;
+    mFlinger.mutableUseColorManagement() = false;
     mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::UNMANAGED;
 
     // Default to using HWC virtual displays
@@ -455,6 +456,7 @@
 
     static void injectConfigChange(DisplayTransactionTest* test) {
         test->mFlinger.mutableHasWideColorDisplay() = false;
+        test->mFlinger.mutableUseColorManagement() = false;
         test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::UNMANAGED;
     }
 
@@ -473,6 +475,7 @@
     static constexpr bool WIDE_COLOR_SUPPORTED = true;
 
     static void injectConfigChange(DisplayTransactionTest* test) {
+        test->mFlinger.mutableUseColorManagement() = true;
         test->mFlinger.mutableHasWideColorDisplay() = true;
         test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::UNMANAGED;
     }
@@ -501,6 +504,7 @@
     static constexpr bool WIDE_COLOR_SUPPORTED = false;
 
     static void injectConfigChange(DisplayTransactionTest* test) {
+        test->mFlinger.mutableUseColorManagement() = true;
         test->mFlinger.mutableHasWideColorDisplay() = true;
     }
 
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 9df4264..d8e7581 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -113,6 +113,7 @@
      */
 
     auto& mutableHasWideColorDisplay() { return SurfaceFlinger::hasWideColorDisplay; }
+    auto& mutableUseColorManagement() { return SurfaceFlinger::useColorManagement; }
 
     auto& mutableDisplayTokens() { return mFlinger->mDisplayTokens; }
     auto& mutableCurrentState() { return mFlinger->mCurrentState; }