Merge "h/q/d: Dump ovinfo only on pipe config errors"
diff --git a/common.mk b/common.mk
index d8ea260..64f60e4 100644
--- a/common.mk
+++ b/common.mk
@@ -33,11 +33,6 @@
     common_flags += -DMDSS_TARGET
 endif
 
-ifeq ($(call is-board-platform-in-list, mpq8092), true)
-    common_flags += -DVPU_TARGET
-endif
-
-
 common_deps  :=
 kernel_includes :=
 
diff --git a/libcopybit/copybit.cpp b/libcopybit/copybit.cpp
index c0246e3..645cd81 100644
--- a/libcopybit/copybit.cpp
+++ b/libcopybit/copybit.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.
@@ -154,7 +154,7 @@
     img->width      = rhs->w;
     img->height     = rhs->h;
     img->format     = get_format(rhs->format);
-    img->offset     = hnd->offset;
+    img->offset     = (uint32_t)hnd->offset;
     img->memory_id  = hnd->fd;
 }
 /** setup rectangles */
@@ -162,9 +162,7 @@
                       struct mdp_blit_req *e,
                       const struct copybit_rect_t *dst,
                       const struct copybit_rect_t *src,
-                      const struct copybit_rect_t *scissor,
-                      uint32_t horiz_padding,
-                      uint32_t vert_padding) {
+                      const struct copybit_rect_t *scissor) {
     struct copybit_rect_t clip;
     intersect(&clip, scissor, dst);
 
@@ -312,7 +310,7 @@
             case COPYBIT_PLANE_ALPHA:
                 if (value < 0)      value = MDP_ALPHA_NOP;
                 if (value >= 256)   value = 255;
-                ctx->mAlpha = value;
+                ctx->mAlpha = (uint8_t)value;
                 break;
             case COPYBIT_DITHER:
                 if (value == COPYBIT_ENABLE) {
@@ -491,7 +489,8 @@
                 return -EINVAL;
             }
         }
-        const uint32_t maxCount = sizeof(list->req)/sizeof(list->req[0]);
+        const uint32_t maxCount =
+                (uint32_t)(sizeof(list->req)/sizeof(list->req[0]));
         const struct copybit_rect_t bounds = { 0, 0, (int)dst->w, (int)dst->h };
         struct copybit_rect_t clip;
         status = 0;
@@ -508,7 +507,7 @@
             set_infos(ctx, req, flags);
             set_image(&req->dst, dst);
             set_image(&req->src, src);
-            set_rects(ctx, req, dst_rect, src_rect, &clip, src->horiz_padding, src->vert_padding);
+            set_rects(ctx, req, dst_rect, src_rect, &clip);
 
             if (req->src_rect.w<=0 || req->src_rect.h<=0)
                 continue;
@@ -553,6 +552,9 @@
 static int finish_copybit(struct copybit_device_t *dev)
 {
     // NOP for MDP copybit
+    if(!dev)
+       return -EINVAL;
+
     return 0;
 }
 static int clear_copybit(struct copybit_device_t *dev,
@@ -702,6 +704,10 @@
                         struct hw_device_t** device)
 {
     int status = -EINVAL;
+
+    if (!strcmp(name, COPYBIT_HARDWARE_COPYBIT0)) {
+        return COPYBIT_FAILURE;
+    }
     copybit_context_t *ctx;
     ctx = (copybit_context_t *)malloc(sizeof(copybit_context_t));
     memset(ctx, 0, sizeof(*ctx));
diff --git a/libcopybit/copybit_c2d.cpp b/libcopybit/copybit_c2d.cpp
index 231bb2d..852b8c0 100644
--- a/libcopybit/copybit_c2d.cpp
+++ b/libcopybit/copybit_c2d.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.
@@ -80,8 +80,8 @@
 
 C2D_STATUS (*LINK_c2dDestroySurface)( uint32 surface_id );
 
-C2D_STATUS (*LINK_c2dMapAddr) ( int mem_fd, void * hostptr, uint32 len,
-                                uint32 offset, uint32 flags, void ** gpuaddr);
+C2D_STATUS (*LINK_c2dMapAddr) ( int mem_fd, void * hostptr, size_t len,
+                                size_t offset, uint32 flags, void ** gpuaddr);
 
 C2D_STATUS (*LINK_c2dUnMapAddr) ( void * gpuaddr);
 
@@ -147,7 +147,7 @@
     alloc_data temp_src_buffer;
     alloc_data temp_dst_buffer;
     unsigned int dst[NUM_SURFACE_TYPES]; // dst surfaces
-    unsigned int mapped_gpu_addr[MAX_SURFACES]; // GPU addresses mapped inside copybit
+    uintptr_t mapped_gpu_addr[MAX_SURFACES]; // GPU addresses mapped inside copybit
     int blit_rgb_count;         // Total RGB surfaces being blit
     int blit_yuv_2_plane_count; // Total 2 plane YUV surfaces being
     int blit_yuv_3_plane_count; // Total 3 plane YUV  surfaces being blit
@@ -182,8 +182,8 @@
     int yStride;       //luma stride
     int plane1_stride;
     int plane2_stride;
-    int plane1_offset;
-    int plane2_offset;
+    size_t plane1_offset;
+    size_t plane2_offset;
 };
 
 /**
@@ -334,10 +334,11 @@
     return c2dBpp;
 }
 
-static uint32 c2d_get_gpuaddr(copybit_context_t* ctx,
+static size_t c2d_get_gpuaddr(copybit_context_t* ctx,
                               struct private_handle_t *handle, int &mapped_idx)
 {
-    uint32 memtype, *gpuaddr = 0;
+    uint32 memtype;
+    size_t *gpuaddr = 0;
     C2D_STATUS rc;
     int freeindex = 0;
     bool mapaddr = false;
@@ -374,11 +375,11 @@
         if (rc == C2D_STATUS_OK) {
             // We have mapped the GPU address inside copybit. We need to unmap
             // this address after the blit. Store this address
-            ctx->mapped_gpu_addr[freeindex] = (uint32) gpuaddr;
+            ctx->mapped_gpu_addr[freeindex] = (size_t)gpuaddr;
             mapped_idx = freeindex;
         }
     }
-    return (uint32) gpuaddr;
+    return (size_t)gpuaddr;
 }
 
 static void unmap_gpuaddr(copybit_context_t* ctx, int mapped_idx)
@@ -498,7 +499,7 @@
     struct private_handle_t* handle = (struct private_handle_t*)rhs->handle;
     C2D_SURFACE_TYPE surfaceType;
     int status = COPYBIT_SUCCESS;
-    uint32 gpuaddr = 0;
+    uintptr_t gpuaddr = 0;
     int c2d_format;
     mapped_idx = -1;
 
@@ -542,7 +543,7 @@
             ((flags & FLAGS_PREMULTIPLIED_ALPHA) ? C2D_FORMAT_PREMULTIPLIED : 0);
         surfaceDef.width = rhs->w;
         surfaceDef.height = rhs->h;
-        int aligned_width = ALIGN(surfaceDef.width,32);
+        int aligned_width = ALIGN((int)surfaceDef.width,32);
         surfaceDef.stride = (aligned_width * c2diGetBpp(surfaceDef.format))>>3;
 
         if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType,
@@ -730,7 +731,8 @@
        (ctx->trg_transform & C2D_TARGET_ROTATE_180)) {
         /* target rotation is 270 */
         c2dObject->target_rect.x        = (dst->t)<<16;
-        c2dObject->target_rect.y        = ctx->fb_width?(ALIGN(ctx->fb_width,32)- dst->r):dst->r;
+        c2dObject->target_rect.y        = ctx->fb_width?
+                (ALIGN(ctx->fb_width,32)- dst->r):dst->r;
         c2dObject->target_rect.y        = c2dObject->target_rect.y<<16;
         c2dObject->target_rect.height   = ((dst->r) - (dst->l))<<16;
         c2dObject->target_rect.width    = ((dst->b) - (dst->t))<<16;
@@ -743,7 +745,8 @@
     } else if(ctx->trg_transform & C2D_TARGET_ROTATE_180) {
         c2dObject->target_rect.y        = ctx->fb_height?(ctx->fb_height - dst->b):dst->b;
         c2dObject->target_rect.y        = c2dObject->target_rect.y<<16;
-        c2dObject->target_rect.x        = ctx->fb_width?(ALIGN(ctx->fb_width,32) - dst->r):dst->r;
+        c2dObject->target_rect.x        = ctx->fb_width?
+                (ALIGN(ctx->fb_width,32) - dst->r):dst->r;
         c2dObject->target_rect.x        = c2dObject->target_rect.x<<16;
         c2dObject->target_rect.height   = ((dst->b) - (dst->t))<<16;
         c2dObject->target_rect.width    = ((dst->r) - (dst->l))<<16;
@@ -957,7 +960,7 @@
  */
 static size_t get_size(const bufferInfo& info)
 {
-    size_t size = 0;
+    int size = 0;
     int w = info.width;
     int h = info.height;
     int aligned_w = ALIGN(w, 32);
@@ -1067,8 +1070,7 @@
     }
 }
 
-static bool need_to_execute_draw(struct copybit_context_t* ctx,
-                                          eC2DFlags flags)
+static bool need_to_execute_draw(eC2DFlags flags)
 {
     if (flags & FLAGS_TEMP_SRC_DST) {
         return true;
@@ -1185,7 +1187,7 @@
         dst_hnd->fd = ctx->temp_dst_buffer.fd;
         dst_hnd->size = ctx->temp_dst_buffer.size;
         dst_hnd->flags = ctx->temp_dst_buffer.allocType;
-        dst_hnd->base = (int)(ctx->temp_dst_buffer.base);
+        dst_hnd->base = (uintptr_t)(ctx->temp_dst_buffer.base);
         dst_hnd->offset = ctx->temp_dst_buffer.offset;
         dst_hnd->gpuaddr = 0;
         dst_image.handle = dst_hnd;
@@ -1270,7 +1272,7 @@
         src_hnd->fd = ctx->temp_src_buffer.fd;
         src_hnd->size = ctx->temp_src_buffer.size;
         src_hnd->flags = ctx->temp_src_buffer.allocType;
-        src_hnd->base = (int)(ctx->temp_src_buffer.base);
+        src_hnd->base = (uintptr_t)(ctx->temp_src_buffer.base);
         src_hnd->offset = ctx->temp_src_buffer.offset;
         src_hnd->gpuaddr = 0;
         src_image.handle = src_hnd;
@@ -1354,7 +1356,7 @@
 
     // Check if we need to perform an early draw-finish.
     flags |= (need_temp_dst || need_temp_src) ? FLAGS_TEMP_SRC_DST : 0;
-    if (need_to_execute_draw(ctx, (eC2DFlags)flags))
+    if (need_to_execute_draw((eC2DFlags)flags))
     {
         finish_copybit(dev);
     }
@@ -1388,8 +1390,11 @@
 }
 
 static int set_sync_copybit(struct copybit_device_t *dev,
-    int acquireFenceFd)
+    int /*acquireFenceFd*/)
 {
+    if(!dev)
+        return -EINVAL;
+
     return 0;
 }
 
@@ -1432,9 +1437,12 @@
 static int fill_color(struct copybit_device_t *dev,
                       struct copybit_image_t const *dst,
                       struct copybit_rect_t const *rect,
-                      uint32_t color)
+                      uint32_t /*color*/)
 {
     // TODO: Implement once c2d driver supports color fill
+    if(!dev || !dst || !rect)
+       return -EINVAL;
+
     return -EINVAL;
 }
 
@@ -1502,10 +1510,13 @@
                         struct hw_device_t** device)
 {
     int status = COPYBIT_SUCCESS;
+    if (strcmp(name, COPYBIT_HARDWARE_COPYBIT0)) {
+        return COPYBIT_FAILURE;
+    }
+
     C2D_RGB_SURFACE_DEF surfDefinition = {0};
     C2D_YUV_SURFACE_DEF yuvSurfaceDef = {0} ;
     struct copybit_context_t *ctx;
-    char fbName[64];
 
     ctx = (struct copybit_context_t *)malloc(sizeof(struct copybit_context_t));
     if(!ctx) {
diff --git a/libcopybit/software_converter.cpp b/libcopybit/software_converter.cpp
index e26b795..71e685e 100644
--- a/libcopybit/software_converter.cpp
+++ b/libcopybit/software_converter.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 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
@@ -52,7 +52,7 @@
     unsigned int   width   = src->w - src->horiz_padding;
     unsigned int   height  = src->h;
     unsigned int   y_size  = stride * src->h;
-    unsigned int   c_width = ALIGN(stride/2, 16);
+    unsigned int   c_width = ALIGN(stride/2, (unsigned int)16);
     unsigned int   c_size  = c_width * src->h/2;
     unsigned int   chromaPadding = c_width - width/2;
     unsigned int   chromaSize = c_size * 2;
@@ -128,19 +128,20 @@
     int height;
     int src_stride;
     int dst_stride;
-    int src_plane1_offset;
-    int src_plane2_offset;
-    int dst_plane1_offset;
-    int dst_plane2_offset;
+    size_t src_plane1_offset;
+    size_t src_plane2_offset;
+    size_t dst_plane1_offset;
+    size_t dst_plane2_offset;
 };
 
 /* Internal function to do the actual copy of source to destination */
-static int copy_source_to_destination(const int src_base, const int dst_base,
+static int copy_source_to_destination(const uintptr_t src_base,
+                                      const uintptr_t dst_base,
                                       copyInfo& info)
 {
     if (!src_base || !dst_base) {
-        ALOGE("%s: invalid memory src_base = 0x%x dst_base=0x%x",
-             __FUNCTION__, src_base, dst_base);
+        ALOGE("%s: invalid memory src_base = 0x%p dst_base=0x%p",
+             __FUNCTION__, (void*)src_base, (void*)dst_base);
          return COPYBIT_FAILURE;
     }
 
diff --git a/libgralloc/Android.mk b/libgralloc/Android.mk
index ef10f54..18beaf2 100644
--- a/libgralloc/Android.mk
+++ b/libgralloc/Android.mk
@@ -21,7 +21,7 @@
 LOCAL_MODULE_PATH             := $(TARGET_OUT_SHARED_LIBRARIES)/hw
 LOCAL_MODULE_TAGS             := optional
 LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes)
-LOCAL_SHARED_LIBRARIES        := $(common_libs) libmemalloc
+LOCAL_SHARED_LIBRARIES        := $(common_libs) libmemalloc libqdMetaData
 LOCAL_SHARED_LIBRARIES        += libqdutils libGLESv1_CM
 LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdgralloc\"
 LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 878f17c..9f95667 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.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
@@ -428,7 +428,7 @@
             }
             size = alignedw*alignedh +
                     (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
-            size = ALIGN(size, 4096);
+            size = ALIGN(size, (size_t)4096);
             break;
         case HAL_PIXEL_FORMAT_YCbCr_420_SP:
         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
@@ -577,7 +577,7 @@
     private_handle_t* hnd = new private_handle_t(data.fd, data.size,
                                                  data.allocType, 0, format,
                                                  alignedw, alignedh);
-    hnd->base = (int) data.base;
+    hnd->base = (uintptr_t) data.base;
     hnd->offset = data.offset;
     hnd->gpuaddr = 0;
     *pHnd = hnd;
diff --git a/libgralloc/fb_priv.h b/libgralloc/fb_priv.h
index 01af2e1..0ff082f 100644
--- a/libgralloc/fb_priv.h
+++ b/libgralloc/fb_priv.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-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.
@@ -41,7 +41,7 @@
     uint32_t fbFormat;
     uint32_t flags;
     uint32_t numBuffers;
-    uint32_t bufferMask;
+    size_t   bufferMask;
     pthread_mutex_t lock;
     private_handle_t *currentBuffer;
     struct fb_var_screeninfo info;
@@ -51,7 +51,6 @@
     float ydpi;
     float fps;
     uint32_t swapInterval;
-    uint32_t currentOffset;
 };
 
 
diff --git a/libgralloc/framebuffer.cpp b/libgralloc/framebuffer.cpp
index a7a58dc..d1f4207 100644
--- a/libgralloc/framebuffer.cpp
+++ b/libgralloc/framebuffer.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2010-2012 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.
@@ -72,7 +72,6 @@
     if (property_interval >= 0)
         interval = property_interval;
 
-    fb_context_t* ctx = (fb_context_t*)dev;
     private_module_t* m = reinterpret_cast<private_module_t*>(
         dev->common.module);
     if (interval < dev->minSwapInterval || interval > dev->maxSwapInterval)
@@ -90,7 +89,7 @@
         (const_cast<native_handle_t*>(buffer));
     const size_t offset = hnd->base - m->framebuffer->base;
     m->info.activate = FB_ACTIVATE_VBL;
-    m->info.yoffset = offset / m->finfo.line_length;
+    m->info.yoffset = (int)(offset / m->finfo.line_length);
     if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1) {
         ALOGE("%s: FBIOPUT_VSCREENINFO for primary failed, str: %s",
                 __FUNCTION__, strerror(errno));
@@ -102,6 +101,9 @@
 static int fb_compositionComplete(struct framebuffer_device_t* dev)
 {
     // TODO: Properly implement composition complete callback
+    if(!dev) {
+        return -1;
+    }
     glFinish();
 
     return 0;
@@ -202,8 +204,8 @@
     }
 
     //adreno needs 4k aligned offsets. Max hole size is 4096-1
-    int  size = roundUpToPageSize(info.yres * info.xres *
-                                                       (info.bits_per_pixel/8));
+    size_t size = roundUpToPageSize(info.yres * info.xres *
+                                               (info.bits_per_pixel/8));
 
     /*
      * Request NUM_BUFFERS screens (at least 2 for page flipping)
@@ -224,13 +226,13 @@
 
     //consider the included hole by 4k alignment
     uint32_t line_length = (info.xres * info.bits_per_pixel / 8);
-    info.yres_virtual = (size * numberOfBuffers) / line_length;
+    info.yres_virtual = (uint32_t) ((size * numberOfBuffers) / line_length);
 
     uint32_t flags = PAGE_FLIP;
 
     if (info.yres_virtual < ((size * 2) / line_length) ) {
         // we need at least 2 for page-flipping
-        info.yres_virtual = size / line_length;
+        info.yres_virtual = (int)(size / line_length);
         flags &= ~PAGE_FLIP;
         ALOGW("page flipping not supported (yres_virtual=%d, requested=%d)",
               info.yres_virtual, info.yres*2);
@@ -244,12 +246,13 @@
     if (int(info.width) <= 0 || int(info.height) <= 0) {
         // the driver doesn't return that information
         // default to 160 dpi
-        info.width  = ((info.xres * 25.4f)/160.0f + 0.5f);
-        info.height = ((info.yres * 25.4f)/160.0f + 0.5f);
+        info.width  = (uint32_t)(((float)(info.xres) * 25.4f)/160.0f + 0.5f);
+        info.height = (uint32_t)(((float)(info.yres) * 25.4f)/160.0f + 0.5f);
     }
 
-    float xdpi = (info.xres * 25.4f) / info.width;
-    float ydpi = (info.yres * 25.4f) / info.height;
+    float xdpi = ((float)(info.xres) * 25.4f) / (float)info.width;
+    float ydpi = ((float)(info.yres) * 25.4f) / (float)info.height;
+
 #ifdef MSMFB_METADATA_GET
     struct msmfb_metadata metadata;
     memset(&metadata, 0 , sizeof(metadata));
@@ -259,7 +262,7 @@
         close(fd);
         return -errno;
     }
-    float fps  = metadata.data.panel_frame_rate;
+    float fps = (float)metadata.data.panel_frame_rate;
 #else
     //XXX: Remove reserved field usage on all baselines
     //The reserved[3] field is used to store FPS by the driver.
@@ -320,7 +323,6 @@
      * map the framebuffer
      */
 
-    int err;
     module->numBuffers = info.yres_virtual / info.yres;
     module->bufferMask = 0;
     //adreno needs page aligned offsets. Align the fbsize to pagesize.
@@ -336,9 +338,8 @@
         close(fd);
         return -errno;
     }
-    module->framebuffer->base = intptr_t(vaddr);
+    module->framebuffer->base = uintptr_t(vaddr);
     memset(vaddr, 0, fbSize);
-    module->currentOffset = 0;
     //Enable vsync
     int enable = 1;
     ioctl(module->framebuffer->fd, MSMFB_OVERLAY_VSYNC_CTRL,
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index b6253cd..19e948a 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 The Android Open Source Project
- * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-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.
@@ -70,13 +70,13 @@
     /* force 1MB alignment selectively for secure buffers, MDP5 onwards */
 #ifdef MDSS_TARGET
     if (usage & GRALLOC_USAGE_PROTECTED) {
-        data.align = ALIGN(data.align, SZ_1M);
+        data.align = ALIGN((int) data.align, SZ_1M);
         size = ALIGN(size, data.align);
     }
 #endif
 
     data.size = size;
-    data.pHandle = (unsigned int) pHandle;
+    data.pHandle = (uintptr_t) pHandle;
     err = mAllocCtrl->allocate(data, usage);
 
     if (!err) {
@@ -97,9 +97,12 @@
             flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY;
         }
 
+        ColorSpace_t colorSpace = ITU_R_601;
+        flags |= private_handle_t::PRIV_FLAGS_ITU_R_601;
         if (bufferType == BUFFER_TYPE_VIDEO) {
             if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
 #ifndef MDSS_TARGET
+                colorSpace = ITU_R_601_FR;
                 flags |= private_handle_t::PRIV_FLAGS_ITU_R_601_FR;
 #else
                 // Per the camera spec ITU 709 format should be set only for
@@ -108,14 +111,15 @@
                 // camera buffer
                 //
                 if (usage & GRALLOC_USAGE_HW_CAMERA_MASK) {
-                    if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER)
+                    if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
                         flags |= private_handle_t::PRIV_FLAGS_ITU_R_709;
-                    else
+                        colorSpace = ITU_R_709;
+                    } else {
                         flags |= private_handle_t::PRIV_FLAGS_ITU_R_601_FR;
+                        colorSpace = ITU_R_601_FR;
+                    }
                 }
 #endif
-            } else {
-                flags |= private_handle_t::PRIV_FLAGS_ITU_R_601;
             }
         }
 
@@ -148,14 +152,15 @@
         }
 
         flags |= data.allocType;
-        int eBaseAddr = int(eData.base) + eData.offset;
+        uintptr_t eBaseAddr = (uintptr_t)(eData.base) + eData.offset;
         private_handle_t *hnd = new private_handle_t(data.fd, size, flags,
                 bufferType, format, width, height, eData.fd, eData.offset,
                 eBaseAddr);
 
         hnd->offset = data.offset;
-        hnd->base = int(data.base) + data.offset;
+        hnd->base = (uintptr_t)(data.base) + data.offset;
         hnd->gpuaddr = 0;
+        setMetaData(hnd, UPDATE_COLOR_SPACE, (void*) &colorSpace);
 
         *pHandle = hnd;
     }
@@ -182,7 +187,7 @@
     }
 }
 
-int gpu_context_t::gralloc_alloc_framebuffer_locked(size_t size, int usage,
+int gpu_context_t::gralloc_alloc_framebuffer_locked(int usage,
                                                     buffer_handle_t* pHandle)
 {
     private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
@@ -197,7 +202,7 @@
         return -EINVAL;
     }
 
-    const uint32_t bufferMask = m->bufferMask;
+    const size_t bufferMask = m->bufferMask;
     const uint32_t numBuffers = m->numBuffers;
     size_t bufferSize = m->finfo.line_length * m->info.yres;
 
@@ -219,7 +224,7 @@
     }
 
     // create a "fake" handle for it
-    intptr_t vaddr = intptr_t(m->framebuffer->base);
+    uintptr_t vaddr = uintptr_t(m->framebuffer->base);
     private_handle_t* hnd = new private_handle_t(
         dup(m->framebuffer->fd), bufferSize,
         private_handle_t::PRIV_FLAGS_USES_PMEM |
@@ -236,18 +241,18 @@
         vaddr += bufferSize;
     }
     hnd->base = vaddr;
-    hnd->offset = vaddr - intptr_t(m->framebuffer->base);
+    hnd->offset = vaddr - uintptr_t(m->framebuffer->base);
     *pHandle = hnd;
     return 0;
 }
 
 
-int gpu_context_t::gralloc_alloc_framebuffer(size_t size, int usage,
+int gpu_context_t::gralloc_alloc_framebuffer(int usage,
                                              buffer_handle_t* pHandle)
 {
     private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
     pthread_mutex_lock(&m->lock);
-    int err = gralloc_alloc_framebuffer_locked(size, usage, pHandle);
+    int err = gralloc_alloc_framebuffer_locked(usage, pHandle);
     pthread_mutex_unlock(&m->lock);
     return err;
 }
@@ -265,7 +270,8 @@
 
     //If input format is HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED then based on
     //the usage bits, gralloc assigns a format.
-    if(format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
+    if(format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
+       format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
         if(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER)
             grallocFormat = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; //NV12
         else if((usage & GRALLOC_USAGE_HW_CAMERA_MASK)
@@ -299,7 +305,7 @@
 
     int err = 0;
     if(useFbMem) {
-        err = gralloc_alloc_framebuffer(size, usage, pHandle);
+        err = gralloc_alloc_framebuffer(usage, pHandle);
     } else {
         err = gralloc_alloc_buffer(size, usage, pHandle, bufferType,
                                    grallocFormat, alignedw, alignedh);
@@ -317,8 +323,8 @@
     private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
     if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
         const size_t bufferSize = m->finfo.line_length * m->info.yres;
-        int index = (hnd->base - m->framebuffer->base) / bufferSize;
-        m->bufferMask &= ~(1<<index);
+        size_t index = (hnd->base - m->framebuffer->base) / bufferSize;
+        m->bufferMask &= ~(1LU<<index);
     } else {
 
         terminateBuffer(&m->base, const_cast<private_handle_t*>(hnd));
@@ -328,9 +334,9 @@
         if(err)
             return err;
         // free the metadata space
-        unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
+        size_t size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
         err = memalloc->free_buffer((void*)hnd->base_metadata,
-                                    (size_t) size, hnd->offset_metadata,
+                                    size, hnd->offset_metadata,
                                     hnd->fd_metadata);
         if (err)
             return err;
diff --git a/libgralloc/gpu.h b/libgralloc/gpu.h
index 8712c6c..a34ff7e 100644
--- a/libgralloc/gpu.h
+++ b/libgralloc/gpu.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-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.
@@ -51,10 +51,10 @@
                              int format, int usage,
                              buffer_handle_t* pHandle,
                              int* pStride);
-    int gralloc_alloc_framebuffer_locked(size_t size, int usage,
+    int gralloc_alloc_framebuffer_locked(int usage,
                                          buffer_handle_t* pHandle);
 
-    int gralloc_alloc_framebuffer(size_t size, int usage,
+    int gralloc_alloc_framebuffer(int usage,
                                   buffer_handle_t* pHandle);
 
     static int gralloc_free(alloc_device_t* dev, buffer_handle_t handle);
diff --git a/libgralloc/gr.h b/libgralloc/gr.h
index 20b2994..52e9cc4 100644
--- a/libgralloc/gr.h
+++ b/libgralloc/gr.h
@@ -42,7 +42,8 @@
     return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
 }
 
-inline size_t ALIGN(size_t x, size_t align) {
+template <class Type>
+inline Type ALIGN(Type x, Type align) {
     return (x + align-1) & ~(align-1);
 }
 
diff --git a/libgralloc/gralloc.cpp b/libgralloc/gralloc.cpp
index 2567300..fd4d208 100644
--- a/libgralloc/gralloc.cpp
+++ b/libgralloc/gralloc.cpp
@@ -44,6 +44,11 @@
                         int l, int t, int w, int h,
                         void** vaddr);
 
+extern int gralloc_lock_ycbcr(gralloc_module_t const* module,
+                        buffer_handle_t handle, int usage,
+                        int l, int t, int w, int h,
+                        struct android_ycbcr *ycbcr);
+
 extern int gralloc_unlock(gralloc_module_t const* module,
                           buffer_handle_t handle);
 
@@ -58,36 +63,37 @@
 
 // HAL module methods
 static struct hw_module_methods_t gralloc_module_methods = {
-open: gralloc_device_open
+    open: gralloc_device_open
 };
 
 // HAL module initialize
 struct private_module_t HAL_MODULE_INFO_SYM = {
-base: {
-    common: {
-        tag: HARDWARE_MODULE_TAG,
-             version_major: 1,
-             version_minor: 0,
-             id: GRALLOC_HARDWARE_MODULE_ID,
-             name: "Graphics Memory Allocator Module",
-             author: "The Android Open Source Project",
-             methods: &gralloc_module_methods,
-             dso: 0,
-             reserved: {0},
-            },
-    registerBuffer: gralloc_register_buffer,
-    unregisterBuffer: gralloc_unregister_buffer,
-    lock: gralloc_lock,
-    unlock: gralloc_unlock,
-    perform: gralloc_perform,
-      },
-framebuffer: 0,
-fbFormat: 0,
-flags: 0,
-numBuffers: 0,
-bufferMask: 0,
-lock: PTHREAD_MUTEX_INITIALIZER,
-currentBuffer: 0,
+    base: {
+        common: {
+            tag: HARDWARE_MODULE_TAG,
+            version_major: 1,
+            version_minor: 0,
+            id: GRALLOC_HARDWARE_MODULE_ID,
+            name: "Graphics Memory Allocator Module",
+            author: "The Android Open Source Project",
+            methods: &gralloc_module_methods,
+            dso: 0,
+            reserved: {0},
+        },
+        registerBuffer: gralloc_register_buffer,
+        unregisterBuffer: gralloc_unregister_buffer,
+        lock: gralloc_lock,
+        unlock: gralloc_unlock,
+        perform: gralloc_perform,
+        lock_ycbcr: gralloc_lock_ycbcr,
+    },
+    framebuffer: 0,
+    fbFormat: 0,
+    flags: 0,
+    numBuffers: 0,
+    bufferMask: 0,
+    lock: PTHREAD_MUTEX_INITIALIZER,
+    currentBuffer: 0,
 };
 
 // Open Gralloc device
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index 89f1a88..b2714c5 100644
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -79,6 +79,7 @@
     // libraries
     GRALLOC_MODULE_PERFORM_GET_STRIDE,
     GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE,
+    GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE,
     GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES,
     GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE,
 };
@@ -209,33 +210,35 @@
         // ints
         int     magic;
         int     flags;
-        int     size;
-        int     offset;
+        size_t  size;
+        size_t  offset;
         int     bufferType;
-        int     base;
-        int     offset_metadata;
+        uintptr_t base;
+        size_t  offset_metadata;
         // The gpu address mapped into the mmu.
-        int     gpuaddr;
+        uintptr_t gpuaddr;
         int     format;
         int     width;
         int     height;
-        int     base_metadata;
+        uintptr_t base_metadata;
 
 #ifdef __cplusplus
-        static const int sNumInts = 12;
+        //TODO64: Revisit this on 64-bit
+        static const int sNumInts = (6 + (3 * (sizeof(size_t)/sizeof(int))) +
+                                    (3 * (sizeof(uintptr_t)/sizeof(int))));
         static const int sNumFds = 2;
         static const int sMagic = 'gmsm';
 
-        private_handle_t(int fd, int size, int flags, int bufferType,
-                         int format,int width, int height, int eFd = -1,
-                         int eOffset = 0, int eBase = 0) :
+        private_handle_t(int fd, size_t size, int flags, int bufferType,
+                         int format, int width, int height, int eFd = -1,
+                         size_t eOffset = 0, uintptr_t eBase = 0) :
             fd(fd), fd_metadata(eFd), magic(sMagic),
             flags(flags), size(size), offset(0), bufferType(bufferType),
             base(0), offset_metadata(eOffset), gpuaddr(0),
             format(format), width(width), height(height),
             base_metadata(eBase)
         {
-            version = sizeof(native_handle);
+            version = (int) sizeof(native_handle);
             numInts = sNumInts;
             numFds = sNumFds;
         }
@@ -254,7 +257,8 @@
                 hnd->magic != sMagic)
             {
                 ALOGD("Invalid gralloc handle (at %p): "
-                      "ver(%d/%d) ints(%d/%d) fds(%d/%d) magic(%c%c%c%c/%c%c%c%c)",
+                      "ver(%d/%zu) ints(%d/%d) fds(%d/%d)"
+                      "magic(%c%c%c%c/%c%c%c%c)",
                       h,
                       h ? h->version : -1, sizeof(native_handle),
                       h ? h->numInts : -1, sNumInts,
diff --git a/libgralloc/ionalloc.cpp b/libgralloc/ionalloc.cpp
index 311fd8f..3acf06e 100644
--- a/libgralloc/ionalloc.cpp
+++ b/libgralloc/ionalloc.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
@@ -28,7 +28,7 @@
  */
 
 #define DEBUG 0
-#include <linux/ioctl.h>
+#include <sys/ioctl.h>
 #include <sys/mman.h>
 #include <stdlib.h>
 #include <fcntl.h>
@@ -114,16 +114,16 @@
     data.base = base;
     data.fd = fd_data.fd;
     ioctl(mIonFd, ION_IOC_FREE, &handle_data);
-    ALOGD_IF(DEBUG, "ion: Allocated buffer base:%p size:%d fd:%d",
+    ALOGD_IF(DEBUG, "ion: Allocated buffer base:%p size:%zu fd:%d",
           data.base, ionAllocData.len, data.fd);
     return 0;
 }
 
 
-int IonAlloc::free_buffer(void* base, size_t size, int offset, int fd)
+int IonAlloc::free_buffer(void* base, size_t size, size_t offset, int fd)
 {
     Locker::Autolock _l(mLock);
-    ALOGD_IF(DEBUG, "ion: Freeing buffer base:%p size:%d fd:%d",
+    ALOGD_IF(DEBUG, "ion: Freeing buffer base:%p size:%zu fd:%d",
           base, size, fd);
     int err = 0;
     err = open_device();
@@ -136,7 +136,7 @@
     return err;
 }
 
-int IonAlloc::map_buffer(void **pBase, size_t size, int offset, int fd)
+int IonAlloc::map_buffer(void **pBase, size_t size, size_t offset, int fd)
 {
     int err = 0;
     void *base = 0;
@@ -154,15 +154,15 @@
         ALOGE("ion: Failed to map memory in the client: %s",
               strerror(errno));
     } else {
-        ALOGD_IF(DEBUG, "ion: Mapped buffer base:%p size:%d offset:%d fd:%d",
+        ALOGD_IF(DEBUG, "ion: Mapped buffer base:%p size:%zu offset:%d fd:%d",
               base, size, offset, fd);
     }
     return err;
 }
 
-int IonAlloc::unmap_buffer(void *base, size_t size, int offset)
+int IonAlloc::unmap_buffer(void *base, size_t size, size_t /*offset*/)
 {
-    ALOGD_IF(DEBUG, "ion: Unmapping buffer  base:%p size:%d", base, size);
+    ALOGD_IF(DEBUG, "ion: Unmapping buffer  base:%p size:%zu", base, size);
     int err = 0;
     if(munmap(base, size)) {
         err = -errno;
@@ -172,12 +172,11 @@
     return err;
 
 }
-int IonAlloc::clean_buffer(void *base, size_t size, int offset, int fd, int op)
+int IonAlloc::clean_buffer(void *base, size_t size, size_t offset, int fd, int op)
 {
     struct ion_flush_data flush_data;
     struct ion_fd_data fd_data;
     struct ion_handle_data handle_data;
-    ion_user_handle_t handle;
     int err = 0;
 
     err = open_device();
@@ -195,8 +194,9 @@
     handle_data.handle = fd_data.handle;
     flush_data.handle  = fd_data.handle;
     flush_data.vaddr   = base;
-    flush_data.offset  = offset;
-    flush_data.length  = size;
+    // offset and length are uint32_t
+    flush_data.offset  = (uint32_t) offset;
+    flush_data.length  = (uint32_t) size;
 
     struct ion_custom_data d;
     switch(op) {
diff --git a/libgralloc/ionalloc.h b/libgralloc/ionalloc.h
index 174f44b..683c9af 100644
--- a/libgralloc/ionalloc.h
+++ b/libgralloc/ionalloc.h
@@ -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
@@ -42,16 +42,16 @@
     virtual int alloc_buffer(alloc_data& data);
 
     virtual int free_buffer(void *base, size_t size,
-                            int offset, int fd);
+                            size_t offset, int fd);
 
     virtual int map_buffer(void **pBase, size_t size,
-                           int offset, int fd);
+                           size_t offset, int fd);
 
     virtual int unmap_buffer(void *base, size_t size,
-                             int offset);
+                             size_t offset);
 
     virtual int clean_buffer(void*base, size_t size,
-                             int offset, int fd, int op);
+                             size_t offset, int fd, int op);
 
     IonAlloc() { mIonFd = FD_INIT; }
 
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index df9f7e4..e415b3c 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -56,9 +56,11 @@
 }
 
 static int gralloc_map(gralloc_module_t const* module,
-                       buffer_handle_t handle,
-                       void** vaddr)
+                       buffer_handle_t handle)
 {
+    if(!module)
+        return -EINVAL;
+
     private_handle_t* hnd = (private_handle_t*)handle;
     void *mappedAddress;
     if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) &&
@@ -75,8 +77,6 @@
         }
 
         hnd->base = intptr_t(mappedAddress) + hnd->offset;
-        //LOGD("gralloc_map() succeeded fd=%d, off=%d, size=%d, vaddr=%p",
-        //        hnd->fd, hnd->offset, hnd->size, mappedAddress);
         mappedAddress = MAP_FAILED;
         size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
         err = memalloc->map_buffer(&mappedAddress, size,
@@ -89,13 +89,15 @@
         }
         hnd->base_metadata = intptr_t(mappedAddress) + hnd->offset_metadata;
     }
-    *vaddr = (void*)hnd->base;
     return 0;
 }
 
 static int gralloc_unmap(gralloc_module_t const* module,
                          buffer_handle_t handle)
 {
+    if(!module)
+        return -EINVAL;
+
     private_handle_t* hnd = (private_handle_t*)handle;
     if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
         int err = -EINVAL;
@@ -131,7 +133,7 @@
 int gralloc_register_buffer(gralloc_module_t const* module,
                             buffer_handle_t handle)
 {
-    if (private_handle_t::validate(handle) < 0)
+    if (!module || private_handle_t::validate(handle) < 0)
         return -EINVAL;
 
     // In this implementation, we don't need to do anything here
@@ -146,8 +148,7 @@
     private_handle_t* hnd = (private_handle_t*)handle;
     hnd->base = 0;
     hnd->base_metadata = 0;
-    void *vaddr;
-    int err = gralloc_map(module, handle, &vaddr);
+    int err = gralloc_map(module, handle);
     if (err) {
         ALOGE("%s: gralloc_map failed", __FUNCTION__);
         return err;
@@ -159,7 +160,7 @@
 int gralloc_unregister_buffer(gralloc_module_t const* module,
                               buffer_handle_t handle)
 {
-    if (private_handle_t::validate(handle) < 0)
+    if (!module || private_handle_t::validate(handle) < 0)
         return -EINVAL;
 
     /*
@@ -181,6 +182,9 @@
 int terminateBuffer(gralloc_module_t const* module,
                     private_handle_t* hnd)
 {
+    if(!module)
+        return -EINVAL;
+
     /*
      * If the buffer has been mapped during a lock operation, it's time
      * to un-map it. It's an error to be here with a locked buffer.
@@ -203,12 +207,10 @@
     return 0;
 }
 
-int gralloc_lock(gralloc_module_t const* module,
-                 buffer_handle_t handle, int usage,
-                 int l, int t, int w, int h,
-                 void** vaddr)
+static int gralloc_map_and_invalidate (gralloc_module_t const* module,
+                                       buffer_handle_t handle, int usage)
 {
-    if (private_handle_t::validate(handle) < 0)
+    if (!module || private_handle_t::validate(handle) < 0)
         return -EINVAL;
 
     int err = 0;
@@ -218,10 +220,9 @@
             // we need to map for real
             pthread_mutex_t* const lock = &sMapLock;
             pthread_mutex_lock(lock);
-            err = gralloc_map(module, handle, vaddr);
+            err = gralloc_map(module, handle);
             pthread_mutex_unlock(lock);
         }
-        *vaddr = (void*)hnd->base;
         if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) {
             //Invalidate if reading in software. No need to do this for the
             //metadata buffer as it is only read/written in software.
@@ -240,11 +241,56 @@
     return err;
 }
 
+int gralloc_lock(gralloc_module_t const* module,
+                 buffer_handle_t handle, int usage,
+                 int /*l*/, int /*t*/, int /*w*/, int /*h*/,
+                 void** vaddr)
+{
+    private_handle_t* hnd = (private_handle_t*)handle;
+    int err = gralloc_map_and_invalidate(module, handle, usage);
+    if(!err)
+        *vaddr = (void*)hnd->base;
+    return err;
+}
+
+int gralloc_lock_ycbcr(gralloc_module_t const* module,
+                 buffer_handle_t handle, int usage,
+                 int /*l*/, int /*t*/, int /*w*/, int /*h*/,
+                 struct android_ycbcr *ycbcr)
+{
+    private_handle_t* hnd = (private_handle_t*)handle;
+    int err = gralloc_map_and_invalidate(module, handle, usage);
+    size_t ystride, cstride;
+    if(!err) {
+        //hnd->format holds our implementation defined format
+        //HAL_PIXEL_FORMAT_YCrCb_420_SP is the only one set right now.
+        switch (hnd->format) {
+            case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+                ystride = ALIGN(hnd->width, 16);
+                cstride = ALIGN(hnd->width, 16)/2;
+                ycbcr->y  = (void*)hnd->base;
+                ycbcr->cr = (void*)(hnd->base + ystride * hnd->height);
+                ycbcr->cb = (void*)(hnd->base + ystride * hnd->height + 1);
+                ycbcr->ystride = ystride;
+                ycbcr->cstride = cstride;
+                ycbcr->chroma_step = 2;
+                memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
+                break;
+            default:
+                ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__,
+                      hnd->format);
+                err = -EINVAL;
+        }
+    }
+    return err;
+}
+
 int gralloc_unlock(gralloc_module_t const* module,
                    buffer_handle_t handle)
 {
-    if (private_handle_t::validate(handle) < 0)
+    if (!module || private_handle_t::validate(handle) < 0)
         return -EINVAL;
+
     int err = 0;
     private_handle_t* hnd = (private_handle_t*)handle;
 
@@ -276,6 +322,9 @@
 {
     int res = -EINVAL;
     va_list args;
+    if(!module)
+        return res;
+
     va_start(args, operation);
     switch (operation) {
         case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER:
@@ -289,7 +338,6 @@
                 int format = va_arg(args, int);
 
                 native_handle_t** handle = va_arg(args, native_handle_t**);
-                int memoryFlags = va_arg(args, int);
                 private_handle_t* hnd = (private_handle_t*)native_handle_create(
                     private_handle_t::sNumFds, private_handle_t::sNumInts);
                 hnd->magic = private_handle_t::sMagic;
@@ -352,6 +400,25 @@
                 res = 0;
             } break;
 
+        case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE:
+            {
+                private_handle_t* hnd =  va_arg(args, private_handle_t*);
+                int *stride = va_arg(args, int *);
+                int *height = va_arg(args, int *);
+                if (private_handle_t::validate(hnd)) {
+                    return res;
+                }
+                MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+                if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
+                    *stride = metadata->bufferDim.sliceWidth;
+                    *height = metadata->bufferDim.sliceHeight;
+                } else {
+                    *stride = hnd->width;
+                    *height = hnd->height;
+                }
+                res = 0;
+            } break;
+
         case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES:
             {
                 int width   = va_arg(args, int);
diff --git a/libgralloc/memalloc.h b/libgralloc/memalloc.h
index 664bfa2..fcd7913 100644
--- a/libgralloc/memalloc.h
+++ b/libgralloc/memalloc.h
@@ -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
@@ -43,10 +43,10 @@
 struct alloc_data {
     void           *base;
     int            fd;
-    int            offset;
+    size_t         offset;
     size_t         size;
     size_t         align;
-    unsigned int   pHandle;
+    uintptr_t      pHandle;
     bool           uncached;
     unsigned int   flags;
     int            allocType;
@@ -62,19 +62,19 @@
 
     // Free buffer
     virtual int free_buffer(void *base, size_t size,
-                            int offset, int fd) = 0;
+                            size_t offset, int fd) = 0;
 
     // Map buffer
     virtual int map_buffer(void **pBase, size_t size,
-                           int offset, int fd) = 0;
+                           size_t offset, int fd) = 0;
 
     // Unmap buffer
     virtual int unmap_buffer(void *base, size_t size,
-                             int offset) = 0;
+                             size_t offset) = 0;
 
     // Clean and invalidate
     virtual int clean_buffer(void *base, size_t size,
-                             int offset, int fd, int op) = 0;
+                             size_t offset, int fd, int op) = 0;
 
     // Destructor
     virtual ~IMemAlloc() {};
diff --git a/libhwcomposer/Android.mk b/libhwcomposer/Android.mk
index 9749c69..68da8a0 100644
--- a/libhwcomposer/Android.mk
+++ b/libhwcomposer/Android.mk
@@ -25,8 +25,4 @@
                                  hwc_dump_layers.cpp \
                                  hwc_ad.cpp \
                                  hwc_virtual.cpp
-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 15b9da4..48937c8 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -38,7 +38,6 @@
 #include "hwc_copybit.h"
 #include "hwc_ad.h"
 #include "profiler.h"
-#include "hwc_vpuclient.h"
 #include "hwc_virtual.h"
 
 using namespace qhwc;
@@ -116,7 +115,7 @@
         // cache we need to reset it.
         // We can probably rethink that later on
         if (LIKELY(list && list->numHwLayers > 0)) {
-            for(uint32_t j = 0; j < list->numHwLayers; j++) {
+            for(size_t j = 0; j < list->numHwLayers; j++) {
                 if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET)
                     list->hwLayers[j].compositionType = HWC_FRAMEBUFFER;
             }
@@ -136,7 +135,7 @@
                  */
                 ctx->isPaddingRound = true;
             }
-            ctx->mPrevHwLayerCount[i] = list->numHwLayers;
+            ctx->mPrevHwLayerCount[i] = (int)list->numHwLayers;
         } else {
             ctx->mPrevHwLayerCount[i] = 0;
         }
