Merge "hwc: Add MetaData support in overlay path."
diff --git a/libcopybit/copybit.h b/libcopybit/copybit.h
index d57b84d..07593f3 100644
--- a/libcopybit/copybit.h
+++ b/libcopybit/copybit.h
@@ -250,6 +250,11 @@
     * @return 0 if successful
     */
   int (*flush_get_fence)(struct copybit_device_t *dev, int* fd);
+
+  /* Clears the buffer
+   */
+  int (*clear)(struct copybit_device_t *dev, struct copybit_image_t const *buf,
+               struct copybit_rect_t *rect);
 };
 
 
diff --git a/libcopybit/copybit_c2d.cpp b/libcopybit/copybit_c2d.cpp
index c186242..efbd350 100644
--- a/libcopybit/copybit_c2d.cpp
+++ b/libcopybit/copybit_c2d.cpp
@@ -90,6 +90,10 @@
 /* create a fence fd for the timestamp */
 C2D_STATUS (*LINK_c2dCreateFenceFD) ( uint32 target_id, c2d_ts_handle timestamp,
                                                             int32 *fd);
+
+C2D_STATUS (*LINK_c2dFillSurface) ( uint32 surface_id, uint32 fill_color,
+                                    C2D_RECT * fill_rect);
+
 /******************************************************************************/
 
 #if defined(COPYBIT_Z180)
@@ -674,6 +678,28 @@
     return status;
 }
 
+static int clear_copybit(struct copybit_device_t *dev,
+                         struct copybit_image_t const *buf,
+                         struct copybit_rect_t *rect)
+{
+    int ret = 0;
+    int flags = FLAGS_PREMULTIPLIED_ALPHA;
+    int mapped_dst_idx = -1;
+    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    C2D_RECT c2drect = {rect->l, rect->t, rect->r - rect->l, rect->b - rect->t};
+    ret = set_image(ctx, ctx->dst[RGB_SURFACE], buf,
+                       (eC2DFlags)flags, mapped_dst_idx);
+    if(ret) {
+        ALOGE("%s: set_image error", __FUNCTION__);
+        unmap_gpuaddr(ctx, mapped_dst_idx);
+        return COPYBIT_FAILURE;
+    }
+
+    ret = LINK_c2dFillSurface(ctx->dst[RGB_SURFACE], 0x0, &c2drect);
+    return ret;
+}
+
+
 /** setup rectangles */
 static void set_rects(struct copybit_context_t *ctx,
                       C2D_OBJECT *c2dObject,
@@ -1258,8 +1284,7 @@
         return COPYBIT_FAILURE;
     }
 
-    src_surface.config_mask = C2D_NO_BILINEAR_BIT | C2D_NO_ANTIALIASING_BIT |
-                              ctx->config_mask;
+    src_surface.config_mask = C2D_NO_ANTIALIASING_BIT | ctx->config_mask;
     src_surface.global_alpha = ctx->src_global_alpha;
     if (enableBlend) {
         if(src_surface.config_mask & C2D_GLOBAL_ALPHA_BIT) {
@@ -1272,12 +1297,6 @@
                 unmap_gpuaddr(ctx, mapped_src_idx);
                 return COPYBIT_FAILURE;
             }
-        } else {
-            int c2d_format = get_format(src->format);
-            if(is_alpha(c2d_format))
-                src_surface.config_mask &= ~C2D_ALPHA_BLEND_NONE;
-            else
-                src_surface.config_mask |= C2D_ALPHA_BLEND_NONE;
         }
     } else {
         src_surface.config_mask |= C2D_ALPHA_BLEND_NONE;
@@ -1476,11 +1495,14 @@
                                            "c2dGetDriverCapabilities");
     *(void **)&LINK_c2dCreateFenceFD = ::dlsym(ctx->libc2d2,
                                            "c2dCreateFenceFD");
