hwc: Add DMA pipe support in MDP composition.

This change adds support to MDP composition to use DMA pipes when
layer scaling is not needed. Also makes sure not to invoke
MDP rotator when DMA pipes are configured since MDP rotator will
expect both the DMA pipes to available for performing rotation.
In such cases, we let the first frame of rotated video frame to
fall back to FB.

Change-Id: I3c3697dd2713ce9b86ba1e23192ec5841abd25ec
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index 540040a..fccfcde 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -200,6 +200,7 @@
 
     ctx->mOverlay->configBegin();
     ctx->mRotMgr->configBegin();
+    ctx->mNeedsRotator = false;
 
     for (int32_t i = numDisplays; i >= 0; i--) {
         hwc_display_contents_1_t *list = displays[i];
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index f141af8..56432db 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -250,6 +250,7 @@
         case MDPCOMP_OV_DMA:
             mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_DMA, dpy);
             if(mdp_pipe != ovutils::OV_INVALID) {
+                ctx->mDMAInUse = true;
                 return mdp_pipe;
             }
         case MDPCOMP_OV_ANY:
@@ -277,10 +278,14 @@
     //Number of layers
     const int dpy = HWC_DISPLAY_PRIMARY;
     int numAppLayers = ctx->listStats[dpy].numAppLayers;
+    int numDMAPipes = qdutils::MDPVersion::getInstance().getDMAPipes();
 
     overlay::Overlay& ov = *ctx->mOverlay;
     int availablePipes = ov.availablePipes(dpy);
 
+    if(ctx->mNeedsRotator)
+        availablePipes -= numDMAPipes;
+
     if(numAppLayers < 1 || numAppLayers > MAX_PIPES_PER_MIXER ||
                            pipesNeeded(ctx, list) > availablePipes) {
         ALOGD_IF(isDebug(), "%s: Unsupported number of layers",__FUNCTION__);
@@ -320,14 +325,19 @@
         return false;
     }
 
+    if(ctx->mNeedsRotator && ctx->mDMAInUse) {
+        ALOGD_IF(isDebug(), "%s: DMA not available for Rotator",__FUNCTION__);
+        return false;
+    }
+
     //MDP composition is not efficient if layer needs rotator.
     for(int i = 0; i < numAppLayers; ++i) {
         // As MDP h/w supports flip operation, use MDP comp only for
         // 180 transforms. Fail for any transform involving 90 (90, 270).
         hwc_layer_1_t* layer = &list->hwLayers[i];
         private_handle_t *hnd = (private_handle_t *)layer->handle;
-        if((layer->transform & HWC_TRANSFORM_ROT_90)  && (!isYuvBuffer(hnd)
-                                                            || !canRotate())) {
+
+        if(layer->transform & HWC_TRANSFORM_ROT_90 && !isYuvBuffer(hnd)) {
             ALOGD_IF(isDebug(), "%s: orientation involved",__FUNCTION__);
             return false;
         }
@@ -347,6 +357,7 @@
         return -1;
     }
 
+    ctx->mDMAInUse = false;
     if(!allocLayerPipes(ctx, list, mCurrentFrame)) {
         ALOGD_IF(isDebug(), "%s: Falling back to FB", __FUNCTION__);
         return false;
@@ -468,7 +479,14 @@
         info.rot = NULL;
         MdpPipeInfoLowRes& pipe_info = *(MdpPipeInfoLowRes*)info.pipeInfo;
 
-        pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_ANY);
+        ePipeType type = MDPCOMP_OV_ANY;
+
+        if(!qhwc::needsScaling(layer) && !ctx->mNeedsRotator
+                             && ctx->mMDP.version >= qdutils::MDSS_V5) {
+            type = MDPCOMP_OV_DMA;
+        }
+
+        pipe_info.index = getMdpPipe(ctx, type);
         if(pipe_info.index == ovutils::OV_INVALID) {
             ALOGD_IF(isDebug(), "%s: Unable to get pipe for UI", __FUNCTION__);
             return false;
@@ -637,7 +655,7 @@
 
         ePipeType type = MDPCOMP_OV_ANY;
 
-        if(!qhwc::needsScaling(layer) && !ctx->mDMAInUse
+        if(!qhwc::needsScaling(layer) && !ctx->mNeedsRotator
                              && ctx->mMDP.version >= qdutils::MDSS_V5)
             type = MDPCOMP_OV_DMA;
 
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index 926f637..d847f56 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -88,8 +88,6 @@
     /* configures MPD pipes */
     virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
                 PipeLayerPair& pipeLayerPair) = 0;
-    /* Is rotation supported */
-    virtual bool canRotate(){ return true; };
 
 
     /* set/reset flags for MDPComp */
@@ -173,7 +171,6 @@
             FrameInfo& current_frame);
 
     virtual int pipesNeeded(hwc_context_t *ctx, hwc_display_contents_1_t* list);
-    virtual bool canRotate(){ return false; };
 };
 }; //namespace
 #endif
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 013833f..3af37dd 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -299,7 +299,6 @@
     ctx->listStats[dpy].skipCount = 0;
     ctx->listStats[dpy].needsAlphaScale = false;
     ctx->listStats[dpy].yuvCount = 0;
-    ctx->mDMAInUse = false;
 
     for (size_t i = 0; i < list->numHwLayers; i++) {
         hwc_layer_1_t const* layer = &list->hwLayers[i];
@@ -318,8 +317,8 @@
             ctx->listStats[dpy].yuvIndices[yuvCount] = i;
             yuvCount++;
 
-            if((layer->transform & HWC_TRANSFORM_ROT_90) && !ctx->mDMAInUse)
-                ctx->mDMAInUse = true;
+            if(layer->transform & HWC_TRANSFORM_ROT_90)
+                ctx->mNeedsRotator = true;
         }
 
         if(!ctx->listStats[dpy].needsAlphaScale)
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index e4431d0..52069ba 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -296,6 +296,8 @@
     struct vsync_state vstate;
     //DMA used for rotator
     bool mDMAInUse;
+    //MDP rotater needed
+    bool mNeedsRotator;
 };
 
 namespace qhwc {
diff --git a/libhwcomposer/hwc_video.cpp b/libhwcomposer/hwc_video.cpp
index 2166a5b..f09cc35 100644
--- a/libhwcomposer/hwc_video.cpp
+++ b/libhwcomposer/hwc_video.cpp
@@ -94,6 +94,13 @@
         }
     }
 
+    if((layer->transform & HWC_TRANSFORM_ROT_90) && ctx->mDMAInUse) {
+        ctx->mDMAInUse = false;
+        ALOGD_IF(VIDEO_DEBUG, "%s: Rotator not available since \
+                  DMA Pipe(s) are in use",__FUNCTION__);
+        return false;
+    }
+
     if(configure(ctx, layer)) {
         markFlags(layer);
         mModeOn = true;