sf: Determine if virtual display can use HWC for composition

For HWC virtual display using V4L2 approach:
1. HWC virtual display implementation doesn't send output buffer
   back to Surface Flinger.
2. For non-wfd virtual displays(e.g. Simulated Secondary Displays,
   Screen Record, CTS etc..), configure VDS to use GPU for
   composition on output/sink buffer.
3. For wfd virtual display (a.k.a hybrid wfd), use
   Framebuffer surface (similar to external display mechanism).

For HWC virtual display using VDS approach:
1. HWC is allocated for first virtual display connection.
2. Subsequent virtual display sessions will be composed by GLES driver.
ToDo: Modify VDS component to allocate hwcDisplayId based on
mForceHwcCopy (which is based on Usage Flags)

Change-Id: Ib7d2c00ca5fa07908b2eac8085654f8d2cd9af0b
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e0558ab..bd64601 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1235,6 +1235,78 @@
     mHwc->setVirtualDisplayProperties(hwcDisplayId, w, h, format);
 }
 
+void SurfaceFlinger::configureVirtualDisplay(int32_t &hwcDisplayId,
+                                        sp<DisplaySurface> &dispSurface,
+                                        sp<IGraphicBufferProducer> &producer,
+                                        const DisplayDeviceState state,
+                                        sp<IGraphicBufferProducer> bqProducer,
+                                        sp<IGraphicBufferConsumer> bqConsumer)
+{
+    bool vdsEnabled = mHwc->isVDSEnabled();
+
+    //for V4L2 based virtual display implementation
+    if(!vdsEnabled) {
+        // persist.sys.wfd.virtual will be set if WFD is launched via
+        // settings app. This is currently being done in
+        // ExtendedRemoteDisplay-WFD stack.
+        // This flag will be reset at the time of disconnection of virtual WFD
+        // display.
+        // This flag is set to zero if WFD is launched via QCOM WFD
+        // proprietary APIs which use HDMI piggyback approach.
+        char value[PROPERTY_VALUE_MAX];
+        property_get("persist.sys.wfd.virtual", value, "0");
+        int wfdVirtual = atoi(value);
+        if(!wfdVirtual) {
+            // This is for non-wfd virtual display scenarios(e.g. SSD/SR/CTS)
+            sp<VirtualDisplaySurface> vds = new VirtualDisplaySurface(*mHwc,
+                    hwcDisplayId, state.surface, bqProducer, bqConsumer, state.displayName);
+            dispSurface = vds;
+            // There won't be any interaction with HWC for this virtual display.
+            // so the GLES driver can pass buffers directly to the sink.
+            producer = state.surface;
+        } else {
+            hwcDisplayId = allocateHwcDisplayId(state.type);
+            if (hwcDisplayId >= 0) {
+                // This is for WFD virtual display scenario.
+                // Read virtual display properties and create a
+                // rendering surface for it inorder to be handled by hwc.
+                setVirtualDisplayData(hwcDisplayId, state.surface);
+                dispSurface = new FramebufferSurface(*mHwc, state.type,
+                bqConsumer);
+                producer = bqProducer;
+            } else {
+                // in case of WFD Virtual + SSD/SR concurrency scenario,
+                // WFD virtual display instance gets valid hwcDisplayId and
+                // SSD/SR will get invalid hwcDisplayId
+                sp<VirtualDisplaySurface> vds = new VirtualDisplaySurface(*mHwc,
+                        hwcDisplayId, state.surface, bqProducer, bqConsumer, state.displayName);
+                dispSurface = vds;
+                // There won't be any interaction with HWC for this virtual
+                // display, so the GLES driver can pass buffers directly to the
+                // sink.
+                producer = state.surface;
+            }
+        }
+    } else {
+        // VDS solution is enabled
+        // HWC is allocated for first virtual display.
+        // Subsequent virtual display sessions will be composed by GLES driver.
+        // ToDo: Modify VDS component to allocate hwcDisplayId based on
+        // mForceHwcCopy (which is based on Usage Flags)
+
+        sp<VirtualDisplaySurface> vds = new VirtualDisplaySurface(*mHwc,
+                hwcDisplayId, state.surface, bqProducer, bqConsumer, state.displayName);
+        dispSurface = vds;
+        if (hwcDisplayId >= 0) {
+            producer = vds;
+        } else {
+            // There won't be any interaction with HWC for this virtual display,
+            // so the GLES driver can pass buffers directly to the sink.
+            producer = state.surface;
+        }
+    }
+}
+
 void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
 {
     const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
@@ -1384,33 +1456,9 @@
                         // they have external state (layer stack, projection,
                         // etc.) but no internal state (i.e. a DisplayDevice).
                         if (state.surface != NULL) {
-
-                            char value[PROPERTY_VALUE_MAX];
-                            hwcDisplayId = allocateHwcDisplayId(state.type);
-                            property_get("persist.sys.wfd.virtual", value, "0");
-                            int wfdVirtual = atoi(value);
-                            if(!wfdVirtual) {
-                                sp<VirtualDisplaySurface> vds = new VirtualDisplaySurface(
-                                        *mHwc, hwcDisplayId, state.surface,
-                                        bqProducer, bqConsumer, state.displayName);
-                                if (hwcDisplayId >= 0) {
-                                   producer = vds;
-                                } else {
-                                  // There won't be any interaction with HWC for this virtual display,
-                                  // so the GLES driver can pass buffers directly to the sink.
-                                  producer = state.surface;
-                                }
-                            } else {
-                                //Read virtual display properties and create a
-                                //rendering surface for it inorder to be handled
-                                //by hwc.
-                                setVirtualDisplayData(hwcDisplayId,
-                                                                 state.surface);
-                                dispSurface = new FramebufferSurface(*mHwc,
-                                                                    state.type,
-                                                                    bqConsumer);
-                                producer = bqProducer;
-                            }
+                            configureVirtualDisplay(hwcDisplayId,
+                                    dispSurface, producer, state, bqProducer,
+                                    bqConsumer);
                         }
                     } else {
                         ALOGE_IF(state.surface!=NULL,