@@ -161,29 +160,31 @@
 
 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;
+    uint32_t origXres = ctx->dpyAttr[dpy].xres_orig;
+    uint32_t origYres = ctx->dpyAttr[dpy].yres_orig;
+    uint32_t fakeXres = ctx->dpyAttr[dpy].xres;
+    uint32_t fakeYres = ctx->dpyAttr[dpy].yres;
+    float xresRatio = (float)origXres / (float)fakeXres;
+    float yresRatio = (float)origYres / (float)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;
+        uint32_t layerWidth = displayFrame.right - displayFrame.left;
+        uint32_t layerHeight = displayFrame.bottom - displayFrame.top;
+        uint32_t sourceWidth = sourceCrop.right - sourceCrop.left;
+        uint32_t sourceHeight = sourceCrop.bottom - sourceCrop.top;
 
-        if (isEqual(layerWidth / sourceWidth, xresRatio) &&
-                isEqual(layerHeight / sourceHeight, yresRatio))
+        if (isEqual(((float)layerWidth / (float)sourceWidth), xresRatio) &&
+                isEqual(((float)layerHeight / (float)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;
+        displayFrame.left = (int)(xresRatio * (float)displayFrame.left);
+        displayFrame.top = (int)(yresRatio * (float)displayFrame.top);
+        displayFrame.right = (int)((float)displayFrame.left +
+                                   (float)layerWidth * xresRatio);
+        displayFrame.bottom = (int)((float)displayFrame.top +
+                                    (float)layerHeight * yresRatio);
     }
 }
 
@@ -199,15 +200,10 @@
         if (ctx->dpyAttr[dpy].customFBSize)
             scaleDisplayFrame(ctx, dpy, list);
 
-        reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
+        reset_layer_prop(ctx, dpy, (int)list->numHwLayers - 1);
         setListStats(ctx, list, dpy);
 
-        if (ctx->mVPUClient == NULL)
-            fbComp = (ctx->mMDPComp[dpy]->prepare(ctx, list) < 0);
-#ifdef VPU_TARGET
-        else
-            fbComp = (ctx->mVPUClient->prepare(ctx, dpy, list) < 0);
-#endif
+        fbComp = (ctx->mMDPComp[dpy]->prepare(ctx, list) < 0);
 
         if (fbComp) {
             const int fbZ = 0;
@@ -218,6 +214,7 @@
             if(ctx->mCopyBit[dpy])
                 ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
         }
+        setGPUHint(ctx, list);
     }
     return 0;
 }
@@ -231,7 +228,7 @@
     if (LIKELY(list && list->numHwLayers > 1) &&
             ctx->dpyAttr[dpy].isActive &&
             ctx->dpyAttr[dpy].connected) {
-        reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
+        reset_layer_prop(ctx, dpy, (int)list->numHwLayers - 1);
         if(!ctx->dpyAttr[dpy].isPause) {
             ctx->dpyAttr[dpy].isConfiguring = false;
             setListStats(ctx, list, dpy);
@@ -266,13 +263,13 @@
 
     //Will be unlocked at the end of set
     ctx->mDrawLock.lock();
-    reset(ctx, numDisplays, displays);
+    reset(ctx, (int)numDisplays, displays);
 
     ctx->mOverlay->configBegin();
     ctx->mRotMgr->configBegin();
     overlay::Writeback::configBegin();
 
-    for (int32_t i = (numDisplays-1); i >= 0; i--) {
+    for (int32_t i = ((int32_t)numDisplays-1); i >=0 ; i--) {
         hwc_display_contents_1_t *list = displays[i];
         int dpy = getDpyforExternalDisplay(ctx, i);
         switch(dpy) {
@@ -476,7 +473,8 @@
     case HWC_DISPLAY_TYPES_SUPPORTED:
         if(ctx->mMDP.hasOverlay) {
             supported |= HWC_DISPLAY_VIRTUAL_BIT;
-            if(!qdutils::MDPVersion::getInstance().is8x26())
+            if(!(qdutils::MDPVersion::getInstance().is8x26() ||
+                        qdutils::MDPVersion::getInstance().is8x16()))
                 supported |= HWC_DISPLAY_EXTERNAL_BIT;
         }
         value[0] = supported;
@@ -500,7 +498,7 @@
     int ret = 0;
     const int dpy = HWC_DISPLAY_PRIMARY;
     if (LIKELY(list) && ctx->dpyAttr[dpy].isActive) {
-        uint32_t last = list->numHwLayers - 1;
+        size_t last = list->numHwLayers - 1;
         hwc_layer_1_t *fbLayer = &list->hwLayers[last];
         int fd = -1; //FenceFD from the Copybit(valid in async mode)
         bool copybitDone = false;
@@ -513,12 +511,7 @@
         if(ctx->mHwcDebug[dpy])
             ctx->mHwcDebug[dpy]->dumpLayers(list);
 
-        if (ctx->mVPUClient != NULL) {
-#ifdef VPU_TARGET
-            ctx->mVPUClient->predraw(ctx, dpy, list);
-#endif
-        }
-        else if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
+        if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
             ALOGE("%s: MDPComp draw failed", __FUNCTION__);
             ret = -1;
         }
@@ -543,10 +536,6 @@
             ret = -1;
         }
 
-#ifdef VPU_TARGET
-        if (ctx->mVPUClient != NULL)
-            ctx->mVPUClient->draw(ctx, dpy, list);
-#endif
     }
 
     closeAcquireFds(list);
@@ -565,7 +554,7 @@
     if (LIKELY(list) && ctx->dpyAttr[dpy].isActive &&
         ctx->dpyAttr[dpy].connected &&
         !ctx->dpyAttr[dpy].isPause) {
-        uint32_t last = list->numHwLayers - 1;
+        size_t last = list->numHwLayers - 1;
         hwc_layer_1_t *fbLayer = &list->hwLayers[last];
         int fd = -1; //FenceFD from the Copybit(valid in async mode)
         bool copybitDone = false;
@@ -618,7 +607,7 @@
 {
     int ret = 0;
     hwc_context_t* ctx = (hwc_context_t*)(dev);
-    for (uint32_t i = 0; i < numDisplays; i++) {
+    for (int i = 0; i < (int)numDisplays; i++) {
         hwc_display_contents_1_t* list = displays[i];
         int dpy = getDpyforExternalDisplay(ctx, i);
         switch(dpy) {
@@ -698,7 +687,7 @@
         HWC_DISPLAY_NO_ATTRIBUTE,
     };
 
-    const int NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
+    const size_t NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
             sizeof(DISPLAY_ATTRIBUTES)[0]);
 
     for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
diff --git a/libhwcomposer/hwc_ad.cpp b/libhwcomposer/hwc_ad.cpp
index 236093b..be3793a 100644
--- a/libhwcomposer/hwc_ad.cpp
+++ b/libhwcomposer/hwc_ad.cpp
@@ -82,7 +82,7 @@
     if(adFd >= 0) {
         char opStr[4] = "";
         snprintf(opStr, sizeof(opStr), "%d", value);
-        int ret = write(adFd, opStr, strlen(opStr));
+        ssize_t ret = write(adFd, opStr, strlen(opStr));
         if(ret < 0) {
             ALOGE("%s: Failed to write %d with error %s",
                     __func__, value, strerror(errno));
@@ -206,7 +206,8 @@
         return false;
     }
 
-    int tmpW, tmpH, size;
+    int tmpW, tmpH;
+    size_t size;
     int format = ovutils::getHALFormat(wb->getOutputFormat());
     if(format < 0) {
         ALOGE("%s invalid format %d", __func__, format);
@@ -217,7 +218,7 @@
     size = getBufferSizeAndDimensions(hnd->width, hnd->height,
                 format, tmpW, tmpH);
 
-    if(!wb->configureMemory(size)) {
+    if(!wb->configureMemory((uint32_t)size)) {
         ALOGE("%s: config memory failed", __func__);
         mDoable = false;
         return false;
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 3a4bada..dc9a813 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -38,7 +38,7 @@
 
     region_iterator(hwc_region_t region) {
         mRegion = region;
-        r.end = region.numRects;
+        r.end = (int)region.numRects;
         r.current = 0;
         this->next = iterate;
     }
@@ -177,7 +177,7 @@
                 return true;
             hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
 
-            if (layer->transform & HAL_TRANSFORM_ROT_90) {
+            if (has90Transform(layer)) {
                 src_h = sourceCrop.right - sourceCrop.left;
                 src_w = sourceCrop.bottom - sourceCrop.top;
             } else {
@@ -193,8 +193,8 @@
                          __FUNCTION__, dst_w,src_w,dst_h,src_h);
               return false;
             }
-            dx = (float)dst_w/src_w;
-            dy = (float)dst_h/src_h;
+            dx = (float)dst_w/(float)src_w;
+            dy = (float)dst_h/(float)src_h;
 
             if (dx > MAX_SCALE_FACTOR || dx < MIN_SCALE_FACTOR)
                 return false;
@@ -273,7 +273,7 @@
 
     //render buffer
     if (ctx->mMDP.version == qdutils::MDP_V3_0_4) {
-        last = list->numHwLayers - 1;
+        last = (uint32_t)list->numHwLayers - 1;
         renderBuffer = (private_handle_t *)list->hwLayers[last].handle;
     } else {
         renderBuffer = getCurrentRenderBuffer();
@@ -462,8 +462,8 @@
         return -1;
     }
 
-    float dsdx = (float)screen_w/src_crop_width;
-    float dtdy = (float)screen_h/src_crop_height;
+    float dsdx = (float)screen_w/(float)src_crop_width;
+    float dtdy = (float)screen_h/(float)src_crop_height;
 
     float scaleLimitMax = copybitsMaxScale * copybitsMaxScale;
     float scaleLimitMin = copybitsMinScale * copybitsMinScale;
@@ -494,14 +494,14 @@
        int tmp_h =  src_crop_height;
 
        if (dsdx > copybitsMaxScale || dtdy > copybitsMaxScale ){
-         tmp_w = src_crop_width*copybitsMaxScale;
-         tmp_h = src_crop_height*copybitsMaxScale;
+         tmp_w = (int)((float)src_crop_width*copybitsMaxScale);
+         tmp_h = (int)((float)src_crop_height*copybitsMaxScale);
        }else if (dsdx < 1/copybitsMinScale ||dtdy < 1/copybitsMinScale ){
          // ceil the tmp_w and tmp_h value to maintain proper ratio
          // b/w src and dst (should not cross the desired scale limit
          // due to float -> int )
-         tmp_w = ceil(src_crop_width/copybitsMinScale);
-         tmp_h = ceil(src_crop_height/copybitsMinScale);
+         tmp_w = (int)ceil((float)src_crop_width/copybitsMinScale);
+         tmp_h = (int)ceil((float)src_crop_height/copybitsMinScale);
        }
        ALOGD("%s:%d::tmp_w = %d,tmp_h = %d",__FUNCTION__,__LINE__,tmp_w,tmp_h);
 
diff --git a/libhwcomposer/hwc_dump_layers.cpp b/libhwcomposer/hwc_dump_layers.cpp
index bebcc18..6d084f3 100644
--- a/libhwcomposer/hwc_dump_layers.cpp
+++ b/libhwcomposer/hwc_dump_layers.cpp
@@ -211,7 +211,7 @@
 void HwcDebug::logLayer(size_t layerIndex, hwc_layer_1_t hwLayers[])
 {
     if (NULL == hwLayers) {
-        ALOGE("Display[%s] Layer[%d] Error. No hwc layers to log.",
+        ALOGE("Display[%s] Layer[%zu] Error. No hwc layers to log.",
             mDisplayName, layerIndex);
         return;
     }
@@ -238,7 +238,7 @@
         getHalPixelFormatStr(hnd->format, pixFormatStr);
 
     // Log Line 1
-    ALOGI("Display[%s] Layer[%d] SrcBuff[%dx%d] SrcCrop[%dl, %dt, %dr, %db] "
+    ALOGI("Display[%s] Layer[%zu] SrcBuff[%dx%d] SrcCrop[%dl, %dt, %dr, %db] "
         "DispFrame[%dl, %dt, %dr, %db] VisRegsScr%s", mDisplayName, layerIndex,
         (hnd)? getWidth(hnd) : -1, (hnd)? getHeight(hnd) : -1,
         sourceCrop.left, sourceCrop.top,
@@ -247,7 +247,7 @@
         displayFrame.right, displayFrame.bottom,
         hwcVisRegsScrLog.string());
     // Log Line 2
-    ALOGI("Display[%s] Layer[%d] LayerCompType = %s, Format = %s, "
+    ALOGI("Display[%s] Layer[%zu] LayerCompType = %s, Format = %s, "
         "Orientation = %s, Flags = %s%s%s, Hints = %s%s%s, "
         "Blending = %s%s%s", mDisplayName, layerIndex,
         (layer->compositionType == HWC_FRAMEBUFFER)? "Framebuffer(GPU)":
@@ -292,7 +292,7 @@
         return;
 
     if (NULL == hwLayers) {
-        ALOGE("Display[%s] Layer[%d] %s%s Error: No hwc layers to dump.",
+        ALOGE("Display[%s] Layer[%zu] %s%s Error: No hwc layers to dump.",
             mDisplayName, layerIndex, dumpLogStrRaw, dumpLogStrPng);
         return;
     }
@@ -302,7 +302,7 @@
     char pixFormatStr[32] = "None";
 
     if (NULL == hnd) {
-        ALOGI("Display[%s] Layer[%d] %s%s Skipping dump: Bufferless layer.",
+        ALOGI("Display[%s] Layer[%zu] %s%s Skipping dump: Bufferless layer.",
             mDisplayName, layerIndex, dumpLogStrRaw, dumpLogStrPng);
         return;
     }
@@ -315,7 +315,7 @@
         SkBitmap *tempSkBmp = new SkBitmap();
         SkBitmap::Config tempSkBmpConfig = SkBitmap::kNo_Config;
         snprintf(dumpFilename, sizeof(dumpFilename),
-            "%s/sfdump%03d.layer%d.%s.png", mDumpDirPng,
+            "%s/sfdump%03d.layer%zu.%s.png", mDumpDirPng,
             mDumpCntrPng, layerIndex, mDisplayName);
 
         switch (hnd->format) {
@@ -337,11 +337,11 @@
             tempSkBmp->setPixels((void*)hnd->base);
             bResult = SkImageEncoder::EncodeFile(dumpFilename,
                                     *tempSkBmp, SkImageEncoder::kPNG_Type, 100);
-            ALOGI("Display[%s] Layer[%d] %s Dump to %s: %s",
+            ALOGI("Display[%s] Layer[%zu] %s Dump to %s: %s",
                 mDisplayName, layerIndex, dumpLogStrPng,
                 dumpFilename, bResult ? "Success" : "Fail");
         } else {
-            ALOGI("Display[%s] Layer[%d] %s Skipping dump: Unsupported layer"
+            ALOGI("Display[%s] Layer[%zu] %s Skipping dump: Unsupported layer"
                 " format %s for png encoder",
                 mDisplayName, layerIndex, dumpLogStrPng, pixFormatStr);
         }
@@ -352,7 +352,7 @@
         char dumpFilename[PATH_MAX];
         bool bResult = false;
         snprintf(dumpFilename, sizeof(dumpFilename),
-            "%s/sfdump%03d.layer%d.%dx%d.%s.%s.raw",
+            "%s/sfdump%03d.layer%zu.%dx%d.%s.%s.raw",
             mDumpDirRaw, mDumpCntrRaw,
             layerIndex, getWidth(hnd), getHeight(hnd),
             pixFormatStr, mDisplayName);
@@ -361,7 +361,7 @@
             bResult = (bool) fwrite((void*)hnd->base, hnd->size, 1, fp);
             fclose(fp);
         }
-        ALOGI("Display[%s] Layer[%d] %s Dump to %s: %s",
+        ALOGI("Display[%s] Layer[%zu] %s Dump to %s: %s",
             mDisplayName, layerIndex, dumpLogStrRaw,
             dumpFilename, bResult ? "Success" : "Fail");
     }
@@ -432,7 +432,8 @@
             strlcpy(pixFormatStr, "YCbCr_420_SP_VENUS", sizeof(pixFormatStr));
             break;
         default:
-            snprintf(pixFormatStr, sizeof(pixFormatStr), "Unknown0x%X", format);
+            size_t len = sizeof(pixFormatStr);
+            snprintf(pixFormatStr, len, "Unknown0x%X", format);
             break;
     }
 }
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index 678eecb..d69d68e 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -66,8 +66,9 @@
 bool IFBUpdate::prepareAndValidate(hwc_context_t *ctx,
             hwc_display_contents_1 *list, int fbZorder) {
     hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
-    return prepare(ctx, list, layer->displayFrame, fbZorder) &&
+    mModeOn = prepare(ctx, list, layer->displayFrame, fbZorder) &&
             ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd);
+    return mModeOn;
 }
 
 //================= Low res====================================
@@ -91,6 +92,7 @@
     if(mDpy && (extOrient & HWC_TRANSFORM_ROT_90)) {
         mRot = ctx->mRotMgr->getNext();
         if(mRot == NULL) return false;
+        ctx->mLayerRotMap[mDpy]->add(layer, mRot);
         // Composed FB content will have black bars, if the viewFrame of the
         // external is different from {0, 0, fbWidth, fbHeight}, so intersect
         // viewFrame with sourceCrop to avoid those black bars
@@ -101,7 +103,6 @@
             mRot = NULL;
             return false;
         }
-        ctx->mLayerRotMap[mDpy]->add(layer, mRot);
         info.format = (mRot)->getDstFormat();
         updateSource(orient, info, sourceCrop);
         rotFlags |= ovutils::ROT_PREROTATED;
@@ -140,7 +141,8 @@
 
         //Request a pipe
         ovutils::eMdpPipeType type = ovutils::OV_MDP_PIPE_ANY;
-        if(qdutils::MDPVersion::getInstance().is8x26() && mDpy) {
+        if((qdutils::MDPVersion::getInstance().is8x26() ||
+                   qdutils::MDPVersion::getInstance().is8x16()) && mDpy) {
             //For 8x26 external always use DMA pipe
             type = ovutils::OV_MDP_PIPE_DMA;
         }
@@ -238,7 +240,7 @@
     overlay::Overlay& ov = *(ctx->mOverlay);
     ovutils::eDest dest = mDest;
     int fd = hnd->fd;
-    uint32_t offset = hnd->offset;
+    uint32_t offset = (uint32_t)hnd->offset;
     if(mRot) {
         if(!mRot->queueBuffer(fd, offset))
             return false;
@@ -395,14 +397,14 @@
     bool ret = true;
     overlay::Overlay& ov = *(ctx->mOverlay);
     if(mDestLeft != ovutils::OV_INVALID) {
-        if (!ov.queueBuffer(hnd->fd, hnd->offset, mDestLeft)) {
+        if (!ov.queueBuffer(hnd->fd, (uint32_t)hnd->offset, mDestLeft)) {
             ALOGE("%s: queue failed for left of dpy = %d",
                   __FUNCTION__, mDpy);
             ret = false;
         }
     }
     if(mDestRight != ovutils::OV_INVALID) {
-        if (!ov.queueBuffer(hnd->fd, hnd->offset, mDestRight)) {
+        if (!ov.queueBuffer(hnd->fd, (uint32_t)hnd->offset, mDestRight)) {
             ALOGE("%s: queue failed for right of dpy = %d",
                   __FUNCTION__, mDpy);
             ret = false;
@@ -425,35 +427,13 @@
         layer = &list->hwLayers[extOnlyLayerIndex];
         layer->compositionType = HWC_OVERLAY;
     }
+
     overlay::Overlay& ov = *(ctx->mOverlay);
 
     ovutils::Whf info(mAlignedFBWidth,
             mAlignedFBHeight,
             ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
                 mTileEnabled));
-    //Request left pipe, VG first owing to higher prio
-    ovutils::eDest destL = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy,
-            Overlay::MIXER_DEFAULT);
-    if(destL == ovutils::OV_INVALID) {
-        destL = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
-            Overlay::MIXER_DEFAULT);
-        if(destL == ovutils::OV_INVALID) {
-            ALOGE("%s: No pipes available to configure fb for dpy %d's left"
-                    " mixer", __FUNCTION__, mDpy);
-            return false;
-        }
-    }
-    //Request right pipe
-    ovutils::eDest destR = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
-            Overlay::MIXER_DEFAULT);
-    if(destR == ovutils::OV_INVALID) {
-        ALOGE("%s: No pipes available to configure fb for dpy %d's right"
-                " mixer", __FUNCTION__, mDpy);
-        return false;
-    }
-
-    mDestLeft = destL;
-    mDestRight = destR;
 
     ovutils::eMdpFlags mdpFlags = OV_MDP_BLEND_FG_PREMULT;
     ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
@@ -466,46 +446,68 @@
             ovutils::DEFAULT_PLANE_ALPHA,
             (ovutils::eBlending)
             getBlending(layer->blending));
-    ov.setSource(parg, destL);
-    ov.setSource(parg, destR);
-
-    //Crop and Position are same for FB
-    ovutils::Dim cropPosL(
-            fbUpdatingRect.left,
-            fbUpdatingRect.top,
-            (fbUpdatingRect.right - fbUpdatingRect.left) / 2,
-            fbUpdatingRect.bottom - fbUpdatingRect.top);
-
-    ovutils::Dim cropPosR(
-            cropPosL.x + cropPosL.w,
-            cropPosL.y,
-            cropPosL.w,
-            cropPosL.h);
-
-    ov.setCrop(cropPosL, destL);
-    ov.setCrop(cropPosR, destR);
-    ov.setPosition(cropPosL, destL);
-    ov.setPosition(cropPosR, destR);
 
     int transform = layer->transform;
     ovutils::eTransform orient =
             static_cast<ovutils::eTransform>(transform);
-    ov.setTransform(orient, destL);
-    ov.setTransform(orient, destR);
 
-    ret = true;
-    if (!ov.commit(destL)) {
-        ALOGE("%s: commit fails for left", __FUNCTION__);
-        ret = false;
+    hwc_rect_t cropL = fbUpdatingRect;
+    hwc_rect_t cropR = fbUpdatingRect;
+
+    //Request left pipe (or 1 by default)
+    ovutils::eDest destL = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
+            Overlay::MIXER_DEFAULT);
+    if(destL == ovutils::OV_INVALID) {
+        ALOGE("%s: No pipes available to configure fb for dpy %d's left"
+                " mixer", __FUNCTION__, mDpy);
+        return false;
     }
-    if (!ov.commit(destR)) {
-        ALOGE("%s: commit fails for right", __FUNCTION__);
-        ret = false;
+
+    ovutils::eDest destR = ovutils::OV_INVALID;
+
+    //Request right pipe (2 pipes needed only if dim > 2048)
+    if((fbUpdatingRect.right - fbUpdatingRect.left) >
+            qdutils::MAX_DISPLAY_DIM) {
+        destR = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
+                Overlay::MIXER_DEFAULT);
+        if(destR == ovutils::OV_INVALID) {
+            ALOGE("%s: No pipes available to configure fb for dpy %d's right"
+                    " mixer", __FUNCTION__, mDpy);
+            return false;
+        }
+
+        if(ctx->mOverlay->comparePipePriority(destL, destR) == -1) {
+            qhwc::swap(destL, destR);
+        }
+
+        //Split crop equally when using 2 pipes
+        cropL.right = (fbUpdatingRect.right + fbUpdatingRect.left) / 2;
+        cropR.left = cropL.right;
     }
-    if(ret == false) {
-        ctx->mLayerRotMap[mDpy]->clear();
+
+    mDestLeft = destL;
+    mDestRight = destR;
+
+    if(destL != OV_INVALID) {
+        if(configMdp(ctx->mOverlay, parg, orient,
+                    cropL, cropL, NULL /*metadata*/, destL) < 0) {
+            ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
+            ctx->mLayerRotMap[mDpy]->clear();
+            return false;
+        }
     }
-    return ret;
+
+    //configure right pipe
+    if(destR != OV_INVALID) {
+        if(configMdp(ctx->mOverlay, parg, orient,
+                    cropR, cropR, NULL /*metadata*/, destR) < 0) {
+            ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
+            ctx->mLayerRotMap[mDpy]->clear();
+            return false;
+        }
+    }
+
+    return true;
 }
 
 //---------------------------------------------------------------------
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index d864290..1222dcf 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -149,7 +149,8 @@
             ALOGE("%s: failed to instantiate idleInvalidator object",
                   __FUNCTION__);
         } else {
-            idleInvalidator->init(timeout_handler, ctx, idle_timeout);
+            idleInvalidator->init(timeout_handler, ctx,
+                                  (unsigned int)idle_timeout);
         }
     }
 
@@ -268,7 +269,7 @@
 }
 
 void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
-    const int numAppLayers = list->numHwLayers - 1;
+    const int numAppLayers = (int)list->numHwLayers - 1;
     for(int i = 0; i < numAppLayers; i++) {
         hnd[i] = list->hwLayers[i].handle;
     }
@@ -603,9 +604,10 @@
 
         //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
         // may not need it if Gfx pre-rotation can handle all flips & rotations
+        int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
         if(qdutils::MDPVersion::getInstance().is8x26() &&
                                 (ctx->dpyAttr[mDpy].xres > 1024) &&
-                                (layer->transform & HWC_TRANSFORM_FLIP_H) &&
+                                (transform & HWC_TRANSFORM_FLIP_H) &&
                                 (!isYuvBuffer(hnd)))
                    return false;
     }
@@ -1125,10 +1127,8 @@
              mCurrentFrame.fbCount);
 }
 
-hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
-        hwc_display_contents_1_t* list){
+hwc_rect_t MDPComp::getUpdatingFBRect(hwc_display_contents_1_t* list){
     hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
-    hwc_layer_1_t *fbLayer = &list->hwLayers[mCurrentFrame.layerCount];
 
     /* Update only the region of FB needed for composition */
     for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
@@ -1145,7 +1145,7 @@
         hwc_display_contents_1_t* list) {
 
     //Capability checks
-    if(!resourceCheck(ctx, list)) {
+    if(!resourceCheck()) {
         ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
         return false;
     }
@@ -1158,7 +1158,7 @@
 
     //Configure framebuffer first if applicable
     if(mCurrentFrame.fbZ >= 0) {
-        hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
+        hwc_rect_t fbRect = getUpdatingFBRect(list);
         if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
         {
             ALOGD_IF(isDebug(), "%s configure framebuffer failed",
@@ -1219,8 +1219,7 @@
     return true;
 }
 
-bool MDPComp::resourceCheck(hwc_context_t *ctx,
-        hwc_display_contents_1_t *list) {
+bool MDPComp::resourceCheck() {
     const bool fbUsed = mCurrentFrame.fbCount;
     if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
         ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
@@ -1274,7 +1273,6 @@
 int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
     int ret = 0;
     const int numLayers = ctx->listStats[mDpy].numAppLayers;
-    MDPVersion& mdpVersion = qdutils::MDPVersion::getInstance();
 
     //Do not cache the information for next draw cycle.
     if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
@@ -1380,7 +1378,7 @@
         for(int index = 0; index < n4k2kYuvCount; index++){
             int n4k2kYuvIndex =
                     ctx->listStats[mDpy].yuv4k2kIndices[index];
-            if(mCurrentFrame.fbZ > n4k2kYuvIndex){
+            if(mCurrentFrame.fbZ >= n4k2kYuvIndex){
                 mCurrentFrame.fbZ += 1;
             }
         }
@@ -1437,6 +1435,10 @@
             && Overlay::getDMAMode() != Overlay::DMA_BLOCK_MODE
             && ctx->mMDP.version >= qdutils::MDSS_V5) {
             type = MDPCOMP_OV_DMA;
+        } else if(qhwc::needsScaling(layer) &&
+                !(ctx->listStats[mDpy].yuvCount) &&
+                ! qdutils::MDPVersion::getInstance().isRGBScalarSupported()){
+            type = MDPCOMP_OV_VG;
         }
 
         pipe_info.index = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT);
@@ -1515,7 +1517,7 @@
             ovutils::eDest indexL = pipe_info.lIndex;
             ovutils::eDest indexR = pipe_info.rIndex;
             int fd = hnd->fd;
-            uint32_t offset = hnd->offset;
+            uint32_t offset = (uint32_t)hnd->offset;
             if(rot) {
                 rot->queueBuffer(fd, offset);
                 fd = rot->getDstMemId();
@@ -1561,7 +1563,7 @@
                     hnd, dest );
 
             int fd = hnd->fd;
-            uint32_t offset = hnd->offset;
+            uint32_t offset = (uint32_t)hnd->offset;
 
             Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
             if(rot) {
@@ -1598,7 +1600,7 @@
         if((dst.left > lSplit) || (dst.right < lSplit)) {
             mCurrentFrame.mdpCount += 1;
         }
-        if(mCurrentFrame.fbZ > n4k2kYuvIndex){
+        if(mCurrentFrame.fbZ >= n4k2kYuvIndex){
             mCurrentFrame.fbZ += 1;
         }
     }
@@ -1761,7 +1763,7 @@
             ovutils::eDest indexL = pipe_info.lIndex;
             ovutils::eDest indexR = pipe_info.rIndex;
             int fd = hnd->fd;
-            uint32_t offset = hnd->offset;
+            uint32_t offset = (uint32_t)hnd->offset;
             if(rot) {
                 rot->queueBuffer(fd, offset);
                 fd = rot->getDstMemId();
@@ -1798,7 +1800,7 @@
             ovutils::eDest indexR = pipe_info.rIndex;
 
             int fd = hnd->fd;
-            int offset = hnd->offset;
+            int offset = (uint32_t)hnd->offset;
 
             if(ctx->mAD->isModeOn()) {
                 if(ctx->mAD->draw(ctx, fd, offset)) {
@@ -1846,7 +1848,7 @@
 
 //================MDPCompSrcSplit==============================================
 bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
-        MdpPipeInfoSplit& pipe_info, ePipeType /*type*/) {
+        MdpPipeInfoSplit& pipe_info, ePipeType type) {
     private_handle_t *hnd = (private_handle_t *)layer->handle;
     hwc_rect_t dst = layer->displayFrame;
     hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
@@ -1856,13 +1858,9 @@
     //If 2 pipes are staged on a single stage of a mixer, then the left pipe
     //should have a higher priority than the right one. Pipe priorities are
     //starting with VG0, VG1 ... , RGB0 ..., DMA1
-    //TODO Currently we acquire VG pipes for left side and RGB/DMA for right to
-    //make sure pipe priorities are satisfied. A better way is to have priority
-    //as part of overlay object and acquire any 2 pipes. Assign the higher
-    //priority one to left side and lower to right side.
 
     //1 pipe by default for a layer
-    pipe_info.lIndex = getMdpPipe(ctx, MDPCOMP_OV_VG, Overlay::MIXER_DEFAULT);
+    pipe_info.lIndex = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT);
     if(pipe_info.lIndex == ovutils::OV_INVALID) {
         if(isYuvBuffer(hnd)) {
             return false;
@@ -1877,38 +1875,31 @@
     //If layer's crop width or dest width > 2048, use 2 pipes
     if((dst.right - dst.left) > qdutils::MAX_DISPLAY_DIM or
             (crop.right - crop.left) > qdutils::MAX_DISPLAY_DIM) {
-        ePipeType rightType = isYuvBuffer(hnd) ?
-                MDPCOMP_OV_VG : MDPCOMP_OV_ANY;
-        pipe_info.rIndex = getMdpPipe(ctx, rightType, Overlay::MIXER_DEFAULT);
+        pipe_info.rIndex = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT);
         if(pipe_info.rIndex == ovutils::OV_INVALID) {
-            return false;
+            if(isYuvBuffer(hnd)) {
+                return false;
+            }
+            pipe_info.rIndex = getMdpPipe(ctx, MDPCOMP_OV_ANY,
+                    Overlay::MIXER_DEFAULT);
+            if(pipe_info.rIndex == ovutils::OV_INVALID) {
+                return false;
+            }
+        }
+
+        // Return values
+        // 1  Left pipe is higher priority, do nothing.
+        // 0  Pipes of same priority.
+        //-1  Right pipe is of higher priority, needs swap.
+        if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
+                pipe_info.rIndex) == -1) {
+            qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
         }
     }
 
     return true;
 }
 
-bool MDPCompSrcSplit::allocLayerPipes(hwc_context_t *ctx,
-        hwc_display_contents_1_t* list) {
-    for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
-        if(mCurrentFrame.isFBComposed[index]) continue;
-        hwc_layer_1_t* layer = &list->hwLayers[index];
-        int mdpIndex = mCurrentFrame.layerToMDP[index];
-        PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
-        info.pipeInfo = new MdpPipeInfoSplit;
-        info.rot = NULL;
-        MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
-
-        ePipeType type = MDPCOMP_OV_ANY;
-        if(!acquireMDPPipes(ctx, layer, pipe_info, type)) {
-            ALOGD_IF(isDebug(), "%s: Unable to get pipe for type = %d",
-                    __FUNCTION__, (int) type);
-            return false;
-        }
-    }
-    return true;
-}
-
 int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
         PipeLayerPair& PipeLayerPair) {
     private_handle_t *hnd = (private_handle_t *)layer->handle;
@@ -1956,12 +1947,12 @@
     if(isYuvBuffer(hnd) && (transform & HWC_TRANSFORM_ROT_90)) {
         (*rot) = ctx->mRotMgr->getNext();
         if((*rot) == NULL) return -1;
+        ctx->mLayerRotMap[mDpy]->add(layer, *rot);
         //Configure rotator for pre-rotation
         if(configRotator(*rot, whf, crop, mdpFlagsL, orient, downscale) < 0) {
             ALOGE("%s: configRotator failed!", __FUNCTION__);
             return -1;
         }
-        ctx->mLayerRotMap[mDpy]->add(layer, *rot);
         whf.format = (*rot)->getDstFormat();
         updateSource(orient, whf, crop);
         rotFlags |= ROT_PREROTATED;
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index 22b8baf..470ce12 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -53,6 +53,7 @@
     static bool init(hwc_context_t *ctx);
     static void resetIdleFallBack() { sIdleFallBack = false; }
     static void reset() { sHandleTimeout = false; };
+    static bool isIdleFallback() { return sIdleFallBack; }
 
 protected:
     enum { MAX_SEC_LAYERS = 1 }; //TODO add property support
@@ -212,9 +213,8 @@
             hwc_display_contents_1_t* list);
     void reset(hwc_context_t *ctx);
     bool isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer);
-    bool resourceCheck(hwc_context_t *ctx, hwc_display_contents_1_t *list);
-    hwc_rect_t getUpdatingFBRect(hwc_context_t *ctx,
-            hwc_display_contents_1_t* list);
+    bool resourceCheck();
+    hwc_rect_t getUpdatingFBRect(hwc_display_contents_1_t* list);
 
     int mDpy;
     static bool sEnabled;
@@ -308,9 +308,6 @@
     virtual bool acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
             MdpPipeInfoSplit& pipe_info, ePipeType type);
 
-    virtual bool allocLayerPipes(hwc_context_t *ctx,
-            hwc_display_contents_1_t* list);
-
     virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
             PipeLayerPair& pipeLayerPair);
 };
diff --git a/libhwcomposer/hwc_qclient.cpp b/libhwcomposer/hwc_qclient.cpp
index 2320bc0..5313795 100644
--- a/libhwcomposer/hwc_qclient.cpp
+++ b/libhwcomposer/hwc_qclient.cpp
@@ -30,7 +30,6 @@
 #include <hwc_qclient.h>
 #include <IQService.h>
 #include <hwc_utils.h>
-#include <hwc_vpuclient.h>
 #include <mdp_version.h>
 
 #define QCLIENT_DEBUG 0
@@ -95,20 +94,6 @@
     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 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;
 }
@@ -186,12 +171,6 @@
         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());
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index e51a1a4..e1f7827 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -32,6 +32,7 @@
 #include "comptype.h"
 #include "external.h"
 #include "virtual.h"
+#include "hwc_virtual.h"
 #include "mdp_version.h"
 using namespace overlay;
 namespace qhwc {
@@ -107,53 +108,15 @@
 }
 
 void handle_pause(hwc_context_t* ctx, int dpy) {
-    {
-        Locker::Autolock _l(ctx->mDrawLock);
-        ctx->dpyAttr[dpy].isActive = true;
-        ctx->dpyAttr[dpy].isPause = true;
-        ctx->proc->invalidate(ctx->proc);
-    }
-    usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
-           * 2 / 1000);
-    // At this point all the pipes used by External have been
-    // marked as UNSET.
-    {
-        Locker::Autolock _l(ctx->mDrawLock);
-        // Perform commit to unstage the pipes.
-        if (!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
-            ALOGE("%s: display commit fail! for %d dpy",
-                  __FUNCTION__, dpy);
-        }
+    if(ctx->mHWCVirtual) {
+        ctx->mHWCVirtual->pause(ctx, dpy);
     }
     return;
 }
 
 void handle_resume(hwc_context_t* ctx, int dpy) {
-    //Treat Resume as Online event
-    //Since external didnt have any pipes, force primary to give up
-    //its pipes; we don't allow inter-mixer pipe transfers.
-    {
-        Locker::Autolock _l(ctx->mDrawLock);
-
-        // A dynamic resolution change (DRC) can be made for a WiFi
-        // display. In order to support the resolution change, we
-        // need to reconfigure the corresponding display attributes.
-        // Since DRC is only on WiFi display, we only need to call
-        // configure() on the VirtualDisplay device.
-        if(dpy == HWC_DISPLAY_VIRTUAL)
-            ctx->mVirtualDisplay->configure();
-
-        ctx->dpyAttr[dpy].isConfiguring = true;
-        ctx->dpyAttr[dpy].isActive = true;
-        ctx->proc->invalidate(ctx->proc);
-    }
-    usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
-           * 2 / 1000);
-    //At this point external has all the pipes it would need.
-    {
-        Locker::Autolock _l(ctx->mDrawLock);
-        ctx->dpyAttr[dpy].isPause = false;
-        ctx->proc->invalidate(ctx->proc);
+    if(ctx->mHWCVirtual) {
+        ctx->mHWCVirtual->resume(ctx, dpy);
     }
     return;
 }
@@ -360,7 +323,7 @@
     }
 
     while(1) {
-        len = uevent_next_event(udata, sizeof(udata) - 2);
+        len = uevent_next_event(udata, (int)sizeof(udata) - 2);
         handle_uevent(ctx, udata, len);
     }
 
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 5c36304..3f5d77a 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -37,7 +37,6 @@
 #include "mdp_version.h"
 #include "hwc_copybit.h"
 #include "hwc_dump_layers.h"
-#include "hwc_vpuclient.h"
 #include "external.h"
 #include "virtual.h"
 #include "hwc_qclient.h"
@@ -53,6 +52,26 @@
 using namespace overlay::utils;
 namespace ovutils = overlay::utils;
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EGLAPI EGLBoolean eglGpuPerfHintQCOM(EGLDisplay dpy, EGLContext ctx,
+                                           EGLint *attrib_list);
+#define EGL_GPU_HINT_1        0x32D0
+#define EGL_GPU_HINT_2        0x32D1
+
+#define EGL_GPU_LEVEL_0       0x0
+#define EGL_GPU_LEVEL_1       0x1
+#define EGL_GPU_LEVEL_2       0x2
+#define EGL_GPU_LEVEL_3       0x3
+#define EGL_GPU_LEVEL_4       0x4
+#define EGL_GPU_LEVEL_5       0x5
+
+#ifdef __cplusplus
+}
+#endif
+
 namespace qhwc {
 
 bool isValidResolution(hwc_context_t *ctx, uint32_t xres, uint32_t yres)
@@ -104,12 +123,12 @@
     if (int(info.width) <= 0 || int(info.height) <= 0) {
         // the driver doesn't return that information
         // default to 160 dpi
-        info.width  = ((info.xres * 25.4f)/160.0f + 0.5f);
-        info.height = ((info.yres * 25.4f)/160.0f + 0.5f);
+        info.width  = (int)(((float)info.xres * 25.4f)/160.0f + 0.5f);
+        info.height = (int)(((float)info.yres * 25.4f)/160.0f + 0.5f);
     }
 
-    float xdpi = (info.xres * 25.4f) / info.width;
-    float ydpi = (info.yres * 25.4f) / info.height;
+    float xdpi = ((float)info.xres * 25.4f) / (float)info.width;
+    float ydpi = ((float)info.yres * 25.4f) / (float)info.height;
 
 #ifdef MSMFB_METADATA_GET
     struct msmfb_metadata metadata;
@@ -123,7 +142,7 @@
         return -errno;
     }
 
-    float fps  = metadata.data.panel_frame_rate;
+    float fps  = (float)metadata.data.panel_frame_rate;
 #else
     //XXX: Remove reserved field usage on all baselines
     //The reserved[3] field is used to store FPS by the driver.
@@ -144,7 +163,8 @@
     ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres = info.yres;
     ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xdpi = xdpi;
     ctx->dpyAttr[HWC_DISPLAY_PRIMARY].ydpi = ydpi;
-    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period = 1000000000l / fps;
+    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period =
+            (uint32_t)(1000000000l / fps);
 
     //To change resolution of primary display
     changeResolution(ctx, info.xres, info.yres);
@@ -237,7 +257,6 @@
     // Initialize device orientation to its default orientation
     ctx->deviceOrientation = 0;
     ctx->mBufferMirrorMode = false;
-    ctx->mVPUClient = NULL;
 
     // Read the system property to determine if downscale feature is enabled.
     ctx->mMDPDownscaleEnabled = false;
@@ -247,10 +266,14 @@
         ctx->mMDPDownscaleEnabled = true;
     }
 
-#ifdef VPU_TARGET
-    if(qdutils::MDPVersion::getInstance().is8092())
-        ctx->mVPUClient = new VPUClient(ctx);
-#endif
+    // Initialize gpu perfomance hint related parameters
+    property_get("sys.hwc.gpu_perf_mode", value, "0");
+    ctx->mGPUHintInfo.mGpuPerfModeEnable = atoi(value)? true : false;
+
+    ctx->mGPUHintInfo.mEGLDisplay = NULL;
+    ctx->mGPUHintInfo.mEGLContext = NULL;
+    ctx->mGPUHintInfo.mPrevCompositionGLES = false;
+    ctx->mGPUHintInfo.mCurrGPUPerfMode = EGL_GPU_LEVEL_0;
 
     ALOGI("Initializing Qualcomm Hardware Composer");
     ALOGI("MDP version: %d", ctx->mMDP.version);
@@ -285,11 +308,6 @@
         ctx->mExtDisplay = NULL;
     }
 
-#ifdef VPU_TARGET
-    if(ctx->mVPUClient != NULL)
-        delete ctx->mVPUClient;
-#endif
-
     for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
         if(ctx->mFBUpdate[i]) {
             delete ctx->mFBUpdate[i];
@@ -371,26 +389,26 @@
 
     float asX = 0;
     float asY = 0;
-    float asW = fbWidth;
-    float asH = fbHeight;
+    float asW = (float)fbWidth;
+    float asH = (float)fbHeight;
 
     // based on the action safe ratio, get the Action safe rectangle
-    asW = fbWidth * (1.0f -  asWidthRatio / 100.0f);
-    asH = fbHeight * (1.0f -  asHeightRatio / 100.0f);
-    asX = (fbWidth - asW) / 2;
-    asY = (fbHeight - asH) / 2;
+    asW = ((float)fbWidth * (1.0f -  (float)asWidthRatio / 100.0f));
+    asH = ((float)fbHeight * (1.0f -  (float)asHeightRatio / 100.0f));
+    asX = ((float)fbWidth - asW) / 2;
+    asY = ((float)fbHeight - asH) / 2;
 
     // calculate the position ratio
-    xRatio = (float)x/fbWidth;
-    yRatio = (float)y/fbHeight;
-    wRatio = (float)w/fbWidth;
-    hRatio = (float)h/fbHeight;
+    xRatio = (float)x/(float)fbWidth;
+    yRatio = (float)y/(float)fbHeight;
+    wRatio = (float)w/(float)fbWidth;
+    hRatio = (float)h/(float)fbHeight;
 
     //Calculate the position...
-    x = (xRatio * asW) + asX;
-    y = (yRatio * asH) + asY;
-    w = (wRatio * asW);
-    h = (hRatio * asH);
+    x = int((xRatio * asW) + asX);
+    y = int((yRatio * asH) + asY);
+    w = int(wRatio * asW);
+    h = int(hRatio * asH);
 
     // Convert it back to hwc_rect_t
     rect.left = x;
@@ -405,10 +423,9 @@
 // based on the position and aspect ratio with orientation
 void getAspectRatioPosition(hwc_context_t* ctx, int dpy, int extOrientation,
                             hwc_rect_t& inRect, hwc_rect_t& outRect) {
-    hwc_rect_t viewFrame = ctx->mViewFrame[dpy];
     // Physical display resolution
-    float fbWidth  = ctx->dpyAttr[dpy].xres;
-    float fbHeight = ctx->dpyAttr[dpy].yres;
+    float fbWidth  = (float)ctx->dpyAttr[dpy].xres;
+    float fbHeight = (float)ctx->dpyAttr[dpy].yres;
     //display position(x,y,w,h) in correct aspectratio after rotation
     int xPos = 0;
     int yPos = 0;
@@ -429,7 +446,7 @@
     Dim outPos(outRect.left, outRect.top, outRect.right - outRect.left,
                 outRect.bottom - outRect.top);
 
-    Whf whf(fbWidth, fbHeight, 0);
+    Whf whf((uint32_t)fbWidth, (uint32_t)fbHeight, 0);
     eTransform extorient = static_cast<eTransform>(extOrientation);
     // To calculate the destination co-ordinates in the new orientation
     preRotateSource(extorient, whf, inPos);
@@ -437,30 +454,23 @@
     if(extOrientation & HAL_TRANSFORM_ROT_90) {
         // Swap width/height for input position
         swapWidthHeight(actualWidth, actualHeight);
-        getAspectRatioPosition(fbWidth, fbHeight, (int)actualWidth,
+        getAspectRatioPosition((int)fbWidth, (int)fbHeight, (int)actualWidth,
                                (int)actualHeight, rect);
         xPos = rect.left;
         yPos = rect.top;
-        width = rect.right - rect.left;
-        height = rect.bottom - rect.top;
-        // swap viewframe coordinates for 90 degree rotation.
-        swap(viewFrame.left, viewFrame.top);
-        swap(viewFrame.right, viewFrame.bottom);
+        width = float(rect.right - rect.left);
+        height = float(rect.bottom - rect.top);
     }
-    // if viewframe left and top coordinates are non zero value then exclude it
-    // during the computation of xRatio and yRatio
-    xRatio = (inPos.x - viewFrame.left)/actualWidth;
-    yRatio = (inPos.y - viewFrame.top)/actualHeight;
-    // Use viewframe width and height to compute wRatio and hRatio.
-    wRatio = (float)inPos.w/(float)(viewFrame.right - viewFrame.left);
-    hRatio = (float)inPos.h/(float)(viewFrame.bottom - viewFrame.top);
+    xRatio = (float)(inPos.x/actualWidth);
+    yRatio = (float)(inPos.y/actualHeight);
+    wRatio = (float)(inPos.w/actualWidth);
+    hRatio = (float)(inPos.h/actualHeight);
 
-
-    //Calculate the position...
-    outPos.x = (xRatio * width) + xPos;
-    outPos.y = (yRatio * height) + yPos;
-    outPos.w = wRatio * width;
-    outPos.h = hRatio * height;
+    //Calculate the pos9ition...
+    outPos.x = uint32_t((xRatio * width) + (float)xPos);
+    outPos.y = uint32_t((yRatio * height) + (float)yPos);
+    outPos.w = uint32_t(wRatio * width);
+    outPos.h = uint32_t(hRatio * height);
     ALOGD_IF(HWC_UTILS_DEBUG, "%s: Calculated AspectRatio Position: x = %d,"
                  "y = %d w = %d h = %d", __FUNCTION__, outPos.x, outPos.y,
                  outPos.w, outPos.h);
@@ -473,22 +483,23 @@
                         isOrientationPortrait(ctx)) {
         hwc_rect_t r = {0, 0, 0, 0};
         //Calculate the position
-        xRatio = (outPos.x - xPos)/width;
+        xRatio = (float)(outPos.x - xPos)/width;
         // GetaspectRatio -- tricky to get the correct aspect ratio
         // But we need to do this.
-        getAspectRatioPosition(width, height, width, height, r);
+        getAspectRatioPosition((int)width, (int)height,
+                               (int)width,(int)height, r);
         xPos = r.left;
         yPos = r.top;
-        float tempHeight = r.bottom - r.top;
-        yRatio = yPos/height;
-        wRatio = outPos.w/width;
+        float tempHeight = float(r.bottom - r.top);
+        yRatio = (float)yPos/height;
+        wRatio = (float)outPos.w/width;
         hRatio = tempHeight/height;
 
         //Map the coordinates back to Framebuffer domain
-        outPos.x = (xRatio * fbWidth);
-        outPos.y = (yRatio * fbHeight);
-        outPos.w = wRatio * fbWidth;
-        outPos.h = hRatio * fbHeight;
+        outPos.x = uint32_t(xRatio * fbWidth);
+        outPos.y = uint32_t(yRatio * fbHeight);
+        outPos.w = uint32_t(wRatio * fbWidth);
+        outPos.h = uint32_t(hRatio * fbHeight);
 
         ALOGD_IF(HWC_UTILS_DEBUG, "%s: Calculated AspectRatio for device in"
                  "portrait: x = %d,y = %d w = %d h = %d", __FUNCTION__,
@@ -501,18 +512,18 @@
             ctx->mExtDisplay->getAttributes(extW, extH);
         else
             ctx->mVirtualDisplay->getAttributes(extW, extH);
-        fbWidth  = ctx->dpyAttr[dpy].xres;
-        fbHeight = ctx->dpyAttr[dpy].yres;
+        fbWidth  = (float)ctx->dpyAttr[dpy].xres;
+        fbHeight = (float)ctx->dpyAttr[dpy].yres;
         //Calculate the position...
-        xRatio = outPos.x/fbWidth;
-        yRatio = outPos.y/fbHeight;
-        wRatio = outPos.w/fbWidth;
-        hRatio = outPos.h/fbHeight;
+        xRatio = (float)outPos.x/fbWidth;
+        yRatio = (float)outPos.y/fbHeight;
+        wRatio = (float)outPos.w/fbWidth;
+        hRatio = (float)outPos.h/fbHeight;
 
-        outPos.x = xRatio * extW;
-        outPos.y = yRatio * extH;
-        outPos.w = wRatio * extW;
-        outPos.h = hRatio * extH;
+        outPos.x = uint32_t(xRatio * (float)extW);
+        outPos.y = uint32_t(yRatio * (float)extH);
+        outPos.w = uint32_t(wRatio * (float)extW);
+        outPos.h = uint32_t(hRatio * (float)extH);
     }
     // Convert Dim to hwc_rect_t
     outRect.left = outPos.x;
@@ -575,8 +586,8 @@
                 int extW, extH;
                 // if downscale is enabled, map the co-ordinates to new
                 // domain(downscaled)
-                float fbWidth  = ctx->dpyAttr[dpy].xres;
-                float fbHeight = ctx->dpyAttr[dpy].yres;
+                float fbWidth  = (float)ctx->dpyAttr[dpy].xres;
+                float fbHeight = (float)ctx->dpyAttr[dpy].yres;
                 // query MDP configured attributes
                 if(dpy == HWC_DISPLAY_EXTERNAL)
                     ctx->mExtDisplay->getAttributes(extW, extH);
@@ -587,10 +598,10 @@
                 float hRatio = ((float)extH)/fbHeight;
 
                 //convert Dim to hwc_rect_t
-                displayFrame.left *= wRatio;
-                displayFrame.top *= hRatio;
-                displayFrame.right *= wRatio;
-                displayFrame.bottom *= hRatio;
+                displayFrame.left = int(wRatio*(float)displayFrame.left);
+                displayFrame.top = int(hRatio*(float)displayFrame.top);
+                displayFrame.right = int(wRatio*(float)displayFrame.right);
+                displayFrame.bottom = int(hRatio*(float)displayFrame.bottom);
             }
         }else {
             if(extOrient || ctx->dpyAttr[dpy].mDownScaleMode) {
@@ -751,14 +762,16 @@
     for(uint32_t i = 0; i < list->numHwLayers - 1; i++) {
         hwc_layer_1_t *layer = &list->hwLayers[i];
         hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
+        int transform = (list->hwLayers[i].flags & HWC_COLOR_FILL) ? 0 :
+                list->hwLayers[i].transform;
         trimLayer(ctx, dpy,
-                list->hwLayers[i].transform,
+                transform,
                 (hwc_rect_t&)crop,
                 (hwc_rect_t&)list->hwLayers[i].displayFrame);
-        layer->sourceCropf.left = crop.left;
-        layer->sourceCropf.right = crop.right;
-        layer->sourceCropf.top = crop.top;
-        layer->sourceCropf.bottom = crop.bottom;
+        layer->sourceCropf.left = (float)crop.left;
+        layer->sourceCropf.right = (float)crop.right;
+        layer->sourceCropf.top = (float)crop.top;
+        layer->sourceCropf.bottom = (float)crop.bottom;
     }
 }
 
@@ -788,8 +801,8 @@
         hwc_display_contents_1_t *list, int dpy) {
     const int prevYuvCount = ctx->listStats[dpy].yuvCount;
     memset(&ctx->listStats[dpy], 0, sizeof(ListStats));
-    ctx->listStats[dpy].numAppLayers = list->numHwLayers - 1;
-    ctx->listStats[dpy].fbLayerIndex = list->numHwLayers - 1;
+    ctx->listStats[dpy].numAppLayers = (int)list->numHwLayers - 1;
+    ctx->listStats[dpy].fbLayerIndex = (int)list->numHwLayers - 1;
     ctx->listStats[dpy].skipCount = 0;
     ctx->listStats[dpy].preMultipliedAlpha = false;
     ctx->listStats[dpy].isSecurePresent = false;
@@ -841,22 +854,20 @@
 
         if (UNLIKELY(isYuvBuffer(hnd))) {
             int& yuvCount = ctx->listStats[dpy].yuvCount;
-            ctx->listStats[dpy].yuvIndices[yuvCount] = i;
+            ctx->listStats[dpy].yuvIndices[yuvCount] = (int)i;
             yuvCount++;
 
             if(UNLIKELY(is4kx2kYuvBuffer(hnd))){
                 int& yuv4k2kCount = ctx->listStats[dpy].yuv4k2kCount;
-                ctx->listStats[dpy].yuv4k2kIndices[yuv4k2kCount] = i;
+                ctx->listStats[dpy].yuv4k2kIndices[yuv4k2kCount] = (int)i;
                 yuv4k2kCount++;
             }
 
             if((layer->transform & HWC_TRANSFORM_ROT_90) &&
-                    canUseRotator(ctx, dpy)) {
-                if( (dpy == HWC_DISPLAY_PRIMARY) &&
-                        ctx->mOverlay->isPipeTypeAttached(OV_MDP_PIPE_DMA)) {
-                    ctx->isPaddingRound = true;
-                }
-                Overlay::setDMAMode(Overlay::DMA_BLOCK_MODE);
+               canUseRotator(ctx, dpy)) {
+               if(ctx->mOverlay->isPipeTypeAttached(OV_MDP_PIPE_DMA))
+                  ctx->isPaddingRound = true;
+               Overlay::setDMAMode(Overlay::DMA_BLOCK_MODE);
             }
         }
         if(layer->blending == HWC_BLENDING_PREMULT)
@@ -864,7 +875,7 @@
 
 
         if(UNLIKELY(isExtOnly(hnd))){
-            ctx->listStats[dpy].extOnlyLayerIndex = i;
+            ctx->listStats[dpy].extOnlyLayerIndex = (int)i;
         }
     }
     if(ctx->listStats[dpy].yuvCount > 0) {
@@ -1130,7 +1141,7 @@
 }
 
 void optimizeLayerRects(const hwc_display_contents_1_t *list) {
-    int i=list->numHwLayers-2;
+    int i= (int)list->numHwLayers-2;
     while(i > 0) {
         //see if there is no blending required.
         //If it is opaque see if we can substract this region from below
@@ -1145,7 +1156,8 @@
                   hwc_rect_t& bottomframe = layer->displayFrame;
                   hwc_rect_t bottomCrop =
                       integerizeSourceCrop(layer->sourceCropf);
-                  int transform =layer->transform;
+                  int transform = (layer->flags & HWC_COLOR_FILL) ? 0 :
+                      layer->transform;
 
                   hwc_rect_t irect = getIntersection(bottomframe, topframe);
                   if(isValidRect(irect)) {
@@ -1155,10 +1167,10 @@
                      qhwc::calculate_crop_rects(bottomCrop, bottomframe,
                                                 dest_rect, transform);
                      //Update layer sourceCropf
-                     layer->sourceCropf.left = bottomCrop.left;
-                     layer->sourceCropf.top = bottomCrop.top;
-                     layer->sourceCropf.right = bottomCrop.right;
-                     layer->sourceCropf.bottom = bottomCrop.bottom;
+                     layer->sourceCropf.left =(float)bottomCrop.left;
+                     layer->sourceCropf.top = (float)bottomCrop.top;
+                     layer->sourceCropf.right = (float)bottomCrop.right;
+                     layer->sourceCropf.bottom = (float)bottomCrop.bottom;
                   }
                }
                j--;
@@ -1171,7 +1183,7 @@
 void getNonWormholeRegion(hwc_display_contents_1_t* list,
                               hwc_rect_t& nwr)
 {
-    uint32_t last = list->numHwLayers - 1;
+    size_t last = list->numHwLayers - 1;
     hwc_rect_t fbDisplayFrame = list->hwLayers[last].displayFrame;
     //Initiliaze nwr to first frame
     nwr.left =  list->hwLayers[0].displayFrame.left;
@@ -1179,7 +1191,7 @@
     nwr.right =  list->hwLayers[0].displayFrame.right;
     nwr.bottom =  list->hwLayers[0].displayFrame.bottom;
 
-    for (uint32_t i = 1; i < last; i++) {
+    for (size_t i = 1; i < last; i++) {
         hwc_rect_t displayFrame = list->hwLayers[i].displayFrame;
         nwr = getUnion(nwr, displayFrame);
     }
@@ -1312,12 +1324,11 @@
     if(ret < 0) {
         ALOGE("%s: ioctl MSMFB_BUFFER_SYNC failed, err=%s",
                   __FUNCTION__, strerror(errno));
-        ALOGE("%s: acq_fen_fd_cnt=%d flags=%d fd=%d dpy=%d numHwLayers=%d",
+        ALOGE("%s: acq_fen_fd_cnt=%d flags=%d fd=%d dpy=%d numHwLayers=%zu",
               __FUNCTION__, data.acq_fen_fd_cnt, data.flags, fbFd,
               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 ||
@@ -1329,10 +1340,8 @@
                 // Release all the app layer fds immediately,
                 // if animation is in progress.
                 list->hwLayers[i].releaseFenceFd = -1;
-            } else if(list->hwLayers[i].releaseFenceFd < 0 &&
-                    !(layerProp[i].mFlags & HWC_VPUCOMP)) {
+            } else if(list->hwLayers[i].releaseFenceFd < 0 ) {
                 //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
@@ -1376,19 +1385,13 @@
                 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 &&
-                (!qdutils::MDPVersion::getInstance().is8092())) {
+                metadata->interlaced) {
             ovutils::setMdpFlags(mdpFlags,
                     ovutils::OV_MDP_DEINTERLACE);
         }
@@ -1574,17 +1577,7 @@
     int downscale = 0;
     int rotFlags = ovutils::ROT_FLAGS_NONE;
     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
+    Whf whf(getWidth(hnd), getHeight(hnd), format, (uint32_t)hnd->size);
 
     // Handle R/B swap
     if (layer->flags & HWC_FORMAT_RB_SWAP) {
@@ -1614,6 +1607,7 @@
             ((transform & HWC_TRANSFORM_ROT_90) || downscale)) {
         *rot = ctx->mRotMgr->getNext();
         if(*rot == NULL) return -1;
+        ctx->mLayerRotMap[dpy]->add(layer, *rot);
         if(!dpy)
             BwcPM::setBwc(crop, dst, transform, mdpFlags);
         //Configure rotator for pre-rotation
@@ -1621,7 +1615,6 @@
             ALOGE("%s: configRotator failed!", __FUNCTION__);
             return -1;
         }
-        ctx->mLayerRotMap[dpy]->add(layer, *rot);
         whf.format = (*rot)->getDstFormat();
         updateSource(orient, whf, crop);
         rotFlags |= ovutils::ROT_PREROTATED;
@@ -1691,17 +1684,7 @@
     const int downscale = 0;
     int rotFlags = ROT_FLAGS_NONE;
     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
+    Whf whf(getWidth(hnd), getHeight(hnd), format, (uint32_t)hnd->size);
 
     // Handle R/B swap
     if (layer->flags & HWC_FORMAT_RB_SWAP) {
@@ -1732,12 +1715,12 @@
     if(isYuvBuffer(hnd) && (transform & HWC_TRANSFORM_ROT_90)) {
         (*rot) = ctx->mRotMgr->getNext();
         if((*rot) == NULL) return -1;
+        ctx->mLayerRotMap[dpy]->add(layer, *rot);
         //Configure rotator for pre-rotation
         if(configRotator(*rot, whf, crop, mdpFlagsL, orient, downscale) < 0) {
             ALOGE("%s: configRotator failed!", __FUNCTION__);
             return -1;
         }
-        ctx->mLayerRotMap[dpy]->add(layer, *rot);
         whf.format = (*rot)->getDstFormat();
         updateSource(orient, whf, crop);
         rotFlags |= ROT_PREROTATED;
@@ -1848,7 +1831,7 @@
     eZorder rz = (eZorder)(z + 1);
 
     Whf whf(getWidth(hnd), getHeight(hnd),
-            getMdpFormat(hnd->format), hnd->size);
+            getMdpFormat(hnd->format), (uint32_t)hnd->size);
 
     /* Calculate the external display position based on MDP downscale,
        ActionSafe, and extorientation features. */
@@ -1860,6 +1843,7 @@
     if(isYuvBuffer(hnd) && (transform & HWC_TRANSFORM_ROT_90)) {
         (*rot) = ctx->mRotMgr->getNext();
         if((*rot) == NULL) return -1;
+        ctx->mLayerRotMap[dpy]->add(layer, *rot);
         if(!dpy)
             BwcPM::setBwc(crop, dst, transform, mdpFlagsL);
         //Configure rotator for pre-rotation
@@ -1867,7 +1851,6 @@
             ALOGE("%s: configRotator failed!", __FUNCTION__);
             return -1;
         }
-        ctx->mLayerRotMap[dpy]->add(layer, *rot);
         whf.format = (*rot)->getDstFormat();
         updateSource(orient, whf, crop);
         rotFlags |= ROT_PREROTATED;
@@ -2021,6 +2004,78 @@
     return true;
 }
 
+bool isGLESComp(hwc_context_t *ctx,
+                     hwc_display_contents_1_t* list) {
+    int numAppLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
+    for(int index = 0; index < numAppLayers; index++) {
+        hwc_layer_1_t* layer = &(list->hwLayers[index]);
+        if(layer->compositionType == HWC_FRAMEBUFFER)
+            return true;
+    }
+    return false;
+}
+
+void setGPUHint(hwc_context_t* ctx, hwc_display_contents_1_t* list) {
+    struct gpu_hint_info *gpuHint = &ctx->mGPUHintInfo;
+    if(!gpuHint->mGpuPerfModeEnable)
+        return;
+    /* Set the GPU hint flag to high for MIXED/GPU composition only for
+       first frame after MDP -> GPU/MIXED mode transition. Set the GPU
+       hint to default if the previous composition is GPU or current GPU
+       composition is due to idle fallback */
+    if(!gpuHint->mEGLDisplay || !gpuHint->mEGLContext) {
+        gpuHint->mEGLDisplay = eglGetCurrentDisplay();
+        if(!gpuHint->mEGLDisplay) {
+            ALOGW("%s Warning: EGL current display is NULL", __FUNCTION__);
+            return;
+        }
+        gpuHint->mEGLContext = eglGetCurrentContext();
+        if(!gpuHint->mEGLContext) {
+            ALOGW("%s Warning: EGL current context is NULL", __FUNCTION__);
+            return;
+        }
+    }
+    if(isGLESComp(ctx, list)) {
+        if(!gpuHint->mPrevCompositionGLES && !MDPComp::isIdleFallback()) {
+            EGLint attr_list[] = {EGL_GPU_HINT_1,
+                                  EGL_GPU_LEVEL_3,
+                                  EGL_NONE };
+            if((gpuHint->mCurrGPUPerfMode != EGL_GPU_LEVEL_3) &&
+                !eglGpuPerfHintQCOM(gpuHint->mEGLDisplay,
+                                    gpuHint->mEGLContext, attr_list)) {
+                ALOGW("eglGpuPerfHintQCOM failed for Built in display");
+            } else {
+                gpuHint->mCurrGPUPerfMode = EGL_GPU_LEVEL_3;
+                gpuHint->mPrevCompositionGLES = true;
+            }
+        } else {
+            EGLint attr_list[] = {EGL_GPU_HINT_1,
+                                  EGL_GPU_LEVEL_0,
+                                  EGL_NONE };
+            if((gpuHint->mCurrGPUPerfMode != EGL_GPU_LEVEL_0) &&
+                !eglGpuPerfHintQCOM(gpuHint->mEGLDisplay,
+                                    gpuHint->mEGLContext, attr_list)) {
+                ALOGW("eglGpuPerfHintQCOM failed for Built in display");
+            } else {
+                gpuHint->mCurrGPUPerfMode = EGL_GPU_LEVEL_0;
+            }
+        }
+    } else {
+        /* set the GPU hint flag to default for MDP composition */
+        EGLint attr_list[] = {EGL_GPU_HINT_1,
+                              EGL_GPU_LEVEL_0,
+                              EGL_NONE };
+        if((gpuHint->mCurrGPUPerfMode != EGL_GPU_LEVEL_0) &&
+                !eglGpuPerfHintQCOM(gpuHint->mEGLDisplay,
+                                    gpuHint->mEGLContext, attr_list)) {
+            ALOGW("eglGpuPerfHintQCOM failed for Built in display");
+        } else {
+            gpuHint->mCurrGPUPerfMode = EGL_GPU_LEVEL_0;
+        }
+        gpuHint->mPrevCompositionGLES = false;
+    }
+}
+
 void BwcPM::setBwc(const hwc_rect_t& crop,
             const hwc_rect_t& dst, const int& transform,
             ovutils::eMdpFlags& mdpFlags) {
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 4aa6410..ed68988 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -30,6 +30,8 @@
 #include <utils/String8.h>
 #include "qdMetaData.h"
 #include <overlayUtils.h>
+#include <EGL/egl.h>
+
 
 #define ALIGN_TO(x, align)     (((x) + ((align)-1)) & ~((align)-1))
 #define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
@@ -60,7 +62,6 @@
 class CopyBit;
 class HwcDebug;
 class AssertiveDisplay;
-class VPUClient;
 class HWCVirtualBase;
 
 
@@ -145,14 +146,12 @@
 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 {
@@ -190,7 +189,7 @@
 }
 
 inline hwc_rect_t integerizeSourceCrop(const hwc_frect_t& cropF) {
-    hwc_rect_t cropI = {0};
+    hwc_rect_t cropI = {0,0,0,0};
     cropI.left = int(ceilf(cropF.left));
     cropI.top = int(ceilf(cropF.top));
     cropI.right = int(floorf(cropF.right));
@@ -344,6 +343,12 @@
 
 bool isDisplaySplit(hwc_context_t* ctx, int dpy);
 
+// Set the GPU hint flag to high for MIXED/GPU composition only for
+// first frame after MDP to GPU/MIXED mode transition.
+// Set the GPU hint to default if the current composition type is GPU
+// due to idle fallback or MDP composition.
+void setGPUHint(hwc_context_t* ctx, hwc_display_contents_1_t* list);
+
 // Inline utility functions
 static inline bool isSkipLayer(const hwc_layer_1_t* l) {
     return (UNLIKELY(l && (l->flags & HWC_SKIP_LAYER)));
@@ -442,6 +447,20 @@
     ANIMATION_STARTED,
 };
 
+// Structure holds the information about the GPU hint.
+struct gpu_hint_info {
+    // system level flag to enable gpu_perf_mode
+    bool mGpuPerfModeEnable;
+    // Stores the current GPU performance mode DEFAULT/HIGH
+    bool mCurrGPUPerfMode;
+    // true if previous composition used GPU
+    bool mPrevCompositionGLES;
+    // Stores the EGLContext of current process
+    EGLContext mEGLContext;
+    // Stores the EGLDisplay of current process
+    EGLDisplay mEGLDisplay;
+};
+
 // -----------------------------------------------------------------------------
 // HWC context
 // This structure contains overall state
@@ -471,7 +490,6 @@
     qhwc::HwcDebug *mHwcDebug[HWC_NUM_DISPLAY_TYPES];
     hwc_rect_t mViewFrame[HWC_NUM_DISPLAY_TYPES];
     qhwc::AssertiveDisplay *mAD;
-    qhwc::VPUClient *mVPUClient;
     eAnimationState mAnimationState[HWC_NUM_DISPLAY_TYPES];
     qhwc::HWCVirtualBase *mHWCVirtual;
 
@@ -506,6 +524,7 @@
     // Downscale feature switch, set via system the property
     // sys.hwc.mdp_downscale_enabled
     bool mMDPDownscaleEnabled;
+    struct gpu_hint_info mGPUHintInfo;
 };
 
 namespace qhwc {
diff --git a/libhwcomposer/hwc_virtual.cpp b/libhwcomposer/hwc_virtual.cpp
index cc29d45..f68d08f 100644
--- a/libhwcomposer/hwc_virtual.cpp
+++ b/libhwcomposer/hwc_virtual.cpp
@@ -69,6 +69,7 @@
     //Cleanup virtual display objs, since there is no explicit disconnect
     if(ctx->dpyAttr[dpy].connected && (displays[dpy] == NULL)) {
         ctx->dpyAttr[dpy].connected = false;
+        ctx->dpyAttr[dpy].isPause = false;
 
         if(ctx->mFBUpdate[dpy]) {
             delete ctx->mFBUpdate[dpy];
@@ -94,8 +95,8 @@
     const int dpy = HWC_DISPLAY_VIRTUAL;
 
     if (list && list->outbuf && list->numHwLayers > 0) {
-        reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
-        uint32_t last = list->numHwLayers - 1;
+        reset_layer_prop(ctx, dpy, (int)list->numHwLayers - 1);
+        uint32_t last = (uint32_t)list->numHwLayers - 1;
         hwc_layer_1_t *fbLayer = &list->hwLayers[last];
         int fbWidth = 0, fbHeight = 0;
         getLayerResolution(fbLayer, fbWidth, fbHeight);
@@ -104,6 +105,7 @@
 
         if(ctx->dpyAttr[dpy].connected == false) {
             ctx->dpyAttr[dpy].connected = true;
+            ctx->dpyAttr[dpy].isPause = false;
             // 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
@@ -113,16 +115,27 @@
             // allow one padding round to free up resources but this breaks
             // certain use cases.
         }
+        if(!ctx->dpyAttr[dpy].isPause) {
+            ctx->dpyAttr[dpy].isConfiguring = false;
+            ctx->dpyAttr[dpy].fd = Writeback::getInstance()->getFbFd();
+            private_handle_t *ohnd = (private_handle_t *)list->outbuf;
+            Writeback::getInstance()->configureDpyInfo(ohnd->width,
+                                                          ohnd->height);
+            setListStats(ctx, list, dpy);
 
-        ctx->dpyAttr[dpy].isConfiguring = false;
-        ctx->dpyAttr[dpy].fd = Writeback::getInstance()->getFbFd();
-        private_handle_t *ohnd = (private_handle_t *)list->outbuf;
-        Writeback::getInstance()->configureDpyInfo(ohnd->width, ohnd->height);
-        setListStats(ctx, list, dpy);
-
-        if(ctx->mMDPComp[dpy]->prepare(ctx, list) < 0) {
-            const int fbZ = 0;
-            ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ);
+            if(ctx->mMDPComp[dpy]->prepare(ctx, list) < 0) {
+                const int fbZ = 0;
+                ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ);
+            }
+        } else {
+            /* Virtual Display is in Pause state.
+             * Mark all application layers as OVERLAY so that
+             * GPU will not compose.
+             */
+            for(size_t i = 0 ;i < (size_t)(list->numHwLayers - 1); i++) {
+                hwc_layer_1_t *layer = &list->hwLayers[i];
+                layer->compositionType = HWC_OVERLAY;
+            }
         }
     }
     return 0;
@@ -134,10 +147,12 @@
     const int dpy = HWC_DISPLAY_VIRTUAL;
 
     if (list && list->outbuf && list->numHwLayers > 0) {
-        uint32_t last = list->numHwLayers - 1;
+        uint32_t last = (uint32_t)list->numHwLayers - 1;
         hwc_layer_1_t *fbLayer = &list->hwLayers[last];
 
-        if(ctx->dpyAttr[dpy].connected) {
+        if(ctx->dpyAttr[dpy].connected
+                && (!ctx->dpyAttr[dpy].isPause))
+        {
             private_handle_t *ohnd = (private_handle_t *)list->outbuf;
             int format = ohnd->format;
             if (format == HAL_PIXEL_FORMAT_RGBA_8888)
@@ -173,7 +188,8 @@
                 ret = -1;
             }
 
-            Writeback::getInstance()->queueBuffer(ohnd->fd, ohnd->offset);
+            Writeback::getInstance()->queueBuffer(ohnd->fd,
+                                        (uint32_t)ohnd->offset);
             if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
                 ALOGE("%s: display commit fail!", __FUNCTION__);
                 ret = -1;
@@ -194,6 +210,36 @@
     return ret;
 }
 
+void HWCVirtualVDS::pause(hwc_context_t* ctx, int dpy) {
+    {
+        Locker::Autolock _l(ctx->mDrawLock);
+        ctx->dpyAttr[dpy].isActive = true;
+        ctx->dpyAttr[dpy].isPause = true;
+        ctx->proc->invalidate(ctx->proc);
+    }
+    usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
+            * 2 / 1000);
+    return;
+}
+
+void HWCVirtualVDS::resume(hwc_context_t* ctx, int dpy) {
+    {
+        Locker::Autolock _l(ctx->mDrawLock);
+        ctx->dpyAttr[dpy].isConfiguring = true;
+        ctx->dpyAttr[dpy].isActive = true;
+        ctx->proc->invalidate(ctx->proc);
+    }
+    usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
+            * 2 / 1000);
+    //At this point external has all the pipes it would need.
+    {
+        Locker::Autolock _l(ctx->mDrawLock);
+        ctx->dpyAttr[dpy].isPause = false;
+        ctx->proc->invalidate(ctx->proc);
+    }
+    return;
+}
+
 /* Implementation for HWCVirtualV4L2 class */
 
 int HWCVirtualV4L2::prepare(hwc_composer_device_1 *dev,
@@ -207,7 +253,7 @@
             ctx->dpyAttr[dpy].isActive &&
             ctx->dpyAttr[dpy].connected &&
             canUseMDPforVirtualDisplay(ctx,list)) {
-        reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
+        reset_layer_prop(ctx, dpy, (int)list->numHwLayers - 1);
         if(!ctx->dpyAttr[dpy].isPause) {
             ctx->dpyAttr[dpy].isConfiguring = false;
             setListStats(ctx, list, dpy);
@@ -239,7 +285,7 @@
             ctx->dpyAttr[dpy].connected &&
             (!ctx->dpyAttr[dpy].isPause) &&
             canUseMDPforVirtualDisplay(ctx,list)) {
-        uint32_t last = list->numHwLayers - 1;
+        uint32_t last = (uint32_t)list->numHwLayers - 1;
         hwc_layer_1_t *fbLayer = &list->hwLayers[last];
         int fd = -1; //FenceFD from the Copybit(valid in async mode)
         bool copybitDone = false;
@@ -294,3 +340,56 @@
 
     return ret;
 }
+
+void HWCVirtualV4L2::pause(hwc_context_t* ctx, int dpy) {
+    {
+        Locker::Autolock _l(ctx->mDrawLock);
+        ctx->dpyAttr[dpy].isActive = true;
+        ctx->dpyAttr[dpy].isPause = true;
+        ctx->proc->invalidate(ctx->proc);
+    }
+    usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
+            * 2 / 1000);
+    // At this point all the pipes used by External have been
+    // marked as UNSET.
+    {
+        Locker::Autolock _l(ctx->mDrawLock);
+        // Perform commit to unstage the pipes.
+        if (!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
+            ALOGE("%s: display commit fail! for %d dpy",
+                    __FUNCTION__, dpy);
+        }
+    }
+    return;
+}
+
+void HWCVirtualV4L2::resume(hwc_context_t* ctx, int dpy){
+    //Treat Resume as Online event
+    //Since external didnt have any pipes, force primary to give up
+    //its pipes; we don't allow inter-mixer pipe transfers.
+    {
+        Locker::Autolock _l(ctx->mDrawLock);
+
+        // A dynamic resolution change (DRC) can be made for a WiFi
+        // display. In order to support the resolution change, we
+        // need to reconfigure the corresponding display attributes.
+        // Since DRC is only on WiFi display, we only need to call
+        // configure() on the VirtualDisplay device.
+        //TODO: clean up
+        if(dpy == HWC_DISPLAY_VIRTUAL)
+            ctx->mVirtualDisplay->configure();
+
+        ctx->dpyAttr[dpy].isConfiguring = true;
+        ctx->dpyAttr[dpy].isActive = true;
+        ctx->proc->invalidate(ctx->proc);
+    }
+    usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
+            * 2 / 1000);
+    //At this point external has all the pipes it would need.
+    {
+        Locker::Autolock _l(ctx->mDrawLock);
+        ctx->dpyAttr[dpy].isPause = false;
+        ctx->proc->invalidate(ctx->proc);
+    }
+    return;
+}
diff --git a/libhwcomposer/hwc_virtual.h b/libhwcomposer/hwc_virtual.h
index 26f401f..6bc3898 100644
--- a/libhwcomposer/hwc_virtual.h
+++ b/libhwcomposer/hwc_virtual.h
@@ -22,6 +22,7 @@
 #define HWC_VIRTUAL
 
 #include <hwc_utils.h>
+#include <virtual.h>
 
 namespace qhwc {
 namespace ovutils = overlay::utils;
@@ -39,6 +40,8 @@
     virtual void init(hwc_context_t *ctx) = 0;
     virtual void destroy(hwc_context_t *ctx, size_t numDisplays,
                        hwc_display_contents_1_t** displays) = 0;
+    virtual void pause(hwc_context_t* ctx, int dpy) = 0;
+    virtual void resume(hwc_context_t* ctx, int dpy) = 0;
 };
 
 class HWCVirtualVDS : public HWCVirtualBase {
@@ -59,6 +62,8 @@
     // during virtual display disconnect.
     virtual void destroy(hwc_context_t *ctx, size_t numDisplays,
                        hwc_display_contents_1_t** displays);
+    virtual void pause(hwc_context_t* ctx, int dpy);
+    virtual void resume(hwc_context_t* ctx, int dpy);
 };
 
 class HWCVirtualV4L2 : public HWCVirtualBase {
@@ -80,6 +85,8 @@
     // during virtual display disconnect. This function is no-op for V4L2 design
     virtual void destroy(hwc_context_t *, size_t ,
                        hwc_display_contents_1_t** ) {};
+    virtual void pause(hwc_context_t* ctx, int dpy);
+    virtual void resume(hwc_context_t* ctx, int dpy);
 };
 
 }; //namespace
diff --git a/libhwcomposer/hwc_vpuclient.cpp b/libhwcomposer/hwc_vpuclient.cpp
deleted file mode 100644
index 6904efc..0000000
--- a/libhwcomposer/hwc_vpuclient.cpp
+++ /dev/null
@@ -1,964 +0,0 @@
-/*
- * 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 <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(hwc_context_t *ctx)
-{
-    mVPULib = dlopen("libvpu.so", RTLD_NOW);
-    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);
-}
-
-void setLayer(hwc_layer_1_t *layer, Layer *vLayer)
-{
-    // 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::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;
-    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)
-{
-    if (!mVPU)
-        return 0;
-
-    return mVPU->processCommand(command, inParcel, outParcel);
-}
-
-}; // namespace qhwc
diff --git a/libhwcomposer/hwc_vpuclient.h b/libhwcomposer/hwc_vpuclient.h
deleted file mode 100644
index bb2a4b6..0000000
--- a/libhwcomposer/hwc_vpuclient.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
-* 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.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef HWC_VPU_H
-#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;
-};
-
-namespace qhwc {
-
-class VPUClient {
-public:
-    VPUClient(hwc_context_t *ctx);
-
-    ~VPUClient();
-
-    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);
-    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 3729f21..7bde83b 100644
--- a/libhwcomposer/hwc_vsync.cpp
+++ b/libhwcomposer/hwc_vsync.cpp
@@ -37,6 +37,10 @@
 
 #define HWC_VSYNC_THREAD_NAME "hwcVsyncThread"
 #define MAX_SYSFS_FILE_PATH             255
+#define PANEL_ON_STR "panel_power_on ="
+#define ARRAY_LENGTH(array) (sizeof((array))/sizeof((array)[0]))
+const int MAX_DATA = 64;
+bool logvsync = false;
 
 int hwc_vsync_control(hwc_context_t* ctx, int dpy, int enable)
 {
@@ -51,6 +55,40 @@
     return ret;
 }
 
+static void handle_vsync_event(hwc_context_t* ctx, int dpy, char *data)
+{
+    // extract timestamp
+    uint64_t timestamp = 0;
+    if (!strncmp(data, "VSYNC=", strlen("VSYNC="))) {
+        timestamp = strtoull(data + strlen("VSYNC="), NULL, 0);
+    }
+    // send timestamp to SurfaceFlinger
+    ALOGD_IF (logvsync, "%s: timestamp %"PRIu64" sent to SF for dpy=%d",
+            __FUNCTION__, timestamp, dpy);
+    ctx->proc->vsync(ctx->proc, dpy, timestamp);
+}
+
+static void handle_blank_event(hwc_context_t* ctx, int dpy, char *data)
+{
+    if (!strncmp(data, PANEL_ON_STR, strlen(PANEL_ON_STR))) {
+        uint32_t poweron = strtoul(data + strlen(PANEL_ON_STR), NULL, 0);
+        ALOGI("%s: dpy:%d panel power state: %d", __FUNCTION__, dpy, poweron);
+        ctx->dpyAttr[dpy].isActive = poweron ? true: false;
+    }
+}
+
+struct event {
+    const char* name;
+    void (*callback)(hwc_context_t* ctx, int dpy, char *data);
+};
+
+struct event event_list[] =  {
+    { "vsync_event", handle_vsync_event },
+    { "show_blank_event", handle_blank_event },
+};
+
+#define num_events ARRAY_LENGTH(event_list)
+
 static void *vsync_loop(void *param)
 {
     hwc_context_t * ctx = reinterpret_cast<hwc_context_t *>(param);
@@ -60,14 +98,11 @@
     setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY +
                 android::PRIORITY_MORE_FAVORABLE);
 
-    const int MAX_DATA = 64;
     char vdata[MAX_DATA];
-    bool logvsync = false;
-
-    struct pollfd pfd[2];
-    int fb_fd[2];
-    uint64_t timestamp[2] = {0,0};
-    int num_displays;
+    //Number of physical displays
+    //We poll on all the nodes.
+    int num_displays = HWC_NUM_DISPLAY_TYPES - 1;
+    struct pollfd pfd[num_displays][num_events];
 
     char property[PROPERTY_VALUE_MAX];
     if(property_get("debug.hwc.fakevsync", property, NULL) > 0) {
@@ -80,69 +115,62 @@
             logvsync = true;
     }
 
-    if (ctx->mExtDisplay->isConnected())
-        num_displays = 2;
-    else
-        num_displays = 1;
+    char node_path[MAX_SYSFS_FILE_PATH];
 
-    char vsync_node_path[MAX_SYSFS_FILE_PATH];
     for (int dpy = HWC_DISPLAY_PRIMARY; dpy < num_displays; dpy++) {
-        snprintf(vsync_node_path, sizeof(vsync_node_path),
-                "/sys/class/graphics/fb%d/vsync_event",
-                dpy == HWC_DISPLAY_PRIMARY ? 0 :
-                overlay::Overlay::getInstance()->
-                                getFbForDpy(HWC_DISPLAY_EXTERNAL));
-        ALOGI("%s: Reading vsync for dpy=%d from %s", __FUNCTION__, dpy,
-                vsync_node_path);
-        fb_fd[dpy] = open(vsync_node_path, O_RDONLY);
+        for(size_t ev = 0; ev < num_events; ev++) {
+            snprintf(node_path, sizeof(node_path),
+                    "/sys/class/graphics/fb%d/%s",
+                    dpy == HWC_DISPLAY_PRIMARY ? 0 :
+                    overlay::Overlay::getInstance()->
+                    getFbForDpy(HWC_DISPLAY_EXTERNAL),
+                    event_list[ev].name);
 
-        if (fb_fd[dpy] < 0) {
-            // Make sure fb device is opened before starting this thread so this
-            // never happens.
-            ALOGE ("%s:not able to open vsync node for dpy=%d, %s",
-                    __FUNCTION__, dpy, strerror(errno));
-            if (dpy == HWC_DISPLAY_PRIMARY) {
-                ctx->vstate.fakevsync = true;
-                break;
+            ALOGI("%s: Reading event %zu for dpy %d from %s", __FUNCTION__,
+                    ev, dpy, node_path);
+            pfd[dpy][ev].fd = open(node_path, O_RDONLY);
+
+            if (dpy == HWC_DISPLAY_PRIMARY && pfd[dpy][ev].fd < 0) {
+                // Make sure fb device is opened before starting
+                // this thread so this never happens.
+                ALOGE ("%s:unable to open event node for dpy=%d event=%zu, %s",
+                        __FUNCTION__, dpy, ev, strerror(errno));
+                if (ev == 0) {
+                    ctx->vstate.fakevsync = true;
+                    //XXX: Blank events don't work with fake vsync,
+                    //but we shouldn't be running on fake vsync anyway.
+                    break;
+                }
             }
-        }
-        // Read once from the fds to clear the first notify
-        pread(fb_fd[dpy], vdata , MAX_DATA, 0);
 
-        pfd[dpy].fd = fb_fd[dpy];
-        if (pfd[dpy].fd >= 0)
-            pfd[dpy].events = POLLPRI | POLLERR;
+            pread(pfd[dpy][ev].fd, vdata , MAX_DATA, 0);
+            if (pfd[dpy][ev].fd >= 0)
+                pfd[dpy][ev].events = POLLPRI | POLLERR;
+        }
     }
 
     if (LIKELY(!ctx->vstate.fakevsync)) {
         do {
-            int err = poll(pfd, num_displays, -1);
+            int err = poll(*pfd, num_displays * num_events, -1);
             if(err > 0) {
                 for (int dpy = HWC_DISPLAY_PRIMARY; dpy < num_displays; dpy++) {
-                    if (pfd[dpy].revents & POLLPRI) {
-                        int len = pread(pfd[dpy].fd, vdata, MAX_DATA, 0);
-                        if (UNLIKELY(len < 0)) {
-                            // If the read was just interrupted - it is not a
-                            // fatal error. Just continue in this case
-                            ALOGE ("%s: Unable to read vsync for dpy=%d : %s",
-                                    __FUNCTION__, dpy, strerror(errno));
-                            continue;
+                    for(size_t ev = 0; ev < num_events; ev++) {
+                        if (pfd[dpy][ev].revents & POLLPRI) {
+                            ssize_t len = pread(pfd[dpy][ev].fd, vdata, MAX_DATA, 0);
+                            if (UNLIKELY(len < 0)) {
+                                // If the read was just interrupted - it is not
+                                // a fatal error. Just continue in this case
+                                ALOGE ("%s: Unable to read event:%zu for \
+                                        dpy=%d : %s",
+                                        __FUNCTION__, ev, dpy, strerror(errno));
+                                continue;
+                            }
+                            event_list[ev].callback(ctx, dpy, vdata);
                         }
-                        // extract timestamp
-                        if (!strncmp(vdata, "VSYNC=", strlen("VSYNC="))) {
-                            timestamp[dpy] = strtoull(vdata + strlen("VSYNC="),
-                                    NULL, 0);
-                        }
-                        // send timestamp to SurfaceFlinger
-                        ALOGD_IF (logvsync,
-                            "%s: timestamp %"PRIu64" sent to SF for dpy=%d",
-                            __FUNCTION__, timestamp[dpy], dpy);
-                        ctx->proc->vsync(ctx->proc, dpy, timestamp[dpy]);
                     }
                 }
-
             } else {
-                ALOGE("%s: vsync poll failed errno: %s", __FUNCTION__,
+                ALOGE("%s: poll failed errno: %s", __FUNCTION__,
                         strerror(errno));
                 continue;
             }
@@ -157,16 +185,17 @@
         //Also, fake vsync is delivered only for the primary display.
         do {
             usleep(16666);
-            timestamp[HWC_DISPLAY_PRIMARY] = systemTime();
-            ctx->proc->vsync(ctx->proc, HWC_DISPLAY_PRIMARY,
-                    timestamp[HWC_DISPLAY_PRIMARY]);
+            uint64_t timestamp = systemTime();
+            ctx->proc->vsync(ctx->proc, HWC_DISPLAY_PRIMARY, timestamp);
 
         } while (true);
     }
 
     for (int dpy = HWC_DISPLAY_PRIMARY; dpy <= HWC_DISPLAY_EXTERNAL; dpy++ ) {
-        if(fb_fd[dpy] >= 0)
-            close (fb_fd[dpy]);
+        for( size_t event = 0; event < num_events; event++) {
+            if(pfd[dpy][event].fd >= 0)
+                close (pfd[dpy][event].fd);
+        }
     }
 
     return NULL;
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index 265aa9f..7e7f275 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -175,6 +175,19 @@
     return false;
 }
 
+int Overlay::comparePipePriority(utils::eDest pipe1Index,
+        utils::eDest pipe2Index) {
+    validate((int)pipe1Index);
+    validate((int)pipe2Index);
+    uint8_t pipe1Prio = mPipeBook[(int)pipe1Index].mPipe->getPriority();
+    uint8_t pipe2Prio = mPipeBook[(int)pipe2Index].mPipe->getPriority();
+    if(pipe1Prio > pipe2Prio)
+        return 1;
+    if(pipe1Prio < pipe2Prio)
+        return -1;
+    return 0;
+}
+
 bool Overlay::commit(utils::eDest dest) {
     bool ret = false;
     int index = (int)dest;
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index d8615cd..44193be 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -114,6 +114,12 @@
      * displays
      */
     bool isPipeTypeAttached(utils::eMdpPipeType type);
+    /* Compare pipe priorities and return
+     * 1 if 1st pipe has a higher priority
+     * 0 if both have the same priority
+     *-1 if 2nd pipe has a higher priority
+     */
+    int comparePipePriority(utils::eDest pipe1Index, utils::eDest pipe2Index);
     /* Returns pipe dump. Expects a NULL terminated buffer of big enough size
      * to populate.
      */
diff --git a/liboverlay/overlayCtrlData.h b/liboverlay/overlayCtrlData.h
index 26202ec..51209a7 100644
--- a/liboverlay/overlayCtrlData.h
+++ b/liboverlay/overlayCtrlData.h
@@ -79,6 +79,8 @@
     void setDownscale(int dscale_factor);
     /* Update the src format based on rotator's dest */
     void updateSrcFormat(const uint32_t& rotDstFormat);
+    /* return pipe priority */
+    uint8_t getPriority() const;
     /* dump the state of the object */
     void dump() const;
     /* Return the dump in the specified buffer */
@@ -208,6 +210,10 @@
     mMdp->setDownscale(dscale_factor);
 }
 
+inline uint8_t Ctrl::getPriority() const {
+    return mMdp->getPriority();
+}
+
 inline void Ctrl::getDump(char *buf, size_t len) {
     mMdp->getDump(buf, len);
 }
diff --git a/liboverlay/overlayMdp.cpp b/liboverlay/overlayMdp.cpp
index cfbff5e..d36c975 100644
--- a/liboverlay/overlayMdp.cpp
+++ b/liboverlay/overlayMdp.cpp
@@ -194,6 +194,10 @@
             if (!(mOVInfo.flags & MDP_SOURCE_ROTATED_90) &&
                 (mOVInfo.src_rect.h % 4))
                 mOVInfo.src_rect.h = utils::aligndown(mOVInfo.src_rect.h, 4);
+            // For interlaced, width must be multiple of 4 when rotated 90deg.
+            else if ((mOVInfo.flags & MDP_SOURCE_ROTATED_90) &&
+                (mOVInfo.src_rect.w % 4))
+                mOVInfo.src_rect.w = utils::aligndown(mOVInfo.src_rect.w, 4);
         }
     } else {
         if (mdpVersion >= MDSS_V5) {
diff --git a/liboverlay/overlayMdp.h b/liboverlay/overlayMdp.h
index 843556b..d312c2e 100644
--- a/liboverlay/overlayMdp.h
+++ b/liboverlay/overlayMdp.h
@@ -80,6 +80,8 @@
     utils::Dim getDstRectDim() const;
     /* returns a copy to src rect dim */
     utils::Dim getSrcRectDim() const;
+    /* return pipe priority */
+    uint8_t getPriority() const;
     /* setVisualParam */
     bool setVisualParams(const MetaData_t& data);
 
@@ -304,6 +306,10 @@
         mOVInfo.flags |= MDP_SOURCE_ROTATED_90;
 }
 
+inline uint8_t MdpCtrl::getPriority() const {
+    return mOVInfo.priority;
+}
+
 ///////    MdpCtrl3D //////
 
 inline MdpCtrl3D::MdpCtrl3D() { reset(); }
diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h
index c0066f3..c2649f3 100644
--- a/liboverlay/overlayUtils.h
+++ b/liboverlay/overlayUtils.h
@@ -272,7 +272,6 @@
     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 {
diff --git a/liboverlay/pipes/overlayGenPipe.cpp b/liboverlay/pipes/overlayGenPipe.cpp
index 9e57223..303cd34 100644
--- a/liboverlay/pipes/overlayGenPipe.cpp
+++ b/liboverlay/pipes/overlayGenPipe.cpp
@@ -106,6 +106,10 @@
     return mCtrl->getCrop();
 }
 
+uint8_t GenericPipe::getPriority() const {
+    return mCtrl->getPriority();
+}
+
 void GenericPipe::dump() const
 {
     ALOGE("== Dump Generic pipe start ==");
diff --git a/liboverlay/pipes/overlayGenPipe.h b/liboverlay/pipes/overlayGenPipe.h
index 813a2b3..ee6f9ad 100644
--- a/liboverlay/pipes/overlayGenPipe.h
+++ b/liboverlay/pipes/overlayGenPipe.h
@@ -69,6 +69,8 @@
     bool isOpen() const;
     /* return Ctrl fd. Used for S3D */
     int getCtrlFd() const;
+    /* return pipe priority */
+    uint8_t getPriority() const;
     /* dump the state of the object */
     void dump() const;
     /* Return the dump in the specified buffer */
diff --git a/libqdutils/mdp_version.cpp b/libqdutils/mdp_version.cpp
index ed21b2c..a757e69 100644
--- a/libqdutils/mdp_version.cpp
+++ b/libqdutils/mdp_version.cpp
@@ -45,7 +45,7 @@
     MDSS_MDP_HW_REV_103 = 0x10030000, //8084
     MDSS_MDP_HW_REV_104 = 0x10040000, //Next version
     MDSS_MDP_HW_REV_105 = 0x10050000, //Next version
-    MDSS_MDP_HW_REV_107 = 0x10070000, //Next version
+    MDSS_MDP_HW_REV_106 = 0x10060000, //8x16
     MDSS_MDP_HW_REV_200 = 0x20000000, //8092
     MDSS_MDP_HW_REV_206 = 0x20060000, //Future
 };
@@ -53,6 +53,7 @@
 enum mdp_rev {
     MDSS_MDP_HW_REV_104 = 0x10040000, //Next version
     MDSS_MDP_HW_REV_206 = 0x20060000, //Future
+    MDSS_MDP_HW_REV_107 = 0x10070000, //Next version
 };
 #endif
 
@@ -67,14 +68,13 @@
     mMDPUpscale = 0;
     mMDPDownscale = 0;
     mMacroTileEnabled = false;
-    mPanelType = NO_PANEL;
     mLowBw = 0;
     mHighBw = 0;
     mSourceSplit = false;
+    mRGBHasNoScalar = false;
 
-    if(!updatePanelInfo()) {
-        ALOGE("Unable to read Primary Panel Information");
-    }
+    updatePanelInfo();
+
     if(!updateSysFsInfo()) {
         ALOGE("Unable to read display sysfs node");
     }
@@ -114,10 +114,12 @@
 }
 // This function reads the sysfs node to read the primary panel type
 // and updates information accordingly
-bool MDPVersion::updatePanelInfo() {
+void  MDPVersion::updatePanelInfo() {
     FILE *displayDeviceFP = NULL;
+    FILE *panelInfoNodeFP = NULL;
     const int MAX_FRAME_BUFFER_NAME_SIZE = 128;
     char fbType[MAX_FRAME_BUFFER_NAME_SIZE];
+    char panelInfo[MAX_FRAME_BUFFER_NAME_SIZE];
     const char *strCmdPanel = "mipi dsi cmd panel";
     const char *strVideoPanel = "mipi dsi video panel";
     const char *strLVDSPanel = "lvds panel";
@@ -128,21 +130,62 @@
         fread(fbType, sizeof(char), MAX_FRAME_BUFFER_NAME_SIZE,
                 displayDeviceFP);
         if(strncmp(fbType, strCmdPanel, strlen(strCmdPanel)) == 0) {
-            mPanelType = MIPI_CMD_PANEL;
+            mPanelInfo.mType = MIPI_CMD_PANEL;
         }
         else if(strncmp(fbType, strVideoPanel, strlen(strVideoPanel)) == 0) {
-            mPanelType = MIPI_VIDEO_PANEL;
+            mPanelInfo.mType = MIPI_VIDEO_PANEL;
         }
         else if(strncmp(fbType, strLVDSPanel, strlen(strLVDSPanel)) == 0) {
-            mPanelType = LVDS_PANEL;
+            mPanelInfo.mType = LVDS_PANEL;
         }
         else if(strncmp(fbType, strEDPPanel, strlen(strEDPPanel)) == 0) {
-            mPanelType = EDP_PANEL;
+            mPanelInfo.mType = EDP_PANEL;
         }
         fclose(displayDeviceFP);
-        return true;
-    }else {
-        return false;
+    } else {
+        ALOGE("Unable to read Primary Panel Information");
+    }
+
+    panelInfoNodeFP = fopen("/sys/class/graphics/fb0/msm_fb_panel_info", "r");
+    if(panelInfoNodeFP){
+        size_t len = PAGE_SIZE;
+        ssize_t read;
+        char *readLine = (char *) malloc (len);
+        while((read = getline((char **)&readLine, &len,
+                              panelInfoNodeFP)) != -1) {
+            int token_ct=0;
+            char *tokens[10];
+            memset(tokens, 0, sizeof(tokens));
+
+            if(!tokenizeParams(readLine, TOKEN_PARAMS_DELIM, tokens,
+                               &token_ct)) {
+                if(!strncmp(tokens[0], "pu_en", strlen("pu_en"))) {
+                    mPanelInfo.mPartialUpdateEnable = atoi(tokens[1]);
+                    ALOGI("PartialUpdate status: %s",
+                          mPanelInfo.mPartialUpdateEnable? "Enabled" :
+                          "Disabled");
+                }
+                if(!strncmp(tokens[0], "xalign", strlen("xalign"))) {
+                    mPanelInfo.mLeftAlign = atoi(tokens[1]);
+                    ALOGI("Left Align: %d", mPanelInfo.mLeftAlign);
+                }
+                if(!strncmp(tokens[0], "walign", strlen("walign"))) {
+                    mPanelInfo.mWidthAlign = atoi(tokens[1]);
+                    ALOGI("Width Align: %d", mPanelInfo.mWidthAlign);
+                }
+                if(!strncmp(tokens[0], "ystart", strlen("ystart"))) {
+                    mPanelInfo.mTopAlign = atoi(tokens[1]);
+                    ALOGI("Top Align: %d", mPanelInfo.mTopAlign);
+                }
+                if(!strncmp(tokens[0], "halign", strlen("halign"))) {
+                    mPanelInfo.mHeightAlign = atoi(tokens[1]);
+                    ALOGI("Height Align: %d", mPanelInfo.mHeightAlign);
+                }
+            }
+        }
+        fclose(panelInfoNodeFP);
+    } else {
+        ALOGE("Failed to open msm_fb_panel_info node");
     }
 }
 
@@ -223,6 +266,10 @@
                                     strlen("src_split"))) {
                             mSourceSplit = true;
                         }
+                        else if(!strncmp(tokens[i], "non_scalar_rgb",
+                                    strlen("non_scalar_rgb"))) {
+                            mRGBHasNoScalar = true;
+                        }
                     }
                 }
             }
@@ -295,6 +342,10 @@
     return mSourceSplit;
 }
 
+bool MDPVersion::isRGBScalarSupported() const {
+    return (!mRGBHasNoScalar);
+}
+
 bool MDPVersion::is8x26() {
     return (mMdpRev >= MDSS_MDP_HW_REV_101 and
             mMdpRev < MDSS_MDP_HW_REV_102);
@@ -315,5 +366,10 @@
             mMdpRev < MDSS_MDP_HW_REV_206);
 }
 
+bool MDPVersion::is8x16() {
+    return (mMdpRev >= MDSS_MDP_HW_REV_106 and
+            mMdpRev < MDSS_MDP_HW_REV_107);
+}
+
 }; //namespace qdutils
 
diff --git a/libqdutils/mdp_version.h b/libqdutils/mdp_version.h
index 5e36291..aab8643 100644
--- a/libqdutils/mdp_version.h
+++ b/libqdutils/mdp_version.h
@@ -92,13 +92,25 @@
     friend class MDPVersion;
 };
 
+struct PanelInfo {
+    char mType;                  // Smart or Dumb
+    int mPartialUpdateEnable;    // Partial update feature
+    int mLeftAlign;              // ROI left alignment restriction
+    int mWidthAlign;             // ROI width alignment restriction
+    int mTopAlign;               // ROI top alignment restriction
+    int mHeightAlign;            // ROI height alignment restriction
+    PanelInfo() : mType(NO_PANEL), mPartialUpdateEnable(0),
+    mLeftAlign(0), mWidthAlign(0), mTopAlign(0), mHeightAlign(0){}
+    friend class MDPVersion;
+};
+
 class MDPVersion : public Singleton <MDPVersion>
 {
 public:
     MDPVersion();
     ~MDPVersion();
     int getMDPVersion() {return mMDPVersion;}
-    char getPanelType() {return mPanelType;}
+    char getPanelType() {return mPanelInfo.mType;}
     bool hasOverlay() {return mHasOverlay;}
     uint8_t getTotalPipes() {
         return (uint8_t)(mRGBPipes + mVGPipes + mDMAPipes);
@@ -113,23 +125,29 @@
     bool supportsMacroTile();
     int getLeftSplit() { return mSplit.left(); }
     int getRightSplit() { return mSplit.right(); }
+    int isPartialUpdateEnabled() { return mPanelInfo.mPartialUpdateEnable; }
+    int getLeftAlign() { return mPanelInfo.mLeftAlign; }
+    int getWidthAlign() { return mPanelInfo.mWidthAlign; }
+    int getTopAlign() { return mPanelInfo.mTopAlign; }
+    int getHeightAlign() { return mPanelInfo.mHeightAlign; }
     unsigned long getLowBw() { return mLowBw; }
     unsigned long getHighBw() { return mHighBw; }
     bool isSrcSplit() const;
+    bool isRGBScalarSupported() const;
     bool is8x26();
     bool is8x74v2();
     bool is8084();
     bool is8092();
+    bool is8x16();
 
 private:
     bool updateSysFsInfo();
-    bool updatePanelInfo();
+    void updatePanelInfo();
     bool updateSplitInfo();
     int tokenizeParams(char *inputParams, const char *delim,
                         char* tokenStr[], int *idx);
     int mFd;
     int mMDPVersion;
-    char mPanelType;
     bool mHasOverlay;
     uint32_t mMdpRev;
     uint8_t mRGBPipes;
@@ -140,9 +158,11 @@
     uint32_t mMDPUpscale;
     bool mMacroTileEnabled;
     Split mSplit;
+    PanelInfo mPanelInfo;
     unsigned long mLowBw; //kbps
     unsigned long mHighBw; //kbps
     bool mSourceSplit;
+    bool mRGBHasNoScalar;
 };
 }; //namespace qdutils
 #endif //INCLUDE_LIBQCOMUTILS_MDPVER
diff --git a/libqdutils/qdMetaData.cpp b/libqdutils/qdMetaData.cpp
index b736478..0390599 100644
--- a/libqdutils/qdMetaData.cpp
+++ b/libqdutils/qdMetaData.cpp
@@ -82,26 +82,6 @@
             break;
         case UPDATE_BUFFER_GEOMETRY:
             memcpy((void *)&data->bufferDim, param, sizeof(BufferDim_t));
-            break;
-        case PP_PARAM_VFM_DATA:
-        {
-            int32_t     indx = 0;
-            VfmData_t*  pVfmData = reinterpret_cast <VfmData_t *>(param);
-            int32_t     dataType = pVfmData->dataType;
-
-            if(dataType > 0){
-                indx = getVfmDataIdx(dataType);
-                if(indx < MAX_VFM_DATA_COUNT){
-                    data->vfmDataBitMap |= dataType;
-                    memcpy((void *)&data->vfmData[indx], param,
-                        sizeof(VfmData_t));
-                }else{
-                    ALOGE("unknown dataType %d", dataType);
-                }
-            }else{
-                ALOGE("invalid dataType in PP_PARAM_VFM_DATA %d", dataType);
-            }
-        }
         break;
         case UPDATE_COLOR_SPACE:
             data->colorSpace = *((ColorSpace_t *)param);
