hwc: enable dual display on hwc 1.1

Enable dual display on HWC 1.1; video uses overlay.

Bug: 7124159
Change-Id: I8333e46cfc74072f6259fba2b82368f0dd52b6df
Signed-off-by: Iliyan Malchev <malchev@google.com>
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index 37e99df..170b8a9 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -53,6 +53,7 @@
         case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
         case utils::OV_UI_MIRROR:
         case utils::OV_2D_TRUE_UI_MIRROR:
+        case utils::OV_UI_VIDEO_TV:
         case utils::OV_BYPASS_1_LAYER:
         case utils::OV_BYPASS_2_LAYER:
         case utils::OV_BYPASS_3_LAYER:
@@ -187,16 +188,19 @@
     return mState.state();
 }
 
-Overlay *Overlay::sInstance = 0;
+Overlay *Overlay::sInstance[] = {0};
 
-Overlay* Overlay::getInstance() {
-    if(sInstance == NULL) {
-        if(utils::initOverlay() == -1) {
-            ALOGE("utils::initOverlay() ERROR!!");
-        }
-        sInstance = new Overlay();
+Overlay* Overlay::getInstance(int disp) {
+    if(sInstance[disp] == NULL) {
+        sInstance[disp] = new Overlay();
     }
-    return sInstance;
+    return sInstance[disp];
+}
+
+void Overlay::initOverlay() {
+    if(utils::initOverlay() == -1) {
+        ALOGE("utils::initOverlay() ERROR!!");
+    }
 }
 
 } // overlay
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index 12b3883..f8f9c34 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -66,8 +66,11 @@
     /* expose state */
     utils::eOverlayState getState() const;
 
-    /* Returns the singleton instance of overlay */
-    static Overlay* getInstance();
+    /* Closes open pipes */
+    static void initOverlay();
+
+    /* Returns the per-display singleton instance of overlay */
+    static Overlay* getInstance(int disp);
 
 private:
     /* Ctor setup */
@@ -84,8 +87,8 @@
     /* Holds the actual overlay impl, set when changing state*/
     OverlayImplBase *mOv;
 
-    /* Singleton Instance*/
-    static Overlay *sInstance;
+    /* Per-display Singleton Instance HWC_NUM_DISPLAY_TYPES */
+    static Overlay *sInstance[2];
 };
 
 } // overlay
diff --git a/liboverlay/overlayState.h b/liboverlay/overlayState.h
index e4fbece..85d61d5 100644
--- a/liboverlay/overlayState.h
+++ b/liboverlay/overlayState.h
@@ -145,6 +145,19 @@
     typedef overlay::OverlayImpl<pipe0, pipe1, pipe2> ovimpl;
 };
 