+    *(void **)&LINK_c2dFillSurface = ::dlsym(ctx->libc2d2,
+                                           "c2dFillSurface");
 
     if (!LINK_c2dCreateSurface || !LINK_c2dUpdateSurface || !LINK_c2dReadSurface
         || !LINK_c2dDraw || !LINK_c2dFlush || !LINK_c2dWaitTimestamp ||
         !LINK_c2dFinish  || !LINK_c2dDestroySurface ||
-        !LINK_c2dGetDriverCapabilities || !LINK_c2dCreateFenceFD) {
+        !LINK_c2dGetDriverCapabilities || !LINK_c2dCreateFenceFD ||
+        !LINK_c2dFillSurface) {
         ALOGE("%s: dlsym ERROR", __FUNCTION__);
         clean_up(ctx);
         status = COPYBIT_FAILURE;
@@ -1498,6 +1520,7 @@
     ctx->device.stretch = stretch_copybit;
     ctx->device.finish = finish_copybit;
     ctx->device.flush_get_fence = flush_get_fence_copybit;
+    ctx->device.clear = clear_copybit;
 
     /* Create RGB Surface */
     surfDefinition.buffer = (void*)0xdddddddd;
diff --git a/libexternal/external.cpp b/libexternal/external.cpp
index 3f13906..af28bce 100644
--- a/libexternal/external.cpp
+++ b/libexternal/external.cpp
@@ -174,6 +174,10 @@
     memset(&mVInfo, 0, sizeof(mVInfo));
     //Determine the fb index for external display devices.
     updateExtDispDevFbIndex();
+    // disable HPD at start, it will be enabled later
+    // when the display powers on
+    // This helps for framework reboot or adb shell stop/start
+    writeHPDOption(0);
 
 }
 
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 9af52c9..c697cf8 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -175,7 +175,6 @@
 {
     int ionFlags = 0;
     int ret;
-    bool noncontig = false;
 
     data.uncached = useUncached(usage);
     data.allocType = 0;
@@ -183,24 +182,33 @@
     if(usage & GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP)
         ionFlags |= ION_HEAP(ION_SF_HEAP_ID);
 
-    if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP) {
+    if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP)
         ionFlags |= ION_HEAP(ION_SYSTEM_HEAP_ID);
-        noncontig = true;
-    }
 
-    if(usage & GRALLOC_USAGE_PRIVATE_IOMMU_HEAP) {
+    if(usage & GRALLOC_USAGE_PRIVATE_IOMMU_HEAP)
         ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
-        noncontig = true;
-    }
 
-    if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP)
-        ionFlags |= ION_HEAP(ION_CP_MM_HEAP_ID);
+    //MM Heap is exclusively a secure heap.
+    if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
+        //XXX: Right now the MM heap is the only secure heap we have. When we
+        //have other secure heaps, we can change this.
+        if(usage & GRALLOC_USAGE_PROTECTED) {
+            ionFlags |= ION_HEAP(ION_CP_MM_HEAP_ID);
+            ionFlags |= ION_SECURE;
+        }
+        else {
+            ALOGW("GRALLOC_USAGE_PRIVATE_MM_HEAP \
+                  cannot be used as an insecure heap!\
+                  trying to use IOMMU instead !!");
+            ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
+        }
+    }
 
     if(usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP)
         ionFlags |= ION_HEAP(ION_ADSP_HEAP_ID);
 
-    if(usage & GRALLOC_USAGE_PROTECTED && !noncontig)
-        ionFlags |= ION_SECURE;
+    if(usage & GRALLOC_USAGE_PROTECTED)
+         data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
 
     // if no flags are set, default to
     // SF + IOMMU heaps, so that bypass can work
@@ -218,16 +226,11 @@
     {
         ALOGW("Falling back to system heap");
         data.flags = ION_HEAP(ION_SYSTEM_HEAP_ID);
-        noncontig = true;
         ret = mIonAlloc->alloc_buffer(data);
     }
 
     if(ret >= 0 ) {
         data.allocType |= private_handle_t::PRIV_FLAGS_USES_ION;
-        if(noncontig)
-            data.allocType |= private_handle_t::PRIV_FLAGS_NONCONTIGUOUS_MEM;
-        if(ionFlags & ION_SECURE)
-            data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
     }
 
     return ret;
@@ -280,8 +283,6 @@
             size += ALIGN( alignedw * ALIGN(height/2, 32), 8192);
             break;
         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
