Merge "libcopybit: Merge copybit HAL from jb"
diff --git a/libcopybit/c2d2.h b/libcopybit/c2d2.h
index 8209425..886f38a 100644
--- a/libcopybit/c2d2.h
+++ b/libcopybit/c2d2.h
@@ -232,33 +232,6 @@
     C2D_DRAW_LINE_NOLAST     = (1 << 17), /* disable last pixel draw for line */
 } C2D_SOURCE_CONFIG;
 
-/* Configuration bits, driver capabilities used by 2Dapplications */
-typedef enum {
-    C2D_DRIVER_SUPPORTS_GLOBAL_ALPHA_OP           = (1 << 0),
-    C2D_DRIVER_SUPPORTS_TILE_OP                   = (1 << 1),
-    C2D_DRIVER_SUPPORTS_COLOR_KEY_OP              = (1 << 2),
-    C2D_DRIVER_SUPPORTS_NO_PIXEL_ALPHA_OP         = (1 << 3),
-    C2D_DRIVER_SUPPORTS_TARGET_ROTATE_OP          = (1 << 4),
-    C2D_DRIVER_SUPPORTS_ANTI_ALIASING_OP          = (1 << 5), /* antialiasing */
-    C2D_DRIVER_SUPPORTS_BILINEAR_FILTER_OP        = (1 << 6),   /* antialiasing */
-    C2D_DRIVER_SUPPORTS_LENS_CORRECTION_OP        = (1 << 7),
-    C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP = (1 << 8),
-    C2D_DRIVER_SUPPORTS_SHADER_BLOB_OP            = (1 << 9),
-    C2D_DRIVER_SUPPORTS_MASK_SURFACE_OP           = (1 << 10),  /* mask surface */
-    C2D_DRIVER_SUPPORTS_MIRROR_H_OP               = (1 << 11), /* horizontal flip */
-    C2D_DRIVER_SUPPORTS_MIRROR_V_OP               = (1 << 12), /* vertical flip */
-    C2D_DRIVER_SUPPORTS_SCISSOR_RECT_OP           = (1 << 13),
-    C2D_DRIVER_SUPPORTS_SOURCE_RECT_OP            = (1 << 14),
-    C2D_DRIVER_SUPPORTS_TARGET_RECT_OP            = (1 << 15),
-    C2D_DRIVER_SUPPORTS_ROTATE_OP                 = (1 << 16), /* all rotations */
-    C2D_DRIVER_SUPPORTS_ALL_CAPABILITIES_OP       = ((0xFFFFFFFF) >> (31 - 16)) /* mask for all capabilities supported */
-} C2D_DRIVER_CAPABILITIES;
-
-/* 2D driver workaround bits used by the 2D applications */
-typedef enum {
-    C2D_DRIVER_WORKAROUND_NONE  = 0, /* NO workaround */
-    C2D_DRIVER_WORKAROUND_SWAP_UV_FOR_YUV_TARGET  = (1 << 0), /* Swap UV when this flag set */
-} C2D_DRIVER_WORKAROUND;
 
 /* Target configuration bits, defines rotation + mirroring.
  * Mirror is applied prior to rotation if enabled. */
@@ -334,15 +307,6 @@
                                         /* this bit is valid with HOST types */
 } C2D_SURFACE_TYPE;
 
-/* Structure to query Driver information */
-typedef struct {
-    uint32 capabilities_mask;
-    uint32 workaround_mask;
-    uint32 reserved1;
-    uint32 reserved2;
-    uint32 reserved3;
-} C2D_DRIVER_INFO;
-
 /* Structure for registering a RGB buffer as a blit surface */
 typedef struct {
     uint32 format;   /* RGB color format plus additional mode bits */
@@ -424,6 +388,51 @@
     struct C2D_OBJECT_STR *next; /* pointer to the next object or NULL */
 } C2D_OBJECT;
 
+/* Configuration bits, driver capabilities used by 2Dapplications */
+typedef enum {
+    C2D_DRIVER_SUPPORTS_GLOBAL_ALPHA_OP           = (1 << 0),
+    C2D_DRIVER_SUPPORTS_TILE_OP                   = (1 << 1),
+    C2D_DRIVER_SUPPORTS_COLOR_KEY_OP              = (1 << 2),
+    C2D_DRIVER_SUPPORTS_NO_PIXEL_ALPHA_OP         = (1 << 3),
+    C2D_DRIVER_SUPPORTS_TARGET_ROTATE_OP          = (1 << 4),
+    C2D_DRIVER_SUPPORTS_ANTI_ALIASING_OP          = (1 << 5), /* antialiasing */
+    C2D_DRIVER_SUPPORTS_BILINEAR_FILTER_OP        = (1 << 6),
+    C2D_DRIVER_SUPPORTS_LENS_CORRECTION_OP        = (1 << 7),
+    C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP = (1 << 8),
+    C2D_DRIVER_SUPPORTS_SHADER_BLOB_OP            = (1 << 9),
+    C2D_DRIVER_SUPPORTS_MASK_SURFACE_OP           = (1 << 10), /* mask surface */
+    C2D_DRIVER_SUPPORTS_MIRROR_H_OP               = (1 << 11), /* horizontal flip */
+    C2D_DRIVER_SUPPORTS_MIRROR_V_OP               = (1 << 12), /* vertical flip */
+    C2D_DRIVER_SUPPORTS_SCISSOR_RECT_OP           = (1 << 13),
+    C2D_DRIVER_SUPPORTS_SOURCE_RECT_OP            = (1 << 14),
+    C2D_DRIVER_SUPPORTS_TARGET_RECT_OP            = (1 << 15),
+    C2D_DRIVER_SUPPORTS_ROTATE_OP                 = (1 << 16), /* all rotations */
+    C2D_DRIVER_SUPPORTS_FLUSH_WITH_FENCE_FD_OP    = (1 << 17), /* all rotations */
+    C2D_DRIVER_SUPPORTS_ALL_CAPABILITIES_OP       = ((0xFFFFFFFF) >> (31 - 17)) /* mask for all capabilities supported */
+} C2D_DRIVER_CAPABILITIES;
+
+/* 2D driver workaround bits used by the 2D applications */
+typedef enum {
+    C2D_DRIVER_WORKAROUND_NONE  = 0, /* NO workaround */
+    C2D_DRIVER_WORKAROUND_SWAP_UV_FOR_YUV_TARGET  = (1 << 0), /* Swap UV when this flag set */
+} C2D_DRIVER_WORKAROUND;
+
+/* Structure to query Driver information */
+typedef struct {
+    uint32 capabilities_mask;
+    uint32 workaround_mask;
+    uint32 reserved1;
+    uint32 reserved2;
+    uint32 reserved3;
+} C2D_DRIVER_INFO;
+
+/* Structure to query Driver information */
+typedef struct {
+    uint32          max_surface_template_needed;
+    uint32          reserved1;
+    uint32          reserved2;
+    uint32          reserved3;
+} C2D_DRIVER_SETUP_INFO;
 
 /*****************************************************************************/
 /**************************** C2D API 2.0 ********************************/
@@ -662,6 +671,9 @@
  * driver_info is the information about driver */
 C2D_API C2D_STATUS c2dGetDriverCapabilities( C2D_DRIVER_INFO * driver_info);
 
+/* create a fence fd for the timestamp */
+C2D_API C2D_STATUS c2dCreateFenceFD( uint32 target_id, c2d_ts_handle timestamp, int32 *fd);
+
 /*****************************************************************************/
 
 #ifdef __cplusplus
