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_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index f703fa0..8a5d507 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -208,8 +208,8 @@
    return -1;
 }
 
-bool CopyBit::prepareOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list,
-                            int overlapIndex) {
+bool CopyBit::prepareOverlap(hwc_context_t *ctx,
+                             hwc_display_contents_1_t *list) {
 
     if (ctx->mMDP.version < qdutils::MDP_V4_0) {
         ALOGE("%s: Invalid request", __FUNCTION__);
@@ -220,14 +220,35 @@
         ALOGE("%s: Invalid Params", __FUNCTION__);
         return false;
     }
+    PtorInfo* ptorInfo = &(ctx->mPtorInfo);
 
-    //Allocate render buffers if they're not allocated
-    hwc_rect_t overlap = list->hwLayers[overlapIndex].displayFrame;
-    int width = overlap.right - overlap.left;
-    int height = overlap.bottom - overlap.top;
-    int alignW, alignH;
+    // Allocate render buffers if they're not allocated
+    int alignW = 0, alignH = 0;
+    int finalW = 0, finalH = 0;
+    for (int i = 0; i < ptorInfo->count; i++) {
+        int ovlapIndex = ptorInfo->layerIndex[i];
+        hwc_rect_t overlap = list->hwLayers[ovlapIndex].displayFrame;
+        // render buffer width will be the max of two layers
+        // Align Widht and height to 32, Mdp would be configured
+        // with Aligned overlap w/h
+        finalW = max(finalW, ALIGN((overlap.right - overlap.left), 32));
+        finalH += ALIGN((overlap.bottom - overlap.top), 32);
+        if(finalH > ALIGN((overlap.bottom - overlap.top), 32)) {
+            // Calculate the offset for RGBA(4BPP)
+            ptorInfo->mRenderBuffOffset[i] = finalW *
+                (finalH - ALIGN((overlap.bottom - overlap.top), 32)) * 4;
+            // Calculate the dest top, left will always be zero
+            ptorInfo->displayFrame[i].top = (finalH -
+                                (ALIGN((overlap.bottom - overlap.top), 32)));
+        }
+        // calculate the right and bottom values
+        ptorInfo->displayFrame[i].right =  ptorInfo->displayFrame[i].left +
+                                            (overlap.right - overlap.left);
+        ptorInfo->displayFrame[i].bottom = ptorInfo->displayFrame[i].top +
+                                            (overlap.bottom - overlap.top);
+    }
 
-    getBufferSizeAndDimensions(width, height, HAL_PIXEL_FORMAT_RGBA_8888,
+    getBufferSizeAndDimensions(finalW, finalH, HAL_PIXEL_FORMAT_RGBA_8888,
                                alignW, alignH);
 
     if ((mAlignedWidth != alignW) || (mAlignedHeight != alignH)) {
@@ -542,9 +563,9 @@
     return true;
 }
 
-int CopyBit::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list,
-                        int overlapIndex) {
+int CopyBit::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list) {
     int fd = -1;
+    PtorInfo* ptorInfo = &(ctx->mPtorInfo);
 
     if (ctx->mMDP.version < qdutils::MDP_V4_0) {
         ALOGE("%s: Invalid request", __FUNCTION__);
@@ -559,30 +580,34 @@
     }
 
     int copybitLayerCount = 0;
-    hwc_rect_t overlap = list->hwLayers[overlapIndex].displayFrame;
+    for(int j = 0; j < ptorInfo->count; j++) {
+        int ovlapIndex = ptorInfo->layerIndex[j];
+        hwc_rect_t overlap = list->hwLayers[ovlapIndex].displayFrame;
 
-    // Draw overlapped content of layers on render buffer
-    for (int i = 0; i <= overlapIndex; i++) {
-
-        int ret = -1;
-        if ((list->hwLayers[i].acquireFenceFd != -1)) {
-            // Wait for acquire fence on the App buffers.
-            ret = sync_wait(list->hwLayers[i].acquireFenceFd, 1000);
-            if (ret < 0) {
-                ALOGE("%s: sync_wait error!! error no = %d err str = %s",
-                        __FUNCTION__, errno, strerror(errno));
+        // Draw overlapped content of layers on render buffer
+        for (int i = 0; i <= ovlapIndex; i++) {
+            hwc_layer_1_t *layer = &list->hwLayers[i];
+            if(!isValidRect(getIntersection(layer->displayFrame,
+                                               overlap))) {
+                continue;
             }
-            close(list->hwLayers[i].acquireFenceFd);
-            list->hwLayers[i].acquireFenceFd = -1;
-        }
+            if ((list->hwLayers[i].acquireFenceFd != -1)) {
+                // Wait for acquire fence on the App buffers.
+                if(sync_wait(list->hwLayers[i].acquireFenceFd, 1000) < 0) {
+                    ALOGE("%s: sync_wait error!! error no = %d err str = %s",
+                          __FUNCTION__, errno, strerror(errno));
+                }
+                close(list->hwLayers[i].acquireFenceFd);
+                list->hwLayers[i].acquireFenceFd = -1;
+            }
 
-        hwc_layer_1_t *layer = &list->hwLayers[i];
-        int retVal = drawRectUsingCopybit(ctx, layer, renderBuffer, overlap);
-        copybitLayerCount++;
-
-        if(retVal < 0) {
-            ALOGE("%s: drawRectUsingCopybit failed", __FUNCTION__);
-            copybitLayerCount = 0;
+            int retVal = drawRectUsingCopybit(ctx, layer, renderBuffer, overlap,
+                                                ptorInfo->displayFrame[j]);
+            copybitLayerCount++;
+            if(retVal < 0) {
+                ALOGE("%s: drawRectUsingCopybit failed", __FUNCTION__);
+                copybitLayerCount = 0;
+            }
         }
     }
 
@@ -591,12 +616,14 @@
         copybit->flush_get_fence(copybit, &fd);
     }
 
-    ALOGD_IF(DEBUG_COPYBIT, "%s: done!", __FUNCTION__);
+    ALOGD_IF(DEBUG_COPYBIT, "%s: done! copybitLayerCount = %d", __FUNCTION__,
+             copybitLayerCount);
     return fd;
 }
 
 int CopyBit::drawRectUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
-                          private_handle_t *renderBuffer, hwc_rect_t rect)
+                        private_handle_t *renderBuffer, hwc_rect_t overlap,
+                        hwc_rect_t destRect)
 {
     hwc_context_t* ctx = (hwc_context_t*)(dev);
     if (!ctx) {
@@ -626,16 +653,20 @@
     src.horiz_padding = 0;
     src.vert_padding = 0;
 
+
     hwc_rect_t dispFrame = layer->displayFrame;
-    hwc_rect_t iRect = getIntersection(dispFrame, rect);
+    hwc_rect_t iRect = getIntersection(dispFrame, overlap);
     hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
-    qhwc::calculate_crop_rects(crop, dispFrame, iRect, layer->transform);
+    qhwc::calculate_crop_rects(crop, dispFrame, iRect,
+                               layer->transform);
 
     // Copybit source rect
-    copybit_rect_t srcRect = {crop.left, crop.top, crop.right, crop.bottom};
+    copybit_rect_t srcRect = {crop.left, crop.top, crop.right,
+        crop.bottom};
 
     // Copybit destination rect
-    copybit_rect_t dstRect = {rect.left, rect.top, rect.right, rect.bottom};
+    copybit_rect_t dstRect = {destRect.left, destRect.top, destRect.right,
+        destRect.bottom};
 
     // Copybit dst
     copybit_image_t dst;
@@ -647,20 +678,27 @@
 
     copybit_device_t *copybit = mEngine;
 
-    // Copybit region
-    hwc_region_t region = layer->visibleRegionScreen;
+    // Copybit region is the destRect
+    hwc_rect_t regRect = {dstRect.l,dstRect.t, dstRect.r, dstRect.b};
+    hwc_region_t region;
+    region.numRects = 1;
+    region.rects  = &regRect;
     region_iterator copybitRegion(region);
     int acquireFd = layer->acquireFenceFd;
 
-    copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_WIDTH, renderBuffer->width);
-    copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_HEIGHT, renderBuffer->height);
+    copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_WIDTH,
+                           renderBuffer->width);
+    copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_HEIGHT,
+                           renderBuffer->height);
     copybit->set_parameter(copybit, COPYBIT_TRANSFORM, layer->transform);
     copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, layer->planeAlpha);
     copybit->set_parameter(copybit, COPYBIT_BLEND_MODE, layer->blending);
     copybit->set_parameter(copybit, COPYBIT_DITHER,
-        (dst.format == HAL_PIXEL_FORMAT_RGB_565) ? COPYBIT_ENABLE : COPYBIT_DISABLE);
+        (dst.format == HAL_PIXEL_FORMAT_RGB_565) ? COPYBIT_ENABLE :
+        COPYBIT_DISABLE);
     copybit->set_sync(copybit, acquireFd);