-        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
-        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
         case HAL_PIXEL_FORMAT_YV12:
             if ((format == HAL_PIXEL_FORMAT_YV12) && ((width&1) || (height&1))) {
                 ALOGE("w or h is odd for the YV12 format");
@@ -298,6 +299,11 @@
             }
             size = ALIGN(size, 4096);
             break;
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+            alignedh = height;
+            size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2, 4096);
+            break;
         case HAL_PIXEL_FORMAT_YCbCr_422_SP:
         case HAL_PIXEL_FORMAT_YCrCb_422_SP:
             if(width & 1) {
diff --git a/libgralloc/framebuffer.cpp b/libgralloc/framebuffer.cpp
index 0335f5e..d95b376 100644
--- a/libgralloc/framebuffer.cpp
+++ b/libgralloc/framebuffer.cpp
@@ -87,8 +87,8 @@
     private_module_t* m =
         reinterpret_cast<private_module_t*>(dev->common.module);
     struct mdp_display_commit prim_commit;
-    prim_commit.wait_for_finish = 1;
     memset(&prim_commit, 0, sizeof(struct mdp_display_commit));
+    prim_commit.wait_for_finish = 1;
     if (ioctl(m->framebuffer->fd, MSMFB_DISPLAY_COMMIT, &prim_commit) == -1) {
         ALOGE("%s: MSMFB_DISPLAY_COMMIT for primary failed, str: %s",
                 __FUNCTION__, strerror(errno));
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index 8b9a6c5..628494b 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -174,7 +174,7 @@
 
     if ((ssize_t)size <= 0)
         return -EINVAL;
-    size = (bufferSize != 0)? bufferSize : size;
+    size = (bufferSize >= size)? bufferSize : size;
 
     // All buffers marked as protected or for external
     // display need to go to overlay
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index 268630b..9c97aae 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -313,6 +313,7 @@
                 res = 0;
             }
             break;
+#endif
         case GRALLOC_MODULE_PERFORM_GET_STRIDE:
             {
                 int width   = va_arg(args, int);
@@ -321,7 +322,6 @@
                 *stride = AdrenoMemInfo::getInstance().getStride(width, format);
                 res = 0;
             } break;
-#endif
         default:
             break;
     }
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index 540040a..bc705ac 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -108,17 +108,12 @@
 }
 
 //clear prev layer prop flags and realloc for current frame
