Merge "h/q/d: Add missing ASTC format"
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index b345f50..42f3c77 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -126,10 +126,12 @@
 void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format,
                             int tile_enabled, int& aligned_w, int& aligned_h)
 {
-    aligned_w = ALIGN(width, 32);
-    aligned_h = ALIGN(height, 32);
+    aligned_w = width;
+    aligned_h = height;
     // Currently surface padding is only computed for RGB* surfaces.
     if (format <= HAL_PIXEL_FORMAT_sRGB_X_8888) {
+        aligned_w = ALIGN(width, 32);
+        aligned_h = ALIGN(height, 32);
         // Don't add any additional padding if debug.gralloc.map_fb_memory
         // is enabled
         char property[PROPERTY_VALUE_MAX];
@@ -195,12 +197,13 @@
             case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
             case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
                 aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
+                aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
                 break;
             case HAL_PIXEL_FORMAT_BLOB:
-                aligned_w = width;
                 break;
             case HAL_PIXEL_FORMAT_NV21_ZSL:
                 aligned_w = ALIGN(width, 64);
+                aligned_h = ALIGN(height, 64);
                 break;
             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
@@ -408,9 +411,9 @@
 }
 
 // helper function
-size_t getSize(int format, int width, int height, int alignedw, int alignedh)
-{
-    size_t size;
+size_t getSize(int format, int width, int height, const int alignedw,
+        const int alignedh) {
+    size_t size = 0;
 
     switch (format) {
         case HAL_PIXEL_FORMAT_RGBA_8888:
@@ -443,16 +446,14 @@
         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");
-                return -EINVAL;
+                return 0;
             }
-            alignedh = height;
             size = alignedw*alignedh +
                     (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
             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 + 1, 4096);
             break;
         case HAL_PIXEL_FORMAT_YCbCr_422_SP:
@@ -461,28 +462,23 @@
         case HAL_PIXEL_FORMAT_YCrCb_422_I:
             if(width & 1) {
                 ALOGE("width is odd for the YUV422_SP format");
-                return -EINVAL;
+                return 0;
             }
-            alignedh = height;
             size = ALIGN(alignedw * alignedh * 2, 4096);
             break;
         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
-            alignedh = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
             size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
             break;
         case HAL_PIXEL_FORMAT_BLOB:
             if(height != 1) {
                 ALOGE("%s: Buffers with format HAL_PIXEL_FORMAT_BLOB \
                       must have height==1 ", __FUNCTION__);
-                return -EINVAL;
+                return 0;
             }
-            alignedh = height;
-            alignedw = width;
             size = width;
             break;
         case HAL_PIXEL_FORMAT_NV21_ZSL:
-            alignedh = ALIGN(height, 64);
             size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2, 4096);
             break;
         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
@@ -517,7 +513,7 @@
             break;
         default:
             ALOGE("unrecognized pixel format: 0x%x", format);
-            return -EINVAL;
+            return 0;
     }
     return size;
 }
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index da179f9..bb7060b 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -282,13 +282,9 @@
             grallocFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP; //NV21
         else if(usage & GRALLOC_USAGE_HW_CAMERA_WRITE)
             grallocFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP; //NV21
-    }
-
-    if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
-            (usage & GRALLOC_USAGE_HW_COMPOSER )) {
-        //XXX: If we still haven't set a format, default to
-        //RGBA8888
-        grallocFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+        else if(usage & GRALLOC_USAGE_HW_COMPOSER)
+            //XXX: If we still haven't set a format, default to RGBA8888
+            grallocFormat = HAL_PIXEL_FORMAT_RGBA_8888;
     }
 
     getGrallocInformationFromFormat(grallocFormat, &bufferType);
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index 431757d..5c9f2d1 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -105,9 +105,8 @@
 //Helper
 static void reset(hwc_context_t *ctx, int numDisplays,
                   hwc_display_contents_1_t** displays) {
-
     ctx->numActiveDisplays = 0;
-    for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
+    for(int i = 0; i < numDisplays; i++) {
         hwc_display_contents_1_t *list = displays[i];
         // XXX:SurfaceFlinger no longer guarantees that this
         // value is reset on every prepare. However, for the layer
@@ -199,7 +198,7 @@
 
         if (fbComp) {
             const int fbZ = 0;
-            ctx->mFBUpdate[dpy]->prepare(ctx, list, fbZ);
+            ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ);
         }
 
         if (ctx->mMDP.version < qdutils::MDP_V4_0) {
@@ -225,7 +224,7 @@
             setListStats(ctx, list, dpy);
             if(ctx->mMDPComp[dpy]->prepare(ctx, list) < 0) {
                 const int fbZ = 0;
-                ctx->mFBUpdate[dpy]->prepare(ctx, list, fbZ);
+                ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ);
             }
         } else {
             /* External Display is in Pause state.
@@ -341,7 +340,11 @@
         ctx->mOverlay->configBegin();
         ctx->mOverlay->configDone();
         ctx->mRotMgr->clear();
-        overlay::Writeback::clear();
+        // If VDS is connected, do not clear WB object as it
+        // will end up detaching IOMMU. This is required
+        // to send black frame to WFD sink on power suspend.
+        // Note: With this change, we keep the WriteBack object
+        // alive on power suspend for AD use case.
     }
     switch(dpy) {
     case HWC_DISPLAY_PRIMARY:
@@ -660,7 +663,7 @@
 }
 
 int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
-        uint32_t config, const uint32_t* attributes, int32_t* values) {
+        uint32_t /*config*/, const uint32_t* attributes, int32_t* values) {
 
     hwc_context_t* ctx = (hwc_context_t*)(dev);
     disp = getDpyforExternalDisplay(ctx, disp);
diff --git a/libhwcomposer/hwc_ad.cpp b/libhwcomposer/hwc_ad.cpp
index 929ccc4..236093b 100644
--- a/libhwcomposer/hwc_ad.cpp
+++ b/libhwcomposer/hwc_ad.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2013 The Linux Foundation. All rights reserved.
+* Copyright (c) 2013-2014 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
@@ -249,6 +249,14 @@
             adWrite(on);
         }
     }
+
+    if(!ctx->mOverlay->validateAndSet(overlay::Overlay::DPY_WRITEBACK,
+            mWbFd)) {
+        ALOGE("%s: Failed to validate and set overlay for dpy %d"
+                ,__FUNCTION__, overlay::Overlay::DPY_WRITEBACK);
+        return false;
+    }
+
     return true;
 }
 
@@ -270,12 +278,12 @@
     return true;
 }
 
-int AssertiveDisplay::getDstFd(hwc_context_t *ctx) const {
+int AssertiveDisplay::getDstFd() const {
     overlay::Writeback *wb = overlay::Writeback::getInstance();
     return wb->getDstFd();
 }
 
-uint32_t AssertiveDisplay::getDstOffset(hwc_context_t *ctx) const {
+uint32_t AssertiveDisplay::getDstOffset() const {
     overlay::Writeback *wb = overlay::Writeback::getInstance();
     return wb->getOffset();
 }
diff --git a/libhwcomposer/hwc_ad.h b/libhwcomposer/hwc_ad.h
index c745b15..3bfde17 100644
--- a/libhwcomposer/hwc_ad.h
+++ b/libhwcomposer/hwc_ad.h
@@ -51,8 +51,8 @@
     }
     bool isDoable() const { return mDoable; }
     bool isModeOn() const { return (mWbFd >= 0); }
-    int getDstFd(hwc_context_t *ctx) const;
-    uint32_t getDstOffset(hwc_context_t *ctx) const;
+    int getDstFd() const;
+    uint32_t getDstOffset() const;
 
 private:
     //State of feature turned on and off
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 86cad8f..8c83469 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
  *
  * Not a Contribution.
  *
@@ -162,8 +162,6 @@
     bool useCopybitForYUV = canUseCopybitForYUV(ctx);
     bool useCopybitForRGB = canUseCopybitForRGB(ctx, list, dpy);
     LayerProp *layerProp = ctx->layerProp[dpy];
-    size_t fbLayerIndex = ctx->listStats[dpy].fbLayerIndex;
-    hwc_layer_1_t *fbLayer = &list->hwLayers[fbLayerIndex];
 
     // Following are MDP3 limitations for which we
     // need to fallback to GPU composition:
@@ -326,7 +324,7 @@
             list->hwLayers[i].acquireFenceFd = -1;
         }
         retVal = drawLayerUsingCopybit(ctx, &(list->hwLayers[i]),
-                                                    renderBuffer, dpy, !i);
+                                                    renderBuffer, !i);
         copybitLayerCount++;
         if(retVal < 0) {
             ALOGE("%s : drawLayerUsingCopybit failed", __FUNCTION__);
@@ -347,7 +345,7 @@
 }
 
 int  CopyBit::drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
-                          private_handle_t *renderBuffer, int dpy, bool isFG)
+                          private_handle_t *renderBuffer, bool isFG)
 {
     hwc_context_t* ctx = (hwc_context_t*)(dev);
     int err = 0, acquireFd;
diff --git a/libhwcomposer/hwc_copybit.h b/libhwcomposer/hwc_copybit.h
index 4d8123c..f7be644 100644
--- a/libhwcomposer/hwc_copybit.h
+++ b/libhwcomposer/hwc_copybit.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
  *
  * Not a Contribution, Apache license notifications and license are retained
  * for attribution purposes only.
@@ -54,7 +54,7 @@
     struct copybit_device_t *mEngine;
     // Helper functions for copybit composition
     int  drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
-                          private_handle_t *renderBuffer, int dpy, bool isFG);
+                          private_handle_t *renderBuffer, bool isFG);
     int fillColorUsingCopybit(hwc_layer_1_t *layer,
                           private_handle_t *renderBuffer);
     bool canUseCopybitForYUV (hwc_context_t *ctx);
diff --git a/libhwcomposer/hwc_dump_layers.cpp b/libhwcomposer/hwc_dump_layers.cpp
index aeaac08..6df8ce3 100644
--- a/libhwcomposer/hwc_dump_layers.cpp
+++ b/libhwcomposer/hwc_dump_layers.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013, Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 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
@@ -38,6 +38,9 @@
 #include <comptype.h>
 #include <SkBitmap.h>
 #include <SkImageEncoder.h>
+#ifdef STDC_FORMAT_MACROS
+#include <inttypes.h>
+#endif
 
 namespace qhwc {
 
@@ -308,7 +311,7 @@
         char dumpFilename[PATH_MAX];
         SkBitmap *tempSkBmp = new SkBitmap();
         SkBitmap::Config tempSkBmpConfig = SkBitmap::kNo_Config;
-        sprintf(dumpFilename, "%s/sfdump%03d.layer%d.%s.png", mDumpDirPng,
+        sprintf(dumpFilename, "%s/sfdump%03d.layer%zu.%s.png", mDumpDirPng,
             mDumpCntrPng, layerIndex, mDisplayName);
 
         switch (hnd->format) {
@@ -344,7 +347,7 @@
     if (needDumpRaw && hnd->base) {
         char dumpFilename[PATH_MAX];
         bool bResult = false;
-        sprintf(dumpFilename, "%s/sfdump%03d.layer%d.%dx%d.%s.%s.raw",
+        sprintf(dumpFilename, "%s/sfdump%03d.layer%zu.%dx%d.%s.%s.raw",
             mDumpDirRaw, mDumpCntrRaw,
             layerIndex, getWidth(hnd), getHeight(hnd),
             pixFormatStr, mDisplayName);
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index 0123452..b81494d 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -60,6 +60,12 @@
     mRot = NULL;
 }
 
+bool IFBUpdate::prepareAndValidate(hwc_context_t *ctx,
+            hwc_display_contents_1 *list, int fbZorder) {
+    return prepare(ctx, list, fbZorder) &&
+            ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd);
+}
+
 //================= Low res====================================
 FBUpdateNonSplit::FBUpdateNonSplit(hwc_context_t *ctx, const int& dpy):
         IFBUpdate(ctx, dpy) {}
diff --git a/libhwcomposer/hwc_fbupdate.h b/libhwcomposer/hwc_fbupdate.h
index 4b449c8..da4cdfc 100644
--- a/libhwcomposer/hwc_fbupdate.h
+++ b/libhwcomposer/hwc_fbupdate.h
@@ -39,7 +39,9 @@
     virtual ~IFBUpdate() {};
     // Sets up members and prepares overlay if conditions are met
     virtual bool prepare(hwc_context_t *ctx, hwc_display_contents_1 *list,
-                                                       int fbZorder) = 0;
+            int fbZorder) = 0;
+    virtual bool prepareAndValidate(hwc_context_t *ctx,
+            hwc_display_contents_1 *list, int fbZorder);
     // Draws layer
     virtual bool draw(hwc_context_t *ctx, private_handle_t *hnd) = 0;
     //Reset values
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index dbd05ae..40b00dd 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
  * Not a Contribution, Apache license notifications and license are retained
  * for attribution purposes only.
  *
@@ -233,7 +233,7 @@
     fbCount = numLayers;
     mdpCount = 0;
     needsRedraw = true;
-    fbZ = 0;
+    fbZ = -1;
 }
 
 void MDPComp::FrameInfo::map() {
@@ -300,7 +300,6 @@
 }
 
 bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
-    const int dpy = HWC_DISPLAY_PRIMARY;
     private_handle_t *hnd = (private_handle_t *)layer->handle;
 
     if(!hnd) {
@@ -316,9 +315,6 @@
     if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
         return false;
 
-    int hw_w = ctx->dpyAttr[mDpy].xres;
-    int hw_h = ctx->dpyAttr[mDpy].yres;
-
     hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
     hwc_rect_t dst = layer->displayFrame;
     int crop_w = crop.right - crop.left;
@@ -407,7 +403,6 @@
 
 bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
     bool ret = true;
-    const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
 
     if(!isEnabled()) {
         ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
@@ -458,7 +453,6 @@
 
         hwc_rect_t dstRect = layer->displayFrame;
         hwc_rect_t srcRect = integerizeSourceCrop(layer->sourceCropf);
-        int transform = layer->transform;
 
         hwc_rect_t res  = getIntersection(visibleRect, dstRect);
 
@@ -515,7 +509,6 @@
             hwc_rect_t dstRect = list->hwLayers[index].displayFrame;
             hwc_rect_t srcRect = integerizeSourceCrop(
                                         list->hwLayers[index].sourceCropf);
-            int transform = list->hwLayers[index].transform;
 
             /* Intersect against display boundaries */
             roi = getUnion(roi, dstRect);
@@ -637,7 +630,6 @@
     }
 
     mCurrentFrame.fbCount = 0;
-    mCurrentFrame.fbZ = -1;
     memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
            sizeof(mCurrentFrame.isFBComposed));
     mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
@@ -729,7 +721,7 @@
 
 bool MDPComp::loadBasedCompPreferGPU(hwc_context_t *ctx,
         hwc_display_contents_1_t* list) {
-    if(not isLoadBasedCompDoable(ctx, list)) {
+    if(not isLoadBasedCompDoable(ctx)) {
         return false;
     }
 
@@ -840,7 +832,7 @@
 
 bool MDPComp::loadBasedCompPreferMDP(hwc_context_t *ctx,
         hwc_display_contents_1_t* list) {
-    if(not isLoadBasedCompDoable(ctx, list)) {
+    if(not isLoadBasedCompDoable(ctx)) {
         return false;
     }
 
@@ -919,8 +911,7 @@
     return true;
 }
 
-bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx,
-        hwc_display_contents_1_t* list) {
+bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
     if(mDpy or isSecurePresent(ctx, mDpy) or
             isYuvPresent(ctx, mDpy)) {
         return false;
@@ -1128,14 +1119,14 @@
     int maxBatchCount = 0;
     int fbZ = -1;
 
-    /* All or Nothing is cached. No batching needed */
-    if(!mCurrentFrame.fbCount) {
-        mCurrentFrame.fbZ = -1;
+    /* Nothing is cached. No batching needed */
+    if(mCurrentFrame.fbCount == 0) {
         return true;
     }
-    if(!mCurrentFrame.mdpCount) {
-        mCurrentFrame.fbZ = 0;
-        return true;
+
+    /* No MDP comp layers, try to use other comp modes */
+    if(mCurrentFrame.mdpCount == 0) {
+        return false;
     }
 
     fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
@@ -1174,7 +1165,6 @@
     int fbCount = 0;
 
     for(int i = 0; i < numAppLayers; i++) {
-        hwc_layer_1_t* layer = &list->hwLayers[i];
         if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
             if(!mCurrentFrame.drop[i])
                 fbCount++;
@@ -1288,6 +1278,12 @@
         }
     }
 
+    if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
+        ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
+                ,__FUNCTION__, mDpy);
+        return false;
+    }
+
     setRedraw(ctx, list);
     return true;
 }
@@ -1484,12 +1480,9 @@
     return ret;
 }
 
-bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx,
-        hwc_display_contents_1_t* list, int index) {
+bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
 
     bool bRet = true;
-    hwc_layer_1_t* layer = &list->hwLayers[index];
-    private_handle_t *hnd = (private_handle_t *)layer->handle;
     int mdpIndex = mCurrentFrame.layerToMDP[index];
     PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
     info.pipeInfo = new MdpYUVPipeInfo;
@@ -1514,10 +1507,10 @@
     }
     return bRet;
 }
