hwc: Extend PTOR feature for two layers

- Consider two smallest layers for PTOR feature which uses MDP comp.
- These two layers are rendered on a buffer and are queued to MDP
  to acheive full MDP Composition
- This helps to acheive performance enhancement

Change-Id: I43d9306ff19cd2d7a410c885316523965a44cbd4
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 0a38b10..dd16847 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -817,80 +817,117 @@
         ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
         return false;
     }
-
-    // Find overlap index
-    int overlapIdx = numAppLayers - 1;
-    uint32_t layerPixelCount, minPixelCount = 0;
-    for (int i = numAppLayers - 1; i >= 0; i--) {
+    // MDP comp checks
+    for(int i = 0; i < numAppLayers; i++) {
         hwc_layer_1_t* layer = &list->hwLayers[i];
-        hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
-        layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
-        if (!minPixelCount || (layerPixelCount < minPixelCount)) {
-            minPixelCount = layerPixelCount;
-            overlapIdx = i;
+        if(not isSupportedForMDPComp(ctx, layer)) {
+            ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
+            return false;
         }
     }
 
-    // No overlap
-    if (!overlapIdx)
-        return false;
-
     /* We cannot use this composition mode, if:
      1. A below layer needs scaling.
      2. Overlap is not peripheral to display.
      3. Overlap or a below layer has 90 degree transform.
-     4. Intersection of Overlap layer with a below layer is not valid.
-     5. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
+     4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
      */
 
-    hwc_rect_t overlap = list->hwLayers[overlapIdx].displayFrame;
-    if (!isPeripheral(overlap, ctx->mViewFrame[mDpy]))
-        return false;
-
-    if ((3 * (overlap.right - overlap.left) * (overlap.bottom - overlap.top)) >
-        ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres))
-        return false;
-
-    for (int i = overlapIdx; i >= 0; i--) {
+    int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
+    hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
+    memset(overlapRect, 0, sizeof(overlapRect));
+    int layerPixelCount, minPixelCount = 0;
+    int numPTORLayersFound = 0;
+    for (int i = numAppLayers-1; (i >= 0 &&
+                                  numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
         hwc_layer_1_t* layer = &list->hwLayers[i];
+        hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
         hwc_rect_t dispFrame = layer->displayFrame;
-
-        if (has90Transform(layer))
-            return false;
-
-        if (i < overlapIdx) {
-            if (needsScaling(layer) ||
-                !isValidRect(getIntersection(dispFrame, overlap)))
-                return false;
+        layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
+        // PTOR layer should be peripheral and cannot have transform
+        if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
+                                has90Transform(layer)) {
+            continue;
+        }
+        if((3 * (layerPixelCount + minPixelCount)) >
+                ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
+            // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
+            continue;
+        }
+        // Found the PTOR layer
+        bool found = true;
+        for (int j = i-1; j >= 0; j--) {
+            // Check if the layers below this layer qualifies for PTOR comp
+            hwc_layer_1_t* layer = &list->hwLayers[j];
+            hwc_rect_t disFrame = layer->displayFrame;
+            //layer below PTOR is intersecting and has 90 degree transform or
+            // needs scaling cannot be supported.
+            if ((isValidRect(getIntersection(dispFrame, disFrame)))
+                            && (has90Transform(layer) || needsScaling(layer))) {
+                found = false;
+                break;
+            }
+        }
+        // Store the minLayer Index
+        if(found) {
+            minLayerIndex[numPTORLayersFound] = i;
+            overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
+            minPixelCount += layerPixelCount;
+            numPTORLayersFound++;
         }
     }
 
-    mOverlapIndex = overlapIdx;
-    if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list, overlapIdx)) {
-        ALOGD_IF(isDebug(), "%s: Overlap prepare failed!",__FUNCTION__);
-        mOverlapIndex = -1;
-        return false;
+    if(isValidRect(getIntersection(overlapRect[0], overlapRect[1]))) {
+        ALOGD_IF(isDebug(), "%s: Ignore Rect2 its intersects with Rect1",
+                 __FUNCTION__);
+        // reset second minLayerIndex[1];
+        minLayerIndex[1] = -1;
+        numPTORLayersFound--;
     }
 
-    hwc_rect_t sourceCrop[overlapIdx];
-    hwc_rect_t displayFrame[overlapIdx];
+    // No overlap layers
+    if (!numPTORLayersFound)
+        return false;
 
-    // Remove overlap from crop & displayFrame of below layers
-    for (int i = 0; i < overlapIdx; i++) {
+    ctx->mPtorInfo.count = numPTORLayersFound;
+    for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
+        ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
+    }
+
+    if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
+        // reset PTOR
+        ctx->mPtorInfo.count = 0;
+        return false;
+    }
+    // Store the displayFrame and the sourceCrops of the layers
+    hwc_rect_t displayFrame[numAppLayers];
+    hwc_rect_t sourceCrop[numAppLayers];
+    for(int i = 0; i < numAppLayers; i++) {
         hwc_layer_1_t* layer = &list->hwLayers[i];
         displayFrame[i] = layer->displayFrame;
         sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
+    }
 
-        // Update layer attributes
-        hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
-        hwc_rect_t destRect = deductRect(layer->displayFrame, overlap);
-        qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
-                                   layer->transform);
-
-        layer->sourceCropf.left = (float)srcCrop.left;
-        layer->sourceCropf.top = (float)srcCrop.top;
-        layer->sourceCropf.right = (float)srcCrop.right;
-        layer->sourceCropf.bottom = (float)srcCrop.bottom;
+    for(int j = 0; j < numPTORLayersFound; j++) {
+        int index =  ctx->mPtorInfo.layerIndex[j];
+        // Remove overlap from crop & displayFrame of below layers
+        for (int i = 0; i < index && index !=-1; i++) {
+            hwc_layer_1_t* layer = &list->hwLayers[i];
+            if(!isValidRect(getIntersection(layer->displayFrame,
+                                            overlapRect[j])))  {
+                continue;
+            }
+            // Update layer attributes
+            hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
+            hwc_rect_t destRect = deductRect(layer->displayFrame,
+                                             overlapRect[j]);
+            qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
+                                       layer->transform);
+            layer->sourceCropf.left = (float)srcCrop.left;
+            layer->sourceCropf.top = (float)srcCrop.top;
+            layer->sourceCropf.right = (float)srcCrop.right;
+            layer->sourceCropf.bottom = (float)srcCrop.bottom;
+        }
     }
 
     mCurrentFrame.mdpCount = numAppLayers;