-    int err = copybit->stretch(copybit, &dst, &src, &dstRect, &srcRect, &copybitRegion);
+    int err = copybit->stretch(copybit, &dst, &src, &dstRect, &srcRect,
+                               &copybitRegion);
 
     if (err < 0)
         ALOGE("%s: copybit stretch failed",__FUNCTION__);
diff --git a/libhwcomposer/hwc_copybit.h b/libhwcomposer/hwc_copybit.h
index 3d3d302..99a39c8 100644
--- a/libhwcomposer/hwc_copybit.h
+++ b/libhwcomposer/hwc_copybit.h
@@ -51,11 +51,9 @@
 
     void setReleaseFdSync(int fd);
 
-    bool prepareOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list,
-                        int overlapIndex);
+    bool prepareOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list);
 
-    int drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list,
-                    int overlapIndex);
+    int drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list);
 
 private:
     /* cached data */
@@ -87,8 +85,10 @@
     // Helper functions for copybit composition
     int  drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
                           private_handle_t *renderBuffer, bool isFG);
+    // Helper function to draw copybit layer for PTOR comp
     int drawRectUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
-                          private_handle_t *renderBuffer, hwc_rect_t rect);
+                          private_handle_t *renderBuffer, hwc_rect_t overlap,
+                          hwc_rect_t destRect);
     int fillColorUsingCopybit(hwc_layer_1_t *layer,
                           private_handle_t *renderBuffer);
     bool canUseCopybitForYUV (hwc_context_t *ctx);
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();
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index 5f39902..713020a 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -48,7 +48,6 @@
     /* dumpsys */
     void dump(android::String8& buf, hwc_context_t *ctx);
     bool isGLESOnlyComp() { return (mCurrentFrame.mdpCount == 0); }
