Merge "hwc: Refresh framebuffer when an updating layer is marked for GPU"
diff --git a/libcopybit/copybit.cpp b/libcopybit/copybit.cpp
index ff7dc4e..5d8da05 100644
--- a/libcopybit/copybit.cpp
+++ b/libcopybit/copybit.cpp
@@ -555,6 +555,108 @@
     // NOP for MDP copybit
     return 0;
 }
+static int clear_copybit(struct copybit_device_t *dev,
+                         struct copybit_image_t const *buf,
+                         struct copybit_rect_t *rect)
+{
+    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    uint32_t color = 0; // black color
+
+    if (!ctx) {
+        ALOGE ("%s: Invalid copybit context", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    struct blitReq list1;
+    memset((char *)&list1 , 0 ,sizeof (struct blitReq) );
+    list1.count = 1;
+    int rel_fen_fd = -1;
+    int my_tmp_get_fence = -1;
+
+    list1.sync.rel_fen_fd  =  &my_tmp_get_fence;
+    mdp_blit_req* req = &list1.req[0];
+
+    if(!req) {
+        ALOGE ("%s : Invalid request", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    set_image(&req->dst, buf);
+    set_image(&req->src, buf);
+
+    if (rect->l < 0 || (uint32_t)(rect->r - rect->l) > req->dst.width ||
+       rect->t < 0 || (uint32_t)(rect->b - rect->t) > req->dst.height) {
+       ALOGE ("%s : Invalid rect : src_rect l %d t %d r %d b %d",\
+       __FUNCTION__, rect->l, rect->t, rect->r, rect->b);
+       return -EINVAL;
+    }
+
+    req->dst_rect.x  = rect->l;
+    req->dst_rect.y  = rect->t;
+    req->dst_rect.w  = rect->r - rect->l;
+    req->dst_rect.h  = rect->b - rect->t;
+
+    req->src_rect = req->dst_rect;
+
+    req->const_color.b = (uint32_t)((color >> 16) & 0xff);
+    req->const_color.g = (uint32_t)((color >> 8) & 0xff);
+    req->const_color.r = (uint32_t)((color >> 0) & 0xff);
+    req->const_color.alpha = MDP_ALPHA_NOP;
+
+    req->transp_mask = MDP_TRANSP_NOP;
+    req->flags = MDP_SOLID_FILL | MDP_MEMORY_ID_TYPE_FB | MDP_BLEND_FG_PREMULT;
+    int status = msm_copybit(ctx, &list1);
+
+    if (my_tmp_get_fence !=  -1)
+        close(my_tmp_get_fence);
+
+    return status;
+}
+
+/** Fill the rect on dst with RGBA color **/
+static int fill_color(struct copybit_device_t *dev,
+                      struct copybit_image_t const *dst,
+                      struct copybit_rect_t const *rect,
+                      uint32_t color)
+{
+    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    if (!ctx) {
+        ALOGE("%s: Invalid copybit context", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) {
+        ALOGE("%s: Invalid DST w=%d h=%d", __FUNCTION__, dst->w, dst->h);
+        return -EINVAL;
+    }
+
+    if (rect->l < 0 || (uint32_t)(rect->r - rect->l) > dst->w ||
+        rect->t < 0 || (uint32_t)(rect->b - rect->t) > dst->h) {
+        ALOGE("%s: Invalid destination rect: l=%d t=%d r=%d b=%d",
+                __FUNCTION__, rect->l, rect->t, rect->r, rect->b);
+        return -EINVAL;
+    }
+
+    struct blitReq* list = &ctx->list;
+    mdp_blit_req* req = &list->req[list->count++];
+    set_infos(ctx, req, MDP_SOLID_FILL);
+    set_image(&req->src, dst);
+    set_image(&req->dst, dst);
+
+    req->dst_rect.x = rect->l;
+    req->dst_rect.y = rect->t;
+    req->dst_rect.w = rect->r - rect->l;
+    req->dst_rect.h = rect->b - rect->t;
+    req->src_rect = req->dst_rect;
+
+    req->const_color.r = (uint32_t)((color >> 0) & 0xff);
+    req->const_color.g = (uint32_t)((color >> 8) & 0xff);
+    req->const_color.b = (uint32_t)((color >> 16) & 0xff);
+    req->const_color.alpha = (uint32_t)((color >> 24) & 0xff);
+
+    int status = msm_copybit(ctx, list);
+    return status;
+}
 
 /*****************************************************************************/
 
@@ -606,7 +708,9 @@
     ctx->device.set_sync = set_sync_copybit;
     ctx->device.stretch = stretch_copybit;
     ctx->device.finish = finish_copybit;
+    ctx->device.fill_color = fill_color;
     ctx->device.flush_get_fence = flush_get_fence;
+    ctx->device.clear = clear_copybit;
     ctx->mAlpha = MDP_ALPHA_NOP;
     ctx->mFlags = 0;
     ctx->sync.flags = 0;
diff --git a/libcopybit/copybit.h b/libcopybit/copybit.h
index 13d78b5..dbb89f0 100644
--- a/libcopybit/copybit.h
+++ b/libcopybit/copybit.h
@@ -242,6 +242,21 @@
                    struct copybit_rect_t const *src_rect,
                    struct copybit_region_t const *region);
 
+    /**
+     * Fill the rect on dst with RGBA color
+     *
+     * @param dev from open
+     * @param dst is destination image
+     * @param rect is destination rectangle
+     * @param color is RGBA color to fill
+     *
+     * @return 0 if successful
+     */
+    int (*fill_color)(struct copybit_device_t *dev,
+                      struct copybit_image_t const *dst,
+                      struct copybit_rect_t const *rect,
+                      uint32_t color);
+
   /**
     * Execute the completion of the copybit draw operation.
     *
diff --git a/libcopybit/copybit_c2d.cpp b/libcopybit/copybit_c2d.cpp
index 914bed7..231bb2d 100644
--- a/libcopybit/copybit_c2d.cpp
+++ b/libcopybit/copybit_c2d.cpp
@@ -1428,6 +1428,16 @@
     return status;
 }
 
+/** Fill the rect on dst with RGBA color **/
+static int fill_color(struct copybit_device_t *dev,
+                      struct copybit_image_t const *dst,
+                      struct copybit_rect_t const *rect,
+                      uint32_t color)
+{
+    // TODO: Implement once c2d driver supports color fill
+    return -EINVAL;
+}
+
 /*****************************************************************************/
 
 static void clean_up(copybit_context_t* ctx)
@@ -1561,6 +1571,7 @@
     ctx->device.finish = finish_copybit;
     ctx->device.flush_get_fence = flush_get_fence_copybit;
     ctx->device.clear = clear_copybit;
+    ctx->device.fill_color = fill_color;
 
     /* Create RGB Surface */
     surfDefinition.buffer = (void*)0xdddddddd;
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index b6952d3..d86be3e 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -484,6 +484,9 @@
     case HWC_FORMAT_RB_SWAP:
         value[0] = 1;
         break;
+    case HWC_COLOR_FILL:
+        value[0] = 1;
+        break;
     default:
         return -EINVAL;
     }
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 2068732..2104bff 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -2,8 +2,7 @@
  * Copyright (C) 2010 The Android Open Source Project
  * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
  *
- * Not a Contribution, Apache license notifications and license are retained
- * for attribution purposes only.
+ * Not a Contribution.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -25,7 +24,9 @@
 #include "hwc_copybit.h"
 #include "comptype.h"
 #include "gr.h"
+#include "cb_utils.h"
 
+using namespace qdutils;
 namespace qhwc {
 
 struct range {
@@ -127,20 +128,6 @@
     return renderArea;
 }
 
-bool checkNonWormholeRegion(private_handle_t* hnd, hwc_rect_t& rect)
-{
-    unsigned int height = rect.bottom - rect.top;
-    unsigned int width = rect.right - rect.left;
-    copybit_image_t buf;
-    buf.w = ALIGN(hnd->width, 32);
-    buf.h = hnd->height;
-
-    if (buf.h != height || buf.w != width)
-        return false;
-
-    return true;
-}
-
 bool CopyBit::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list,
                                                             int dpy) {
 
@@ -189,15 +176,6 @@
             if (layer->planeAlpha != 0xFF)
                 return true;
         }
-        /*
-         * Fallback to GPU in MDP3 when NonWormholeRegion is not of frame buffer
-         * size as artifact is seen in WormholeRegion of previous frame.
-         */
-        hwc_rect_t nonWormHoleRegion;
-        getNonWormholeRegion(list, nonWormHoleRegion);
-        if(!checkNonWormholeRegion(fbHnd, nonWormHoleRegion))
-           return true;
-
     }
 
     //Allocate render buffers if they're not allocated
@@ -270,23 +248,23 @@
 
     if (ctx->mMDP.version >= qdutils::MDP_V4_0) {
         //Wait for the previous frame to complete before rendering onto it
-        if(mRelFd[0] >=0) {
-            sync_wait(mRelFd[0], 1000);
-            close(mRelFd[0]);
-            mRelFd[0] = -1;
+        if(mRelFd[mCurRenderBufferIndex] >=0) {
+            sync_wait(mRelFd[mCurRenderBufferIndex], 1000);
+            close(mRelFd[mCurRenderBufferIndex]);
+            mRelFd[mCurRenderBufferIndex] = -1;
         }
-
-        //Clear the visible region on the render buffer
-        //XXX: Do this only when needed.
-        hwc_rect_t clearRegion;
-        getNonWormholeRegion(list, clearRegion);
-        clear(renderBuffer, clearRegion);
     } else {
-        if(mRelFd[0] >=0) {
+        if(mRelFd[mCurRenderBufferIndex] >=0) {
             copybit_device_t *copybit = getCopyBitDevice();
-            copybit->set_sync(copybit, mRelFd[0]);
+            copybit->set_sync(copybit, mRelFd[mCurRenderBufferIndex]);
         }
     }
+
+    //Clear the transparent or left out region on the render buffer
+    hwc_rect_t clearRegion = {0,0,0,0};
+    if(CBUtils::getuiClearRegion(list, clearRegion, layerProp))
+        clear(renderBuffer, clearRegion);
+
     // numAppLayers-1, as we iterate from 0th layer index with HWC_COPYBIT flag
     for (int i = 0; i <= (ctx->listStats[dpy].numAppLayers-1); i++) {
         hwc_layer_1_t *layer = &list->hwLayers[i];
@@ -338,6 +316,9 @@
 
     private_handle_t *hnd = (private_handle_t *)layer->handle;
     if(!hnd) {
+        if (layer->flags & HWC_COLOR_FILL) { // Color layer
+            return fillColorUsingCopybit(layer, renderBuffer);
+        }
         ALOGE("%s: invalid handle", __FUNCTION__);
         return -1;
     }
@@ -586,6 +567,44 @@
     return err;
 }
 
+int CopyBit::fillColorUsingCopybit(hwc_layer_1_t *layer,
+                          private_handle_t *renderBuffer)
+{
+    if (!renderBuffer) {
+        ALOGE("%s: Render Buffer is NULL", __FUNCTION__);
+        return -1;
+    }
+
+    // Copybit dst
+    copybit_image_t dst;
+    dst.w = ALIGN(renderBuffer->width, 32);
+    dst.h = renderBuffer->height;
+    dst.format = renderBuffer->format;
+    dst.base = (void *)renderBuffer->base;
+    dst.handle = (native_handle_t *)renderBuffer;
+
+    // Copybit dst rect
+    hwc_rect_t displayFrame = layer->displayFrame;
+    copybit_rect_t dstRect = {displayFrame.left, displayFrame.top,
+                              displayFrame.right, displayFrame.bottom};
+
+    uint32_t color = layer->transform;
+    copybit_device_t *copybit = mEngine;
+    copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_WIDTH,
+                           renderBuffer->width);
+    copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_HEIGHT,
+                           renderBuffer->height);
+    copybit->set_parameter(copybit, COPYBIT_DITHER,
+                           (dst.format == HAL_PIXEL_FORMAT_RGB_565) ?
+                           COPYBIT_ENABLE : COPYBIT_DISABLE);
+    copybit->set_parameter(copybit, COPYBIT_BLEND_MODE, layer->blending);
+    copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, layer->planeAlpha);
+    copybit->set_parameter(copybit, COPYBIT_BLIT_TO_FRAMEBUFFER,COPYBIT_ENABLE);
+    int res = copybit->fill_color(copybit, &dst, &dstRect, color);
+    copybit->set_parameter(copybit,COPYBIT_BLIT_TO_FRAMEBUFFER,COPYBIT_DISABLE);
+    return res;
+}
+
 void CopyBit::getLayerResolution(const hwc_layer_1_t* layer,
                                  unsigned int& width, unsigned int& height)
 {
@@ -630,6 +649,11 @@
 {
     for (int i = 0; i < NUM_RENDER_BUFFERS; i++) {
         if(mRenderBuffer[i]) {
+            //Since we are freeing buffer close the fence if it has a valid one.
+            if(mRelFd[i] >= 0) {
+                close(mRelFd[i]);
+                mRelFd[i] = -1;
+            }
             free_buffer(mRenderBuffer[i]);
             mRenderBuffer[i] = NULL;
         }
@@ -641,10 +665,9 @@
 }
 
 void CopyBit::setReleaseFd(int fd) {
-    if(mRelFd[0] >=0)
-        close(mRelFd[0]);
-    mRelFd[0] = mRelFd[1];
-    mRelFd[1] = dup(fd);
+    if(mRelFd[mCurRenderBufferIndex] >=0)
+        close(mRelFd[mCurRenderBufferIndex]);
+    mRelFd[mCurRenderBufferIndex] = dup(fd);
 }
 
 struct copybit_device_t* CopyBit::getCopyBitDevice() {
@@ -654,10 +677,10 @@
 CopyBit::CopyBit():mIsModeOn(false), mCopyBitDraw(false),
     mCurRenderBufferIndex(0){
     hw_module_t const *module;
-    for (int i = 0; i < NUM_RENDER_BUFFERS; i++)
+    for (int i = 0; i < NUM_RENDER_BUFFERS; i++) {
         mRenderBuffer[i] = NULL;
-    mRelFd[0] = -1;
-    mRelFd[1] = -1;
+        mRelFd[i] = -1;
+    }
 
     char value[PROPERTY_VALUE_MAX];
     property_get("debug.hwc.dynThreshold", value, "2");
@@ -675,10 +698,6 @@
 CopyBit::~CopyBit()
 {
     freeRenderBuffers();
-    if(mRelFd[0] >=0)
-        close(mRelFd[0]);
-    if(mRelFd[1] >=0)
-        close(mRelFd[1]);
     if(mEngine)
     {
         copybit_close(mEngine);
diff --git a/libhwcomposer/hwc_copybit.h b/libhwcomposer/hwc_copybit.h
index 03fe950..8278ff3 100644
--- a/libhwcomposer/hwc_copybit.h
+++ b/libhwcomposer/hwc_copybit.h
@@ -50,6 +50,8 @@
     // Helper functions for copybit composition
     int  drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
                           private_handle_t *renderBuffer, int dpy, bool isFG);
+    int fillColorUsingCopybit(hwc_layer_1_t *layer,
+                          private_handle_t *renderBuffer);
     bool canUseCopybitForYUV (hwc_context_t *ctx);
     bool canUseCopybitForRGB (hwc_context_t *ctx,
                                      hwc_display_contents_1_t *list, int dpy);
@@ -77,9 +79,8 @@
     // Index of the current intermediate render buffer
     int mCurRenderBufferIndex;
 
-    //These are the the release FDs of the T-2 and T-1 round
-    //We wait on the T-2 fence
-    int mRelFd[2];
+    // Release FDs of the intermediate render buffer
+    int mRelFd[NUM_RENDER_BUFFERS];
 
     //Dynamic composition threshold for deciding copybit usage.
     double mDynThreshold;
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index fff53ed..c93edcb 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -306,12 +306,6 @@
 
     hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
     hwc_rect_t dst = layer->displayFrame;
-
-    if(dst.left < 0 || dst.top < 0 || dst.right > hw_w || dst.bottom > hw_h) {
-       hwc_rect_t scissor = {0, 0, hw_w, hw_h };
-       qhwc::calculate_crop_rects(crop, dst, scissor, layer->transform);
-    }
-
     int crop_w = crop.right - crop.left;
     int crop_h = crop.bottom - crop.top;
     int dst_w = dst.right - dst.left;
@@ -407,6 +401,12 @@
     return ret;
 }
 
+/*
+ * 1) Identify layers that are not visible in the updating ROI and drop them
+ * from composition.
+ * 2) If we have a scaling layers which needs cropping against generated ROI.
+ * Reset ROI to full resolution.
+ */
 bool MDPComp::validateAndApplyROI(hwc_context_t *ctx,
                                hwc_display_contents_1_t* list, hwc_rect_t roi) {
     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
@@ -414,15 +414,22 @@
     if(!isValidRect(roi))
         return false;
 
-    for(int i = 0; i < numAppLayers; i++){
+    hwc_rect_t visibleRect = roi;
+
+    for(int i = numAppLayers - 1; i >= 0; i--){
+
+        if(!isValidRect(visibleRect)) {
+            mCurrentFrame.drop[i] = true;
+            mCurrentFrame.dropCount++;
+        }
+
         const hwc_layer_1_t* layer =  &list->hwLayers[i];
 
         hwc_rect_t dstRect = layer->displayFrame;
         hwc_rect_t srcRect = integerizeSourceCrop(layer->sourceCropf);
         int transform = layer->transform;
-        trimLayer(ctx, mDpy, transform, srcRect, dstRect);
 
-        hwc_rect_t res  = getIntersection(roi, dstRect);
+        hwc_rect_t res  = getIntersection(visibleRect, dstRect);
 
         int res_w = res.right - res.left;
         int res_h = res.bottom - res.top;
@@ -437,12 +444,15 @@
              * cropping */
             if((res_w != dst_w || res_h != dst_h) &&
                needsScaling (ctx, layer, mDpy)) {
-                ALOGE("%s: Resetting ROI due to scaling", __FUNCTION__);
+                ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
                 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
                 mCurrentFrame.dropCount = 0;
                 return false;
             }
         }
+
+        if (layer->blending == HWC_BLENDING_NONE)
+            visibleRect = deductRect(visibleRect, res);
     }
     return true;
 }
@@ -461,6 +471,9 @@
         return;
     }
 
+    if(isSkipPresent(ctx, mDpy))
+        return;
+
     if(list->flags & HWC_GEOMETRY_CHANGED)
         return;
 
@@ -474,7 +487,6 @@
             int transform = list->hwLayers[index].transform;
 
             /* Intersect against display boundaries */
-            trimLayer(ctx, mDpy, transform, srcRect, dstRect);
             roi = getUnion(roi, dstRect);
         }
     }
@@ -749,6 +761,12 @@
         return false;
     }
 
+    /* Bail out if we are processing only secured video layers
+     * and we dont have any */
+    if(!isSecurePresent(ctx, mDpy) && secureOnly){
+        return false;
+    }
+
     if(!mdpCount)
         return false;
 
@@ -1100,7 +1118,6 @@
             if (hnd) {
                 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
                 hwc_rect_t dst = layer->displayFrame;
-                trimLayer(ctx, mDpy, layer->transform, crop, dst);
                 float bpp = ((float)hnd->size) / (hnd->width * hnd->height);
                 size += bpp * (crop.right - crop.left) *
                     (crop.bottom - crop.top) *
@@ -1146,7 +1163,7 @@
     //do not cache the information for next draw cycle.
     if(numLayers > MAX_NUM_APP_LAYERS) {
         mCachedFrame.updateCounts(mCurrentFrame);
-        ALOGE("%s: Number of App layers exceeded the limit ",
+        ALOGI("%s: Number of App layers exceeded the limit ",
         __FUNCTION__);
         ret = -1;
         return ret;
@@ -1222,10 +1239,11 @@
         }
     } else {
         reset(numLayers, list);
+        memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
+        mCurrentFrame.dropCount = 0;
         ret = -1;
         goto exit;
     }
-
     //UpdateLayerFlags
     setMDPCompLayerFlags(ctx, list);
     mCachedFrame.cacheAll(list);
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index 926f425..5cb87f8 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -92,7 +92,7 @@
         while(((iter_str - strUdata) <= len) && (*iter_str)) {
             char* pstr = strstr(iter_str, "PANEL_ALIVE=0");
             if (pstr != NULL) {
-                ALOGE("%s: got change event in fb0 with PANEL_ALIVE=0",
+                ALOGI("%s: got change event in fb0 with PANEL_ALIVE=0",
                                                            __FUNCTION__);
                 ctx->mPanelResetStatus = true;
                 return true;
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index aa40223..f32ad34 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -612,7 +612,6 @@
 
     hwc_rect_t displayFrame  = layer->displayFrame;
     hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
-    trimLayer(ctx, dpy, layer->transform, sourceCrop, displayFrame);
 
     dst_w = displayFrame.right - displayFrame.left;
     dst_h = displayFrame.bottom - displayFrame.top;
@@ -640,7 +639,6 @@
     hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
     hwc_rect_t displayFrame  = layer->displayFrame;
     private_handle_t *hnd = (private_handle_t *)layer->handle;
-    trimLayer(ctx, dpy, layer->transform, sourceCrop, displayFrame);
 
     cropL = sourceCrop;
     dstL = displayFrame;
@@ -701,8 +699,35 @@
     return false;
 }
 
+static void trimLayer(hwc_context_t *ctx, const int& dpy, const int& transform,
+        hwc_rect_t& crop, hwc_rect_t& dst) {
+    int hw_w = ctx->dpyAttr[dpy].xres;
+    int hw_h = ctx->dpyAttr[dpy].yres;
+    if(dst.left < 0 || dst.top < 0 ||
+            dst.right > hw_w || dst.bottom > hw_h) {
+        hwc_rect_t scissor = {0, 0, hw_w, hw_h };
+        qhwc::calculate_crop_rects(crop, dst, scissor, transform);
+    }
+}
+
+static void trimList(hwc_context_t *ctx, hwc_display_contents_1_t *list,
+        const int& dpy) {
+    for(uint32_t i = 0; i < list->numHwLayers - 1; i++) {
+        hwc_layer_1_t *layer = &list->hwLayers[i];
+        hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
+        trimLayer(ctx, dpy,
+                list->hwLayers[i].transform,
+                (hwc_rect_t&)crop,
+                (hwc_rect_t&)list->hwLayers[i].displayFrame);
+        layer->sourceCropf.left = crop.left;
+        layer->sourceCropf.right = crop.right;
+        layer->sourceCropf.top = crop.top;
+        layer->sourceCropf.bottom = crop.bottom;
+    }
+}
+
 void setListStats(hwc_context_t *ctx,
-        const hwc_display_contents_1_t *list, int dpy) {
+        hwc_display_contents_1_t *list, int dpy) {
     const int prevYuvCount = ctx->listStats[dpy].yuvCount;
     memset(&ctx->listStats[dpy], 0, sizeof(ListStats));
     ctx->listStats[dpy].numAppLayers = list->numHwLayers - 1;
@@ -719,6 +744,7 @@
                       (int)ctx->dpyAttr[dpy].xres, (int)ctx->dpyAttr[dpy].yres);
     ctx->listStats[dpy].secureUI = false;
 
+    trimList(ctx, list, dpy);
     optimizeLayerRects(ctx, list, dpy);
 
     for (size_t i = 0; i < (size_t)ctx->listStats[dpy].numAppLayers; i++) {
@@ -988,36 +1014,25 @@
    return res;
 }
 
-/* deducts given rect from layers display-frame and source crop.
-   also it avoid hole creation.*/
-void deductRect(const hwc_layer_1_t* layer, hwc_rect_t& irect) {
-    hwc_rect_t& disprect = (hwc_rect_t&)layer->displayFrame;
-    hwc_rect_t srcrect = integerizeSourceCrop(layer->sourceCropf);
-    int irect_w = irect.right - irect.left;
-    int irect_h = irect.bottom - irect.top;
+/* Not a geometrical rect deduction. Deducts rect2 from rect1 only if it results
+ * a single rect */
+hwc_rect_t deductRect(const hwc_rect_t& rect1, const hwc_rect_t& rect2) {
 
-    if((disprect.left == irect.left) && (disprect.right == irect.right)) {
-        if((disprect.top == irect.top) && (irect.bottom <= disprect.bottom)) {
-            disprect.top = irect.bottom;
-            srcrect.top += irect_h;
-        }
-        else if((disprect.bottom == irect.bottom)
-                                && (irect.top >= disprect.top)) {
-            disprect.bottom = irect.top;
-            srcrect.bottom -= irect_h;
-        }
-    }
-    else if((disprect.top == irect.top) && (disprect.bottom == irect.bottom)) {
-        if((disprect.left == irect.left) && (irect.right <= disprect.right)) {
-            disprect.left = irect.right;
-            srcrect.left += irect_w;
-        }
-        else if((disprect.right == irect.right)
-                                && (irect.left >= disprect.left)) {
-            disprect.right = irect.left;
-            srcrect.right -= irect_w;
-        }
-    }
+   hwc_rect_t res = rect1;
+
+   if((rect1.left == rect2.left) && (rect1.right == rect2.right)) {
+      if((rect1.top == rect2.top) && (rect2.bottom <= rect1.bottom))
+         res.top = rect2.bottom;
+      else if((rect1.bottom == rect2.bottom)&& (rect2.top >= rect1.top))
+         res.bottom = rect2.top;
+   }
+   else if((rect1.top == rect2.top) && (rect1.bottom == rect2.bottom)) {
+      if((rect1.left == rect2.left) && (rect2.right <= rect1.right))
+         res.left = rect2.right;
+      else if((rect1.right == rect2.right)&& (rect2.left >= rect1.left))
+         res.right = rect2.left;
+   }
+   return res;
 }
 
 void optimizeLayerRects(hwc_context_t *ctx,
@@ -1033,17 +1048,22 @@
             hwc_rect_t& topframe =
                 (hwc_rect_t&)list->hwLayers[i].displayFrame;
             while(j >= 0) {
-                if(!needsScaling(ctx, &list->hwLayers[j], dpy)) {
-                    hwc_rect_t& bottomframe =
-                        (hwc_rect_t&)list->hwLayers[j].displayFrame;
+               if(!needsScaling(ctx, &list->hwLayers[j], dpy)) {
+                  hwc_layer_1_t* layer = (hwc_layer_1_t*)&list->hwLayers[j];
+                  hwc_rect_t& bottomframe = layer->displayFrame;
+                  hwc_rect_t& bottomCrop = layer->sourceCrop;
+                  int transform =layer->transform;
 
-                    hwc_rect_t irect = getIntersection(bottomframe, topframe);
-                    if(isValidRect(irect)) {
-                        //if intersection is valid rect, deduct it
-                        deductRect(&list->hwLayers[j], irect);
-                    }
-                }
-                j--;
+                  hwc_rect_t irect = getIntersection(bottomframe, topframe);
+                  if(isValidRect(irect)) {
+                     //if intersection is valid rect, deduct it
+                     bottomframe = deductRect(bottomframe, irect);
+                     qhwc::calculate_crop_rects(bottomCrop, bottomframe,
+                                                bottomframe, transform);
+
+                  }
+               }
+               j--;
             }
         }
         i--;
@@ -1229,17 +1249,6 @@
     return ret;
 }
 
-void trimLayer(hwc_context_t *ctx, const int& dpy, const int& transform,
-        hwc_rect_t& crop, hwc_rect_t& dst) {
-    int hw_w = ctx->dpyAttr[dpy].xres;
-    int hw_h = ctx->dpyAttr[dpy].yres;
-    if(dst.left < 0 || dst.top < 0 ||
-            dst.right > hw_w || dst.bottom > hw_h) {
-        hwc_rect_t scissor = {0, 0, hw_w, hw_h };
-        qhwc::calculate_crop_rects(crop, dst, scissor, transform);
-    }
-}
-
 void setMdpFlags(hwc_layer_1_t *layer,
         ovutils::eMdpFlags &mdpFlags,
         int rotDownscale, int transform) {
@@ -1448,7 +1457,6 @@
     }
 
     setMdpFlags(layer, mdpFlags, downscale, transform);
-    trimLayer(ctx, dpy, transform, crop, dst);
 
     if(isYuvBuffer(hnd) && //if 90 component or downscale, use rot
             ((transform & HWC_TRANSFORM_ROT_90) || downscale)) {
@@ -1565,7 +1573,6 @@
         }
     }
 
-
     setMdpFlags(layer, mdpFlagsL, 0, transform);
 
     if(lDest != OV_INVALID && rDest != OV_INVALID) {
@@ -1573,8 +1580,6 @@
         setMdpFlags(mdpFlagsL, OV_MDSS_MDP_DUAL_PIPE);
     }
 
-    trimLayer(ctx, dpy, transform, crop, dst);
-
     //Will do something only if feature enabled and conditions suitable
     //hollow call otherwise
     if(ctx->mAD->prepare(ctx, crop, whf, hnd)) {
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 93d65c5..66a02d6 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -131,6 +131,7 @@
 
 // HAL specific features
 enum {
+    HWC_COLOR_FILL = 0x00000008,
     HWC_FORMAT_RB_SWAP = 0x00000040,
 };
 
@@ -186,7 +187,7 @@
 // -----------------------------------------------------------------------------
 // Utility functions - implemented in hwc_utils.cpp
 void dumpLayer(hwc_layer_1_t const* l);
-void setListStats(hwc_context_t *ctx, const hwc_display_contents_1_t *list,
+void setListStats(hwc_context_t *ctx, hwc_display_contents_1_t *list,
         int dpy);
 void initContext(hwc_context_t *ctx);
 void closeContext(hwc_context_t *ctx);
@@ -213,7 +214,7 @@
 
 int getExtOrientation(hwc_context_t* ctx);
 bool isValidRect(const hwc_rect_t& rect);
-void deductRect(const hwc_layer_1_t* layer, hwc_rect_t& irect);
+hwc_rect_t deductRect(const hwc_rect_t& rect1, const hwc_rect_t& rect2);
 hwc_rect_t getIntersection(const hwc_rect_t& rect1, const hwc_rect_t& rect2);
 hwc_rect_t getUnion(const hwc_rect_t& rect1, const hwc_rect_t& rect2);
 void optimizeLayerRects(hwc_context_t *ctx,
@@ -253,10 +254,6 @@
 int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy,
         int fd);
 
-//Trims a layer's source crop which is outside of screen boundary.
-void trimLayer(hwc_context_t *ctx, const int& dpy, const int& transform,
-        hwc_rect_t& crop, hwc_rect_t& dst);
-
 //Sets appropriate mdp flags for a layer.
 void setMdpFlags(hwc_layer_1_t *layer,
         ovutils::eMdpFlags &mdpFlags,
diff --git a/libmemtrack/memtrack_msm.h b/libmemtrack/memtrack_msm.h
index ff2db3c..74aa576 100644
--- a/libmemtrack/memtrack_msm.h
+++ b/libmemtrack/memtrack_msm.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef _MEMTRACK_QCOM_H_
-#define _MEMTRACK_QCOM_H_
+#ifndef _MEMTRACK_MSM_H_
+#define _MEMTRACK_MSM_H_
 
 int kgsl_memtrack_get_memory(pid_t pid, enum memtrack_type type,
                              struct memtrack_record *records,
diff --git a/libqdutils/Android.mk b/libqdutils/Android.mk
index b6bbc47..d514405 100644
--- a/libqdutils/Android.mk
+++ b/libqdutils/Android.mk
@@ -4,13 +4,14 @@
 
 LOCAL_MODULE                  := libqdutils
 LOCAL_MODULE_TAGS             := optional
-LOCAL_SHARED_LIBRARIES        := $(common_libs)
+LOCAL_SHARED_LIBRARIES        := $(common_libs) libui
 LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes)
 LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdutils\"
 LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
 LOCAL_SRC_FILES               := profiler.cpp mdp_version.cpp \
                                  idle_invalidator.cpp \
-                                 comptype.cpp qd_utils.cpp
+                                 comptype.cpp qd_utils.cpp \
+                                 cb_utils.cpp
 include $(BUILD_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
diff --git a/libqdutils/cb_utils.cpp b/libqdutils/cb_utils.cpp
new file mode 100644
index 0000000..bc7e5b1
--- /dev/null
+++ b/libqdutils/cb_utils.cpp
@@ -0,0 +1,79 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+* Redistribution and use in source and binary forms, with or without
+* * modification, are permitted provided that the following conditions are
+* met:
+*   * Redistributions of source code must retain the above copyrigh
+*     notice, this list of conditions and the following disclaimer
+*   * Redistributions in binary form must reproduce the above
+*     copyright notice, this list of conditions and the following
+*     disclaimer in the documentation and/or other materials provided
+*     with the distribution.
+*   * Neither the name of The Linux Foundation nor the names of its
+*     contributors may be used to endorse or promote products derived
+*     from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "cb_utils.h"
+
+/* get union of two rects into 3rd rect */
+void getUnion(hwc_rect_t& rect1,hwc_rect_t& rect2, hwc_rect_t& irect) {
+    irect.left   = min(rect1.left, rect2.left);
+    irect.top    = min(rect1.top, rect2.top);
+    irect.right  = max(rect1.right, rect2.right);
+    irect.bottom = max(rect1.bottom, rect2.bottom);
+}
+
+using namespace android;
+using namespace qhwc;
+namespace qdutils {
+
+int CBUtils::getuiClearRegion(hwc_display_contents_1_t* list,
+          hwc_rect_t &clearWormholeRect, LayerProp *layerProp) {
+
+    uint32_t last = list->numHwLayers - 1;
+    hwc_rect_t fbFrame = list->hwLayers[last].displayFrame;
+
+    Rect fbFrameRect(fbFrame.left,fbFrame.top,fbFrame.right,fbFrame.bottom);
+    Region wormholeRegion(fbFrameRect);
+
+    for (uint32_t i = 0 ; i < last; i++) {
+        // need to take care only in per pixel blending.
+        // Restrict calculation only for copybit layers.
+        if((list->hwLayers[i].blending != HWC_BLENDING_NONE) ||
+           !(layerProp[i].mFlags & HWC_COPYBIT))
+            continue ;
+        hwc_rect_t displayFrame = list->hwLayers[i].displayFrame;
+        Rect tmpRect(displayFrame.left,displayFrame.top,displayFrame.right,
+        displayFrame.bottom);
+        Region tmpRegion(tmpRect);
+        wormholeRegion.subtractSelf(wormholeRegion.intersect(tmpRegion));
+    }
+    if (wormholeRegion.isEmpty()) {
+        return 0;
+    }
+    //TO DO :- 1. remove union and call clear for each rect.
+    //      :- 2. support swap ract feature.
+    Region::const_iterator it = wormholeRegion.begin();
+    Region::const_iterator const end = wormholeRegion.end();
+    while (it != end) {
+        const Rect& r = *it++;
+        hwc_rect_t tmpWormRect = {r.left,r.top,r.right,r.bottom};
+        getUnion(clearWormholeRect, tmpWormRect, clearWormholeRect);
+
+    }
+    return 1;
+}
+
+}//namespace qdutils
diff --git a/libqdutils/cb_utils.h b/libqdutils/cb_utils.h
new file mode 100644
index 0000000..85dd78f
--- /dev/null
+++ b/libqdutils/cb_utils.h
@@ -0,0 +1,45 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+* Redistribution and use in source and binary forms, with or without
+* * modification, are permitted provided that the following conditions are
+* met:
+*   * Redistributions of source code must retain the above copyrigh
+*     notice, this list of conditions and the following disclaimer
+*   * Redistributions in binary form must reproduce the above
+*     copyright notice, this list of conditions and the following
+*     disclaimer in the documentation and/or other materials provided
+*     with the distribution.
+*   * Neither the name of The Linux Foundation nor the names of its
+*     contributors may be used to endorse or promote products derived
+*     from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#ifndef CB_UTIL_H
+#define CB_UTIL_H
+
+#include <ui/Region.h>
+#include "hwc_utils.h"
+
+using namespace qhwc;
+namespace qdutils {
+class CBUtils {
+public:
+static int getuiClearRegion(hwc_display_contents_1_t* list,
+                              hwc_rect_t &clearWormholeRec,
+                                      LayerProp *layerProp);
+};
+}//namespace qdutils
+#endif /* end of include guard: CB_UTIL_H*/
+