Merge "[SurfaceFlinger] Add getCompositionPreference APIs to SurfaceComposer."
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 7f9668f..08fbfff 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -558,6 +558,25 @@
         outLayers->clear();
         return reply.readParcelableVector(outLayers);
     }
+
+    virtual status_t getCompositionPreference(ui::Dataspace* dataSpace,
+                                              ui::PixelFormat* pixelFormat) const {
+        Parcel data, reply;
+        status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        if (error != NO_ERROR) {
+            return error;
+        }
+        error = remote()->transact(BnSurfaceComposer::GET_COMPOSITION_PREFERENCE, data, &reply);
+        if (error != NO_ERROR) {
+            return error;
+        }
+        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());
+        }
+        return error;
+    }
 };
 
 // Out-of-line virtual method definition to trigger vtable emission in this
@@ -881,6 +900,18 @@
             }
             return result;
         }
+        case GET_COMPOSITION_PREFERENCE: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+            ui::Dataspace dataSpace;
+            ui::PixelFormat pixelFormat;
+            status_t error = getCompositionPreference(&dataSpace, &pixelFormat);
+            reply->writeInt32(error);
+            if (error == NO_ERROR) {
+                reply->writeInt32(static_cast<int32_t>(dataSpace));
+                reply->writeInt32(static_cast<int32_t>(pixelFormat));
+            }
+            return NO_ERROR;
+        }
         default: {
             return BBinder::onTransact(code, data, reply, flags);
         }
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 7168de4..4caadd1 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -854,6 +854,11 @@
     ComposerService::getComposerService()->setPowerMode(token, mode);
 }
 
+status_t SurfaceComposerClient::getCompositionPreference(ui::Dataspace* dataSpace,
+                                                         ui::PixelFormat* pixelFormat) {
+    return ComposerService::getComposerService()->getCompositionPreference(dataSpace, pixelFormat);
+}
+
 status_t SurfaceComposerClient::clearAnimationFrameStats() {
     return ComposerService::getComposerService()->clearAnimationFrameStats();
 }
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 8df2f03..46103c4 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -231,6 +231,9 @@
      * Requires the ACCESS_SURFACE_FLINGER permission.
      */
     virtual status_t getLayerDebugInfo(std::vector<LayerDebugInfo>* outLayers) const = 0;
+
+    virtual status_t getCompositionPreference(ui::Dataspace* dataSpace,
+                                              ui::PixelFormat* pixelFormat) const = 0;
 };
 
 // ----------------------------------------------------------------------------
@@ -267,7 +270,8 @@
         ENABLE_VSYNC_INJECTIONS,
         INJECT_VSYNC,
         GET_LAYER_DEBUG_INFO,
-        CREATE_SCOPED_CONNECTION
+        CREATE_SCOPED_CONNECTION,
+        GET_COMPOSITION_PREFERENCE,
     };
 
     virtual status_t onTransact(uint32_t code, const Parcel& data,
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index d83ba84..662acc9 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -101,6 +101,10 @@
     /* 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);
+
     // ------------------------------------------------------------------------
     // surface creation / destruction
 
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 3542aba..243f27f 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -622,6 +622,10 @@
     status_t getLayerDebugInfo(std::vector<LayerDebugInfo>* /*layers*/) const override {
         return NO_ERROR;
     }
+    status_t getCompositionPreference(ui::Dataspace* /*outDataSpace*/,
+                                      ui::PixelFormat* /*outPixelFormat*/) const override {
+        return NO_ERROR;
+    }
 
 protected:
     IBinder* onAsBinder() override { return nullptr; }
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index d008f26..a5bd73a 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -197,6 +197,8 @@
 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;
 
 std::string getHwcServiceName() {
     char value[PROPERTY_VALUE_MAX] = {};
@@ -323,13 +325,24 @@
     hasWideColorDisplay =
             getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(false);
     useColorManagement =
-            getBool<V1_2::ISurfaceFlingerConfigs, &V1_2::ISurfaceFlingerConfigs::useColorManagement>(false);
+            getBool<V1_2::ISurfaceFlingerConfigs,
+                    &V1_2::ISurfaceFlingerConfigs::useColorManagement>(false);
+
+    auto surfaceFlingerConfigsServiceV1_2 = V1_2::ISurfaceFlingerConfigs::getService();
+    if (surfaceFlingerConfigsServiceV1_2) {
+        surfaceFlingerConfigsServiceV1_2->getCompositionPreference(
+            [&](Dataspace tmpDataSpace, ui::PixelFormat tmpPixelFormat) {
+                compositionDataSpace = tmpDataSpace;
+                compositionPixelFormat = tmpPixelFormat;
+            });
+    }
 
     useContextPriority = getBool<ISurfaceFlingerConfigs,
                                  &ISurfaceFlingerConfigs::useContextPriority>(true);
 
     V1_1::DisplayOrientation primaryDisplayOrientation =
-        getDisplayOrientation< V1_1::ISurfaceFlingerConfigs, &V1_1::ISurfaceFlingerConfigs::primaryDisplayOrientation>(
+        getDisplayOrientation<V1_1::ISurfaceFlingerConfigs,
+                              &V1_1::ISurfaceFlingerConfigs::primaryDisplayOrientation>(
             V1_1::DisplayOrientation::ORIENTATION_0);
 
     switch (primaryDisplayOrientation) {
@@ -651,8 +664,11 @@
                             renderengine::RenderEngine::USE_COLOR_MANAGEMENT : 0);
     renderEngineFeature |= (useContextPriority ?
                             renderengine::RenderEngine::USE_HIGH_PRIORITY_CONTEXT : 0);
-    getBE().mRenderEngine = renderengine::impl::RenderEngine::create(HAL_PIXEL_FORMAT_RGBA_8888,
-                                                                     renderEngineFeature);
+
+    // TODO(b/77156734): We need to stop casting and use HAL types when possible.
+    getBE().mRenderEngine =
+        renderengine::impl::RenderEngine::create(static_cast<int32_t>(compositionPixelFormat),
+                                                 renderEngineFeature);
     LOG_ALWAYS_FATAL_IF(getBE().mRenderEngine == nullptr, "couldn't create RenderEngine");
 
     LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,
@@ -1170,6 +1186,13 @@
     return NO_ERROR;
 }
 
+status_t SurfaceFlinger::getCompositionPreference(Dataspace* outDataSpace,
+                                                  ui::PixelFormat* outPixelFormat) const {
+    *outDataSpace = compositionDataSpace;
+    *outPixelFormat = compositionPixelFormat;
+    return NO_ERROR;
+}
+
 // ----------------------------------------------------------------------------
 
 sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection(
@@ -4824,7 +4847,8 @@
         // granted a reference to Client* and Handle* to do anything with it.
         case SET_TRANSACTION_STATE:
         // Creating a scoped connection is safe, as per discussion in ISurfaceComposer.h
-        case CREATE_SCOPED_CONNECTION: {
+        case CREATE_SCOPED_CONNECTION:
+        case GET_COMPOSITION_PREFERENCE: {
             return OK;
         }
         case CAPTURE_LAYERS:
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index b20fe44..72ede93 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -296,6 +296,12 @@
 
     static bool useContextPriority;
 
+    // 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 char const* getServiceName() ANDROID_API {
         return "SurfaceFlinger";
     }
@@ -454,6 +460,8 @@
     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;
 
 
     /* ------------------------------------------------------------------------