-    bool isPTORActive() { return (mOverlapIndex != -1); }
     int drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list);
     static MDPComp* getObject(hwc_context_t *ctx, const int& dpy);
     /* Handler to invoke frame redraw on Idle Timer expiry */
@@ -249,8 +248,6 @@
     struct LayerCache mCachedFrame;
     //Enable 4kx2k yuv layer split
     static bool sEnable4k2kYUVSplit;
-    /* Overlap layer index */
-    int mOverlapIndex;
     bool mModeOn; // if prepare happened
     bool allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index);
 };
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index a6cb79e..275af38 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -295,6 +295,7 @@
     ctx->mGPUHintInfo.mCompositionState = COMPOSITION_STATE_MDP;
     ctx->mGPUHintInfo.mCurrGPUPerfMode = EGL_GPU_LEVEL_0;
 #endif
+    memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
     ALOGI("Initializing Qualcomm Hardware Composer");
     ALOGI("MDP version: %d", ctx->mMDP.version);
 }
@@ -1363,7 +1364,7 @@
         }
     }
 
-    if ((fd >= 0) && !dpy && ctx->mMDPComp[dpy]->isPTORActive()) {
+    if ((fd >= 0) && !dpy && ctx->mPtorInfo.isActive()) {
         // Acquire c2d fence of Overlap render buffer
         acquireFd[count++] = fd;
     }
@@ -1429,7 +1430,7 @@
     }
 
     if (!dpy && ctx->mCopyBit[dpy]) {
-        if (ctx->mMDPComp[dpy]->isPTORActive())
+        if (ctx->mPtorInfo.isActive())
             ctx->mCopyBit[dpy]->setReleaseFdSync(releaseFd);
         else
             ctx->mCopyBit[dpy]->setReleaseFd(releaseFd);
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 6b7d87f..ad06e89 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -41,6 +41,8 @@
 #define MIN_DISPLAY_YRES 200
 #define HWC_WFDDISPSYNC_LOG 0
 #define STR(f) #f;
+// Max number of PTOR layers handled
+#define MAX_PTOR_LAYERS 2
 
 //Fwrd decls
 struct hwc_context_t;
@@ -131,6 +133,23 @@
     int  renderBufIndexforABC;
 };
 
+//PTOR Comp info
+struct PtorInfo {
+    int count;
+    int layerIndex[MAX_PTOR_LAYERS];
+    int mRenderBuffOffset[MAX_PTOR_LAYERS];
+    hwc_rect_t displayFrame[MAX_PTOR_LAYERS];
+    bool isActive() { return (count>0); }
+    int getPTORArrayIndex(int index) {
+        int idx = -1;
+        for(int i = 0; i < count; i++) {
+            if(index == layerIndex[i])
+                idx = i;
+        }
+        return idx;
+    }
+};
+
 struct LayerProp {
     uint32_t mFlags; //qcom specific layer flags
     LayerProp():mFlags(0){};
@@ -574,6 +593,8 @@
     struct gpu_hint_info mGPUHintInfo;
     //App Buffer Composition
     bool enableABC;
+    // PTOR Info
+    qhwc::PtorInfo mPtorInfo;
 };
 
 namespace qhwc {