Switch to version 2 of ComposeDevice

Note backward compatibility is maintained on emu host side while previous
version 1 will be handled correctly. This CL makes it ready for
upcoming CLs that support physical display emulation.

The key is to pass the displayId to host side to support multi-display.

Test: manually
Change-Id: Ia8e9b8953ff949e67c5f6214cde2635b2e5b82e1
diff --git a/system/OpenglSystemCommon/EmulatorFeatureInfo.h b/system/OpenglSystemCommon/EmulatorFeatureInfo.h
index 95b3e60..422812c 100644
--- a/system/OpenglSystemCommon/EmulatorFeatureInfo.h
+++ b/system/OpenglSystemCommon/EmulatorFeatureInfo.h
@@ -60,9 +60,11 @@
 enum HostComposition {
     HOST_COMPOSITION_NONE = 0,
     HOST_COMPOSITION_V1,
+    HOST_COMPOSITION_V2,
 };
 
 static const char kHostCompositionV1[] = "ANDROID_EMU_host_composition_v1";
+static const char kHostCompositionV2[] = "ANDROID_EMU_host_composition_v2";
 
 // No querying errors from host extension
 static const char kGLESNoHostError[] = "ANDROID_EMU_gles_no_host_error";
diff --git a/system/OpenglSystemCommon/HostConnection.cpp b/system/OpenglSystemCommon/HostConnection.cpp
index be6a84e..0165ae6 100644
--- a/system/OpenglSystemCommon/HostConnection.cpp
+++ b/system/OpenglSystemCommon/HostConnection.cpp
@@ -358,7 +358,11 @@
 void HostConnection::queryAndSetHostCompositionImpl(ExtendedRCEncoderContext *rcEnc) {
     const std::string& glExtensions = queryGLExtensions(rcEnc);
     ALOGD("HostComposition ext %s", glExtensions.c_str());
-    if (glExtensions.find(kHostCompositionV1) != std::string::npos) {
+    // make sure V2 is checked first before V1, as host may declare supporting both
+    if (glExtensions.find(kHostCompositionV2) != std::string::npos) {
+        rcEnc->setHostComposition(HOST_COMPOSITION_V2);
+    }
+    else if (glExtensions.find(kHostCompositionV1) != std::string::npos) {
         rcEnc->setHostComposition(HOST_COMPOSITION_V1);
     }
     else {
diff --git a/system/OpenglSystemCommon/HostConnection.h b/system/OpenglSystemCommon/HostConnection.h
index 22b36b0..df111fd 100644
--- a/system/OpenglSystemCommon/HostConnection.h
+++ b/system/OpenglSystemCommon/HostConnection.h
@@ -57,6 +57,8 @@
     bool hasNativeSyncV3() const { return m_featureInfo.syncImpl >= SYNC_IMPL_NATIVE_SYNC_V3; }
     bool hasHostCompositionV1() const {
         return m_featureInfo.hostComposition == HOST_COMPOSITION_V1; }
+    bool hasHostCompositionV2() const {
+        return m_featureInfo.hostComposition == HOST_COMPOSITION_V2; }
     bool hasYUV420toNV21() const {
         return m_featureInfo.hasYUV420888toNV21; }
     bool hasYUVCache() const {
diff --git a/system/hwc2/EmuHWC2.cpp b/system/hwc2/EmuHWC2.cpp
index 00b7a21..8925a00 100644
--- a/system/hwc2/EmuHWC2.cpp
+++ b/system/hwc2/EmuHWC2.cpp
@@ -696,9 +696,15 @@
     DEFINE_AND_VALIDATE_HOST_CONNECTION
     hostCon->lock();
     bool hostCompositionV1 = rcEnc->hasHostCompositionV1();
+    bool hostCompositionV2 = rcEnc->hasHostCompositionV2();
     hostCon->unlock();
 
-    if (hostCompositionV1) {
+    // if we supports v2, then discard v1
+    if (hostCompositionV2) {
+        hostCompositionV1 = false;
+    }
+
+    if (hostCompositionV2 || hostCompositionV1) {
         uint32_t numLayer = 0;
         for (auto layer: mLayers) {
             if (layer->getCompositionType() == Composition::Device ||
@@ -720,13 +726,28 @@
             return Error::None;
         }
 
-        if (mComposeMsg == nullptr || mComposeMsg->getLayerCnt() < numLayer) {
-            mComposeMsg.reset(new ComposeMsg(numLayer));
+        if (hostCompositionV1) {
+            if (mComposeMsg == nullptr || mComposeMsg->getLayerCnt() < numLayer) {
+                mComposeMsg.reset(new ComposeMsg(numLayer));
+            }
+        } else {
+            if (mComposeMsg_v2 == nullptr || mComposeMsg_v2->getLayerCnt() < numLayer) {
+                mComposeMsg_v2.reset(new ComposeMsg_v2(numLayer));
+            }
         }
 
         // Handle the composition
-        ComposeDevice* p = mComposeMsg->get();
-        ComposeLayer* l = p->layer;
+        ComposeDevice* p;
+        ComposeDevice_v2* p2;
+        ComposeLayer* l;
+
+        if (hostCompositionV1) {
+            p = mComposeMsg->get();
+            l = p->layer;
+        } else {
+            p2 = mComposeMsg_v2->get();
+            l = p2->layer;
+        }
 
         for (auto layer: mLayers) {
             if (layer->getCompositionType() != Composition::Device &&
@@ -781,14 +802,28 @@
                   layer->getZ(), l->composeMode, l->transform);
             l++;
         }
-        p->version = 1;
-        p->targetHandle = mGralloc->getTargetCb();
-        p->numLayers = numLayer;
+        if (hostCompositionV1) {
+            p->version = 1;
+            p->targetHandle = mGralloc->getTargetCb();
+            p->numLayers = numLayer;
+        } else {
+            p2->version = 2;
+            p2->displayId = (uint32_t)mId;
+            p2->targetHandle = mGralloc->getTargetCb();
+            p2->numLayers = numLayer;
+        }
 
         hostCon->lock();
-        rcEnc->rcCompose(rcEnc,
-                         sizeof(ComposeDevice) + numLayer * sizeof(ComposeLayer),
-                         (void *)p);
+        if (hostCompositionV1) {
+            rcEnc->rcCompose(rcEnc,
+                             sizeof(ComposeDevice) + numLayer * sizeof(ComposeLayer),
+                             (void *)p);
+        } else {
+            rcEnc->rcCompose(rcEnc,
+                             sizeof(ComposeDevice_v2) + numLayer * sizeof(ComposeLayer),
+                             (void *)p2);
+        }
+
         hostCon->unlock();
 
         // Send a retire fence and use it as the release fence for all layers,
diff --git a/system/hwc2/EmuHWC2.h b/system/hwc2/EmuHWC2.h
index a10f5c4..899d734 100644
--- a/system/hwc2/EmuHWC2.h
+++ b/system/hwc2/EmuHWC2.h
@@ -191,6 +191,25 @@
         ComposeDevice* mComposeDevice;
     };
 
+    class ComposeMsg_v2 {
+    public:
+        ComposeMsg_v2(uint32_t layerCnt = 0) :
+          mData(sizeof(ComposeDevice_v2) + layerCnt * sizeof(ComposeLayer))
+        {
+            mComposeDevice = reinterpret_cast<ComposeDevice_v2*>(mData.data());
+            mLayerCnt = layerCnt;
+        }
+
+        ComposeDevice_v2* get() { return mComposeDevice; }
+
+        uint32_t getLayerCnt() { return mLayerCnt; }
+
+    private:
+        std::vector<uint8_t> mData;
+        uint32_t mLayerCnt;
+        ComposeDevice_v2* mComposeDevice;
+    };
+
     class Display {
     public:
         Display(EmuHWC2& device, HWC2::DisplayType type);
@@ -348,6 +367,7 @@
         mutable std::mutex mStateMutex;
         std::unique_ptr<GrallocModule> mGralloc;
         std::unique_ptr<ComposeMsg> mComposeMsg;
+        std::unique_ptr<ComposeMsg_v2> mComposeMsg_v2;
         int mSyncDeviceFd;
 
    };