+template <> struct StateTraits<utils::OV_UI_VIDEO_TV>
+{
+    typedef overlay::GenericPipe<utils::EXTERNAL> pipe0; //ext UI
+    typedef overlay::GenericPipe<utils::EXTERNAL> pipe1; //ext video
+    typedef overlay::NullPipe pipe2;
+
+    typedef Rotator rot0;
+    typedef Rotator rot1;
+    typedef NullRotator rot2;
+
+    typedef overlay::OverlayImpl<pipe0, pipe1, pipe2> ovimpl;
+};
+
 template <> struct StateTraits<utils::OV_3D_VIDEO_ON_2D_PANEL>
 {
     typedef overlay::M3DPrimaryPipe<utils::OV_PIPE0> pipe0;
@@ -199,7 +212,7 @@
 
 template <> struct StateTraits<utils::OV_UI_MIRROR>
 {
-    typedef overlay::UIMirrorPipe pipe0;
+    typedef overlay::GenericPipe<ovutils::EXTERNAL> pipe0; //Ext UI
     typedef overlay::NullPipe pipe1;   // place holder
     typedef overlay::NullPipe pipe2;   // place holder
 
@@ -212,9 +225,9 @@
 
 template <> struct StateTraits<utils::OV_2D_TRUE_UI_MIRROR>
 {
-    typedef overlay::GenericPipe<utils::PRIMARY> pipe0;
+    typedef overlay::GenericPipe<utils::PRIMARY> pipe0; //Vid prim
     typedef overlay::VideoExtPipe pipe1;
-    typedef overlay::UIMirrorPipe pipe2;
+    typedef overlay::GenericPipe<ovutils::EXTERNAL> pipe2; //EXT UI
 
     typedef Rotator rot0;
     typedef Rotator rot1;
@@ -335,6 +348,9 @@
         case utils::OV_2D_TRUE_UI_MIRROR:
             newov = handle_from<utils::OV_2D_TRUE_UI_MIRROR>(toState, ov);
             break;
+        case utils::OV_UI_VIDEO_TV:
+            newov = handle_from<utils::OV_UI_VIDEO_TV>(toState, ov);
+            break;
         case utils::OV_BYPASS_1_LAYER:
             newov = handle_from<utils::OV_BYPASS_1_LAYER>(toState, ov);
             break;
@@ -391,6 +407,9 @@
         case utils::OV_2D_TRUE_UI_MIRROR:
             ov = handle_from_to<FROM_STATE, utils::OV_2D_TRUE_UI_MIRROR>(ov);
             break;
+        case utils::OV_UI_VIDEO_TV:
+            ov = handle_from_to<FROM_STATE, utils::OV_UI_VIDEO_TV>(ov);
+            break;
         case utils::OV_BYPASS_1_LAYER:
             ov = handle_from_to<FROM_STATE, utils::OV_BYPASS_1_LAYER>(ov);
             break;
@@ -580,6 +599,69 @@
     return newov;
 }
 
+/* Transition from OV_UI_MIRROR to OV_UI_VIDEO_TV */
+template<>
+inline OverlayImplBase* OverlayState::handle_from_to<
+        utils::OV_UI_MIRROR,
+        utils::OV_UI_VIDEO_TV>(
+        OverlayImplBase* ov) {
+    OVASSERT(ov, "%s: ov is null", __FUNCTION__);
+    ALOGD("FROM_STATE = %s TO_STATE = %s",
+            utils::getStateString(utils::OV_UI_MIRROR),
+            utils::getStateString(utils::OV_UI_VIDEO_TV));
+
+    // Create new ovimpl based on new state
+    typedef StateTraits<utils::OV_UI_VIDEO_TV> NewState;
+    OverlayImplBase* newov = new NewState::ovimpl;
+
+    //copy pipe0/rot0 (ext video)
+    newov->copyOvPipe(ov, utils::OV_PIPE0);
+
+    ov->closePipe(utils::OV_PIPE1);
+    RotatorBase* rot1 = new NewState::rot1;
+    newov->initPipe(rot1, utils::OV_PIPE1);
+
+    ov->closePipe(utils::OV_PIPE2);
+    RotatorBase* rot2 = new NewState::rot2;
+    newov->initPipe(rot2, utils::OV_PIPE2);
+
+    // All pipes are copied or deleted so no more need for previous ovimpl
+    delete ov;
+    ov = 0;
+    return newov;
+}
+
+/* Transition from OV_UI_VIDEO_TV to OV_UI_MIRROR */
+template<>
+inline OverlayImplBase* OverlayState::handle_from_to<
+        utils::OV_UI_VIDEO_TV,
+        utils::OV_UI_MIRROR>(
+        OverlayImplBase* ov) {
+    OVASSERT(ov, "%s: ov is null", __FUNCTION__);
+    ALOGD("FROM_STATE = %s TO_STATE = %s",
+            utils::getStateString(utils::OV_UI_VIDEO_TV),
+            utils::getStateString(utils::OV_UI_MIRROR));
+
+    // Create new ovimpl based on new state
+    typedef StateTraits<utils::OV_UI_MIRROR> NewState;
+    OverlayImplBase* newov = new NewState::ovimpl;
+
+    //copy pipe0/rot0 (ext video)
+    newov->copyOvPipe(ov, utils::OV_PIPE0);
+
+    ov->closePipe(utils::OV_PIPE1);
+    RotatorBase* rot1 = new NewState::rot1;
+    newov->initPipe(rot1, utils::OV_PIPE1);
+
+    ov->closePipe(utils::OV_PIPE2);
+    RotatorBase* rot2 = new NewState::rot2;
+    newov->initPipe(rot2, utils::OV_PIPE2);
+
+    // All pipes are copied or deleted so no more need for previous ovimpl
+    delete ov;
+    ov = 0;
+    return newov;
+}
 } // overlay
 
 #endif // OVERLAY_STATE_H
diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h
index f308b95..8db37c5 100644
--- a/liboverlay/overlayUtils.h
+++ b/liboverlay/overlayUtils.h
@@ -402,6 +402,8 @@
     /* UI Mirroring */
     OV_UI_MIRROR,
     OV_2D_TRUE_UI_MIRROR,
+    /* Dual display with video */
+    OV_UI_VIDEO_TV,
 
     /* Composition Bypass */
     OV_BYPASS_1_LAYER,
@@ -648,6 +650,8 @@
             return "OV_UI_MIRROR";
         case OV_2D_TRUE_UI_MIRROR:
             return "OV_2D_TRUE_UI_MIRROR";
+        case OV_UI_VIDEO_TV:
+            return "OV_UI_VIDEO_TV";
         case OV_BYPASS_1_LAYER:
             return "OV_BYPASS_1_LAYER";
         case OV_BYPASS_2_LAYER: