Merge "hwc: Derive view frame for external display."
diff --git a/common.mk b/common.mk
index 47c455f..ae4ea61 100644
--- a/common.mk
+++ b/common.mk
@@ -36,8 +36,7 @@
     common_flags += -DMDSS_TARGET
 endif
 
-ifeq ($(call is-board-platform-in-list, mpq8092 msm_bronze msm8916), true)
-    #XXX: Replace with check from MDP when available
+ifeq ($(call is-board-platform-in-list, mpq8092), true)
     common_flags += -DVPU_TARGET
 endif
 
diff --git a/libexternal/external.cpp b/libexternal/external.cpp
index d905e0d..1268b0f 100644
--- a/libexternal/external.cpp
+++ b/libexternal/external.cpp
@@ -175,6 +175,7 @@
     int len = -1;
     char scanInfo[17];
     char *ce_info_str = NULL;
+    char *save_ptr;
     const char token[] = ", \n";
     int ce_info = -1;
     char sysFsScanInfoFilePath[MAX_SYSFS_FILE_PATH];
@@ -210,13 +211,13 @@
      */
 
     /* PT */
-    ce_info_str = strtok(scanInfo, token);
+    ce_info_str = strtok_r(scanInfo, token, &save_ptr);
     if (ce_info_str) {
         /* IT */
-        ce_info_str = strtok(NULL, token);
+        ce_info_str = strtok_r(NULL, token, &save_ptr);
         if (ce_info_str) {
             /* CE */
-            ce_info_str = strtok(NULL, token);
+            ce_info_str = strtok_r(NULL, token, &save_ptr);
             if (ce_info_str)
                 ce_info = atoi(ce_info_str);
         }
@@ -493,7 +494,6 @@
 
 void ExternalDisplay::setResolution(int ID)
 {
-    struct fb_var_screeninfo info;
     int ret = 0;
     ret = ioctl(mFd, FBIOGET_VSCREENINFO, &mVInfo);
     if(ret < 0) {
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index dc5f6ae..723267b 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -46,6 +46,9 @@
 #define VENUS_BUFFER_SIZE(args...) 0
 #endif
 
+#define ASTC_BLOCK_SIZE 16
+#define ASTC_IN_UNITS(n, unit_size)  (((n) + (unit_size) -1) / (unit_size))
+
 using namespace gralloc;
 using namespace qdutils;
 
@@ -123,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];
@@ -192,12 +197,83 @@
             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:
+                aligned_w = ASTC_IN_UNITS(width, 4);
+                aligned_h = ASTC_IN_UNITS(height, 4);
+                break;
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
+                aligned_w = ASTC_IN_UNITS(width, 5);
+                aligned_h = ASTC_IN_UNITS(height, 4);
+                break;
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
+                aligned_w = ASTC_IN_UNITS(width, 5);
+                aligned_h = ASTC_IN_UNITS(height, 5);
+                break;
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
+                aligned_w = ASTC_IN_UNITS(width, 6);
+                aligned_h = ASTC_IN_UNITS(height, 5);
+                break;
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
+                aligned_w = ASTC_IN_UNITS(width, 6);
+                aligned_h = ASTC_IN_UNITS(height, 6);
+                break;
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
+                aligned_w = ASTC_IN_UNITS(width, 8);
+                aligned_h = ASTC_IN_UNITS(height, 5);
+                break;
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
+                aligned_w = ASTC_IN_UNITS(width, 8);
+                aligned_h = ASTC_IN_UNITS(height, 6);
+                break;
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
+                aligned_w = ASTC_IN_UNITS(width, 8);
+                aligned_h = ASTC_IN_UNITS(height, 8);
+                break;
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
+                aligned_w = ASTC_IN_UNITS(width, 10);
+                aligned_h = ASTC_IN_UNITS(height, 5);
+                break;
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
+                aligned_w = ASTC_IN_UNITS(width, 10);
+                aligned_h = ASTC_IN_UNITS(height, 6);
+                break;
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
+                aligned_w = ASTC_IN_UNITS(width, 10);
+                aligned_h = ASTC_IN_UNITS(height, 8);
+                break;
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
+                aligned_w = ASTC_IN_UNITS(width, 10);
+                aligned_h = ASTC_IN_UNITS(height, 10);
+                break;
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
+                aligned_w = ASTC_IN_UNITS(width, 12);
+                aligned_h = ASTC_IN_UNITS(height, 10);
+                break;
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
+                aligned_w = ASTC_IN_UNITS(width, 12);
+                aligned_h = ASTC_IN_UNITS(height, 12);
                 break;
             default: break;
         }
@@ -335,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:
@@ -370,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:
@@ -388,33 +462,58 @@
         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:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
+            size = alignedw * alignedh * ASTC_BLOCK_SIZE;
+            break;
         default:
             ALOGE("unrecognized pixel format: 0x%x", format);
-            return -EINVAL;
+            return 0;
     }
     return size;
 }
@@ -467,9 +566,7 @@
             tileEnabled,
             alignedw,
             alignedh);
-
-    if(size)
-        size = getSize(format, width, height, alignedw, alignedh);
+    size = getSize(format, width, height, alignedw, alignedh);
 }
 
 
diff --git a/libgralloc/framebuffer.cpp b/libgralloc/framebuffer.cpp
index 3109303..a7a58dc 100644
--- a/libgralloc/framebuffer.cpp
+++ b/libgralloc/framebuffer.cpp
@@ -134,12 +134,16 @@
     memset(&module->commit, 0, sizeof(struct mdp_display_commit));
 
     struct fb_fix_screeninfo finfo;
-    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
+    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) {
+        close(fd);
         return -errno;
+    }
 
     struct fb_var_screeninfo info;
-    if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
+    if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) {
+        close(fd);
         return -errno;
+    }
 
     info.reserved[0] = 0;
     info.reserved[1] = 0;
@@ -232,8 +236,10 @@
               info.yres_virtual, info.yres*2);
     }
 
-    if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
+    if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) {
+        close(fd);
         return -errno;
+    }
 
     if (int(info.width) <= 0 || int(info.height) <= 0) {
         // the driver doesn't return that information
@@ -250,6 +256,7 @@
     metadata.op = metadata_op_frame_rate;
     if (ioctl(fd, MSMFB_METADATA_GET, &metadata) == -1) {
         ALOGE("Error retrieving panel frame rate");
+        close(fd);
         return -errno;
     }
     float fps  = metadata.data.panel_frame_rate;
@@ -289,11 +296,15 @@
          );
 
 
-    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
+    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) {
+        close(fd);
         return -errno;
+    }
 
-    if (finfo.smem_len <= 0)
+    if (finfo.smem_len <= 0) {
+        close(fd);
         return -errno;
+    }
 
     module->flags = flags;
     module->info = info;
@@ -322,6 +333,7 @@
     void* vaddr = mmap(0, fbSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
     if (vaddr == MAP_FAILED) {
         ALOGE("Error mapping the framebuffer (%s)", strerror(errno));
+        close(fd);
         return -errno;
     }
     module->framebuffer->base = intptr_t(vaddr);
@@ -373,6 +385,10 @@
 
         /* initialize our state here */
         fb_context_t *dev = (fb_context_t*)malloc(sizeof(*dev));
+        if(dev == NULL) {
+            gralloc_close(gralloc_device);
+            return status;
+        }
         memset(dev, 0, sizeof(*dev));
 
         /* initialize the procs */
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/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index 66a67d3..c56eca9 100644
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -117,6 +117,36 @@
     //v4l2_fourcc('Y', 'B', 'W', 'C'). 10 bit per component. This compressed
     //format reduces the memory access bandwidth
     HAL_PIXEL_FORMAT_YCbCr_422_I_10BIT_COMPRESSED = 0x43574259,
+
+    //Khronos ASTC formats
+    HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR    = 0x93B0,
+    HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR    = 0x93B1,
+    HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR    = 0x93B2,
+    HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR    = 0x93B3,
+    HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR    = 0x93B4,
+    HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR    = 0x93B5,
+    HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR    = 0x93B6,
+    HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR    = 0x93B7,
+    HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR   = 0x93B8,
+    HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR   = 0x93B9,
+    HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR   = 0x93BA,
+    HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR  = 0x93BB,
+    HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR  = 0x93BC,
+    HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR  = 0x93BD,
+    HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR    = 0x93D0,
+    HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR    = 0x93D1,
+    HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR    = 0x93D2,
+    HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR    = 0x93D3,
+    HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR    = 0x93D4,
+    HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR    = 0x93D5,
+    HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR    = 0x93D6,
+    HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR    = 0x93D7,
+    HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR   = 0x93D8,
+    HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR   = 0x93D9,
+    HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR   = 0x93DA,
+    HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR  = 0x93DB,
+    HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR  = 0x93DC,
+    HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR  = 0x93DD,
 };
 
 /* possible formats for 3D content*/
diff --git a/libhwcomposer/Android.mk b/libhwcomposer/Android.mk
index 72e064e..9749c69 100644
--- a/libhwcomposer/Android.mk
+++ b/libhwcomposer/Android.mk
@@ -25,10 +25,8 @@
                                  hwc_dump_layers.cpp \
                                  hwc_ad.cpp \
                                  hwc_virtual.cpp
-
-ifeq ($(call is-board-platform-in-list, mpq8092 msm_bronze msm8916), true)
+ifeq ($(call is-board-platform-in-list, mpq8092), true)
     LOCAL_SRC_FILES += hwc_vpuclient.cpp
 endif
 
-
 include $(BUILD_SHARED_LIBRARY)
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index dcad00b..1de864a 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.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.
@@ -105,17 +105,40 @@
 //Helper
 static void reset(hwc_context_t *ctx, int numDisplays,
                   hwc_display_contents_1_t** displays) {
-    for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
+
+    ctx->numActiveDisplays = 0;
+    ctx->isPaddingRound = false;
+
+    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
         // cache we need to reset it.
         // We can probably rethink that later on
-        if (LIKELY(list && list->numHwLayers > 1)) {
+        if (LIKELY(list && list->numHwLayers > 0)) {
             for(uint32_t j = 0; j < list->numHwLayers; j++) {
                 if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET)
                     list->hwLayers[j].compositionType = HWC_FRAMEBUFFER;
             }
+
+            /* For display devices like SSD and screenrecord, we cannot
+             * rely on isActive and connected attributes of dpyAttr to
+             * determine if the displaydevice is active. Hence in case if
+             * the layer-list is non-null and numHwLayers > 0, we assume
+             * the display device to be active.
+             */
+            ctx->numActiveDisplays += 1;
+
+            if((ctx->mPrevHwLayerCount[i] == 1) and (list->numHwLayers > 1)) {
+                /* If the previous cycle for dpy 'i' has 0 AppLayers and the
+                 * current cycle has atleast 1 AppLayer, padding round needs
+                 * to be invoked on current cycle to free up the resources.
+                 */
+                ctx->isPaddingRound = true;
+            }
+            ctx->mPrevHwLayerCount[i] = list->numHwLayers;
+        } else {
+            ctx->mPrevHwLayerCount[i] = 0;
         }
 
         if(ctx->mFBUpdate[i])
@@ -132,22 +155,65 @@
         ctx->mHWCVirtual->destroy(ctx, numDisplays, displays);
 }
 
+bool isEqual(float f1, float f2) {
+        return ((int)(f1*100) == (int)(f2*100)) ? true : false;
+}
+
+static void scaleDisplayFrame(hwc_context_t *ctx, int dpy,
+                            hwc_display_contents_1_t *list) {
+    float origXres = ctx->dpyAttr[dpy].xres_orig;
+    float origYres = ctx->dpyAttr[dpy].yres_orig;
+    float fakeXres = ctx->dpyAttr[dpy].xres;
+    float fakeYres = ctx->dpyAttr[dpy].yres;
+    float xresRatio = origXres / fakeXres;
+    float yresRatio = origYres / fakeYres;
+    for (size_t i = 0; i < list->numHwLayers; i++) {
+        hwc_layer_1_t *layer = &list->hwLayers[i];
+        hwc_rect_t& displayFrame = layer->displayFrame;
+        hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
+        float layerWidth = displayFrame.right - displayFrame.left;
+        float layerHeight = displayFrame.bottom - displayFrame.top;
+        float sourceWidth = sourceCrop.right - sourceCrop.left;
+        float sourceHeight = sourceCrop.bottom - sourceCrop.top;
+
+        if (isEqual(layerWidth / sourceWidth, xresRatio) &&
+                isEqual(layerHeight / sourceHeight, yresRatio))
+            break;
+
+        displayFrame.left = xresRatio * displayFrame.left;
+        displayFrame.top = yresRatio * displayFrame.top;
+        displayFrame.right = displayFrame.left + layerWidth * xresRatio;
+        displayFrame.bottom = displayFrame.top + layerHeight * yresRatio;
+    }
+}
+
 static int hwc_prepare_primary(hwc_composer_device_1 *dev,
         hwc_display_contents_1_t *list) {
     ATRACE_CALL();
     hwc_context_t* ctx = (hwc_context_t*)(dev);
     const int dpy = HWC_DISPLAY_PRIMARY;
+    bool fbComp = false;
     if (LIKELY(list && list->numHwLayers > 1) &&
             ctx->dpyAttr[dpy].isActive) {
+
+        if (ctx->dpyAttr[dpy].customFBSize)
+            scaleDisplayFrame(ctx, dpy, list);
+
         reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
         setListStats(ctx, list, dpy);
+
+        if (ctx->mVPUClient == NULL)
+            fbComp = (ctx->mMDPComp[dpy]->prepare(ctx, list) < 0);
 #ifdef VPU_TARGET
-        ctx->mVPUClient->prepare(ctx, list);
+        else
+            fbComp = (ctx->mVPUClient->prepare(ctx, dpy, list) < 0);
 #endif
-        if(ctx->mMDPComp[dpy]->prepare(ctx, list) < 0) {
+
+        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) {
             if(ctx->mCopyBit[dpy])
                 ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
@@ -171,7 +237,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.
@@ -206,7 +272,7 @@
     ctx->mRotMgr->configBegin();
     overlay::Writeback::configBegin();
 
-    for (int32_t i = numDisplays; i >= 0; i--) {
+    for (int32_t i = (numDisplays-1); i >= 0; i--) {
         hwc_display_contents_1_t *list = displays[i];
         int dpy = getDpyforExternalDisplay(ctx, i);
         switch(dpy) {
@@ -287,7 +353,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:
@@ -414,6 +484,9 @@
     case HWC_COLOR_FILL:
         value[0] = 1;
         break;
+    case HWC_MAX_WRITEBACK_WIDTH:
+        value[0] = qdutils::MAX_DISPLAY_DIM;
+        break;
     default:
         return -EINVAL;
     }
@@ -440,13 +513,15 @@
         if(ctx->mHwcDebug[dpy])
             ctx->mHwcDebug[dpy]->dumpLayers(list);
 
-        if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
+        if (ctx->mVPUClient != NULL) {
+#ifdef VPU_TARGET
+            ctx->mVPUClient->predraw(ctx, dpy, list);
+#endif
+        }
+        else if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
             ALOGE("%s: MDPComp draw failed", __FUNCTION__);
             ret = -1;
         }
-#ifdef VPU_TARGET
-        ctx->mVPUClient->draw(ctx, list);
-#endif
 
         //TODO We dont check for SKIP flag on this layer because we need PAN
         //always. Last layer is always FB
@@ -467,6 +542,11 @@
             ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy);
             ret = -1;
         }
+
+#ifdef VPU_TARGET
+        if (ctx->mVPUClient != NULL)
+            ctx->mVPUClient->draw(ctx, dpy, list);
+#endif
     }
 
     closeAcquireFds(list);
@@ -538,7 +618,7 @@
 {
     int ret = 0;
     hwc_context_t* ctx = (hwc_context_t*)(dev);
-    for (uint32_t i = 0; i <= numDisplays; i++) {
+    for (uint32_t i = 0; i < numDisplays; i++) {
         hwc_display_contents_1_t* list = displays[i];
         int dpy = getDpyforExternalDisplay(ctx, i);
         switch(dpy) {
@@ -599,7 +679,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);
@@ -697,6 +777,8 @@
     if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
         struct hwc_context_t *dev;
         dev = (hwc_context_t*)malloc(sizeof(*dev));
+        if(dev == NULL)
+            return status;
         memset(dev, 0, sizeof(*dev));
 
         //Initialize hwc context
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..d47853a 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;
@@ -519,7 +517,7 @@
                src.format != HAL_PIXEL_FORMAT_RGBA_8888) {
            format = HAL_PIXEL_FORMAT_RGBX_8888;
        }
-       if (0 == alloc_buffer(&tmpHnd, tmp_w, tmp_h, format, usage)){
+       if (0 == alloc_buffer(&tmpHnd, tmp_w, tmp_h, format, usage) && tmpHnd) {
             copybit_image_t tmp_dst;
             copybit_rect_t tmp_rect;
             tmp_dst.w = tmp_w;
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..bebcc18 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 {
 
@@ -58,11 +61,12 @@
   mDpy(dpy) {
     char dumpPropStr[PROPERTY_VALUE_MAX];
     if(mDpy) {
-        strncpy(mDisplayName, "external", strlen("external"));
+        strlcpy(mDisplayName, "external", sizeof(mDisplayName));
     } else {
-        strncpy(mDisplayName, "primary", strlen("primary"));
+        strlcpy(mDisplayName, "primary", sizeof(mDisplayName));
     }
-    sprintf(mDumpPropKeyDisplayType, "debug.sf.dump.%s", (char *)mDisplayName);
+    snprintf(mDumpPropKeyDisplayType, sizeof(mDumpPropKeyDisplayType),
+             "debug.sf.dump.%s", (char *)mDisplayName);
 
     if ((property_get("debug.sf.dump.enable", dumpPropStr, NULL) > 0)) {
         if(!strncmp(dumpPropStr, "true", strlen("true"))) {
@@ -110,7 +114,7 @@
     if ((property_get("debug.sf.dump.png", dumpPropStr, NULL) > 0) &&
             (strncmp(dumpPropStr, mDumpPropStrPng, PROPERTY_VALUE_MAX - 1))) {
         // Strings exist & not equal implies it has changed, so trigger a dump
-        strncpy(mDumpPropStrPng, dumpPropStr, PROPERTY_VALUE_MAX - 1);
+        strlcpy(mDumpPropStrPng, dumpPropStr, sizeof(mDumpPropStrPng));
         mDumpCntLimPng = atoi(dumpPropStr);
         if (mDumpCntLimPng > MAX_ALLOWED_FRAMEDUMPS) {
             ALOGW("Warning: Using debug.sf.dump.png %d (= max)",
@@ -119,7 +123,7 @@
         }
         mDumpCntLimPng = (mDumpCntLimPng < 0) ? 0: mDumpCntLimPng;
         if (mDumpCntLimPng) {
-            sprintf(mDumpDirPng,
+            snprintf(mDumpDirPng, sizeof(mDumpDirPng),
                     "/data/sfdump.png.%04d.%02d.%02d.%02d.%02d.%02d",
                     dumpTime.tm_year + 1900, dumpTime.tm_mon + 1,
                     dumpTime.tm_mday, dumpTime.tm_hour,
@@ -140,7 +144,7 @@
     if ((property_get("debug.sf.dump", dumpPropStr, NULL) > 0) &&
             (strncmp(dumpPropStr, mDumpPropStrRaw, PROPERTY_VALUE_MAX - 1))) {
         // Strings exist & not equal implies it has changed, so trigger a dump
-        strncpy(mDumpPropStrRaw, dumpPropStr, PROPERTY_VALUE_MAX - 1);
+        strlcpy(mDumpPropStrRaw, dumpPropStr, sizeof(mDumpPropStrRaw));
         mDumpCntLimRaw = atoi(dumpPropStr);
         if (mDumpCntLimRaw > MAX_ALLOWED_FRAMEDUMPS) {
             ALOGW("Warning: Using debug.sf.dump %d (= max)",
@@ -149,7 +153,7 @@
         }
         mDumpCntLimRaw = (mDumpCntLimRaw < 0) ? 0: mDumpCntLimRaw;
         if (mDumpCntLimRaw) {
-            sprintf(mDumpDirRaw,
+            snprintf(mDumpDirRaw, sizeof(mDumpDirRaw),
                     "/data/sfdump.raw.%04d.%02d.%02d.%02d.%02d.%02d",
                     dumpTime.tm_year + 1900, dumpTime.tm_mon + 1,
                     dumpTime.tm_mday, dumpTime.tm_hour,
@@ -274,11 +278,13 @@
     bool needDumpRaw = (mDumpCntrRaw <= mDumpCntLimRaw)? true:false;
 
     if (needDumpPng) {
-        sprintf(dumpLogStrPng, "[png-dump-frame: %03d of %03d]", mDumpCntrPng,
+        snprintf(dumpLogStrPng, sizeof(dumpLogStrPng),
+            "[png-dump-frame: %03d of %03d]", mDumpCntrPng,
             mDumpCntLimPng);
     }
     if (needDumpRaw) {
-        sprintf(dumpLogStrRaw, "[raw-dump-frame: %03d of %03d]", mDumpCntrRaw,
+        snprintf(dumpLogStrRaw, sizeof(dumpLogStrRaw),
+            "[raw-dump-frame: %03d of %03d]", mDumpCntrRaw,
             mDumpCntLimRaw);
     }
 
@@ -308,7 +314,8 @@
         char dumpFilename[PATH_MAX];
         SkBitmap *tempSkBmp = new SkBitmap();
         SkBitmap::Config tempSkBmpConfig = SkBitmap::kNo_Config;
-        sprintf(dumpFilename, "%s/sfdump%03d.layer%d.%s.png", mDumpDirPng,
+        snprintf(dumpFilename, sizeof(dumpFilename),
+            "%s/sfdump%03d.layer%d.%s.png", mDumpDirPng,
             mDumpCntrPng, layerIndex, mDisplayName);
 
         switch (hnd->format) {
@@ -344,7 +351,8 @@
     if (needDumpRaw && hnd->base) {
         char dumpFilename[PATH_MAX];
         bool bResult = false;
-        sprintf(dumpFilename, "%s/sfdump%03d.layer%d.%dx%d.%s.%s.raw",
+        snprintf(dumpFilename, sizeof(dumpFilename),
+            "%s/sfdump%03d.layer%d.%dx%d.%s.%s.raw",
             mDumpDirRaw, mDumpCntrRaw,
             layerIndex, getWidth(hnd), getHeight(hnd),
             pixFormatStr, mDisplayName);
@@ -366,65 +374,65 @@
 
     switch(format) {
         case HAL_PIXEL_FORMAT_RGBA_8888:
-            strcpy(pixFormatStr, "RGBA_8888");
+            strlcpy(pixFormatStr, "RGBA_8888", sizeof(pixFormatStr));
             break;
         case HAL_PIXEL_FORMAT_RGBX_8888:
-            strcpy(pixFormatStr, "RGBX_8888");
+            strlcpy(pixFormatStr, "RGBX_8888", sizeof(pixFormatStr));
             break;
         case HAL_PIXEL_FORMAT_RGB_888:
-            strcpy(pixFormatStr, "RGB_888");
+            strlcpy(pixFormatStr, "RGB_888", sizeof(pixFormatStr));
             break;
         case HAL_PIXEL_FORMAT_RGB_565:
-            strcpy(pixFormatStr, "RGB_565");
+            strlcpy(pixFormatStr, "RGB_565", sizeof(pixFormatStr));
             break;
         case HAL_PIXEL_FORMAT_BGRA_8888:
-            strcpy(pixFormatStr, "BGRA_8888");
+            strlcpy(pixFormatStr, "BGRA_8888", sizeof(pixFormatStr));
             break;
         case HAL_PIXEL_FORMAT_YV12:
-            strcpy(pixFormatStr, "YV12");
+            strlcpy(pixFormatStr, "YV12", sizeof(pixFormatStr));
             break;
         case HAL_PIXEL_FORMAT_YCbCr_422_SP:
-            strcpy(pixFormatStr, "YCbCr_422_SP_NV16");
+            strlcpy(pixFormatStr, "YCbCr_422_SP_NV16", sizeof(pixFormatStr));
             break;
         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-            strcpy(pixFormatStr, "YCrCb_420_SP_NV21");
+            strlcpy(pixFormatStr, "YCrCb_420_SP_NV21", sizeof(pixFormatStr));
             break;
         case HAL_PIXEL_FORMAT_YCbCr_422_I:
-            strcpy(pixFormatStr, "YCbCr_422_I_YUY2");
+            strlcpy(pixFormatStr, "YCbCr_422_I_YUY2", sizeof(pixFormatStr));
             break;
         case HAL_PIXEL_FORMAT_YCrCb_422_I:
-            strlcpy(pixFormatStr, "YCrCb_422_I_YVYU",
-                            sizeof("YCrCb_422_I_YVYU"));
+            strlcpy(pixFormatStr, "YCrCb_422_I_YVYU", sizeof(pixFormatStr));
             break;
         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
-            strcpy(pixFormatStr, "NV12_ENCODEABLE");
+            strlcpy(pixFormatStr, "NV12_ENCODEABLE", sizeof(pixFormatStr));
             break;
         case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
-            strcpy(pixFormatStr, "YCbCr_420_SP_TILED_TILE_4x2");
+            strlcpy(pixFormatStr, "YCbCr_420_SP_TILED_TILE_4x2",
+                   sizeof(pixFormatStr));
             break;
         case HAL_PIXEL_FORMAT_YCbCr_420_SP:
-            strcpy(pixFormatStr, "YCbCr_420_SP");
+            strlcpy(pixFormatStr, "YCbCr_420_SP", sizeof(pixFormatStr));
             break;
         case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
-            strcpy(pixFormatStr, "YCrCb_420_SP_ADRENO");
+            strlcpy(pixFormatStr, "YCrCb_420_SP_ADRENO", sizeof(pixFormatStr));
             break;
         case HAL_PIXEL_FORMAT_YCrCb_422_SP:
-            strcpy(pixFormatStr, "YCrCb_422_SP");
+            strlcpy(pixFormatStr, "YCrCb_422_SP", sizeof(pixFormatStr));
             break;
         case HAL_PIXEL_FORMAT_R_8:
-            strcpy(pixFormatStr, "R_8");
+            strlcpy(pixFormatStr, "R_8", sizeof(pixFormatStr));
             break;
         case HAL_PIXEL_FORMAT_RG_88:
-            strcpy(pixFormatStr, "RG_88");
+            strlcpy(pixFormatStr, "RG_88", sizeof(pixFormatStr));
             break;
         case HAL_PIXEL_FORMAT_INTERLACE:
-            strcpy(pixFormatStr, "INTERLACE");
+            strlcpy(pixFormatStr, "INTERLACE", sizeof(pixFormatStr));
             break;
         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
-            strcpy(pixFormatStr, "YCbCr_420_SP_VENUS");
+            strlcpy(pixFormatStr, "YCbCr_420_SP_VENUS", sizeof(pixFormatStr));
             break;
         default:
-            sprintf(pixFormatStr, "Unknown0x%X", format);
+            snprintf(pixFormatStr, sizeof(pixFormatStr), "Unknown0x%X", format);
             break;
     }
 }
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index 6bc2e75..78a05e9 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012, 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.
@@ -45,7 +45,7 @@
 }
 
 IFBUpdate::IFBUpdate(hwc_context_t *ctx, const int& dpy) : mDpy(dpy) {
-    size_t size;
+    size_t size = 0;
     getBufferAttributes(ctx->dpyAttr[mDpy].xres,
             ctx->dpyAttr[mDpy].yres,
             HAL_PIXEL_FORMAT_RGBA_8888,
@@ -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) {}
@@ -167,12 +173,12 @@
         // Dont do wormhole calculation when extDownscale is enabled on External
         if(ctx->listStats[mDpy].isDisplayAnimating && mDpy) {
             sourceCrop = layer->displayFrame;
-            displayFrame = sourceCrop;
         } else if((!mDpy ||
-                   (mDpy && !extOrient
-                   && !ctx->dpyAttr[mDpy].mDownScaleMode))
-                   && (extOnlyLayerIndex == -1)) {
-            if(!qdutils::MDPVersion::getInstance().is8x26()) {
+                  (mDpy && !extOrient
+                  && !ctx->dpyAttr[mDpy].mDownScaleMode))
+                  && (extOnlyLayerIndex == -1)) {
+            if(!qdutils::MDPVersion::getInstance().is8x26() &&
+                !ctx->dpyAttr[mDpy].customFBSize) {
                 getNonWormholeRegion(list, sourceCrop);
                 displayFrame = sourceCrop;
             }
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 8008d39..6ff1aa3 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__);
@@ -424,8 +419,8 @@
                   __FUNCTION__);
         ret = false;
     } else if(ctx->isPaddingRound) {
-        ctx->isPaddingRound = false;
-        ALOGD_IF(isDebug(), "%s: padding round",__FUNCTION__);
+        ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
+                 __FUNCTION__,mDpy);
         ret = false;
     }
     return ret;
@@ -451,13 +446,13 @@
         if(!isValidRect(visibleRect)) {
             mCurrentFrame.drop[i] = true;
             mCurrentFrame.dropCount++;
+            continue;
         }
 
         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;
 
         hwc_rect_t res  = getIntersection(visibleRect, dstRect);
 
@@ -472,17 +467,17 @@
         }else {
             /* Reset frame ROI when any layer which needs scaling also needs ROI
              * cropping */
-            if((res_w != dst_w || res_h != dst_h) &&
-                    needsScaling (layer)) {
+            if((res_w != dst_w || res_h != dst_h) && needsScaling (layer)) {
                 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);
+            /* deduct any opaque region from visibleRect */
+            if (layer->blending == HWC_BLENDING_NONE)
+                visibleRect = deductRect(visibleRect, res);
+        }
     }
     return true;
 }
@@ -514,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);
@@ -636,7 +630,6 @@
     }
 
     mCurrentFrame.fbCount = 0;
-    mCurrentFrame.fbZ = -1;
     memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
            sizeof(mCurrentFrame.isFBComposed));
     mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
@@ -728,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;
     }
 
@@ -738,7 +731,8 @@
     int stagesForMDP = min(sMaxPipesPerMixer, ctx->mOverlay->availablePipes(
             mDpy, Overlay::MIXER_DEFAULT));
     //If MDP has X possible stages, it can take X layers.
-    const int batchSize = numAppLayers - (stagesForMDP - 1); //1 for FB
+    const int batchSize = (numAppLayers - mCurrentFrame.dropCount) -
+                                               (stagesForMDP - 1); //1 for FB
 
     if(batchSize <= 0) {
         ALOGD_IF(isDebug(), "%s: Not attempting", __FUNCTION__);
@@ -746,20 +740,50 @@
     }
 
     int minBatchStart = -1;
+    int minBatchEnd = -1;
     size_t minBatchPixelCount = SIZE_MAX;
 
-    for(int i = 0; i <= numAppLayers - batchSize; i++) {
+    /* Iterate through the layer list to find out a contigous batch of batchSize
+     * non-dropped layers with loweest pixel count */
+    for(int i = 0; i <= (numAppLayers - batchSize); i++) {
+        if(mCurrentFrame.drop[i])
+            continue;
+
+        int batchCount = batchSize;
         uint32_t batchPixelCount = 0;
-        for(int j = i; j < i + batchSize; j++) {
-            hwc_layer_1_t* layer = &list->hwLayers[j];
-            hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
-            batchPixelCount += (crop.right - crop.left) *
+        int j = i;
+        for(; j < numAppLayers && batchCount; j++){
+            if(!mCurrentFrame.drop[j]) {
+                hwc_layer_1_t* layer = &list->hwLayers[j];
+                hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
+                hwc_rect_t dst = layer->displayFrame;
+
+                /* If we have a valid ROI, count pixels only for the MDP fetched
+                 * region of the buffer */
+                if((ctx->listStats[mDpy].roi.w != ctx->dpyAttr[mDpy].xres) ||
+                   (ctx->listStats[mDpy].roi.h != ctx->dpyAttr[mDpy].yres)) {
+                    hwc_rect_t roi;
+                    roi.left = ctx->listStats[mDpy].roi.x;
+                    roi.top = ctx->listStats[mDpy].roi.y;
+                    roi.right = roi.left + ctx->listStats[mDpy].roi.w;
+                    roi.bottom = roi.top + ctx->listStats[mDpy].roi.h;
+
+                    /* valid ROI means no scaling layer is composed. So check
+                     * only intersection to find actual fetched pixels */
+                    crop  = getIntersection(roi, dst);
+                }
+
+                batchPixelCount += (crop.right - crop.left) *
                     (crop.bottom - crop.top);
+                batchCount--;
+            }
         }
 
-        if(batchPixelCount < minBatchPixelCount) {
+        /* we dont want to program any batch of size lesser than batchSize */
+        if(!batchCount && (batchPixelCount < minBatchPixelCount)) {
             minBatchPixelCount = batchPixelCount;
             minBatchStart = i;
+            minBatchEnd = j-1;
         }
     }
 
@@ -769,8 +793,10 @@
         return false;
     }
 
+    /* non-dropped layers falling ouside the selected batch will be marked for
+     * MDP */
     for(int i = 0; i < numAppLayers; i++) {
-        if(i < minBatchStart || i >= minBatchStart + batchSize) {
+        if((i < minBatchStart || i > minBatchEnd) && !mCurrentFrame.drop[i] ) {
             hwc_layer_1_t* layer = &list->hwLayers[i];
             if(not isSupportedForMDPComp(ctx, layer)) {
                 ALOGD_IF(isDebug(), "%s: MDP unsupported layer found at %d",
@@ -784,10 +810,12 @@
 
     mCurrentFrame.fbZ = minBatchStart;
     mCurrentFrame.fbCount = batchSize;
-    mCurrentFrame.mdpCount = mCurrentFrame.layerCount - batchSize;
+    mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
+             mCurrentFrame.dropCount;
 
-    ALOGD_IF(isDebug(), "%s: fbZ %d batchSize %d",
-                __FUNCTION__, mCurrentFrame.fbZ, batchSize);
+    ALOGD_IF(isDebug(), "%s: fbZ %d batchSize %d fbStart: %d fbEnd: %d",
+             __FUNCTION__, mCurrentFrame.fbZ, batchSize, minBatchStart,
+             minBatchEnd);
 
     if(sEnable4k2kYUVSplit){
         adjustForSourceSplit(ctx, list);
@@ -804,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;
     }
 
@@ -821,7 +849,9 @@
     const int fullScreenLayers = bwLeft * 1000000000 / (ctx->dpyAttr[mDpy].xres
             * ctx->dpyAttr[mDpy].yres * bpp * panelRefRate);
 
-    const int fbBatchSize = numAppLayers - (fullScreenLayers - 1);
+    const int fbBatchSize = (numAppLayers - mCurrentFrame.dropCount)
+            - (fullScreenLayers - 1);
+
     //If batch size is not at least 2, we aren't really preferring MDP, since
     //only 1 layer going to GPU could actually translate into an entire FB
     //needed to be fetched by MDP, thus needing more b/w rather than less.
@@ -830,28 +860,43 @@
         return false;
     }
 
-    //Top-most layers constitute FB batch
-    const int fbBatchStart = numAppLayers - fbBatchSize;
+    //Find top fbBatchSize non-dropped layers to get your batch
+    int fbStart = -1, fbEnd = -1, batchCount = fbBatchSize;
+    for(int i = numAppLayers - 1; i >= 0; i--) {
+        if(mCurrentFrame.drop[i])
+            continue;
 
-    //Bottom-most layers constitute MDP batch
-    for(int i = 0; i < fbBatchStart; i++) {
-        hwc_layer_1_t* layer = &list->hwLayers[i];
-        if(not isSupportedForMDPComp(ctx, layer)) {
-            ALOGD_IF(isDebug(), "%s: MDP unsupported layer found at %d",
-                    __FUNCTION__, i);
-            reset(ctx);
-            return false;
+        if(fbEnd < 0)
+            fbEnd = i;
+
+        if(!(--batchCount)) {
+            fbStart = i;
+            break;
         }
-        mCurrentFrame.isFBComposed[i] = false;
     }
 
-    mCurrentFrame.fbZ = fbBatchStart;
-    mCurrentFrame.fbCount = fbBatchSize;
-    mCurrentFrame.mdpCount = mCurrentFrame.layerCount - fbBatchSize;
+    //Bottom layers constitute MDP batch
+    for(int i = 0; i < fbStart; i++) {
+        if((i < fbStart || i > fbEnd) && !mCurrentFrame.drop[i] ) {
+            hwc_layer_1_t* layer = &list->hwLayers[i];
+            if(not isSupportedForMDPComp(ctx, layer)) {
+                ALOGD_IF(isDebug(), "%s: MDP unsupported layer found at %d",
+                         __FUNCTION__, i);
+                reset(ctx);
+                return false;
+            }
+            mCurrentFrame.isFBComposed[i] = false;
+        }
+    }
 
-    ALOGD_IF(isDebug(), "%s: FB Z %d, num app layers %d, MDP Batch Size %d",
-                __FUNCTION__, mCurrentFrame.fbZ, numAppLayers,
-                numAppLayers - fbBatchSize);
+    mCurrentFrame.fbZ = fbStart;
+    mCurrentFrame.fbCount = fbBatchSize;
+    mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount
+                                                      - mCurrentFrame.dropCount;
+
+    ALOGD_IF(isDebug(), "%s: FB Z %d, app layers %d, non-dropped layers: %d, "
+             "MDP Batch Size %d",__FUNCTION__, mCurrentFrame.fbZ, numAppLayers,
+             numAppLayers - mCurrentFrame.dropCount, mCurrentFrame.mdpCount);
 
     if(sEnable4k2kYUVSplit){
         adjustForSourceSplit(ctx, list);
@@ -866,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;
@@ -1075,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);
@@ -1121,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++;
@@ -1235,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;
 }
@@ -1247,10 +1296,6 @@
         return false;
     }
 
-    if(!arePipesAvailable(ctx, list)) {
-        return false;
-    }
-
     double size = calcMDPBytesRead(ctx, list);
     if(!bandwidthCheck(ctx, size)) {
         ALOGD_IF(isDebug(), "%s: Exceeds bandwidth",__FUNCTION__);
@@ -1360,11 +1405,10 @@
     const int numLayers = ctx->listStats[mDpy].numAppLayers;
     MDPVersion& mdpVersion = qdutils::MDPVersion::getInstance();
 
-    //number of app layers exceeds MAX_NUM_APP_LAYERS fall back to GPU
-    //do not cache the information for next draw cycle.
-    if(numLayers > MAX_NUM_APP_LAYERS) {
-        ALOGI("%s: Number of App layers exceeded the limit ",
-        __FUNCTION__);
+    //Do not cache the information for next draw cycle.
+    if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
+        ALOGI("%s: Unsupported layer count for mdp composition",
+                __FUNCTION__);
         mCachedFrame.reset();
         return -1;
     }
@@ -1431,12 +1475,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;
@@ -1461,10 +1502,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;
@@ -1504,58 +1545,6 @@
                            &PipeLayerPair.rot);
 }
 
-bool MDPCompNonSplit::arePipesAvailable(hwc_context_t *ctx,
-        hwc_display_contents_1_t* list) {
-    overlay::Overlay& ov = *ctx->mOverlay;
-    int numPipesNeeded = mCurrentFrame.mdpCount;
-    int availPipes = ov.availablePipes(mDpy, Overlay::MIXER_DEFAULT);
-
-    //Reserve pipe for FB
-    if(mCurrentFrame.fbCount)
-        availPipes -= 1;
-
-    if(numPipesNeeded > availPipes) {
-        ALOGD_IF(isDebug(), "%s: Insufficient pipes, dpy %d needed %d, avail %d",
-                __FUNCTION__, mDpy, numPipesNeeded, availPipes);
-        return false;
-    }
-
-    if(not areVGPipesAvailable(ctx, list)) {
-        return false;
-    }
-
-    return true;
-}
-
-bool MDPCompNonSplit::areVGPipesAvailable(hwc_context_t *ctx,
-        hwc_display_contents_1_t* list) {
-    overlay::Overlay& ov = *ctx->mOverlay;
-    int pipesNeeded = 0;
-    for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
-        if(!mCurrentFrame.isFBComposed[i]) {
-            hwc_layer_1_t* layer = &list->hwLayers[i];
-            hwc_rect_t dst = layer->displayFrame;
-            private_handle_t *hnd = (private_handle_t *)layer->handle;
-            if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
-                pipesNeeded = pipesNeeded + 2;
-            }
-            else if(isYuvBuffer(hnd)) {
-                pipesNeeded++;
-            }
-        }
-    }
-
-    int availableVGPipes = ov.availablePipes(mDpy, ovutils::OV_MDP_PIPE_VG);
-    if(pipesNeeded > availableVGPipes) {
-        ALOGD_IF(isDebug(), "%s: Insufficient VG pipes for video layers"
-                "dpy %d needed %d, avail %d",
-                __FUNCTION__, mDpy, pipesNeeded, availableVGPipes);
-        return false;
-    }
-
-    return true;
-}
-
 bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
         hwc_display_contents_1_t* list) {
     for(int index = 0; index < mCurrentFrame.layerCount; index++) {
@@ -1565,7 +1554,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;
             }
         }
@@ -1579,6 +1568,10 @@
 
         if(isYuvBuffer(hnd)) {
             type = MDPCOMP_OV_VG;
+        } else if(qdutils::MDPVersion::getInstance().is8x26() &&
+                (ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024)) {
+            if(qhwc::needsScaling(layer))
+                type = MDPCOMP_OV_RGB;
         } else if(!qhwc::needsScaling(layer)
             && Overlay::getDMAMode() != Overlay::DMA_BLOCK_MODE
             && ctx->mMDP.version >= qdutils::MDSS_V5) {
@@ -1749,110 +1742,9 @@
     }
 }
 
-int MDPCompSplit::pipesNeeded(hwc_context_t *ctx,
-        hwc_display_contents_1_t* list,
-        int mixer) {
-    int pipesNeeded = 0;
-    const int xres = ctx->dpyAttr[mDpy].xres;
-
-    const int lSplit = getLeftSplit(ctx, mDpy);
-
-    for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
-        if(!mCurrentFrame.isFBComposed[i]) {
-            hwc_layer_1_t* layer = &list->hwLayers[i];
-            hwc_rect_t dst = layer->displayFrame;
-            if(mixer == Overlay::MIXER_LEFT && dst.left < lSplit) {
-                pipesNeeded++;
-            } else if(mixer == Overlay::MIXER_RIGHT && dst.right > lSplit) {
-                pipesNeeded++;
-            }
-        }
-    }
-    return pipesNeeded;
-}
-
-bool MDPCompSplit::arePipesAvailable(hwc_context_t *ctx,
-        hwc_display_contents_1_t* list) {
-    overlay::Overlay& ov = *ctx->mOverlay;
-    int totalPipesNeeded = 0;
-
-    for(int i = 0; i < Overlay::MIXER_MAX; i++) {
-        int numPipesNeeded = pipesNeeded(ctx, list, i);
-        int availPipes = ov.availablePipes(mDpy, i);
-
-        //Reserve pipe(s)for FB
-        if(mCurrentFrame.fbCount)
-            numPipesNeeded += 1;
-
-        totalPipesNeeded += numPipesNeeded;
-
-        //Per mixer check.
-        if(numPipesNeeded > availPipes) {
-            ALOGD_IF(isDebug(), "%s: Insufficient pipes for "
-                     "dpy %d mixer %d needed %d, avail %d",
-                     __FUNCTION__, mDpy, i, numPipesNeeded, availPipes);
-            return false;
-        }
-    }
-
-    //Per display check, since unused pipes can get counted twice.
-    int totalPipesAvailable = ov.availablePipes(mDpy);
-    if(totalPipesNeeded > totalPipesAvailable) {
-        ALOGD_IF(isDebug(), "%s: Insufficient pipes for "
-                "dpy %d needed %d, avail %d",
-                __FUNCTION__, mDpy, totalPipesNeeded, totalPipesAvailable);
-        return false;
-    }
-
-    if(not areVGPipesAvailable(ctx, list)) {
-        return false;
-    }
-
-    return true;
-}
-
-bool MDPCompSplit::areVGPipesAvailable(hwc_context_t *ctx,
-        hwc_display_contents_1_t* list) {
-    overlay::Overlay& ov = *ctx->mOverlay;
-    int pipesNeeded = 0;
-    const int lSplit = getLeftSplit(ctx, mDpy);
-    for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
-        if(!mCurrentFrame.isFBComposed[i]) {
-            hwc_layer_1_t* layer = &list->hwLayers[i];
-            hwc_rect_t dst = layer->displayFrame;
-            private_handle_t *hnd = (private_handle_t *)layer->handle;
-            if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
-                if((dst.left > lSplit)||(dst.right < lSplit)){
-                    pipesNeeded = pipesNeeded + 2;
-                    continue;
-                }
-            }
-            if(isYuvBuffer(hnd)) {
-                if(dst.left < lSplit) {
-                    pipesNeeded++;
-                }
-                if(dst.right > lSplit) {
-                    pipesNeeded++;
-                }
-            }
-        }
-    }
-
-    int availableVGPipes = ov.availablePipes(mDpy, ovutils::OV_MDP_PIPE_VG);
-    if(pipesNeeded > availableVGPipes) {
-        ALOGD_IF(isDebug(), "%s: Insufficient VG pipes for video layers"
-                "dpy %d needed %d, avail %d",
-                __FUNCTION__, mDpy, pipesNeeded, availableVGPipes);
-        return false;
-    }
-
-    return true;
-}
-
 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;
@@ -1886,7 +1778,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;
                 }
             }
@@ -2047,8 +1939,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..f2a8eda 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -136,9 +136,6 @@
     /* configures MPD pipes */
     virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
                           PipeLayerPair& pipeLayerPair) = 0;
-    /* Checks for pipes needed versus pipes available */
-    virtual bool arePipesAvailable(hwc_context_t *ctx,
-            hwc_display_contents_1_t* list) = 0;
     /* 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,
@@ -172,8 +169,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 +242,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 {
@@ -270,18 +265,10 @@
     virtual bool allocLayerPipes(hwc_context_t *ctx,
                                  hwc_display_contents_1_t* list);
 
-    /* Checks for pipes needed versus pipes available */
-    virtual bool arePipesAvailable(hwc_context_t *ctx,
-            hwc_display_contents_1_t* list);
-
-    /* Checks for video pipes needed versus pipes available */
-    virtual bool areVGPipesAvailable(hwc_context_t *ctx,
-            hwc_display_contents_1_t* list);
-
     /* 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,
@@ -311,14 +298,6 @@
     virtual bool allocLayerPipes(hwc_context_t *ctx,
                                  hwc_display_contents_1_t* list);
 
-    /* Checks for pipes needed versus pipes available */
-    virtual bool arePipesAvailable(hwc_context_t *ctx,
-            hwc_display_contents_1_t* list);
-
-    /* Checks for video pipes needed versus pipes available */
-    virtual bool areVGPipesAvailable(hwc_context_t *ctx,
-            hwc_display_contents_1_t* list);
-
     /* 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,
@@ -327,9 +306,6 @@
     /* configures 4kx2k yuv layer*/
     virtual int configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
             PipeLayerPair& PipeLayerPair);
-
-    int pipesNeeded(hwc_context_t *ctx, hwc_display_contents_1_t* list,
-            int mixer);
 };
 
 }; //namespace
diff --git a/libhwcomposer/hwc_qclient.cpp b/libhwcomposer/hwc_qclient.cpp
index 8c99d64..2320bc0 100644
--- a/libhwcomposer/hwc_qclient.cpp
+++ b/libhwcomposer/hwc_qclient.cpp
@@ -31,6 +31,7 @@
 #include <IQService.h>
 #include <hwc_utils.h>
 #include <hwc_vpuclient.h>
+#include <mdp_version.h>
 
 #define QCLIENT_DEBUG 0
 
@@ -94,16 +95,19 @@
     return result;
 }
 
+#ifdef VPU_TARGET
 static android::status_t vpuCommand(hwc_context_t *ctx,
         uint32_t command,
         const Parcel* inParcel,
         Parcel* outParcel) {
     status_t result = NO_INIT;
-#ifdef VPU_TARGET
-    result = ctx->mVPUClient->processCommand(command, inParcel, outParcel);
+#ifdef QCOM_BSP
+    if(qdutils::MDPVersion::getInstance().is8092())
+        result = ctx->mVPUClient->processCommand(command, inParcel, outParcel);
 #endif
     return result;
 }
+#endif
 
 static void setExtOrientation(hwc_context_t *ctx, uint32_t orientation) {
     ctx->mExtOrientation = orientation;
@@ -126,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();
@@ -181,11 +186,12 @@
         Parcel* outParcel) {
     status_t ret = NO_ERROR;
 
+#ifdef VPU_TARGET
     if (command > IQService::VPU_COMMAND_LIST_START &&
         command < IQService::VPU_COMMAND_LIST_END) {
         return vpuCommand(mHwcContext, command, inParcel, outParcel);
     }
-
+#endif
     switch(command) {
         case IQService::SECURING:
             securing(mHwcContext, inParcel->readInt32());
@@ -213,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 5692ef1..d2104ed 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.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.
@@ -54,6 +54,34 @@
 
 namespace qhwc {
 
+bool isValidResolution(hwc_context_t *ctx, uint32_t xres, uint32_t yres)
+{
+    return !((xres > qdutils::MAX_DISPLAY_DIM &&
+                !isDisplaySplit(ctx, HWC_DISPLAY_PRIMARY)) ||
+            (xres < MIN_DISPLAY_XRES || yres < MIN_DISPLAY_YRES));
+}
+
+void changeResolution(hwc_context_t *ctx, int xres_orig, int yres_orig) {
+    //Store original display resolution.
+    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres_orig = xres_orig;
+    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres_orig = yres_orig;
+    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].customFBSize = false;
+
+    char property[PROPERTY_VALUE_MAX] = {'\0'};
+    char *yptr = NULL;
+    if (property_get("debug.hwc.fbsize", property, NULL) > 0) {
+        yptr = strcasestr(property,"x");
+        int xres = atoi(property);
+        int yres = atoi(yptr + 1);
+        if (isValidResolution(ctx,xres,yres) &&
+                 xres != xres_orig && yres != yres_orig) {
+            ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres = xres;
+            ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres = yres;
+            ctx->dpyAttr[HWC_DISPLAY_PRIMARY].customFBSize = true;
+        }
+    }
+}
+
 static int openFramebufferDevice(hwc_context_t *ctx)
 {
     struct fb_fix_screeninfo finfo;
@@ -117,6 +145,9 @@
     ctx->dpyAttr[HWC_DISPLAY_PRIMARY].ydpi = ydpi;
     ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period = 1000000000l / fps;
 
+    //To change resolution of primary display
+    changeResolution(ctx, info.xres, info.yres);
+
     //Unblank primary on first boot
     if(ioctl(fb_fd, FBIOBLANK,FB_BLANK_UNBLANK) < 0) {
         ALOGE("%s: Failed to unblank display", __FUNCTION__);
@@ -182,12 +213,17 @@
         ctx->dpyAttr[i].mAsHeightRatio = 0;
     }
 
+    for (uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
+        ctx->mPrevHwLayerCount[i] = 0;
+    }
+
     MDPComp::init(ctx);
     ctx->mAD = new AssertiveDisplay(ctx);
 
     ctx->vstate.enable = false;
     ctx->vstate.fakevsync = false;
     ctx->mExtOrientation = 0;
+    ctx->numActiveDisplays = 1;
 
     //Right now hwc starts the service but anybody could do it, or it could be
     //independent process as well.
@@ -200,8 +236,11 @@
     // Initialize device orientation to its default orientation
     ctx->deviceOrientation = 0;
     ctx->mBufferMirrorMode = false;
+    ctx->mVPUClient = NULL;
+
 #ifdef VPU_TARGET
-    ctx->mVPUClient = new VPUClient();
+    if(qdutils::MDPVersion::getInstance().is8092())
+        ctx->mVPUClient = new VPUClient(ctx);
 #endif
 
     ALOGI("Initializing Qualcomm Hardware Composer");
@@ -238,9 +277,8 @@
     }
 
 #ifdef VPU_TARGET
-    if(ctx->mVPUClient) {
+    if(ctx->mVPUClient != NULL)
         delete ctx->mVPUClient;
-    }
 #endif
 
     for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
@@ -452,7 +490,7 @@
     // the position based on the new width and height
     if ((extOrientation & HWC_TRANSFORM_ROT_90) &&
                         isOrientationPortrait(ctx)) {
-        hwc_rect_t r;
+        hwc_rect_t r = {0, 0, 0, 0};
         //Calculate the position
         xRatio = (outPos.x - xPos)/width;
         // GetaspectRatio -- tricky to get the correct aspect ratio
@@ -460,7 +498,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;
@@ -787,7 +824,7 @@
     ctx->dpyAttr[dpy].mActionSafePresent = isActionSafePresent(ctx, dpy);
 
     trimList(ctx, list, dpy);
-    optimizeLayerRects(ctx, list, dpy);
+    optimizeLayerRects(list);
 
     // Calculate view frame of ext display from primary resolution
     // and primary device orientation.
@@ -887,6 +924,7 @@
     if(prevYuvCount != ctx->listStats[dpy].yuvCount) {
         ctx->mVideoTransFlag = true;
     }
+
     if(dpy == HWC_DISPLAY_PRIMARY) {
         ctx->mAD->markDoable(ctx, list);
     }
@@ -998,8 +1036,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;
@@ -1106,14 +1142,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 =
@@ -1199,7 +1233,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));
@@ -1222,38 +1255,42 @@
     for(uint32_t i = 0; i < ctx->mLayerRotMap[dpy]->getCount(); i++) {
         int rotFd = ctx->mRotMgr->getRotDevFd();
         int rotReleaseFd = -1;
+        overlay::Rotator* currRot = ctx->mLayerRotMap[dpy]->getRot(i);
+        hwc_layer_1_t* currLayer = ctx->mLayerRotMap[dpy]->getLayer(i);
+        if((currRot == NULL) || (currLayer == NULL)) {
+            continue;
+        }
         struct mdp_buf_sync rotData;
         memset(&rotData, 0, sizeof(rotData));
         rotData.acq_fen_fd =
-                &ctx->mLayerRotMap[dpy]->getLayer(i)->acquireFenceFd;
+                &currLayer->acquireFenceFd;
         rotData.rel_fen_fd = &rotReleaseFd; //driver to populate this
-        rotData.session_id = ctx->mLayerRotMap[dpy]->getRot(i)->getSessId();
+        rotData.session_id = currRot->getSessId();
         int ret = 0;
         ret = ioctl(rotFd, MSMFB_BUFFER_SYNC, &rotData);
         if(ret < 0) {
             ALOGE("%s: ioctl MSMFB_BUFFER_SYNC failed for rot sync, err=%s",
                     __FUNCTION__, strerror(errno));
         } else {
-            close(ctx->mLayerRotMap[dpy]->getLayer(i)->acquireFenceFd);
+            close(currLayer->acquireFenceFd);
             //For MDP to wait on.
-            ctx->mLayerRotMap[dpy]->getLayer(i)->acquireFenceFd =
+            currLayer->acquireFenceFd =
                     dup(rotReleaseFd);
             //A buffer is free to be used by producer as soon as its copied to
             //rotator
-            ctx->mLayerRotMap[dpy]->getLayer(i)->releaseFenceFd =
+            currLayer->releaseFenceFd =
                     rotReleaseFd;
         }
     }
 
-    //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;
@@ -1293,6 +1330,7 @@
               dpy, list->numHwLayers);
     }
 
+    LayerProp *layerProp = ctx->layerProp[dpy];
     for(uint32_t i = 0; i < list->numHwLayers; i++) {
         if(list->hwLayers[i].compositionType == HWC_OVERLAY ||
            list->hwLayers[i].compositionType == HWC_BLIT ||
@@ -1304,9 +1342,17 @@
                 // Release all the app layer fds immediately,
                 // if animation is in progress.
                 list->hwLayers[i].releaseFenceFd = -1;
-            } else if(list->hwLayers[i].releaseFenceFd < 0) {
-                //If rotator has not already populated this field.
-                list->hwLayers[i].releaseFenceFd = dup(releaseFd);
+            } else if(list->hwLayers[i].releaseFenceFd < 0 &&
+                    !(layerProp[i].mFlags & HWC_VPUCOMP)) {
+                //If rotator has not already populated this field
+                // & if it's a not VPU layer
+                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);
+                }
             }
         }
     }
@@ -1343,13 +1389,19 @@
                 ovutils::OV_MDP_BLEND_FG_PREMULT);
     }
 
+    if (layer->flags & HWC_VPU_PIPE) {
+        ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_VPU_PIPE);
+    }
+
     if(isYuvBuffer(hnd)) {
         if(isSecureBuffer(hnd)) {
             ovutils::setMdpFlags(mdpFlags,
                     ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
         }
+        // in mpq, deinterlacing is done in vpu
         if(metadata && (metadata->operation & PP_PARAM_INTERLACED) &&
-                metadata->interlaced) {
+                metadata->interlaced &&
+                (!qdutils::MDPVersion::getInstance().is8092())) {
             ovutils::setMdpFlags(mdpFlags,
                     ovutils::OV_MDP_DEINTERLACE);
         }
@@ -1537,6 +1589,16 @@
     uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
     Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
 
+#ifdef VPU_TARGET
+    if(ctx->mVPUClient != NULL &&
+            ctx->mVPUClient->supportedVPULayer(dpy, layer)) {
+        whf.format = getMdpFormat(
+                ctx->mVPUClient->getLayerFormat(dpy, layer));
+        whf.w = ctx->mVPUClient->getWidth(dpy, layer);
+        whf.h = ctx->mVPUClient->getHeight(dpy, layer);
+    }
+#endif
+
     // Handle R/B swap
     if (layer->flags & HWC_FORMAT_RB_SWAP) {
         if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
@@ -1566,7 +1628,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__);
@@ -1644,6 +1706,16 @@
     uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
     Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
 
+#ifdef VPU_TARGET
+    if(ctx->mVPUClient != NULL &&
+            ctx->mVPUClient->supportedVPULayer(dpy, layer)) {
+        whf.format = getMdpFormat(
+                ctx->mVPUClient->getLayerFormat(dpy, layer));
+        whf.w = ctx->mVPUClient->getWidth(dpy, layer);
+        whf.h = ctx->mVPUClient->getHeight(dpy, layer);
+    }
+#endif
+
     // Handle R/B swap
     if (layer->flags & HWC_FORMAT_RB_SWAP) {
         if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
@@ -1773,8 +1845,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;
@@ -1796,7 +1866,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__);
@@ -1930,7 +2000,33 @@
     ctx->layerProp[dpy] = new LayerProp[numAppLayers];
 }
 
-void BwcPM::setBwc(hwc_context_t *ctx, const hwc_rect_t& crop,
+/* Since we fake non-Hybrid WFD solution as external display, this
+ * function helps us in determining the priority between external
+ * (hdmi/non-Hybrid WFD display) and virtual display devices(SSD/
+ * screenrecord). This can be removed once wfd-client migrates to
+ * using virtual-display api's.
+ */
+bool canUseMDPforVirtualDisplay(hwc_context_t* ctx,
+                                const hwc_display_contents_1_t *list) {
+
+    /* We rely on the fact that for pure virtual display solution
+     * list->outbuf will be a non-NULL handle.
+     *
+     * If there are three active displays (which means there is one
+     * primary, one external and one virtual active display)
+     * we give mdss/mdp hw resources(pipes,smp,etc) for external
+     * display(hdmi/non-Hybrid WFD display) rather than for virtual
+     * display(SSD/screenrecord)
+     */
+
+    if(list->outbuf and (ctx->numActiveDisplays == HWC_NUM_DISPLAY_TYPES)) {
+        return false;
+    }
+
+    return true;
+}
+
+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 2b889f5..8293505 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -35,6 +35,8 @@
 #define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
 #define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
 #define MAX_NUM_APP_LAYERS 32
+#define MIN_DISPLAY_XRES 200
+#define MIN_DISPLAY_YRES 200
 
 //Fwrd decls
 struct hwc_context_t;
@@ -95,6 +97,13 @@
     bool mActionSafePresent;
     int mAsWidthRatio;
     int mAsHeightRatio;
+
+    //If property fbsize set via adb shell debug.hwc.fbsize = XRESxYRES
+    //following fields are used.
+    bool customFBSize;
+    uint32_t xres_orig;
+    uint32_t yres_orig;
+
 };
 
 struct ListStats {
@@ -127,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);
 };
@@ -136,12 +145,14 @@
 enum {
     HWC_MDPCOMP = 0x00000001,
     HWC_COPYBIT = 0x00000002,
+    HWC_VPUCOMP = 0x00000004,
 };
 
 // HAL specific features
 enum {
     HWC_COLOR_FILL = 0x00000008,
     HWC_FORMAT_RB_SWAP = 0x00000040,
+    HWC_VPU_PIPE = 0x00000200,
 };
 
 class LayerRotMap {
@@ -230,6 +241,9 @@
 bool isGLESOnlyComp(hwc_context_t *ctx, const int& dpy);
 void reset_layer_prop(hwc_context_t* ctx, int dpy, int numAppLayers);
 
+bool canUseMDPforVirtualDisplay(hwc_context_t* ctx,
+                                const hwc_display_contents_1_t *list);
+
 //Helper function to dump logs
 void dumpsys_log(android::String8& buf, const char* fmt, ...);
 
@@ -238,8 +252,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);
 
@@ -386,7 +399,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;
         }
@@ -396,7 +409,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;
         }
@@ -475,6 +488,10 @@
     eAnimationState mAnimationState[HWC_NUM_DISPLAY_TYPES];
     qhwc::HWCVirtualBase *mHWCVirtual;
 
+    // stores the #numHwLayers of the previous frame
+    // for each display device
+    int mPrevHwLayerCount[HWC_NUM_DISPLAY_TYPES];
+
     // stores the primary device orientation
     int deviceOrientation;
     //Securing in progress indicator
@@ -491,15 +508,14 @@
     int mExtOrientation;
     //Flags the transition of a video session
     bool mVideoTransFlag;
-
     //Used for SideSync feature
     //which overrides the mExtOrientation
     bool mBufferMirrorMode;
-
     qhwc::LayerRotMap *mLayerRotMap[HWC_NUM_DISPLAY_TYPES];
-
     // Panel reset flag will be set if BTA check fails
     bool mPanelResetStatus;
+    // number of active Displays
+    int numActiveDisplays;
 };
 
 namespace qhwc {
diff --git a/libhwcomposer/hwc_virtual.cpp b/libhwcomposer/hwc_virtual.cpp
index 51ade32..cc29d45 100644
--- a/libhwcomposer/hwc_virtual.cpp
+++ b/libhwcomposer/hwc_virtual.cpp
@@ -62,14 +62,12 @@
         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;
 
     //Cleanup virtual display objs, since there is no explicit disconnect
-    if(ctx->dpyAttr[dpy].connected &&
-        (numDisplays <= HWC_NUM_PHYSICAL_DISPLAY_TYPES ||
-        displays[dpy] == NULL)) {
+    if(ctx->dpyAttr[dpy].connected && (displays[dpy] == NULL)) {
         ctx->dpyAttr[dpy].connected = false;
 
         if(ctx->mFBUpdate[dpy]) {
@@ -80,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.");
+        }
     }
 }
 
@@ -101,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;
@@ -114,7 +122,7 @@
 
         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);
         }
     }
     return 0;
@@ -129,11 +137,22 @@
         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)
+                format = HAL_PIXEL_FORMAT_RGBX_8888;
             Writeback::getInstance()->setOutputFormat(
-                                    utils::getMdpFormat(ohnd->format));
+                                    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);
@@ -142,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;
@@ -180,14 +205,15 @@
 
     if (LIKELY(list && list->numHwLayers > 1) &&
             ctx->dpyAttr[dpy].isActive &&
-            ctx->dpyAttr[dpy].connected) {
+            ctx->dpyAttr[dpy].connected &&
+            canUseMDPforVirtualDisplay(ctx,list)) {
         reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
         if(!ctx->dpyAttr[dpy].isPause) {
             ctx->dpyAttr[dpy].isConfiguring = false;
             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 {
             /* Virtual Display is in Pause state.
@@ -211,7 +237,8 @@
 
     if (LIKELY(list) && ctx->dpyAttr[dpy].isActive &&
             ctx->dpyAttr[dpy].connected &&
-            !ctx->dpyAttr[dpy].isPause) {
+            (!ctx->dpyAttr[dpy].isPause) &&
+            canUseMDPforVirtualDisplay(ctx,list)) {
         uint32_t last = list->numHwLayers - 1;
         hwc_layer_1_t *fbLayer = &list->hwLayers[last];
         int fd = -1; //FenceFD from the Copybit(valid in async mode)
@@ -257,7 +284,7 @@
 
     closeAcquireFds(list);
 
-    if (list && !ctx->mVirtualonExtActive && (list->retireFenceFd < 0) ) {
+    if (list && list->outbuf && (list->retireFenceFd < 0) ) {
         // SF assumes HWC waits for the acquire fence and returns a new fence
         // that signals when we're done. Since we don't wait, and also don't
         // touch the buffer, we can just handle the acquire fence back to SF
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_vpuclient.cpp b/libhwcomposer/hwc_vpuclient.cpp
index 23c6841..6904efc 100644
--- a/libhwcomposer/hwc_vpuclient.cpp
+++ b/libhwcomposer/hwc_vpuclient.cpp
@@ -1,93 +1,964 @@
 /*
-* 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 copyright
-*      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.
-*/
+ * 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
+ * met:
+ *    * Redistributions of source code must retain the above copyright
+ *      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.  INNO 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 INCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING INANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
 
 #include <dlfcn.h>
 #include "hwc_vpuclient.h"
-#include "hwc_utils.h"
-#include <vpu/vpu.h>
 #include <binder/Parcel.h>
-
+#include "hwc_fbupdate.h"
+#include <vpu/vpu.h>
 
 using namespace vpu;
 using namespace android;
+using namespace overlay::utils;
+namespace ovutils = overlay::utils;
+
 namespace qhwc {
 
-VPUClient::VPUClient()
+VPUClient::VPUClient(hwc_context_t *ctx)
 {
     mVPULib = dlopen("libvpu.so", RTLD_NOW);
-    VPU* (*init)();
-    *(void **) &init =  dlsym(mVPULib, "getObject");
-    if(init)
-        mVPU = init();
-    else
-        mVPU = NULL;
+    VPU* (*getObject)();
+
+    mVPU = NULL;
+    if (mVPULib == NULL) {
+        ALOGE("%s: Cannot open libvpu.so object", __FUNCTION__);
+        return;
+    }
+
+    *(void **) &getObject =  dlsym(mVPULib, "getObject");
+    if (getObject) {
+        mVPU = getObject();
+        ALOGI("Initializing VPU client..");
+
+       // calling vpu init
+        if (mVPU->init() == NO_ERROR) {
+            // passing display attributes to libvpu
+            ALOGD_IF(isDebug(), "%s: VFM init successful!", __FUNCTION__);
+
+            DispAttr_t attr;
+            attr.width = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
+            attr.height = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
+            attr.fp100s = (ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period) ?
+              1000000000/(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period/100):0;
+            mVPU->setDisplayAttr((DISPLAY_ID)HWC_DISPLAY_PRIMARY, attr);
+
+            ALOGD_IF(isDebug(),"%s: Display attr: width:%d height:%d fp100s:%d",
+                    __FUNCTION__, attr.width, attr.height, attr.fp100s);
+
+            // memsetting the pipe structure to 0
+            memset(mProp, 0, sizeof(mProp));
+
+            mDebugLogs = 0;
+            // enable logs
+            char property[PROPERTY_VALUE_MAX];
+            if ( property_get("debug.vpuclient.logs", property, NULL) > 0 )
+                mDebugLogs = atoi(property);
+
+            // allocating memory for LayerList
+            for (int i = 0; i < HWC_NUM_DISPLAY_TYPES; ++i)
+                vList[i] = (LayerList*) malloc(sizeof(LayerList));
+        }
+        else {
+            ALOGE("Error: VPU init failed!");
+            mVPU = NULL;
+        }
+    }
 }
 
 VPUClient::~VPUClient()
 {
+    // freeing LayerList
+    for (int i = 0; i < HWC_NUM_DISPLAY_TYPES; ++i) {
+        if (vList[i])
+            free(vList[i]);
+    }
+
     void (*destroy) (VPU*);
     *(void **) &destroy = dlsym(mVPULib, "deleteObject");
     dlclose(mVPULib);
 }
 
-int VPUClient::prepare(hwc_context_t *ctx,
-                                hwc_display_contents_1_t* list)
+void setLayer(hwc_layer_1_t *layer, Layer *vLayer)
 {
-    int err = 0;
-    if(!mVPU)
-        return err;
-    // * Check VPU status
-    // * Check session availability
-    // * Other individual checks
-    // Do not pass hwc context/list
-    // Mark buffers to be drawn for VPU
-    return err;
+    // setting handle info in vLayer
+    vLayer->handle = (private_handle_t *)(layer->handle);
+
+    if (vLayer->handle) {
+        vLayer->srcStride.width = getWidth(vLayer->handle);
+        vLayer->srcStride.height = getHeight(vLayer->handle);
+    }
+
+    // setting source crop
+    hwc_rect_t sourceRect = integerizeSourceCrop(layer->sourceCropf);
+    vLayer->srcRect.left = sourceRect.left;
+    vLayer->srcRect.top  = sourceRect.top;
+    vLayer->srcRect.right = sourceRect.right;
+    vLayer->srcRect.bottom = sourceRect.bottom;
+
+    // setting destination crop
+    vLayer->tgtRect.left = layer->displayFrame.left;
+    vLayer->tgtRect.top = layer->displayFrame.top;
+    vLayer->tgtRect.right = layer->displayFrame.right;
+    vLayer->tgtRect.bottom = layer->displayFrame.bottom;
+
+    if (layer->flags & HWC_GEOMETRY_CHANGED)
+        vLayer->inFlags |= GEOMETRY_CHANGED;
+
+    vLayer->acquireFenceFd = layer->acquireFenceFd;
+
+    if (layer->compositionType == HWC_FRAMEBUFFER_TARGET || isSkipLayer(layer))
+        vLayer->inFlags |= SKIP_LAYER;
 }
 
-int VPUClient::draw(hwc_context_t *ctx,
-                             hwc_display_contents_1_t* list)
+int VPUClient::setupVpuSession(hwc_context_t *ctx, int display,
+                                            hwc_display_contents_1_t* list)
+{
+    memset(vList[display], 0, sizeof(LayerList));
+    memset(mProp, 0, sizeof(mProp));
+    mNumVpuLayers = 0;
+
+    // setting up the layer
+    LayerList *vpuList = vList[display];
+    vpuList->numLayers = list->numHwLayers;
+    for (unsigned int i=0; i<(list->numHwLayers); ++i) {
+        hwc_layer_1_t *layer = &list->hwLayers[i];
+        Layer *vLayer = &vpuList->layers[i];
+        VpuLayerProp* prop = &mProp[display][i];
+
+        // Storing the sourceCropf, as it's going to be changed for overlay Set
+        // will be restored after overlay set in prepare.
+        prop->sourceCropf = layer->sourceCropf;
+
+        // filling up the vpu list
+        setLayer(layer, vLayer);
+        ALOGD_IF(isDebug2(), "%s:Done setting lyr:%d for VFM", __FUNCTION__, i);
+    }
+
+    if (mVPU->setupVpuSession((DISPLAY_ID)display, vpuList) != NO_ERROR) {
+        //error in vpu prepare
+        ALOGE("%s: ERROR in VPU::setupVpuSession", __FUNCTION__);
+        return -1;
+    }
+    ALOGD_IF(isDebug2(), "%s: Done VFM: setupVpuSession", __FUNCTION__);
+
+    mGpuFallback = true;
+    LayerProp *layerProp = ctx->layerProp[display];
+    // check if the pipeID is already set for this layer, then will need to
+    // ensure that it is reserved in overlay
+    for (unsigned int i=0; i<(vpuList->numLayers); ++i) {
+        hwc_layer_1_t *layer = &list->hwLayers[i];
+        Layer *vLayer = &vpuList->layers[i];
+        VpuLayerProp* prop = &mProp[display][i];
+
+        if (vLayer->outFlags & VPU_LAYER) {
+            ALOGD_IF(isDebug(), "%s: VPU supported layer:%d", __FUNCTION__, i);
+
+            mNumVpuLayers++;
+            mGpuFallback = false;
+            // Reserving the pipe used in last iteration for the same layer
+            if ((vLayer->outFlags & RESERVE_PREV_PIPES) &&
+                                            vLayer->sDestPipes.numPipes > 0) {
+                prop->pipeCount = vLayer->sDestPipes.numPipes;
+                if (prop->pipeCount == 1) {
+                    setPipeId(prop, vLayer->sDestPipes.pipe[0]);
+                    ALOGD_IF(isDebug(), "%s: VPU: Reserved pipe:%d",
+                            __FUNCTION__, prop->pipeID[0]);
+                }
+                else if (prop->pipeCount == 2) {
+                    setPipeId(prop, vLayer->sDestPipes.pipe[0],
+                                                    vLayer->sDestPipes.pipe[1]);
+                    ALOGD_IF(isDebug(), "%s: VPU: Reserved lpipe:%d, rpipe:%d",
+                            __FUNCTION__, prop->pipeID[0], prop->pipeID[1]);
+                }
+                else {
+                    ALOGE("%s: Invalid pipeCount for resevation", __FUNCTION__);
+                }
+            }
+            else {
+                ALOGD_IF(isDebug(), "%s: 1st vid frame for VPU", __FUNCTION__);
+                prop->firstBuffer = true;
+            }
+
+            // marking the layer pipes for vpu.
+            prop->vpuLayer = true;
+            prop->layer = layer;
+            layer->flags |= HWC_VPU_PIPE;
+
+            // getting image width and height
+            prop->width = layer->displayFrame.right - layer->displayFrame.left;
+            prop->height = layer->displayFrame.bottom - layer->displayFrame.top;
+
+            //setting source crop = dest crop (only for layers drawn by vpu,
+            // since we know it will be scaled up/down by vpu)
+            layer->sourceCropf.left = 0.0;
+            layer->sourceCropf.top = 0.0;
+            layer->sourceCropf.right = (float) prop->width;
+            layer->sourceCropf.bottom = (float) prop->height;
+
+            // setting the flag so that mdpComp wont recognize it as the MDPCOMP
+            layerProp[i].mFlags |= HWC_VPUCOMP;
+
+            // TODO: need to get the proper solution for color fill
+
+            // storing locally the vpu supported format from VFM
+            prop->format = vLayer->vpuOutPixFmt;
+            ALOGD_IF(isDebug(), "%s: MDP: sourceCropf: w:%d h:%d format:%d",
+                    __FUNCTION__, prop->width, prop->height, prop->format);
+        }
+    }
+    return 0;
+}
+
+bool VPUClient::allocResLayerPipes(hwc_context_t* ctx, int dpy,
+                                         hwc_display_contents_1_t* list)
+{
+    overlay::Overlay& ov = *ctx->mOverlay;
+    for (unsigned int i=0; i<(list->numHwLayers); ++i) {
+        int pipeid = -1;
+        VpuLayerProp* prop = &mProp[dpy][i];
+
+        // checking if there is already a reserved pipe for this layer
+        // then use the same allocated pipe for this layer
+        getPipeId(prop, pipeid);
+
+        if (pipeid != -1) {
+            // there is a reserved pipe for this layer.
+            ovutils::eDest dest = ov.reservePipe(pipeid);
+            if (dest == ovutils::OV_INVALID) {
+                ALOGE("%s: Unable to get reserved pipe: layer#%d",
+                        __FUNCTION__, i);
+                return false;
+            }
+
+            // setting dest locally
+            setDest(prop, dest);
+            ALOGD_IF(isDebug(), "%s: Reserving pipe:%d, dest:%d ", __FUNCTION__,
+                    pipeid, dest);
+        }
+        else {
+            ALOGD_IF(isDebug2(), "%s: No reserved pipe for layer:%d",
+                    __FUNCTION__, i);
+        }
+    }
+    return true;
+}
+
+bool VPUClient::allocLayerPipes(hwc_context_t* ctx, int dpy,
+                                         hwc_display_contents_1_t* list)
+{
+    // checking if the pipes are reserved for any layer,
+    // if yes, then updating the index of the pipes
+    if (!allocResLayerPipes(ctx, dpy, list)) {
+        ALOGE("%s: Reserved pipe alloc failed", __FUNCTION__);
+        return false;
+    }
+
+    for (unsigned int i=0; i<(list->numHwLayers); ++i) {
+        hwc_layer_1_t* layer = &list->hwLayers[i];
+        private_handle_t *hnd = (private_handle_t *)layer->handle;
+        VpuLayerProp* prop = &mProp[dpy][i];
+        int pipe = -1;
+        overlay::Overlay& ov = *ctx->mOverlay;
+
+        // only care about the layers supported by VPU
+        if (!prop->vpuLayer)
+            continue;
+
+        // continue if this layer has reserved pipe
+        getPipeId(prop, pipe);
+        if (pipe != -1)
+            continue;
+
+        ovutils::eDest dest = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, dpy,
+                overlay::Overlay::MIXER_DEFAULT);
+        if (dest == ovutils::OV_INVALID) {
+            ALOGE("%s: Unable to allocate pipe for layer#%d", __FUNCTION__, i);
+            return false;
+        }
+
+        // setting dest locally
+        setDest(prop, dest);
+        ALOGD_IF(isDebug(), "%s: Newly allocated pipe_dest:%d", __FUNCTION__,
+                dest);
+    }
+    return true;
+}
+
+bool VPUClient::allocResLayerPipesSplit(hwc_context_t* ctx, int dpy,
+                                         hwc_display_contents_1_t* list)
+{
+    overlay::Overlay& ov = *ctx->mOverlay;
+    for (unsigned int i=0; i<(list->numHwLayers); ++i) {
+        int lpipeid = -1;
+        int rpipeid = -1;
+        VpuLayerProp* prop = &mProp[dpy][i];
+
+        // checking if there is already a reserved pipe for this layer
+        // then use the same allocated pipe for this layer
+        getPipeId(prop, lpipeid, rpipeid);
+
+        if (lpipeid != -1 && rpipeid != -1) {
+            ovutils::eDest ldest = ov.reservePipe(lpipeid);
+            if (ldest == ovutils::OV_INVALID) {
+                ALOGD_IF(isDebug(), "%s: Unable to get reserved pipe-lsplit: "
+                         "layer#%d", __FUNCTION__, i);
+                return false;
+            }
+
+            ovutils::eDest rdest = ov.reservePipe(rpipeid);
+            if (rdest == ovutils::OV_INVALID) {
+                ALOGD_IF(isDebug(), "%s: Unable to get reserved pipe-rsplit: "
+                         "layer#%d", __FUNCTION__, i);
+                return false;
+            }
+
+            setDest(prop, ldest, rdest);
+            ALOGD_IF(isDebug(), "%s: Reserve lpipe:%d, ldest:%d, rpipe:%d, "
+                    "rdest:%d", __FUNCTION__, lpipeid, ldest, rpipeid, rdest);
+        }
+        else if (lpipeid != -1 || rpipeid != -1) {
+            ALOGE("%s: Bug: only one pipe reserved!", __FUNCTION__);
+            return false;
+        }
+    }
+    return true;
+}
+
+bool VPUClient::allocLayerPipesSplit(hwc_context_t* ctx, int dpy,
+                                         hwc_display_contents_1_t* list)
+{
+    // checking if the pipes are reserved for any layer,
+    // if yes, then updating the index of the pipes
+    if (!allocResLayerPipesSplit(ctx, dpy, list)) {
+        ALOGE("%s: Reserved pipe alloc failed", __FUNCTION__);
+        return false;
+    }
+
+    for (unsigned int i=0; i<(list->numHwLayers); ++i) {
+        hwc_layer_1_t* layer = &list->hwLayers[i];
+        private_handle_t *hnd = (private_handle_t *)layer->handle;
+        VpuLayerProp* prop = &mProp[dpy][i];
+        int lpipe, rpipe;
+        overlay::Overlay& ov = *ctx->mOverlay;
+
+        // only care about the layers supported by VPU
+        if (!prop->vpuLayer)
+            continue;
+
+        // only care about the layers supported by VPU
+        getPipeId(prop, lpipe, rpipe);
+        if (lpipe != -1 && rpipe != -1)
+            continue;
+
+        ovutils::eDest ldest = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, dpy,
+                overlay::Overlay::MIXER_LEFT);
+        if (ldest == ovutils::OV_INVALID) {
+            ALOGE("%s: Unable to allocate pipe for layer#%d", __FUNCTION__, i);
+            return false;
+        }
+
+        ovutils::eDest rdest = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, dpy,
+                overlay::Overlay::MIXER_RIGHT);
+        if (rdest == ovutils::OV_INVALID) {
+            ALOGE("%s: Unable to allocate pipe for layer#%d", __FUNCTION__, i);
+            return false;
+        }
+
+        // setting dests locally
+        setDest(prop, ldest, rdest);
+        ALOGD_IF(isDebug(), "%s: Newly allocated ldest:%d rdest:%d",
+                __FUNCTION__, ldest, rdest);
+    }
+    return true;
+}
+
+bool VPUClient::configureLayers(hwc_context_t* ctx, int dpy,
+                                         hwc_display_contents_1_t* list)
+{
+    for (unsigned int i=0; i<(list->numHwLayers); ++i) {
+        VpuLayerProp* prop = &mProp[dpy][i];
+        hwc_layer_1_t* layer = &list->hwLayers[i];
+
+        if (!prop->vpuLayer)
+            continue;
+
+        eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
+        eZorder zOrder = static_cast<eZorder>(i);
+        eIsFg isFg = IS_FG_OFF;
+        setPipeCount(prop, 1);
+        eDest dest = (eDest) getDest(prop, 0);
+
+        ALOGD_IF(isDebug(),"%s: configuring: layer:%p z_order:%d dest_pipe:%d",
+                __FUNCTION__, layer, zOrder, dest);
+
+        if (configureNonSplit(ctx, layer, dpy, mdpFlags, zOrder, isFg,
+                            dest, NULL)) {
+            ALOGE("%s: Failed to configure overlay for layer %d",
+                    __FUNCTION__, i);
+            return false;
+        }
+        ALOGD_IF(isDebug2(), "%s: layer:%d configured!", __FUNCTION__, i);
+
+        // Pipe is successfully allocated for this layer; retrieving it from
+        // overlay
+        int pipeId = ctx->mOverlay->getPipeId((eDest) getDest(prop, 0));
+        setPipeId(prop, pipeId);
+
+        ALOGD_IF(isDebug(), "%s: allocated pipe:%d layer:%d", __FUNCTION__,
+                    pipeId, i);
+    }
+    return true;
+}
+
+bool VPUClient::configureLayersSplit(hwc_context_t* ctx, int dpy,
+                                         hwc_display_contents_1_t* list)
+{
+    for (unsigned int i=0; i<(list->numHwLayers); ++i) {
+        VpuLayerProp* prop = &mProp[dpy][i];
+        hwc_layer_1_t* layer = &list->hwLayers[i];
+
+        if (!prop->vpuLayer)
+            continue;
+
+        eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
+        eZorder zOrder = static_cast<eZorder>(i);
+        eIsFg isFg = IS_FG_OFF;
+        setPipeCount(prop, 2);
+        eDest ldest = (eDest) getDest(prop, 0);
+        eDest rdest = (eDest) getDest(prop, 1);
+
+        ALOGD_IF(isDebug(),"%s: configuring: layer:%p z_order:%d dest_pipeL:%d"
+                "dest_pipeR:%d",__FUNCTION__, layer, zOrder, ldest, rdest);
+
+        if (configureSplit(ctx, layer, dpy, mdpFlags, zOrder, isFg, ldest,
+                            rdest, NULL)) {
+            ALOGE("%s: Failed to configure overlay for layer %d",
+                    __FUNCTION__, i);
+            return false;
+        }
+        ALOGD_IF(isDebug2(), "%s: layer:%d configured!", __FUNCTION__, i);
+
+        // Pipe is successfully allocated for this layer; retrieving it from
+        // overlay
+        int lpipeId = ctx->mOverlay->getPipeId((eDest) getDest(prop, 0));
+        int rpipeId = ctx->mOverlay->getPipeId((eDest) getDest(prop, 1));
+        setPipeId(prop, lpipeId, rpipeId);
+
+        ALOGD_IF(isDebug(), "%s: allocated l-pipe:%d - r-pipe:%d for layer:%d",
+                __FUNCTION__, lpipeId, rpipeId, i);
+    }
+    return true;
+}
+
+void VPUClient::setMDPCompLayerFlags(hwc_context_t *ctx, int dpy,
+                                   hwc_display_contents_1_t* list)
+{
+    LayerProp *layerProp = ctx->layerProp[dpy];
+
+    // disableGpu only disables gpu for video layer. The expected behavior is to
+    // show a blank screen in case VPU doesnt support a video layer, and gpu
+    // fallback is disabled by the user.
+    bool disableGpu = false;
+    char property[PROPERTY_VALUE_MAX];
+    if ((property_get("persist.hwc.noGpuFallback", property, NULL) > 0) &&
+        (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
+            (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
+        ALOGD_IF(isDebug(), "%s: GPU fallback is disabled through prop",
+                __FUNCTION__);
+        disableGpu = true;
+    }
+
+    // no layers are supported by vpu
+    if (mGpuFallback && !disableGpu) {
+        ALOGD_IF(isDebug(), "%s: No VPU supported layers - Falling back to GPU",
+                __FUNCTION__);
+        return;
+    }
+
+    for (unsigned int i=0; i<(list->numHwLayers); ++i) {
+        hwc_layer_1_t* layer = &(list->hwLayers[i]);
+        VpuLayerProp* prop = &mProp[dpy][i];
+        private_handle_t *hnd = (private_handle_t *)layer->handle;
+
+        // mark vpu layers as HWC_OVERLAY, and those video layers that
+        // are not supported by vpu and gpu fallback is disabled by the
+        // user.
+        if (prop->vpuLayer || (isYuvBuffer(hnd) && disableGpu)) {
+            layer->compositionType = HWC_OVERLAY;
+            layer->hints |= HWC_HINT_CLEAR_FB;
+            ALOGD_IF(isDebug(), "%s: Marking layer:%d as overlay",
+                    __FUNCTION__, i);
+        }
+    }
+}
+
+int VPUClient::prepare(hwc_context_t *ctx, int display,
+            hwc_display_contents_1_t* list)
+{
+    if (!mVPU) {
+        return -1;
+    }
+
+    const int numLayers = ctx->listStats[display].numAppLayers;
+    //number of app layers exceeds MAX_NUM_APP_LAYERS fall back to GPU
+    //do not cache the information for next draw cycle.
+    if (numLayers > MAX_NUM_APP_LAYERS) {
+        ALOGE("%s: Number of App layers exceeded the limit ",__FUNCTION__);
+        return -1;
+    }
+
+    if (setupVpuSession(ctx, display, list)) {
+        ALOGD_IF(isDebug(), "%s: Vpu session setup failed! ",__FUNCTION__);
+        return -1;
+    }
+
+    LayerProp *layerProp = ctx->layerProp[display];
+    bool isSplit = isDisplaySplit(ctx, display);
+    ALOGD_IF(isDebug2(), "%s: Split Pipe:%d ", __FUNCTION__,
+            isSplit ? 1 : 0);
+
+    // setting up the layer
+    LayerList *vpuList = vList[display];
+    vpuList->numLayers = list->numHwLayers;
+
+    // Prepare FB Update at z-0
+    if (numLayers > mNumVpuLayers) {
+        if (!ctx->mFBUpdate[display]->prepare(ctx, list, mNumVpuLayers)) {
+            ALOGD_IF(isDebug(), "%s configure framebuffer failed",
+                    __FUNCTION__);
+            return -1;
+        }
+    }
+
+    // Allocate pipe for layers
+    if (!isSplit ? !allocLayerPipes(ctx, display, list) :
+                 !allocLayerPipesSplit(ctx, display, list)) {
+        ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
+        return -1;
+    }
+
+    // Configure layers
+    if (!isSplit ? !configureLayers(ctx, display, list) :
+                 !configureLayersSplit(ctx, display, list)) {
+        ALOGD_IF(isDebug(), "%s: Unable to configure MDP pipes", __FUNCTION__);
+        return -1;
+    }
+
+    // Set layer flags for MDP/VPU composition
+    setMDPCompLayerFlags(ctx, display, list);
+
+    for (unsigned int i=0; i<(list->numHwLayers); ++i) {
+        VpuLayerProp* prop = &mProp[display][i];
+
+        if (!prop->vpuLayer)
+            continue;
+
+        hwc_layer_1_t *layer = &list->hwLayers[i];
+        Layer *vLayer = &vpuList->layers[i];
+
+        // re-storing the sourceCropf, as it was changed in setVpuSession for
+        // overlay set
+        layer->sourceCropf = prop->sourceCropf;
+
+        // updating the pipe info inside vfm list
+        if ( prop->pipeCount > 0  && prop->pipeCount <= MAX_PIPES_PER_LAYER ) {
+            vLayer->sDestPipes.numPipes = prop->pipeCount;
+
+            for (int j=0; j < prop->pipeCount; ++j) {
+                // Setting pipe for VPU
+                vLayer->sDestPipes.pipe[j] = prop->pipeID[j];
+            }
+        }
+    }
+
+    if (mVPU->prepare((DISPLAY_ID)display, vpuList) != NO_ERROR) {
+        //error in vpu prepare
+        ALOGE("%s: ERROR in VPU::prepare", __func__);
+        return -1;
+    }
+    return 0;
+}
+
+bool VPUClient::queueHandle(hwc_context_t* ctx, VpuLayerProp* prop,
+        private_handle_t* hnd)
+{
+    overlay::Overlay& ov = *ctx->mOverlay;
+    ovutils::eDest dest = (eDest) getDest(prop, 0);
+
+    int fd = hnd->fd;
+    uint32_t offset = hnd->offset;
+
+    if (dest != ovutils::OV_INVALID) {
+        if (!ov.queueBuffer(fd, offset, dest)) {
+            ALOGE("%s: queueBuffer failed", __FUNCTION__);
+            return false;
+        }
+        else {
+            ALOGD_IF(isDebug(), "%s: Queue handle successful: hnd:0x%x "
+                    "dest:%d", __FUNCTION__, (unsigned int) hnd, dest);
+        }
+    }
+    else {
+        ALOGE("%s: Invalid Dest: dest:%d", __FUNCTION__, dest);
+        return false;
+    }
+    return true;
+}
+
+bool VPUClient::queueHandleSplit(hwc_context_t* ctx, VpuLayerProp* prop,
+        private_handle_t* hnd)
+{
+    overlay::Overlay& ov = *ctx->mOverlay;
+    ovutils::eDest ldest = (eDest) getDest(prop, 0);
+    ovutils::eDest rdest = (eDest) getDest(prop, 1);
+
+    int fd = hnd->fd;
+    uint32_t offset = hnd->offset;
+
+    // play left mixer
+    if (ldest != ovutils::OV_INVALID) {
+        ALOGD_IF(isDebug(), "%s: Queuing left mixer", __FUNCTION__);
+        if (!ov.queueBuffer(fd, offset, ldest)) {
+            ALOGE("%s: queueBuffer failed for left mixer ", __FUNCTION__);
+            return false;
+        }
+        else {
+            ALOGD_IF(isDebug(), "%s: Queue left-handle successful: hnd:0x%x "
+                    "ldest:%d", __FUNCTION__, (unsigned int) hnd, ldest);
+        }
+    }
+    else {
+        ALOGE("%s: Invalid l-Split Dest", __FUNCTION__);
+        return false;
+    }
+
+    // play right mixer
+    if (rdest != ovutils::OV_INVALID) {
+        ALOGD_IF(isDebug(), "%s: Queuing right mixer", __FUNCTION__);
+        if (!ov.queueBuffer(fd, offset, rdest)) {
+            ALOGE("%s: queueBuffer failed for right mixer ", __FUNCTION__);
+            return false;
+        }
+        else {
+            ALOGD_IF(isDebug(), "%s: Queue right-handle successful: hnd:0x%x "
+                    "rdest:%d", __FUNCTION__, (unsigned int) hnd, rdest);
+        }
+    }
+    else {
+        ALOGE("%s: Invalid r-Split Dest", __FUNCTION__);
+        return false;
+    }
+    return true;
+}
+
+bool VPUClient::drawDummyLayers(hwc_context_t* ctx, int dpy,
+                    hwc_display_contents_1_t* list)
 {
     int err = 0;
-    if(!mVPU)
-        return err;
-    // Queue buffers to VPU
-    return err;
+    for (unsigned int i=0; i<(list->numHwLayers); ++i) {
+        VpuLayerProp* prop = &mProp[dpy][i];
+
+        if (!prop->vpuLayer)
+            continue;
+
+        // displaying blank screen for the first frame
+        if (prop->firstBuffer) {
+            ALOGD_IF(isDebug(), "%s: Displaying first (blank) frame",
+                    __FUNCTION__);
+            prop->firstBuffer = false;
+
+            if (mHnd[dpy][i] != NULL)
+                free_buffer(mHnd[dpy][i]);
+
+            // TO-FIX: out dummy buffer is currently allocated based on
+            // RGB888 format
+            err = alloc_buffer(&mHnd[dpy][i], prop->width, prop->height,
+                HAL_PIXEL_FORMAT_RGB_888, GRALLOC_USAGE_PRIVATE_IOMMU_HEAP);
+            if (err == -1) {
+                ALOGE("%s: Dummy buffer allocation failed!", __FUNCTION__);
+                return false;
+            }
+
+            private_handle_t* hnd = mHnd[dpy][i];
+            if (prop->format == HAL_PIXEL_FORMAT_RGB_888) {
+                ALOGD_IF(isDebug(), "%s: Format: RGB888", __FUNCTION__);
+                memset((void*)hnd->base, 0x0, hnd->size);
+            }
+            else if (prop->format ==
+                    HAL_PIXEL_FORMAT_YCbCr_422_I_10BIT_COMPRESSED) {
+                ALOGD_IF(isDebug(), "%s: Format: 10BIT_BWC", __FUNCTION__);
+                memset((void*)hnd->base, 0xaa, hnd->size);
+            }
+            else {
+                ALOGE("%s: Error! Wrong VPU out format - layer:%d",
+                        __FUNCTION__, i);
+                return false;
+            }
+
+            bool isSplit = isDisplaySplit(ctx, dpy);
+            if (!isSplit ? !queueHandle(ctx, prop, hnd) :
+                        !queueHandleSplit(ctx, prop, hnd)) {
+                ALOGD_IF(isDebug(), "%s: Error in queue handle: layer:%d",
+                        __FUNCTION__, i);
+                return false;
+            }
+            else {
+                ALOGD_IF(isDebug(), "%s: queue handle successful: hnd:0x%x "
+                        "layer:%d", __FUNCTION__, (unsigned int) hnd, i);
+            }
+        }
+    }
+    return true;
+}
+
+int VPUClient::predraw(hwc_context_t *ctx, int display,
+                                        hwc_display_contents_1_t* list)
+{
+    if (!mVPU) {
+        return -1;
+    }
+
+    if (!ctx || !list) {
+        ALOGE("%s: invalid contxt or list",__FUNCTION__);
+        return -1;
+    }
+
+    if (ctx->listStats[display].numAppLayers > MAX_NUM_APP_LAYERS) {
+        ALOGE("%s: Exceeding max layer count", __FUNCTION__);
+        return -1;
+    }
+
+    // Although all the video layers are composed through VPU, but still need to
+    // queue the first buffer (blank screen) to mdp in order to initialize the
+    // settings
+    if (!drawDummyLayers(ctx, display, list)) {
+        ALOGE("%s: Failed to draw the first layer through overlay",
+                __FUNCTION__);
+        return -1;
+    }
+    return 0;
+}
+
+int VPUClient::draw(hwc_context_t *ctx, int display,
+                                        hwc_display_contents_1_t* list)
+{
+    if (!mVPU) {
+        return -1;
+    }
+
+    LayerList *vpuList = vList[display];
+    vpuList->numLayers = list->numHwLayers;
+
+    for (unsigned int i=0; i<(list->numHwLayers); ++i) {
+        hwc_layer_1_t *layer = &list->hwLayers[i];
+        Layer *vLayer = &vpuList->layers[i];
+
+        // setting layer info again for the update content.
+        setLayer(layer, vLayer);
+    }
+
+    // queuing the buffer to VPU
+    if (mVPU->draw((DISPLAY_ID)display, vpuList) != NO_ERROR) {
+        //error in vpu draw
+        ALOGE("%s: ERROR in VPU::draw", __func__);
+        return -1;
+    }
+
+    ALOGD_IF(isDebug2(), "%s: Done VFM draw", __FUNCTION__);
+
+    LayerProp *layerProp = ctx->layerProp[display];
+    // setting releaseFenceFd for the vpu layer
+    for (unsigned int i=0; i<(vpuList->numLayers); ++i) {
+
+        VpuLayerProp* prop = &mProp[display][i];
+        if (!prop->vpuLayer)
+            continue;
+
+        hwc_layer_1_t *layer = &list->hwLayers[i];
+        Layer *vLayer = &vpuList->layers[i];
+
+        // TODO: Fix properly once the releaseFenceFd is implemented
+        layer->releaseFenceFd = vLayer->releaseFenceFd;
+        ALOGD_IF(isDebug(), "%s: releaseFd:%d for layer:%d", __FUNCTION__,
+                layer->releaseFenceFd, i);
+    }
+    return 0;
+}
+
+int VPUClient::getLayerIdx(int dpy, hwc_layer_1_t *layer)
+{
+    for (int i=0; i < MAX_NUM_APP_LAYERS; ++i) {
+        VpuLayerProp* prop = &mProp[dpy][i];
+
+        if (!prop->vpuLayer)
+            continue;
+
+        if (prop->layer == layer) {
+            ALOGD_IF(isDebug2(), "%s: OUT - dpy:%d", __FUNCTION__, dpy);
+            return i;
+        }
+    }
+    return -1;
+}
+
+int VPUClient::getLayerFormat(int dpy, hwc_layer_1_t *layer)
+{
+    if (!mVPU) {
+        return -1;
+    }
+
+    int idx = -1;
+    if ((idx = getLayerIdx(dpy, layer)) == -1) {
+        ALOGE("%s: Layer not found!", __FUNCTION__);
+        return -1;
+    }
+
+    VpuLayerProp* prop = &mProp[dpy][idx];
+    ALOGD_IF(isDebug(), "%s: layer:%d format:0x%x", __FUNCTION__, idx,
+            (unsigned int) prop->format);
+
+    return prop->format;
+}
+
+int VPUClient::getWidth(int dpy, hwc_layer_1_t *layer)
+{
+    if (!mVPU) {
+        return -1;
+    }
+
+    int idx = -1;
+    if ((idx = getLayerIdx(dpy, layer)) == -1) {
+        ALOGE("%s: Layer not found!", __FUNCTION__);
+        return -1;
+    }
+
+    VpuLayerProp* prop = &mProp[dpy][idx];
+    ALOGD_IF(isDebug(), "%s: layer:%d width:%d", __FUNCTION__, idx,
+            prop->width);
+
+    return prop->width;
+}
+
+int VPUClient::getHeight(int dpy, hwc_layer_1_t *layer)
+{
+    if (!mVPU) {
+        return -1;
+    }
+
+    int idx = -1;
+    if ((idx = getLayerIdx(dpy, layer)) == -1) {
+        ALOGE("%s: Layer not found!", __FUNCTION__);
+        return -1;
+    }
+
+    VpuLayerProp* prop = &mProp[dpy][idx];
+    ALOGD_IF(isDebug(), "%s: layer:%d height:%d", __FUNCTION__, idx,
+            prop->height);
+
+    return prop->height;
+}
+
+// TODO: getter function has side-effect. Need to cleanup
+void VPUClient::getPipeId(VpuLayerProp* prop, int &pipe)
+{
+    pipe = (prop->pipeCount == 1) ? (prop->pipeID[0]) : -1;
+}
+
+void VPUClient::getPipeId(VpuLayerProp* prop, int &lPipe, int &rPipe)
+{
+    lPipe = (prop->pipeCount == 2) ? (prop->pipeID[0]) : -1;
+    rPipe = (prop->pipeCount == 2) ? (prop->pipeID[1]) : -1;
+}
+
+int VPUClient::getDest(VpuLayerProp* prop, int pipenum)
+{
+    return (prop->pipeCount > 0) ? (prop->dest[pipenum]) : -1;
+}
+
+void VPUClient::setPipeCount(VpuLayerProp* prop, int count)
+{
+    prop->pipeCount = count;
+}
+
+void VPUClient::setPipeId(VpuLayerProp* prop, int lPipeId, int rPipeId)
+{
+    prop->pipeCount = 2;
+    prop->pipeID[0] = lPipeId;
+    prop->pipeID[1] = rPipeId;
+}
+
+void VPUClient::setPipeId(VpuLayerProp* prop, int pipeId)
+{
+    prop->pipeCount = 1;
+    prop->pipeID[0] = pipeId;
+}
+
+void VPUClient::setDest(VpuLayerProp* prop, int lDest, int rDest)
+{
+    prop->dest[0] = lDest;
+    prop->dest[1] = rDest;
+}
+
+void VPUClient::setDest(VpuLayerProp* prop, int dest)
+{
+    prop->dest[0] = dest;
+}
+
+bool VPUClient::supportedVPULayer(VpuLayerProp* prop)
+{
+    if (!prop->vpuLayer)
+        return false;
+
+    return true;
+}
+
+bool VPUClient::supportedVPULayer(int dpy, hwc_layer_1_t *layer)
+{
+    if (!mVPU) {
+        return false;
+    }
+
+    int idx = -1;
+    if ((idx = getLayerIdx(dpy, layer)) == -1) {
+        ALOGD_IF(isDebug(), "%s: Layer not found!", __FUNCTION__);
+        return false;
+    }
+    return true;
 }
 
 int VPUClient::processCommand(uint32_t command,
-        const Parcel* inParcel, Parcel* outParcel)
+                              const Parcel* inParcel, Parcel* outParcel)
 {
-    if(!mVPU)
+    if (!mVPU)
         return 0;
-    //XXX: Enable when VPU enables it
-    //return mVPU->processCommand(command, inParcel, outParcel);
-    return 0;
+
+    return mVPU->processCommand(command, inParcel, outParcel);
 }
 
 }; // namespace qhwc
diff --git a/libhwcomposer/hwc_vpuclient.h b/libhwcomposer/hwc_vpuclient.h
index 9985517..bb2a4b6 100644
--- a/libhwcomposer/hwc_vpuclient.h
+++ b/libhwcomposer/hwc_vpuclient.h
@@ -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
@@ -31,13 +31,20 @@
 #define HWC_VPU_H
 
 #include <sys/types.h>
+#include "hwc_utils.h"
+
+#define MAX_PIPES_PER_LAYER 2
 
 //Forward declarations
 struct hwc_display_contents_1;
 typedef struct hwc_display_contents_1 hwc_display_contents_1_t;
+struct hwc_layer_1;
+typedef struct hwc_layer_1 hwc_layer_1_t;
 struct hwc_context_t;
+
 namespace vpu {
 class VPU;
+struct LayerList;
 };
 namespace android {
 class Parcel;
@@ -47,21 +54,91 @@
 
 class VPUClient {
 public:
-    VPUClient();
+    VPUClient(hwc_context_t *ctx);
 
     ~VPUClient();
 
-    int prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list);
-
-    int draw(hwc_context_t *ctx, hwc_display_contents_1_t* list);
-
+    int setupVpuSession(hwc_context_t *ctx, int display,
+                            hwc_display_contents_1_t* list);
+    int prepare(hwc_context_t *ctx, int display,
+                            hwc_display_contents_1_t* list);
+    int predraw(hwc_context_t *ctx, int display,
+                            hwc_display_contents_1_t* list);
+    int draw(hwc_context_t *ctx, int display,
+                            hwc_display_contents_1_t* list);
     int processCommand(uint32_t command,
-            const android::Parcel* inParcel, android::Parcel* outParcel);
+        const android::Parcel* inParcel, android::Parcel* outParcel);
+    int getLayerFormat(int dpy, hwc_layer_1_t *layer);
+    int getWidth(int dpy, hwc_layer_1_t *layer);
+    int getHeight(int dpy, hwc_layer_1_t *layer);
+    bool supportedVPULayer(int dpy, hwc_layer_1_t *layer);
 
 private:
     vpu::VPU *mVPU;
     void* mVPULib;
 
+    /* VpuLayerProp struct:
+     *  This struct corresponds to only one layer
+     *  pipeCount: number of pipes required for a layer
+     *  pipeID[]: pipe ids corresponding to the layer
+     */
+    struct VpuLayerProp {
+        int format;
+        int width;
+        int height;
+        int pipeCount;
+        bool vpuLayer;
+        bool firstBuffer;
+        hwc_frect_t sourceCropf;
+        hwc_layer_1_t *layer;
+        int pipeID[MAX_PIPES_PER_LAYER];
+        int dest[MAX_PIPES_PER_LAYER];
+    };
+    int mNumVpuLayers;  /* total num of vpu supported layers */
+    int mGpuFallback;   /* all layers are not supported by vpu */
+
+    VpuLayerProp mProp[HWC_NUM_DISPLAY_TYPES][MAX_NUM_APP_LAYERS];
+    int mDebugLogs;
+    private_handle_t *mHnd[HWC_NUM_DISPLAY_TYPES][MAX_NUM_APP_LAYERS];
+    vpu::LayerList *vList[HWC_NUM_DISPLAY_TYPES];
+
+    /* Private debug functions */
+    int32_t isDebug() { return (mDebugLogs >= 1); }
+    int32_t isDebug2() { return (mDebugLogs >= 2); }
+
+    /* Private Get/Set functions */
+    int getLayerIdx(int dpy, hwc_layer_1_t *layer);
+    void getPipeId(VpuLayerProp* prop, int &pipe);
+    void getPipeId(VpuLayerProp* prop, int &lPipe, int &rPipe);
+    int getDest(VpuLayerProp* prop, int pipenum);
+    void setPipeCount(VpuLayerProp* prop, int count);
+    void setPipeId(VpuLayerProp* prop, int lPipeId, int rPipeId);
+    void setPipeId(VpuLayerProp* prop, int pipeId);
+    void setDest(VpuLayerProp* prop, int lDest, int rDest);
+    void setDest(VpuLayerProp* prop, int dest);
+
+    /* Private implementations */
+    bool supportedVPULayer(VpuLayerProp* prop);
+    bool allocResLayerPipes(hwc_context_t* ctx, int dpy,
+                            hwc_display_contents_1_t* list);
+    bool allocLayerPipes(hwc_context_t* ctx, int dpy,
+                            hwc_display_contents_1_t* list);
+    bool allocResLayerPipesSplit(hwc_context_t* ctx, int dpy,
+                            hwc_display_contents_1_t* list);
+    bool allocLayerPipesSplit(hwc_context_t* ctx, int dpy,
+                            hwc_display_contents_1_t* list);
+    bool configureLayers(hwc_context_t* ctx, int dpy,
+                            hwc_display_contents_1_t* list);
+    bool configureLayersSplit(hwc_context_t* ctx, int dpy,
+                            hwc_display_contents_1_t* list);
+    void setMDPCompLayerFlags(hwc_context_t *ctx, int dpy,
+                            hwc_display_contents_1_t* list);
+    bool drawDummyLayers(hwc_context_t* ctx, int dpy,
+                            hwc_display_contents_1_t* list);
+    bool queueHandle(hwc_context_t* ctx, VpuLayerProp* prop,
+                            private_handle_t* hnd);
+    bool queueHandleSplit(hwc_context_t* ctx, VpuLayerProp* prop,
+                            private_handle_t* hnd);
 }; // class VPU
 }; // namespace qhwc
 #endif /* end of include guard: HWC_VPU_H */
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/liblight/lights.c b/liblight/lights.c
index ccfbe10..229777a 100644
--- a/liblight/lights.c
+++ b/liblight/lights.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2014 The  Linux Foundation. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -115,6 +116,9 @@
 {
     int err = 0;
     int brightness = rgb_to_brightness(state);
+    if(!dev) {
+        return -1;
+    }
     pthread_mutex_lock(&g_lock);
     err = write_int(LCD_FILE, brightness);
     pthread_mutex_unlock(&g_lock);
@@ -125,12 +129,15 @@
 set_speaker_light_locked(struct light_device_t* dev,
         struct light_state_t const* state)
 {
-    int len;
-    int alpha, red, green, blue;
+    int red, green, blue;
     int blink;
     int onMS, offMS;
     unsigned int colorRGB;
 
+    if(!dev) {
+        return -1;
+    }
+
     switch (state->flashMode) {
         case LIGHT_FLASH_TIMED:
             onMS = state->flashOnMS;
@@ -217,6 +224,9 @@
         struct light_state_t const* state)
 {
     int err = 0;
+    if(!dev) {
+        return -1;
+    }
     pthread_mutex_lock(&g_lock);
     err = write_int(BUTTON_FILE, state->color & 0xFF);
     pthread_mutex_unlock(&g_lock);
diff --git a/libmemtrack/memtrack_msm.c b/libmemtrack/memtrack_msm.c
index ac93f44..8adff96 100644
--- a/libmemtrack/memtrack_msm.c
+++ b/libmemtrack/memtrack_msm.c
@@ -22,6 +22,8 @@
 
 int msm_memtrack_init(const struct memtrack_module *module)
 {
+    if(!module)
+        return -1;
     return 0;
 }
 
@@ -31,6 +33,8 @@
                                 struct memtrack_record *records,
                                 size_t *num_records)
 {
+    if(!module)
+        return -1;
     if (type == MEMTRACK_TYPE_GL || type == MEMTRACK_TYPE_GRAPHICS) {
         return kgsl_memtrack_get_memory(pid, type, records, num_records);
     }
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..265aa9f 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -45,7 +45,8 @@
 
 
 Overlay::Overlay() {
-    PipeBook::NUM_PIPES = qdutils::MDPVersion::getInstance().getTotalPipes();
+    int numPipes = qdutils::MDPVersion::getInstance().getTotalPipes();
+    PipeBook::NUM_PIPES = (numPipes <= utils::OV_MAX)? numPipes : utils::OV_MAX;
     for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
         mPipeBook[i].init();
     }
@@ -69,13 +70,6 @@
         PipeBook::resetAllocation(i);
     }
     mDumpStr[0] = '\0';
-
-#ifdef USES_QSEED_SCALAR
-    Scale *scalar = getScalar();
-    if(scalar) {
-        scalar->configBegin();
-    }
-#endif
 }
 
 void Overlay::configDone() {
@@ -86,11 +80,11 @@
             //fds
             if(mPipeBook[i].valid()) {
                 char str[32];
-                sprintf(str, "Unset=%s dpy=%d mix=%d; ",
+                snprintf(str, 32, "Unset=%s dpy=%d mix=%d; ",
                         PipeBook::getDestStr((eDest)i),
                         mPipeBook[i].mDisplay, mPipeBook[i].mMixer);
 #if PIPE_DEBUG
-                strncat(mDumpStr, str, strlen(str));
+                strlcat(mDumpStr, str, sizeof(mDumpStr));
 #endif
             }
             mPipeBook[i].destroy();
@@ -98,13 +92,6 @@
     }
     dump();
     PipeBook::save();
-
-#ifdef USES_QSEED_SCALAR
-    Scale *scalar = getScalar();
-    if(scalar) {
-        scalar->configDone();
-    }
-#endif
 }
 
 int Overlay::getPipeId(utils::eDest dest) {
@@ -160,7 +147,7 @@
             snprintf(str, 32, "Set=%s dpy=%d mix=%d; ",
                      PipeBook::getDestStr(dest), dpy, mixer);
 #if PIPE_DEBUG
-            strncat(mDumpStr, str, strlen(str));
+            strlcat(mDumpStr, str, sizeof(mDumpStr));
 #endif
         }
     } else {
@@ -410,19 +397,19 @@
 void Overlay::getDump(char *buf, size_t len) {
     int totalPipes = 0;
     const char *str = "\nOverlay State\n\n";
-    strncat(buf, str, strlen(str));
+    strlcat(buf, str, len);
     for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
         if(mPipeBook[i].valid()) {
             mPipeBook[i].mPipe->getDump(buf, len);
             char str[64] = {'\0'};
             snprintf(str, 64, "Display=%d\n\n", mPipeBook[i].mDisplay);
-            strncat(buf, str, strlen(str));
+            strlcat(buf, str, len);
             totalPipes++;
         }
     }
     char str_pipes[64] = {'\0'};
     snprintf(str_pipes, 64, "Pipes=%d\n\n", totalPipes);
-    strncat(buf, str_pipes, strlen(str_pipes));
+    strlcat(buf, str_pipes, len);
 }
 
 void Overlay::clear(int dpy) {
@@ -435,6 +422,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 b278ce4..a25dc5e 100644
--- a/liboverlay/overlayMdp.cpp
+++ b/liboverlay/overlayMdp.cpp
@@ -1,6 +1,6 @@
 /*
 * Copyright (C) 2008 The Android Open Source Project
-* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
+* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -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;
 }
 
@@ -274,8 +245,9 @@
 }
 
 bool MdpCtrl::setVisualParams(const MetaData_t& data) {
-    bool needUpdate = false;
+    ALOGD_IF(0, "In %s: data.operation = %d", __FUNCTION__, data.operation);
 #ifdef USES_POST_PROCESSING
+    bool needUpdate = false;
     /* calculate the data */
     if (data.operation & PP_PARAM_HSIC) {
         if (mParams.params.pa_params.hue != data.hsicData.hue) {
@@ -388,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/overlayMdpRot.cpp b/liboverlay/overlayMdpRot.cpp
index ce2ef5b..38b0a92 100755
--- a/liboverlay/overlayMdpRot.cpp
+++ b/liboverlay/overlayMdpRot.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
  * Not a Contribution, Apache license notifications and license are retained
  * for attribution purposes only.
  *
@@ -94,7 +94,7 @@
     mRotImgInfo.dst.height = whf.h;
 }
 
-void MdpRot::setCrop(const utils::Dim& crop) {
+void MdpRot::setCrop(const utils::Dim& /*crop*/) {
     // NO-OP for non-mdss rotator due to possible h/w limitations
 }
 
@@ -156,7 +156,7 @@
 
     mRotDataInfo.dst.memory_id = mem.getFD();
     mRotDataInfo.dst.offset = 0;
-    mMem.curr().m = mem;
+    mMem.mem = mem;
     return true;
 }
 
@@ -184,23 +184,27 @@
 bool MdpRot::remap(uint32_t numbufs) {
     // if current size changed, remap
     uint32_t opBufSize = calcOutputBufSize();
-    if(opBufSize == mMem.curr().size()) {
+    if(opBufSize == mMem.size()) {
         ALOGE_IF(DEBUG_OVERLAY, "%s: same size %d", __FUNCTION__, opBufSize);
         return true;
     }
 
-    ALOGE_IF(DEBUG_OVERLAY, "%s: size changed - remapping", __FUNCTION__);
-    OVASSERT(!mMem.prev().valid(), "Prev should not be valid");
+    if(!mMem.close()) {
+        ALOGE("%s error in closing prev rot mem", __FUNCTION__);
+        return false;
+    }
 
-    // ++mMem will make curr to be prev, and prev will be curr
-    ++mMem;
+    ALOGE_IF(DEBUG_OVERLAY, "%s: size changed - remapping", __FUNCTION__);
+
     if(!open_i(numbufs, opBufSize)) {
         ALOGE("%s Error could not open", __FUNCTION__);
         return false;
     }
+
     for (uint32_t i = 0; i < numbufs; ++i) {
-        mMem.curr().mRotOffset[i] = i * opBufSize;
+        mMem.mRotOffset[i] = i * opBufSize;
     }
+
     return true;
 }
 
@@ -208,10 +212,8 @@
     ovutils::memset0(mRotImgInfo);
     ovutils::memset0(mLSRotImgInfo);
     ovutils::memset0(mRotDataInfo);
-    ovutils::memset0(mMem.curr().mRotOffset);
-    ovutils::memset0(mMem.prev().mRotOffset);
-    mMem.curr().mCurrOffset = 0;
-    mMem.prev().mCurrOffset = 0;
+    ovutils::memset0(mMem.mRotOffset);
+    mMem.mCurrIndex = 0;
     mOrientation = utils::OVERLAY_TRANSFORM_0;
 }
 
@@ -220,30 +222,21 @@
         mRotDataInfo.src.memory_id = fd;
         mRotDataInfo.src.offset = offset;
 
-        remap(RotMem::Mem::ROT_NUM_BUFS);
-        OVASSERT(mMem.curr().m.numBufs(),
-                "queueBuffer numbufs is 0");
+        if(false == remap(RotMem::ROT_NUM_BUFS)) {
+            ALOGE("%s Remap failed, not queueing", __FUNCTION__);
+            return false;
+        }
+
         mRotDataInfo.dst.offset =
-                mMem.curr().mRotOffset[mMem.curr().mCurrOffset];
-        mMem.curr().mCurrOffset =
-                (mMem.curr().mCurrOffset + 1) % mMem.curr().m.numBufs();
+                mMem.mRotOffset[mMem.mCurrIndex];
+        mMem.mCurrIndex =
+                (mMem.mCurrIndex + 1) % mMem.mem.numBufs();
 
         if(!overlay::mdp_wrapper::rotate(mFd.getFD(), mRotDataInfo)) {
             ALOGE("MdpRot failed rotate");
             dump();
             return false;
         }
-
-        // if the prev mem is valid, we need to close
-        if(mMem.prev().valid()) {
-            // FIXME if no wait for vsync the above
-            // play will return immediatly and might cause
-            // tearing when prev.close is called.
-            if(!mMem.prev().close()) {
-                ALOGE("%s error in closing prev rot mem", __FUNCTION__);
-                return false;
-            }
-        }
     }
     return true;
 }
@@ -251,7 +244,7 @@
 void MdpRot::dump() const {
     ALOGE("== Dump MdpRot start ==");
     mFd.dump();
-    mMem.curr().m.dump();
+    mMem.mem.dump();
     mdp_wrapper::dump("mRotImgInfo", mRotImgInfo);
     mdp_wrapper::dump("mRotDataInfo", mRotDataInfo);
     ALOGE("== Dump MdpRot end ==");
diff --git a/liboverlay/overlayMdssRot.cpp b/liboverlay/overlayMdssRot.cpp
index c6d5332..ce9d9d5 100644
--- a/liboverlay/overlayMdssRot.cpp
+++ b/liboverlay/overlayMdssRot.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
  * Not a Contribution, Apache license notifications and license are retained
  * for attribution purposes only.
  *
@@ -92,7 +92,8 @@
     mRotInfo.dst_rect.h = crop.h;
 }
 
-void MdssRot::setDownscale(int ds) {}
+void MdssRot::setDownscale(int /*ds*/) {
+}
 
 void MdssRot::setFlags(const utils::eMdpFlags& flags) {
     mRotInfo.flags = flags;
@@ -133,30 +134,21 @@
         mRotData.data.memory_id = fd;
         mRotData.data.offset = offset;
 
-        remap(RotMem::Mem::ROT_NUM_BUFS);
-        OVASSERT(mMem.curr().m.numBufs(), "queueBuffer numbufs is 0");
+        if(false == remap(RotMem::ROT_NUM_BUFS)) {
+            ALOGE("%s Remap failed, not queuing", __FUNCTION__);
+            return false;
+        }
 
         mRotData.dst_data.offset =
-                mMem.curr().mRotOffset[mMem.curr().mCurrOffset];
-        mMem.curr().mCurrOffset =
-                (mMem.curr().mCurrOffset + 1) % mMem.curr().m.numBufs();
+                mMem.mRotOffset[mMem.mCurrIndex];
+        mMem.mCurrIndex =
+                (mMem.mCurrIndex + 1) % mMem.mem.numBufs();
 
         if(!overlay::mdp_wrapper::play(mFd.getFD(), mRotData)) {
             ALOGE("MdssRot play failed!");
             dump();
             return false;
         }
-
-        // if the prev mem is valid, we need to close
-        if(mMem.prev().valid()) {
-            // FIXME if no wait for vsync the above
-            // play will return immediatly and might cause
-            // tearing when prev.close is called.
-            if(!mMem.prev().close()) {
-                ALOGE("%s error in closing prev rot mem", __FUNCTION__);
-                return false;
-            }
-        }
     }
     return true;
 }