-//=============MDPCompNonSplit===================================================
+//=============MDPCompNonSplit==================================================
 
 void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
-         hwc_display_contents_1_t* list){
+        hwc_display_contents_1_t*) {
     //As we split 4kx2k yuv layer and program to 2 VG pipes
     //(if available) increase mdpcount accordingly
     mCurrentFrame.mdpCount += ctx->listStats[mDpy].yuv4k2kCount;
@@ -1618,7 +1611,7 @@
         hwc_layer_1_t* layer = &list->hwLayers[index];
         private_handle_t *hnd = (private_handle_t *)layer->handle;
         if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
-            if(allocSplitVGPipesfor4k2k(ctx, list, index)){
+            if(allocSplitVGPipesfor4k2k(ctx, index)){
                 continue;
             }
         }
@@ -1810,7 +1803,6 @@
         hwc_display_contents_1_t* list,
         int mixer) {
     int pipesNeeded = 0;
-    const int xres = ctx->dpyAttr[mDpy].xres;
 
     const int lSplit = getLeftSplit(ctx, mDpy);
 
@@ -1909,7 +1901,6 @@
 bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
         MdpPipeInfoSplit& pipe_info,
         ePipeType type) {
-    const int xres = ctx->dpyAttr[mDpy].xres;
     const int lSplit = getLeftSplit(ctx, mDpy);
 
     hwc_rect_t dst = layer->displayFrame;
@@ -1943,7 +1934,7 @@
         const int lSplit = getLeftSplit(ctx, mDpy);
         if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
             if((dst.left > lSplit)||(dst.right < lSplit)){
-                if(allocSplitVGPipesfor4k2k(ctx, list, index)){
+                if(allocSplitVGPipesfor4k2k(ctx, index)){
                     continue;
                 }
             }
@@ -2104,8 +2095,8 @@
 
             if(ctx->mAD->isModeOn()) {
                 if(ctx->mAD->draw(ctx, fd, offset)) {
-                    fd = ctx->mAD->getDstFd(ctx);
-                    offset = ctx->mAD->getDstOffset(ctx);
+                    fd = ctx->mAD->getDstFd();
+                    offset = ctx->mAD->getDstOffset();
                 }
             }
 
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index bc41bd9..40a0cb5 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -172,8 +172,7 @@
     bool loadBasedCompPreferMDP(hwc_context_t *ctx,
             hwc_display_contents_1_t* list);
     /* Checks if its worth doing load based partial comp */
-    bool isLoadBasedCompDoable(hwc_context_t *ctx,
-            hwc_display_contents_1_t* list);
+    bool isLoadBasedCompDoable(hwc_context_t *ctx);
     /* checks for conditions where only video can be bypassed */
     bool tryVideoOnly(hwc_context_t *ctx, hwc_display_contents_1_t* list);
     bool videoOnlyComp(hwc_context_t *ctx, hwc_display_contents_1_t* list,
@@ -246,8 +245,7 @@
     struct LayerCache mCachedFrame;
     //Enable 4kx2k yuv layer split
     static bool sEnable4k2kYUVSplit;
-    bool allocSplitVGPipesfor4k2k(hwc_context_t *ctx,
-            hwc_display_contents_1_t* list, int index);
+    bool allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index);
 };
 
 class MDPCompNonSplit : public MDPComp {
@@ -281,7 +279,7 @@
     /* Increments mdpCount if 4k2k yuv layer split is enabled.
      * updates framebuffer z order if fb lies above source-split layer */
     virtual void adjustForSourceSplit(hwc_context_t *ctx,
-             hwc_display_contents_1_t* list);
+            hwc_display_contents_1_t* list);
 
     /* configures 4kx2k yuv layer to 2 VG pipes*/
     virtual int configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
diff --git a/libhwcomposer/hwc_qclient.cpp b/libhwcomposer/hwc_qclient.cpp
index 8c5b079..2320bc0 100644
--- a/libhwcomposer/hwc_qclient.cpp
+++ b/libhwcomposer/hwc_qclient.cpp
@@ -130,8 +130,9 @@
     //XXX: Need to check what to return for HDMI
     outParcel->writeInt32(ctx->mMDP.panel);
 }