diff --git a/libcopybit/copybit.h b/libcopybit/copybit.h
index 5adc433..d57b84d 100644
--- a/libcopybit/copybit.h
+++ b/libcopybit/copybit.h
@@ -240,6 +240,16 @@
     */
   int (*finish)(struct copybit_device_t *dev);
 
+  /**
+    * Trigger the copybit draw operation(async).
+    *
+    * @param dev from open
+    *
+    * @param fd - gets the fencefd
+    *
+    * @return 0 if successful
+    */
+  int (*flush_get_fence)(struct copybit_device_t *dev, int* fd);
 };
 
 
diff --git a/libcopybit/copybit_c2d.cpp b/libcopybit/copybit_c2d.cpp
index 6cda9a5..2fa55cd 100644
--- a/libcopybit/copybit_c2d.cpp
+++ b/libcopybit/copybit_c2d.cpp
@@ -17,8 +17,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 #include <cutils/log.h>
+#include <sys/resource.h>
+#include <sys/prctl.h>
 
 #include <stdint.h>
 #include <string.h>
@@ -85,6 +86,10 @@
 C2D_STATUS (*LINK_c2dUnMapAddr) ( void * gpuaddr);
 
 C2D_STATUS (*LINK_c2dGetDriverCapabilities) ( C2D_DRIVER_INFO * driver_info);
+
+/* create a fence fd for the timestamp */
+C2D_STATUS (*LINK_c2dCreateFenceFD) ( uint32 target_id, c2d_ts_handle timestamp,
+                                                            int32 *fd);
 /******************************************************************************/
 
 #if defined(COPYBIT_Z180)
@@ -150,6 +155,15 @@
     int config_mask;
     int dst_surface_type;
     bool is_premultiplied_alpha;
+    void* time_stamp;
+
+    // used for signaling the wait thread
+    bool wait_timestamp;
+    pthread_t wait_thread_id;
+    bool stop_thread;
+    pthread_mutex_t wait_cleanup_lock;
+    pthread_cond_t wait_cleanup_cond;
+
 };
 
 struct bufferInfo {
@@ -193,6 +207,46 @@
 };
 
 
+/* thread function which waits on the timeStamp and cleans up the surfaces */
+static void* c2d_wait_loop(void* ptr) {
+    copybit_context_t* ctx = (copybit_context_t*)(ptr);
+    char thread_name[64] = "copybitWaitThr";
+    prctl(PR_SET_NAME, (unsigned long) &thread_name, 0, 0, 0);
+    setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
+
+    while(ctx->stop_thread == false) {
+        pthread_mutex_lock(&ctx->wait_cleanup_lock);
+        while(ctx->wait_timestamp == false && !ctx->stop_thread) {
+            pthread_cond_wait(&(ctx->wait_cleanup_cond),
+                              &(ctx->wait_cleanup_lock));
+        }
+        if(ctx->wait_timestamp) {
+            if(LINK_c2dWaitTimestamp(ctx->time_stamp)) {
+                ALOGE("%s: LINK_c2dWaitTimeStamp ERROR!!", __FUNCTION__);
+            }
+            ctx->wait_timestamp = false;
+            // Unmap any mapped addresses.
+            for (int i = 0; i < MAX_SURFACES; i++) {
+                if (ctx->mapped_gpu_addr[i]) {
+                    LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[i]);
+                    ctx->mapped_gpu_addr[i] = 0;
+                }
+            }
+            // Reset the counts after the draw.
+            ctx->blit_rgb_count = 0;
+            ctx->blit_yuv_2_plane_count = 0;
+            ctx->blit_yuv_3_plane_count = 0;
+            ctx->blit_count = 0;
+        }
+        pthread_mutex_unlock(&ctx->wait_cleanup_lock);
+        if(ctx->stop_thread)
+            break;
+    }
+    pthread_exit(NULL);
+    return NULL;
+}
+
+
 /* convert COPYBIT_FORMAT to C2D format */
 static int get_format(int format) {
     switch (format) {
@@ -545,18 +599,46 @@
     {
         ctx->blit_list[i].next = &(ctx->blit_list[i+1]);
     }
-
     ctx->blit_list[ctx->blit_count-1].next = NULL;
     if(LINK_c2dDraw(target,ctx->trg_transform, 0x0, 0, 0, ctx->blit_list,
                     ctx->blit_count)) {
         ALOGE("%s: LINK_c2dDraw ERROR", __FUNCTION__);
         return COPYBIT_FAILURE;
     }
-
     return COPYBIT_SUCCESS;
 }
 
 
+
+static int flush_get_fence_copybit (struct copybit_device_t *dev, int* fd)
+{
+    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    int status = COPYBIT_FAILURE;
+    if (!ctx)
+        return COPYBIT_FAILURE;
+    pthread_mutex_lock(&ctx->wait_cleanup_lock);
+    status = msm_copybit(ctx, ctx->dst[ctx->dst_surface_type]);
+
+    if(LINK_c2dFlush(ctx->dst[ctx->dst_surface_type], &ctx->time_stamp)) {
+        ALOGE("%s: LINK_c2dFlush ERROR", __FUNCTION__);
+        // unlock the mutex and return failure
+        pthread_mutex_unlock(&ctx->wait_cleanup_lock);
+        return COPYBIT_FAILURE;
+    }
+    if(LINK_c2dCreateFenceFD(ctx->dst[ctx->dst_surface_type], ctx->time_stamp,
+                                                                        fd)) {
+        ALOGE("%s: LINK_c2dCreateFenceFD ERROR", __FUNCTION__);
+        status = COPYBIT_FAILURE;
+    }
+    if(status == COPYBIT_SUCCESS) {
+        //signal the wait_thread
+        ctx->wait_timestamp = true;
+        pthread_cond_signal(&ctx->wait_cleanup_cond);
+    }
+    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
+    return status;
+}
+
 static int finish_copybit(struct copybit_device_t *dev)
 {
     struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
@@ -647,11 +729,13 @@
     int value)
 {
     struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    int status = COPYBIT_SUCCESS;
     if (!ctx) {
         ALOGE("%s: null context", __FUNCTION__);
         return -EINVAL;
     }
 
+    pthread_mutex_lock(&ctx->wait_cleanup_lock);
     switch(name) {
         case COPYBIT_PLANE_ALPHA:
         {
@@ -729,11 +813,11 @@
             break;
         default:
             ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
-            return -EINVAL;
+            status = -EINVAL;
             break;
     }
-
-    return COPYBIT_SUCCESS;
+    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
+    return status;
 }
 
 /** Get a static info value */
@@ -1211,7 +1295,7 @@
         set_rects(ctx, &(src_surface), dst_rect, src_rect, &clip);
         if (ctx->blit_count == MAX_BLIT_OBJECT_COUNT) {
             ALOGW("Reached end of blit count");
-            finish_copybit(dev);;
+            finish_copybit(dev);
         }
         ctx->blit_list[ctx->blit_count] = src_surface;
         ctx->blit_count++;
@@ -1261,9 +1345,13 @@
     struct copybit_region_t const *region)
 {
     struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    int status = COPYBIT_SUCCESS;
     bool needsBlending = (ctx->src_global_alpha != 0);
-    return stretch_copybit_internal(dev, dst, src, dst_rect, src_rect,
+    pthread_mutex_lock(&ctx->wait_cleanup_lock);
+    status = stretch_copybit_internal(dev, dst, src, dst_rect, src_rect,
                                     region, needsBlending);
+    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
+    return status;
 }
 
 /** Perform a blit type operation */
@@ -1282,9 +1370,21 @@
 
 static void clean_up(copybit_context_t* ctx)
 {
+    void* ret;
     if (!ctx)
         return;
 
+    // stop the wait_cleanup_thread
+    pthread_mutex_lock(&ctx->wait_cleanup_lock);
+    ctx->stop_thread = true;
+    // Signal waiting thread
+    pthread_cond_signal(&ctx->wait_cleanup_cond);
+    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
+    // waits for the cleanup thread to exit
+    pthread_join(ctx->wait_thread_id, &ret);
+    pthread_mutex_destroy(&ctx->wait_cleanup_lock);
+    pthread_cond_destroy (&ctx->wait_cleanup_cond);
+
     for (int i = 0; i < NUM_SURFACE_TYPES; i++) {
         if (ctx->dst[i])
             LINK_c2dDestroySurface(ctx->dst[i]);
@@ -1370,11 +1470,13 @@
                                            "c2dUnMapAddr");
     *(void **)&LINK_c2dGetDriverCapabilities = ::dlsym(ctx->libc2d2,
                                            "c2dGetDriverCapabilities");
+    *(void **)&LINK_c2dCreateFenceFD = ::dlsym(ctx->libc2d2,
+                                           "c2dCreateFenceFD");
 
     if (!LINK_c2dCreateSurface || !LINK_c2dUpdateSurface || !LINK_c2dReadSurface
         || !LINK_c2dDraw || !LINK_c2dFlush || !LINK_c2dWaitTimestamp ||
         !LINK_c2dFinish  || !LINK_c2dDestroySurface ||
-        !LINK_c2dGetDriverCapabilities) {
+        !LINK_c2dGetDriverCapabilities || !LINK_c2dCreateFenceFD) {
         ALOGE("%s: dlsym ERROR", __FUNCTION__);
         clean_up(ctx);
         status = COPYBIT_FAILURE;
@@ -1391,6 +1493,7 @@
     ctx->device.blit = blit_copybit;
     ctx->device.stretch = stretch_copybit;
     ctx->device.finish = finish_copybit;
+    ctx->device.flush_get_fence = flush_get_fence_copybit;
 
     /* Create RGB Surface */
     surfDefinition.buffer = (void*)0xdddddddd;
@@ -1560,6 +1663,19 @@
     ctx->blit_yuv_3_plane_count = 0;
     ctx->blit_count = 0;
 
+    ctx->wait_timestamp = false;
+    ctx->stop_thread = false;
+    pthread_mutex_init(&(ctx->wait_cleanup_lock), NULL);
+    pthread_cond_init(&(ctx->wait_cleanup_cond), NULL);
+    /* Start the wait thread */
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+
+    pthread_create(&ctx->wait_thread_id, &attr, &c2d_wait_loop,
+                                                            (void *)ctx);
+    pthread_attr_destroy(&attr);
+
     *device = &ctx->device.common;
     return status;
 }
diff --git a/libgralloc/Android.mk b/libgralloc/Android.mk
index 159a252..f4e3834 100644
--- a/libgralloc/Android.mk
+++ b/libgralloc/Android.mk
@@ -35,7 +35,7 @@
 LOCAL_MODULE                  := libmemalloc
 LOCAL_MODULE_TAGS             := optional
 LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes)
-LOCAL_SHARED_LIBRARIES        := $(common_libs) libgenlock
+LOCAL_SHARED_LIBRARIES        := $(common_libs) libgenlock libqdutils
 LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdmemalloc\"
 LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
 LOCAL_SRC_FILES               :=  ionalloc.cpp alloc_controller.cpp
diff --git a/libgralloc/framebuffer.cpp b/libgralloc/framebuffer.cpp
index 1193a27..5293ca9 100644
--- a/libgralloc/framebuffer.cpp
+++ b/libgralloc/framebuffer.cpp
@@ -267,9 +267,20 @@
 
     float xdpi = (info.xres * 25.4f) / info.width;
     float ydpi = (info.yres * 25.4f) / info.height;
+#ifdef MSMFB_METADATA_GET
+    struct msmfb_metadata metadata;
+    memset(&metadata, 0 , sizeof(metadata));
+    metadata.op = metadata_op_frame_rate;
+    if (ioctl(fd, MSMFB_METADATA_GET, &metadata) == -1) {
+        ALOGE("Error retrieving panel frame rate");
+        return -errno;
+    }
+    float fps  = 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.
     float fps  = info.reserved[3] & 0xFF;
-
+#endif
     ALOGI("using (fd=%d)\n"
           "id           = %s\n"
           "xres         = %d px\n"
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index 6ccc7e0..dc755cb 100644
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -84,7 +84,8 @@
 enum {
     /* Gralloc perform enums
     */
-    GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER = 0x080000001,
+    GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER =
+                                    GRALLOC_MODULE_PERFORM_PRIVATE_START,
 };
 
 #define GRALLOC_HEAP_MASK   (GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP |\
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index 176a84e..197c372 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -348,6 +348,21 @@
                 break;
 
             }
+        case GRALLOC_MODULE_PERFORM_UPDATE_BUFFER_GEOMETRY:
+            {
+                int width = va_arg(args, int);
+                int height = va_arg(args, int);
+                int format = va_arg(args, int);
+                private_handle_t* hnd =  va_arg(args, private_handle_t*);
+                if (private_handle_t::validate(hnd)) {
+                    return res;
+                }
+                hnd->width = width;
+                hnd->height = height;
+                hnd->format = format;
+                res = 0;
+            }
+            break;
         default:
             break;
     }
diff --git a/libhwcomposer/Android.mk b/libhwcomposer/Android.mk
index 543efd9..a9ada35 100644
--- a/libhwcomposer/Android.mk
+++ b/libhwcomposer/Android.mk
@@ -8,7 +8,7 @@
 LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes)
 LOCAL_SHARED_LIBRARIES        := $(common_libs) libEGL liboverlay libgenlock \
                                  libexternal libqdutils libhardware_legacy \
-                                 libdl libmemalloc libqservice
+                                 libdl libmemalloc libqservice libsync
 LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdhwcomposer\"
 LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
 LOCAL_SRC_FILES               := hwc.cpp          \
@@ -17,6 +17,7 @@
                                  hwc_uevents.cpp  \
                                  hwc_vsync.cpp    \
                                  hwc_fbupdate.cpp \
-                                 hwc_mdpcomp.cpp
+                                 hwc_mdpcomp.cpp  \
+                                 hwc_copybit.cpp
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index ac1be19..ba84580 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -2,6 +2,9 @@
  * Copyright (C) 2010 The Android Open Source Project
  * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
  *
+ * Not a Contribution, Apache license notifications and license are retained
+ * for attribution purposes only.
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
@@ -30,6 +33,7 @@
 #include "hwc_fbupdate.h"
 #include "hwc_mdpcomp.h"
 #include "external.h"
+#include "hwc_copybit.h"
 
 using namespace qhwc;
 #define VSYNC_DEBUG 0
@@ -96,6 +100,9 @@
 
         if(ctx->mFBUpdate[i])
             ctx->mFBUpdate[i]->reset();
+
+        if(ctx->mCopyBit[i])
+            ctx->mCopyBit[i]->reset();
     }
     VideoOverlay::reset();
 }
@@ -127,11 +134,16 @@
         if(fbLayer->handle) {
             setListStats(ctx, list, dpy);
             reset_layer_prop(ctx, dpy);
-            if(!ctx->mMDPComp->prepare(ctx, list)) {
+            int ret = ctx->mMDPComp->prepare(ctx, list);
+            if(!ret) {
+                // IF MDPcomp fails use this route
                 VideoOverlay::prepare(ctx, list, dpy);
                 ctx->mFBUpdate[dpy]->prepare(ctx, fbLayer);
             }
             ctx->mLayerCache[dpy]->updateLayerCache(list);
+            // Use Copybit, when MDP comp fails
+            if(!ret && ctx->mCopyBit[dpy])
+                ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
         }
     }
     return 0;
@@ -154,6 +166,8 @@
             VideoOverlay::prepare(ctx, list, dpy);
             ctx->mFBUpdate[dpy]->prepare(ctx, fbLayer);
             ctx->mLayerCache[dpy]->updateLayerCache(list);
+            if(ctx->mCopyBit[dpy])
+                ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
             ctx->mExtDispConfiguring = false;
         }
     }
@@ -296,8 +310,10 @@
         ctx->dpyAttr[dpy].isActive) {
         uint32_t last = list->numHwLayers - 1;
         hwc_layer_1_t *fbLayer = &list->hwLayers[last];
-
-        hwc_sync(ctx, list, dpy);
+        int fd = -1; //FenceFD from the Copybit(valid in async mode)
+        if(ctx->mCopyBit[dpy])
+            ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
+        hwc_sync(ctx, list, dpy, fd);
         if (!VideoOverlay::draw(ctx, list, dpy)) {
             ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
             ret = -1;
@@ -338,8 +354,11 @@
         ctx->dpyAttr[dpy].connected) {
         uint32_t last = list->numHwLayers - 1;
         hwc_layer_1_t *fbLayer = &list->hwLayers[last];
+        int fd = -1; //FenceFD from the Copybit(valid in async mode)
+        if(ctx->mCopyBit[dpy])
+            ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
 
-        hwc_sync(ctx, list, dpy);
+        hwc_sync(ctx, list, dpy, fd);
 
         if (!VideoOverlay::draw(ctx, list, dpy)) {
             ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
@@ -369,7 +388,6 @@
     int ret = 0;
     hwc_context_t* ctx = (hwc_context_t*)(dev);
     Locker::Autolock _l(ctx->mBlankLock);
-
     for (uint32_t i = 0; i < numDisplays; i++) {
         hwc_display_contents_1_t* list = displays[i];
         switch(i) {
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 1249e84..e764c69 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * Not a Contribution, Apache license notifications and license are retained
  * for attribution purposes only.
@@ -20,14 +20,12 @@
 
 #define DEBUG_COPYBIT 0
 #include <copybit.h>
-#include <genlock.h>
-#include "hwc_copybit.h"
+#include <utils/Timers.h>
 #include "hwc_copybit.h"
 #include "comptype.h"
 
 namespace qhwc {
 
-
 struct range {
     int current;
     int end;
@@ -65,44 +63,9 @@
     mutable range r;
 };
 
-// Initialize CopyBit Class Static Mmembers.
-functype_eglGetRenderBufferANDROID CopyBit::LINK_eglGetRenderBufferANDROID
-                                                                   = NULL;
-functype_eglGetCurrentSurface CopyBit::LINK_eglGetCurrentSurface = NULL;
-int CopyBit::sYuvCount = 0;
-int CopyBit::sYuvLayerIndex = -1;
-bool CopyBit::sIsModeOn = false;
-bool CopyBit::sIsLayerSkip = false;
-void* CopyBit::egl_lib = NULL;
-
-void CopyBit::openEglLibAndGethandle()
-{
-    egl_lib = ::dlopen("libEGL_adreno200.so", RTLD_GLOBAL | RTLD_LAZY);
-    if (!egl_lib) {
-        return;
-    }
-    updateEglHandles(egl_lib);
-}
-void CopyBit::closeEglLib()
-{
-    if(egl_lib)
-        ::dlclose(egl_lib);
-
-    egl_lib = NULL;
-    updateEglHandles(NULL);
-}
-
-void CopyBit::updateEglHandles(void* egl_lib)
-{
-    if(egl_lib != NULL) {
-        *(void **)&CopyBit::LINK_eglGetRenderBufferANDROID =
-                             ::dlsym(egl_lib, "eglGetRenderBufferANDROID");
-        *(void **)&CopyBit::LINK_eglGetCurrentSurface =
-                                  ::dlsym(egl_lib, "eglGetCurrentSurface");
-   }else {
-        LINK_eglGetCurrentSurface = NULL;
-        LINK_eglGetCurrentSurface = NULL;
-   }
+void CopyBit::reset() {
+    mIsModeOn = false;
+    mCopyBitDraw = false;
 }
 
 bool CopyBit::canUseCopybitForYUV(hwc_context_t *ctx) {
@@ -113,15 +76,16 @@
     return true;
 }
 
-bool CopyBit::canUseCopybitForRGB(hwc_context_t *ctx, hwc_display_contents_1_t *list) {
-    int compositionType =
-        qdutils::QCCompositionType::getInstance().getCompositionType();
+bool CopyBit::canUseCopybitForRGB(hwc_context_t *ctx,
+                                        hwc_display_contents_1_t *list,
+                                        int dpy) {
+    int compositionType = qdutils::QCCompositionType::
+                                    getInstance().getCompositionType();
 
     if ((compositionType & qdutils::COMPOSITION_TYPE_C2D) ||
         (compositionType & qdutils::COMPOSITION_TYPE_DYN)) {
-         if (sYuvCount) {
+         if(ctx->listStats[dpy].yuvCount) {
              //Overlay up & running. Dont use COPYBIT for RGB layers.
-             // TODO need to implement blending with C2D
              return false;
          }
     }
@@ -131,17 +95,13 @@
         // use copybit, if (TotalRGBRenderArea < 2 * FB Area)
         // this is done based on perf inputs in ICS
         // TODO: Above condition needs to be re-evaluated in JB
-
-        framebuffer_device_t *fbDev = ctx->mFbDev;
-        if (!fbDev) {
-            ALOGE("%s:Invalid FB device", __FUNCTION__);
-            return false;
-        }
-        unsigned int fbArea = (fbDev->width * fbDev->height);
+        int fbWidth =  ctx->dpyAttr[dpy].xres;
+        int fbHeight =  ctx->dpyAttr[dpy].yres;
+        unsigned int fbArea = (fbWidth * fbHeight);
         unsigned int renderArea = getRGBRenderingArea(list);
             ALOGD_IF (DEBUG_COPYBIT, "%s:renderArea %u, fbArea %u",
                                   __FUNCTION__, renderArea, fbArea);
-        if (renderArea < (2 * fbArea)) {
+        if (renderArea <= (2 * fbArea)) {
             return true;
         }
     } else if ((compositionType & qdutils::COMPOSITION_TYPE_MDP)) {
@@ -154,7 +114,8 @@
     return false;
 }
 
-unsigned int CopyBit::getRGBRenderingArea(const hwc_display_contents_1_t *list) {
+unsigned int CopyBit::getRGBRenderingArea
+                                    (const hwc_display_contents_1_t *list) {
     //Calculates total rendering area for RGB layers
     unsigned int renderArea = 0;
     unsigned int w=0, h=0;
@@ -170,71 +131,116 @@
     return renderArea;
 }
 
-bool CopyBit::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list) {
+bool CopyBit::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list,
+                                                            int dpy) {
 
-    int compositionType =
-        qdutils::QCCompositionType::getInstance().getCompositionType();
+    if(mEngine == NULL) {
+        // No copybit device found - cannot use copybit
+        return false;
+    }
+    int compositionType = qdutils::QCCompositionType::
+                                    getInstance().getCompositionType();
 
-    if ((compositionType & qdutils::COMPOSITION_TYPE_GPU) ||
-        (compositionType & qdutils::COMPOSITION_TYPE_CPU))   {
+    if ((compositionType == qdutils::COMPOSITION_TYPE_GPU) ||
+        (compositionType == qdutils::COMPOSITION_TYPE_CPU))   {
         //GPU/CPU composition, don't change layer composition type
         return true;
     }
 
-    bool useCopybitForYUV = canUseCopybitForYUV(ctx);
-    bool useCopybitForRGB = canUseCopybitForRGB(ctx, list);
-
     if(!(validateParams(ctx, list))) {
-       ALOGE("%s:Invalid Params", __FUNCTION__);
-       return false;
+        ALOGE("%s:Invalid Params", __FUNCTION__);
+        return false;
     }
 
-    for (int i=list->numHwLayers-1; i >= 0 ; i--) {
+    if(ctx->listStats[dpy].skipCount) {
+        //GPU will be anyways used
+        return false;
+    }
+
+    bool useCopybitForYUV = canUseCopybitForYUV(ctx);
+    bool useCopybitForRGB = canUseCopybitForRGB(ctx, list, dpy);
+
+    // numAppLayers-1, as we iterate till 0th layer index
+    for (int i = ctx->listStats[dpy].numAppLayers-1; i >= 0 ; i--) {
         private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
 
-        if (isSkipLayer(&list->hwLayers[i])) {
-            return true;
-        } else if (hnd->bufferType == BUFFER_TYPE_VIDEO) {
-          //YUV layer, check, if copybit can be used
-          if (useCopybitForYUV) {
-              list->hwLayers[i].compositionType = HWC_USE_COPYBIT;
-          }
-       } else if (hnd->bufferType == BUFFER_TYPE_UI) {
-          //RGB layer, check, if copybit can be used
-          if (useCopybitForRGB) {
-              list->hwLayers[i].compositionType = HWC_USE_COPYBIT;
-          }
-       }
-    }
-    return true;
-}
-
-bool CopyBit::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list, EGLDisplay dpy,
-                                                               EGLSurface sur){
-    // draw layers marked for COPYBIT
-    int retVal = true;
-    for (size_t i=0; i<list->numHwLayers; i++) {
-        if (list->hwLayers[i].compositionType == HWC_USE_COPYBIT) {
-            retVal = drawLayerUsingCopybit(ctx, &(list->hwLayers[i]),
-                                                     (EGLDisplay)dpy,
-                                                     (EGLSurface)sur,
-                                      LINK_eglGetRenderBufferANDROID,
-                                          LINK_eglGetCurrentSurface);
-           if(retVal<0) {
-              ALOGE("%s : drawLayerUsingCopybit failed", __FUNCTION__);
-           }
+        if (hnd->bufferType == BUFFER_TYPE_VIDEO) {
+            //YUV layer, check, if copybit can be used
+            // mark the video layer to gpu when all layer is
+            // going to gpu in case of dynamic composition.
+            if (useCopybitForYUV) {
+                list->hwLayers[i].compositionType = HWC_BLIT;
+                mCopyBitDraw = true;
+            }
+        } else if (hnd->bufferType == BUFFER_TYPE_UI) {
+            //RGB layer, check, if copybit can be used
+            if (useCopybitForRGB) {
+                ALOGD_IF(DEBUG_COPYBIT, "%s: Marking layer[%d] for copybit for"
+                                "dpy[%d] ", __FUNCTION__, i, dpy);
+                list->hwLayers[i].compositionType = HWC_BLIT;
+                mCopyBitDraw = true;
+            }
         }
     }
     return true;
 }
 
+bool CopyBit::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list,
+                                                        int dpy, int32_t *fd) {
+    // draw layers marked for COPYBIT
+    int retVal = true;
+    int copybitLayerCount = 0;
+
+    if(mCopyBitDraw == false) // there is no layer marked for copybit
+        return true ;
+
+    size_t fbLayerIndex = ctx->listStats[dpy].fbLayerIndex;
+    hwc_layer_1_t *fbLayer = &list->hwLayers[fbLayerIndex];
+    //render buffer
+    private_handle_t *renderBuffer = (private_handle_t *)fbLayer->handle;
+    if (!renderBuffer) {
+        ALOGE("%s: HWC_FRAMEBUFFER_TARGET layer handle is NULL", __FUNCTION__);
+        return false;
+    }
+    // numAppLayers-1, as we iterate from 0th layer index with HWC_BLIT flag
+    for (int i = 0; i <= (ctx->listStats[dpy].numAppLayers-1); i++) {
+        hwc_layer_1_t *layer = &list->hwLayers[i];
+        if(!list->hwLayers[i].compositionType == HWC_BLIT) {
+            ALOGD_IF(DEBUG_COPYBIT, "%s: Not Marked for C2D", __FUNCTION__);
+            continue;
+        }
+        int ret = -1;
+        if (list->hwLayers[i].acquireFenceFd != -1 ) {
+            // Wait for acquire Fence on the App buffers.
+            ret = sync_wait(list->hwLayers[i].acquireFenceFd, 1000);
+            if(ret < 0) {
+                ALOGE("%s: sync_wait error!! error no = %d err str = %s",
+                                    __FUNCTION__, errno, strerror(errno));
+            }
+            close(list->hwLayers[i].acquireFenceFd);
+            list->hwLayers[i].acquireFenceFd = -1;
+        }
+        retVal = drawLayerUsingCopybit(ctx, &(list->hwLayers[i]),
+                                                    renderBuffer, dpy);
+        copybitLayerCount++;
+        if(retVal < 0) {
+            ALOGE("%s : drawLayerUsingCopybit failed", __FUNCTION__);
+        }
+    }
+
+    if (copybitLayerCount) {
+        copybit_device_t *copybit = getCopyBitDevice();
+        // Async mode
+        copybit->flush_get_fence(copybit, fd);
+    }
+    return true;
+}
+
 int  CopyBit::drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
-                                                            EGLDisplay dpy,
-                                                        EGLSurface surface,
-        functype_eglGetRenderBufferANDROID& LINK_eglGetRenderBufferANDROID,
-                    functype_eglGetCurrentSurface LINK_eglGetCurrentSurface)
+                                     private_handle_t *renderBuffer, int dpy)
 {
     hwc_context_t* ctx = (hwc_context_t*)(dev);
+    int err = 0;
     if(!ctx) {
          ALOGE("%s: null context ", __FUNCTION__);
          return -1;
@@ -246,26 +252,9 @@
         return -1;
     }
 
-    // Lock this buffer for read.
-    genlock_lock_type lockType = GENLOCK_READ_LOCK;
-    int err = genlock_lock_buffer(hnd, lockType, GENLOCK_MAX_TIMEOUT);
-    if (GENLOCK_FAILURE == err) {
-        ALOGE("%s: genlock_lock_buffer(READ) failed", __FUNCTION__);
-        return -1;
-    }
-    //render buffer
-    EGLSurface eglSurface = LINK_eglGetCurrentSurface(EGL_DRAW);
-    android_native_buffer_t *renderBuffer =
-     (android_native_buffer_t *)LINK_eglGetRenderBufferANDROID(dpy, eglSurface);
-    if (!renderBuffer) {
-        ALOGE("%s: eglGetRenderBuffer returned NULL buffer", __FUNCTION__);
-        genlock_unlock_buffer(hnd);
-        return -1;
-    }
-    private_handle_t *fbHandle = (private_handle_t *)renderBuffer->handle;
+    private_handle_t *fbHandle = (private_handle_t *)renderBuffer;
     if(!fbHandle) {
         ALOGE("%s: Framebuffer handle is NULL", __FUNCTION__);
-        genlock_unlock_buffer(hnd);
         return -1;
     }
 
@@ -281,8 +270,6 @@
     // this needs to change to accomodate vertical stride
     // if needed in the future
     src.vert_padding = 0;
-    // Remove the srcBufferTransform if any
-    layer->transform = (layer->transform & FINAL_TRANSFORM_MASK);
 
     // Copybit source rect
     hwc_rect_t sourceCrop = layer->sourceCrop;
@@ -302,9 +289,9 @@
     dst.h = fbHandle->height;
     dst.format = fbHandle->format;
     dst.base = (void *)fbHandle->base;
-    dst.handle = (native_handle_t *)renderBuffer->handle;
+    dst.handle = (native_handle_t *)fbHandle;
 
-    copybit_device_t *copybit = ctx->mCopybitEngine->getEngine();
+    copybit_device_t *copybit = mEngine;
 
     int32_t screen_w        = displayFrame.right - displayFrame.left;
     int32_t screen_h        = displayFrame.bottom - displayFrame.top;
@@ -330,7 +317,6 @@
         ALOGE("%s: wrong params for display screen_w=%d src_crop_width=%d \
         screen_w=%d src_crop_width=%d", __FUNCTION__, screen_w,
                                 src_crop_width,screen_w,src_crop_width);
-        genlock_unlock_buffer(hnd);
         return -1;
     }
 
@@ -346,7 +332,6 @@
         ALOGE("%s: greater than max supported size dsdx=%f dtdy=%f \
               scaleLimitMax=%f scaleLimitMin=%f", __FUNCTION__,dsdx,dtdy,
                                           scaleLimitMax,1/scaleLimitMin);
-        genlock_unlock_buffer(hnd);
         return -1;
     }
     if(dsdx > copybitsMaxScale ||
@@ -411,7 +396,6 @@
                                                              __LINE__);
                 if(tmpHnd)
                     free_buffer(tmpHnd);
-                genlock_unlock_buffer(hnd);
                 return err;
             }
             // copy new src and src rect crop
@@ -431,9 +415,8 @@
                                               layer->transform);
     //TODO: once, we are able to read layer alpha, update this
     copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 255);
-    copybit->set_parameter(copybit, COPYBIT_PREMULTIPLIED_ALPHA,
-                      (layer->blending == HWC_BLENDING_PREMULT)?
-                                             COPYBIT_ENABLE : COPYBIT_DISABLE);
+    copybit->set_parameter(copybit, COPYBIT_BLEND_MODE,
+                                              layer->blending);
     copybit->set_parameter(copybit, COPYBIT_DITHER,
                              (dst.format == HAL_PIXEL_FORMAT_RGB_565)?
                                              COPYBIT_ENABLE : COPYBIT_DISABLE);
@@ -449,13 +432,6 @@
 
     if(err < 0)
         ALOGE("%s: copybit stretch failed",__FUNCTION__);
-
-    // Unlock this buffer since copybit is done with it.
-    err = genlock_unlock_buffer(hnd);
-    if (GENLOCK_FAILURE == err) {
-        ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
-    }
-
     return err;
 }
 
@@ -468,62 +444,41 @@
     height = displayFrame.bottom - displayFrame.top;
 }
 
-bool CopyBit::validateParams(hwc_context_t *ctx, const hwc_display_contents_1_t *list) {
-   //Validate parameters
-   if (!ctx) {
-       ALOGE("%s:Invalid HWC context", __FUNCTION__);
-       return false;
-   } else if (!list) {
-       ALOGE("%s:Invalid HWC layer list", __FUNCTION__);
-       return false;
-   }
-
-   framebuffer_device_t *fbDev = ctx->mFbDev;
-
-   if (!fbDev) {
-       ALOGE("%s:Invalid FB device", __FUNCTION__);
-       return false;
-   }
-
-   if (LINK_eglGetRenderBufferANDROID == NULL ||
-            LINK_eglGetCurrentSurface == NULL) {
-       ALOGE("%s:Not able to link to ADRENO", __FUNCTION__);
-       return false;
-   }
-
-   return true;
+bool CopyBit::validateParams(hwc_context_t *ctx,
+                                        const hwc_display_contents_1_t *list) {
+    //Validate parameters
+    if (!ctx) {
+        ALOGE("%s:Invalid HWC context", __FUNCTION__);
+        return false;
+    } else if (!list) {
+        ALOGE("%s:Invalid HWC layer list", __FUNCTION__);
+        return false;
+    }
+    return true;
 }
 
-//CopybitEngine Class functions
-CopybitEngine* CopybitEngine::sInstance = 0;
 
-struct copybit_device_t* CopybitEngine::getEngine() {
-   return sEngine;
-}
-CopybitEngine* CopybitEngine::getInstance() {
-   if(sInstance == NULL)
-       sInstance = new CopybitEngine();
-   return sInstance;
+struct copybit_device_t* CopyBit::getCopyBitDevice() {
+    return mEngine;
 }
 
-CopybitEngine::CopybitEngine(){
+CopyBit::CopyBit():mIsModeOn(false), mCopyBitDraw(false){
     hw_module_t const *module;
     if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
-        copybit_open(module, &sEngine);
-        CopyBit::openEglLibAndGethandle();
+        if(copybit_open(module, &mEngine) < 0) {
+            ALOGE("FATAL ERROR: copybit open failed.");
+        }
     } else {
-       ALOGE("FATAL ERROR: copybit open failed.");
+        ALOGE("FATAL ERROR: copybit hw module not found");
     }
 }
 
-CopybitEngine::~CopybitEngine()
+CopyBit::~CopyBit()
 {
-    if(sEngine)
+    if(mEngine)
     {
-        CopyBit::closeEglLib();
-        copybit_close(sEngine);
-        sEngine = NULL;
+        copybit_close(mEngine);
+        mEngine = NULL;
     }
 }
-
 }; //namespace qhwc
diff --git a/libhwcomposer/hwc_copybit.h b/libhwcomposer/hwc_copybit.h
index ae82b6c..015d85a 100644
--- a/libhwcomposer/hwc_copybit.h
+++ b/libhwcomposer/hwc_copybit.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * Not a Contribution, Apache license notifications and license are retained
  * for attribution purposes only.
@@ -20,94 +20,49 @@
 #ifndef HWC_COPYBIT_H
 #define HWC_COPYBIT_H
 #include "hwc_utils.h"
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <gralloc_priv.h>
-#include <gr.h>
-#include <dlfcn.h>
 
 #define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
 #define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
 
 namespace qhwc {
-//Feature for using Copybit to display RGB layers.
-typedef EGLClientBuffer (*functype_eglGetRenderBufferANDROID) (
-                                              EGLDisplay dpy,
-                                              EGLSurface draw);
-typedef EGLSurface (*functype_eglGetCurrentSurface)(EGLint readdraw);
 
 class CopyBit {
 public:
+    CopyBit();
+    ~CopyBit();
+    // API to get copybit engine(non static)
+    struct copybit_device_t *getCopyBitDevice();
     //Sets up members and prepares copybit if conditions are met
-    static bool prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list);
+    bool prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list,
+                                                                   int dpy);
     //Draws layer if the layer is set for copybit in prepare
-    static bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list, EGLDisplay dpy,
-                                                                EGLSurface sur);
-    //Receives data from hwc
-    static void setStats(int yuvCount, int yuvLayerIndex, bool isYuvLayerSkip);
-
-    static void updateEglHandles(void*);
-    static int  drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
-                                        EGLDisplay dpy, EGLSurface surface,
-        functype_eglGetRenderBufferANDROID& LINK_eglGetRenderBufferANDROID,
-                  functype_eglGetCurrentSurface LINK_eglGetCurrentSurface);
-    static bool canUseCopybitForYUV (hwc_context_t *ctx);
-    static bool canUseCopybitForRGB (hwc_context_t *ctx,
-                                     hwc_display_contents_1_t *list);
-    static bool validateParams (hwc_context_t *ctx,
-                                const hwc_display_contents_1_t *list);
-    static void closeEglLib();
-    static void openEglLibAndGethandle();
+    bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list,
+                                                        int dpy, int* fd);
+    // resets the values
+    void reset();
 private:
-    //Marks layer flags if this feature is used
-    static void markFlags(hwc_layer_1_t *layer);
-    //returns yuv count
-    static int getYuvCount();
-
-    //Number of yuv layers in this drawing round
-    static int sYuvCount;
-    //Index of YUV layer, relevant only if count is 1
-    static int sYuvLayerIndex;
-    //Flags if a yuv layer is animating or below something that is animating
-    static bool sIsLayerSkip;
+    // holds the copybit device
+    struct copybit_device_t *mEngine;
+    // Helper functions for copybit composition
+    int  drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
+                                       private_handle_t *renderBuffer, int dpy);
+    bool canUseCopybitForYUV (hwc_context_t *ctx);
+    bool canUseCopybitForRGB (hwc_context_t *ctx,
+                                     hwc_display_contents_1_t *list, int dpy);
+    bool validateParams (hwc_context_t *ctx,
+                                const hwc_display_contents_1_t *list);
     //Flags if this feature is on.
-    static bool sIsModeOn;
-    //handle for adreno lib
-    static void* egl_lib;
+    bool mIsModeOn;
+    // flag that indicates whether CopyBit composition is enabled for this cycle
+    bool mCopyBitDraw;
 
-    static functype_eglGetRenderBufferANDROID LINK_eglGetRenderBufferANDROID;
-    static functype_eglGetCurrentSurface LINK_eglGetCurrentSurface;
+    unsigned int getRGBRenderingArea
+                            (const hwc_display_contents_1_t *list);
 
-    static  unsigned int getRGBRenderingArea (const hwc_display_contents_1_t *list);
-
-    static void getLayerResolution(const hwc_layer_1_t* layer,
+    void getLayerResolution(const hwc_layer_1_t* layer,
                                    unsigned int &width, unsigned int& height);
 };
 
-class CopybitEngine {
-public:
-    ~CopybitEngine();
-    // API to get copybit engine(non static)
-    struct copybit_device_t *getEngine();
-    // API to get singleton
-    static CopybitEngine* getInstance();
-private:
-    CopybitEngine();
-    struct copybit_device_t *sEngine;
-    static CopybitEngine* sInstance; // singleton
-};
-
-
-inline void CopyBit::setStats(int yuvCount, int yuvLayerIndex,
-        bool isYuvLayerSkip) {
-    sYuvCount = yuvCount;
-    sYuvLayerIndex = yuvLayerIndex;
-    sIsLayerSkip = isYuvLayerSkip;
-}
-
-inline int CopyBit::getYuvCount() { return sYuvCount; }
-
-
 }; //namespace qhwc
 
 #endif //HWC_COPYBIT_H
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 2c0a77a..2e58b93 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -215,7 +215,8 @@
     if(isSecureBuffer(hnd)) {
         ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
     }