@@ -178,7 +170,7 @@
 
     mRotData.dst_data.memory_id = mem.getFD();
     mRotData.dst_data.offset = 0;
-    mMem.curr().m = mem;
+    mMem.mem = mem;
     return true;
 }
 
@@ -186,23 +178,27 @@
     // Calculate the size based on rotator's dst format, w and h.
     uint32_t opBufSize = calcOutputBufSize();
     // If current size changed, remap
-    if(opBufSize == mMem.curr().size()) {
+    if(opBufSize == mMem.size()) {
         ALOGE_IF(DEBUG_OVERLAY, "%s: same size %d", __FUNCTION__, opBufSize);
         return true;
     }
 
     ALOGE_IF(DEBUG_OVERLAY, "%s: size changed - remapping", __FUNCTION__);
-    OVASSERT(!mMem.prev().valid(), "Prev should not be valid");
 
-    // ++mMem will make curr to be prev, and prev will be curr
-    ++mMem;
+    if(!mMem.close()) {
+        ALOGE("%s error in closing prev rot mem", __FUNCTION__);
+        return false;
+    }
+
     if(!open_i(numbufs, opBufSize)) {
         ALOGE("%s Error could not open", __FUNCTION__);
         return false;
     }
+
     for (uint32_t i = 0; i < numbufs; ++i) {
-        mMem.curr().mRotOffset[i] = i * opBufSize;
+        mMem.mRotOffset[i] = i * opBufSize;
     }
+
     return true;
 }
 
@@ -233,17 +229,15 @@
     ovutils::memset0(mRotData);
     mRotData.data.memory_id = -1;
     mRotInfo.id = MSMFB_NEW_REQUEST;