-static void reset_layer_prop(hwc_context_t* ctx, int dpy) {
-    int layer_count = ctx->listStats[dpy].numAppLayers;
-
+static void reset_layer_prop(hwc_context_t* ctx, int dpy, int numAppLayers) {
     if(ctx->layerProp[dpy]) {
        delete[] ctx->layerProp[dpy];
        ctx->layerProp[dpy] = NULL;
     }
-
-    if(layer_count) {
-       ctx->layerProp[dpy] = new LayerProp[layer_count];
-    }
+    ctx->layerProp[dpy] = new LayerProp[numAppLayers];
 }
 
 static int display_commit(hwc_context_t *ctx, int dpy) {
@@ -136,23 +131,27 @@
         hwc_display_contents_1_t *list) {
     hwc_context_t* ctx = (hwc_context_t*)(dev);
     const int dpy = HWC_DISPLAY_PRIMARY;
-    if (LIKELY(list && list->numHwLayers > 1 &&
-        list->numHwLayers <= MAX_NUM_LAYERS) && ctx->dpyAttr[dpy].isActive) {
+    if (LIKELY(list && list->numHwLayers > 1) &&
+            ctx->dpyAttr[dpy].isActive) {
+        reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
         uint32_t last = list->numHwLayers - 1;
         hwc_layer_1_t *fbLayer = &list->hwLayers[last];
         if(fbLayer->handle) {
+            if(list->numHwLayers > MAX_NUM_LAYERS) {
+                ctx->mFBUpdate[dpy]->prepare(ctx, list);
+                return 0;
+            }
             setListStats(ctx, list, dpy);
-            reset_layer_prop(ctx, dpy);
-            int ret = ctx->mMDPComp->prepare(ctx, list);
+            bool ret = ctx->mMDPComp->prepare(ctx, list);
             if(!ret) {
                 // IF MDPcomp fails use this route
                 ctx->mVidOv[dpy]->prepare(ctx, list);
                 ctx->mFBUpdate[dpy]->prepare(ctx, list);
+                // Use Copybit, when MDP comp fails
+                if(ctx->mCopyBit[dpy])
+                    ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
+                ctx->mLayerCache[dpy]->updateLayerCache(list);
             }
-            ctx->mLayerCache[dpy]->updateLayerCache(list);
-            // Use Copybit, when MDP comp fails
-            if(!ret && ctx->mCopyBit[dpy])
-                ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
         }
     }
     return 0;
@@ -162,22 +161,25 @@
         hwc_display_contents_1_t *list, int dpy) {
     hwc_context_t* ctx = (hwc_context_t*)(dev);
 
-    if (LIKELY(list && list->numHwLayers > 1 &&
-        list->numHwLayers <= MAX_NUM_LAYERS) &&
-        ctx->dpyAttr[dpy].isActive &&
-        ctx->dpyAttr[dpy].connected) {
+    if (LIKELY(list && list->numHwLayers > 1) &&
+            ctx->dpyAttr[dpy].isActive &&
+            ctx->dpyAttr[dpy].connected) {
+        reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
         uint32_t last = list->numHwLayers - 1;
+        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
         if(!ctx->dpyAttr[dpy].isPause) {
-            hwc_layer_1_t *fbLayer = &list->hwLayers[last];
             if(fbLayer->handle) {
+                ctx->mExtDispConfiguring = false;
+                if(list->numHwLayers > MAX_NUM_LAYERS) {
+                    ctx->mFBUpdate[dpy]->prepare(ctx, list);
+                    return 0;
+                }
                 setListStats(ctx, list, dpy);
-                reset_layer_prop(ctx, dpy);
                 ctx->mVidOv[dpy]->prepare(ctx, list);
                 ctx->mFBUpdate[dpy]->prepare(ctx, list);
                 ctx->mLayerCache[dpy]->updateLayerCache(list);
                 if(ctx->mCopyBit[dpy])
                     ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
-                ctx->mExtDispConfiguring = false;
             }
         } else {
             // External Display is in Pause state.
@@ -200,6 +202,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];
@@ -361,19 +364,15 @@
 
         //TODO We dont check for SKIP flag on this layer because we need PAN
         //always. Last layer is always FB
-        private_handle_t *hnd = NULL;
+        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
         if(copybitDone) {
             hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
-        } else {
-            hnd = (private_handle_t *)fbLayer->handle;
         }
-        if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET && hnd) {
-            if(!(fbLayer->flags & HWC_SKIP_LAYER) &&
-                (list->numHwLayers > 1)) {
-                if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
-                    ALOGE("%s: FBUpdate draw failed", __FUNCTION__);
-                    ret = -1;
-                }
+
+        if(hnd) {
+            if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
+                ALOGE("%s: FBUpdate draw failed", __FUNCTION__);
+                ret = -1;
             }
         }
 
@@ -412,16 +411,12 @@
             ret = -1;
         }
 
-        private_handle_t *hnd = NULL;
+        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
         if(copybitDone) {
             hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
-        } else {
-            hnd = (private_handle_t *)fbLayer->handle;
         }
 
-        if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET &&
-                !(fbLayer->flags & HWC_SKIP_LAYER) && hnd &&
-                (list->numHwLayers > 1)) {
+        if(hnd) {
             if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
                 ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
                 ret = -1;
@@ -430,7 +425,7 @@
 
         if (display_commit(ctx, dpy) < 0) {
             ALOGE("%s: display commit fail!", __FUNCTION__);
-            return -1;
+            ret = -1;
         }
     }
 
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 4549dcf..3f40753 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -93,7 +93,7 @@
 
     if (compositionType & qdutils::COMPOSITION_TYPE_DYN) {
         // DYN Composition:
-        // use copybit, if (TotalRGBRenderArea < 2 * FB Area)
+        // use copybit, if (TotalRGBRenderArea < threashold * FB Area)
         // this is done based on perf inputs in ICS
         // TODO: Above condition needs to be re-evaluated in JB
         int fbWidth =  ctx->dpyAttr[dpy].xres;
@@ -102,7 +102,7 @@
         unsigned int renderArea = getRGBRenderingArea(list);
             ALOGD_IF (DEBUG_COPYBIT, "%s:renderArea %u, fbArea %u",
                                   __FUNCTION__, renderArea, fbArea);
-        if (renderArea <= (2 * fbArea)) {
+        if (renderArea < (mDynThreshold * fbArea)) {
             return true;
         }
     } else if ((compositionType & qdutils::COMPOSITION_TYPE_MDP)) {
@@ -201,6 +201,25 @@
     return true;
 }
 
+int CopyBit::clear (private_handle_t* hnd, hwc_rect_t& rect)
+{
+    int ret = 0;
+    copybit_rect_t clear_rect = {rect.left, rect.top,
+        rect.right,
+        rect.bottom};
+
+    copybit_image_t buf;
+    buf.w = ALIGN(hnd->width,32);
+    buf.h = hnd->height;
+    buf.format = hnd->format;
+    buf.base = (void *)hnd->base;
+    buf.handle = (native_handle_t *)hnd;
+
+    copybit_device_t *copybit = mEngine;
+    ret = copybit->clear(copybit, &buf, &clear_rect);
+    return ret;
+}
+
 bool CopyBit::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list,
                                                         int dpy, int32_t *fd) {
     // draw layers marked for COPYBIT
@@ -224,6 +243,12 @@
         close(mRelFd[0]);
         mRelFd[0] = -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);
     // 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];
@@ -529,6 +554,11 @@
         mRenderBuffer[i] = NULL;
     mRelFd[0] = -1;
     mRelFd[1] = -1;
+
+    char value[PROPERTY_VALUE_MAX];
+    property_get("debug.hwc.dynThreshold", value, "2");
+    mDynThreshold = atof(value);
+
     if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
         if(copybit_open(module, &mEngine) < 0) {
             ALOGE("FATAL ERROR: copybit open failed.");
diff --git a/libhwcomposer/hwc_copybit.h b/libhwcomposer/hwc_copybit.h
index 45d254a..a2d6405 100644
--- a/libhwcomposer/hwc_copybit.h
+++ b/libhwcomposer/hwc_copybit.h
@@ -70,6 +70,8 @@
 
     void freeRenderBuffers();
 
+    int clear (private_handle_t* hnd, hwc_rect_t& rect);
+
     private_handle_t* mRenderBuffer[NUM_RENDER_BUFFERS];
 
     // Index of the current intermediate render buffer
@@ -78,6 +80,9 @@
     //These are the the release FDs of the T-2 and T-1 round
     //We wait on the T-2 fence
     int mRelFd[2];
+
+    //Dynamic composition threshold for deciding copybit usage.
+    double mDynThreshold;
 };
 
 }; //namespace qhwc
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index f7fce09..a8ad8fe 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -66,10 +66,6 @@
     if (LIKELY(ctx->mOverlay)) {
         overlay::Overlay& ov = *(ctx->mOverlay);
         private_handle_t *hnd = (private_handle_t *)layer->handle;
-        if (!hnd) {
-            ALOGE("%s:NULL private handle for layer!", __FUNCTION__);
-            return false;
-        }
         ovutils::Whf info(hnd->width, hnd->height,
                 ovutils::getMdpFormat(hnd->format), hnd->size);
 
@@ -167,10 +163,6 @@
     if (LIKELY(ctx->mOverlay)) {
         overlay::Overlay& ov = *(ctx->mOverlay);
         private_handle_t *hnd = (private_handle_t *)layer->handle;
-        if (!hnd) {
-            ALOGE("%s:NULL private handle for layer!", __FUNCTION__);
-            return false;
-        }
         ovutils::Whf info(hnd->width, hnd->height,
                 ovutils::getMdpFormat(hnd->format), hnd->size);
 
@@ -228,12 +220,16 @@
         hwc_rect_t displayFrame = sourceCrop;
         //For FB left, top will always be 0
         //That should also be the case if using 2 mixers for single display
-        ovutils::Dim dpos(displayFrame.left,
+        ovutils::Dim dposL(displayFrame.left,
                 displayFrame.top,
                 (displayFrame.right - displayFrame.left) / 2,
                 displayFrame.bottom - displayFrame.top);
-        ov.setPosition(dpos, destL);
-        ov.setPosition(dpos, destR);
+        ov.setPosition(dposL, destL);
+        ovutils::Dim dposR(0,
+                displayFrame.top,
+                (displayFrame.right - displayFrame.left) / 2,
+                displayFrame.bottom - displayFrame.top);
+        ov.setPosition(dposR, destR);
 
         ret = true;
         if (!ov.commit(destL)) {
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_qclient.cpp b/libhwcomposer/hwc_qclient.cpp
index c130208..edf579f 100644
--- a/libhwcomposer/hwc_qclient.cpp
+++ b/libhwcomposer/hwc_qclient.cpp
@@ -42,11 +42,7 @@
 QClient::QClient(hwc_context_t *ctx) : mHwcContext(ctx),
         mMPDeathNotifier(new MPDeathNotifier(ctx))
 {
-
     ALOGD_IF(QCLIENT_DEBUG, "QClient Constructor invoked");
-    //The only way to make this class in this process subscribe to media
-    //player's death.
-    IMediaDeathNotifier::getMediaPlayerService();
 }
 
 QClient::~QClient()
@@ -72,6 +68,10 @@
 }
 
 void QClient::securing(uint32_t startEnd) {
+    //The only way to make this class in this process subscribe to media
+    //player's death.
+    IMediaDeathNotifier::getMediaPlayerService();
+
     mHwcContext->mSecuring = startEnd;
     //We're done securing
     if(startEnd == IQService::END)
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index eced7a4..5018d2e 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -19,6 +19,7 @@
  */
 #define HWC_UTILS_DEBUG 0
 #include <sys/ioctl.h>
+#include <linux/fb.h>
 #include <binder/IServiceManager.h>
 #include <EGL/egl.h>
 #include <cutils/properties.h>
@@ -121,7 +122,6 @@
         IVideoOverlay::getObject(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres,
         HWC_DISPLAY_PRIMARY);
 
-    char value[PROPERTY_VALUE_MAX];
     // Check if the target supports copybit compostion (dyn/mdp/c2d) to
     // decide if we need to open the copybit module.
     int compositionType =
@@ -283,9 +283,21 @@
 }
 
 bool isAlphaScaled(hwc_layer_1_t const* layer) {
-    if(needsScaling(layer)) {
-        if(layer->blending != HWC_BLENDING_NONE)
+    if(needsScaling(layer) && isAlphaPresent(layer)) {
+        return true;
+    }
+    return false;
+}
+
+bool isAlphaPresent(hwc_layer_1_t const* layer) {
+    private_handle_t *hnd = (private_handle_t *)layer->handle;
+    int format = hnd->format;
+    switch(format) {
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+        case HAL_PIXEL_FORMAT_BGRA_8888:
+            // In any more formats with Alpha go here..
             return true;
+        default : return false;
     }
     return false;
 }
@@ -298,7 +310,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];
@@ -317,8 +328,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)
@@ -812,6 +823,8 @@
     if(rDest != OV_INVALID) {
         PipeArgs pargR(mdpFlagsR, whf, z, isFg,
                 static_cast<eRotFlags>(rotFlags));
+        tmp_dstR.right = tmp_dstR.right - tmp_dstR.left;
+        tmp_dstR.left = 0;
         if(configMdp(ctx->mOverlay, pargR, orient,
                 tmp_cropR, tmp_dstR, metadata, rDest) < 0) {
             ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 7221c13..254903e 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -29,14 +29,11 @@
 #include <utils/String8.h>
 #include "qdMetaData.h"
 #include <overlayUtils.h>
-#include <linux/fb.h>
 
 #define ALIGN_TO(x, align)     (((x) + ((align)-1)) & ~((align)-1))
 #define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
 #define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
-#define FINAL_TRANSFORM_MASK 0x000F
-#define MAX_NUM_DISPLAYS 4 //Yes, this is ambitious
-#define MAX_NUM_LAYERS 32
+#define MAX_NUM_LAYERS 32 //includes fb layer
 #define MAX_DISPLAY_DIM 2048
 
 // For support of virtual displays
@@ -144,6 +141,7 @@
 bool isSecureModePolicy(int mdpVersion);
 bool isExternalActive(hwc_context_t* ctx);
 bool needsScaling(hwc_layer_1_t const* layer);
+bool isAlphaPresent(hwc_layer_1_t const* layer);
 int hwc_vsync_control(hwc_context_t* ctx, int dpy, int enable);
 
 //Helper function to dump logs
@@ -297,6 +295,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;
diff --git a/libhwcomposer/hwc_vsync.cpp b/libhwcomposer/hwc_vsync.cpp
index 559cd7d..b42043f 100644
--- a/libhwcomposer/hwc_vsync.cpp
+++ b/libhwcomposer/hwc_vsync.cpp
@@ -136,9 +136,11 @@
             cur_timestamp = systemTime();
         }
         // send timestamp to HAL
-        ALOGD_IF (logvsync, "%s: timestamp %llu sent to HWC for %s",
-                  __FUNCTION__, cur_timestamp, "fb0");
-        ctx->proc->vsync(ctx->proc, dpy, cur_timestamp);
+        if(ctx->vstate.enable) {
+            ALOGD_IF (logvsync, "%s: timestamp %llu sent to HWC for %s",
+                      __FUNCTION__, cur_timestamp, "fb0");
+            ctx->proc->vsync(ctx->proc, dpy, cur_timestamp);
+        }
 
     } while (true);
     if(fd_timestamp >= 0)
diff --git a/liboverlay/overlayMem.h b/liboverlay/overlayMem.h
index d3cabb6..5fbe91b 100644
--- a/liboverlay/overlayMem.h
+++ b/liboverlay/overlayMem.h
@@ -138,21 +138,11 @@
     data.uncached = true;
 
     err = mAlloc->allocate(data, allocFlags);
-    //see if we can fallback to other heap
-    //we can try MM_HEAP once if it's not secure playback
-    if (err != 0 && !isSecure) {
-        allocFlags |= GRALLOC_USAGE_PRIVATE_MM_HEAP;
-        err = mAlloc->allocate(data, allocFlags);
-        if (err != 0) {
-            ALOGE(" could not allocate from fallback heap");
-            return false;
-        }
-    } else if (err != 0) {
-        ALOGE("OvMem: error allocating memory can not fall back");
+    if (err != 0) {
+        ALOGE("OvMem: Error allocating memory");
         return false;
     }
 
-
     mFd = data.fd;
     mBaseAddr = data.base;
     mAllocType = data.allocType;
diff --git a/liboverlay/overlayUtils.cpp b/liboverlay/overlayUtils.cpp
index 8cc9cc0..898132f 100644
--- a/liboverlay/overlayUtils.cpp
+++ b/liboverlay/overlayUtils.cpp
@@ -28,6 +28,7 @@
 */
 
 #include <stdlib.h>
+#include <math.h>
 #include <utils/Log.h>
 #include <linux/msm_mdp.h>
 #include <cutils/properties.h>
@@ -189,7 +190,9 @@
     // Use-case: Video playback [with downscaling and rotation].
     if (dst_w && dst_h)
     {
-        uint32_t dscale = (src_w * src_h) / (dst_w * dst_h);
+        float fDscale =  (float)(src_w * src_h) / (float)(dst_w * dst_h);
+        uint32_t dscale = (int)sqrtf(fDscale);
+
         if(dscale < 2) {
             // Down-scale to > 50% of orig.
             dscale_factor = utils::ROT_DS_NONE;
diff --git a/libqservice/IQService.cpp b/libqservice/IQService.cpp
index 6c6f7b6..53b05e3 100644
--- a/libqservice/IQService.cpp
+++ b/libqservice/IQService.cpp
@@ -133,7 +133,7 @@
         } break;
         case SCREEN_REFRESH: {
             CHECK_INTERFACE(IQService, data, reply);
-            if(callerUid != AID_GRAPHICS) {
+            if(callerUid != AID_SYSTEM) {
                 ALOGE("display.qservice SCREEN_REFRESH access denied: \
                       pid=%d uid=%d process=%s",callerPid,
                       callerUid, callingProcName);