Merge "[SurfaceFlinger] Expose WCG composition preference through ISurfaceComposer API."
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index cc0a307..e66c0e5 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -565,8 +565,10 @@
         return reply.readParcelableVector(outLayers);
     }
 
-    virtual status_t getCompositionPreference(ui::Dataspace* dataSpace,
-                                              ui::PixelFormat* pixelFormat) const {
+    virtual status_t getCompositionPreference(ui::Dataspace* defaultDataspace,
+                                              ui::PixelFormat* defaultPixelFormat,
+                                              ui::Dataspace* wideColorGamutDataspace,
+                                              ui::PixelFormat* wideColorGamutPixelFormat) const {
         Parcel data, reply;
         status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (error != NO_ERROR) {
@@ -578,8 +580,10 @@
         }
         error = static_cast<status_t>(reply.readInt32());
         if (error == NO_ERROR) {
-            *dataSpace = static_cast<ui::Dataspace>(reply.readInt32());
-            *pixelFormat = static_cast<ui::PixelFormat>(reply.readInt32());
+            *defaultDataspace = static_cast<ui::Dataspace>(reply.readInt32());
+            *defaultPixelFormat = static_cast<ui::PixelFormat>(reply.readInt32());
+            *wideColorGamutDataspace = static_cast<ui::Dataspace>(reply.readInt32());
+            *wideColorGamutPixelFormat = static_cast<ui::PixelFormat>(reply.readInt32());
         }
         return error;
     }
@@ -925,13 +929,19 @@
         }
         case GET_COMPOSITION_PREFERENCE: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
-            ui::Dataspace dataSpace;
-            ui::PixelFormat pixelFormat;
-            status_t error = getCompositionPreference(&dataSpace, &pixelFormat);
+            ui::Dataspace defaultDataspace;
+            ui::PixelFormat defaultPixelFormat;
+            ui::Dataspace wideColorGamutDataspace;
+            ui::PixelFormat wideColorGamutPixelFormat;
+            status_t error =
+                    getCompositionPreference(&defaultDataspace, &defaultPixelFormat,
+                                             &wideColorGamutDataspace, &wideColorGamutPixelFormat);
             reply->writeInt32(error);
             if (error == NO_ERROR) {
-                reply->writeInt32(static_cast<int32_t>(dataSpace));
-                reply->writeInt32(static_cast<int32_t>(pixelFormat));
+                reply->writeInt32(static_cast<int32_t>(defaultDataspace));
+                reply->writeInt32(static_cast<int32_t>(defaultPixelFormat));
+                reply->writeInt32(static_cast<int32_t>(wideColorGamutDataspace));
+                reply->writeInt32(static_cast<int32_t>(wideColorGamutDataspace));
             }
             return NO_ERROR;
         }
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 7498f36..e5a2454 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -866,9 +866,12 @@
     ComposerService::getComposerService()->setPowerMode(token, mode);
 }
 