diff --git a/libqdutils/qdMetaData.h b/libqdutils/qdMetaData.h
index 3a0e615..3ebe782 100644
--- a/libqdutils/qdMetaData.h
+++ b/libqdutils/qdMetaData.h
@@ -35,19 +35,6 @@
 #endif
 
 #define MAX_IGC_LUT_ENTRIES 256
-#define MAX_VFM_DATA_SIZE   64 //bytes per data buffer
-#define MAX_VFM_DATA_COUNT  16 //number of data buffers
-
-/* This macro finds the index corresponding to a type */
-/* This is equivalent to indx = LOG_2(type) */
-inline int32_t getVfmDataIdx(int32_t type){
-    int32_t indx = 0, x = type;
-    while( x >> 1) {
-        x = (x >> 1);
-        indx++;
-    }
-    return indx;
-}
 
 enum ColorSpace_t{
     ITU_R_601,
@@ -80,11 +67,6 @@
     int32_t sliceHeight;
 };
 
-struct VfmData_t {
-    int32_t dataType;
-    char    data[MAX_VFM_DATA_SIZE];
-};
-
 struct MetaData_t {
     int32_t operation;
     int32_t interlaced;
@@ -95,8 +77,6 @@
     struct IGCData_t igcData;
     struct Sharp2Data_t Sharp2Data;
     int64_t timestamp;
-    int32_t vfmDataBitMap;
-    struct VfmData_t vfmData[MAX_VFM_DATA_COUNT];
     enum ColorSpace_t colorSpace;
 };
 
