SurfaceFlinger: Add support for virtual display

- Creates a rendering surface when invoked via hybrid path
- Makes changes in HWC wrapper to handle virtual display via HWC

Change-Id: I86560b5009949b75c267249799a446b8279eff32
Conflicts:
services/surfaceflinger/SurfaceFlinger.h
services/surfaceflinger/SurfaceFlinger.cpp
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 96a8adb..0ff26be 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1210,6 +1210,26 @@
     // here the transaction has been committed
 }
 
+void SurfaceFlinger::setVirtualDisplayData(
+    int32_t hwcDisplayId,
+    const sp<IGraphicBufferProducer>& sink)
+{
+    sp<ANativeWindow> mNativeWindow = new Surface(sink);
+    ANativeWindow* const window = mNativeWindow.get();
+
+    int format;
+    window->query(window, NATIVE_WINDOW_FORMAT, &format);
+
+    EGLSurface surface;
+    EGLint w, h;
+    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    surface = eglCreateWindowSurface(display, mRenderEngine->getEGLConfig(), window, NULL);
+    eglQuerySurface(display, surface, EGL_WIDTH,  &w);
+    eglQuerySurface(display, surface, EGL_HEIGHT, &h);
+
+    mHwc->setVirtualDisplayProperties(hwcDisplayId, w, h, format);
+}
+
 void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
 {
     const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
@@ -1328,13 +1348,32 @@
                         // etc.) but no internal state (i.e. a DisplayDevice).
                         if (state.surface != NULL) {
 
+                            char value[PROPERTY_VALUE_MAX];
                             hwcDisplayId = allocateHwcDisplayId(state.type);
-                            sp<VirtualDisplaySurface> vds = new VirtualDisplaySurface(
-                                    *mHwc, hwcDisplayId, state.surface,
-                                    bqProducer, bqConsumer, state.displayName);
-
-                            dispSurface = vds;
-                            producer = vds;
+                            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;
+                            }
                         }
                     } else {
                         ALOGE_IF(state.surface!=NULL,
@@ -1350,7 +1389,7 @@
                     }
 
                     const wp<IBinder>& display(curr.keyAt(i));
-                    if (dispSurface != NULL) {
+                    if (dispSurface != NULL && producer != NULL) {
                         sp<DisplayDevice> hw = new DisplayDevice(this,
                                 state.type, hwcDisplayId,
                                 mHwc->getFormat(hwcDisplayId), state.isSecure,