-    if((metadata->operation & PP_PARAM_INTERLACED) && metadata->interlaced) {
+    if(metadata && (metadata->operation & PP_PARAM_INTERLACED) &&
+                                              metadata->interlaced) {
         ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_DEINTERLACE);
     }
 }
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index 334df26..6b8f4e3 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -27,6 +27,8 @@
 #include <stdlib.h>
 #include "hwc_utils.h"
 #include "hwc_fbupdate.h"
+#include "hwc_copybit.h"
+#include "comptype.h"
 #include "external.h"
 
 namespace qhwc {
@@ -38,6 +40,16 @@
     int vsync = 0;
     int64_t timestamp = 0;
     const char *str = udata;
+    bool usecopybit = false;
+    int compositionType =
+        qdutils::QCCompositionType::getInstance().getCompositionType();
+
+    if (compositionType & (qdutils::COMPOSITION_TYPE_DYN |
+                           qdutils::COMPOSITION_TYPE_MDP |
+                           qdutils::COMPOSITION_TYPE_C2D)) {
+        usecopybit = true;
+
+    }
 
     if(!strcasestr("change@/devices/virtual/switch/hdmi", str) &&
        !strcasestr("change@/devices/virtual/switch/wfd", str)) {
@@ -72,6 +84,8 @@
             ctx->mFBUpdate[HWC_DISPLAY_EXTERNAL] =
                 IFBUpdate::getObject(ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].xres,
                 HWC_DISPLAY_EXTERNAL);
+            if(usecopybit)
+                ctx->mCopyBit[HWC_DISPLAY_EXTERNAL] = new CopyBit();
         } else {
             ctx->mExtDisplay->processUEventOffline(udata);
             if(ctx->mFBUpdate[HWC_DISPLAY_EXTERNAL]) {
@@ -79,6 +93,11 @@
                 delete ctx->mFBUpdate[HWC_DISPLAY_EXTERNAL];
                 ctx->mFBUpdate[HWC_DISPLAY_EXTERNAL] = NULL;
             }
+            if(ctx->mCopyBit[HWC_DISPLAY_EXTERNAL]){
+                Locker::Autolock _l(ctx->mExtSetLock);
+                delete ctx->mCopyBit[HWC_DISPLAY_EXTERNAL];
+                ctx->mCopyBit[HWC_DISPLAY_EXTERNAL] = NULL;
+            }
         }
         ALOGD("%s sending hotplug: connected = %d", __FUNCTION__, connected);
         Locker::Autolock _l(ctx->mExtSetLock); //hwc comp could be on
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 76635d5..9cc5c24 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -1,6 +1,9 @@
 /*
  * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012, The Linux Foundation All rights reserved.
+ * Copyright (C) 2012-2013, The Linux Foundation All rights reserved.
+ *
+ * Not a Contribution, Apache license notifications and license are retained
+ * for attribution purposes only.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +17,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
+#define HWC_UTILS_DEBUG 0
 #include <sys/ioctl.h>
 #include <EGL/egl.h>
 #include <cutils/properties.h>
@@ -25,9 +28,10 @@
 #include "hwc_mdpcomp.h"
 #include "hwc_fbupdate.h"
 #include "mdp_version.h"
+#include "hwc_copybit.h"
 #include "external.h"
 #include "QService.h"
-
+#include "comptype.h"
 namespace qhwc {
 
 // Opens Framebuffer device
@@ -66,6 +70,19 @@
     ctx->mFBUpdate[HWC_DISPLAY_PRIMARY] =
         IFBUpdate::getObject(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres,
         HWC_DISPLAY_PRIMARY);
+
+    char value[PROPERTY_VALUE_MAX];
+    // Check if the target supports copybit compostion (dyn/mdp/c2d) to
+    // decide if we need to open the copybit module.
+    int compositionType =
+        qdutils::QCCompositionType::getInstance().getCompositionType();
+
+    if (compositionType & (qdutils::COMPOSITION_TYPE_DYN |
+                           qdutils::COMPOSITION_TYPE_MDP |
+                           qdutils::COMPOSITION_TYPE_C2D)) {
+            ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit();
+    }
+
     ctx->mExtDisplay = new ExternalDisplay(ctx);
     for (uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++)
         ctx->mLayerCache[i] = new LayerCache();
@@ -87,6 +104,13 @@
         ctx->mOverlay = NULL;
     }
 
+    for(int i = 0; i< HWC_NUM_DISPLAY_TYPES; i++) {
+        if(ctx->mCopyBit[i]) {
+            delete ctx->mCopyBit[i];
+            ctx->mCopyBit[i] = NULL;
+        }
+    }
+
     if(ctx->mFbDev) {
         framebuffer_close(ctx->mFbDev);
         ctx->mFbDev = NULL;
@@ -251,13 +275,15 @@
     return ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive;
 }
 
-int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy) {
+int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy,
+                                                        int fd) {
     int ret = 0;
     struct mdp_buf_sync data;
     int acquireFd[MAX_NUM_LAYERS];
     int count = 0;
     int releaseFd = -1;
     int fbFd = -1;
+    memset(&data, 0, sizeof(data));
     bool swapzero = false;
     data.flags = MDP_BUF_SYNC_FLAG_WAIT;
     data.acq_fen_fd = acquireFd;
@@ -270,35 +296,52 @@
 
     //Accumulate acquireFenceFds
     for(uint32_t i = 0; i < list->numHwLayers; i++) {
-        if((list->hwLayers[i].compositionType == HWC_OVERLAY ||
-            list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) &&
-            list->hwLayers[i].acquireFenceFd != -1 ){
+        if(list->hwLayers[i].compositionType == HWC_OVERLAY &&
+                        list->hwLayers[i].acquireFenceFd != -1) {
             if(UNLIKELY(swapzero))
                 acquireFd[count++] = -1;
             else
                 acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
         }
+        if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
+            if(UNLIKELY(swapzero))
+                acquireFd[count++] = -1;
+            else if(fd != -1) {
+                //set the acquireFD from fd - which is coming from c2d
+                acquireFd[count++] = fd;
+                // Buffer sync IOCTL should be async when using c2d fence is
+                // used
+                data.flags &= ~MDP_BUF_SYNC_FLAG_WAIT;
+            } else if(list->hwLayers[i].acquireFenceFd != -1)
+                acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
+        }
     }
 
     data.acq_fen_fd_cnt = count;
     fbFd = ctx->dpyAttr[dpy].fd;
-
     //Waits for acquire fences, returns a release fence
-    if(LIKELY(!swapzero))
+    if(LIKELY(!swapzero)) {
+        uint64_t start = systemTime();
         ret = ioctl(fbFd, MSMFB_BUFFER_SYNC, &data);
+        ALOGD_IF(HWC_UTILS_DEBUG, "%s: time taken for MSMFB_BUFFER_SYNC IOCTL = %d",
+                            __FUNCTION__, (size_t) ns2ms(systemTime() - start));
+    }
     if(ret < 0) {
         ALOGE("ioctl MSMFB_BUFFER_SYNC failed, err=%s",
                 strerror(errno));
     }
-
     for(uint32_t i = 0; i < list->numHwLayers; i++) {
-        if((list->hwLayers[i].compositionType == HWC_OVERLAY ||
-            list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET)) {
+        if(list->hwLayers[i].compositionType == HWC_OVERLAY ||
+           list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
             //Close the acquireFenceFds
             if(list->hwLayers[i].acquireFenceFd > 0) {
                 close(list->hwLayers[i].acquireFenceFd);
                 list->hwLayers[i].acquireFenceFd = -1;
             }
+            if(fd > 0) {
+                close(fd);
+                fd = -1;
+            }
             //Populate releaseFenceFds.
             if(UNLIKELY(swapzero))
                 list->hwLayers[i].releaseFenceFd = -1;
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 9541404..0005582 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -1,6 +1,9 @@
 /*
  * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * Not a Contribution, Apache license notifications and license are retained
+ * for attribution purposes only.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -51,6 +54,7 @@
 class ExternalDisplay;
 class IFBUpdate;
 class MDPComp;
+class CopyBit;
 
 struct MDPInfo {
     int version;
@@ -82,7 +86,6 @@
     bool needsAlphaScale;
 };
 
-
 struct LayerProp {
     uint32_t mFlags; //qcom specific layer flags
     LayerProp():mFlags(0) {};
@@ -133,7 +136,8 @@
 void dumpsys_log(android::String8& buf, const char* fmt, ...);
 
 //Sync point impl.
-int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy);
+int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy,
+                                                    int fd);
 
 // Inline utility functions
 static inline bool isSkipLayer(const hwc_layer_1_t* l) {
@@ -214,6 +218,10 @@
     const hwc_procs_t* proc;
     //Framebuffer device
     framebuffer_device_t *mFbDev;
+
+    //CopyBit objects
+    qhwc::CopyBit *mCopyBit[HWC_NUM_DISPLAY_TYPES];
+
     //Overlay object - NULL for non overlay devices
     overlay::Overlay *mOverlay;
     //QService object
diff --git a/libhwcomposer/hwc_video.cpp b/libhwcomposer/hwc_video.cpp
index 1784593..16d0c89 100644
--- a/libhwcomposer/hwc_video.cpp
+++ b/libhwcomposer/hwc_video.cpp
@@ -108,7 +108,8 @@
     }
 
     MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
-    if ((metadata->operation & PP_PARAM_INTERLACED) && metadata->interlaced) {
+    if (metadata && (metadata->operation & PP_PARAM_INTERLACED) &&
+                                             metadata->interlaced) {
         ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_DEINTERLACE);
     }
 
diff --git a/liboverlay/overlayMdssRot.cpp b/liboverlay/overlayMdssRot.cpp
index 86df0c2..071e9f2 100644
--- a/liboverlay/overlayMdssRot.cpp
+++ b/liboverlay/overlayMdssRot.cpp
@@ -95,10 +95,7 @@
 }
 
 void MdssRot::setFlags(const utils::eMdpFlags& flags) {
-    mRotInfo.flags &= ~utils::OV_MDP_SECURE_OVERLAY_SESSION;
-    if (flags & utils::OV_MDP_SECURE_OVERLAY_SESSION) {
-        mRotInfo.flags |= utils::OV_MDP_SECURE_OVERLAY_SESSION;
-    }
+    mRotInfo.flags |= flags;
 }
 
 void MdssRot::setTransform(const utils::eTransform& rot, const bool& rotUsed)
diff --git a/libqdutils/Android.mk b/libqdutils/Android.mk
index ecae273..eb04afb 100644
--- a/libqdutils/Android.mk
+++ b/libqdutils/Android.mk
@@ -9,8 +9,8 @@
 LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdutils\"
 LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
 LOCAL_SRC_FILES               := profiler.cpp mdp_version.cpp \
-                                 idle_invalidator.cpp
-
+                                 idle_invalidator.cpp \
+                                 comptype.cpp
 include $(BUILD_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
diff --git a/libqdutils/comptype.cpp b/libqdutils/comptype.cpp
new file mode 100644
index 0000000..a29158a
--- /dev/null
+++ b/libqdutils/comptype.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation or the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include<comptype.h>
+
+//Instanticate the QCCompositionType Singleton
+ANDROID_SINGLETON_STATIC_INSTANCE(qdutils::QCCompositionType);
diff --git a/libqdutils/comptype.h b/libqdutils/comptype.h
index a90f957..63c99d3 100644
--- a/libqdutils/comptype.h
+++ b/libqdutils/comptype.h
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
-
+ * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
  * met:
@@ -10,7 +10,7 @@
  *     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 Code Aurora Forum, Inc. nor the names of its
+ *   * Neither the name of The Linux Foundation or the names of its
  *     contributors may be used to endorse or promote products derived
  *     from this software without specific prior written permission.
  *
@@ -89,5 +89,4 @@
 
 }
 }; //namespace qdutils
-ANDROID_SINGLETON_STATIC_INSTANCE(qdutils::QCCompositionType);
 #endif //INCLUDE_LIBQCOM_COMPTYPES