-static void setHSIC(hwc_context_t* ctx, const Parcel* inParcel) {
+static void setHSIC(const Parcel* inParcel) {
     int dpy = inParcel->readInt32();
+    ALOGD_IF(0, "In %s: dpy = %d", __FUNCTION__, dpy);
     HSICData_t hsic_data;
     hsic_data.hue = inParcel->readInt32();
     hsic_data.saturation = inParcel->readFloat();
@@ -191,7 +192,6 @@
         return vpuCommand(mHwcContext, command, inParcel, outParcel);
     }
 #endif
-
     switch(command) {
         case IQService::SECURING:
             securing(mHwcContext, inParcel->readInt32());
@@ -219,7 +219,7 @@
             getDisplayAttributes(mHwcContext, inParcel, outParcel);
             break;
         case IQService::SET_HSIC_DATA:
-            setHSIC(mHwcContext, inParcel);
+            setHSIC(inParcel);
         case IQService::PAUSE_WFD:
             pauseWFD(mHwcContext, inParcel->readInt32());
             break;
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index f6476f5..d94e0e9 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -494,7 +494,6 @@
         getAspectRatioPosition(width, height, width, height, r);
         xPos = r.left;
         yPos = r.top;
-        float tempWidth = r.right - r.left;
         float tempHeight = r.bottom - r.top;
         yRatio = yPos/height;
         wRatio = outPos.w/width;
@@ -799,7 +798,7 @@
     ctx->dpyAttr[dpy].mActionSafePresent = isActionSafePresent(ctx, dpy);
 
     trimList(ctx, list, dpy);
-    optimizeLayerRects(ctx, list, dpy);
+    optimizeLayerRects(list);
 
     for (size_t i = 0; i < (size_t)ctx->listStats[dpy].numAppLayers; i++) {
         hwc_layer_1_t const* layer = &list->hwLayers[i];
@@ -1009,8 +1008,6 @@
     const int& sci_t = scissor.top;
     const int& sci_r = scissor.right;
     const int& sci_b = scissor.bottom;
-    int sci_w = abs(sci_r - sci_l);
-    int sci_h = abs(sci_b - sci_t);
 
     double leftCutRatio = 0.0, rightCutRatio = 0.0, topCutRatio = 0.0,
             bottomCutRatio = 0.0;
@@ -1117,14 +1114,12 @@
    return res;
 }
 
-void optimizeLayerRects(hwc_context_t *ctx,
-                        const hwc_display_contents_1_t *list, const int& dpy) {
+void optimizeLayerRects(const hwc_display_contents_1_t *list) {
     int i=list->numHwLayers-2;
-    hwc_rect_t irect;
     while(i > 0) {
-
         //see if there is no blending required.
-        //If it is opaque see if we can substract this region from below layers.
+        //If it is opaque see if we can substract this region from below
+        //layers.
         if(list->hwLayers[i].blending == HWC_BLENDING_NONE) {
             int j= i-1;
             hwc_rect_t& topframe =
@@ -1210,7 +1205,6 @@
     int retireFd = -1;
     int fbFd = -1;
     bool swapzero = false;
-    int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion();
 
     struct mdp_buf_sync data;
     memset(&data, 0, sizeof(data));
@@ -1256,15 +1250,14 @@
         }
     }
 
-    //Accumulate acquireFenceFds for MDP
+    //Accumulate acquireFenceFds for MDP Overlays
     if(list->outbufAcquireFenceFd >= 0) {
         //Writeback output buffer
         acquireFd[count++] = list->outbufAcquireFenceFd;
     }
 
     for(uint32_t i = 0; i < list->numHwLayers; i++) {
-        if((list->hwLayers[i].compositionType == HWC_OVERLAY  ||
-                        list->hwLayers[i].compositionType == HWC_BLIT) &&
+        if(list->hwLayers[i].compositionType == HWC_OVERLAY &&
                         list->hwLayers[i].acquireFenceFd >= 0) {
             if(UNLIKELY(swapzero))
                 acquireFd[count++] = -1;
@@ -1320,7 +1313,13 @@
                     !(layerProp[i].mFlags & HWC_VPUCOMP)) {
                 //If rotator has not already populated this field
                 // & if it's a not VPU layer
-                list->hwLayers[i].releaseFenceFd = dup(releaseFd);
+                if(list->hwLayers[i].compositionType == HWC_BLIT) {
+                    //For Blit, the app layers should be released when the Blit is
+                    //complete. This fd was passed from copybit->draw
+                    list->hwLayers[i].releaseFenceFd = dup(fd);
+                } else {
+                    list->hwLayers[i].releaseFenceFd = dup(releaseFd);
+                }
             }
         }
     }
@@ -1556,7 +1555,6 @@
     int rotFlags = ovutils::ROT_FLAGS_NONE;
     uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
     Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
-    LayerProp *layerProp = ctx->layerProp[dpy];
 
 #ifdef VPU_TARGET
     if(ctx->mVPUClient != NULL &&
@@ -1597,7 +1595,7 @@
         *rot = ctx->mRotMgr->getNext();
         if(*rot == NULL) return -1;
         if(!dpy)
-            BwcPM::setBwc(ctx, crop, dst, transform, mdpFlags);
+            BwcPM::setBwc(crop, dst, transform, mdpFlags);
         //Configure rotator for pre-rotation
         if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
             ALOGE("%s: configRotator failed!", __FUNCTION__);
@@ -1674,7 +1672,6 @@
     int rotFlags = ROT_FLAGS_NONE;
     uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
     Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
-    LayerProp *layerProp = ctx->layerProp[dpy];
 
 #ifdef VPU_TARGET
     if(ctx->mVPUClient != NULL &&
@@ -1815,8 +1812,6 @@
 
     MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
 
-    int hw_w = ctx->dpyAttr[dpy].xres;
-    int hw_h = ctx->dpyAttr[dpy].yres;
     hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);;
     hwc_rect_t dst = layer->displayFrame;
     int transform = layer->transform;
@@ -1838,7 +1833,7 @@
         (*rot) = ctx->mRotMgr->getNext();
         if((*rot) == NULL) return -1;
         if(!dpy)
-            BwcPM::setBwc(ctx, crop, dst, transform, mdpFlagsL);
+            BwcPM::setBwc(crop, dst, transform, mdpFlagsL);
         //Configure rotator for pre-rotation
         if(configRotator(*rot, whf, crop, mdpFlagsL, orient, downscale) < 0) {
             ALOGE("%s: configRotator failed!", __FUNCTION__);
@@ -1998,7 +1993,7 @@
     return true;
 }
 
-void BwcPM::setBwc(hwc_context_t *ctx, const hwc_rect_t& crop,
+void BwcPM::setBwc(const hwc_rect_t& crop,
             const hwc_rect_t& dst, const int& transform,
             ovutils::eMdpFlags& mdpFlags) {
     //Target doesnt support Bwc
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index ce1abeb..3393b59 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -136,7 +136,7 @@
 };
 
 struct BwcPM {
-    static void setBwc(hwc_context_t *ctx, const hwc_rect_t& crop,
+    static void setBwc(const hwc_rect_t& crop,
             const hwc_rect_t& dst, const int& transform,
             ovutils::eMdpFlags& mdpFlags);
 };
@@ -247,8 +247,7 @@
 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,
-        const hwc_display_contents_1_t *list, const int& dpy);
+void optimizeLayerRects(const hwc_display_contents_1_t *list);
 bool areLayersIntersecting(const hwc_layer_1_t* layer1,
         const hwc_layer_1_t* layer2);
 
@@ -395,7 +394,7 @@
 
 static inline int getWidth(const private_handle_t* hnd) {
     if(isYuvBuffer(hnd)) {
-        MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+        MetaData_t *metadata = reinterpret_cast<MetaData_t*>(hnd->base_metadata);
         if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
             return metadata->bufferDim.sliceWidth;
         }
@@ -405,7 +404,7 @@
 
 static inline int getHeight(const private_handle_t* hnd) {
     if(isYuvBuffer(hnd)) {
-        MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+        MetaData_t *metadata = reinterpret_cast<MetaData_t*>(hnd->base_metadata);
         if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
             return metadata->bufferDim.sliceHeight;
         }
diff --git a/libhwcomposer/hwc_virtual.cpp b/libhwcomposer/hwc_virtual.cpp
index 600ba8d..c081400 100644
--- a/libhwcomposer/hwc_virtual.cpp
+++ b/libhwcomposer/hwc_virtual.cpp
@@ -62,7 +62,7 @@
         ctx->mMDPComp[dpy]->reset();
 }
 
-void HWCVirtualVDS::destroy(hwc_context_t *ctx, size_t numDisplays,
+void HWCVirtualVDS::destroy(hwc_context_t *ctx, size_t /*numDisplays*/,
                        hwc_display_contents_1_t** displays) {
     int dpy = HWC_DISPLAY_VIRTUAL;
 
@@ -78,6 +78,11 @@
             delete ctx->mMDPComp[dpy];
             ctx->mMDPComp[dpy] = NULL;
         }
+        // We reset the WB session to non-secure when the virtual display
+        // has been disconnected.
+        if(!Writeback::getInstance()->setSecure(false)) {
+            ALOGE("Failure while attempting to reset WB session.");
+        }
     }
 }
 
@@ -99,9 +104,14 @@
 
         if(ctx->dpyAttr[dpy].connected == false) {
             ctx->dpyAttr[dpy].connected = true;
+            // We set the vsync period to the primary refresh rate, leaving
+            // it up to the consumer to decide how fast to consume frames.
+            ctx->dpyAttr[dpy].vsync_period
+                              = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period;
             init(ctx);
-            //First round, just setup and return so primary can free pipes
-            return 0;
+            // XXX: for architectures with limited resources we would normally
+            // allow one padding round to free up resources but this breaks
+            // certain use cases.
         }
 
         ctx->dpyAttr[dpy].isConfiguring = false;
@@ -127,8 +137,7 @@
         uint32_t last = list->numHwLayers - 1;
         hwc_layer_1_t *fbLayer = &list->hwLayers[last];
 
-        if(fbLayer->handle && !isSecondaryConfiguring(ctx) &&
-                !ctx->mMDPComp[dpy]->isGLESOnlyComp()) {
+        if(ctx->dpyAttr[dpy].connected) {
             private_handle_t *ohnd = (private_handle_t *)list->outbuf;
             int format = ohnd->format;
             if (format == HAL_PIXEL_FORMAT_RGBA_8888)
@@ -136,6 +145,15 @@
             Writeback::getInstance()->setOutputFormat(
                                     utils::getMdpFormat(format));
 
+            // Configure WB as secure if the output buffer handle is secure.
+            if(isSecureBuffer(ohnd)){
+                if(! Writeback::getInstance()->setSecure(true))
+                {
+                    ALOGE("Failed to set WB as secure for virtual display");
+                    return false;
+                }
+            }
+
             int fd = -1; //FenceFD from the Copybit
             hwc_sync(ctx, list, dpy, fd);
 
@@ -143,7 +161,13 @@
                 ALOGE("%s: MDPComp draw failed", __FUNCTION__);
                 ret = -1;
             }
-            if (!ctx->mFBUpdate[dpy]->draw(ctx,
+            // We need an FB layer handle check to cater for this usecase:
+            // Video is playing in landscape on primary, then launch
+            // ScreenRecord app.
+            // In this scenario, the first VDS draw call will have HWC
+            // composition and VDS does nit involve GPU to get eglSwapBuffer
+            // to get valid fb handle.
+            if (fbLayer->handle && !ctx->mFBUpdate[dpy]->draw(ctx,
                         (private_handle_t *)fbLayer->handle)) {
                 ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
                 ret = -1;
diff --git a/libhwcomposer/hwc_virtual.h b/libhwcomposer/hwc_virtual.h
index 502aa3b..26f401f 100644
--- a/libhwcomposer/hwc_virtual.h
+++ b/libhwcomposer/hwc_virtual.h
@@ -75,11 +75,11 @@
     // instantiates mdpcomp, copybit and fbupdate objects and initialize those
     // objects for virtual display during virtual display connect. This function
     // is no-op for V4L2 design
-    virtual void init(hwc_context_t *ctx) {};
+    virtual void init(hwc_context_t *) {};
     // Destroys mdpcomp, copybit and fbupdate objects and for virtual display
     // during virtual display disconnect. This function is no-op for V4L2 design
-    virtual void destroy(hwc_context_t *ctx, size_t numDisplays,
-                       hwc_display_contents_1_t** displays){};
+    virtual void destroy(hwc_context_t *, size_t ,
+                       hwc_display_contents_1_t** ) {};
 };
 
 }; //namespace
diff --git a/libhwcomposer/hwc_vsync.cpp b/libhwcomposer/hwc_vsync.cpp
index 595b7f2..3729f21 100644
--- a/libhwcomposer/hwc_vsync.cpp
+++ b/libhwcomposer/hwc_vsync.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
  *
  * Not a Contribution, Apache license notifications and license are
  * retained for attribution purposes only.
@@ -30,6 +30,8 @@
 #include "string.h"
 #include "external.h"
 #include "overlay.h"
+#define __STDC_FORMAT_MACROS 1
+#include <inttypes.h>
 
 namespace qhwc {
 
@@ -133,8 +135,8 @@
                         }
                         // send timestamp to SurfaceFlinger
                         ALOGD_IF (logvsync,
-                                "%s: timestamp %llu sent to SF for dpy=%d",
-                                __FUNCTION__, timestamp[dpy], dpy);
+                            "%s: timestamp %"PRIu64" sent to SF for dpy=%d",
+                            __FUNCTION__, timestamp[dpy], dpy);
                         ctx->proc->vsync(ctx->proc, dpy, timestamp[dpy]);
                     }
                 }
diff --git a/liboverlay/mdpWrapper.h b/liboverlay/mdpWrapper.h
index d96317c..1bfa058 100644
--- a/liboverlay/mdpWrapper.h
+++ b/liboverlay/mdpWrapper.h
@@ -42,6 +42,8 @@
 #include <errno.h>
 #include "overlayUtils.h"
 
+#define IOCTL_DEBUG 0
+
 namespace overlay{
 
 namespace mdp_wrapper{
@@ -63,6 +65,9 @@
 /* MSMFB_OVERLAY_SET */
 bool setOverlay(int fd, mdp_overlay& ov);
 
+/* MSMFB_OVERLAY_PREPARE */
+bool validateAndSet(const int& fd, mdp_overlay_list& list);
+
 /* MSM_ROTATOR_IOCTL_FINISH */
 bool endRotator(int fd, int sessionId);
 
@@ -167,6 +172,15 @@
     return true;
 }
 
+inline bool validateAndSet(const int& fd, mdp_overlay_list& list) {
+    if (ioctl(fd, MSMFB_OVERLAY_PREPARE, &list) < 0) {
+        ALOGD_IF(IOCTL_DEBUG, "Failed to call ioctl MSMFB_OVERLAY_PREPARE "
+                "err=%s", strerror(errno));
+        return false;
+    }
+    return true;
+}
+
 inline bool endRotator(int fd, uint32_t sessionId) {
     if (ioctl(fd, MSM_ROTATOR_IOCTL_FINISH, &sessionId) < 0) {
         ALOGE("Failed to call ioctl MSM_ROTATOR_IOCTL_FINISH err=%s",
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index ad23e84..6feffc4 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -69,13 +69,6 @@
         PipeBook::resetAllocation(i);
     }
     mDumpStr[0] = '\0';
-
-#ifdef USES_QSEED_SCALAR
-    Scale *scalar = getScalar();
-    if(scalar) {
-        scalar->configBegin();
-    }
-#endif
 }
 
 void Overlay::configDone() {
@@ -98,13 +91,6 @@
     }
     dump();
     PipeBook::save();
-
-#ifdef USES_QSEED_SCALAR
-    Scale *scalar = getScalar();
-    if(scalar) {
-        scalar->configDone();
-    }
-#endif
 }
 
 int Overlay::getPipeId(utils::eDest dest) {
@@ -435,6 +421,22 @@
     }
 }
 
+bool Overlay::validateAndSet(const int& dpy, const int& fbFd) {
+    GenericPipe* pipeArray[PipeBook::NUM_PIPES];
+    memset(&pipeArray, 0, sizeof(pipeArray));
+
+    int num = 0;
+    for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
+        if(PipeBook::isUsed(i) && mPipeBook[i].valid() &&
+                mPipeBook[i].mDisplay == dpy) {
+            pipeArray[num++] = mPipeBook[i].mPipe;
+        }
+    }
+
+    //Protect against misbehaving clients
+    return num ? GenericPipe::validateAndSet(pipeArray, num, fbFd) : true;
+}
+
 void Overlay::initScalar() {
 #ifdef USES_QSEED_SCALAR
     if(sLibScaleHandle == NULL) {
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index fe855c1..d8615cd 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -120,6 +120,8 @@
     void getDump(char *buf, size_t len);
     /* Reset usage and allocation bits on all pipes for given display */
     void clear(int dpy);
+    /* Validate the set of pipes for a display and set them in driver */
+    bool validateAndSet(const int& dpy, const int& fbFd);
 
     /* Closes open pipes, called during startup */
     static int initOverlay();
@@ -131,8 +133,6 @@
     static int getFbForDpy(const int& dpy);
     static bool displayCommit(const int& fd, const utils::Dim& roi);
     static bool displayCommit(const int& fd);
-    /* Returns the scalar object */
-    static scale::Scale *getScalar();
 
 private:
     /* Ctor setup */
@@ -141,6 +141,8 @@
     void validate(int index);
     static void setDMAMultiplexingSupported();
     void dump() const;
+    /* Returns the scalar object */
+    static scale::Scale *getScalar();
     /* Creates a scalar object using libscale.so */
     static void initScalar();
     /* Destroys the scalar object using libscale.so */
@@ -212,6 +214,8 @@
     static bool sDMAMultiplexingSupported;
     static void *sLibScaleHandle;
     static scale::Scale *sScale;
+
+    friend class MdpCtrl;
 };
 
 inline void Overlay::validate(int index) {
diff --git a/liboverlay/overlayCtrlData.h b/liboverlay/overlayCtrlData.h
index dbf328a..26202ec 100644
--- a/liboverlay/overlayCtrlData.h
+++ b/liboverlay/overlayCtrlData.h
@@ -84,6 +84,8 @@
     /* Return the dump in the specified buffer */
     void getDump(char *buf, size_t len);
 
+    static bool validateAndSet(Ctrl* ctrlArray[], const int& count,
+            const int& fbFd);
 private:
     // mdp ctrl struct(info e.g.)
     MdpCtrl *mMdp;
@@ -181,6 +183,19 @@
     mMdp->updateSrcFormat(rotDstFmt);
 }
 
+inline bool Ctrl::validateAndSet(Ctrl* ctrlArray[], const int& count,
+        const int& fbFd) {
+    MdpCtrl* mdpCtrlArray[count];
+    memset(&mdpCtrlArray, 0, sizeof(mdpCtrlArray));
+
+    for(int i = 0; i < count; i++) {
+        mdpCtrlArray[i] = ctrlArray[i]->mMdp;
+    }
+
+    bool ret = MdpCtrl::validateAndSet(mdpCtrlArray, count, fbFd);
+    return ret;
+}
+
 inline utils::Dim Ctrl::getCrop() const {
     return mMdp->getSrcRectDim();
 }
diff --git a/liboverlay/overlayMdp.cpp b/liboverlay/overlayMdp.cpp
index 3ec0405..a25dc5e 100644
--- a/liboverlay/overlayMdp.cpp
+++ b/liboverlay/overlayMdp.cpp
@@ -206,35 +206,6 @@
     }
 
     doDownscale();
-
-    if(!mdp_wrapper::setOverlay(mFd.getFD(), mOVInfo)) {
-        ALOGE("MdpCtrl failed to setOverlay");
-        mdp_wrapper::dump("== Bad OVInfo is: ", mOVInfo);
-#ifdef USES_QSEED_SCALAR
-        if(Overlay::getScalar()) {
-            Overlay::getScalar()->configAbort(mDpy);
-        }
-#endif
-        return false;
-    }
-
-#ifdef USES_QSEED_SCALAR
-    if(Overlay::getScalar()) {
-        Overlay::getScalar()->configSet(mOVInfo, mDpy, mFd.getFD());
-    }
-#endif
-
-    return true;
-}
-
-bool MdpCtrl::get() {
-    mdp_overlay ov;
-    ov.id = mOVInfo.id;
-    if (!mdp_wrapper::getOverlay(mFd.getFD(), ov)) {
-        ALOGE("MdpCtrl get failed");
-        return false;
-    }
-    mOVInfo = ov;
     return true;
 }
 
@@ -389,6 +360,38 @@
     return true;
 }
 
+bool MdpCtrl::validateAndSet(MdpCtrl* mdpCtrlArray[], const int& count,
+        const int& fbFd) {
+    mdp_overlay* ovArray[count];
+    memset(&ovArray, 0, sizeof(ovArray));
+
+    for(int i = 0; i < count; i++) {
+        ovArray[i] = &mdpCtrlArray[i]->mOVInfo;
+    }
+
+    struct mdp_overlay_list list;
+    memset(&list, 0, sizeof(struct mdp_overlay_list));
+    list.num_overlays = count;
+    list.overlay_list = ovArray;
+
+#ifdef USES_QSEED_SCALAR
+    Scale *scalar = Overlay::getScalar();
+    if(scalar) {
+        scalar->applyScale(&list);
+    }
+#endif
+
+    if(!mdp_wrapper::validateAndSet(fbFd, list)) {
+        if(list.processed_overlays < list.num_overlays) {
+            mdp_wrapper::dump("Bad ov dump: ",
+                *list.overlay_list[list.processed_overlays]);
+        }
+        return false;
+    }
+
+    return true;
+}
+
 
 //// MdpData ////////////
 bool MdpData::init(const int& dpy) {
diff --git a/liboverlay/overlayMdp.h b/liboverlay/overlayMdp.h
index daaeaf2..843556b 100644
--- a/liboverlay/overlayMdp.h
+++ b/liboverlay/overlayMdp.h
@@ -72,7 +72,6 @@
     void dump() const;
     /* Return the dump in the specified buffer */
     void getDump(char *buf, size_t len);
-
     /* returns session id */
     int getPipeId() const;
     /* returns the fd associated to ctrl*/
@@ -84,14 +83,14 @@
     /* setVisualParam */
     bool setVisualParams(const MetaData_t& data);
 
+    static bool validateAndSet(MdpCtrl* mdpCtrlArray[], const int& count,
+            const int& fbFd);
 private:
     /* Perform transformation calculations */
     void doTransform();
     void doDownscale();
     /* get orient / user_data[0] */
-        int getOrient() const;
-    /* overlay get */
-    bool get();
+    int getOrient() const;
     /* returns flags from mdp structure */
     int getFlags() const;
     /* set flags to mdp structure */
diff --git a/liboverlay/pipes/overlayGenPipe.cpp b/liboverlay/pipes/overlayGenPipe.cpp
index 394a56e..9e57223 100644
--- a/liboverlay/pipes/overlayGenPipe.cpp
+++ b/liboverlay/pipes/overlayGenPipe.cpp
@@ -137,4 +137,16 @@
     return mCtrl->getPipeId();
 }
 
+bool GenericPipe::validateAndSet(GenericPipe* pipeArray[], const int& count,
+        const int& fbFd) {
+    Ctrl* ctrlArray[count];
+    memset(&ctrlArray, 0, sizeof(ctrlArray));
+
+    for(int i = 0; i < count; i++) {
+        ctrlArray[i] = pipeArray[i]->mCtrl;
+    }
+
+    return Ctrl::validateAndSet(ctrlArray, count, fbFd);
+}
+
 } //namespace overlay
diff --git a/liboverlay/pipes/overlayGenPipe.h b/liboverlay/pipes/overlayGenPipe.h
index 57e1758..813a2b3 100644
--- a/liboverlay/pipes/overlayGenPipe.h
+++ b/liboverlay/pipes/overlayGenPipe.h
@@ -75,6 +75,8 @@
     void getDump(char *buf, size_t len);
     int getPipeId();
 
+    static bool validateAndSet(GenericPipe* pipeArray[], const int& count,
+            const int& fbFd);
 private:
     /* set Closed pipe */
     bool setClosed();