(TEMP) hwc: external: Enable default mirroring on hwc1.1

Related to bug: 7124159

UI Mirror works with tearing because sync operates at primary vsync.  Need
kernel patch to wait on external post.

Change-Id: I77116ef40ae25a2207feb5ca3cd9065ef0da6e4a
Signed-off-by: Iliyan Malchev <malchev@google.com>
diff --git a/libhwcomposer/Android.mk b/libhwcomposer/Android.mk
index 4e52ede..8697b5a 100644
--- a/libhwcomposer/Android.mk
+++ b/libhwcomposer/Android.mk
@@ -16,5 +16,6 @@
                                  hwc_utils.cpp    \
                                  hwc_uevents.cpp  \
                                  hwc_mdpcomp.cpp  \
+                                 hwc_uimirror.cpp \
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index 3be2def..202e40d 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -27,6 +27,7 @@
 #include <mdp_version.h>
 #include "hwc_utils.h"
 #include "hwc_video.h"
+#include "hwc_uimirror.h"
 #include "external.h"
 #include "hwc_mdpcomp.h"
 
@@ -83,9 +84,13 @@
         hwc_display_contents_1_t *list) {
     hwc_context_t* ctx = (hwc_context_t*)(dev);
     if (LIKELY(list && list->numHwLayers)) {
+        uint32_t last = list->numHwLayers - 1;
+        hwc_layer_1_t *fblayer = &list->hwLayers[last];
         setListStats(ctx, list, HWC_DISPLAY_PRIMARY);
         if(VideoOverlay::prepare(ctx, list, HWC_DISPLAY_PRIMARY)) {
             ctx->overlayInUse = true;
+        } else if(UIMirrorOverlay::prepare(ctx, fblayer)) {
+            ctx->overlayInUse = true;
         } else if(MDPComp::configure(ctx, list)) {
             ctx->overlayInUse = true;
         } else {
@@ -100,7 +105,7 @@
 
     hwc_context_t* ctx = (hwc_context_t*)(dev);
     if (LIKELY(list && list->numHwLayers)) {
-        setListStats(ctx, list, HWC_DISPLAY_EXTERNAL);
+        //setListStats(ctx, list, HWC_DISPLAY_EXTERNAL);
         //Nothing to do for now
     }
     return 0;
@@ -210,7 +215,7 @@
         ALOGI("fps: %d", value[0]);
         break;
     case HWC_DISPLAY_TYPES_SUPPORTED:
-        //Enable later
+        //TODO Enable later
         //if(ctx->mMDP.hasOverlay)
             //supported |= HWC_DISPLAY_EXTERNAL_BIT;
         value[0] = supported;
@@ -226,10 +231,17 @@
     if (LIKELY(list && list->numHwLayers)) {
         VideoOverlay::draw(ctx, list, HWC_DISPLAY_PRIMARY);
         MDPComp::draw(ctx, list);
+        uint32_t last = list->numHwLayers - 1;
+        hwc_layer_1_t *fblayer = &list->hwLayers[last];
+        if(ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive) {
+            UIMirrorOverlay::draw(ctx, fblayer);
+        }
         hwc_sync(ctx, list, HWC_DISPLAY_PRIMARY);
+        if(ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive) {
+            ctx->mExtDisplay->post();
+        }
         //TODO We dont check for SKIP flag on this layer because we need PAN
         //always. Last layer is always FB
-        uint32_t last = list->numHwLayers - 1;
         if(list->hwLayers[last].compositionType == HWC_FRAMEBUFFER_TARGET) {
             ctx->mFbDev->post(ctx->mFbDev, list->hwLayers[last].handle);
         }
@@ -240,7 +252,7 @@
 static int hwc_set_external(hwc_context_t *ctx,
         hwc_display_contents_1_t* list) {
     if (LIKELY(list && list->numHwLayers)) {
-        hwc_sync(ctx, list, HWC_DISPLAY_EXTERNAL);
+        //hwc_sync(ctx, list, HWC_DISPLAY_EXTERNAL);
         uint32_t last = list->numHwLayers - 1;
         if(list->hwLayers[last].compositionType == HWC_FRAMEBUFFER_TARGET &&
             ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive) {
diff --git a/libhwcomposer/hwc_video.cpp b/libhwcomposer/hwc_video.cpp
index 3aa7e7a..170c29e 100644
--- a/libhwcomposer/hwc_video.cpp
+++ b/libhwcomposer/hwc_video.cpp
@@ -65,9 +65,11 @@
     switch(dpy) {
         case HWC_DISPLAY_PRIMARY:
             if(ctx->listStats[dpy].yuvCount == 1) {
-                newState = ovutils::OV_2D_VIDEO_ON_PANEL;
+                newState = isExternalActive(ctx) ?
+                    ovutils::OV_2D_VIDEO_ON_PANEL_TV : ovutils::OV_2D_VIDEO_ON_PANEL;
                 if(isSkipLayer(yuvLayer) && !isSecureBuffer(hnd)) {
-                    newState = ovutils::OV_CLOSED;
+                    newState = isExternalActive(ctx) ?
+                        ovutils::OV_2D_VIDEO_ON_TV : ovutils::OV_CLOSED;
                 }
             }
             break;
@@ -237,6 +239,13 @@
                 case ovutils::OV_2D_VIDEO_ON_PANEL:
                     ret &= configPrimVid(ctx, yuvLayer);
                     break;
+                case ovutils::OV_2D_VIDEO_ON_PANEL_TV:
+                    ret &= configPrimVid(ctx, yuvLayer);
+                    ret &= configExtVid(ctx, yuvLayer);
+                    break;
+                case ovutils::OV_2D_VIDEO_ON_TV:
+                    ret &= configExtVid(ctx, yuvLayer);
+                    break;
                 default:
                     return false;
             }
@@ -281,6 +290,24 @@
                         ret = false;
                     }
                     break;
+                case ovutils::OV_2D_VIDEO_ON_PANEL_TV:
+                    if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE0)) {
+                        ALOGE("%s: queueBuffer failed for primary", __FUNCTION__);
+                        ret = false;
+                    }
+                    // Play external
+                    if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE1)) {
+                        ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
+                        ret = false;
+                    }
+                    break;
+                case ovutils::OV_2D_VIDEO_ON_TV:
+                    // Play external
+                    if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE1)) {
+                        ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
+                        ret = false;
+                    }
+                    break;
                 default:
                     ret = false;
                     break;