-    ovutils::memset0(mMem.curr().mRotOffset);
-    ovutils::memset0(mMem.prev().mRotOffset);
-    mMem.curr().mCurrOffset = 0;
-    mMem.prev().mCurrOffset = 0;
+    ovutils::memset0(mMem.mRotOffset);
+    mMem.mCurrIndex = 0;
     mOrientation = utils::OVERLAY_TRANSFORM_0;
 }
 
 void MdssRot::dump() const {
     ALOGE("== Dump MdssRot start ==");
     mFd.dump();
-    mMem.curr().m.dump();
+    mMem.mem.dump();
     mdp_wrapper::dump("mRotInfo", mRotInfo);
     mdp_wrapper::dump("mRotData", mRotData);
     ALOGE("== Dump MdssRot end ==");
diff --git a/liboverlay/overlayRotator.cpp b/liboverlay/overlayRotator.cpp
index d912dc7..0e5b0ec 100644
--- a/liboverlay/overlayRotator.cpp
+++ b/liboverlay/overlayRotator.cpp
@@ -63,48 +63,45 @@
 
 bool RotMem::close() {
     bool ret = true;
-    for(uint32_t i=0; i < RotMem::MAX_ROT_MEM; ++i) {
-        // skip current, and if valid, close
-        if(m[i].valid()) {
-            if(m[i].close() == false) {
-                ALOGE("%s error in closing rot mem %d", __FUNCTION__, i);
-                ret = false;
-            }
+    if(valid()) {
+        if(mem.close() == false) {
+            ALOGE("%s error in closing rot mem", __FUNCTION__);
+            ret = false;
         }
     }
     return ret;
 }
 
-RotMem::Mem::Mem() : mCurrOffset(0) {
+RotMem::RotMem() : mCurrIndex(0) {
     utils::memset0(mRotOffset);
     for(int i = 0; i < ROT_NUM_BUFS; i++) {
         mRelFence[i] = -1;
     }
 }
 
-RotMem::Mem::~Mem() {
+RotMem::~RotMem() {
     for(int i = 0; i < ROT_NUM_BUFS; i++) {
         ::close(mRelFence[i]);
         mRelFence[i] = -1;
     }
 }
 
-void RotMem::Mem::setReleaseFd(const int& fence) {
+void RotMem::setReleaseFd(const int& fence) {
     int ret = 0;
 
-    if(mRelFence[mCurrOffset] >= 0) {
+    if(mRelFence[mCurrIndex] >= 0) {
         //Wait for previous usage of this buffer to be over.
         //Can happen if rotation takes > vsync and a fast producer. i.e queue
         //happens in subsequent vsyncs either because content is 60fps or
         //because the producer is hasty sometimes.
-        ret = sync_wait(mRelFence[mCurrOffset], 1000);
+        ret = sync_wait(mRelFence[mCurrIndex], 1000);
         if(ret < 0) {
             ALOGE("%s: sync_wait error!! error no = %d err str = %s",
                 __FUNCTION__, errno, strerror(errno));
         }
-        ::close(mRelFence[mCurrOffset]);
+        ::close(mRelFence[mCurrIndex]);
     }
-    mRelFence[mCurrOffset] = fence;
+    mRelFence[mCurrIndex] = fence;
 }
 
 //============RotMgr=========================
@@ -178,7 +175,7 @@
     }
     char str[4] = {'\0'};
     snprintf(str, 4, "\n");
-    strncat(buf, str, strlen(str));
+    strlcat(buf, str, len);
 }
 
 int RotMgr::getRotDevFd() {
diff --git a/liboverlay/overlayRotator.h b/liboverlay/overlayRotator.h
index 2bbfb91..be0c8bd 100644
--- a/liboverlay/overlayRotator.h
+++ b/liboverlay/overlayRotator.h
@@ -45,36 +45,21 @@
    we don't need this RotMem wrapper. The inner class is sufficient.
 */
 struct RotMem {
-    // Max rotator memory allocations
-    enum { MAX_ROT_MEM = 2};
-
-    //Manages the rotator buffer offsets.
-    struct Mem {
-        Mem();
-        ~Mem();
-        bool valid() { return m.valid(); }
-        bool close() { return m.close(); }
-        uint32_t size() const { return m.bufSz(); }
-        void setReleaseFd(const int& fence);
-        // Max rotator buffers
-        enum { ROT_NUM_BUFS = 2 };
-        // rotator data info dst offset
-        uint32_t mRotOffset[ROT_NUM_BUFS];
-        int mRelFence[ROT_NUM_BUFS];
-        // current offset slot from mRotOffset
-        uint32_t mCurrOffset;
-        OvMem m;
-    };
-
-    RotMem() : _curr(0) {}
-    Mem& curr() { return m[_curr % MAX_ROT_MEM]; }
-    const Mem& curr() const { return m[_curr % MAX_ROT_MEM]; }
-    Mem& prev() { return m[(_curr+1) % MAX_ROT_MEM]; }
-    RotMem& operator++() { ++_curr; return *this; }
-    void setReleaseFd(const int& fence) { curr().setReleaseFd(fence); }
+    // Max rotator buffers
+    enum { ROT_NUM_BUFS = 2 };
+    RotMem();
+    ~RotMem();
     bool close();
-    uint32_t _curr;
-    Mem m[MAX_ROT_MEM];
+    bool valid() { return mem.valid(); }
+    uint32_t size() const { return mem.bufSz(); }
+    void setReleaseFd(const int& fence);
+
+    // rotator data info dst offset
+    uint32_t mRotOffset[ROT_NUM_BUFS];
+    int mRelFence[ROT_NUM_BUFS];
+    // current slot being used
+    uint32_t mCurrIndex;
+    OvMem mem;
 };
 
 class Rotator
diff --git a/liboverlay/overlayUtils.cpp b/liboverlay/overlayUtils.cpp
index 30de1db..41efc48 100644
--- a/liboverlay/overlayUtils.cpp
+++ b/liboverlay/overlayUtils.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+* Copyright (c) 2011-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
@@ -417,7 +417,7 @@
             "V.Deci=%d\n",
             prefix, ov.id, ov.z_order, ov.is_fg, ov.alpha,
             ov.transp_mask, ov.flags, ov.horz_deci, ov.vert_deci);
-    strncat(buf, str, strlen(str));
+    strlcat(buf, str, len);
     getDump(buf, len, "\tsrc", ov.src);
     getDump(buf, len, "\tsrc_rect", ov.src_rect);
     getDump(buf, len, "\tdst_rect", ov.dst_rect);
@@ -430,7 +430,7 @@
             "%s w=%d h=%d format=%d %s\n",
             prefix, ov.width, ov.height, ov.format,
             overlay::utils::getFormatString(ov.format));
-    strncat(buf, str_src, strlen(str_src));
+    strlcat(buf, str_src, len);
 }
 
 void getDump(char *buf, size_t len, const char *prefix,
@@ -439,7 +439,7 @@
     snprintf(str_rect, 256,
             "%s x=%d y=%d w=%d h=%d\n",
             prefix, ov.x, ov.y, ov.w, ov.h);
-    strncat(buf, str_rect, strlen(str_rect));
+    strlcat(buf, str_rect, len);
 }
 
 void getDump(char *buf, size_t len, const char *prefix,
@@ -448,7 +448,7 @@
     snprintf(str, 256,
             "%s id=%d\n",
             prefix, ov.id);
-    strncat(buf, str, strlen(str));
+    strlcat(buf, str, len);
     getDump(buf, len, "\tdata", ov.data);
 }
 
@@ -458,7 +458,7 @@
     snprintf(str_data, 256,
             "%s offset=%d memid=%d id=%d flags=0x%x\n",
             prefix, ov.offset, ov.memory_id, ov.id, ov.flags);
-    strncat(buf, str_data, strlen(str_data));
+    strlcat(buf, str_data, len);
 }
 
 void getDump(char *buf, size_t len, const char *prefix,
@@ -467,7 +467,7 @@
     snprintf(str, 256, "%s sessid=%u rot=%d, enable=%d downscale=%d\n",
             prefix, rot.session_id, rot.rotations, rot.enable,
             rot.downscale_ratio);
-    strncat(buf, str, strlen(str));
+    strlcat(buf, str, len);
     getDump(buf, len, "\tsrc", rot.src);
     getDump(buf, len, "\tdst", rot.dst);
     getDump(buf, len, "\tsrc_rect", rot.src_rect);
@@ -479,7 +479,7 @@
     snprintf(str, 256,
             "%s sessid=%u\n",
             prefix, rot.session_id);
-    strncat(buf, str, strlen(str));
+    strlcat(buf, str, len);
     getDump(buf, len, "\tsrc", rot.src);
     getDump(buf, len, "\tdst", rot.dst);
 }
diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h
index 33802e5..400d96a 100644
--- a/liboverlay/overlayUtils.h
+++ b/liboverlay/overlayUtils.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+* Copyright (c) 2011-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
@@ -272,6 +272,7 @@
     OV_MDSS_MDP_BWC_EN = MDP_BWC_EN,
     OV_MDSS_MDP_DUAL_PIPE = MDSS_MDP_DUAL_PIPE,
     OV_MDP_SOLID_FILL = MDP_SOLID_FILL,
+    OV_MDP_VPU_PIPE = MDP_VPU_PIPE,
 };
 
 enum eZorder {
@@ -423,7 +424,7 @@
 const char* getFormatString(int format);
 
 template <class T>
-inline void memset0(T& t) { ::memset(&t, 0, sizeof(T)); }
+inline void memset0(T& t) { ::memset(&t, 0, sizeof(t)); }
 
 template <class T> inline void swap ( T& a, T& b )
 {
@@ -815,7 +816,7 @@
 
 inline void OvFD::setPath(const char* const dev)
 {
-    ::strncpy(mPath, dev, utils::MAX_PATH_LEN);
+    ::strlcpy(mPath, dev, sizeof(mPath));
 }
 
 inline bool OvFD::close()
diff --git a/liboverlay/overlayWriteback.cpp b/liboverlay/overlayWriteback.cpp
index fdead74..08af00f 100644
--- a/liboverlay/overlayWriteback.cpp
+++ b/liboverlay/overlayWriteback.cpp
@@ -261,7 +261,7 @@
         utils::getDump(buf, len, "WBData", sWb->mFbData);
         char str[4] = {'\0'};
         snprintf(str, 4, "\n");
-        strncat(buf, str, strlen(str));
+        strlcat(buf, str, len);
         return true;
     }
     return false;
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();
diff --git a/libqdutils/display_config.cpp b/libqdutils/display_config.cpp
index 45b0211..60f1f68 100644
--- a/libqdutils/display_config.cpp
+++ b/libqdutils/display_config.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
@@ -37,7 +37,7 @@
 
 int isExternalConnected(void) {
     int ret;
-    status_t err = FAILED_TRANSACTION;
+    status_t err = (status_t) FAILED_TRANSACTION;
     sp<IQService> binder = getBinder();
     Parcel inParcel, outParcel;
     if(binder != NULL) {
@@ -54,7 +54,7 @@
 }
 
 int getDisplayAttributes(int dpy, DisplayAttributes_t& dpyattr) {
-    status_t err = FAILED_TRANSACTION;
+    status_t err = (status_t) FAILED_TRANSACTION;
     sp<IQService> binder = getBinder();
     Parcel inParcel, outParcel;
     inParcel.writeInt32(dpy);
@@ -76,7 +76,7 @@
 }
 
 int setHSIC(int dpy, const HSICData_t& hsic_data) {
-    status_t err = FAILED_TRANSACTION;
+    status_t err = (status_t) FAILED_TRANSACTION;
     sp<IQService> binder = getBinder();
     Parcel inParcel, outParcel;
     inParcel.writeInt32(dpy);
@@ -93,7 +93,7 @@
 }
 
 int getDisplayVisibleRegion(int dpy, hwc_rect_t &rect) {
-    status_t err = FAILED_TRANSACTION;
+    status_t err = (status_t) FAILED_TRANSACTION;
     sp<IQService> binder = getBinder();
     Parcel inParcel, outParcel;
     inParcel.writeInt32(dpy);
diff --git a/libqdutils/mdp_version.cpp b/libqdutils/mdp_version.cpp
index b743d7a..c341dfa 100644
--- a/libqdutils/mdp_version.cpp
+++ b/libqdutils/mdp_version.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.
 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -99,7 +99,7 @@
                                 char* tokenStr[], int *idx) {
     char *tmp_token = NULL;
     char *temp_ptr;
-    int ret = 0, index = 0;
+    int index = 0;
     if (!inputParams) {
         return -1;
     }
@@ -149,7 +149,7 @@
 // and parses and updates information accordingly.
 bool MDPVersion::updateSysFsInfo() {
     FILE *sysfsFd;
-    size_t len = 0;
+    size_t len = PAGE_SIZE;
     ssize_t read;
     char *line = NULL;
     char sysfsPath[255];
@@ -172,6 +172,7 @@
                 __FUNCTION__, sysfsPath);
         return false;
     } else {
+        line = (char *) malloc(len);
         while((read = getline(&line, &len, sysfsFd)) != -1) {
             int index=0;
             char *tokens[10];
@@ -221,9 +222,8 @@
                     }
                 }
             }
-            free(line);
-            line = NULL;
         }
+        free(line);
         fclose(sysfsFd);
     }
     ALOGD_IF(DEBUG, "%s: mMDPVersion: %d mMdpRev: %x mRGBPipes:%d,"
@@ -246,6 +246,7 @@
         if(fp){
             //Format "left right" space as delimiter
             if(fread(split, sizeof(char), 64, fp)) {
+                split[sizeof(split) - 1] = '\0';
                 mSplit.mLeft = atoi(split);
                 ALOGI_IF(mSplit.mLeft, "Left Split=%d", mSplit.mLeft);
                 char *rght = strpbrk(split, " ");
diff --git a/libqdutils/qdMetaData.cpp b/libqdutils/qdMetaData.cpp
index f39eef9..ecbf873 100644
--- a/libqdutils/qdMetaData.cpp
+++ b/libqdutils/qdMetaData.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.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -31,6 +31,8 @@
 #include <sys/mman.h>
 #include <cutils/log.h>
 #include <gralloc_priv.h>
+#define __STDC_FORMAT_MACROS 1
+#include <inttypes.h>
 #include "qdMetaData.h"
 
 int setMetaData(private_handle_t *handle, DispParamType paramType,
@@ -106,7 +108,7 @@
             break;
     }
     if(munmap(base, size))
-        ALOGE("%s: failed to unmap ptr 0x%x, err %d", __func__, (int)base,
+        ALOGE("%s: failed to unmap ptr 0x%"PRIdPTR", err %d", __func__, (intptr_t)base,
                                                                         errno);
     return 0;
 }
diff --git a/libqdutils/qd_utils.cpp b/libqdutils/qd_utils.cpp
index 5a457d0..0698b33 100644
--- a/libqdutils/qd_utils.cpp
+++ b/libqdutils/qd_utils.cpp
@@ -31,7 +31,6 @@
 
 
 #define MAX_FRAME_BUFFER_NAME_SIZE      (80)
-#define MAX_DISPLAY_DEVICES             (3)
 
 int getHDMINode(void)
 {
@@ -40,7 +39,7 @@
     char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];
     int j = 0;
 
-    for(j = 0; j < MAX_DISPLAY_DEVICES; j++) {
+    for(j = 0; j < HWC_NUM_DISPLAY_TYPES; j++) {
         snprintf (msmFbTypePath, sizeof(msmFbTypePath),
                   "/sys/class/graphics/fb%d/msm_fb_type", j);
         displayDeviceFP = fopen(msmFbTypePath, "r");
@@ -58,7 +57,7 @@
         }
     }
 
-    if (j < MAX_DISPLAY_DEVICES)
+    if (j < HWC_NUM_DISPLAY_TYPES)
         return j;
     else
         ALOGE("%s: Failed to find HDMI node", __func__);
diff --git a/libqdutils/qd_utils.h b/libqdutils/qd_utils.h
index cca55d5..db6d367 100644
--- a/libqdutils/qd_utils.h
+++ b/libqdutils/qd_utils.h
@@ -42,6 +42,7 @@
 #include <sys/poll.h>
 #include <sys/resource.h>
 #include <cutils/properties.h>
+#include <hardware/hwcomposer.h>
 
 #define EDID_RAW_DATA_SIZE 640
 
diff --git a/libqservice/IQService.cpp b/libqservice/IQService.cpp
index d2180bb..f0d7576 100644
--- a/libqservice/IQService.cpp
+++ b/libqservice/IQService.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.
@@ -55,7 +55,7 @@
     virtual android::status_t dispatch(uint32_t command, const Parcel* inParcel,
             Parcel* outParcel) {
         ALOGD_IF(QSERVICE_DEBUG, "%s: dispatch in:%p", __FUNCTION__, inParcel);
-        status_t err = android::FAILED_TRANSACTION;
+        status_t err = (status_t) android::FAILED_TRANSACTION;
         Parcel data;
         Parcel *reply = outParcel;
         data.writeInterfaceToken(IQService::getInterfaceDescriptor());
@@ -80,7 +80,7 @@
     IPCThreadState* ipc = IPCThreadState::self();
     const int callerPid = ipc->getCallingPid();
     const int callerUid = ipc->getCallingUid();
-    const size_t MAX_BUF_SIZE = 1024;
+    const int MAX_BUF_SIZE = 1024;
     char callingProcName[MAX_BUF_SIZE] = {0};
 
     getProcName(callerPid, callingProcName, MAX_BUF_SIZE);
@@ -123,7 +123,7 @@
     snprintf(buf, size, "/proc/%d/cmdline", pid);
     fd = open(buf, O_RDONLY);
     if (fd < 0) {
-        strcpy(buf, "Unknown");
+        strlcpy(buf, "Unknown", size);
     } else {
         int len = read(fd, buf, size - 1);
         buf[len] = 0;
diff --git a/libqservice/QService.cpp b/libqservice/QService.cpp
index aac5788..e4af422 100644
--- a/libqservice/QService.cpp
+++ b/libqservice/QService.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.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -54,7 +54,7 @@
 
 status_t QService::dispatch(uint32_t command, const Parcel* inParcel,
         Parcel* outParcel) {
-    status_t err = FAILED_TRANSACTION;
+    status_t err = (status_t) FAILED_TRANSACTION;
     if (mClient.get()) {
         ALOGD_IF(QSERVICE_DEBUG, "Dispatching command: %d", command);
         err = mClient->notifyCallback(command, inParcel, outParcel);
diff --git a/libqservice/QServiceUtils.h b/libqservice/QServiceUtils.h
index 2817429..699164d 100644
--- a/libqservice/QServiceUtils.h
+++ b/libqservice/QServiceUtils.h
@@ -49,7 +49,7 @@
 }
 
 inline android::status_t sendSingleParam(uint32_t command, uint32_t value) {
-    android::status_t err = android::FAILED_TRANSACTION;
+    android::status_t err = (android::status_t) android::FAILED_TRANSACTION;
     android::sp<qService::IQService> binder = getBinder();
     android::Parcel inParcel, outParcel;
     inParcel.writeInt32(value);
diff --git a/libvirtual/virtual.cpp b/libvirtual/virtual.cpp
index 342044c..795d8a1 100644
--- a/libvirtual/virtual.cpp
+++ b/libvirtual/virtual.cpp
@@ -191,7 +191,7 @@
                                    getFbForDpy(HWC_DISPLAY_VIRTUAL);
 
         char strDevPath[MAX_SYSFS_FILE_PATH];
-        sprintf(strDevPath,"/dev/graphics/fb%d", fbNum);
+        snprintf(strDevPath,sizeof(strDevPath), "/dev/graphics/fb%d", fbNum);
 
         mFd = open(strDevPath, O_RDWR);
         if(mFd < 0) {