hwc : Add support for ABC in MDP3

In display list if one layer has same parameters
as framebuffer on index '0'. Use this layer
as FB and blit other layer(s) on top of it.

Change-Id: If38712781f24a2e27686d2b370643f51a9b05358
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 2cd2d2a..1df8635 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -342,16 +342,16 @@
 
 bool CopyBit::drawUsingAppBufferComposition(hwc_context_t *ctx,
                                       hwc_display_contents_1_t *list,
-                                      int dpy) {
-    int layerCount = 0;
-    uint32_t last = list->numHwLayers - 1;
-    hwc_layer_1_t *fbLayer = &list->hwLayers[last];
-    private_handle_t *fbhnd = (private_handle_t *)fbLayer->handle;
+                                      int dpy, int *copybitFd) {
+     int layerCount = 0;
+     uint32_t last = list->numHwLayers - 1;
+     hwc_layer_1_t *fbLayer = &list->hwLayers[last];
+     private_handle_t *fbhnd = (private_handle_t *)fbLayer->handle;
 
     if(ctx->enableABC == false)
        return false;
 
-    if(ctx->listStats[dpy].numAppLayers != MAX_LAYERS_FOR_ABC )
+    if(ctx->listStats[dpy].numAppLayers > MAX_LAYERS_FOR_ABC )
        return false;
 
     layerCount = ctx->listStats[dpy].numAppLayers;
@@ -371,9 +371,33 @@
        }
     }
 
-    if(ctx->listStats[dpy].renderBufIndexforABC == 0){
+    if(ctx->listStats[dpy].renderBufIndexforABC == 0) {
+       if(layerCount == 1)
           return true;
-    // Todo::same for two layers.
+
+       if(layerCount == MAX_LAYERS_FOR_ABC) {
+          // Pass the Acquire Fence FD to driver for base layer
+          int abcRenderBufIdx = ctx->listStats[dpy].renderBufIndexforABC;
+          private_handle_t *renderBuffer =
+          (private_handle_t *)list->hwLayers[abcRenderBufIdx].handle;
+          copybit_device_t *copybit = getCopyBitDevice();
+          if(list->hwLayers[abcRenderBufIdx].acquireFenceFd >=0){
+             copybit->set_sync(copybit,
+             list->hwLayers[abcRenderBufIdx].acquireFenceFd);
+          }
+          for(int i = 1; i < layerCount; i++){
+             int retVal = drawLayerUsingCopybit(ctx,
+               &(list->hwLayers[i]),renderBuffer, 0);
+             if(retVal < 0) {
+                ALOGE("%s : Copybit failed", __FUNCTION__);
+             }
+          }
+          // Get Release Fence FD of copybit for the App layer(s)
+          copybit->flush_get_fence(copybit, copybitFd);
+          close(list->hwLayers[abcRenderBufIdx].acquireFenceFd);
+          list->hwLayers[abcRenderBufIdx].acquireFenceFd = -1;
+          return true;
+       }
     }
     return false;
 }
@@ -392,7 +416,7 @@
        return false ;
     }
 
-    if(drawUsingAppBufferComposition(ctx, list, dpy)) {
+    if(drawUsingAppBufferComposition(ctx, list, dpy, fd)) {
        return true;
     }
     //render buffer
diff --git a/libhwcomposer/hwc_copybit.h b/libhwcomposer/hwc_copybit.h
index 3137538..3e9dff0 100644
--- a/libhwcomposer/hwc_copybit.h
+++ b/libhwcomposer/hwc_copybit.h
@@ -27,7 +27,7 @@
 //twice
 #define MAX_SCALE_FACTOR 16
 #define MIN_SCALE_FACTOR 0.0625
-#define MAX_LAYERS_FOR_ABC 1
+#define MAX_LAYERS_FOR_ABC 2
 namespace qhwc {
 
 class CopyBit {
@@ -75,7 +75,7 @@
     struct copybit_device_t *mEngine;
     bool drawUsingAppBufferComposition(hwc_context_t *ctx,
                                 hwc_display_contents_1_t *list,
-                                int dpy);
+                                int dpy, int *fd);
     // Helper functions for copybit composition
     int  drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
                           private_handle_t *renderBuffer, bool isFG);
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index ea3aecb..18ae28f 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -1333,7 +1333,15 @@
                         list->hwLayers[i].acquireFenceFd >= 0) {
             if(UNLIKELY(swapzero))
                 acquireFd[count++] = -1;
-            else
+            // if ABC is enabled for more than one layer.
+            // renderBufIndexforABC will work as FB.Hence
+            // set the acquireFD from fd - which is coming from copybit
+            else if(fd >= 0 && (isAbcInUse(ctx) == true)) {
+                if(ctx->listStats[dpy].renderBufIndexforABC ==(int32_t)i)
+                   acquireFd[count++] = fd;
+                else
+                   continue;
+            } else
                 acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
         }
         if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
@@ -1386,10 +1394,15 @@
 #ifdef QCOM_BSP
                 //If rotator has not already populated this field
                 // & if it's a not VPU layer
-                if((list->hwLayers[i].compositionType == HWC_BLIT)&&
-                                        (isAbcInUse(ctx) == false)){
-                    //For Blit, the app layers should be released when the Blit is
-                    //complete. This fd was passed from copybit->draw
+
+                // if ABC is enabled for more than one layer
+                if(fd >= 0 && (isAbcInUse(ctx) == true) &&
+                  ctx->listStats[dpy].renderBufIndexforABC !=(int32_t)i){
+                    list->hwLayers[i].releaseFenceFd = dup(fd);
+                } else if((list->hwLayers[i].compositionType == HWC_BLIT)&&
+                                               (isAbcInUse(ctx) == false)){
+                    //For Blit, the app layers should be released when the Blit
+                    //is complete. This fd was passed from copybit->draw
                     list->hwLayers[i].releaseFenceFd = dup(fd);
                 } else
 #endif