diff --git a/libhwcomposer/hwcomposer.cpp b/libhwcomposer/hwcomposer.cpp
new file mode 100755
index 0000000..c43fa04
--- /dev/null
+++ b/libhwcomposer/hwcomposer.cpp
@@ -0,0 +1,1734 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <hardware/hardware.h>
+
+#include <fcntl.h>
+#include <errno.h>
+
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+#include <cutils/properties.h>
+
+#include <hardware/hwcomposer.h>
+#include <overlayLib.h>
+#include <overlayLibUI.h>
+#include <copybit.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <ui/android_native_buffer.h>
+#include <gralloc_priv.h>
+#include <genlock.h>
+#include <qcom_ui.h>
+#include <gr.h>
+
+/*****************************************************************************/
+#define ALIGN(x, align) (((x) + ((align)-1)) & ~((align)-1))
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+#ifdef COMPOSITION_BYPASS
+#define MAX_BYPASS_LAYERS 3
+#define BYPASS_DEBUG 0
+#define BYPASS_INDEX_OFFSET 4
+
+enum BypassState {
+    BYPASS_ON,
+    BYPASS_OFF,
+    BYPASS_OFF_PENDING,
+};
+
+enum BypassBufferLockState {
+    BYPASS_BUFFER_UNLOCKED,
+    BYPASS_BUFFER_LOCKED,
+};
+#endif
+
+enum HWCLayerType{
+    HWC_SINGLE_VIDEO           = 0x1,
+    HWC_ORIG_RESOLUTION        = 0x2,
+    HWC_S3D_LAYER              = 0x4,
+    HWC_STOP_UI_MIRRORING_MASK = 0xF
+};
+
+enum eHWCOverlayStatus {
+    HWC_OVERLAY_OPEN,
+    HWC_OVERLAY_PREPARE_TO_CLOSE,
+    HWC_OVERLAY_CLOSED
+};
+
+struct hwc_context_t {
+    hwc_composer_device_t device;
+    /* our private state goes below here */
+    overlay::Overlay* mOverlayLibObject;
+    native_handle_t *previousOverlayHandle;
+#ifdef COMPOSITION_BYPASS
+    overlay::OverlayUI* mOvUI[MAX_BYPASS_LAYERS];
+    native_handle_t* previousBypassHandle[MAX_BYPASS_LAYERS];
+    BypassBufferLockState bypassBufferLockState[MAX_BYPASS_LAYERS];
+    int layerindex[MAX_BYPASS_LAYERS];
+    int nPipesUsed;
+    BypassState bypassState;
+#endif
+#if defined HDMI_DUAL_DISPLAY
+    external_display mHDMIEnabled; // Type of external display
+    bool pendingHDMI;
+#endif
+    int previousLayerCount;
+    eHWCOverlayStatus hwcOverlayStatus;
+};
+
+static int hwc_device_open(const struct hw_module_t* module, const char* name,
+        struct hw_device_t** device);
+
+static struct hw_module_methods_t hwc_module_methods = {
+    open: hwc_device_open
+};
+
+
+struct private_hwc_module_t {
+    hwc_module_t base;
+    copybit_device_t *copybitEngine;
+    framebuffer_device_t *fbDevice;
+    int compositionType;
+    bool isBypassEnabled; //from build.prop ro.sf.compbypass.enable
+};
+
+struct private_hwc_module_t HAL_MODULE_INFO_SYM = {
+    base: {
+        common: {
+            tag: HARDWARE_MODULE_TAG,
+            version_major: 1,
+            version_minor: 0,
+            id: HWC_HARDWARE_MODULE_ID,
+            name: "Hardware Composer Module",
+            author: "The Android Open Source Project",
+            methods: &hwc_module_methods,
+        }
+   },
+   copybitEngine: NULL,
+   fbDevice: NULL,
+   compositionType: 0,
+   isBypassEnabled: false,
+};
+
+//Only at this point would the compiler know all storage class sizes.
+//The header has hooks which need to know those beforehand.
+#include "external_display_only.h"
+
+/*****************************************************************************/
+
+static void dump_layer(hwc_layer_t const* l) {
+    LOGD("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, {%d,%d,%d,%d}, {%d,%d,%d,%d}",
+            l->compositionType, l->flags, l->handle, l->transform, l->blending,
+            l->sourceCrop.left,
+            l->sourceCrop.top,
+            l->sourceCrop.right,
+            l->sourceCrop.bottom,
+            l->displayFrame.left,
+            l->displayFrame.top,
+            l->displayFrame.right,
+            l->displayFrame.bottom);
+}
+
+static inline int min(const int& a, const int& b) {
+    return (a < b) ? a : b;
+}
+
+static inline int max(const int& a, const int& b) {
+    return (a > b) ? a : b;
+}
+#ifdef COMPOSITION_BYPASS
+void setLayerbypassIndex(hwc_layer_t* layer, const int bypass_index)
+{
+    layer->flags &= ~HWC_BYPASS_INDEX_MASK;
+    layer->flags |= bypass_index << BYPASS_INDEX_OFFSET;
+}
+
+int  getLayerbypassIndex(hwc_layer_t* layer)
+{
+    int byp_index = -1;
+
+    if(layer->flags & HWC_COMP_BYPASS) {
+        byp_index = ((layer->flags & HWC_BYPASS_INDEX_MASK) >> BYPASS_INDEX_OFFSET);
+        byp_index = (byp_index < MAX_BYPASS_LAYERS ? byp_index : -1 );
+    }
+    return byp_index;
+}
+
+void unlockPreviousBypassBuffers(hwc_context_t* ctx) {
+    // Unlock the previous bypass buffers. We can blindly unlock the buffers here,
+    // because buffers will be in this list only if the lock was successfully acquired.
+    for(int i = 0; i < MAX_BYPASS_LAYERS && ctx->previousBypassHandle[i]; i++) {
+       private_handle_t *hnd = (private_handle_t*) ctx->previousBypassHandle[i];
+
+       // Validate the handle to make sure it hasn't been deallocated.
+       if (private_handle_t::validate(ctx->previousBypassHandle[i])) {
+            continue;
+       }
+       // Check if the handle was locked previously
+       if (private_handle_t::PRIV_FLAGS_HWC_LOCK & hnd->flags) {
+          if (GENLOCK_FAILURE == genlock_unlock_buffer(ctx->previousBypassHandle[i])) {
+              LOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
+          } else {
+              ctx->previousBypassHandle[i] = NULL;
+              // Reset the lock flag
+              hnd->flags &= ~private_handle_t::PRIV_FLAGS_HWC_LOCK;
+          }
+       }
+    }
+}
+
+void print_info(hwc_layer_t* layer)
+{
+     hwc_rect_t sourceCrop = layer->sourceCrop;
+     hwc_rect_t displayFrame = layer->displayFrame;
+
+     int s_l = sourceCrop.left;
+     int s_t = sourceCrop.top;
+     int s_r = sourceCrop.right;
+     int s_b = sourceCrop.bottom;
+
+     int d_l = displayFrame.left;
+     int d_t = displayFrame.top;
+     int d_r = displayFrame.right;
+     int d_b = displayFrame.bottom;
+
+     LOGE_IF(BYPASS_DEBUG, "src:[%d,%d,%d,%d] (%d x %d) dst:[%d,%d,%d,%d] (%d x %d)",
+                             s_l, s_t, s_r, s_b, (s_r - s_l), (s_b - s_t),
+                             d_l, d_t, d_r, d_b, (d_r - d_l), (d_b - d_t));
+}
+
+//Crops source buffer against destination and FB boundaries
+void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst, int hw_w, int hw_h) {
+
+    int& crop_x = crop.left;
+    int& crop_y = crop.top;
+    int& crop_r = crop.right;
+    int& crop_b = crop.bottom;
+    int crop_w = crop.right - crop.left;
+    int crop_h = crop.bottom - crop.top;
+
+    int& dst_x = dst.left;
+    int& dst_y = dst.top;
+    int& dst_r = dst.right;
+    int& dst_b = dst.bottom;
+    int dst_w = dst.right - dst.left;
+    int dst_h = dst.bottom - dst.top;
+
+    if(dst_x < 0) {
+        float scale_x =  crop_w * 1.0f / dst_w;
+        float diff_factor = (scale_x * abs(dst_x));
+        crop_x = crop_x + (int)diff_factor;
+        crop_w = crop_r - crop_x;
+
+        dst_x = 0;
+        dst_w = dst_r - dst_x;;
+    }
+    if(dst_r > hw_w) {
+        float scale_x = crop_w * 1.0f / dst_w;
+        float diff_factor = scale_x * (dst_r - hw_w);
+        crop_r = crop_r - diff_factor;
+        crop_w = crop_r - crop_x;
+
+        dst_r = hw_w;
+        dst_w = dst_r - dst_x;
+    }
+    if(dst_y < 0) {
+        float scale_y = crop_h * 1.0f / dst_h;
+        float diff_factor = scale_y * abs(dst_y);
+        crop_y = crop_y + diff_factor;
+        crop_h = crop_b - crop_y;
+
+        dst_y = 0;
+        dst_h = dst_b - dst_y;
+    }
+    if(dst_b > hw_h) {
+        float scale_y = crop_h * 1.0f / dst_h;
+        float diff_factor = scale_y * (dst_b - hw_h);
+        crop_b = crop_b - diff_factor;
+        crop_h = crop_b - crop_y;
+
+        dst_b = hw_h;
+        dst_h = dst_b - dst_y;
+    }
+
+    LOGE_IF(BYPASS_DEBUG,"crop: [%d,%d,%d,%d] dst:[%d,%d,%d,%d]",
+                     crop_x, crop_y, crop_w, crop_h,dst_x, dst_y, dst_w, dst_h);
+}
+
+/*
+ * Configures pipe(s) for composition bypass
+ */
+static int prepareBypass(hwc_context_t *ctx, hwc_layer_t *layer,
+                        int nPipeIndex, int vsync_wait, int isFG) {
+
+    if (ctx && ctx->mOvUI[nPipeIndex]) {
+        overlay::OverlayUI *ovUI = ctx->mOvUI[nPipeIndex];
+
+        private_hwc_module_t* hwcModule = reinterpret_cast<
+                private_hwc_module_t*>(ctx->device.common.module);
+        if (!hwcModule) {
+            LOGE("%s: NULL Module", __FUNCTION__);
+            return -1;
+        }
+
+        private_handle_t *hnd = (private_handle_t *)layer->handle;
+        if(!hnd) {
+            LOGE("%s: layer handle is NULL", __FUNCTION__);
+            return -1;
+        }
+
+        int hw_w = hwcModule->fbDevice->width;
+        int hw_h = hwcModule->fbDevice->height;
+
+        hwc_rect_t sourceCrop = layer->sourceCrop;
+        hwc_rect_t displayFrame = layer->displayFrame;
+
+        const int src_w = sourceCrop.right - sourceCrop.left;
+        const int src_h = sourceCrop.bottom - sourceCrop.top;
+
+        hwc_rect_t crop = sourceCrop;
+        int crop_w = crop.right - crop.left;
+        int crop_h = crop.bottom - crop.top;
+
+        hwc_rect_t dst = displayFrame;
+        int dst_w = dst.right - dst.left;
+        int dst_h = dst.bottom - dst.top;
+
+        if(hnd != NULL && (hnd->flags & private_handle_t::PRIV_FLAGS_NONCONTIGUOUS_MEM )) {
+            LOGE("%s: Unable to setup bypass due to non-pmem memory",__FUNCTION__);
+            return -1;
+        }
+
+        if(dst.left < 0 || dst.top < 0 || dst.right > hw_w || dst.bottom > hw_h) {
+            LOGE_IF(BYPASS_DEBUG,"%s: Destination has negative coordinates", __FUNCTION__);
+
+            calculate_crop_rects(crop, dst, hw_w, hw_h);
+
+            //Update calulated width and height
+            crop_w = crop.right - crop.left;
+            crop_h = crop.bottom - crop.top;
+
+            dst_w = dst.right - dst.left;
+            dst_h = dst.bottom - dst.top;
+        }
+
+        if( (dst_w > hw_w)|| (dst_h > hw_h)) {
+            LOGE_IF(BYPASS_DEBUG,"%s: Destination rectangle exceeds FB resolution", __FUNCTION__);
+            print_info(layer);
+            dst_w = hw_w;
+            dst_h = hw_h;
+        }
+
+        overlay_buffer_info info;
+        info.width = src_w;
+        info.height = src_h;
+        info.format = hnd->format;
+        info.size = hnd->size;
+
+        int fbnum = 0;
+        int orientation = layer->transform;
+        const bool useVGPipe =  (nPipeIndex != (MAX_BYPASS_LAYERS-1));
+        //only last layer should wait for vsync
+        const bool waitForVsync = vsync_wait;
+        const bool isFg = isFG;
+        //Just to differentiate zorders for different layers
+        const int zorder = nPipeIndex;
+
+        ovUI->setSource(info, orientation);
+        ovUI->setCrop(crop.left, crop.top, crop_w, crop_h);
+        ovUI->setDisplayParams(fbnum, waitForVsync, isFg, zorder, useVGPipe);
+        ovUI->setPosition(dst.left, dst.top, dst_w, dst_h);
+
+        LOGE_IF(BYPASS_DEBUG,"%s: Bypass set: crop[%d,%d,%d,%d] dst[%d,%d,%d,%d] waitforVsync: %d \
+                                isFg: %d zorder: %d VG = %d nPipe: %d",__FUNCTION__,
+                                crop.left, crop.top, crop_w, crop_h,
+                                dst.left, dst.top, dst_w, dst_h,
+                                waitForVsync, isFg, zorder, useVGPipe, nPipeIndex );
+
+        if(ovUI->commit() != overlay::NO_ERROR) {
+            LOGE("%s: Overlay Commit failed", __FUNCTION__);
+            return -1;
+        }
+    }
+    return 0;
+}
+
+/*
+ * Checks if doing comp. bypass is possible.
+ * It is possible if
+ * 1. No MDP pipe is used
+ * 2. Rotation is not needed
+ * 3. We have atmost MAX_BYPASS_LAYERS
+ */
+inline static bool isBypassDoable(hwc_composer_device_t *dev, const int yuvCount,
+        const hwc_layer_list_t* list) {
+    hwc_context_t* ctx = (hwc_context_t*)(dev);
+    private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(
+                                                           dev->common.module);
+    //Check if enabled in build.prop
+    if(hwcModule->isBypassEnabled == false) {
+        return false;
+    }
+
+    if(list->numHwLayers < 1) {
+        return false;
+    }
+
+#if defined HDMI_DUAL_DISPLAY
+    //Disable bypass when HDMI is enabled
+    if(ctx->mHDMIEnabled || ctx->pendingHDMI) {
+        return false;
+    }
+#endif
+
+    if(ExtDispOnly::isModeOn()) {
+        return false;
+    }
+
+    //Bypass is not efficient if rotation or asynchronous mode is needed.
+    for(int i = 0; i < list->numHwLayers; ++i) {
+        if(list->hwLayers[i].transform) {
+            return false;
+        }
+        if(list->hwLayers[i].flags & HWC_LAYER_ASYNCHRONOUS) {
+            return false;
+        }
+    }
+
+    return (yuvCount == 0) && (ctx->hwcOverlayStatus == HWC_OVERLAY_CLOSED)
+                                   && (list->numHwLayers <= MAX_BYPASS_LAYERS);
+}
+
+void setBypassLayerFlags(hwc_context_t* ctx, hwc_layer_list_t* list)
+{
+    for(int index = 0 ; index < MAX_BYPASS_LAYERS; index++ )
+    {
+        int layer_index = ctx->layerindex[index];
+        if(layer_index >= 0) {
+            hwc_layer_t* layer = &(list->hwLayers[layer_index]);
+
+            layer->flags |= HWC_COMP_BYPASS;
+            layer->compositionType = HWC_USE_OVERLAY;
+            layer->hints |= HWC_HINT_CLEAR_FB;
+        }
+    }
+
+    if( list->numHwLayers > ctx->nPipesUsed ) {
+         list->flags &= ~HWC_SKIP_COMPOSITION; //Compose to FB
+    } else {
+         list->flags |= HWC_SKIP_COMPOSITION; // Dont
+    }
+}
+
+bool setupBypass(hwc_context_t* ctx, hwc_layer_list_t* list) {
+    int nPipeIndex, vsync_wait, isFG;
+    int numHwLayers = list->numHwLayers;
+    int nPipeAvailable = MAX_BYPASS_LAYERS;
+
+    for (int index = 0 ; (index < numHwLayers) && nPipeAvailable; index++) {
+
+        hwc_layer_t* layer = &(list->hwLayers[index]);
+
+        nPipeIndex =  MAX_BYPASS_LAYERS - nPipeAvailable;
+        //Set VSYNC wait is needed only for the last pipe queued
+        vsync_wait = (nPipeIndex == (numHwLayers-1));
+        //Set isFG to true for layer with z-order zero
+        isFG = !index;
+
+        //Clear Bypass flags for the layer
+        layer->flags &= ~HWC_COMP_BYPASS;
+        layer->flags |= HWC_BYPASS_INDEX_MASK;
+
+        if( prepareBypass(ctx, &(list->hwLayers[index]), nPipeIndex, vsync_wait, isFG) != 0 ) {
+           LOGE_IF(BYPASS_DEBUG, "%s: layer %d failed to configure bypass for pipe index: %d",
+                                                               __FUNCTION__, index, nPipeIndex);
+           return false;
+         } else {
+           ctx->layerindex[nPipeIndex] = index;
+           setLayerbypassIndex(layer, nPipeIndex);
+           nPipeAvailable--;
+         }
+    }
+    ctx->nPipesUsed =  MAX_BYPASS_LAYERS - nPipeAvailable;
+    return true;
+}
+
+void unsetBypassLayerFlags(hwc_layer_list_t* list) {
+    if (!list)
+        return;
+
+    for (int index = 0 ; index < list->numHwLayers; index++) {
+        if(list->hwLayers[index].flags & HWC_COMP_BYPASS) {
+            list->hwLayers[index].flags &= ~HWC_COMP_BYPASS;
+        }
+    }
+}
+
+void unsetBypassBufferLockState(hwc_context_t* ctx) {
+    for (int i= 0; i< MAX_BYPASS_LAYERS; i++) {
+        ctx->bypassBufferLockState[i] = BYPASS_BUFFER_UNLOCKED;
+    }
+}
+
+void storeLockedBypassHandle(hwc_layer_list_t* list, hwc_context_t* ctx) {
+   if (!list)
+        return;
+
+   for(int index = 0; index < MAX_BYPASS_LAYERS; index++ ) {
+       hwc_layer_t layer = list->hwLayers[ctx->layerindex[index]];
+
+       if (layer.flags & HWC_COMP_BYPASS) {
+            private_handle_t *hnd = (private_handle_t*)layer.handle;
+
+            if (ctx->bypassBufferLockState[index] == BYPASS_BUFFER_LOCKED) {
+               ctx->previousBypassHandle[index] = (native_handle_t*)layer.handle;
+               hnd->flags |= private_handle_t::PRIV_FLAGS_HWC_LOCK;
+           } else {
+              ctx->previousBypassHandle[index] = NULL;
+           }
+       }
+   }
+}
+
+void closeExtraPipes(hwc_context_t* ctx) {
+
+    int pipes_used = ctx->nPipesUsed;
+
+    //Unused pipes must be of higher z-order
+    for (int i =  pipes_used ; i < MAX_BYPASS_LAYERS; i++) {
+        if (ctx->previousBypassHandle[i]) {
+            private_handle_t *hnd = (private_handle_t*) ctx->previousBypassHandle[i];
+
+            if (!private_handle_t::validate(ctx->previousBypassHandle[i])) {
+                if (GENLOCK_FAILURE == genlock_unlock_buffer(ctx->previousBypassHandle[i])) {
+                    LOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
+                } else {
+                    ctx->previousBypassHandle[i] = NULL;
+                    ctx->bypassBufferLockState[i] = BYPASS_BUFFER_UNLOCKED;
+                    hnd->flags &= ~private_handle_t::PRIV_FLAGS_HWC_LOCK;
+                }
+            }
+        }
+        ctx->mOvUI[i]->closeChannel();
+        ctx->layerindex[i] = -1;
+    }
+}
+#endif  //COMPOSITION_BYPASS
+
+static int setVideoOverlayStatusInGralloc(hwc_context_t* ctx, const bool enable) {
+#if defined HDMI_DUAL_DISPLAY
+    private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(
+                                                           ctx->device.common.module);
+    if(!hwcModule) {
+        LOGE("%s: invalid params", __FUNCTION__);
+        return -1;
+    }
+
+    framebuffer_device_t *fbDev = hwcModule->fbDevice;
+    if (!fbDev) {
+        LOGE("%s: fbDev is NULL", __FUNCTION__);
+        return -1;
+    }
+
+    // Inform the gralloc to stop or start UI mirroring
+    fbDev->videoOverlayStarted(fbDev, enable);
+#endif
+    return 0;
+}
+
+static void setHWCOverlayStatus(hwc_context_t *ctx, bool isVideoPresent) {
+
+    switch (ctx->hwcOverlayStatus) {
+        case HWC_OVERLAY_OPEN:
+            ctx->hwcOverlayStatus =
+                isVideoPresent ? HWC_OVERLAY_OPEN : HWC_OVERLAY_PREPARE_TO_CLOSE;
+        break;
+        case HWC_OVERLAY_PREPARE_TO_CLOSE:
+            ctx->hwcOverlayStatus =
+                isVideoPresent ? HWC_OVERLAY_OPEN : HWC_OVERLAY_CLOSED;
+        break;
+        case HWC_OVERLAY_CLOSED:
+            ctx->hwcOverlayStatus =
+                isVideoPresent ? HWC_OVERLAY_OPEN : HWC_OVERLAY_CLOSED;
+        break;
+        default:
+          LOGE("%s: Invalid hwcOverlayStatus (status =%d)", __FUNCTION__,
+                ctx->hwcOverlayStatus);
+        break;
+    }
+}
+
+static int hwc_closeOverlayChannels(hwc_context_t* ctx) {
+#ifdef USE_OVERLAY
+    overlay::Overlay *ovLibObject = ctx->mOverlayLibObject;
+    if(!ovLibObject) {
+        LOGE("%s: invalid params", __FUNCTION__);
+        return -1;
+    }
+
+    if (HWC_OVERLAY_PREPARE_TO_CLOSE == ctx->hwcOverlayStatus) {
+        // Video mirroring is going on, and we do not have any layers to
+        // mirror directly. Close the current video channel and inform the
+        // gralloc to start UI mirroring
+        ovLibObject->closeChannel();
+        // Inform the gralloc that video overlay has stopped.
+        setVideoOverlayStatusInGralloc(ctx, false);
+    }
+#endif
+    return 0;
+}
+
+/*
+ * Configures mdp pipes
+ */
+static int prepareOverlay(hwc_context_t *ctx, hwc_layer_t *layer, const int flags) {
+     int ret = 0;
+
+#ifdef COMPOSITION_BYPASS
+     if(ctx && (ctx->bypassState != BYPASS_OFF)) {
+        ctx->nPipesUsed = 0;
+        closeExtraPipes(ctx);
+        ctx->bypassState = BYPASS_OFF;
+     }
+#endif
+
+     if (LIKELY(ctx && ctx->mOverlayLibObject)) {
+        private_hwc_module_t* hwcModule =
+            reinterpret_cast<private_hwc_module_t*>(ctx->device.common.module);
+        if (UNLIKELY(!hwcModule)) {
+            LOGE("prepareOverlay null module ");
+            return -1;
+        }
+
+        private_handle_t *hnd = (private_handle_t *)layer->handle;
+        overlay::Overlay *ovLibObject = ctx->mOverlayLibObject;
+        overlay_buffer_info info;
+        info.width = hnd->width;
+        info.height = hnd->height;
+        info.format = hnd->format;
+        info.size = hnd->size;
+
+        int hdmiConnected = 0;
+
+#if defined HDMI_DUAL_DISPLAY
+        if(!ctx->pendingHDMI) //makes sure the UI channel is opened first
+            hdmiConnected = (int)ctx->mHDMIEnabled;
+#endif
+        ret = ovLibObject->setSource(info, layer->transform,
+                            hdmiConnected, flags);
+        if (!ret) {
+            LOGE("prepareOverlay setSource failed");
+            return -1;
+        }
+
+        ret = ovLibObject->setTransform(layer->transform);
+        if (!ret) {
+            LOGE("prepareOverlay setTransform failed transform %x",
+                    layer->transform);
+            return -1;
+        }
+
+        hwc_rect_t sourceCrop = layer->sourceCrop;
+        ret = ovLibObject->setCrop(sourceCrop.left, sourceCrop.top,
+                                  (sourceCrop.right - sourceCrop.left),
+                                  (sourceCrop.bottom - sourceCrop.top));
+        if (!ret) {
+            LOGE("prepareOverlay setCrop failed");
+            return -1;
+        }
+#if defined HDMI_DUAL_DISPLAY
+        // Send the device orientation to  overlayLib
+        if(hwcModule) {
+            framebuffer_device_t *fbDev = reinterpret_cast<framebuffer_device_t*>
+                                                            (hwcModule->fbDevice);
+            if(fbDev) {
+                private_module_t* m = reinterpret_cast<private_module_t*>(
+                                                         fbDev->common.module);
+                if(m)
+                    ovLibObject->setDeviceOrientation(m->orientation);
+            }
+        }
+#endif
+        if (layer->flags & HWC_USE_ORIGINAL_RESOLUTION) {
+            framebuffer_device_t* fbDev = hwcModule->fbDevice;
+            ret = ovLibObject->setPosition(0, 0,
+                                           fbDev->width, fbDev->height);
+        } else {
+            hwc_rect_t displayFrame = layer->displayFrame;
+            ret = ovLibObject->setPosition(displayFrame.left, displayFrame.top,
+                                    (displayFrame.right - displayFrame.left),
+                                    (displayFrame.bottom - displayFrame.top));
+        }
+        if (!ret) {
+            LOGE("prepareOverlay setPosition failed");
+            return -1;
+        }
+     }
+     return 0;
+}
+
+void unlockPreviousOverlayBuffer(hwc_context_t* ctx)
+{
+    if (ctx->previousOverlayHandle) {
+        // Validate the handle before attempting to use it.
+        if (!private_handle_t::validate(ctx->previousOverlayHandle)) {
+            private_handle_t *hnd = (private_handle_t*)ctx->previousOverlayHandle;
+            // Unlock any previously locked buffers
+            if (private_handle_t::PRIV_FLAGS_HWC_LOCK & hnd->flags) {
+                if (GENLOCK_NO_ERROR == genlock_unlock_buffer(ctx->previousOverlayHandle)) {
+                    ctx->previousOverlayHandle = NULL;
+                    hnd->flags &= ~private_handle_t::PRIV_FLAGS_HWC_LOCK;
+                } else {
+                    LOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
+                }
+            }
+        }
+    }
+}
+
+bool canSkipComposition(hwc_context_t* ctx, int yuvBufferCount, int currentLayerCount,
+                        int numLayersNotUpdating)
+{
+    if (!ctx) {
+        LOGE("%s: invalid context",__FUNCTION__);
+        return false;
+    }
+
+    hwc_composer_device_t* dev = (hwc_composer_device_t *)(ctx);
+    private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(
+                                                           dev->common.module);
+    if (hwcModule->compositionType == COMPOSITION_TYPE_CPU)
+        return false;
+
+    //Video / Camera case
+    if (yuvBufferCount == 1) {
+        //If the previousLayerCount is anything other than the current count, it
+        //means something changed and we need to compose atleast once to FB.
+        if (currentLayerCount != ctx->previousLayerCount) {
+            ctx->previousLayerCount = currentLayerCount;
+            return false;
+        }
+        // We either have only one overlay layer or we have
+        // all non-updating UI layers.
+        // We can skip the composition of the UI layers.
+        if ((currentLayerCount == 1) ||
+            ((currentLayerCount - 1) == numLayersNotUpdating)) {
+            return true;
+        }
+    } else {
+        ctx->previousLayerCount = -1;
+    }
+    return false;
+}
+
+inline void getLayerResolution(const hwc_layer_t* layer, int& width, int& height)
+{
+   hwc_rect_t displayFrame  = layer->displayFrame;
+
+   width = displayFrame.right - displayFrame.left;
+   height = displayFrame.bottom - displayFrame.top;
+}
+
+static bool canUseCopybit(const framebuffer_device_t* fbDev, const hwc_layer_list_t* list) {
+
+    if(!fbDev) {
+       LOGE("ERROR: %s : fb device is invalid",__func__);
+       return false;
+    }
+
+    if (!list)
+        return false;
+
+    int fb_w = fbDev->width;
+    int fb_h = fbDev->height;
+
+    /*
+     * Use copybit only when we need to blit
+     * max 2 full screen sized regions
+     */
+
+    unsigned int renderArea = 0;
+
+    for(int i = 0; i < list->numHwLayers; i++ ) {
+        int w, h;
+        getLayerResolution(&list->hwLayers[i], w, h);
+        renderArea += w*h;
+    }
+
+    return (renderArea <= (2 * fb_w * fb_h));
+}
+
+static void handleHDMIStateChange(hwc_composer_device_t *dev, int externaltype) {
+#if defined HDMI_DUAL_DISPLAY
+    hwc_context_t* ctx = (hwc_context_t*)(dev);
+    private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(
+                                                           dev->common.module);
+    //Route the event to fbdev only if we are in default mirror mode
+    if(ExtDispOnly::isModeOn() == false) {
+        framebuffer_device_t *fbDev = hwcModule->fbDevice;
+        if (fbDev) {
+            fbDev->enableHDMIOutput(fbDev, externaltype);
+        }
+
+        if(ctx && ctx->mOverlayLibObject) {
+            overlay::Overlay *ovLibObject = ctx->mOverlayLibObject;
+            if (!externaltype) {
+                // Close the external overlay channels if HDMI is disconnected
+                ovLibObject->closeExternalChannel();
+            }
+        }
+    }
+#endif
+}
+
+/*
+ * function to set the status of external display in hwc
+ * Just mark flags and do stuff after eglSwapBuffers
+ * externaltype - can be HDMI, WIFI or OFF
+ */
+static void hwc_enableHDMIOutput(hwc_composer_device_t *dev, int externaltype) {
+#if defined HDMI_DUAL_DISPLAY
+    hwc_context_t* ctx = (hwc_context_t*)(dev);
+    private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(
+                                                           dev->common.module);
+    framebuffer_device_t *fbDev = hwcModule->fbDevice;
+    overlay::Overlay *ovLibObject = ctx->mOverlayLibObject;
+    if(externaltype && ctx->mHDMIEnabled &&
+            (externaltype != ctx->mHDMIEnabled)) {
+        // Close the current external display - as the SF will
+        // prioritize and send the correct external display HDMI/WFD
+        handleHDMIStateChange(dev, 0);
+    }
+    // Store the external display
+    ctx->mHDMIEnabled = (external_display)externaltype;
+    if(ctx->mHDMIEnabled) { //On connect, allow bypass to draw once to FB
+        ctx->pendingHDMI = true;
+    } else { //On disconnect, close immediately (there will be no bypass)
+        handleHDMIStateChange(dev, ctx->mHDMIEnabled);
+    }
+#endif
+}
+
+static bool isValidDestination(const framebuffer_device_t* fbDev, const hwc_rect_t& rect)
+{
+    if (!fbDev) {
+        LOGE("%s: fbDev is null", __FUNCTION__);
+        return false;
+    }
+
+    int dest_width = (rect.right - rect.left);
+    int dest_height = (rect.bottom - rect.top);
+
+    if (rect.left < 0 || rect.right < 0 || rect.top < 0 || rect.bottom < 0
+        || dest_width <= 0 || dest_height <= 0) {
+        LOGE("%s: destination: left=%d right=%d top=%d bottom=%d width=%d"
+             "height=%d", __FUNCTION__, rect.left, rect.right, rect.top,
+             rect.bottom, dest_width, dest_height);
+        return false;
+    }
+
+    if ((rect.left+dest_width) > fbDev->width || (rect.top+dest_height) > fbDev->height) {
+        LOGE("%s: destination out of bound params", __FUNCTION__);
+        return false;
+    }
+
+    return true;
+}
+
+static int getYUVBufferCount (const hwc_layer_list_t* list) {
+    int yuvBufferCount = 0;
+    if (list) {
+        for (size_t i=0 ; i<list->numHwLayers; i++) {
+            private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
+            if (hnd && (hnd->bufferType == BUFFER_TYPE_VIDEO) &&
+               !(list->hwLayers[i].flags & HWC_DO_NOT_USE_OVERLAY)) {
+                yuvBufferCount++;
+                if (yuvBufferCount > 1) {
+                    break;
+                }
+            }
+        }
+    }
+    return yuvBufferCount;
+}
+
+static int getS3DVideoFormat (const hwc_layer_list_t* list) {
+    int s3dFormat = 0;
+    if (list) {
+        for (size_t i=0; i<list->numHwLayers; i++) {
+            private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
+            if (hnd && (hnd->bufferType == BUFFER_TYPE_VIDEO))
+                s3dFormat = FORMAT_3D_INPUT(hnd->format);
+            if (s3dFormat)
+                break;
+        }
+    }
+    return s3dFormat;
+}
+
+static int getS3DFormat (const hwc_layer_list_t* list) {
+    int s3dFormat = 0;
+    if (list) {
+        for (size_t i=0; i<list->numHwLayers; i++) {
+            private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
+            if (hnd)
+                s3dFormat = FORMAT_3D_INPUT(hnd->format);
+            if (s3dFormat)
+                break;
+        }
+    }
+    return s3dFormat;
+}
+
+
+static int getLayerS3DFormat (hwc_layer_t &layer) {
+    int s3dFormat = 0;
+    private_handle_t *hnd = (private_handle_t *)layer.handle;
+    if (hnd)
+        s3dFormat = FORMAT_3D_INPUT(hnd->format);
+    return s3dFormat;
+}
+static bool isS3DCompositionRequired() {
+#ifdef HDMI_AS_PRIMARY
+    return overlay::is3DTV();
+#endif
+    return false;
+}
+
+static void markUILayerForS3DComposition (hwc_layer_t &layer, int s3dVideoFormat) {
+#ifdef HDMI_AS_PRIMARY
+    layer.compositionType = HWC_FRAMEBUFFER;
+    switch(s3dVideoFormat) {
+        case HAL_3D_IN_SIDE_BY_SIDE_L_R:
+        case HAL_3D_IN_SIDE_BY_SIDE_R_L:
+            layer.hints |= HWC_HINT_DRAW_S3D_SIDE_BY_SIDE;
+            break;
+        case HAL_3D_IN_TOP_BOTTOM:
+            layer.hints |= HWC_HINT_DRAW_S3D_TOP_BOTTOM;
+            break;
+        default:
+            LOGE("%s: Unknown S3D input format 0x%x", __FUNCTION__, s3dVideoFormat);
+            break;
+    }
+#endif
+    return;
+}
+
+static int getLayersNotUpdatingCount(const hwc_layer_list_t* list) {
+    int numLayersNotUpdating = 0;
+    if (list) {
+        for (size_t i=0 ; i<list->numHwLayers; i++) {
+            private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
+            if (hnd && (hnd->bufferType != BUFFER_TYPE_VIDEO) &&
+               list->hwLayers[i].flags & HWC_LAYER_NOT_UPDATING)
+               numLayersNotUpdating++;
+        }
+    }
+    return numLayersNotUpdating;
+}
+
+static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list) {
+
+    hwc_context_t* ctx = (hwc_context_t*)(dev);
+
+    if(!ctx) {
+        LOGE("hwc_prepare invalid context");
+        return -1;
+    }
+
+    private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(
+                                                           dev->common.module);
+    if (!hwcModule) {
+        LOGE("hwc_prepare invalid module");
+#ifdef COMPOSITION_BYPASS
+        unlockPreviousBypassBuffers(ctx);
+        unsetBypassBufferLockState(ctx);
+#endif
+        unlockPreviousOverlayBuffer(ctx);
+        ExtDispOnly::close();
+        return -1;
+    }
+
+    int yuvBufferCount = 0;
+    int layerType = 0;
+    bool isS3DCompositionNeeded = false;
+    int s3dVideoFormat = 0;
+    int numLayersNotUpdating = 0;
+    bool useCopybit = false;
+    bool isSkipLayerPresent = false;
+    bool skipComposition = false;
+
+    if (list) {
+        useCopybit = canUseCopybit(hwcModule->fbDevice, list);
+        yuvBufferCount = getYUVBufferCount(list);
+        numLayersNotUpdating = getLayersNotUpdatingCount(list);
+        skipComposition = canSkipComposition(ctx, yuvBufferCount,
+                                list->numHwLayers, numLayersNotUpdating);
+
+        if (yuvBufferCount == 1) {
+            s3dVideoFormat = getS3DVideoFormat(list);
+            if (s3dVideoFormat)
+                isS3DCompositionNeeded = isS3DCompositionRequired();
+        } else if((s3dVideoFormat = getS3DFormat(list))){
+            if (s3dVideoFormat)
+                isS3DCompositionNeeded = isS3DCompositionRequired();
+        } else {
+            unlockPreviousOverlayBuffer(ctx);
+        }
+
+        if (list->flags & HWC_GEOMETRY_CHANGED) {
+            if (yuvBufferCount == 1) {
+                // Inform the gralloc of the current video overlay status
+                setVideoOverlayStatusInGralloc(ctx, true);
+            }
+        }
+
+        for (size_t i=0 ; i<list->numHwLayers ; i++) {
+            private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
+
+            // If there is a single Fullscreen layer, we can bypass it - TBD
+            // If there is only one video/camera buffer, we can bypass itn
+            if (list->hwLayers[i].flags & HWC_SKIP_LAYER) {
+                // During the animaton UI layers are marked as SKIP
+                // need to still mark the layer for S3D composition
+                isSkipLayerPresent = true;
+                skipComposition = false;
+                //Reset count, so that we end up composing once after animation
+                //is over, in case of overlay.
+                ctx->previousLayerCount = -1;
+
+                if (isS3DCompositionNeeded)
+                    markUILayerForS3DComposition(list->hwLayers[i], s3dVideoFormat);
+
+// LGE_CHANGE_E, [G1_Player][bokyung.kim@lge.com], 20120201, Apply SR 00744210 to fix screen flicker {
+                ssize_t layer_countdown = ((ssize_t)i) - 1;
+                // Mark every layer below the SKIP layer to be composed by the GPU
+                while (layer_countdown >= 0)
+                {
+                    private_handle_t *countdown_handle =
+                               (private_handle_t *)list->hwLayers[layer_countdown].handle;
+                    if (countdown_handle && (countdown_handle->bufferType == BUFFER_TYPE_VIDEO)
+                        && (yuvBufferCount == 1)) {
+                        unlockPreviousOverlayBuffer(ctx);
+                    }
+                    list->hwLayers[layer_countdown].compositionType = HWC_FRAMEBUFFER;
+                    list->hwLayers[layer_countdown].hints &= ~HWC_HINT_CLEAR_FB;
+                    layer_countdown--;
+                }
+// LGE_CHANGE_E, [G1_Player][bokyung.kim@lge.com], 20120201, Apply SR 00744210 to fix screen flicker }
+                continue;
+            }
+            if (hnd && (hnd->bufferType == BUFFER_TYPE_VIDEO) && (yuvBufferCount == 1)) {
+                int flags = WAIT_FOR_VSYNC;
+                flags |= (hnd->flags &
+                       private_handle_t::PRIV_FLAGS_SECURE_BUFFER)?
+                       SECURE_OVERLAY_SESSION : 0;
+                flags |= (1 == list->numHwLayers) ? DISABLE_FRAMEBUFFER_FETCH : 0;
+                if (!isValidDestination(hwcModule->fbDevice, list->hwLayers[i].displayFrame)) {
+                    list->hwLayers[i].compositionType = HWC_FRAMEBUFFER;
+                    //Even though there are no skip layers, animation is still
+                    //ON and in its final stages.
+                    //Reset count, so that we end up composing once after animation
+                    //is done, if overlay is used.
+                    ctx->previousLayerCount = -1;
+                    skipComposition = false;
+#ifdef USE_OVERLAY
+                } else if(prepareOverlay(ctx, &(list->hwLayers[i]), flags) == 0) {
+                    list->hwLayers[i].compositionType = HWC_USE_OVERLAY;
+                    list->hwLayers[i].hints |= HWC_HINT_CLEAR_FB;
+                    // We've opened the channel. Set the state to open.
+                    ctx->hwcOverlayStatus = HWC_OVERLAY_OPEN;
+#endif
+                } else if (hwcModule->compositionType & (COMPOSITION_TYPE_C2D|
+                            COMPOSITION_TYPE_MDP)) {
+                    //Fail safe path: If drawing with overlay fails,
+
+                    //Use C2D if available.
+                    list->hwLayers[i].compositionType = HWC_USE_COPYBIT;
+                } else {
+                    //If C2D is not enabled fall back to GPU.
+                    list->hwLayers[i].compositionType = HWC_FRAMEBUFFER;
+                }
+                if (HWC_USE_OVERLAY != list->hwLayers[i].compositionType) {
+                    unlockPreviousOverlayBuffer(ctx);
+                    skipComposition = false;
+                }
+            } else if (getLayerS3DFormat(list->hwLayers[i])) {
+                int flags = WAIT_FOR_VSYNC;
+                flags |= (1 == list->numHwLayers) ? DISABLE_FRAMEBUFFER_FETCH : 0;
+                flags |= (hnd->flags &
+                       private_handle_t::PRIV_FLAGS_SECURE_BUFFER)?
+                       SECURE_OVERLAY_SESSION : 0;
+#ifdef USE_OVERLAY
+                if(prepareOverlay(ctx, &(list->hwLayers[i]), flags) == 0) {
+                    list->hwLayers[i].compositionType = HWC_USE_OVERLAY;
+                    list->hwLayers[i].hints |= HWC_HINT_CLEAR_FB;
+                    // We've opened the channel. Set the state to open.
+                    ctx->hwcOverlayStatus = HWC_OVERLAY_OPEN;
+                }
+#endif
+            } else if (isS3DCompositionNeeded) {
+                markUILayerForS3DComposition(list->hwLayers[i], s3dVideoFormat);
+            } else if (list->hwLayers[i].flags & HWC_USE_ORIGINAL_RESOLUTION) {
+                list->hwLayers[i].compositionType = HWC_USE_OVERLAY;
+                list->hwLayers[i].hints |= HWC_HINT_CLEAR_FB;
+                layerType |= HWC_ORIG_RESOLUTION;
+            } else if (hnd && hnd->flags & private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY) {
+                //handle later after other layers are handled
+            } else if (hnd && (hwcModule->compositionType &
+                    (COMPOSITION_TYPE_C2D|COMPOSITION_TYPE_MDP))) {
+                list->hwLayers[i].compositionType = HWC_USE_COPYBIT;
+            } else if ((hwcModule->compositionType == COMPOSITION_TYPE_DYN)
+                    && useCopybit) {
+                list->hwLayers[i].compositionType = HWC_USE_COPYBIT;
+            }
+            else {
+                list->hwLayers[i].compositionType = HWC_FRAMEBUFFER;
+            }
+        }
+
+        //Update the stats and pipe config for external-only layers
+        ExtDispOnly::update(ctx, list);
+
+        if (skipComposition) {
+            list->flags |= HWC_SKIP_COMPOSITION;
+        } else {
+            list->flags &= ~HWC_SKIP_COMPOSITION;
+        }
+
+#ifdef COMPOSITION_BYPASS
+        bool isBypassUsed = true;
+        bool isDoable = isBypassDoable(dev, yuvBufferCount, list);
+        //Check if bypass is feasible
+        if(isDoable && !isSkipLayerPresent) {
+            if(setupBypass(ctx, list)) {
+                setBypassLayerFlags(ctx, list);
+                ctx->bypassState = BYPASS_ON;
+            } else {
+                LOGE_IF(BYPASS_DEBUG,"%s: Bypass setup Failed",__FUNCTION__);
+                isBypassUsed = false;
+            }
+        } else {
+            LOGE_IF(BYPASS_DEBUG,"%s: Bypass not possible[%d,%d]",__FUNCTION__,
+                       isDoable, !isSkipLayerPresent );
+            isBypassUsed = false;
+        }
+
+        //Reset bypass states
+        if(!isBypassUsed) {
+            ctx->nPipesUsed = 0;
+            unsetBypassLayerFlags(list);
+            if(ctx->bypassState == BYPASS_ON) {
+                ctx->bypassState = BYPASS_OFF_PENDING;
+            }
+        }
+#endif
+    } else {
+#ifdef COMPOSITION_BYPASS
+        unlockPreviousBypassBuffers(ctx);
+        unsetBypassBufferLockState(ctx);
+#endif
+        unlockPreviousOverlayBuffer(ctx);
+    }
+    return 0;
+}
+// ---------------------------------------------------------------------------
+struct range {
+    int current;
+    int end;
+};
+struct region_iterator : public copybit_region_t {
+    
+    region_iterator(hwc_region_t region) {
+        mRegion = region;
+        r.end = region.numRects;
+        r.current = 0;
+        this->next = iterate;
+    }
+
+private:
+    static int iterate(copybit_region_t const * self, copybit_rect_t* rect) {
+        if (!self || !rect) {
+            LOGE("iterate invalid parameters");
+            return 0;
+        }
+
+        region_iterator const* me = static_cast<region_iterator const*>(self);
+        if (me->r.current != me->r.end) {
+            rect->l = me->mRegion.rects[me->r.current].left;
+            rect->t = me->mRegion.rects[me->r.current].top;
+            rect->r = me->mRegion.rects[me->r.current].right;
+            rect->b = me->mRegion.rects[me->r.current].bottom;
+            me->r.current++;
+            return 1;
+        }
+        return 0;
+    }
+    
+    hwc_region_t mRegion;
+    mutable range r; 
+};
+
+static int drawLayerUsingCopybit(hwc_composer_device_t *dev, hwc_layer_t *layer, EGLDisplay dpy,
+                                 EGLSurface surface)
+{
+    hwc_context_t* ctx = (hwc_context_t*)(dev);
+    if(!ctx) {
+         LOGE("drawLayerUsingCopybit null context ");
+         return -1;
+    }
+
+    private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(dev->common.module);
+    if(!hwcModule) {
+        LOGE("drawLayerUsingCopybit null module ");
+        return -1;
+    }
+
+    private_handle_t *hnd = (private_handle_t *)layer->handle;
+    if(!hnd) {
+        LOGE("drawLayerUsingCopybit invalid handle");
+        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) {
+        LOGE("%s: genlock_lock_buffer(READ) failed", __FUNCTION__);
+        return -1;
+    }
+    //render buffer
+    android_native_buffer_t *renderBuffer = (android_native_buffer_t *)eglGetRenderBufferANDROID(dpy, surface);
+    if (!renderBuffer) {
+        LOGE("eglGetRenderBufferANDROID returned NULL buffer");
+        genlock_unlock_buffer(hnd);
+        return -1;
+    }
+    private_handle_t *fbHandle = (private_handle_t *)renderBuffer->handle;
+    if(!fbHandle) {
+        LOGE("Framebuffer handle is NULL");
+        genlock_unlock_buffer(hnd);
+        return -1;
+    }
+    int alignment = 32;
+    if( HAL_PIXEL_FORMAT_RGB_565 == fbHandle->format )
+        alignment = 16;
+     // Set the copybit source:
+    copybit_image_t src;
+    src.w = ALIGN(hnd->width, alignment);
+    src.h = hnd->height;
+    src.format = hnd->format;
+    src.base = (void *)hnd->base;
+    src.handle = (native_handle_t *)layer->handle;
+    src.horiz_padding = src.w - hnd->width;
+    // Initialize vertical padding to zero for now,
+    // this needs to change to accomodate vertical stride
+    // if needed in the future
+    src.vert_padding = 0;
+
+    // Copybit source rect
+    hwc_rect_t sourceCrop = layer->sourceCrop;
+    copybit_rect_t srcRect = {sourceCrop.left, sourceCrop.top,
+                              sourceCrop.right,
+                              sourceCrop.bottom};
+
+    // Copybit destination rect
+    hwc_rect_t displayFrame = layer->displayFrame;
+    copybit_rect_t dstRect = {displayFrame.left, displayFrame.top,
+                              displayFrame.right,
+                              displayFrame.bottom};
+
+    // Copybit dst
+    copybit_image_t dst;
+    dst.w = ALIGN(fbHandle->width,alignment);
+    dst.h = fbHandle->height;
+    dst.format = fbHandle->format;
+    dst.base = (void *)fbHandle->base;
+    dst.handle = (native_handle_t *)renderBuffer->handle;
+
+    copybit_device_t *copybit = hwcModule->copybitEngine;
+
+    int32_t screen_w        = displayFrame.right - displayFrame.left;
+    int32_t screen_h        = displayFrame.bottom - displayFrame.top;
+    int32_t src_crop_width  = sourceCrop.right - sourceCrop.left;
+    int32_t src_crop_height = sourceCrop.bottom -sourceCrop.top;
+
+    float copybitsMaxScale = (float)copybit->get(copybit,COPYBIT_MAGNIFICATION_LIMIT);
+    float copybitsMinScale = (float)copybit->get(copybit,COPYBIT_MINIFICATION_LIMIT);
+
+    if((layer->transform == HWC_TRANSFORM_ROT_90) ||
+                           (layer->transform == HWC_TRANSFORM_ROT_270)) {
+        //swap screen width and height
+        int tmp = screen_w;
+        screen_w  = screen_h;
+        screen_h = tmp;
+    }
+    private_handle_t *tmpHnd = NULL;
+
+    if(screen_w <=0 || screen_h<=0 ||src_crop_width<=0 || src_crop_height<=0 ) {
+        LOGE("%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;
+    }
+
+    float dsdx = (float)screen_w/src_crop_width;
+    float dtdy = (float)screen_h/src_crop_height;
+
+    float scaleLimitMax = copybitsMaxScale * copybitsMaxScale;
+    float scaleLimitMin = copybitsMinScale * copybitsMinScale;
+    if(dsdx > scaleLimitMax || dtdy > scaleLimitMax || dsdx < 1/scaleLimitMin || dtdy < 1/scaleLimitMin) {
+        LOGE("%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 || dtdy > copybitsMaxScale || dsdx < 1/copybitsMinScale || dtdy < 1/copybitsMinScale){
+        // The requested scale is out of the range the hardware
+        // can support.
+       LOGD("%s:%d::Need to scale twice dsdx=%f, dtdy=%f,copybitsMaxScale=%f,copybitsMinScale=%f,screen_w=%d,screen_h=%d \
+                  src_crop_width=%d src_crop_height=%d",__FUNCTION__,__LINE__,
+                  dsdx,dtdy,copybitsMaxScale,1/copybitsMinScale,screen_w,screen_h,src_crop_width,src_crop_height);
+
+       //Driver makes width and height as even
+       //that may cause wrong calculation of the ratio
+       //in display and crop.Hence we make
+       //crop width and height as even.
+       src_crop_width  = (src_crop_width/2)*2;
+       src_crop_height = (src_crop_height/2)*2;
+
+       int tmp_w =  src_crop_width;
+       int tmp_h =  src_crop_height;
+
+       if (dsdx > copybitsMaxScale || dtdy > copybitsMaxScale ){
+         tmp_w = src_crop_width*copybitsMaxScale;
+         tmp_h = src_crop_height*copybitsMaxScale;
+       }else if (dsdx < 1/copybitsMinScale ||dtdy < 1/copybitsMinScale ){
+         tmp_w = src_crop_width/copybitsMinScale;
+         tmp_h = src_crop_height/copybitsMinScale;
+         tmp_w  = (tmp_w/2)*2;
+         tmp_h = (tmp_h/2)*2;
+       }
+       LOGD("%s:%d::tmp_w = %d,tmp_h = %d",__FUNCTION__,__LINE__,tmp_w,tmp_h);
+
+       int usage = GRALLOC_USAGE_PRIVATE_ADSP_HEAP |
+                   GRALLOC_USAGE_PRIVATE_MM_HEAP;
+
+       if (0 == alloc_buffer(&tmpHnd, tmp_w, tmp_h, fbHandle->format, usage)){
+            copybit_image_t tmp_dst;
+            copybit_rect_t tmp_rect;
+            tmp_dst.w = tmp_w;
+            tmp_dst.h = tmp_h;
+            tmp_dst.format = tmpHnd->format;
+            tmp_dst.handle = tmpHnd;
+            tmp_dst.horiz_padding = src.horiz_padding;
+            tmp_dst.vert_padding = src.vert_padding;
+            tmp_rect.l = 0;
+            tmp_rect.t = 0;
+            tmp_rect.r = tmp_dst.w;
+            tmp_rect.b = tmp_dst.h;
+            //create one clip region
+            hwc_rect tmp_hwc_rect = {0,0,tmp_rect.r,tmp_rect.b};
+            hwc_region_t tmp_hwc_reg = {1,(hwc_rect_t const*)&tmp_hwc_rect};
+            region_iterator tmp_it(tmp_hwc_reg);
+            copybit->set_parameter(copybit,COPYBIT_TRANSFORM,0);
+            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA,
+                        (layer->blending == HWC_BLENDING_NONE) ? -1 : layer->alpha);
+            err = copybit->stretch(copybit,&tmp_dst, &src, &tmp_rect, &srcRect, &tmp_it);
+            if(err < 0){
+                LOGE("%s:%d::tmp copybit stretch failed",__FUNCTION__,__LINE__);
+                if(tmpHnd)
+                    free_buffer(tmpHnd);
+                genlock_unlock_buffer(hnd);
+                return err;
+            }
+            // copy new src and src rect crop
+            src = tmp_dst;
+            srcRect = tmp_rect;
+      }
+    }
+    // Copybit region
+    hwc_region_t region = layer->visibleRegionScreen;
+    region_iterator copybitRegion(region);
+
+    copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_WIDTH, renderBuffer->width);
+    copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_HEIGHT, renderBuffer->height);
+    copybit->set_parameter(copybit, COPYBIT_TRANSFORM, layer->transform);
+    copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA,
+                           (layer->blending == HWC_BLENDING_NONE) ? -1 : layer->alpha);
+    copybit->set_parameter(copybit, COPYBIT_PREMULTIPLIED_ALPHA,
+                           (layer->blending == HWC_BLENDING_PREMULT)? COPYBIT_ENABLE : COPYBIT_DISABLE);
+    copybit->set_parameter(copybit, COPYBIT_DITHER,
+                            (dst.format == HAL_PIXEL_FORMAT_RGB_565)? COPYBIT_ENABLE : COPYBIT_DISABLE);
+    err = copybit->stretch(copybit, &dst, &src, &dstRect, &srcRect, &copybitRegion);
+
+    if(tmpHnd)
+        free_buffer(tmpHnd);
+
+    if(err < 0)
+        LOGE("%s: copybit stretch failed",__FUNCTION__);
+
+    // Unlock this buffer since copybit is done with it.
+    err = genlock_unlock_buffer(hnd);
+    if (GENLOCK_FAILURE == err) {
+        LOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
+    }
+
+    return err;
+}
+
+static int drawLayerUsingOverlay(hwc_context_t *ctx, hwc_layer_t *layer)
+{
+    if (ctx && ctx->mOverlayLibObject) {
+        private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(ctx->device.common.module);
+        if (!hwcModule) {
+            LOGE("drawLayerUsingLayer null module ");
+            return -1;
+        }
+        private_handle_t *hnd = (private_handle_t *)layer->handle;
+        overlay::Overlay *ovLibObject = ctx->mOverlayLibObject;
+        int ret = 0;
+
+        // Lock this buffer for read.
+        if (GENLOCK_NO_ERROR != genlock_lock_buffer(hnd, GENLOCK_READ_LOCK,
+                                                    GENLOCK_MAX_TIMEOUT)) {
+            LOGE("%s: genlock_lock_buffer(READ) failed", __FUNCTION__);
+            return -1;
+        }
+
+        ret = ovLibObject->queueBuffer(hnd);
+
+        // Unlock the previously locked buffer, since the overlay has completed reading the buffer
+        unlockPreviousOverlayBuffer(ctx);
+
+        if (!ret) {
+            LOGE("drawLayerUsingOverlay queueBuffer failed");
+            // Unlock the buffer handle
+            genlock_unlock_buffer(hnd);
+            ctx->previousOverlayHandle = NULL;
+        } else {
+            // Store the current buffer handle as the one that is to be unlocked after
+            // the next overlay play call.
+            ctx->previousOverlayHandle = hnd;
+            hnd->flags |= private_handle_t::PRIV_FLAGS_HWC_LOCK;
+        }
+
+        return ret;
+    }
+    return -1;
+}
+
+#ifdef COMPOSITION_BYPASS
+static int drawLayerUsingBypass(hwc_context_t *ctx, hwc_layer_t *layer, int layer_index) {
+
+    int index = getLayerbypassIndex(layer);
+
+    if(index < 0) {
+        LOGE("%s: Invalid bypass index (%d)", __FUNCTION__, index);
+        return -1;
+    }
+
+    if (ctx && ctx->mOvUI[index]) {
+        overlay::OverlayUI *ovUI = ctx->mOvUI[index];
+        int ret = 0;
+
+        private_handle_t *hnd = (private_handle_t *)layer->handle;
+        if(!hnd) {
+            LOGE("%s handle null", __FUNCTION__);
+            return -1;
+        }
+
+        ctx->bypassBufferLockState[index] = BYPASS_BUFFER_UNLOCKED;
+
+        if (GENLOCK_FAILURE == genlock_lock_buffer(hnd, GENLOCK_READ_LOCK,
+                                                   GENLOCK_MAX_TIMEOUT)) {
+            LOGE("%s: genlock_lock_buffer(READ) failed", __FUNCTION__);
+            return -1;
+        }
+
+        ctx->bypassBufferLockState[index] = BYPASS_BUFFER_LOCKED;
+
+        LOGE_IF(BYPASS_DEBUG,"%s: Bypassing layer: %p using pipe: %d",__FUNCTION__, layer, index );
+
+        ret = ovUI->queueBuffer(hnd);
+
+        if (ret) {
+            // Unlock the locked buffer
+            if (GENLOCK_FAILURE == genlock_unlock_buffer(hnd)) {
+                LOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
+            }
+            ctx->bypassBufferLockState[index] = BYPASS_BUFFER_UNLOCKED;
+            return -1;
+        }
+    }
+    return 0;
+}
+#endif
+
+static int hwc_set(hwc_composer_device_t *dev,
+        hwc_display_t dpy,
+        hwc_surface_t sur,
+        hwc_layer_list_t* list)
+{
+    hwc_context_t* ctx = (hwc_context_t*)(dev);
+    if(!ctx) {
+        LOGE("hwc_set invalid context");
+        ExtDispOnly::close();
+        return -1;
+    }
+
+    private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(
+                                                           dev->common.module);
+    if (!hwcModule) {
+        LOGE("hwc_set invalid module");
+#ifdef COMPOSITION_BYPASS
+        unlockPreviousBypassBuffers(ctx);
+        unsetBypassBufferLockState(ctx);
+#endif
+        ExtDispOnly::close();
+        unlockPreviousOverlayBuffer(ctx);
+        return -1;
+    }
+
+    int ret = 0;
+    if (list) {
+        bool bDumpLayers = needToDumpLayers(); // Check need for debugging dumps
+        for (size_t i=0; i<list->numHwLayers; i++) {
+            if (bDumpLayers)
+                dumpLayer(hwcModule->compositionType, list->flags, i, list->hwLayers);
+            if (list->hwLayers[i].flags & HWC_SKIP_LAYER) {
+                continue;
+            } else if(list->hwLayers[i].flags & HWC_USE_EXT_ONLY) {
+                continue;
+            //Draw after layers for primary are drawn
+#ifdef COMPOSITION_BYPASS
+            } else if (list->hwLayers[i].flags & HWC_COMP_BYPASS) {
+                drawLayerUsingBypass(ctx, &(list->hwLayers[i]), i);
+#endif
+            } else if (list->hwLayers[i].compositionType == HWC_USE_OVERLAY) {
+                drawLayerUsingOverlay(ctx, &(list->hwLayers[i]));
+            } else if (list->flags & HWC_SKIP_COMPOSITION) {
+// LGE_CHANGE_S, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents { 
+            //break;
+                continue;
+// LGE_CHANGE_E, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents }
+            } else if (list->hwLayers[i].compositionType == HWC_USE_COPYBIT) {
+            drawLayerUsingCopybit(dev, &(list->hwLayers[i]), (EGLDisplay)dpy, (EGLSurface)sur);
+            }
+        } 
+    } else {
+        //Device in suspended state. Close all the MDP pipes
+#ifdef COMPOSITION_BYPASS
+        ctx->nPipesUsed = 0;
+#endif
+        ctx->hwcOverlayStatus =  HWC_OVERLAY_PREPARE_TO_CLOSE;
+    }
+
+    bool canSkipComposition = list && list->flags & HWC_SKIP_COMPOSITION;
+    //Draw External-only layers
+    if(ExtDispOnly::draw(ctx, list) != overlay::NO_ERROR) {
+        ExtDispOnly::close();
+    }
+
+#ifdef COMPOSITION_BYPASS
+    unlockPreviousBypassBuffers(ctx);
+    storeLockedBypassHandle(list, ctx);
+    // We have stored the handles, unset the current lock states in the context.
+    unsetBypassBufferLockState(ctx);
+    closeExtraPipes(ctx);
+#if BYPASS_DEBUG
+    if(canSkipComposition)
+        LOGE("%s: skipping eglSwapBuffer call", __FUNCTION__);
+#endif
+#endif
+    // Do not call eglSwapBuffers if we the skip composition flag is set on the list.
+    if (dpy && sur && !canSkipComposition) {
+        EGLBoolean sucess = eglSwapBuffers((EGLDisplay)dpy, (EGLSurface)sur);
+        if (!sucess) {
+            ret = HWC_EGL_ERROR;
+        } else {
+            CALC_FPS();
+        }
+    }
+#if defined HDMI_DUAL_DISPLAY
+    if(ctx->pendingHDMI) {
+        handleHDMIStateChange(dev, ctx->mHDMIEnabled);
+        ctx->pendingHDMI = false;
+    }
+#endif
+
+    hwc_closeOverlayChannels(ctx);
+    int yuvBufferCount = getYUVBufferCount(list);
+    setHWCOverlayStatus(ctx, yuvBufferCount);
+
+    return ret;
+}
+
+static int hwc_device_close(struct hw_device_t *dev)
+{
+    if(!dev) {
+        LOGE("hwc_device_close null device pointer");
+        return -1;
+    }
+
+    struct hwc_context_t* ctx = (struct hwc_context_t*)dev;
+
+    private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(
+            ctx->device.common.module);
+    // Close the overlay and copybit modules
+    if(hwcModule->copybitEngine) {
+        copybit_close(hwcModule->copybitEngine);
+        hwcModule->copybitEngine = NULL;
+    }
+    if(hwcModule->fbDevice) {
+        framebuffer_close(hwcModule->fbDevice);
+        hwcModule->fbDevice = NULL;
+    }
+
+    unlockPreviousOverlayBuffer(ctx);
+
+    if (ctx) {
+         delete ctx->mOverlayLibObject;
+         ctx->mOverlayLibObject = NULL;
+#ifdef COMPOSITION_BYPASS
+            for(int i = 0; i < MAX_BYPASS_LAYERS; i++) {
+                delete ctx->mOvUI[i];
+            }
+            unlockPreviousBypassBuffers(ctx);
+            unsetBypassBufferLockState(ctx);
+#endif
+        ExtDispOnly::close();
+        ExtDispOnly::destroy();
+
+        free(ctx);
+    }
+    return 0;
+}
+
+/*****************************************************************************/
+static int hwc_module_initialize(struct private_hwc_module_t* hwcModule)
+{
+
+    // Open the overlay and copybit modules
+    hw_module_t const *module;
+    if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
+        copybit_open(module, &(hwcModule->copybitEngine));
+    }
+    if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
+        framebuffer_open(module, &(hwcModule->fbDevice));
+    }
+
+    // get the current composition type
+    char property[PROPERTY_VALUE_MAX];
+    if (property_get("debug.sf.hw", property, NULL) > 0) {
+        if(atoi(property) == 0) {
+            //debug.sf.hw = 0
+            hwcModule->compositionType = COMPOSITION_TYPE_CPU;
+        } else { //debug.sf.hw = 1
+            // Get the composition type
+            property_get("debug.composition.type", property, NULL);
+            if (property == NULL) {
+                hwcModule->compositionType = COMPOSITION_TYPE_GPU;
+            } else if ((strncmp(property, "mdp", 3)) == 0) {
+                hwcModule->compositionType = COMPOSITION_TYPE_MDP;
+            } else if ((strncmp(property, "c2d", 3)) == 0) {
+                hwcModule->compositionType = COMPOSITION_TYPE_C2D;
+            } else if ((strncmp(property, "dyn", 3)) == 0) {
+                hwcModule->compositionType = COMPOSITION_TYPE_DYN;
+            } else {
+                hwcModule->compositionType = COMPOSITION_TYPE_GPU;
+            }
+
+            if(!hwcModule->copybitEngine)
+                hwcModule->compositionType = COMPOSITION_TYPE_GPU;
+        }
+    } else { //debug.sf.hw is not set. Use cpu composition
+        hwcModule->compositionType = COMPOSITION_TYPE_CPU;
+    }
+
+    //Check if composition bypass is enabled
+    if(property_get("ro.sf.compbypass.enable", property, NULL) > 0) {
+        if(atoi(property) == 1) {
+            hwcModule->isBypassEnabled = true;
+        }
+    }
+
+    CALC_INIT();
+
+    return 0;
+}
+
+
+static int hwc_device_open(const struct hw_module_t* module, const char* name,
+        struct hw_device_t** device)
+{
+    int status = -EINVAL;
+
+    if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
+        private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>
+                                        (const_cast<hw_module_t*>(module));
+        hwc_module_initialize(hwcModule);
+        struct hwc_context_t *dev;
+        dev = (hwc_context_t*)malloc(sizeof(*dev));
+
+        /* initialize our state here */
+        memset(dev, 0, sizeof(*dev));
+#ifdef USE_OVERLAY
+        dev->mOverlayLibObject = new overlay::Overlay();
+        if(overlay::initOverlay() == -1)
+            LOGE("overlay::initOverlay() ERROR!!");
+#else
+        dev->mOverlayLibObject = NULL;
+#endif
+#ifdef COMPOSITION_BYPASS
+        for(int i = 0; i < MAX_BYPASS_LAYERS; i++) {
+            dev->mOvUI[i] = new overlay::OverlayUI();
+            dev->previousBypassHandle[i] = NULL;
+        }
+        unsetBypassBufferLockState(dev);
+        dev->bypassState = BYPASS_OFF;
+#endif
+        ExtDispOnly::init();
+#if defined HDMI_DUAL_DISPLAY
+        dev->mHDMIEnabled = EXT_DISPLAY_OFF;
+        dev->pendingHDMI = false;
+#endif
+        dev->previousOverlayHandle = NULL;
+        dev->hwcOverlayStatus = HWC_OVERLAY_CLOSED;
+        dev->previousLayerCount = -1;
+        /* initialize the procs */
+        dev->device.common.tag = HARDWARE_DEVICE_TAG;
+        dev->device.common.version = 0;
+        dev->device.common.module = const_cast<hw_module_t*>(module);
+        dev->device.common.close = hwc_device_close;
+
+        dev->device.prepare = hwc_prepare;
+        dev->device.set = hwc_set;
+        dev->device.enableHDMIOutput = hwc_enableHDMIOutput;
+        *device = &dev->device.common;
+
+        status = 0;
+    }
+    return status;
+}
