hwc: Add support for SourceSplit

Add support for SourceSplit. The mixers are abstracted from hwc.
There would be no translations to mixer understood destinations.

1) If a layer's crop and position are < 2048, only 1 pipe can be used
irrespective of position.
2) Else 2 pipes can be used with the layer equally split, without
regard to position.

Change-Id: I501a53838d147887c1e2299366663e05320d5096
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index cc9e3b9..27abf6a 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -39,6 +39,9 @@
 
 IFBUpdate* IFBUpdate::getObject(hwc_context_t *ctx, const int& dpy) {
     if(isDisplaySplit(ctx, dpy)) {
+        if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
+            return new FBSrcSplit(ctx, dpy);
+        }
         return new FBUpdateSplit(ctx, dpy);
     }
     return new FBUpdateNonSplit(ctx, dpy);
@@ -422,5 +425,102 @@
     return ret;
 }
 
+//=================FBSrcSplit====================================
+FBSrcSplit::FBSrcSplit(hwc_context_t *ctx, const int& dpy):
+        FBUpdateSplit(ctx, dpy) {}
+
+bool FBSrcSplit::configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
+        hwc_rect_t fbUpdatingRect, int fbZorder) {
+    bool ret = false;
+    hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
+    int extOnlyLayerIndex = ctx->listStats[mDpy].extOnlyLayerIndex;
+    // ext only layer present..
+    if(extOnlyLayerIndex != -1) {
+        layer = &list->hwLayers[extOnlyLayerIndex];
+        layer->compositionType = HWC_OVERLAY;
+    }
+    overlay::Overlay& ov = *(ctx->mOverlay);
+
+    ovutils::Whf info(mAlignedFBWidth,
+            mAlignedFBHeight,
+            ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
+                mTileEnabled));
+    //Request left pipe, VG first owing to higher prio
+    ovutils::eDest destL = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy,
+            Overlay::MIXER_DEFAULT);
+    if(destL == ovutils::OV_INVALID) {
+        destL = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
+            Overlay::MIXER_DEFAULT);
+        if(destL == ovutils::OV_INVALID) {
+            ALOGE("%s: No pipes available to configure fb for dpy %d's left"
+                    " mixer", __FUNCTION__, mDpy);
+            return false;
+        }
+    }
+    //Request right pipe
+    ovutils::eDest destR = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
+            Overlay::MIXER_DEFAULT);
+    if(destR == ovutils::OV_INVALID) {
+        ALOGE("%s: No pipes available to configure fb for dpy %d's right"
+                " mixer", __FUNCTION__, mDpy);
+        return false;
+    }
+
+    mDestLeft = destL;
+    mDestRight = destR;
+
+    ovutils::eMdpFlags mdpFlags = OV_MDP_BLEND_FG_PREMULT;
+    ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
+
+    ovutils::PipeArgs parg(mdpFlags,
+            info,
+            zOrder,
+            ovutils::IS_FG_OFF,
+            ovutils::ROT_FLAGS_NONE,
+            ovutils::DEFAULT_PLANE_ALPHA,
+            (ovutils::eBlending)
+            getBlending(layer->blending));
+    ov.setSource(parg, destL);
+    ov.setSource(parg, destR);
+
+    //Crop and Position are same for FB
+    ovutils::Dim cropPosL(
+            fbUpdatingRect.left,
+            fbUpdatingRect.top,
+            (fbUpdatingRect.right - fbUpdatingRect.left) / 2,
+            fbUpdatingRect.bottom - fbUpdatingRect.top);
+
+    ovutils::Dim cropPosR(
+            cropPosL.x + cropPosL.w,
+            cropPosL.y,
+            cropPosL.w,
+            cropPosL.h);
+
+    ov.setCrop(cropPosL, destL);
+    ov.setCrop(cropPosR, destR);
+    ov.setPosition(cropPosL, destL);
+    ov.setPosition(cropPosR, destR);
+
+    int transform = layer->transform;
+    ovutils::eTransform orient =
+            static_cast<ovutils::eTransform>(transform);
+    ov.setTransform(orient, destL);
+    ov.setTransform(orient, destR);
+
+    ret = true;
+    if (!ov.commit(destL)) {
+        ALOGE("%s: commit fails for left", __FUNCTION__);
+        ret = false;
+    }
+    if (!ov.commit(destR)) {
+        ALOGE("%s: commit fails for right", __FUNCTION__);
+        ret = false;
+    }
+    if(ret == false) {
+        ctx->mLayerRotMap[mDpy]->clear();
+    }
+    return ret;
+}
+
 //---------------------------------------------------------------------
 }; //namespace qhwc