-status_t SurfaceComposerClient::getCompositionPreference(ui::Dataspace* dataSpace,
-                                                         ui::PixelFormat* pixelFormat) {
-    return ComposerService::getComposerService()->getCompositionPreference(dataSpace, pixelFormat);
+status_t SurfaceComposerClient::getCompositionPreference(
+        ui::Dataspace* defaultDataspace, ui::PixelFormat* defaultPixelFormat,
+        ui::Dataspace* wideColorGamutDataspace, ui::PixelFormat* wideColorGamutPixelFormat) {
+    return ComposerService::getComposerService()
+            ->getCompositionPreference(defaultDataspace, defaultPixelFormat,
+                                       wideColorGamutDataspace, wideColorGamutPixelFormat);
 }
 
 status_t SurfaceComposerClient::clearAnimationFrameStats() {
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 35cb3be..9316ae6 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -280,10 +280,19 @@
      */
     virtual status_t getLayerDebugInfo(std::vector<LayerDebugInfo>* outLayers) const = 0;
 
-    virtual status_t getCompositionPreference(ui::Dataspace* dataSpace,
-                                              ui::PixelFormat* pixelFormat) const = 0;
-
     virtual bool isColorManagementUsed() const = 0;
+
+    /* Gets the composition preference of the default data space and default pixel format,
+     * as well as the wide color gamut data space and wide color gamut pixel format.
+     * If the wide color gamut data space is V0_SRGB, then it implies that the platform
+     * has no wide color gamut support.
+     *
+     * Requires the ACCESS_SURFACE_FLINGER permission.
+     */
+    virtual status_t getCompositionPreference(ui::Dataspace* defaultDataspace,
+                                              ui::PixelFormat* defaultPixelFormat,
+                                              ui::Dataspace* wideColorGamutDataspace,
+                                              ui::PixelFormat* wideColorGamutPixelFormat) const = 0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 1b4eda7..8ccee05 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -101,9 +101,15 @@
     /* Triggers screen on/off or low power mode and waits for it to complete */
     static void setDisplayPowerMode(const sp<IBinder>& display, int mode);
 
-    //
-    static status_t getCompositionPreference(ui::Dataspace* dataSpace,
-                                             ui::PixelFormat* pixelFormat);
+    /* Returns the composition preference of the default data space and default pixel format,
+     * as well as the wide color gamut data space and wide color gamut pixel format.
+     * If the wide color gamut data space is V0_SRGB, then it implies that the platform
+     * has no wide color gamut support.
+     */
+    static status_t getCompositionPreference(ui::Dataspace* defaultDataspace,
+                                             ui::PixelFormat* defaultPixelFormat,
+                                             ui::Dataspace* wideColorGamutDataspace,
+                                             ui::PixelFormat* wideColorGamutPixelFormat);
 
     // ------------------------------------------------------------------------
     // surface creation / destruction
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 25f762b..a3e9249 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -628,8 +628,10 @@
     status_t getLayerDebugInfo(std::vector<LayerDebugInfo>* /*layers*/) const override {
         return NO_ERROR;
     }
-    status_t getCompositionPreference(ui::Dataspace* /*outDataSpace*/,
-                                      ui::PixelFormat* /*outPixelFormat*/) const override {
+    status_t getCompositionPreference(
+            ui::Dataspace* /*outDefaultDataspace*/, ui::PixelFormat* /*outDefaultPixelFormat*/,
+            ui::Dataspace* /*outWideColorGamutDataspace*/,
+            ui::PixelFormat* /*outWideColorGamutPixelFormat*/) const override {
         return NO_ERROR;
     }
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index fc8ca54..5c31ada 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -196,8 +196,10 @@
 int SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientationDefault;
 bool SurfaceFlinger::useColorManagement;
 bool SurfaceFlinger::useContextPriority;
-Dataspace SurfaceFlinger::compositionDataSpace = Dataspace::V0_SRGB;
-ui::PixelFormat SurfaceFlinger::compositionPixelFormat = ui::PixelFormat::RGBA_8888;
+Dataspace SurfaceFlinger::defaultCompositionDataspace = Dataspace::V0_SRGB;
+ui::PixelFormat SurfaceFlinger::defaultCompositionPixelFormat = ui::PixelFormat::RGBA_8888;
+Dataspace SurfaceFlinger::wideColorGamutCompositionDataspace = Dataspace::V0_SRGB;
+ui::PixelFormat SurfaceFlinger::wideColorGamutCompositionPixelFormat = ui::PixelFormat::RGBA_8888;
 
 std::string getHwcServiceName() {
     char value[PROPERTY_VALUE_MAX] = {};
@@ -303,10 +305,13 @@
     auto surfaceFlingerConfigsServiceV1_2 = V1_2::ISurfaceFlingerConfigs::getService();
     if (surfaceFlingerConfigsServiceV1_2) {
         surfaceFlingerConfigsServiceV1_2->getCompositionPreference(
-            [&](Dataspace tmpDataSpace, ui::PixelFormat tmpPixelFormat) {
-                compositionDataSpace = tmpDataSpace;
-                compositionPixelFormat = tmpPixelFormat;
-            });
+                [&](auto tmpDefaultDataspace, auto tmpDefaultPixelFormat,
+                    auto tmpWideColorGamutDataspace, auto tmpWideColorGamutPixelFormat) {
+                    defaultCompositionDataspace = tmpDefaultDataspace;
+                    defaultCompositionPixelFormat = tmpDefaultPixelFormat;
+                    wideColorGamutCompositionDataspace = tmpWideColorGamutDataspace;
+                    wideColorGamutCompositionPixelFormat = tmpWideColorGamutPixelFormat;
+                });
     }
 
     useContextPriority = getBool<ISurfaceFlingerConfigs,
@@ -638,8 +643,8 @@
 
     // TODO(b/77156734): We need to stop casting and use HAL types when possible.
     getBE().mRenderEngine =
-        renderengine::RenderEngine::create(static_cast<int32_t>(compositionPixelFormat),
-                                           renderEngineFeature);
+            renderengine::RenderEngine::create(static_cast<int32_t>(defaultCompositionPixelFormat),
+                                               renderEngineFeature);
     LOG_ALWAYS_FATAL_IF(getBE().mRenderEngine == nullptr, "couldn't create RenderEngine");
 
     LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,
@@ -1157,10 +1162,14 @@
     return NO_ERROR;
 }
 
-status_t SurfaceFlinger::getCompositionPreference(Dataspace* outDataSpace,
-                                                  ui::PixelFormat* outPixelFormat) const {
-    *outDataSpace = compositionDataSpace;
-    *outPixelFormat = compositionPixelFormat;
+status_t SurfaceFlinger::getCompositionPreference(
+        Dataspace* outDataspace, ui::PixelFormat* outPixelFormat,
+        Dataspace* outWideColorGamutDataspace,
+        ui::PixelFormat* outWideColorGamutPixelFormat) const {
+    *outDataspace = defaultCompositionDataspace;
+    *outPixelFormat = defaultCompositionPixelFormat;
+    *outWideColorGamutDataspace = wideColorGamutCompositionDataspace;
+    *outWideColorGamutPixelFormat = wideColorGamutCompositionPixelFormat;
     return NO_ERROR;
 }
 
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 73c9d95..d60765c 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -294,8 +294,14 @@
     // The data space and pixel format that SurfaceFlinger expects hardware composer
     // to composite efficiently. Meaning under most scenarios, hardware composer
     // will accept layers with the data space and pixel format.
-    static ui::Dataspace compositionDataSpace;
-    static ui::PixelFormat compositionPixelFormat;
+    static ui::Dataspace defaultCompositionDataspace;
+    static ui::PixelFormat defaultCompositionPixelFormat;
+
+    // The data space and pixel format that SurfaceFlinger expects hardware composer
+    // to composite efficiently for wide color gamut surfaces. Meaning under most scenarios,
+    // hardware composer will accept layers with the data space and pixel format.
+    static ui::Dataspace wideColorGamutCompositionDataspace;
+    static ui::PixelFormat wideColorGamutCompositionPixelFormat;
 
     static char const* getServiceName() ANDROID_API {
         return "SurfaceFlinger";
@@ -460,9 +466,10 @@
     virtual status_t enableVSyncInjections(bool enable);
     virtual status_t injectVSync(nsecs_t when);
     virtual status_t getLayerDebugInfo(std::vector<LayerDebugInfo>* outLayers) const;
-    status_t getCompositionPreference(ui::Dataspace* outDataSpace,
-                                      ui::PixelFormat* outPixelFormat) const override;
     virtual bool isColorManagementUsed() const;
+    status_t getCompositionPreference(ui::Dataspace* outDataspace, ui::PixelFormat* outPixelFormat,
+                                      ui::Dataspace* outWideColorGamutDataspace,
+                                      ui::PixelFormat* outWideColorGamutPixelFormat) const override;
 
     /* ------------------------------------------------------------------------
      * DeathRecipient interface