@@ -109,7 +89,6 @@
     PP_PARAM_SHARP2     = 0x0020,
     PP_PARAM_TIMESTAMP  = 0x0040,
     UPDATE_BUFFER_GEOMETRY = 0x0080,
-    PP_PARAM_VFM_DATA   = 0x0100,
     UPDATE_COLOR_SPACE = 0x0200,
 };
 
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index 33c3ca0..6c1bba6 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -50,8 +50,6 @@
         SET_HSIC_DATA,           // Set HSIC on dspp
         GET_DISPLAY_VISIBLE_REGION,  // Get the visibleRegion for dpy
         PAUSE_WFD,               // Pause/Resume WFD
-        VPU_COMMAND_LIST_START = 100, //Reserved block for VPU commands
-        VPU_COMMAND_LIST_END   = 200,
         COMMAND_LIST_END = 400,
     };
 
diff --git a/libvirtual/virtual.cpp b/libvirtual/virtual.cpp
index 5453e3a..ca64fad 100644
--- a/libvirtual/virtual.cpp
+++ b/libvirtual/virtual.cpp
@@ -177,13 +177,13 @@
         uint32_t priW = mHwcContext->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
         uint32_t priH = mHwcContext->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
 
-        initResolution(extW, extH);
-
         // Dynamic Resolution Change depends on MDP downscaling.
         // MDP downscale property will be ignored to exercise DRC use case.
         // If DRC is in progress, ext WxH will have non-zero values.
         bool isDRC = (extW > 0) && (extH > 0);
 
+        initResolution(extW, extH);
+
         if(!qdutils::MDPVersion::getInstance().is8x26()
                 && (mHwcContext->mMDPDownscaleEnabled || isDRC)) {