@@ -903,7 +940,7 @@
     bool result = postHeuristicsHandling(ctx, list);
 
     // Restore layer attributes
-    for (int i = 0; i < overlapIdx; i++) {
+    for(int i = 0; i < numAppLayers; i++) {
         hwc_layer_1_t* layer = &list->hwLayers[i];
         layer->displayFrame = displayFrame[i];
         layer->sourceCropf.left = (float)sourceCrop[i].left;
@@ -913,12 +950,16 @@
     }
 
     if (!result) {
-        mOverlapIndex = -1;
+        // reset PTOR
+        ctx->mPtorInfo.count = 0;
         reset(ctx);
+    } else {
+        ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
+                 ctx->mPtorInfo.layerIndex[0],  ctx->mPtorInfo.layerIndex[1]);
     }
 
-    ALOGD_IF(isDebug(), "%s: Postheuristics %s!, Overlap index = %d",
-        __FUNCTION__, (result ? "successful" : "failed"), mOverlapIndex);
+    ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
+             (result ? "successful" : "failed"));
     return result;
 }
 
@@ -1586,7 +1627,9 @@
                     sSimulationFlags, sSimulationFlags);
         }
     }
-    mOverlapIndex = -1;
+    // reset PTOR
+    if(!mDpy)
+        memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
 
     //Do not cache the information for next draw cycle.
     if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
@@ -1685,11 +1728,10 @@
 
 int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
     int fd = -1;
-    if (mOverlapIndex != -1) {
-        fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list, mOverlapIndex);
+    if (ctx->mPtorInfo.isActive()) {
+        fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
         if (fd < 0) {
             ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
-            mOverlapIndex = -1;
         }
     }
     return fd;
@@ -1881,17 +1923,20 @@
                 continue;
             }
 
-            if (!mDpy && (i == mOverlapIndex)) {
+            int fd = hnd->fd;
+            uint32_t offset = (uint32_t)hnd->offset;
+            int index = ctx->mPtorInfo.getPTORArrayIndex(i);
+            if (!mDpy && (index != -1)) {
                 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
+                fd = hnd->fd;
+                // Use the offset of the RenderBuffer
+                offset = ctx->mPtorInfo.mRenderBuffOffset[index];
             }
 
             ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
                     using  pipe: %d", __FUNCTION__, layer,
                     hnd, dest );
 
-            int fd = hnd->fd;
-            uint32_t offset = (uint32_t)hnd->offset;
-
             Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
             if(rot) {
                 if(!rot->queueBuffer(fd, offset))
@@ -2130,12 +2175,14 @@
             ovutils::eDest indexL = pipe_info.lIndex;
             ovutils::eDest indexR = pipe_info.rIndex;
 
-            if (!mDpy && (i == mOverlapIndex)) {
-                hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
-            }
-
             int fd = hnd->fd;
-            int offset = (uint32_t)hnd->offset;
+            uint32_t offset = (uint32_t)hnd->offset;
+            int index = ctx->mPtorInfo.getPTORArrayIndex(i);
+            if (!mDpy && (index != -1)) {
+                hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
+                fd = hnd->fd;
+                offset = ctx->mPtorInfo.mRenderBuffOffset[index];
+            }
 
             if(ctx->mAD->draw(ctx, fd, offset)) {
                 fd = ctx->mAD->getDstFd();