diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..127a6de
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,11 @@
+#Enables the listed display HAL modules
+
+#Libs to be built for all targets (including SDK)
+display-hals := libqcomui
+
+#libs to be built for QCOM targets only
+#ifeq ($(call is-vendor-board-platform,QCOM),true)
+display-hals += libgralloc libgenlock libcopybit
+#endif
+
+include $(call all-named-subdir-makefiles,$(display-hals))
diff --git a/libgenlock/Android.mk b/libgenlock/Android.mk
new file mode 100644
index 0000000..740d6ce
--- /dev/null
+++ b/libgenlock/Android.mk
@@ -0,0 +1,15 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)
+LOCAL_SHARED_LIBRARIES := liblog libcutils
+LOCAL_C_INCLUDES :=
+LOCAL_C_INCLUDES += hardware/qcom/display/libgralloc
+LOCAL_ADDITIONAL_DEPENDENCIES :=
+LOCAL_SRC_FILES := genlock.cpp
+LOCAL_CFLAGS:= -DLOG_TAG=\"libgenlock\"
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libgenlock
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/libgenlock/genlock.cpp b/libgenlock/genlock.cpp
new file mode 100644
index 0000000..5d5536b
--- /dev/null
+++ b/libgenlock/genlock.cpp
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <cutils/log.h>
+#include <cutils/native_handle.h>
+#include <gralloc_priv.h>
+#include <linux/genlock.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#include "genlock.h"
+
+#define GENLOCK_DEVICE "/dev/genlock"
+
+#ifndef USE_GENLOCK
+#define USE_GENLOCK
+#endif
+
+namespace {
+    /* Internal function to map the userspace locks to the kernel lock types */
+    int get_kernel_lock_type(genlock_lock_type lockType)
+    {
+        int kLockType = 0;
+        // If the user sets both a read and write lock, higher preference is
+        // given to the write lock.
+        if (lockType & GENLOCK_WRITE_LOCK) {
+            kLockType = GENLOCK_WRLOCK;
+        } else if (lockType & GENLOCK_READ_LOCK) {
+            kLockType = GENLOCK_RDLOCK;
+        } else {
+            ALOGE("%s: invalid lockType (lockType = %d)", __FUNCTION__, lockType);
+            return -1;
+        }
+        return kLockType;
+    }
+
+    /* Internal function to perform the actual lock/unlock operations */
+    genlock_status_t perform_lock_unlock_operation(native_handle_t *buffer_handle,
+            int lockType, int timeout)
+    {
+        if (private_handle_t::validate(buffer_handle)) {
+            ALOGE("%s: handle is invalid", __FUNCTION__);
+            return GENLOCK_FAILURE;
+        }
+
+        private_handle_t *hnd = reinterpret_cast<private_handle_t*>(buffer_handle);
+        if ((hnd->flags & private_handle_t::PRIV_FLAGS_UNSYNCHRONIZED) == 0) {
+            if (hnd->genlockPrivFd < 0) {
+                ALOGE("%s: the lock has not been created, or has not been attached",
+                        __FUNCTION__);
+                return GENLOCK_FAILURE;
+            }
+
+            genlock_lock lock;
+            lock.op = lockType;
+            lock.flags = 0;
+            lock.timeout = timeout;
+            lock.fd = hnd->genlockHandle;
+
+            if (ioctl(hnd->genlockPrivFd, GENLOCK_IOC_LOCK, &lock)) {
+                ALOGE("%s: GENLOCK_IOC_LOCK failed (lockType0x%x, err=%s fd=%d)", __FUNCTION__,
+                        lockType, strerror(errno), hnd->fd);
+                if (ETIMEDOUT == errno)
+                    return GENLOCK_TIMEDOUT;
+
+                return GENLOCK_FAILURE;
+            }
+        }
+        return GENLOCK_NO_ERROR;
+    }
+
+    /* Internal function to close the fd and release the handle */
+    void close_genlock_fd_and_handle(int& fd, int& handle)
+    {
+        if (fd >=0 ) {
+            close(fd);
+            fd = -1;
+        }
+
+        if (handle >= 0) {
+            close(handle);
+            handle = -1;
+        }
+    }
+
+}
+/*
+ * Create a genlock lock. The genlock lock file descriptor and the lock
+ * handle are stored in the buffer_handle.
+ *
+ * @param: handle of the buffer
+ * @return error status.
+ */
+genlock_status_t genlock_create_lock(native_handle_t *buffer_handle)
+{
+    genlock_status_t ret = GENLOCK_NO_ERROR;
+    if (private_handle_t::validate(buffer_handle)) {
+        ALOGE("%s: handle is invalid", __FUNCTION__);
+        return GENLOCK_FAILURE;
+    }
+
+    private_handle_t *hnd = reinterpret_cast<private_handle_t*>(buffer_handle);
+#ifdef USE_GENLOCK
+    if ((hnd->flags & private_handle_t::PRIV_FLAGS_UNSYNCHRONIZED) == 0) {
+        // Open the genlock device
+        int fd = open(GENLOCK_DEVICE, O_RDWR);
+        if (fd < 0) {
+            ALOGE("%s: open genlock device failed (err=%s)", __FUNCTION__,
+                    strerror(errno));
+            return GENLOCK_FAILURE;
+        }
+
+        // Create a new lock
+        genlock_lock lock;
+        if (ioctl(fd, GENLOCK_IOC_NEW, NULL)) {
+            ALOGE("%s: GENLOCK_IOC_NEW failed (error=%s)", __FUNCTION__,
+                    strerror(errno));
+            close_genlock_fd_and_handle(fd, lock.fd);
+            ret = GENLOCK_FAILURE;
+        }
+
+        // Export the lock for other processes to be able to use it.
+        if (GENLOCK_FAILURE != ret) {
+            if (ioctl(fd, GENLOCK_IOC_EXPORT, &lock)) {
+                ALOGE("%s: GENLOCK_IOC_EXPORT failed (error=%s)", __FUNCTION__,
+                        strerror(errno));
+                close_genlock_fd_and_handle(fd, lock.fd);
+                ret = GENLOCK_FAILURE;
+            }
+        }
+
+        // Store the lock params in the handle.
+        hnd->genlockPrivFd = fd;
+        hnd->genlockHandle = lock.fd;
+    } else {
+        hnd->genlockHandle = 0;
+    }
+#else
+    hnd->genlockHandle = 0;
+#endif
+    return ret;
+}
+
+
+/*
+ * Release a genlock lock associated with the handle.
+ *
+ * @param: handle of the buffer
+ * @return error status.
+ */
+genlock_status_t genlock_release_lock(native_handle_t *buffer_handle)
+{
+    genlock_status_t ret = GENLOCK_NO_ERROR;
+#ifdef USE_GENLOCK
+    if (private_handle_t::validate(buffer_handle)) {
+        ALOGE("%s: handle is invalid", __FUNCTION__);
+        return GENLOCK_FAILURE;
+    }
+
+    private_handle_t *hnd = reinterpret_cast<private_handle_t*>(buffer_handle);
+    if ((hnd->flags & private_handle_t::PRIV_FLAGS_UNSYNCHRONIZED) == 0) {
+        if (hnd->genlockPrivFd < 0) {
+            ALOGE("%s: the lock is invalid", __FUNCTION__);
+            return GENLOCK_FAILURE;
+        }
+
+        // Close the fd and reset the parameters.
+        close_genlock_fd_and_handle(hnd->genlockPrivFd, hnd->genlockHandle);
+    }
+#endif
+    return ret;
+}
+
+
+/*
+ * Attach a lock to the buffer handle passed via an IPC.
+ *
+ * @param: handle of the buffer
+ * @return error status.
+ */
+genlock_status_t genlock_attach_lock(native_handle_t *buffer_handle)
+{
+    genlock_status_t ret = GENLOCK_NO_ERROR;
+#ifdef USE_GENLOCK
+    if (private_handle_t::validate(buffer_handle)) {
+        ALOGE("%s: handle is invalid", __FUNCTION__);
+        return GENLOCK_FAILURE;
+    }
+
+    private_handle_t *hnd = reinterpret_cast<private_handle_t*>(buffer_handle);
+    if ((hnd->flags & private_handle_t::PRIV_FLAGS_UNSYNCHRONIZED) == 0) {
+        // Open the genlock device
+        int fd = open(GENLOCK_DEVICE, O_RDWR);
+        if (fd < 0) {
+            ALOGE("%s: open genlock device failed (err=%s)", __FUNCTION__,
+                    strerror(errno));
+            return GENLOCK_FAILURE;
+        }
+
+        // Attach the local handle to an existing lock
+        genlock_lock lock;
+        lock.fd = hnd->genlockHandle;
+        if (ioctl(fd, GENLOCK_IOC_ATTACH, &lock)) {
+            ALOGE("%s: GENLOCK_IOC_ATTACH failed (err=%s)", __FUNCTION__,
+                    strerror(errno));
+            close_genlock_fd_and_handle(fd, lock.fd);
+            ret = GENLOCK_FAILURE;
+        }
+
+        // Store the relavant information in the handle
+        hnd->genlockPrivFd = fd;
+    }
+#endif
+    return ret;
+}
+
+/*
+ * Lock the buffer specified by the buffer handle. The lock held by the buffer
+ * is specified by the lockType. This function will block if a write lock is
+ * requested on the buffer which has previously been locked for a read or write
+ * operation. A buffer can be locked by multiple clients for read. An optional
+ * timeout value can be specified. By default, there is no timeout.
+ *
+ * @param: handle of the buffer
+ * @param: type of lock to be acquired by the buffer.
+ * @param: timeout value in ms. GENLOCK_MAX_TIMEOUT is the maximum timeout value.
+ * @return error status.
+ */
+genlock_status_t genlock_lock_buffer(native_handle_t *buffer_handle,
+        genlock_lock_type_t lockType,
+        int timeout)
+{
+    genlock_status_t ret = GENLOCK_NO_ERROR;
+#ifdef USE_GENLOCK
+    // Translate the locktype
+    int kLockType = get_kernel_lock_type(lockType);
+    if (-1 == kLockType) {
+        ALOGE("%s: invalid lockType", __FUNCTION__);
+        return GENLOCK_FAILURE;
+    }
+
+    if (0 == timeout) {
+        ALOGW("%s: trying to lock a buffer with timeout = 0", __FUNCTION__);
+    }
+    // Call the private function to perform the lock operation specified.
+    ret = perform_lock_unlock_operation(buffer_handle, kLockType, timeout);
+#endif
+    return ret;
+}
+
+
+/*
+ * Unlocks a buffer that has previously been locked by the client.
+ *
+ * @param: handle of the buffer to be unlocked.
+ * @return: error status.
+*/
+genlock_status_t genlock_unlock_buffer(native_handle_t *buffer_handle)
+{
+    genlock_status_t ret = GENLOCK_NO_ERROR;
+#ifdef USE_GENLOCK
+    // Do the unlock operation by setting the unlock flag. Timeout is always
+    // 0 in this case.
+    ret = perform_lock_unlock_operation(buffer_handle, GENLOCK_UNLOCK, 0);
+#endif
+    return ret;
+}
+
+/*
+ * Blocks the calling process until the lock held on the handle is unlocked.
+ *
+ * @param: handle of the buffer
+ * @param: timeout value for the wait.
+ * return: error status.
+ */
+genlock_status_t genlock_wait(native_handle_t *buffer_handle, int timeout) {
+#ifdef USE_GENLOCK
+    if (private_handle_t::validate(buffer_handle)) {
+        ALOGE("%s: handle is invalid", __FUNCTION__);
+        return GENLOCK_FAILURE;
+    }
+
+    private_handle_t *hnd = reinterpret_cast<private_handle_t*>(buffer_handle);
+    if ((hnd->flags & private_handle_t::PRIV_FLAGS_UNSYNCHRONIZED) == 0) {
+        if (hnd->genlockPrivFd < 0) {
+            ALOGE("%s: the lock is invalid", __FUNCTION__);
+            return GENLOCK_FAILURE;
+        }
+
+        if (0 == timeout)
+            ALOGW("%s: timeout = 0", __FUNCTION__);
+
+        genlock_lock lock;
+        lock.fd = hnd->genlockHandle;
+        lock.timeout = timeout;
+        if (ioctl(hnd->genlockPrivFd, GENLOCK_IOC_WAIT, &lock)) {
+            ALOGE("%s: GENLOCK_IOC_WAIT failed (err=%s)",  __FUNCTION__, strerror(errno));
+            return GENLOCK_FAILURE;
+        }
+    }
+#endif
+    return GENLOCK_NO_ERROR;
+}
diff --git a/libgenlock/genlock.h b/libgenlock/genlock.h
new file mode 100644
index 0000000..b394410
--- /dev/null
+++ b/libgenlock/genlock.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef INCLUDE_LIBGENLOCK
+#define INCLUDE_LIBGENLOCK
+
+#include <cutils/native_handle.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Genlock lock types */
+typedef enum genlock_lock_type{
+    GENLOCK_READ_LOCK  = 1<<0,  // Read lock
+    GENLOCK_WRITE_LOCK = 1<<1,  // Write lock
+}genlock_lock_type_t;
+
+/* Genlock return values */
+typedef enum genlock_status{
+    GENLOCK_NO_ERROR = 0,
+    GENLOCK_TIMEDOUT,
+    GENLOCK_FAILURE,
+} genlock_status_t;
+
+/* Genlock defines */
+#define GENLOCK_MAX_TIMEOUT 1000 // Max 1s timeout
+
+/*
+ * Create a genlock lock. The genlock lock file descriptor and the lock
+ * handle are stored in the buffer_handle.
+ *
+ * @param: handle of the buffer
+ * @return error status.
+ */
+genlock_status_t genlock_create_lock(native_handle_t *buffer_handle);
+
+
+/*
+ * Release a genlock lock associated with the handle.
+ *
+ * @param: handle of the buffer
+ * @return error status.
+ */
+genlock_status_t genlock_release_lock(native_handle_t *buffer_handle);
+
+/*
+ * Attach a lock to the buffer handle passed via an IPC.
+ *
+ * @param: handle of the buffer
+ * @return error status.
+ */
+genlock_status_t genlock_attach_lock(native_handle_t *buffer_handle);
+
+/*
+ * Lock the buffer specified by the buffer handle. The lock held by the buffer
+ * is specified by the lockType. This function will block if a write lock is
+ * requested on the buffer which has previously been locked for a read or write
+ * operation. A buffer can be locked by multiple clients for read. An optional
+ * timeout value can be specified. By default, there is no timeout.
+ *
+ * @param: handle of the buffer
+ * @param: type of lock to be acquired by the buffer.
+ * @param: timeout value in ms. GENLOCK_MAX_TIMEOUT is the maximum timeout value.
+ * @return error status.
+ */
+genlock_status_t genlock_lock_buffer(native_handle_t *buffer_handle,
+                                     genlock_lock_type_t lockType,
+                                     int timeout);
+
+/*
+ * Unlocks a buffer that has previously been locked by the client.
+ *
+ * @param: handle of the buffer to be unlocked.
+ * @return: error status.
+*/
+genlock_status_t genlock_unlock_buffer(native_handle_t *buffer_handle);
+
+/*
+ * Blocks the calling process until the lock held on the handle is unlocked.
+ *
+ * @param: handle of the buffer
+ * @param: timeout value for the wait.
+ * return: error status.
+ */
+genlock_status_t genlock_wait(native_handle_t *buffer_handle, int timeout);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libgralloc/Android.mk b/libgralloc/Android.mk
new file mode 100644
index 0000000..5377d86
--- /dev/null
+++ b/libgralloc/Android.mk
@@ -0,0 +1,75 @@
+# Copyright (C) 2008 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.
+
+# Use this flag until pmem/ashmem is implemented in the new gralloc
+LOCAL_PATH := $(call my-dir)
+
+# HAL module implemenation, not prelinked and stored in
+# hw/<OVERLAY_HARDWARE_MODULE_ID>.<ro.product.board>.so
+include $(CLEAR_VARS)
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+LOCAL_SHARED_LIBRARIES := liblog libcutils libGLESv1_CM libutils libmemalloc libQcomUI
+LOCAL_SHARED_LIBRARIES += libgenlock
+
+LOCAL_C_INCLUDES += hardware/qcom/display/libgenlock
+LOCAL_C_INCLUDES += hardware/qcom/display/libqcomui
+LOCAL_ADDITIONAL_DEPENDENCIES +=
+LOCAL_SRC_FILES :=  framebuffer.cpp \
+                    gpu.cpp         \
+                    gralloc.cpp     \
+                    mapper.cpp
+
+LOCAL_MODULE := gralloc.$(TARGET_BOARD_PLATFORM)
+LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS:= -DLOG_TAG=\"$(TARGET_BOARD_PLATFORM).gralloc\" -DHOST -DDEBUG_CALC_FPS
+
+ifeq ($(call is-board-platform,msm7627_surf msm7627_6x),true)
+    LOCAL_CFLAGS += -DTARGET_MSM7x27
+endif
+
+ifeq ($(TARGET_HAVE_HDMI_OUT),true)
+    LOCAL_CFLAGS += -DHDMI_DUAL_DISPLAY
+    LOCAL_C_INCLUDES += hardware/qcom/display/liboverlay
+    LOCAL_SHARED_LIBRARIES += liboverlay
+endif
+
+ifeq ($(TARGET_USES_SF_BYPASS),true)
+    LOCAL_CFLAGS += -DSF_BYPASS
+endif
+
+ifeq ($(TARGET_GRALLOC_USES_ASHMEM),true)
+    LOCAL_CFLAGS += -DUSE_ASHMEM
+endif
+
+include $(BUILD_SHARED_LIBRARY)
+
+#MemAlloc Library
+include $(CLEAR_VARS)
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)
+LOCAL_C_INCLUDES += hardware/qcom/display/libqcomui
+LOCAL_ADDITIONAL_DEPENDENCIES +=
+LOCAL_SHARED_LIBRARIES := liblog libcutils libutils
+LOCAL_SRC_FILES :=  ionalloc.cpp \
+                    alloc_controller.cpp
+LOCAL_CFLAGS:= -DLOG_TAG=\"memalloc\"
+
+ifeq ($(TARGET_USES_ION),true)
+    LOCAL_CFLAGS += -DUSE_ION
+endif
+
+LOCAL_MODULE := libmemalloc
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_SHARED_LIBRARY)
diff --git a/libgralloc/MODULE_LICENSE_APACHE2 b/libgralloc/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libgralloc/MODULE_LICENSE_APACHE2
diff --git a/libgralloc/NOTICE b/libgralloc/NOTICE
new file mode 100644
index 0000000..3237da6
--- /dev/null
+++ b/libgralloc/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2008-2009, 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.
+
+   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.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
new file mode 100644
index 0000000..47cdc68
--- /dev/null
+++ b/libgralloc/alloc_controller.cpp
@@ -0,0 +1,438 @@
+/*
+ * Copyright (c) 2011-2012, Code Aurora Forum. 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 Code Aurora Forum, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <cutils/log.h>
+#include <utils/RefBase.h>
+#include <fcntl.h>
+#include "gralloc_priv.h"
+#include "alloc_controller.h"
+#include "memalloc.h"
+#include "ionalloc.h"
+#include "ashmemalloc.h"
+#include "gr.h"
+
+using namespace gralloc;
+using android::sp;
+
+const int GRALLOC_HEAP_MASK = GRALLOC_USAGE_PRIVATE_ADSP_HEAP      |
+                              GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP |
+                              GRALLOC_USAGE_PRIVATE_SMI_HEAP       |
+                              GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP    |
+                              GRALLOC_USAGE_PRIVATE_IOMMU_HEAP     |
+                              GRALLOC_USAGE_PRIVATE_MM_HEAP        |
+                              GRALLOC_USAGE_PRIVATE_WRITEBACK_HEAP |
+                              GRALLOC_USAGE_PRIVATE_CAMERA_HEAP;
+
+
+//Common functions
+static bool canFallback(int compositionType, int usage, bool triedSystem)
+{
+    // Fallback to system heap when alloc fails unless
+    // 1. Composition type is MDP
+    // 2. Alloc from system heap was already tried
+    // 3. The heap type is requsted explicitly
+    // 4. The heap type is protected
+    // 5. The buffer is meant for external display only
+
+    if(compositionType == MDP_COMPOSITION)
+        return false;
+    if(triedSystem)
+        return false;
+    if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PROTECTED))
+        return false;
+    if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_EXTERNAL_ONLY))
+        return false;
+    //Return true by default
+    return true;
+}
+
+static bool useUncached(int usage)
+{
+    // System heaps cannot be uncached
+    if(usage & (GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP |
+                GRALLOC_USAGE_PRIVATE_IOMMU_HEAP))
+        return false;
+    if (usage & GRALLOC_USAGE_PRIVATE_UNCACHED)
+        return true;
+    return false;
+}
+
+sp<IAllocController> IAllocController::sController = NULL;
+sp<IAllocController> IAllocController::getInstance(bool useMasterHeap)
+{
+    if(sController == NULL) {
+#ifdef USE_ION
+        sController = new IonController();
+#else
+        if(useMasterHeap)
+            sController = new PmemAshmemController();
+        else
+            sController = new PmemKernelController();
+#endif
+    }
+    return sController;
+}
+
+
+//-------------- IonController-----------------------//
+IonController::IonController()
+{
+    mIonAlloc = new IonAlloc();
+}
+
+int IonController::allocate(alloc_data& data, int usage,
+        int compositionType)
+{
+    int ionFlags = 0;
+    int ret;
+    bool noncontig = false;
+
+    data.uncached = useUncached(usage);
+    if(usage & GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP)
+        ionFlags |= ION_HEAP(ION_SF_HEAP_ID);
+
+    if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP) {
+        ionFlags |= ION_HEAP(ION_SYSTEM_HEAP_ID);
+        noncontig = true;
+    }
+
+    if(usage & GRALLOC_USAGE_PRIVATE_IOMMU_HEAP)
+        ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
+
+    if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP)
+        ionFlags |= ION_HEAP(ION_CP_MM_HEAP_ID);
+
+    if(usage & GRALLOC_USAGE_PRIVATE_WRITEBACK_HEAP)
+        ionFlags |= ION_HEAP(ION_CP_WB_HEAP_ID);
+
+    if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
+        ionFlags |= ION_HEAP(ION_CAMERA_HEAP_ID);
+
+    if(usage & GRALLOC_USAGE_PROTECTED)
+        ionFlags |= ION_SECURE;
+
+    if(usage & GRALLOC_USAGE_PRIVATE_DO_NOT_MAP)
+        data.allocType  =  private_handle_t::PRIV_FLAGS_NOT_MAPPED;
+
+    // if no flags are set, default to
+    // SF + IOMMU heaps, so that bypass can work
+    // we can fall back to system heap if
+    // we run out.
+    if(!ionFlags)
+        ionFlags = ION_HEAP(ION_SF_HEAP_ID) | ION_HEAP(ION_IOMMU_HEAP_ID);
+
+    data.flags = ionFlags;
+    ret = mIonAlloc->alloc_buffer(data);
+    // Fallback
+    if(ret < 0 && canFallback(compositionType,
+                              usage,
+                              (ionFlags & ION_SYSTEM_HEAP_ID)))
+    {
+        ALOGW("Falling back to system heap");
+        data.flags = ION_HEAP(ION_SYSTEM_HEAP_ID);
+        noncontig = true;
+        ret = mIonAlloc->alloc_buffer(data);
+    }
+
+    if(ret >= 0 ) {
+        data.allocType = private_handle_t::PRIV_FLAGS_USES_ION;
+        if(noncontig)
+            data.allocType |= private_handle_t::PRIV_FLAGS_NONCONTIGUOUS_MEM;
+        if(ionFlags & ION_SECURE)
+            data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
+    }
+
+    return ret;
+}
+
+sp<IMemAlloc> IonController::getAllocator(int flags)
+{
+    sp<IMemAlloc> memalloc;
+    if (flags & private_handle_t::PRIV_FLAGS_USES_ION) {
+        memalloc = mIonAlloc;
+    } else {
+        ALOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags);
+    }
+
+    return memalloc;
+}
+
+#if 0
+//-------------- PmemKernelController-----------------------//
+
+PmemKernelController::PmemKernelController()
+{
+     mPmemAdspAlloc = new PmemKernelAlloc(DEVICE_PMEM_ADSP);
+     // XXX: Right now, there is no need to maintain an instance
+     // of the SMI allocator as we need it only in a few cases
+}
+
+PmemKernelController::~PmemKernelController()
+{
+}
+
+int PmemKernelController::allocate(alloc_data& data, int usage,
+        int compositionType)
+{
+    int ret = 0;
+    bool adspFallback = false;
+    if (!(usage & GRALLOC_USAGE_PRIVATE_SMI_HEAP))
+        adspFallback = true;
+
+    // Try SMI first
+    if ((usage & GRALLOC_USAGE_PRIVATE_SMI_HEAP) ||
+        (usage & GRALLOC_USAGE_EXTERNAL_DISP)    ||
+        (usage & GRALLOC_USAGE_PROTECTED))
+    {
+        int tempFd = open(DEVICE_PMEM_SMIPOOL, O_RDWR, 0);
+        if(tempFd > 0) {
+            close(tempFd);
+            sp<IMemAlloc> memalloc;
+            memalloc = new PmemKernelAlloc(DEVICE_PMEM_SMIPOOL);
+            ret = memalloc->alloc_buffer(data);
+            if(ret >= 0)
+                return ret;
+            else {
+                if(adspFallback)
+                    ALOGW("Allocation from SMI failed, trying ADSP");
+            }
+        }
+    }
+
+    if ((usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP) || adspFallback) {
+        ret = mPmemAdspAlloc->alloc_buffer(data);
+    }
+    return ret;
+}
+
+sp<IMemAlloc> PmemKernelController::getAllocator(int flags)
+{
+    sp<IMemAlloc> memalloc;
+    if (flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP)
+        memalloc = mPmemAdspAlloc;
+    else {
+        ALOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags);
+        memalloc = NULL;
+    }
+
+    return memalloc;
+}
+
+//-------------- PmemAshmmemController-----------------------//
+
+PmemAshmemController::PmemAshmemController()
+{
+    mPmemUserspaceAlloc = new PmemUserspaceAlloc();
+    mAshmemAlloc = new AshmemAlloc();
+    mPmemKernelCtrl = new PmemKernelController();
+}
+
+PmemAshmemController::~PmemAshmemController()
+{
+}
+
+int PmemAshmemController::allocate(alloc_data& data, int usage,
+        int compositionType)
+{
+    int ret = 0;
+
+    // Make buffers cacheable by default
+        data.uncached = false;
+
+    // Override if we explicitly need uncached buffers
+    if (usage & GRALLOC_USAGE_PRIVATE_UNCACHED)
+        data.uncached = true;
+
+    // If ADSP or SMI is requested use the kernel controller
+    if(usage & (GRALLOC_USAGE_PRIVATE_ADSP_HEAP|
+                GRALLOC_USAGE_PRIVATE_SMI_HEAP)) {
+        ret = mPmemKernelCtrl->allocate(data, usage, compositionType);
+        if(ret < 0)
+            ALOGE("%s: Failed to allocate ADSP/SMI memory", __func__);
+        else
+            data.allocType = private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP;
+        return ret;
+    }
+
+    if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP) {
+        ret = mAshmemAlloc->alloc_buffer(data);
+        if(ret >= 0) {
+            data.allocType = private_handle_t::PRIV_FLAGS_USES_ASHMEM;
+            data.allocType |= private_handle_t::PRIV_FLAGS_NONCONTIGUOUS_MEM;
+        }
+        return ret;
+    }
+
+    // if no memory specific flags are set,
+    // default to EBI heap, so that bypass
+    // can work. We can fall back to system
+    // heap if we run out.
+    ret = mPmemUserspaceAlloc->alloc_buffer(data);
+
+    // Fallback
+    if(ret >= 0 ) {
+        data.allocType = private_handle_t::PRIV_FLAGS_USES_PMEM;
+    } else if(ret < 0 && canFallback(compositionType, usage, false)) {
+        ALOGW("Falling back to ashmem");
+        ret = mAshmemAlloc->alloc_buffer(data);
+        if(ret >= 0) {
+            data.allocType = private_handle_t::PRIV_FLAGS_USES_ASHMEM;
+            data.allocType |= private_handle_t::PRIV_FLAGS_NONCONTIGUOUS_MEM;
+        }
+    }
+
+    return ret;
+}
+
+sp<IMemAlloc> PmemAshmemController::getAllocator(int flags)
+{
+    sp<IMemAlloc> memalloc;
+    if (flags & private_handle_t::PRIV_FLAGS_USES_PMEM)
+        memalloc = mPmemUserspaceAlloc;
+    else if (flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP)
+        memalloc = mPmemKernelCtrl->getAllocator(flags);
+    else if (flags & private_handle_t::PRIV_FLAGS_USES_ASHMEM)
+        memalloc = mAshmemAlloc;
+    else {
+        ALOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags);
+        memalloc = NULL;
+    }
+
+    return memalloc;
+}
+#endif
+
+size_t getBufferSizeAndDimensions(int width, int height, int format,
+                        int& alignedw, int &alignedh)
+{
+    size_t size;
+
+    alignedw = ALIGN(width, 32);
+    alignedh = ALIGN(height, 32);
+    switch (format) {
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+        case HAL_PIXEL_FORMAT_RGBX_8888:
+        case HAL_PIXEL_FORMAT_BGRA_8888:
+            size = alignedw * alignedh * 4;
+            break;
+        case HAL_PIXEL_FORMAT_RGB_888:
+            size = alignedw * alignedh * 3;
+            break;
+        case HAL_PIXEL_FORMAT_RGB_565:
+        case HAL_PIXEL_FORMAT_RGBA_5551:
+        case HAL_PIXEL_FORMAT_RGBA_4444:
+            size = alignedw * alignedh * 2;
+            break;
+
+            // adreno formats
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:  // NV21
+            size  = ALIGN(alignedw*alignedh, 4096);
+            size += ALIGN(2 * ALIGN(width/2, 32) * ALIGN(height/2, 32), 4096);
+            break;
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:   // NV12
+            // The chroma plane is subsampled,
+            // but the pitch in bytes is unchanged
+            // The GPU needs 4K alignment, but the video decoder needs 8K
+            alignedw = ALIGN(width, 128);
+            size  = ALIGN( alignedw * alignedh, 8192);
+            size += ALIGN( alignedw * ALIGN(height/2, 32), 8192);
+            break;
+        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+        case HAL_PIXEL_FORMAT_YV12:
+            if ((format == HAL_PIXEL_FORMAT_YV12) && ((width&1) || (height&1))) {
+                ALOGE("w or h is odd for the YV12 format");
+                return -EINVAL;
+            }
+            alignedw = ALIGN(width, 16);
+            alignedh = height;
+            if (HAL_PIXEL_FORMAT_NV12_ENCODEABLE == format) {
+                // The encoder requires a 2K aligned chroma offset.
+                size = ALIGN(alignedw*alignedh, 2048) +
+                       (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
+            } else {
+                size = alignedw*alignedh +
+                    (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
+            }
+            size = ALIGN(size, 4096);
+            break;
+
+        default:
+            ALOGE("unrecognized pixel format: %d", format);
+            return -EINVAL;
+    }
+
+    return size;
+}
+
+// Allocate buffer from width, height and format into a
+// private_handle_t. It is the responsibility of the caller
+// to free the buffer using the free_buffer function
+int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage)
+{
+     alloc_data data;
+     int alignedw, alignedh;
+     android::sp<gralloc::IAllocController> sAlloc =
+         gralloc::IAllocController::getInstance(false);
+     data.base = 0;
+     data.fd = -1;
+     data.offset = 0;
+     data.size = getBufferSizeAndDimensions(w, h, format, alignedw, alignedh);
+     data.align = getpagesize();
+     data.uncached = useUncached(usage);
+     int allocFlags = usage;
+
+     int err = sAlloc->allocate(data, allocFlags, 0);
+     if (0 != err) {
+         ALOGE("%s: allocate failed", __FUNCTION__);
+         return -ENOMEM;
+     }
+
+     private_handle_t* hnd = new private_handle_t(data.fd, data.size,
+                             data.allocType, 0, format, alignedw, alignedh);
+     hnd->base = (int) data.base;
+     hnd->offset = data.offset;
+     hnd->gpuaddr = 0;
+     *pHnd = hnd;
+     return 0;
+}
+
+void free_buffer(private_handle_t *hnd)
+{
+    android::sp<gralloc::IAllocController> sAlloc =
+        gralloc::IAllocController::getInstance(false);
+    if (hnd && hnd->fd > 0) {
+        sp<IMemAlloc> memalloc = sAlloc->getAllocator(hnd->flags);
+        memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);
+    }
+    if(hnd)
+        delete hnd;
+
+}
diff --git a/libgralloc/alloc_controller.h b/libgralloc/alloc_controller.h
new file mode 100644
index 0000000..6c907d1
--- /dev/null
+++ b/libgralloc/alloc_controller.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef GRALLOC_ALLOCCONTROLLER_H
+#define GRALLOC_ALLOCCONTROLLER_H
+
+#include <utils/RefBase.h>
+
+namespace gralloc {
+
+    struct alloc_data;
+    class IMemAlloc;
+    class IonAlloc;
+
+    class IAllocController : public android::RefBase {
+
+        public:
+            /* Allocate using a suitable method
+             * Returns the type of buffer allocated
+             */
+            virtual int allocate(alloc_data& data, int usage,
+                    int compositionType) = 0;
+
+            virtual android::sp<IMemAlloc> getAllocator(int flags) = 0;
+
+            virtual ~IAllocController() {};
+
+            static android::sp<IAllocController> getInstance(bool useMasterHeap);
+
+        private:
+            static android::sp<IAllocController> sController;
+
+    };
+
+    class IonController : public IAllocController {
+
+        public:
+            virtual int allocate(alloc_data& data, int usage,
+                    int compositionType);
+
+            virtual android::sp<IMemAlloc> getAllocator(int flags);
+
+            IonController();
+
+        private:
+            android::sp<IonAlloc> mIonAlloc;
+
+    };
+
+    class PmemKernelController : public IAllocController {
+
+        public:
+            virtual int allocate(alloc_data& data, int usage,
+                    int compositionType);
+
+            virtual android::sp<IMemAlloc> getAllocator(int flags);
+
+            PmemKernelController ();
+
+            ~PmemKernelController ();
+
+        private:
+            android::sp<IMemAlloc> mPmemAdspAlloc;
+
+    };
+
+    // Main pmem controller - this should only
+    // be used within gralloc
+    class PmemAshmemController : public IAllocController {
+
+        public:
+            virtual int allocate(alloc_data& data, int usage,
+                    int compositionType);
+
+            virtual android::sp<IMemAlloc> getAllocator(int flags);
+
+            PmemAshmemController();
+
+            ~PmemAshmemController();
+
+        private:
+            android::sp<IMemAlloc> mPmemUserspaceAlloc;
+            android::sp<IMemAlloc> mAshmemAlloc;
+            android::sp<IAllocController> mPmemKernelCtrl;
+
+    };
+
+} //end namespace gralloc
+#endif // GRALLOC_ALLOCCONTROLLER_H
diff --git a/libgralloc/ashmemalloc.cpp b/libgralloc/ashmemalloc.cpp
new file mode 100644
index 0000000..8397e21
--- /dev/null
+++ b/libgralloc/ashmemalloc.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <stdlib.h>
+#include <cutils/log.h>
+#include <linux/ashmem.h>
+#include <cutils/ashmem.h>
+#include <errno.h>
+#include "ashmemalloc.h"
+
+using gralloc::AshmemAlloc;
+int AshmemAlloc::alloc_buffer(alloc_data& data)
+{
+    int err = 0;
+    int fd = -1;
+    void* base = 0;
+    int offset = 0;
+    char name[ASHMEM_NAME_LEN];
+    snprintf(name, ASHMEM_NAME_LEN, "gralloc-buffer-%x", data.pHandle);
+    int prot = PROT_READ | PROT_WRITE;
+    fd = ashmem_create_region(name, data.size);
+    if (fd < 0) {
+        ALOGE("couldn't create ashmem (%s)", strerror(errno));
+        err = -errno;
+    } else {
+        if (ashmem_set_prot_region(fd, prot) < 0) {
+            ALOGE("ashmem_set_prot_region(fd=%d, prot=%x) failed (%s)",
+                 fd, prot, strerror(errno));
+            close(fd);
+            err = -errno;
+        } else {
+            base = mmap(0, data.size, prot, MAP_SHARED|MAP_POPULATE|MAP_LOCKED, fd, 0);
+            if (base == MAP_FAILED) {
+                ALOGE("alloc mmap(fd=%d, size=%d, prot=%x) failed (%s)",
+                     fd, data.size, prot, strerror(errno));
+                close(fd);
+                err = -errno;
+            } else {
+                memset((char*)base + offset, 0, data.size);
+            }
+        }
+    }
+    if(err == 0) {
+        data.fd = fd;
+        data.base = base;
+        data.offset = offset;
+        clean_buffer(base, data.size, offset, fd);
+        ALOGD("ashmem: Allocated buffer base:%p size:%d fd:%d",
+                                base, data.size, fd);
+
+    }
+    return err;
+
+}
+
+int AshmemAlloc::free_buffer(void* base, size_t size, int offset, int fd)
+{
+    ALOGD("ashmem: Freeing buffer base:%p size:%d fd:%d",
+                            base, size, fd);
+    int err = 0;
+
+    if(!base) {
+        ALOGE("Invalid free");
+        return -EINVAL;
+    }
+    err = unmap_buffer(base, size, offset);
+    close(fd);
+    return err;
+}
+
+int AshmemAlloc::map_buffer(void **pBase, size_t size, int offset, int fd)
+{
+    int err = 0;
+    void *base = 0;
+
+    base = mmap(0, size, PROT_READ| PROT_WRITE,
+            MAP_SHARED|MAP_POPULATE, fd, 0);
+    *pBase = base;
+    if(base == MAP_FAILED) {
+        ALOGE("ashmem: Failed to map memory in the client: %s",
+                                strerror(errno));
+        err = -errno;
+    } else {
+        ALOGD("ashmem: Mapped buffer base:%p size:%d fd:%d",
+                 base, size, fd);
+    }
+    return err;
+}
+
+int AshmemAlloc::unmap_buffer(void *base, size_t size, int offset)
+{
+    ALOGD("ashmem: Unmapping buffer base: %p size: %d", base, size);
+    int err = munmap(base, size);
+    if(err) {
+        ALOGE("ashmem: Failed to unmap memory at %p: %s",
+                                base, strerror(errno));
+    }
+    return err;
+
+}
+int AshmemAlloc::clean_buffer(void *base, size_t size, int offset, int fd)
+{
+    int err = 0;
+    if (ioctl(fd, ASHMEM_CACHE_FLUSH_RANGE, NULL)) {
+        ALOGE("ashmem: ASHMEM_CACHE_FLUSH_RANGE failed fd = %d", fd);
+    }
+
+    return err;
+}
+
diff --git a/libgralloc/ashmemalloc.h b/libgralloc/ashmemalloc.h
new file mode 100644
index 0000000..051dcd1
--- /dev/null
+++ b/libgralloc/ashmemalloc.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GRALLOC_ASHMEMALLOC_H
+#define GRALLOC_ASHMEMALLOC_H
+
+#include "memalloc.h"
+#include <linux/ion.h>
+
+namespace gralloc {
+    class AshmemAlloc : public IMemAlloc  {
+
+        public:
+            virtual int alloc_buffer(alloc_data& data);
+
+            virtual int free_buffer(void *base, size_t size,
+                    int offset, int fd);
+
+            virtual int map_buffer(void **pBase, size_t size,
+                    int offset, int fd);
+
+            virtual int unmap_buffer(void *base, size_t size,
+                    int offset);
+
+            virtual int clean_buffer(void*base, size_t size,
+                    int offset, int fd);
+
+    };
+}
+#endif /* GRALLOC_ASHMEMALLOC_H */
diff --git a/libgralloc/framebuffer.cpp b/libgralloc/framebuffer.cpp
new file mode 100644
index 0000000..b6b4a8f
--- /dev/null
+++ b/libgralloc/framebuffer.cpp
@@ -0,0 +1,937 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+* Copyright (c) 2010-2012 Code Aurora Forum. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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 <sys/mman.h>
+
+#include <dlfcn.h>
+
+#include <cutils/ashmem.h>
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include <utils/Timers.h>
+
+#include <hardware/hardware.h>
+#include <hardware/gralloc.h>
+
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <utils/Timers.h>
+
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+
+#include <linux/fb.h>
+#include <linux/msm_mdp.h>
+
+#include <GLES/gl.h>
+
+#include "gralloc_priv.h"
+#include "gr.h"
+#ifdef NO_SURFACEFLINGER_SWAPINTERVAL
+#include <cutils/properties.h>
+#endif
+
+#include <qcom_ui.h>
+
+#define FB_DEBUG 0
+
+#if defined(HDMI_DUAL_DISPLAY)
+#define EVEN_OUT(x) if (x & 0x0001) {x--;}
+using overlay::Overlay;
+/** min of int a, b */
+static inline int min(int a, int b) {
+    return (a<b) ? a : b;
+}
+/** max of int a, b */
+static inline int max(int a, int b) {
+    return (a>b) ? a : b;
+}
+#endif
+
+char framebufferStateName[] = {'S', 'R', 'A'};
+
+/*****************************************************************************/
+
+enum {
+    MDDI_PANEL = '1',
+    EBI2_PANEL = '2',
+    LCDC_PANEL = '3',
+    EXT_MDDI_PANEL = '4',
+    TV_PANEL = '5'
+};
+
+enum {
+    PAGE_FLIP = 0x00000001,
+    LOCKED = 0x00000002
+};
+
+struct fb_context_t {
+    framebuffer_device_t  device;
+};
+
+static int neworientation;
+
+/*****************************************************************************/
+
+static void
+msm_copy_buffer(buffer_handle_t handle, int fd,
+                int width, int height, int format,
+                int x, int y, int w, int h);
+
+static int fb_setSwapInterval(struct framebuffer_device_t* dev,
+            int interval)
+{
+    char pval[PROPERTY_VALUE_MAX];
+    property_get("debug.gr.swapinterval", pval, "-1");
+    int property_interval = atoi(pval);
+    if (property_interval >= 0)
+        interval = property_interval;
+
+    fb_context_t* ctx = (fb_context_t*)dev;
+    private_module_t* m = reinterpret_cast<private_module_t*>(
+            dev->common.module);
+    if (interval < dev->minSwapInterval || interval > dev->maxSwapInterval)
+        return -EINVAL;
+
+    m->swapInterval = interval;
+    return 0;
+}
+
+static int fb_setUpdateRect(struct framebuffer_device_t* dev,
+        int l, int t, int w, int h)
+{
+    if (((w|h) <= 0) || ((l|t)<0))
+        return -EINVAL;
+    fb_context_t* ctx = (fb_context_t*)dev;
+    private_module_t* m = reinterpret_cast<private_module_t*>(
+            dev->common.module);
+    m->info.reserved[0] = 0x54445055; // "UPDT";
+    m->info.reserved[1] = (uint16_t)l | ((uint32_t)t << 16);
+    m->info.reserved[2] = (uint16_t)(l+w) | ((uint32_t)(t+h) << 16);
+    return 0;
+}
+
+static void *disp_loop(void *ptr)
+{
+    struct qbuf_t nxtBuf;
+    static int cur_buf=-1;
+    private_module_t *m = reinterpret_cast<private_module_t*>(ptr);
+
+    while (1) {
+        pthread_mutex_lock(&(m->qlock));
+
+        // wait (sleep) while display queue is empty;
+        if (m->disp.isEmpty()) {
+            pthread_cond_wait(&(m->qpost),&(m->qlock));
+        }
+
+        // dequeue next buff to display and lock it
+        nxtBuf = m->disp.getHeadValue();
+        m->disp.pop();
+        pthread_mutex_unlock(&(m->qlock));
+
+        // post buf out to display synchronously
+        private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>
+                                                (nxtBuf.buf);
+        const size_t offset = hnd->base - m->framebuffer->base;
+        m->info.activate = FB_ACTIVATE_VBL;
+        m->info.yoffset = offset / m->finfo.line_length;
+
+#if defined(HDMI_DUAL_DISPLAY)
+        pthread_mutex_lock(&m->overlayLock);
+        m->orientation = neworientation;
+        m->currentOffset = offset;
+        m->hdmiStateChanged = true;
+        pthread_cond_signal(&(m->overlayPost));
+        pthread_mutex_unlock(&m->overlayLock);
+#endif
+        if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1) {
+            ALOGE("ERROR FBIOPUT_VSCREENINFO failed; frame not displayed");
+        }
+
+        CALC_FPS();
+
+        if (cur_buf == -1) {
+            int nxtAvail = ((nxtBuf.idx + 1) % m->numBuffers);
+            pthread_mutex_lock(&(m->avail[nxtBuf.idx].lock));
+            m->avail[nxtBuf.idx].is_avail = true;
+            m->avail[nxtBuf.idx].state = REF;
+            pthread_cond_broadcast(&(m->avail[nxtBuf.idx].cond));
+            pthread_mutex_unlock(&(m->avail[nxtBuf.idx].lock));
+        } else {
+            pthread_mutex_lock(&(m->avail[nxtBuf.idx].lock));
+            if (m->avail[nxtBuf.idx].state != SUB) {
+                ALOGE_IF(m->swapInterval != 0, "[%d] state %c, expected %c", nxtBuf.idx,
+                    framebufferStateName[m->avail[nxtBuf.idx].state],
+                    framebufferStateName[SUB]);
+            }
+            m->avail[nxtBuf.idx].state = REF;
+            pthread_mutex_unlock(&(m->avail[nxtBuf.idx].lock));
+
+            pthread_mutex_lock(&(m->avail[cur_buf].lock));
+            m->avail[cur_buf].is_avail = true;
+            if (m->avail[cur_buf].state != REF) {
+                ALOGE_IF(m->swapInterval != 0, "[%d] state %c, expected %c", cur_buf,
+                    framebufferStateName[m->avail[cur_buf].state],
+                    framebufferStateName[REF]);
+            }
+            m->avail[cur_buf].state = AVL;
+            pthread_cond_broadcast(&(m->avail[cur_buf].cond));
+            pthread_mutex_unlock(&(m->avail[cur_buf].lock));
+        }
+        cur_buf = nxtBuf.idx;
+    }
+    return NULL;
+}
+
+#if defined(HDMI_DUAL_DISPLAY)
+static int closeHDMIChannel(private_module_t* m)
+{
+    Overlay* pTemp = m->pobjOverlay;
+    if(pTemp != NULL)
+        pTemp->closeChannel();
+    return 0;
+}
+
+static void getSecondaryDisplayDestinationInfo(private_module_t* m, overlay_rect&
+                                rect, int& orientation)
+{
+    Overlay* pTemp = m->pobjOverlay;
+    int width = pTemp->getFBWidth();
+    int height = pTemp->getFBHeight();
+    int fbwidth = m->info.xres, fbheight = m->info.yres;
+    rect.x = 0; rect.y = 0;
+    rect.w = width; rect.h = height;
+    int rot = m->orientation;
+    switch(rot) {
+        // ROT_0
+        case 0:
+        // ROT_180
+        case HAL_TRANSFORM_ROT_180:
+            pTemp->getAspectRatioPosition(fbwidth, fbheight,
+                                                   &rect);
+            if(rot ==  HAL_TRANSFORM_ROT_180)
+                orientation = HAL_TRANSFORM_ROT_180;
+            else
+                orientation  = 0;
+            break;
+            // ROT_90
+        case HAL_TRANSFORM_ROT_90:
+            // ROT_270
+        case HAL_TRANSFORM_ROT_270:
+            //Calculate the Aspectratio for the UI
+            //in the landscape mode
+            //Width and height will be swapped as there
+            //is rotation
+            pTemp->getAspectRatioPosition(fbheight, fbwidth,
+                    &rect);
+
+            if(rot == HAL_TRANSFORM_ROT_90)
+                orientation = HAL_TRANSFORM_ROT_270;
+            else if(rot == HAL_TRANSFORM_ROT_270)
+                orientation = HAL_TRANSFORM_ROT_90;
+            break;
+    }
+    return;
+}
+
+static void *hdmi_ui_loop(void *ptr)
+{
+    private_module_t* m = reinterpret_cast<private_module_t*>(
+            ptr);
+    while (1) {
+        pthread_mutex_lock(&m->overlayLock);
+        while(!(m->hdmiStateChanged))
+            pthread_cond_wait(&(m->overlayPost), &(m->overlayLock));
+        m->hdmiStateChanged = false;
+        if (m->exitHDMIUILoop) {
+            pthread_mutex_unlock(&m->overlayLock);
+            return NULL;
+        }
+        bool waitForVsync = true;
+        int flags = WAIT_FOR_VSYNC;
+        if (m->pobjOverlay) {
+            Overlay* pTemp = m->pobjOverlay;
+            if (m->hdmiMirroringState == HDMI_NO_MIRRORING)
+                closeHDMIChannel(m);
+            else if(m->hdmiMirroringState == HDMI_UI_MIRRORING) {
+                if (!pTemp->isChannelUP()) {
+                   int alignedW = ALIGN(m->info.xres, 32);
+
+                   private_handle_t const* hnd =
+                      reinterpret_cast<private_handle_t const*>(m->framebuffer);
+                   overlay_buffer_info info;
+                   info.width = alignedW;
+                   info.height = hnd->height;
+                   info.format = hnd->format;
+                   info.size = hnd->size;
+
+                   if (m->trueMirrorSupport)
+                       flags &= ~WAIT_FOR_VSYNC;
+                   // start the overlay Channel for mirroring
+                   // m->enableHDMIOutput corresponds to the fbnum
+                   if (pTemp->startChannel(info, m->enableHDMIOutput,
+                                           false, true, 0, VG0_PIPE, flags)) {
+                        pTemp->setFd(m->framebuffer->fd);
+                        pTemp->setCrop(0, 0, m->info.xres, m->info.yres);
+                   } else
+                       closeHDMIChannel(m);
+                }
+
+                if (pTemp->isChannelUP()) {
+                    overlay_rect destRect;
+                    int rot = 0;
+                    int currOrientation = 0;
+                    getSecondaryDisplayDestinationInfo(m, destRect, rot);
+                    pTemp->getOrientation(currOrientation);
+                    if(rot != currOrientation) {
+                        pTemp->setTransform(rot);
+                    }
+                    EVEN_OUT(destRect.x);
+                    EVEN_OUT(destRect.y);
+                    EVEN_OUT(destRect.w);
+                    EVEN_OUT(destRect.h);
+                    int currentX = 0, currentY = 0;
+                    uint32_t currentW = 0, currentH = 0;
+                    if (pTemp->getPosition(currentX, currentY, currentW, currentH)) {
+                        if ((currentX != destRect.x) || (currentY != destRect.y) ||
+                                (currentW != destRect.w) || (currentH != destRect.h)) {
+                            pTemp->setPosition(destRect.x, destRect.y, destRect.w,
+                                                                    destRect.h);
+                        }
+                    }
+                    if (m->trueMirrorSupport) {
+                        // if video is started the UI channel should be NO_WAIT.
+                        flags = !m->videoOverlay ? WAIT_FOR_VSYNC : 0;
+                        pTemp->updateOverlayFlags(flags);
+                    }
+                    pTemp->queueBuffer(m->currentOffset);
+                }
+            }
+            else
+                closeHDMIChannel(m);
+        }
+        pthread_mutex_unlock(&m->overlayLock);
+    }
+    return NULL;
+}
+
+static int fb_videoOverlayStarted(struct framebuffer_device_t* dev, int started)
+{
+    private_module_t* m = reinterpret_cast<private_module_t*>(
+            dev->common.module);
+    pthread_mutex_lock(&m->overlayLock);
+    Overlay* pTemp = m->pobjOverlay;
+    if(started != m->videoOverlay) {
+        m->videoOverlay = started;
+        if (!m->trueMirrorSupport) {
+            m->hdmiStateChanged = true;
+            if (started && pTemp) {
+                m->hdmiMirroringState = HDMI_NO_MIRRORING;
+                closeHDMIChannel(m);
+            } else if (m->enableHDMIOutput)
+                m->hdmiMirroringState = HDMI_UI_MIRRORING;
+            pthread_cond_signal(&(m->overlayPost));
+        }
+    }
+    pthread_mutex_unlock(&m->overlayLock);
+    return 0;
+}
+
+static int fb_enableHDMIOutput(struct framebuffer_device_t* dev, int externaltype)
+{
+    private_module_t* m = reinterpret_cast<private_module_t*>(
+            dev->common.module);
+    pthread_mutex_lock(&m->overlayLock);
+    Overlay* pTemp = m->pobjOverlay;
+    //Check if true mirroring can be supported
+    m->trueMirrorSupport = FrameBufferInfo::getInstance()->canSupportTrueMirroring();
+    m->enableHDMIOutput = externaltype;
+    ALOGE("In fb_enableHDMIOutput: externaltype = %d", m->enableHDMIOutput);
+    if(externaltype) {
+        if (m->trueMirrorSupport) {
+            m->hdmiMirroringState = HDMI_UI_MIRRORING;
+        } else {
+            if(!m->videoOverlay)
+                m->hdmiMirroringState = HDMI_UI_MIRRORING;
+        }
+    } else if (!externaltype && pTemp) {
+        m->hdmiMirroringState = HDMI_NO_MIRRORING;
+        closeHDMIChannel(m);
+    }
+    m->hdmiStateChanged = true;
+    pthread_cond_signal(&(m->overlayPost));
+    pthread_mutex_unlock(&m->overlayLock);
+    return 0;
+}
+
+
+static int fb_setActionSafeWidthRatio(struct framebuffer_device_t* dev, float asWidthRatio)
+{
+    private_module_t* m = reinterpret_cast<private_module_t*>(
+            dev->common.module);
+    pthread_mutex_lock(&m->overlayLock);
+    m->actionsafeWidthRatio = asWidthRatio;
+    pthread_mutex_unlock(&m->overlayLock);
+    return 0;
+}
+
+static int fb_setActionSafeHeightRatio(struct framebuffer_device_t* dev, float asHeightRatio)
+{
+    private_module_t* m = reinterpret_cast<private_module_t*>(
+                    dev->common.module);
+    pthread_mutex_lock(&m->overlayLock);
+    m->actionsafeHeightRatio = asHeightRatio;
+    pthread_mutex_unlock(&m->overlayLock);
+    return 0;
+}
+
+static int fb_orientationChanged(struct framebuffer_device_t* dev, int orientation)
+{
+    private_module_t* m = reinterpret_cast<private_module_t*>(
+            dev->common.module);
+    pthread_mutex_lock(&m->overlayLock);
+    neworientation = orientation;
+    pthread_mutex_unlock(&m->overlayLock);
+    return 0;
+}
+#endif
+
+static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
+{
+    if (private_handle_t::validate(buffer) < 0)
+        return -EINVAL;
+
+    int nxtIdx, futureIdx = -1;
+    bool reuse;
+    struct qbuf_t qb;
+    fb_context_t* ctx = (fb_context_t*)dev;
+
+    private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(buffer);
+    private_module_t* m = reinterpret_cast<private_module_t*>(
+            dev->common.module);
+
+    if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
+
+        reuse = false;
+        nxtIdx = (m->currentIdx + 1) % m->numBuffers;
+        futureIdx = (nxtIdx + 1) % m->numBuffers;
+
+        if (m->swapInterval == 0) {
+            // if SwapInterval = 0 and no buffers available then reuse
+            // current buf for next rendering so don't post new buffer
+            if (pthread_mutex_trylock(&(m->avail[nxtIdx].lock))) {
+                reuse = true;
+            } else {
+                if (! m->avail[nxtIdx].is_avail)
+                    reuse = true;
+                pthread_mutex_unlock(&(m->avail[nxtIdx].lock));
+            }
+        }
+
+        if(!reuse){
+            // unlock previous ("current") Buffer and lock the new buffer
+            m->base.lock(&m->base, buffer,
+                    private_module_t::PRIV_USAGE_LOCKED_FOR_POST,
+                    0,0, m->info.xres, m->info.yres, NULL);
+
+            // post/queue the new buffer
+            pthread_mutex_lock(&(m->avail[nxtIdx].lock));
+            if (m->avail[nxtIdx].is_avail != true) {
+                ALOGE_IF(m->swapInterval != 0, "Found %d buf to be not avail", nxtIdx);
+            }
+
+            m->avail[nxtIdx].is_avail = false;
+
+            if (m->avail[nxtIdx].state != AVL) {
+                ALOGD("[%d] state %c, expected %c", nxtIdx,
+                    framebufferStateName[m->avail[nxtIdx].state],
+                    framebufferStateName[AVL]);
+            }
+
+            m->avail[nxtIdx].state = SUB;
+            pthread_mutex_unlock(&(m->avail[nxtIdx].lock));
+
+            qb.idx = nxtIdx;
+            qb.buf = buffer;
+            pthread_mutex_lock(&(m->qlock));
+            m->disp.push(qb);
+            pthread_cond_signal(&(m->qpost));
+            pthread_mutex_unlock(&(m->qlock));
+
+            if (m->currentBuffer)
+                m->base.unlock(&m->base, m->currentBuffer);
+
+            m->currentBuffer = buffer;
+            m->currentIdx = nxtIdx;
+        } else {
+            if (m->currentBuffer)
+                m->base.unlock(&m->base, m->currentBuffer);
+            m->base.lock(&m->base, buffer,
+                         private_module_t::PRIV_USAGE_LOCKED_FOR_POST,
+                         0,0, m->info.xres, m->info.yres, NULL);
+            m->currentBuffer = buffer;
+        }
+
+    } else {
+        void* fb_vaddr;
+        void* buffer_vaddr;
+        m->base.lock(&m->base, m->framebuffer,
+                GRALLOC_USAGE_SW_WRITE_RARELY,
+                0, 0, m->info.xres, m->info.yres,
+                &fb_vaddr);
+
+        m->base.lock(&m->base, buffer,
+                GRALLOC_USAGE_SW_READ_RARELY,
+                0, 0, m->info.xres, m->info.yres,
+                &buffer_vaddr);
+
+        //memcpy(fb_vaddr, buffer_vaddr, m->finfo.line_length * m->info.yres);
+
+        msm_copy_buffer(
+                m->framebuffer, m->framebuffer->fd,
+                m->info.xres, m->info.yres, m->fbFormat,
+                m->info.xoffset, m->info.yoffset,
+                m->info.width, m->info.height);
+
+        m->base.unlock(&m->base, buffer);
+        m->base.unlock(&m->base, m->framebuffer);
+    }
+
+    ALOGD_IF(FB_DEBUG, "Framebuffer state: [0] = %c [1] = %c [2] = %c",
+        framebufferStateName[m->avail[0].state],
+        framebufferStateName[m->avail[1].state],
+        framebufferStateName[m->avail[2].state]);
+    return 0;
+}
+
+static int fb_compositionComplete(struct framebuffer_device_t* dev)
+{
+    // TODO: Properly implement composition complete callback
+    glFinish();
+
+    return 0;
+}
+
+static int fb_lockBuffer(struct framebuffer_device_t* dev, int index)
+{
+    private_module_t* m = reinterpret_cast<private_module_t*>(
+            dev->common.module);
+
+    // Return immediately if the buffer is available
+    if ((m->avail[index].state == AVL) || (m->swapInterval == 0))
+        return 0;
+
+    pthread_mutex_lock(&(m->avail[index].lock));
+    while (m->avail[index].state != AVL) {
+        pthread_cond_wait(&(m->avail[index].cond),
+                         &(m->avail[index].lock));
+    }
+    pthread_mutex_unlock(&(m->avail[index].lock));
+
+    return 0;
+}
+
+/*****************************************************************************/
+
+int mapFrameBufferLocked(struct private_module_t* module)
+{
+    // already initialized...
+    if (module->framebuffer) {
+        return 0;
+    }
+    char const * const device_template[] = {
+            "/dev/graphics/fb%u",
+            "/dev/fb%u",
+            0 };
+
+    int fd = -1;
+    int i=0;
+    char name[64];
+    char property[PROPERTY_VALUE_MAX];
+
+    while ((fd==-1) && device_template[i]) {
+        snprintf(name, 64, device_template[i], 0);
+        fd = open(name, O_RDWR, 0);
+        i++;
+    }
+    if (fd < 0)
+        return -errno;
+
+    struct fb_fix_screeninfo finfo;
+    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
+        return -errno;
+
+    struct fb_var_screeninfo info;
+    if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
+        return -errno;
+
+    info.reserved[0] = 0;
+    info.reserved[1] = 0;
+    info.reserved[2] = 0;
+    info.xoffset = 0;
+    info.yoffset = 0;
+    info.activate = FB_ACTIVATE_NOW;
+
+    /* Interpretation of offset for color fields: All offsets are from the right,
+    * inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you
+    * can use the offset as right argument to <<). A pixel afterwards is a bit
+    * stream and is written to video memory as that unmodified. This implies
+    * big-endian byte order if bits_per_pixel is greater than 8.
+    */
+
+    if(info.bits_per_pixel == 32) {
+        /*
+         * Explicitly request RGBA_8888
+         */
+        info.bits_per_pixel = 32;
+        info.red.offset     = 24;
+        info.red.length     = 8;
+        info.green.offset   = 16;
+        info.green.length   = 8;
+        info.blue.offset    = 8;
+        info.blue.length    = 8;
+        info.transp.offset  = 0;
+        info.transp.length  = 8;
+
+        /* Note: the GL driver does not have a r=8 g=8 b=8 a=0 config, so if we do
+         * not use the MDP for composition (i.e. hw composition == 0), ask for
+         * RGBA instead of RGBX. */
+        if (property_get("debug.sf.hw", property, NULL) > 0 && atoi(property) == 0)
+            module->fbFormat = HAL_PIXEL_FORMAT_RGBX_8888;
+        else if(property_get("debug.composition.type", property, NULL) > 0 && (strncmp(property, "mdp", 3) == 0))
+            module->fbFormat = HAL_PIXEL_FORMAT_RGBX_8888;
+        else
+            module->fbFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+    } else {
+        /*
+         * Explicitly request 5/6/5
+         */
+        info.bits_per_pixel = 16;
+        info.red.offset     = 11;
+        info.red.length     = 5;
+        info.green.offset   = 5;
+        info.green.length   = 6;
+        info.blue.offset    = 0;
+        info.blue.length    = 5;
+        info.transp.offset  = 0;
+        info.transp.length  = 0;
+        module->fbFormat = HAL_PIXEL_FORMAT_RGB_565;
+    }
+
+    //adreno needs 4k aligned offsets. Max hole size is 4096-1
+    int  size = roundUpToPageSize(info.yres * info.xres * (info.bits_per_pixel/8));
+
+    /*
+     * Request NUM_BUFFERS screens (at lest 2 for page flipping)
+     */
+    int numberOfBuffers = (int)(finfo.smem_len/size);
+    ALOGV("num supported framebuffers in kernel = %d", numberOfBuffers);
+
+    if (property_get("debug.gr.numframebuffers", property, NULL) > 0) {
+        int num = atoi(property);
+        if ((num >= NUM_FRAMEBUFFERS_MIN) && (num <= NUM_FRAMEBUFFERS_MAX)) {
+            numberOfBuffers = num;
+        }
+    }
+    if (numberOfBuffers > NUM_FRAMEBUFFERS_MAX)
+        numberOfBuffers = NUM_FRAMEBUFFERS_MAX;
+
+    ALOGV("We support %d buffers", numberOfBuffers);
+
+    //consider the included hole by 4k alignment
+    uint32_t line_length = (info.xres * info.bits_per_pixel / 8);
+    info.yres_virtual = (size * numberOfBuffers) / line_length;
+
+    uint32_t flags = PAGE_FLIP;
+    if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) {
+        info.yres_virtual = size / line_length;
+        flags &= ~PAGE_FLIP;
+        ALOGW("FBIOPUT_VSCREENINFO failed, page flipping not supported");
+    }
+
+    if (info.yres_virtual < ((size * 2) / line_length) ) {
+        // we need at least 2 for page-flipping
+        info.yres_virtual = size / line_length;
+        flags &= ~PAGE_FLIP;
+        ALOGW("page flipping not supported (yres_virtual=%d, requested=%d)",
+                info.yres_virtual, info.yres*2);
+    }
+
+    if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
+        return -errno;
+
+    if (int(info.width) <= 0 || int(info.height) <= 0) {
+        // the driver doesn't return that information
+        // default to 160 dpi
+        info.width  = ((info.xres * 25.4f)/160.0f + 0.5f);
+        info.height = ((info.yres * 25.4f)/160.0f + 0.5f);
+    }
+
+    float xdpi = (info.xres * 25.4f) / info.width;
+    float ydpi = (info.yres * 25.4f) / info.height;
+    //The reserved[4] field is used to store FPS by the driver.
+    float fps  = info.reserved[4];
+
+    ALOGI(   "using (fd=%d)\n"
+            "id           = %s\n"
+            "xres         = %d px\n"
+            "yres         = %d px\n"
+            "xres_virtual = %d px\n"
+            "yres_virtual = %d px\n"
+            "bpp          = %d\n"
+            "r            = %2u:%u\n"
+            "g            = %2u:%u\n"
+            "b            = %2u:%u\n",
+            fd,
+            finfo.id,
+            info.xres,
+            info.yres,
+            info.xres_virtual,
+            info.yres_virtual,
+            info.bits_per_pixel,
+            info.red.offset, info.red.length,
+            info.green.offset, info.green.length,
+            info.blue.offset, info.blue.length
+    );
+
+    ALOGI(   "width        = %d mm (%f dpi)\n"
+            "height       = %d mm (%f dpi)\n"
+            "refresh rate = %.2f Hz\n",
+            info.width,  xdpi,
+            info.height, ydpi,
+            fps
+    );
+
+
+    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
+        return -errno;
+
+    if (finfo.smem_len <= 0)
+        return -errno;
+
+    module->flags = flags;
+    module->info = info;
+    module->finfo = finfo;
+    module->xdpi = xdpi;
+    module->ydpi = ydpi;
+    module->fps = fps;
+
+#ifdef NO_SURFACEFLINGER_SWAPINTERVAL
+    char pval[PROPERTY_VALUE_MAX];
+    property_get("debug.gr.swapinterval", pval, "1");
+    module->swapInterval = atoi(pval);
+    if (module->swapInterval < private_module_t::PRIV_MIN_SWAP_INTERVAL ||
+        module->swapInterval > private_module_t::PRIV_MAX_SWAP_INTERVAL) {
+        module->swapInterval = 1;
+        ALOGW("Out of range (%d to %d) value for debug.gr.swapinterval, using 1",
+             private_module_t::PRIV_MIN_SWAP_INTERVAL,
+             private_module_t::PRIV_MAX_SWAP_INTERVAL);
+    }
+
+#else
+    /* when surfaceflinger supports swapInterval then can just do this */
+    module->swapInterval = 1;
+#endif
+
+    CALC_INIT();
+
+    module->currentIdx = -1;
+    pthread_cond_init(&(module->qpost), NULL);
+    pthread_mutex_init(&(module->qlock), NULL);
+    for (i = 0; i < NUM_FRAMEBUFFERS_MAX; i++) {
+        pthread_mutex_init(&(module->avail[i].lock), NULL);
+        pthread_cond_init(&(module->avail[i].cond), NULL);
+        module->avail[i].is_avail = true;
+        module->avail[i].state = AVL;
+    }
+
+    /* create display update thread */
+    pthread_t thread1;
+    if (pthread_create(&thread1, NULL, &disp_loop, (void *) module)) {
+         return -errno;
+    }
+
+    /*
+     * map the framebuffer
+     */
+
+    int err;
+    module->numBuffers = info.yres_virtual / info.yres;
+    module->bufferMask = 0;
+    //adreno needs page aligned offsets. Align the fbsize to pagesize.
+    size_t fbSize = roundUpToPageSize(finfo.line_length * info.yres) * module->numBuffers;
+    module->framebuffer = new private_handle_t(fd, fbSize,
+                            private_handle_t::PRIV_FLAGS_USES_PMEM, BUFFER_TYPE_UI,
+                            module->fbFormat, info.xres, info.yres);
+    void* vaddr = mmap(0, fbSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+    if (vaddr == MAP_FAILED) {
+        ALOGE("Error mapping the framebuffer (%s)", strerror(errno));
+        return -errno;
+    }
+    module->framebuffer->base = intptr_t(vaddr);
+    memset(vaddr, 0, fbSize);
+
+#if defined(HDMI_DUAL_DISPLAY)
+    /* Overlay for HDMI*/
+    pthread_mutex_init(&(module->overlayLock), NULL);
+    pthread_cond_init(&(module->overlayPost), NULL);
+    module->pobjOverlay = new Overlay();
+    module->currentOffset = 0;
+    module->exitHDMIUILoop = false;
+    module->hdmiStateChanged = false;
+    pthread_t hdmiUIThread;
+    pthread_create(&hdmiUIThread, NULL, &hdmi_ui_loop, (void *) module);
+    module->hdmiMirroringState = HDMI_NO_MIRRORING;
+    module->trueMirrorSupport = false;
+#endif
+
+    return 0;
+}
+
+static int mapFrameBuffer(struct private_module_t* module)
+{
+    pthread_mutex_lock(&module->lock);
+    int err = mapFrameBufferLocked(module);
+    pthread_mutex_unlock(&module->lock);
+    return err;
+}
+
+/*****************************************************************************/
+
+static int fb_close(struct hw_device_t *dev)
+{
+    fb_context_t* ctx = (fb_context_t*)dev;
+#if defined(HDMI_DUAL_DISPLAY)
+    private_module_t* m = reinterpret_cast<private_module_t*>(
+            ctx->device.common.module);
+    pthread_mutex_lock(&m->overlayLock);
+    m->exitHDMIUILoop = true;
+    pthread_cond_signal(&(m->overlayPost));
+    pthread_mutex_unlock(&m->overlayLock);
+#endif
+    if (ctx) {
+        free(ctx);
+    }
+    return 0;
+}
+
+int fb_device_open(hw_module_t const* module, const char* name,
+        hw_device_t** device)
+{
+    int status = -EINVAL;
+    if (!strcmp(name, GRALLOC_HARDWARE_FB0)) {
+        alloc_device_t* gralloc_device;
+        status = gralloc_open(module, &gralloc_device);
+        if (status < 0)
+            return status;
+
+        /* initialize our state here */
+        fb_context_t *dev = (fb_context_t*)malloc(sizeof(*dev));
+        memset(dev, 0, sizeof(*dev));
+
+        /* 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 = fb_close;
+        dev->device.setSwapInterval = fb_setSwapInterval;
+        dev->device.post            = fb_post;
+        dev->device.setUpdateRect = 0;
+        dev->device.compositionComplete = fb_compositionComplete;
+        //dev->device.lockBuffer = fb_lockBuffer;
+#if defined(HDMI_DUAL_DISPLAY)
+        dev->device.orientationChanged = fb_orientationChanged;
+        dev->device.videoOverlayStarted = fb_videoOverlayStarted;
+        dev->device.enableHDMIOutput = fb_enableHDMIOutput;
+        dev->device.setActionSafeWidthRatio = fb_setActionSafeWidthRatio;
+        dev->device.setActionSafeHeightRatio = fb_setActionSafeHeightRatio;
+#endif
+
+        private_module_t* m = (private_module_t*)module;
+        status = mapFrameBuffer(m);
+        if (status >= 0) {
+            int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3);
+            const_cast<uint32_t&>(dev->device.flags) = 0;
+            const_cast<uint32_t&>(dev->device.width) = m->info.xres;
+            const_cast<uint32_t&>(dev->device.height) = m->info.yres;
+            const_cast<int&>(dev->device.stride) = stride;
+            const_cast<int&>(dev->device.format) = m->fbFormat;
+            const_cast<float&>(dev->device.xdpi) = m->xdpi;
+            const_cast<float&>(dev->device.ydpi) = m->ydpi;
+            const_cast<float&>(dev->device.fps) = m->fps;
+            const_cast<int&>(dev->device.minSwapInterval) = private_module_t::PRIV_MIN_SWAP_INTERVAL;
+            const_cast<int&>(dev->device.maxSwapInterval) = private_module_t::PRIV_MAX_SWAP_INTERVAL;
+            //const_cast<int&>(dev->device.numFramebuffers) = m->numBuffers;
+            if (m->finfo.reserved[0] == 0x5444 &&
+                    m->finfo.reserved[1] == 0x5055) {
+                dev->device.setUpdateRect = fb_setUpdateRect;
+                ALOGD("UPDATE_ON_DEMAND supported");
+            }
+
+            *device = &dev->device.common;
+        }
+
+        // Close the gralloc module
+        gralloc_close(gralloc_device);
+    }
+    return status;
+}
+
+/* Copy a pmem buffer to the framebuffer */
+
+static void
+msm_copy_buffer(buffer_handle_t handle, int fd,
+                int width, int height, int format,
+                int x, int y, int w, int h)
+{
+    struct {
+        unsigned int count;
+        mdp_blit_req req;
+    } blit;
+    private_handle_t *priv = (private_handle_t*) handle;
+
+    memset(&blit, 0, sizeof(blit));
+    blit.count = 1;
+
+    blit.req.flags = 0;
+    blit.req.alpha = 0xff;
+    blit.req.transp_mask = 0xffffffff;
+
+    blit.req.src.width = width;
+    blit.req.src.height = height;
+    blit.req.src.offset = 0;
+    blit.req.src.memory_id = priv->fd;
+
+    blit.req.dst.width = width;
+    blit.req.dst.height = height;
+    blit.req.dst.offset = 0;
+    blit.req.dst.memory_id = fd;
+    blit.req.dst.format = format;
+
+    blit.req.src_rect.x = blit.req.dst_rect.x = x;
+    blit.req.src_rect.y = blit.req.dst_rect.y = y;
+    blit.req.src_rect.w = blit.req.dst_rect.w = w;
+    blit.req.src_rect.h = blit.req.dst_rect.h = h;
+
+    if (ioctl(fd, MSMFB_BLIT, &blit))
+        ALOGE("MSMFB_BLIT failed = %d", -errno);
+}
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
new file mode 100755
index 0000000..77ad174
--- /dev/null
+++ b/libgralloc/gpu.cpp
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (c) 2011-2012 Code Aurora Forum. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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 <limits.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <cutils/properties.h>
+#include <sys/mman.h>
+
+#include <genlock.h>
+
+#include "gr.h"
+#include "gpu.h"
+#include "memalloc.h"
+#include "alloc_controller.h"
+
+using namespace gralloc;
+using android::sp;
+
+gpu_context_t::gpu_context_t(const private_module_t* module,
+        sp<IAllocController> alloc_ctrl ) :
+    mAllocCtrl(alloc_ctrl)
+{
+    // Zero out the alloc_device_t
+    memset(static_cast<alloc_device_t*>(this), 0, sizeof(alloc_device_t));
+
+    char property[PROPERTY_VALUE_MAX];
+    if (property_get("debug.sf.hw", property, NULL) > 0) {
+        if(atoi(property) == 0) {
+            //debug.sf.hw = 0
+            compositionType = CPU_COMPOSITION;
+        } else { //debug.sf.hw = 1
+            // Get the composition type
+            property_get("debug.composition.type", property, NULL);
+            if (property == NULL) {
+                compositionType = GPU_COMPOSITION;
+            } else if ((strncmp(property, "mdp", 3)) == 0) {
+                compositionType = MDP_COMPOSITION;
+            } else if ((strncmp(property, "c2d", 3)) == 0) {
+                compositionType = C2D_COMPOSITION;
+            } else {
+                compositionType = GPU_COMPOSITION;
+            }
+        }
+    } else { //debug.sf.hw is not set. Use cpu composition
+        compositionType = CPU_COMPOSITION;
+    }
+
+    // Initialize the procs
+    common.tag     = HARDWARE_DEVICE_TAG;
+    common.version = 0;
+    common.module  = const_cast<hw_module_t*>(&module->base.common);
+    common.close   = gralloc_close;
+    alloc          = gralloc_alloc;
+#if 0
+    allocSize      = gralloc_alloc_size;
+#endif
+    free           = gralloc_free;
+
+}
+
+int gpu_context_t::gralloc_alloc_framebuffer_locked(size_t size, int usage,
+        buffer_handle_t* pHandle)
+{
+    private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
+
+    // we don't support allocations with both the FB and PMEM_ADSP flags
+    if (usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP) {
+        return -EINVAL;
+    }
+
+    if (m->framebuffer == NULL) {
+        ALOGE("%s: Invalid framebuffer", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    const uint32_t bufferMask = m->bufferMask;
+    const uint32_t numBuffers = m->numBuffers;
+    size_t bufferSize = m->finfo.line_length * m->info.yres;
+
+    //adreno needs FB size to be page aligned
+    bufferSize = roundUpToPageSize(bufferSize);
+
+    if (numBuffers == 1) {
+        // If we have only one buffer, we never use page-flipping. Instead,
+        // we return a regular buffer which will be memcpy'ed to the main
+        // screen when post is called.
+        int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
+        return gralloc_alloc_buffer(bufferSize, newUsage, pHandle, BUFFER_TYPE_UI,
+                                    m->fbFormat, m->info.xres, m->info.yres);
+    }
+
+    if (bufferMask >= ((1LU<<numBuffers)-1)) {
+        // We ran out of buffers.
+        return -ENOMEM;
+    }
+
+    // create a "fake" handles for it
+    // Set the PMEM flag as well, since adreno
+    // treats the FB memory as pmem
+    intptr_t vaddr = intptr_t(m->framebuffer->base);
+    private_handle_t* hnd = new private_handle_t(dup(m->framebuffer->fd), bufferSize,
+                                                 private_handle_t::PRIV_FLAGS_USES_PMEM |
+                                                 private_handle_t::PRIV_FLAGS_FRAMEBUFFER,
+                                                 BUFFER_TYPE_UI, m->fbFormat, m->info.xres,
+                                                 m->info.yres);
+
+    // find a free slot
+    for (uint32_t i=0 ; i<numBuffers ; i++) {
+        if ((bufferMask & (1LU<<i)) == 0) {
+            m->bufferMask |= (1LU<<i);
+            break;
+        }
+        vaddr += bufferSize;
+    }
+
+    hnd->base = vaddr;
+    hnd->offset = vaddr - intptr_t(m->framebuffer->base);
+    *pHandle = hnd;
+    return 0;
+}
+
+
+int gpu_context_t::gralloc_alloc_framebuffer(size_t size, int usage,
+        buffer_handle_t* pHandle)
+{
+    private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
+    pthread_mutex_lock(&m->lock);
+    int err = gralloc_alloc_framebuffer_locked(size, usage, pHandle);
+    pthread_mutex_unlock(&m->lock);
+    return err;
+}
+
+int gpu_context_t::gralloc_alloc_buffer(size_t size, int usage,
+                                        buffer_handle_t* pHandle, int bufferType,
+                                        int format, int width, int height)
+{
+    int err = 0;
+    int flags = 0;
+    size = roundUpToPageSize(size);
+    alloc_data data;
+    data.offset = 0;
+    data.fd = -1;
+    data.base = 0;
+    data.size = size;
+    if(format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED)
+        data.align = 8192;
+    else
+        data.align = getpagesize();
+    data.pHandle = (unsigned int) pHandle;
+    err = mAllocCtrl->allocate(data, usage, compositionType);
+
+    if (usage & GRALLOC_USAGE_PRIVATE_UNSYNCHRONIZED) {
+        flags |= private_handle_t::PRIV_FLAGS_UNSYNCHRONIZED;
+    }
+
+    if (usage & GRALLOC_USAGE_EXTERNAL_ONLY) {
+        flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY;
+        //The EXTERNAL_BLOCK flag is always an add-on
+        if (usage & GRALLOC_USAGE_EXTERNAL_BLOCK) {
+            flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_BLOCK;
+        }
+    }
+
+    if (err == 0) {
+        flags |= data.allocType;
+        private_handle_t* hnd = new private_handle_t(data.fd, size, flags,
+                bufferType, format, width, height);
+
+        hnd->offset = data.offset;
+        hnd->base = int(data.base) + data.offset;
+        *pHandle = hnd;
+    }
+
+    ALOGE_IF(err, "gralloc failed err=%s", strerror(-err));
+    return err;
+}
+
+void gpu_context_t::getGrallocInformationFromFormat(int inputFormat,
+                                                    int *colorFormat,
+                                                    int *bufferType)
+{
+    *bufferType = BUFFER_TYPE_VIDEO;
+    *colorFormat = inputFormat;
+
+    if (inputFormat == HAL_PIXEL_FORMAT_YV12) {
+        *bufferType = BUFFER_TYPE_VIDEO;
+    } else if (inputFormat & S3D_FORMAT_MASK) {
+        // S3D format
+        *colorFormat = COLOR_FORMAT(inputFormat);
+    } else if (inputFormat & INTERLACE_MASK) {
+        // Interlaced
+        *colorFormat = inputFormat ^ HAL_PIXEL_FORMAT_INTERLACE;
+    } else if (inputFormat < 0x7) {
+        // RGB formats
+        *colorFormat = inputFormat;
+        *bufferType = BUFFER_TYPE_UI;
+    } else if ((inputFormat == HAL_PIXEL_FORMAT_R_8) ||
+               (inputFormat == HAL_PIXEL_FORMAT_RG_88)) {
+        *colorFormat = inputFormat;
+        *bufferType = BUFFER_TYPE_UI;
+    }
+}
+
+int gpu_context_t::alloc_impl(int w, int h, int format, int usage,
+        buffer_handle_t* pHandle, int* pStride, size_t bufferSize) {
+    if (!pHandle || !pStride)
+        return -EINVAL;
+
+    size_t size;
+    int alignedw, alignedh;
+    int colorFormat, bufferType;
+    getGrallocInformationFromFormat(format, &colorFormat, &bufferType);
+    size = getBufferSizeAndDimensions(w, h, colorFormat, alignedw, alignedh);
+
+    if ((ssize_t)size <= 0)
+        return -EINVAL;
+    size = (bufferSize >= size)? bufferSize : size;
+
+    // All buffers marked as protected or for external
+    // display need to go to overlay
+    if ((usage & GRALLOC_USAGE_EXTERNAL_DISP) ||
+        (usage & GRALLOC_USAGE_PROTECTED)) {
+            bufferType = BUFFER_TYPE_VIDEO;
+    }
+    int err;
+    if (usage & GRALLOC_USAGE_HW_FB) {
+        err = gralloc_alloc_framebuffer(size, usage, pHandle);
+    } else {
+        err = gralloc_alloc_buffer(size, usage, pHandle, bufferType,
+                                   format, alignedw, alignedh);
+    }
+
+    if (err < 0) {
+        return err;
+    }
+
+    // Create a genlock lock for this buffer handle.
+    err = genlock_create_lock((native_handle_t*)(*pHandle));
+    if (err) {
+        ALOGE("%s: genlock_create_lock failed", __FUNCTION__);
+        free_impl(reinterpret_cast<private_handle_t*>(pHandle));
+        return err;
+    }
+    *pStride = alignedw;
+    return 0;
+}
+
+int gpu_context_t::free_impl(private_handle_t const* hnd) {
+    private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
+    if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
+        // free this buffer
+        const size_t bufferSize = m->finfo.line_length * m->info.yres;
+        int index = (hnd->base - m->framebuffer->base) / bufferSize;
+        m->bufferMask &= ~(1<<index);
+    } else {
+        sp<IMemAlloc> memalloc = mAllocCtrl->getAllocator(hnd->flags);
+        int err = memalloc->free_buffer((void*)hnd->base, (size_t) hnd->size,
+                hnd->offset, hnd->fd);
+        if(err)
+            return err;
+        terminateBuffer(&m->base, const_cast<private_handle_t*>(hnd));
+    }
+
+    // Release the genlock
+    int err = genlock_release_lock((native_handle_t*)hnd);
+    if (err) {
+        ALOGE("%s: genlock_release_lock failed", __FUNCTION__);
+    }
+
+    delete hnd;
+    return 0;
+}
+
+int gpu_context_t::gralloc_alloc(alloc_device_t* dev, int w, int h, int format,
+        int usage, buffer_handle_t* pHandle, int* pStride)
+{
+    if (!dev) {
+        return -EINVAL;
+    }
+    gpu_context_t* gpu = reinterpret_cast<gpu_context_t*>(dev);
+    return gpu->alloc_impl(w, h, format, usage, pHandle, pStride, 0);
+}
+int gpu_context_t::gralloc_alloc_size(alloc_device_t* dev, int w, int h, int format,
+        int usage, buffer_handle_t* pHandle, int* pStride, int bufferSize)
+{
+    if (!dev) {
+        return -EINVAL;
+    }
+    gpu_context_t* gpu = reinterpret_cast<gpu_context_t*>(dev);
+    return gpu->alloc_impl(w, h, format, usage, pHandle, pStride, bufferSize);
+}
+
+
+int gpu_context_t::gralloc_free(alloc_device_t* dev,
+        buffer_handle_t handle)
+{
+    if (private_handle_t::validate(handle) < 0)
+        return -EINVAL;
+
+    private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(handle);
+    gpu_context_t* gpu = reinterpret_cast<gpu_context_t*>(dev);
+    return gpu->free_impl(hnd);
+}
+
+/*****************************************************************************/
+
+int gpu_context_t::gralloc_close(struct hw_device_t *dev)
+{
+    gpu_context_t* ctx = reinterpret_cast<gpu_context_t*>(dev);
+    if (ctx) {
+        /* TODO: keep a list of all buffer_handle_t created, and free them
+         * all here.
+         */
+        delete ctx;
+    }
+    return 0;
+}
+
diff --git a/libgralloc/gpu.h b/libgralloc/gpu.h
new file mode 100644
index 0000000..301c411
--- /dev/null
+++ b/libgralloc/gpu.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2011 Code Aurora Forum. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.
+ */
+
+#ifndef GRALLOC_GPU_H_
+#define GRALLOC_GPU_H_
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <cutils/log.h>
+#include <cutils/ashmem.h>
+#include <utils/RefBase.h>
+
+#include "gralloc_priv.h"
+
+namespace gralloc {
+    class IAllocController;
+    class gpu_context_t : public alloc_device_t {
+        public:
+            gpu_context_t(const private_module_t* module,
+                          android::sp<IAllocController>alloc_ctrl);
+
+            int gralloc_alloc_framebuffer_locked(size_t size, int usage,
+                                                 buffer_handle_t* pHandle);
+
+            int gralloc_alloc_framebuffer(size_t size, int usage,
+                                          buffer_handle_t* pHandle);
+
+            int gralloc_alloc_buffer(size_t size, int usage,
+                                     buffer_handle_t* pHandle,
+                                     int bufferType, int format,
+                                     int width, int height);
+
+            int free_impl(private_handle_t const* hnd);
+
+            int alloc_impl(int w, int h, int format, int usage,
+                           buffer_handle_t* pHandle, int* pStride,
+                           size_t bufferSize = 0);
+
+            static int gralloc_alloc(alloc_device_t* dev, int w, int h,
+                                     int format, int usage,
+                                     buffer_handle_t* pHandle,
+                                     int* pStride);
+
+            static int gralloc_free(alloc_device_t* dev, buffer_handle_t handle);
+
+            static int gralloc_alloc_size(alloc_device_t* dev,
+                                          int w, int h, int format,
+                                          int usage, buffer_handle_t* pHandle,
+                                          int* pStride, int bufferSize);
+
+            static int gralloc_close(struct hw_device_t *dev);
+
+            int get_composition_type() const { return compositionType; }
+
+
+        private:
+            android::sp<IAllocController> mAllocCtrl;
+            int compositionType;
+            void getGrallocInformationFromFormat(int inputFormat,
+                                                 int *colorFormat,
+                                                 int *bufferType);
+    };
+}
+#endif  // GRALLOC_GPU_H
diff --git a/libgralloc/gr.h b/libgralloc/gr.h
new file mode 100644
index 0000000..cc36d9a
--- /dev/null
+++ b/libgralloc/gr.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2011 Code Aurora Forum. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.
+ */
+
+#ifndef GR_H_
+#define GR_H_
+
+#include <stdint.h>
+#ifdef HAVE_ANDROID_OS      // just want PAGE_SIZE define
+# include <asm/page.h>
+#else
+# include <sys/user.h>
+#endif
+#include <limits.h>
+#include <sys/cdefs.h>
+#include <hardware/gralloc.h>
+#include <pthread.h>
+#include <errno.h>
+
+#include <cutils/native_handle.h>
+
+/*****************************************************************************/
+
+struct private_module_t;
+struct private_handle_t;
+
+inline size_t roundUpToPageSize(size_t x) {
+    return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
+}
+
+inline size_t ALIGN(size_t x, size_t align) {
+    return (x + align-1) & ~(align-1);
+}
+
+#define FALSE 0
+#define TRUE  1
+
+int mapFrameBufferLocked(struct private_module_t* module);
+int terminateBuffer(gralloc_module_t const* module, private_handle_t* hnd);
+size_t getBufferSizeAndDimensions(int width, int height, int format,
+                        int& alignedw, int &alignedh);
+
+int decideBufferHandlingMechanism(int format, const char *compositionUsed,
+                                   int hasBlitEngine, int *needConversion,
+                                   int *useBufferDirectly);
+
+// Allocate buffer from width, height, format into a private_handle_t
+// It is the responsibility of the caller to free the buffer
+int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage);
+void free_buffer(private_handle_t *hnd);
+
+/*****************************************************************************/
+
+class Locker {
+    pthread_mutex_t mutex;
+public:
+    class Autolock {
+        Locker& locker;
+    public:
+        inline Autolock(Locker& locker) : locker(locker) {  locker.lock(); }
+        inline ~Autolock() { locker.unlock(); }
+    };
+    inline Locker()        { pthread_mutex_init(&mutex, 0); }
+    inline ~Locker()       { pthread_mutex_destroy(&mutex); }
+    inline void lock()     { pthread_mutex_lock(&mutex); }
+    inline void unlock()   { pthread_mutex_unlock(&mutex); }
+};
+
+#endif /* GR_H_ */
diff --git a/libgralloc/gralloc.cpp b/libgralloc/gralloc.cpp
new file mode 100644
index 0000000..a98baf8
--- /dev/null
+++ b/libgralloc/gralloc.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2008, The Android Open Source Project
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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 <unistd.h>
+#include <fcntl.h>
+
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <cutils/properties.h>
+#include <utils/RefBase.h>
+
+#include <linux/android_pmem.h>
+
+#include "gr.h"
+#include "gpu.h"
+#include "memalloc.h"
+#include "alloc_controller.h"
+
+using namespace gralloc;
+using android::sp;
+
+int fb_device_open(const hw_module_t* module, const char* name,
+        hw_device_t** device);
+
+static int gralloc_device_open(const hw_module_t* module, const char* name,
+        hw_device_t** device);
+
+extern int gralloc_lock(gralloc_module_t const* module,
+        buffer_handle_t handle, int usage,
+        int l, int t, int w, int h,
+        void** vaddr);
+
+extern int gralloc_unlock(gralloc_module_t const* module,
+        buffer_handle_t handle);
+
+extern int gralloc_register_buffer(gralloc_module_t const* module,
+        buffer_handle_t handle);
+
+extern int gralloc_unregister_buffer(gralloc_module_t const* module,
+        buffer_handle_t handle);
+
+extern int gralloc_perform(struct gralloc_module_t const* module,
+        int operation, ... );
+
+// HAL module methods
+static struct hw_module_methods_t gralloc_module_methods = {
+    open: gralloc_device_open
+};
+
+// HAL module initialize
+struct private_module_t HAL_MODULE_INFO_SYM = {
+    base: {
+        common: {
+            tag: HARDWARE_MODULE_TAG,
+            version_major: 1,
+            version_minor: 0,
+            id: GRALLOC_HARDWARE_MODULE_ID,
+            name: "Graphics Memory Allocator Module",
+            author: "The Android Open Source Project",
+            methods: &gralloc_module_methods,
+            dso: 0,
+            reserved: {0},
+        },
+        registerBuffer: gralloc_register_buffer,
+        unregisterBuffer: gralloc_unregister_buffer,
+        lock: gralloc_lock,
+        unlock: gralloc_unlock,
+        perform: gralloc_perform,
+        reserved_proc: {0},
+    },
+    framebuffer: 0,
+    fbFormat: 0,
+    flags: 0,
+    numBuffers: 0,
+    bufferMask: 0,
+    lock: PTHREAD_MUTEX_INITIALIZER,
+    currentBuffer: 0,
+};
+
+// Open Gralloc device
+int gralloc_device_open(const hw_module_t* module, const char* name,
+        hw_device_t** device)
+{
+    int status = -EINVAL;
+    if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
+        const private_module_t* m = reinterpret_cast<const private_module_t*>(
+                module);
+        gpu_context_t *dev;
+        sp<IAllocController> alloc_ctrl = IAllocController::getInstance(true);
+        dev = new gpu_context_t(m, alloc_ctrl);
+        *device = &dev->common;
+        status = 0;
+    } else {
+        status = fb_device_open(module, name, device);
+    }
+    return status;
+}
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
new file mode 100644
index 0000000..0679621
--- /dev/null
+++ b/libgralloc/gralloc_priv.h
@@ -0,0 +1,400 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.
+ */
+
+#ifndef GRALLOC_PRIV_H_
+#define GRALLOC_PRIV_H_
+
+#include <stdint.h>
+#include <limits.h>
+#include <sys/cdefs.h>
+#include <hardware/gralloc.h>
+#include <pthread.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <cutils/native_handle.h>
+
+#include <linux/fb.h>
+
+#if defined(__cplusplus) && defined(HDMI_DUAL_DISPLAY)
+#include "overlayLib.h"
+using namespace overlay;
+#endif
+
+#include <cutils/log.h>
+
+enum {
+    /* gralloc usage bits indicating the type
+     * of allocation that should be used */
+
+    /* ADSP heap is deprecated, use only if using pmem */
+    GRALLOC_USAGE_PRIVATE_ADSP_HEAP       =       GRALLOC_USAGE_PRIVATE_0,
+    /* SF heap is used for application buffers, is not secured */
+    GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP  =       GRALLOC_USAGE_PRIVATE_1,
+    /* SMI heap is deprecated, use only if using pmem */
+    GRALLOC_USAGE_PRIVATE_SMI_HEAP        =       GRALLOC_USAGE_PRIVATE_2,
+    /* SYSTEM heap comes from kernel vmalloc,
+     * can never be uncached, is not secured*/
+    GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP     =       GRALLOC_USAGE_PRIVATE_3,
+    /* IOMMU heap comes from manually allocated pages,
+     * can be cached/uncached, is not secured */
+    GRALLOC_USAGE_PRIVATE_IOMMU_HEAP      =       0x01000000,
+    /* MM heap is a carveout heap for video, can be secured*/
+    GRALLOC_USAGE_PRIVATE_MM_HEAP         =       0x02000000,
+    /* WRITEBACK heap is a carveout heap for writeback, can be secured*/
+    GRALLOC_USAGE_PRIVATE_WRITEBACK_HEAP  =       0x04000000,
+    /* CAMERA heap is a carveout heap for camera, is not secured*/
+    GRALLOC_USAGE_PRIVATE_CAMERA_HEAP     =       0x08000000,
+
+    /* Set this for allocating uncached memory (using O_DSYNC)
+     * cannot be used with noncontiguous heaps */
+    GRALLOC_USAGE_PRIVATE_UNCACHED        =       0x00100000,
+
+    /* This flag needs to be set when using a non-contiguous heap from ION.
+     * If not set, the system heap is assumed to be coming from ashmem
+     */
+    GRALLOC_USAGE_PRIVATE_ION             =       0x00200000,
+
+    /* This flag can be set to disable genlock synchronization
+     * for the gralloc buffer. If this flag is set the caller
+     * is required to perform explicit synchronization.
+     * WARNING - flag is outside the standard PRIVATE region
+     * and may need to be moved if the gralloc API changes
+     */
+    GRALLOC_USAGE_PRIVATE_UNSYNCHRONIZED  =       0X00400000,
+
+    /* Set this flag when you need to avoid mapping the memory in userspace */
+    GRALLOC_USAGE_PRIVATE_DO_NOT_MAP      =       0X00800000,
+
+    /* Buffer content should be displayed on an external display only */
+    GRALLOC_USAGE_EXTERNAL_ONLY           =       0x00010000,
+
+    /* Only this buffer content should be displayed on external, even if
+     * other EXTERNAL_ONLY buffers are available. Used during suspend.
+     */
+    GRALLOC_USAGE_EXTERNAL_BLOCK          =       0x00020000,
+};
+
+enum {
+    /* Gralloc perform enums
+    */
+    GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER = 0x080000001,
+};
+
+
+enum {
+    GPU_COMPOSITION,
+    C2D_COMPOSITION,
+    MDP_COMPOSITION,
+    CPU_COMPOSITION,
+};
+
+/* numbers of max buffers for page flipping */
+#define NUM_FRAMEBUFFERS_MIN 2
+#define NUM_FRAMEBUFFERS_MAX 3
+
+/* number of default bufers for page flipping */
+#define NUM_DEF_FRAME_BUFFERS 2
+#define NO_SURFACEFLINGER_SWAPINTERVAL
+#define INTERLACE_MASK 0x80
+#define S3D_FORMAT_MASK 0xFF000
+#define COLOR_FORMAT(x) (x & 0xFFF) // Max range for colorFormats is 0 - FFF
+#define DEVICE_PMEM "/dev/pmem"
+#define DEVICE_PMEM_ADSP "/dev/pmem_adsp"
+#define DEVICE_PMEM_SMIPOOL "/dev/pmem_smipool"
+/*****************************************************************************/
+#ifdef __cplusplus
+
+//XXX: Remove framebuffer specific classes and defines to a different header
+template <class T>
+struct Node
+{
+    T data;
+    Node<T> *next;
+};
+
+template <class T>
+class Queue
+{
+public:
+    Queue(): front(NULL), back(NULL), len(0) {dummy = new T;}
+    ~Queue()
+    {
+        clear();
+        delete dummy;
+    }
+    void push(const T& item)   //add an item to the back of the queue
+    {
+        if(len != 0) {         //if the queue is not empty
+            back->next = new Node<T>; //create a new node
+            back = back->next; //set the new node as the back node
+            back->data = item;
+            back->next = NULL;
+        } else {
+            back = new Node<T>;
+            back->data = item;
+            back->next = NULL;
+            front = back;
+       }
+       len++;
+    }
+    void pop()                 //remove the first item from the queue
+    {
+        if (isEmpty())
+            return;            //if the queue is empty, no node to dequeue
+        T item = front->data;
+        Node<T> *tmp = front;
+        front = front->next;
+        delete tmp;
+        if(front == NULL)      //if the queue is empty, update the back pointer
+            back = NULL;
+        len--;
+        return;
+    }
+    T& getHeadValue() const    //return the value of the first item in the queue
+    {                          //without modification to the structure
+        if (isEmpty()) {
+            ALOGE("Error can't get head of empty queue");
+            return *dummy;
+        }
+        return front->data;
+    }
+
+    bool isEmpty() const       //returns true if no elements are in the queue
+    {
+        return (front == NULL);
+    }
+
+    size_t size() const        //returns the amount of elements in the queue
+    {
+        return len;
+    }
+
+private:
+    Node<T> *front;
+    Node<T> *back;
+    size_t len;
+    void clear()
+    {
+        while (!isEmpty())
+            pop();
+    }
+    T *dummy;
+};
+#endif
+
+enum {
+    /* OEM specific HAL formats */
+    HAL_PIXEL_FORMAT_NV12_ENCODEABLE  = 0x102,
+    HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED     = 0x108,
+    HAL_PIXEL_FORMAT_YCbCr_420_SP           = 0x109,
+    HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO    = 0x10A,
+    HAL_PIXEL_FORMAT_YCrCb_422_SP           = 0x10B,
+    HAL_PIXEL_FORMAT_R_8                    = 0x10D,
+    HAL_PIXEL_FORMAT_RG_88                  = 0x10E,
+    HAL_PIXEL_FORMAT_INTERLACE              = 0x180,
+
+};
+
+/* possible formats for 3D content*/
+enum {
+    HAL_NO_3D                         = 0x0000,
+    HAL_3D_IN_SIDE_BY_SIDE_L_R        = 0x10000,
+    HAL_3D_IN_TOP_BOTTOM              = 0x20000,
+    HAL_3D_IN_INTERLEAVE              = 0x40000,
+    HAL_3D_IN_SIDE_BY_SIDE_R_L        = 0x80000,
+    HAL_3D_OUT_SIDE_BY_SIDE           = 0x1000,
+    HAL_3D_OUT_TOP_BOTTOM             = 0x2000,
+    HAL_3D_OUT_INTERLEAVE             = 0x4000,
+    HAL_3D_OUT_MONOSCOPIC             = 0x8000
+};
+
+enum {
+	BUFFER_TYPE_UI = 0,
+	BUFFER_TYPE_VIDEO
+};
+
+#if defined(HDMI_DUAL_DISPLAY)
+enum hdmi_mirroring_state {
+    HDMI_NO_MIRRORING,
+    HDMI_UI_MIRRORING,
+    HDMI_ORIGINAL_RESOLUTION_MIRRORING
+};
+#endif
+/*****************************************************************************/
+
+struct private_module_t;
+struct private_handle_t;
+struct PmemAllocator;
+
+struct qbuf_t {
+    buffer_handle_t buf;
+    int  idx;
+};
+
+enum buf_state {
+    SUB,
+    REF,
+    AVL
+};
+
+struct avail_t {
+    pthread_mutex_t lock;
+    pthread_cond_t cond;
+#ifdef __cplusplus
+    bool is_avail;
+    buf_state state;
+#endif
+};
+
+struct private_module_t {
+    gralloc_module_t base;
+
+    struct private_handle_t* framebuffer;
+    uint32_t fbFormat;
+    uint32_t flags;
+    uint32_t numBuffers;
+    uint32_t bufferMask;
+    pthread_mutex_t lock;
+    buffer_handle_t currentBuffer;
+
+    struct fb_var_screeninfo info;
+    struct fb_fix_screeninfo finfo;
+    float xdpi;
+    float ydpi;
+    float fps;
+    int swapInterval;
+#ifdef __cplusplus
+    Queue<struct qbuf_t> disp; // non-empty when buffer is ready for display
+#endif
+    int currentIdx;
+    struct avail_t avail[NUM_FRAMEBUFFERS_MAX];
+    pthread_mutex_t qlock;
+    pthread_cond_t qpost;
+
+    enum {
+        // flag to indicate we'll post this buffer
+        PRIV_USAGE_LOCKED_FOR_POST = 0x80000000,
+        PRIV_MIN_SWAP_INTERVAL = 0,
+        PRIV_MAX_SWAP_INTERVAL = 1,
+    };
+#if defined(__cplusplus) && defined(HDMI_DUAL_DISPLAY)
+    Overlay* pobjOverlay;
+    int orientation;
+    bool videoOverlay;
+    uint32_t currentOffset;
+    int enableHDMIOutput; // holds the type of external display
+    bool trueMirrorSupport;
+    bool exitHDMIUILoop;
+    float actionsafeWidthRatio;
+    float actionsafeHeightRatio;
+    bool hdmiStateChanged;
+    hdmi_mirroring_state hdmiMirroringState;
+    pthread_mutex_t overlayLock;
+    pthread_cond_t overlayPost;
+#endif
+};
+
+/*****************************************************************************/
+
+#ifdef __cplusplus
+struct private_handle_t : public native_handle {
+#else
+struct private_handle_t {
+    native_handle_t nativeHandle;
+#endif
+    enum {
+        PRIV_FLAGS_FRAMEBUFFER    = 0x00000001,
+        PRIV_FLAGS_USES_PMEM      = 0x00000002,
+        PRIV_FLAGS_USES_PMEM_ADSP = 0x00000004,
+        PRIV_FLAGS_USES_ION       = 0x00000008,
+        PRIV_FLAGS_USES_ASHMEM    = 0x00000010,
+        PRIV_FLAGS_NEEDS_FLUSH    = 0x00000020,
+        PRIV_FLAGS_DO_NOT_FLUSH   = 0x00000040,
+        PRIV_FLAGS_SW_LOCK        = 0x00000080,
+        PRIV_FLAGS_NONCONTIGUOUS_MEM = 0x00000100,
+        PRIV_FLAGS_HWC_LOCK       = 0x00000200, // Set by HWC when storing the handle
+        PRIV_FLAGS_SECURE_BUFFER  = 0x00000400,
+        PRIV_FLAGS_UNSYNCHRONIZED = 0x00000800, // For explicit synchronization
+        PRIV_FLAGS_NOT_MAPPED     = 0x00001000, // Not mapped in userspace
+        PRIV_FLAGS_EXTERNAL_ONLY  = 0x00002000, // Display on external only
+        PRIV_FLAGS_EXTERNAL_BLOCK = 0x00004000, // Display only this buffer on external
+    };
+
+    // file-descriptors
+    int     fd;
+    int     genlockHandle; // genlock handle to be dup'd by the binder
+    // ints
+    int     magic;
+    int     flags;
+    int     size;
+    int     offset;
+    int     bufferType;
+
+    // FIXME: the attributes below should be out-of-line
+    int     base;
+    int     gpuaddr; // The gpu address mapped into the mmu. If using ashmem, set to 0 They don't care
+    int     pid;
+    int     format;
+    int     width;
+    int     height;
+    int     genlockPrivFd; // local fd of the genlock device.
+
+#ifdef __cplusplus
+    static const int sNumInts = 12;
+    static const int sNumFds = 2;
+    static const int sMagic = 'gmsm';
+
+    private_handle_t(int fd, int size, int flags, int bufferType, int format, int width, int height) :
+        fd(fd), genlockHandle(-1), magic(sMagic), flags(flags), size(size), offset(0),
+        bufferType(bufferType), base(0), gpuaddr(0), pid(getpid()), format(format),
+        width(width), height(height), genlockPrivFd(-1)
+    {
+        version = sizeof(native_handle);
+        numInts = sNumInts;
+        numFds = sNumFds;
+    }
+    ~private_handle_t() {
+        magic = 0;
+    }
+
+    bool usesPhysicallyContiguousMemory() {
+        return (flags & PRIV_FLAGS_USES_PMEM) != 0;
+    }
+
+    static int validate(const native_handle* h) {
+        const private_handle_t* hnd = (const private_handle_t*)h;
+        if (!h || h->version != sizeof(native_handle) ||
+                h->numInts != sNumInts || h->numFds != sNumFds ||
+                hnd->magic != sMagic)
+        {
+            ALOGE("invalid gralloc handle (at %p)", h);
+            return -EINVAL;
+        }
+        return 0;
+    }
+
+    static private_handle_t* dynamicCast(const native_handle* in) {
+        if (validate(in) == 0) {
+            return (private_handle_t*) in;
+        }
+        return NULL;
+    }
+#endif
+};
+
+#endif /* GRALLOC_PRIV_H_ */
diff --git a/libgralloc/ion_msm.h b/libgralloc/ion_msm.h
new file mode 100644
index 0000000..ae49bce
--- /dev/null
+++ b/libgralloc/ion_msm.h
@@ -0,0 +1,836 @@
+/*
+ * include/linux/ion.h
+ *
+ * Copyright (C) 2011 Google, Inc.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _LINUX_ION_H
+#define _LINUX_ION_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+
+struct ion_handle;
+/**
+ * enum ion_heap_types - list of all possible types of heaps
+ * @ION_HEAP_TYPE_SYSTEM:	 memory allocated via vmalloc
+ * @ION_HEAP_TYPE_SYSTEM_CONTIG: memory allocated via kmalloc
+ * @ION_HEAP_TYPE_CARVEOUT:	 memory allocated from a prereserved
+ * 				 carveout heap, allocations are physically
+ * 				 contiguous
+ * @ION_HEAP_TYPE_IOMMU: IOMMU memory
+ * @ION_HEAP_TYPE_CP:	 memory allocated from a prereserved
+ *				carveout heap, allocations are physically
+ *				contiguous. Used for content protection.
+ * @ION_HEAP_END:		helper for iterating over heaps
+ */
+enum ion_heap_type {
+	ION_HEAP_TYPE_SYSTEM,
+	ION_HEAP_TYPE_SYSTEM_CONTIG,
+	ION_HEAP_TYPE_CARVEOUT,
+	ION_HEAP_TYPE_IOMMU,
+	ION_HEAP_TYPE_CP,
+	ION_HEAP_TYPE_CUSTOM, /* must be last so device specific heaps always
+				 are at the end of this enum */
+	ION_NUM_HEAPS,
+};
+
+#define ION_HEAP_SYSTEM_MASK		(1 << ION_HEAP_TYPE_SYSTEM)
+#define ION_HEAP_SYSTEM_CONTIG_MASK	(1 << ION_HEAP_TYPE_SYSTEM_CONTIG)
+#define ION_HEAP_CARVEOUT_MASK		(1 << ION_HEAP_TYPE_CARVEOUT)
+#define ION_HEAP_CP_MASK		(1 << ION_HEAP_TYPE_CP)
+
+
+/**
+ * These are the only ids that should be used for Ion heap ids.
+ * The ids listed are the order in which allocation will be attempted
+ * if specified. Don't swap the order of heap ids unless you know what
+ * you are doing!
+ * Id's are spaced by purpose to allow new Id's to be inserted in-between (for
+ * possible fallbacks)
+ */
+
+enum ion_heap_ids {
+	INVALID_HEAP_ID = -1,
+	ION_CP_MM_HEAP_ID = 8,
+	ION_CP_MFC_HEAP_ID = 12,
+	ION_CP_WB_HEAP_ID = 16, /* 8660 only */
+	ION_CAMERA_HEAP_ID = 20, /* 8660 only */
+	ION_SF_HEAP_ID = 24,
+	ION_IOMMU_HEAP_ID = 25,
+	ION_QSECOM_HEAP_ID = 27,
+	ION_AUDIO_HEAP_ID = 28,
+
+	ION_MM_FIRMWARE_HEAP_ID = 29,
+	ION_SYSTEM_HEAP_ID = 30,
+
+	ION_HEAP_ID_RESERVED = 31 /** Bit reserved for ION_SECURE flag */
+};
+
+enum ion_fixed_position {
+	NOT_FIXED,
+	FIXED_LOW,
+	FIXED_MIDDLE,
+	FIXED_HIGH,
+};
+
+/**
+ * Flag to use when allocating to indicate that a heap is secure.
+ */
+#define ION_SECURE (1 << ION_HEAP_ID_RESERVED)
+
+/**
+ * Macro should be used with ion_heap_ids defined above.
+ */
+#define ION_HEAP(bit) (1 << (bit))
+
+#define ION_VMALLOC_HEAP_NAME	"vmalloc"
+#define ION_AUDIO_HEAP_NAME	"audio"
+#define ION_SF_HEAP_NAME	"sf"
+#define ION_MM_HEAP_NAME	"mm"
+#define ION_CAMERA_HEAP_NAME	"camera_preview"
+#define ION_IOMMU_HEAP_NAME	"iommu"
+#define ION_MFC_HEAP_NAME	"mfc"
+#define ION_WB_HEAP_NAME	"wb"
+#define ION_MM_FIRMWARE_HEAP_NAME	"mm_fw"
+#define ION_QSECOM_HEAP_NAME	"qsecom"
+#define ION_FMEM_HEAP_NAME	"fmem"
+
+#define CACHED          1
+#define UNCACHED        0
+
+#define ION_CACHE_SHIFT 0
+
+#define ION_SET_CACHE(__cache)  ((__cache) << ION_CACHE_SHIFT)
+
+#define ION_IS_CACHED(__flags)	((__flags) & (1 << ION_CACHE_SHIFT))
+
+/*
+ * This flag allows clients when mapping into the IOMMU to specify to
+ * defer un-mapping from the IOMMU until the buffer memory is freed.
+ */
+#define ION_IOMMU_UNMAP_DELAYED 1
+
+#ifdef __KERNEL__
+#include <linux/err.h>
+#include <mach/ion.h>
+struct ion_device;
+struct ion_heap;
+struct ion_mapper;
+struct ion_client;
+struct ion_buffer;
+
+/* This should be removed some day when phys_addr_t's are fully
+   plumbed in the kernel, and all instances of ion_phys_addr_t should
+   be converted to phys_addr_t.  For the time being many kernel interfaces
+   do not accept phys_addr_t's that would have to */
+#define ion_phys_addr_t unsigned long
+#define ion_virt_addr_t unsigned long
+
+/**
+ * struct ion_platform_heap - defines a heap in the given platform
+ * @type:	type of the heap from ion_heap_type enum
+ * @id:		unique identifier for heap.  When allocating (lower numbers
+ * 		will be allocated from first)
+ * @name:	used for debug purposes
+ * @base:	base address of heap in physical memory if applicable
+ * @size:	size of the heap in bytes if applicable
+ * @memory_type:Memory type used for the heap
+ * @extra_data:	Extra data specific to each heap type
+ */
+struct ion_platform_heap {
+	enum ion_heap_type type;
+	unsigned int id;
+	const char *name;
+	ion_phys_addr_t base;
+	size_t size;
+	enum ion_memory_types memory_type;
+	void *extra_data;
+};
+
+/**
+ * struct ion_cp_heap_pdata - defines a content protection heap in the given
+ * platform
+ * @permission_type:	Memory ID used to identify the memory to TZ
+ * @align:		Alignment requirement for the memory
+ * @secure_base:	Base address for securing the heap.
+ *			Note: This might be different from actual base address
+ *			of this heap in the case of a shared heap.
+ * @secure_size:	Memory size for securing the heap.
+ *			Note: This might be different from actual size
+ *			of this heap in the case of a shared heap.
+ * @reusable		Flag indicating whether this heap is reusable of not.
+ *			(see FMEM)
+ * @mem_is_fmem		Flag indicating whether this memory is coming from fmem
+ *			or not.
+ * @fixed_position	If nonzero, position in the fixed area.
+ * @virt_addr:		Virtual address used when using fmem.
+ * @request_region:	function to be called when the number of allocations
+ *			goes from 0 -> 1
+ * @release_region:	function to be called when the number of allocations
+ *			goes from 1 -> 0
+ * @setup_region:	function to be called upon ion registration
+ *
+ */
+struct ion_cp_heap_pdata {
+	enum ion_permission_type permission_type;
+	unsigned int align;
+	ion_phys_addr_t secure_base; /* Base addr used when heap is shared */
+	size_t secure_size; /* Size used for securing heap when heap is shared*/
+	int reusable;
+	int mem_is_fmem;
+	enum ion_fixed_position fixed_position;
+	ion_virt_addr_t *virt_addr;
+	int (*request_region)(void *);
+	int (*release_region)(void *);
+	void *(*setup_region)(void);
+};
+
+/**
+ * struct ion_co_heap_pdata - defines a carveout heap in the given platform
+ * @adjacent_mem_id:	Id of heap that this heap must be adjacent to.
+ * @align:		Alignment requirement for the memory
+ * @mem_is_fmem		Flag indicating whether this memory is coming from fmem
+ *			or not.
+ * @fixed_position	If nonzero, position in the fixed area.
+ * @request_region:	function to be called when the number of allocations
+ *			goes from 0 -> 1
+ * @release_region:	function to be called when the number of allocations
+ *			goes from 1 -> 0
+ * @setup_region:	function to be called upon ion registration
+ *
+ */
+struct ion_co_heap_pdata {
+	int adjacent_mem_id;
+	unsigned int align;
+	int mem_is_fmem;
+	enum ion_fixed_position fixed_position;
+	int (*request_region)(void *);
+	int (*release_region)(void *);
+	void *(*setup_region)(void);
+};
+
+/**
+ * struct ion_platform_data - array of platform heaps passed from board file
+ * @nr:    number of structures in the array
+ * @request_region: function to be called when the number of allocations goes
+ *						from 0 -> 1
+ * @release_region: function to be called when the number of allocations goes
+ *						from 1 -> 0
+ * @setup_region:   function to be called upon ion registration
+ * @heaps: array of platform_heap structions
+ *
+ * Provided by the board file in the form of platform data to a platform device.
+ */
+struct ion_platform_data {
+	int nr;
+	int (*request_region)(void *);
+	int (*release_region)(void *);
+	void *(*setup_region)(void);
+	struct ion_platform_heap heaps[];
+};
+
+#ifdef CONFIG_ION
+
+/**
+ * ion_client_create() -  allocate a client and returns it
+ * @dev:	the global ion device
+ * @heap_mask:	mask of heaps this client can allocate from
+ * @name:	used for debugging
+ */
+struct ion_client *ion_client_create(struct ion_device *dev,
+				     unsigned int heap_mask, const char *name);
+
+/**
+ *  msm_ion_client_create - allocate a client using the ion_device specified in
+ *				drivers/gpu/ion/msm/msm_ion.c
+ *
+ * heap_mask and name are the same as ion_client_create, return values
+ * are the same as ion_client_create.
+ */
+
+struct ion_client *msm_ion_client_create(unsigned int heap_mask,
+					const char *name);
+
+/**
+ * ion_client_destroy() -  free's a client and all it's handles
+ * @client:	the client
+ *
+ * Free the provided client and all it's resources including
+ * any handles it is holding.
+ */
+void ion_client_destroy(struct ion_client *client);
+
+/**
+ * ion_alloc - allocate ion memory
+ * @client:	the client
+ * @len:	size of the allocation
+ * @align:	requested allocation alignment, lots of hardware blocks have
+ *		alignment requirements of some kind
+ * @flags:	mask of heaps to allocate from, if multiple bits are set
+ *		heaps will be tried in order from lowest to highest order bit
+ *
+ * Allocate memory in one of the heaps provided in heap mask and return
+ * an opaque handle to it.
+ */
+struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
+			     size_t align, unsigned int flags);
+
+/**
+ * ion_free - free a handle
+ * @client:	the client
+ * @handle:	the handle to free
+ *
+ * Free the provided handle.
+ */
+void ion_free(struct ion_client *client, struct ion_handle *handle);
+
+/**
+ * ion_phys - returns the physical address and len of a handle
+ * @client:	the client
+ * @handle:	the handle
+ * @addr:	a pointer to put the address in
+ * @len:	a pointer to put the length in
+ *
+ * This function queries the heap for a particular handle to get the
+ * handle's physical address.  It't output is only correct if
+ * a heap returns physically contiguous memory -- in other cases
+ * this api should not be implemented -- ion_map_dma should be used
+ * instead.  Returns -EINVAL if the handle is invalid.  This has
+ * no implications on the reference counting of the handle --
+ * the returned value may not be valid if the caller is not
+ * holding a reference.
+ */
+int ion_phys(struct ion_client *client, struct ion_handle *handle,
+	     ion_phys_addr_t *addr, size_t *len);
+
+/**
+ * ion_map_kernel - create mapping for the given handle
+ * @client:	the client
+ * @handle:	handle to map
+ * @flags:	flags for this mapping
+ *
+ * Map the given handle into the kernel and return a kernel address that
+ * can be used to access this address. If no flags are specified, this
+ * will return a non-secure uncached mapping.
+ */
+void *ion_map_kernel(struct ion_client *client, struct ion_handle *handle,
+			unsigned long flags);
+
+/**
+ * ion_unmap_kernel() - destroy a kernel mapping for a handle
+ * @client:	the client
+ * @handle:	handle to unmap
+ */
+void ion_unmap_kernel(struct ion_client *client, struct ion_handle *handle);
+
+/**
+ * ion_map_dma - create a dma mapping for a given handle
+ * @client:	the client
+ * @handle:	handle to map
+ *
+ * Return an sglist describing the given handle
+ */
+struct scatterlist *ion_map_dma(struct ion_client *client,
+				struct ion_handle *handle,
+				unsigned long flags);
+
+/**
+ * ion_unmap_dma() - destroy a dma mapping for a handle
+ * @client:	the client
+ * @handle:	handle to unmap
+ */
+void ion_unmap_dma(struct ion_client *client, struct ion_handle *handle);
+
+/**
+ * ion_share() - given a handle, obtain a buffer to pass to other clients
+ * @client:	the client
+ * @handle:	the handle to share
+ *
+ * Given a handle, return a buffer, which exists in a global name
+ * space, and can be passed to other clients.  Should be passed into ion_import
+ * to obtain a new handle for this buffer.
+ *
+ * NOTE: This function does do not an extra reference.  The burden is on the
+ * caller to make sure the buffer doesn't go away while it's being passed to
+ * another client.  That is, ion_free should not be called on this handle until
+ * the buffer has been imported into the other client.
+ */
+struct ion_buffer *ion_share(struct ion_client *client,
+			     struct ion_handle *handle);
+
+/**
+ * ion_import() - given an buffer in another client, import it
+ * @client:	this blocks client
+ * @buffer:	the buffer to import (as obtained from ion_share)
+ *
+ * Given a buffer, add it to the client and return the handle to use to refer
+ * to it further.  This is called to share a handle from one kernel client to
+ * another.
+ */
+struct ion_handle *ion_import(struct ion_client *client,
+			      struct ion_buffer *buffer);
+
+/**
+ * ion_import_fd() - given an fd obtained via ION_IOC_SHARE ioctl, import it
+ * @client:	this blocks client
+ * @fd:		the fd
+ *
+ * A helper function for drivers that will be recieving ion buffers shared
+ * with them from userspace.  These buffers are represented by a file
+ * descriptor obtained as the return from the ION_IOC_SHARE ioctl.
+ * This function coverts that fd into the underlying buffer, and returns
+ * the handle to use to refer to it further.
+ */
+struct ion_handle *ion_import_fd(struct ion_client *client, int fd);
+
+/**
+ * ion_handle_get_flags - get the flags for a given handle
+ *
+ * @client - client who allocated the handle
+ * @handle - handle to get the flags
+ * @flags - pointer to store the flags
+ *
+ * Gets the current flags for a handle. These flags indicate various options
+ * of the buffer (caching, security, etc.)
+ */
+int ion_handle_get_flags(struct ion_client *client, struct ion_handle *handle,
+				unsigned long *flags);
+
+
+/**
+ * ion_map_iommu - map the given handle into an iommu
+ *
+ * @client - client who allocated the handle
+ * @handle - handle to map
+ * @domain_num - domain number to map to
+ * @partition_num - partition number to allocate iova from
+ * @align - alignment for the iova
+ * @iova_length - length of iova to map. If the iova length is
+ *		greater than the handle length, the remaining
+ *		address space will be mapped to a dummy buffer.
+ * @iova - pointer to store the iova address
+ * @buffer_size - pointer to store the size of the buffer
+ * @flags - flags for options to map
+ * @iommu_flags - flags specific to the iommu.
+ *
+ * Maps the handle into the iova space specified via domain number. Iova
+ * will be allocated from the partition specified via partition_num.
+ * Returns 0 on success, negative value on error.
+ */
+int ion_map_iommu(struct ion_client *client, struct ion_handle *handle,
+			int domain_num, int partition_num, unsigned long align,
+			unsigned long iova_length, unsigned long *iova,
+			unsigned long *buffer_size,
+			unsigned long flags, unsigned long iommu_flags);
+
+
+/**
+ * ion_handle_get_size - get the allocated size of a given handle
+ *
+ * @client - client who allocated the handle
+ * @handle - handle to get the size
+ * @size - pointer to store the size
+ *
+ * gives the allocated size of a handle. returns 0 on success, negative
+ * value on error
+ *
+ * NOTE: This is intended to be used only to get a size to pass to map_iommu.
+ * You should *NOT* rely on this for any other usage.
+ */
+
+int ion_handle_get_size(struct ion_client *client, struct ion_handle *handle,
+			unsigned long *size);
+
+/**
+ * ion_unmap_iommu - unmap the handle from an iommu
+ *
+ * @client - client who allocated the handle
+ * @handle - handle to unmap
+ * @domain_num - domain to unmap from
+ * @partition_num - partition to unmap from
+ *
+ * Decrement the reference count on the iommu mapping. If the count is
+ * 0, the mapping will be removed from the iommu.
+ */
+void ion_unmap_iommu(struct ion_client *client, struct ion_handle *handle,
+			int domain_num, int partition_num);
+
+
+/**
+ * ion_secure_heap - secure a heap
+ *
+ * @client - a client that has allocated from the heap heap_id
+ * @heap_id - heap id to secure.
+ *
+ * Secure a heap
+ * Returns 0 on success
+ */
+int ion_secure_heap(struct ion_device *dev, int heap_id);
+
+/**
+ * ion_unsecure_heap - un-secure a heap
+ *
+ * @client - a client that has allocated from the heap heap_id
+ * @heap_id - heap id to un-secure.
+ *
+ * Un-secure a heap
+ * Returns 0 on success
+ */
+int ion_unsecure_heap(struct ion_device *dev, int heap_id);
+
+/**
+ * msm_ion_secure_heap - secure a heap. Wrapper around ion_secure_heap.
+ *
+  * @heap_id - heap id to secure.
+ *
+ * Secure a heap
+ * Returns 0 on success
+ */
+int msm_ion_secure_heap(int heap_id);
+
+/**
+ * msm_ion_unsecure_heap - unsecure a heap. Wrapper around ion_unsecure_heap.
+ *
+  * @heap_id - heap id to secure.
+ *
+ * Un-secure a heap
+ * Returns 0 on success
+ */
+int msm_ion_unsecure_heap(int heap_id);
+
+/**
+ * msm_ion_do_cache_op - do cache operations.
+ *
+ * @client - pointer to ION client.
+ * @handle - pointer to buffer handle.
+ * @vaddr -  virtual address to operate on.
+ * @len - Length of data to do cache operation on.
+ * @cmd - Cache operation to perform:
+ *		ION_IOC_CLEAN_CACHES
+ *		ION_IOC_INV_CACHES
+ *		ION_IOC_CLEAN_INV_CACHES
+ *
+ * Returns 0 on success
+ */
+int msm_ion_do_cache_op(struct ion_client *client, struct ion_handle *handle,
+			void *vaddr, unsigned long len, unsigned int cmd);
+
+#else
+static inline struct ion_client *ion_client_create(struct ion_device *dev,
+				     unsigned int heap_mask, const char *name)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline struct ion_client *msm_ion_client_create(unsigned int heap_mask,
+					const char *name)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline void ion_client_destroy(struct ion_client *client) { }
+
+static inline struct ion_handle *ion_alloc(struct ion_client *client,
+			size_t len, size_t align, unsigned int flags)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline void ion_free(struct ion_client *client,
+	struct ion_handle *handle) { }
+
+
+static inline int ion_phys(struct ion_client *client,
+	struct ion_handle *handle, ion_phys_addr_t *addr, size_t *len)
+{
+	return -ENODEV;
+}
+
+static inline void *ion_map_kernel(struct ion_client *client,
+	struct ion_handle *handle, unsigned long flags)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline void ion_unmap_kernel(struct ion_client *client,
+	struct ion_handle *handle) { }
+
+static inline struct scatterlist *ion_map_dma(struct ion_client *client,
+	struct ion_handle *handle, unsigned long flags)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline void ion_unmap_dma(struct ion_client *client,
+	struct ion_handle *handle) { }
+
+static inline struct ion_buffer *ion_share(struct ion_client *client,
+	struct ion_handle *handle)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline struct ion_handle *ion_import(struct ion_client *client,
+	struct ion_buffer *buffer)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline struct ion_handle *ion_import_fd(struct ion_client *client,
+	int fd)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline int ion_handle_get_flags(struct ion_client *client,
+	struct ion_handle *handle, unsigned long *flags)
+{
+	return -ENODEV;
+}
+
+static inline int ion_map_iommu(struct ion_client *client,
+			struct ion_handle *handle, int domain_num,
+			int partition_num, unsigned long align,
+			unsigned long iova_length, unsigned long *iova,
+			unsigned long *buffer_size,
+			unsigned long flags,
+			unsigned long iommu_flags)
+{
+	return -ENODEV;
+}
+
+static inline void ion_unmap_iommu(struct ion_client *client,
+			struct ion_handle *handle, int domain_num,
+			int partition_num)
+{
+	return;
+}
+
+static inline int ion_secure_heap(struct ion_device *dev, int heap_id)
+{
+	return -ENODEV;
+
+}
+
+static inline int ion_unsecure_heap(struct ion_device *dev, int heap_id)
+{
+	return -ENODEV;
+}
+
+static inline int msm_ion_secure_heap(int heap_id)
+{
+	return -ENODEV;
+
+}
+
+static inline int msm_ion_unsecure_heap(int heap_id)
+{
+	return -ENODEV;
+}
+
+static inline int msm_ion_do_cache_op(struct ion_client *client,
+			struct ion_handle *handle, void *vaddr,
+			unsigned long len, unsigned int cmd)
+{
+	return -ENODEV;
+}
+
+#endif /* CONFIG_ION */
+#endif /* __KERNEL__ */
+
+/**
+ * DOC: Ion Userspace API
+ *
+ * create a client by opening /dev/ion
+ * most operations handled via following ioctls
+ *
+ */
+
+/**
+ * struct ion_allocation_data - metadata passed from userspace for allocations
+ * @len:	size of the allocation
+ * @align:	required alignment of the allocation
+ * @flags:	flags passed to heap
+ * @handle:	pointer that will be populated with a cookie to use to refer
+ *		to this allocation
+ *
+ * Provided by userspace as an argument to the ioctl
+ */
+struct ion_allocation_data {
+	size_t len;
+	size_t align;
+	unsigned int flags;
+	struct ion_handle *handle;
+};
+
+/**
+ * struct ion_fd_data - metadata passed to/from userspace for a handle/fd pair
+ * @handle:	a handle
+ * @fd:		a file descriptor representing that handle
+ *
+ * For ION_IOC_SHARE or ION_IOC_MAP userspace populates the handle field with
+ * the handle returned from ion alloc, and the kernel returns the file
+ * descriptor to share or map in the fd field.  For ION_IOC_IMPORT, userspace
+ * provides the file descriptor and the kernel returns the handle.
+ */
+struct ion_fd_data {
+	struct ion_handle *handle;
+	int fd;
+};
+
+/**
+ * struct ion_handle_data - a handle passed to/from the kernel
+ * @handle:	a handle
+ */
+struct ion_handle_data {
+	struct ion_handle *handle;
+};
+
+/**
+ * struct ion_custom_data - metadata passed to/from userspace for a custom ioctl
+ * @cmd:	the custom ioctl function to call
+ * @arg:	additional data to pass to the custom ioctl, typically a user
+ *		pointer to a predefined structure
+ *
+ * This works just like the regular cmd and arg fields of an ioctl.
+ */
+struct ion_custom_data {
+	unsigned int cmd;
+	unsigned long arg;
+};
+
+
+/* struct ion_flush_data - data passed to ion for flushing caches
+ *
+ * @handle:	handle with data to flush
+ * @fd:		fd to flush
+ * @vaddr:	userspace virtual address mapped with mmap
+ * @offset:	offset into the handle to flush
+ * @length:	length of handle to flush
+ *
+ * Performs cache operations on the handle. If p is the start address
+ * of the handle, p + offset through p + offset + length will have
+ * the cache operations performed
+ */
+struct ion_flush_data {
+	struct ion_handle *handle;
+	int fd;
+	void *vaddr;
+	unsigned int offset;
+	unsigned int length;
+};
+
+/* struct ion_flag_data - information about flags for this buffer
+ *
+ * @handle:	handle to get flags from
+ * @flags:	flags of this handle
+ *
+ * Takes handle as an input and outputs the flags from the handle
+ * in the flag field.
+ */
+struct ion_flag_data {
+	struct ion_handle *handle;
+	unsigned long flags;
+};
+
+#define ION_IOC_MAGIC		'I'
+
+/**
+ * DOC: ION_IOC_ALLOC - allocate memory
+ *
+ * Takes an ion_allocation_data struct and returns it with the handle field
+ * populated with the opaque handle for the allocation.
+ */
+#define ION_IOC_ALLOC		_IOWR(ION_IOC_MAGIC, 0, \
+				      struct ion_allocation_data)
+
+/**
+ * DOC: ION_IOC_FREE - free memory
+ *
+ * Takes an ion_handle_data struct and frees the handle.
+ */
+#define ION_IOC_FREE		_IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data)
+
+/**
+ * DOC: ION_IOC_MAP - get a file descriptor to mmap
+ *
+ * Takes an ion_fd_data struct with the handle field populated with a valid
+ * opaque handle.  Returns the struct with the fd field set to a file
+ * descriptor open in the current address space.  This file descriptor
+ * can then be used as an argument to mmap.
+ */
+#define ION_IOC_MAP		_IOWR(ION_IOC_MAGIC, 2, struct ion_fd_data)
+
+/**
+ * DOC: ION_IOC_SHARE - creates a file descriptor to use to share an allocation
+ *
+ * Takes an ion_fd_data struct with the handle field populated with a valid
+ * opaque handle.  Returns the struct with the fd field set to a file
+ * descriptor open in the current address space.  This file descriptor
+ * can then be passed to another process.  The corresponding opaque handle can
+ * be retrieved via ION_IOC_IMPORT.
+ */
+#define ION_IOC_SHARE		_IOWR(ION_IOC_MAGIC, 4, struct ion_fd_data)
+
+/**
+ * DOC: ION_IOC_IMPORT - imports a shared file descriptor
+ *
+ * Takes an ion_fd_data struct with the fd field populated with a valid file
+ * descriptor obtained from ION_IOC_SHARE and returns the struct with the handle
+ * filed set to the corresponding opaque handle.
+ */
+#define ION_IOC_IMPORT		_IOWR(ION_IOC_MAGIC, 5, int)
+
+/**
+ * DOC: ION_IOC_CUSTOM - call architecture specific ion ioctl
+ *
+ * Takes the argument of the architecture specific ioctl to call and
+ * passes appropriate userdata for that ioctl
+ */
+#define ION_IOC_CUSTOM		_IOWR(ION_IOC_MAGIC, 6, struct ion_custom_data)
+
+
+/**
+ * DOC: ION_IOC_CLEAN_CACHES - clean the caches
+ *
+ * Clean the caches of the handle specified.
+ */
+#define ION_IOC_CLEAN_CACHES	_IOWR(ION_IOC_MAGIC, 7, \
+						struct ion_flush_data)
+/**
+ * DOC: ION_MSM_IOC_INV_CACHES - invalidate the caches
+ *
+ * Invalidate the caches of the handle specified.
+ */
+#define ION_IOC_INV_CACHES	_IOWR(ION_IOC_MAGIC, 8, \
+						struct ion_flush_data)
+/**
+ * DOC: ION_MSM_IOC_CLEAN_CACHES - clean and invalidate the caches
+ *
+ * Clean and invalidate the caches of the handle specified.
+ */
+#define ION_IOC_CLEAN_INV_CACHES	_IOWR(ION_IOC_MAGIC, 9, \
+						struct ion_flush_data)
+
+/**
+ * DOC: ION_IOC_GET_FLAGS - get the flags of the handle
+ *
+ * Gets the flags of the current handle which indicate cachability,
+ * secure state etc.
+ */
+#define ION_IOC_GET_FLAGS		_IOWR(ION_IOC_MAGIC, 10, \
+						struct ion_flag_data)
+#endif /* _LINUX_ION_H */
diff --git a/libgralloc/ionalloc.cpp b/libgralloc/ionalloc.cpp
new file mode 100644
index 0000000..9ff0a5e
--- /dev/null
+++ b/libgralloc/ionalloc.cpp
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <linux/ioctl.h>
+#include <sys/mman.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <cutils/log.h>
+#include <errno.h>
+#include "gralloc_priv.h"
+#include "ionalloc.h"
+
+using gralloc::IonAlloc;
+
+#define ION_DEVICE "/dev/ion"
+
+int IonAlloc::open_device()
+{
+    if(mIonFd == FD_INIT)
+        mIonFd = open(ION_DEVICE, O_RDONLY);
+
+    if(mIonFd < 0 ) {
+        ALOGE("%s: Failed to open ion device - %s",
+                __FUNCTION__, strerror(errno));
+        mIonFd = FD_INIT;
+        return -errno;
+    }
+    return 0;
+}
+
+void IonAlloc::close_device()
+{
+    if(mIonFd >= 0)
+        close(mIonFd);
+    mIonFd = FD_INIT;
+}
+
+int IonAlloc::alloc_buffer(alloc_data& data)
+{
+    int err = 0;
+    int ionSyncFd = FD_INIT;
+    int iFd = FD_INIT;
+    struct ion_handle_data handle_data;
+    struct ion_fd_data fd_data;
+    struct ion_allocation_data ionAllocData;
+
+    void *base = 0;
+
+    ionAllocData.len = data.size;
+    ionAllocData.align = data.align;
+    ionAllocData.flags = data.flags;
+
+    err = open_device();
+    if (err)
+        return err;
+
+    if(data.uncached) {
+        // Use the sync FD to alloc and map
+        // when we need uncached memory
+        // FIX: О–DSYNC defined to open uncached - add that in kernel
+	//ionSyncFd = open(ION_DEVICE, O_RDONLY|O_DSYNC);
+        ionSyncFd = open(ION_DEVICE, O_RDONLY);
+        if(ionSyncFd < 0) {
+            ALOGE("%s: Failed to open ion device - %s",
+                    __FUNCTION__, strerror(errno));
+            return -errno;
+        }
+        iFd = ionSyncFd;
+    } else {
+        iFd = mIonFd;
+    }
+
+    if(ioctl(iFd, ION_IOC_ALLOC, &ionAllocData)) {
+        err = -errno;
+        ALOGE("ION_IOC_ALLOC failed with error - %s", strerror(errno));
+        if(ionSyncFd >= 0)
+            close(ionSyncFd);
+        ionSyncFd = FD_INIT;
+        return err;
+    }
+
+    fd_data.handle = ionAllocData.handle;
+    handle_data.handle = ionAllocData.handle;
+    if(ioctl(iFd, ION_IOC_MAP, &fd_data)) {
+        err = -errno;
+        ALOGE("%s: ION_IOC_MAP failed with error - %s",
+                __FUNCTION__, strerror(errno));
+        ioctl(mIonFd, ION_IOC_FREE, &handle_data);
+        if(ionSyncFd >= 0)
+            close(ionSyncFd);
+        ionSyncFd = FD_INIT;
+        return err;
+    }
+
+    //if(!(data.flags & ION_SECURE) &&
+    if(!(data.allocType & private_handle_t::PRIV_FLAGS_NOT_MAPPED)) {
+
+        base = mmap(0, ionAllocData.len, PROT_READ|PROT_WRITE,
+                                MAP_SHARED, fd_data.fd, 0);
+        if(base == MAP_FAILED) {
+            err = -errno;
+            ALOGE("%s: Failed to map the allocated memory: %s",
+                                    __FUNCTION__, strerror(errno));
+            ioctl(mIonFd, ION_IOC_FREE, &handle_data);
+            ionSyncFd = FD_INIT;
+            return err;
+        }
+        memset(base, 0, ionAllocData.len);
+        // Clean cache after memset
+        clean_buffer(base, data.size, data.offset, fd_data.fd);
+    }
+
+    //Close the uncached FD since we no longer need it;
+    if(ionSyncFd >= 0)
+        close(ionSyncFd);
+    ionSyncFd = FD_INIT;
+
+    data.base = base;
+    data.fd = fd_data.fd;
+    ioctl(mIonFd, ION_IOC_FREE, &handle_data);
+    ALOGD("ion: Allocated buffer base:%p size:%d fd:%d",
+                            data.base, ionAllocData.len, data.fd);
+    return 0;
+}
+
+
+int IonAlloc::free_buffer(void* base, size_t size, int offset, int fd)
+{
+    ALOGD("ion: Freeing buffer base:%p size:%d fd:%d",
+            base, size, fd);
+    int err = 0;
+    err = open_device();
+    if (err)
+        return err;
+
+    if(base)
+        err = unmap_buffer(base, size, offset);
+    close(fd);
+    return err;
+}
+
+int IonAlloc::map_buffer(void **pBase, size_t size, int offset, int fd)
+{
+    int err = 0;
+    void *base = 0;
+    // It is a (quirky) requirement of ION to have opened the
+    // ion fd in the process that is doing the mapping
+    err = open_device();
+    if (err)
+        return err;
+
+    base = mmap(0, size, PROT_READ| PROT_WRITE,
+            MAP_SHARED, fd, 0);
+    *pBase = base;
+    if(base == MAP_FAILED) {
+        err = -errno;
+        ALOGD("ion: Failed to map memory in the client: %s",
+                                strerror(errno));
+    } else {
+        ALOGD("ion: Mapped buffer base:%p size:%d offset:%d fd:%d",
+                                base, size, offset, fd);
+    }
+    return err;
+}
+
+int IonAlloc::unmap_buffer(void *base, size_t size, int offset)
+{
+    ALOGD("ion: Unmapping buffer  base:%p size:%d", base, size);
+    int err = 0;
+    if(munmap(base, size)) {
+        err = -errno;
+        ALOGE("ion: Failed to unmap memory at %p : %s",
+                 base, strerror(errno));
+    }
+    return err;
+
+}
+int IonAlloc::clean_buffer(void *base, size_t size, int offset, int fd)
+{
+    struct ion_flush_data flush_data;
+    struct ion_fd_data fd_data;
+    struct ion_handle_data handle_data;
+    struct ion_handle* handle;
+    int err = 0;
+
+    err = open_device();
+    if (err)
+        return err;
+
+    fd_data.fd = fd;
+    if (ioctl(mIonFd, ION_IOC_IMPORT, &fd_data)) {
+        err = -errno;
+        ALOGE("%s: ION_IOC_IMPORT failed with error - %s",
+                __FUNCTION__, strerror(errno));
+        return err;
+    }
+
+    handle_data.handle = fd_data.handle;
+    flush_data.handle  = fd_data.handle;
+    flush_data.vaddr   = base;
+    flush_data.offset  = offset;
+    flush_data.length  = size;
+    if(ioctl(mIonFd, ION_IOC_CLEAN_INV_CACHES, &flush_data)) {
+        err = -errno;
+        ALOGE("%s: ION_IOC_CLEAN_INV_CACHES failed with error - %s",
+                __FUNCTION__, strerror(errno));
+        ioctl(mIonFd, ION_IOC_FREE, &handle_data);
+        return err;
+    }
+    ioctl(mIonFd, ION_IOC_FREE, &handle_data);
+    return 0;
+}
+
diff --git a/libgralloc/ionalloc.h b/libgralloc/ionalloc.h
new file mode 100644
index 0000000..be26cd7
--- /dev/null
+++ b/libgralloc/ionalloc.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GRALLOC_IONALLOC_H
+#define GRALLOC_IONALLOC_H
+
+#include "memalloc.h"
+#include "ion_msm.h"
+
+namespace gralloc {
+
+    class IonAlloc : public IMemAlloc  {
+
+        public:
+            virtual int alloc_buffer(alloc_data& data);
+
+            virtual int free_buffer(void *base, size_t size,
+                    int offset, int fd);
+
+            virtual int map_buffer(void **pBase, size_t size,
+                    int offset, int fd);
+
+            virtual int unmap_buffer(void *base, size_t size,
+                    int offset);
+
+            virtual int clean_buffer(void*base, size_t size,
+                    int offset, int fd);
+
+            IonAlloc() { mIonFd = FD_INIT; }
+
+            ~IonAlloc() { close_device(); }
+
+        private:
+            int mIonFd;
+
+            int open_device();
+
+            void close_device();
+
+    };
+
+}
+
+#endif /* GRALLOC_IONALLOC_H */
+
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
new file mode 100755
index 0000000..c7ee7d4
--- /dev/null
+++ b/libgralloc/mapper.cpp
@@ -0,0 +1,366 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2011 Code Aurora Forum. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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 <limits.h>
+#include <errno.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <linux/ashmem.h>
+
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+#include <cutils/ashmem.h>
+
+#include <hardware/hardware.h>
+#include <hardware/gralloc.h>
+#include <genlock.h>
+
+#include <linux/android_pmem.h>
+
+#include "gralloc_priv.h"
+#include "gr.h"
+#include "alloc_controller.h"
+#include "memalloc.h"
+
+using namespace gralloc;
+using android::sp;
+/*****************************************************************************/
+
+// Return the type of allocator -
+// these are used for mapping/unmapping
+static sp<IMemAlloc> getAllocator(int flags)
+{
+    sp<IMemAlloc> memalloc;
+    sp<IAllocController> alloc_ctrl = IAllocController::getInstance(true);
+    memalloc = alloc_ctrl->getAllocator(flags);
+    return memalloc;
+}
+
+static int gralloc_map(gralloc_module_t const* module,
+        buffer_handle_t handle,
+        void** vaddr)
+{
+    private_handle_t* hnd = (private_handle_t*)handle;
+    void *mappedAddress;
+    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) &&
+        !(hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER)) {
+        size_t size = hnd->size;
+        sp<IMemAlloc> memalloc = getAllocator(hnd->flags) ;
+        int err = memalloc->map_buffer(&mappedAddress, size,
+                hnd->offset, hnd->fd);
+        if(err) {
+            ALOGE("Could not mmap handle %p, fd=%d (%s)",
+                    handle, hnd->fd, strerror(errno));
+            hnd->base = 0;
+            return -errno;
+        }
+
+        if (mappedAddress == MAP_FAILED) {
+            ALOGE("Could not mmap handle %p, fd=%d (%s)",
+                    handle, hnd->fd, strerror(errno));
+            hnd->base = 0;
+            return -errno;
+        }
+        hnd->base = intptr_t(mappedAddress) + hnd->offset;
+        //ALOGD("gralloc_map() succeeded fd=%d, off=%d, size=%d, vaddr=%p",
+        //        hnd->fd, hnd->offset, hnd->size, mappedAddress);
+    }
+    *vaddr = (void*)hnd->base;
+    return 0;
+}
+
+static int gralloc_unmap(gralloc_module_t const* module,
+        buffer_handle_t handle)
+{
+    private_handle_t* hnd = (private_handle_t*)handle;
+    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
+        int err = -EINVAL;
+        void* base = (void*)hnd->base;
+        size_t size = hnd->size;
+        sp<IMemAlloc> memalloc = getAllocator(hnd->flags) ;
+        if(memalloc != NULL)
+            err = memalloc->unmap_buffer(base, size, hnd->offset);
+        if (err) {
+            ALOGE("Could not unmap memory at address %p", base);
+        }
+    }
+    hnd->base = 0;
+    return 0;
+}
+
+/*****************************************************************************/
+
+static pthread_mutex_t sMapLock = PTHREAD_MUTEX_INITIALIZER;
+
+/*****************************************************************************/
+
+int gralloc_register_buffer(gralloc_module_t const* module,
+        buffer_handle_t handle)
+{
+    if (private_handle_t::validate(handle) < 0)
+        return -EINVAL;
+
+    // In this implementation, we don't need to do anything here
+
+    /* NOTE: we need to initialize the buffer as not mapped/not locked
+     * because it shouldn't when this function is called the first time
+     * in a new process. Ideally these flags shouldn't be part of the
+     * handle, but instead maintained in the kernel or at least
+     * out-of-line
+     */
+
+    // if this handle was created in this process, then we keep it as is.
+    private_handle_t* hnd = (private_handle_t*)handle;
+    if (hnd->pid != getpid()) {
+        hnd->base = 0;
+        void *vaddr;
+        int err = gralloc_map(module, handle, &vaddr);
+        if (err) {
+            ALOGE("%s: gralloc_map failed", __FUNCTION__);
+            return err;
+        }
+
+        // Reset the genlock private fd flag in the handle
+        hnd->genlockPrivFd = -1;
+
+        // Check if there is a valid lock attached to the handle.
+        if (-1 == hnd->genlockHandle) {
+            ALOGE("%s: the lock is invalid.", __FUNCTION__);
+            gralloc_unmap(module, handle);
+            hnd->base = 0;
+            return -EINVAL;
+        }
+
+        // Attach the genlock handle
+        if (GENLOCK_NO_ERROR != genlock_attach_lock((native_handle_t *)handle)) {
+            ALOGE("%s: genlock_attach_lock failed", __FUNCTION__);
+            gralloc_unmap(module, handle);
+            hnd->base = 0;
+            return -EINVAL;
+        }
+    }
+    return 0;
+}
+
+int gralloc_unregister_buffer(gralloc_module_t const* module,
+        buffer_handle_t handle)
+{
+    if (private_handle_t::validate(handle) < 0)
+        return -EINVAL;
+
+    /*
+     * If the buffer has been mapped during a lock operation, it's time
+     * to un-map it. It's an error to be here with a locked buffer.
+     * NOTE: the framebuffer is handled differently and is never unmapped.
+     */
+
+    private_handle_t* hnd = (private_handle_t*)handle;
+
+    // never unmap buffers that were created in this process
+    if (hnd->pid != getpid()) {
+        if (hnd->base != 0) {
+            gralloc_unmap(module, handle);
+        }
+        hnd->base = 0;
+        // Release the genlock
+        if (-1 != hnd->genlockHandle) {
+            return genlock_release_lock((native_handle_t *)handle);
+        } else {
+            ALOGE("%s: there was no genlock attached to this buffer", __FUNCTION__);
+            return -EINVAL;
+        }
+    }
+    return 0;
+}
+
+int terminateBuffer(gralloc_module_t const* module,
+        private_handle_t* hnd)
+{
+    /*
+     * If the buffer has been mapped during a lock operation, it's time
+     * to un-map it. It's an error to be here with a locked buffer.
+     */
+
+    if (hnd->base != 0) {
+        // this buffer was mapped, unmap it now
+        if (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM |
+                          private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP |
+                          private_handle_t::PRIV_FLAGS_USES_ASHMEM |
+                          private_handle_t::PRIV_FLAGS_USES_ION)) {
+            if (hnd->pid != getpid()) {
+                // ... unless it's a "master" pmem buffer, that is a buffer
+                // mapped in the process it's been allocated.
+                // (see gralloc_alloc_buffer())
+                gralloc_unmap(module, hnd);
+            }
+        } else {
+            ALOGE("terminateBuffer: unmapping a non pmem/ashmem buffer flags = 0x%x", hnd->flags);
+            gralloc_unmap(module, hnd);
+        }
+    }
+
+    return 0;
+}
+
+int gralloc_lock(gralloc_module_t const* module,
+        buffer_handle_t handle, int usage,
+        int l, int t, int w, int h,
+        void** vaddr)
+{
+    if (private_handle_t::validate(handle) < 0)
+        return -EINVAL;
+
+    int err = 0;
+    private_handle_t* hnd = (private_handle_t*)handle;
+    if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
+        if (hnd->base == 0) {
+            // we need to map for real
+            pthread_mutex_t* const lock = &sMapLock;
+            pthread_mutex_lock(lock);
+            err = gralloc_map(module, handle, vaddr);
+            pthread_mutex_unlock(lock);
+        }
+        *vaddr = (void*)hnd->base;
+
+        // Lock the buffer for read/write operation as specified. Write lock
+        // has a higher priority over read lock.
+        int lockType = 0;
+        if (usage & GRALLOC_USAGE_SW_WRITE_MASK) {
+            lockType = GENLOCK_WRITE_LOCK;
+        } else if (usage & GRALLOC_USAGE_SW_READ_MASK) {
+            lockType = GENLOCK_READ_LOCK;
+        }
+
+        int timeout = GENLOCK_MAX_TIMEOUT;
+        if (GENLOCK_NO_ERROR != genlock_lock_buffer((native_handle_t *)handle,
+                                                   (genlock_lock_type)lockType,
+                                                   timeout)) {
+            ALOGE("%s: genlock_lock_buffer (lockType=0x%x) failed", __FUNCTION__,
+                lockType);
+            return -EINVAL;
+        } else {
+            // Mark this buffer as locked for SW read/write operation.
+            hnd->flags |= private_handle_t::PRIV_FLAGS_SW_LOCK;
+        }
+
+        if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) &&
+            !(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
+            // Mark the buffer to be flushed after cpu read/write
+            hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
+        }
+    }
+    return err;
+}
+
+int gralloc_unlock(gralloc_module_t const* module,
+        buffer_handle_t handle)
+{
+    if (private_handle_t::validate(handle) < 0)
+        return -EINVAL;
+
+    private_handle_t* hnd = (private_handle_t*)handle;
+
+    if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
+        int err;
+        sp<IMemAlloc> memalloc = getAllocator(hnd->flags) ;
+        err = memalloc->clean_buffer((void*)hnd->base,
+                hnd->size, hnd->offset, hnd->fd);
+        ALOGE_IF(err < 0, "cannot flush handle %p (offs=%x len=%x, flags = 0x%x) err=%s\n",
+                hnd, hnd->offset, hnd->size, hnd->flags, strerror(errno));
+        hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
+    }
+
+    if ((hnd->flags & private_handle_t::PRIV_FLAGS_SW_LOCK)) {
+        // Unlock the buffer.
+        if (GENLOCK_NO_ERROR != genlock_unlock_buffer((native_handle_t *)handle)) {
+            ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
+            return -EINVAL;
+        } else
+            hnd->flags &= ~private_handle_t::PRIV_FLAGS_SW_LOCK;
+    }
+    return 0;
+}
+
+/*****************************************************************************/
+
+int gralloc_perform(struct gralloc_module_t const* module,
+        int operation, ... )
+{
+    int res = -EINVAL;
+    va_list args;
+    va_start(args, operation);
+    switch (operation) {
+        case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER:
+            {
+                int fd = va_arg(args, int);
+                size_t size = va_arg(args, size_t);
+                size_t offset = va_arg(args, size_t);
+                void* base = va_arg(args, void*);
+                int width = va_arg(args, int);
+                int height = va_arg(args, int);
+                int format = va_arg(args, int);
+
+                native_handle_t** handle = va_arg(args, native_handle_t**);
+                int memoryFlags = va_arg(args, int);
+                private_handle_t* hnd = (private_handle_t*)native_handle_create(
+                        private_handle_t::sNumFds, private_handle_t::sNumInts);
+                hnd->magic = private_handle_t::sMagic;
+                hnd->fd = fd;
+                unsigned int contigFlags = GRALLOC_USAGE_PRIVATE_ADSP_HEAP |
+                                  GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP |
+                                  GRALLOC_USAGE_PRIVATE_SMI_HEAP;
+
+                if (memoryFlags & contigFlags) {
+                    // check if the buffer is a pmem buffer
+                    pmem_region region;
+                    if (ioctl(fd, PMEM_GET_SIZE, &region) < 0)
+                        hnd->flags =  private_handle_t::PRIV_FLAGS_USES_ION;
+                    else
+                        hnd->flags =  private_handle_t::PRIV_FLAGS_USES_PMEM |
+                                      private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH;
+                } else {
+                    if (memoryFlags & GRALLOC_USAGE_PRIVATE_ION)
+                        hnd->flags =  private_handle_t::PRIV_FLAGS_USES_ION;
+                    else
+                        hnd->flags =  private_handle_t::PRIV_FLAGS_USES_ASHMEM;
+                }
+
+                hnd->size = size;
+                hnd->offset = offset;
+                hnd->base = intptr_t(base) + offset;
+                hnd->gpuaddr = 0;
+                hnd->width = width;
+                hnd->height = height;
+                hnd->format = format;
+                *handle = (native_handle_t *)hnd;
+                res = 0;
+                break;
+
+            }
+        default:
+            break;
+    }
+    va_end(args);
+    return res;
+}
diff --git a/libgralloc/memalloc.h b/libgralloc/memalloc.h
new file mode 100644
index 0000000..13a54e7
--- /dev/null
+++ b/libgralloc/memalloc.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GRALLOC_MEMALLOC_H
+#define GRALLOC_MEMALLOC_H
+
+#include <stdlib.h>
+#include <utils/RefBase.h>
+
+namespace gralloc {
+
+    struct alloc_data {
+        void           *base;
+        int            fd;
+        int            offset;
+        size_t         size;
+        size_t         align;
+        unsigned int   pHandle;
+        bool           uncached;
+        unsigned int   flags;
+        int            allocType;
+    };
+
+    class IMemAlloc : public android::RefBase {
+
+        public:
+            // Allocate buffer - fill in the alloc_data
+            // structure and pass it in. Mapped address
+            // and fd are returned in the alloc_data struct
+            virtual int alloc_buffer(alloc_data& data) = 0;
+
+            // Free buffer
+            virtual int free_buffer(void *base, size_t size,
+                    int offset, int fd) = 0;
+
+            // Map buffer
+            virtual int map_buffer(void **pBase, size_t size,
+                    int offset, int fd) = 0;
+
+            // Unmap buffer
+            virtual int unmap_buffer(void *base, size_t size,
+                    int offset) = 0;
+
+            // Clean and invalidate
+            virtual int clean_buffer(void *base, size_t size,
+                    int offset, int fd) = 0;
+
+            // Destructor
+            virtual ~IMemAlloc() {};
+
+            enum {
+                FD_INIT = -1,
+            };
+
+    };
+
+} // end gralloc namespace
+#endif // GRALLOC_MEMALLOC_H
diff --git a/libgralloc/pmem_bestfit_alloc.cpp b/libgralloc/pmem_bestfit_alloc.cpp
new file mode 100644
index 0000000..e3875e9
--- /dev/null
+++ b/libgralloc/pmem_bestfit_alloc.cpp
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (c) 2011 Code Aurora Forum. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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 <cutils/log.h>
+
+#include "pmem_bestfit_alloc.h"
+
+
+// align all the memory blocks on a cache-line boundary
+const int SimpleBestFitAllocator::kMemoryAlign = 32;
+
+SimpleBestFitAllocator::SimpleBestFitAllocator()
+    : mHeapSize(0)
+{
+}
+
+SimpleBestFitAllocator::SimpleBestFitAllocator(size_t size)
+    : mHeapSize(0)
+{
+    setSize(size);
+}
+
+SimpleBestFitAllocator::~SimpleBestFitAllocator()
+{
+    while(!mList.isEmpty()) {
+        delete mList.remove(mList.head());
+    }
+}
+
+ssize_t SimpleBestFitAllocator::setSize(size_t size)
+{
+    Locker::Autolock _l(mLock);
+    if (mHeapSize != 0) return -EINVAL;
+    size_t pagesize = getpagesize();
+    mHeapSize = ((size + pagesize-1) & ~(pagesize-1));
+    chunk_t* node = new chunk_t(0, mHeapSize / kMemoryAlign);
+    mList.insertHead(node);
+    return size;
+}
+
+size_t SimpleBestFitAllocator::size() const
+{
+    return mHeapSize;
+}
+
+ssize_t SimpleBestFitAllocator::allocate(size_t size, uint32_t flags)
+{
+    Locker::Autolock _l(mLock);
+    if (mHeapSize == 0) return -EINVAL;
+    ssize_t offset = alloc(size, flags);
+    return offset;
+}
+
+ssize_t SimpleBestFitAllocator::deallocate(size_t offset)
+{
+    Locker::Autolock _l(mLock);
+    if (mHeapSize == 0) return -EINVAL;
+    chunk_t const * const freed = dealloc(offset);
+    if (freed) {
+        return 0;
+    }
+    return -ENOENT;
+}
+
+ssize_t SimpleBestFitAllocator::alloc(size_t size, uint32_t flags)
+{
+    if (size == 0) {
+        return 0;
+    }
+    size = (size + kMemoryAlign-1) / kMemoryAlign;
+    chunk_t* free_chunk = 0;
+    chunk_t* cur = mList.head();
+
+    size_t pagesize = getpagesize();
+    while (cur) {
+        int extra = ( -cur->start & ((pagesize/kMemoryAlign)-1) ) ;
+
+        // best fit
+        if (cur->free && (cur->size >= (size+extra))) {
+            if ((!free_chunk) || (cur->size < free_chunk->size)) {
+                free_chunk = cur;
+            }
+            if (cur->size == size) {
+                break;
+            }
+        }
+        cur = cur->next;
+    }
+
+    if (free_chunk) {
+        const size_t free_size = free_chunk->size;
+        free_chunk->free = 0;
+        free_chunk->size = size;
+        if (free_size > size) {
+            int extra = ( -free_chunk->start & ((pagesize/kMemoryAlign)-1) ) ;
+            if (extra) {
+                chunk_t* split = new chunk_t(free_chunk->start, extra);
+                free_chunk->start += extra;
+                mList.insertBefore(free_chunk, split);
+            }
+
+            LOGE_IF(((free_chunk->start*kMemoryAlign)&(pagesize-1)),
+                    "page is not aligned!!!");
+
+            const ssize_t tail_free = free_size - (size+extra);
+            if (tail_free > 0) {
+                chunk_t* split = new chunk_t(
+                        free_chunk->start + free_chunk->size, tail_free);
+                mList.insertAfter(free_chunk, split);
+            }
+        }
+        return (free_chunk->start)*kMemoryAlign;
+    }
+    // we are out of PMEM. Print pmem stats
+    // check if there is any leak or fragmentation
+
+    LOGD (" Out of PMEM. Dumping PMEM stats for debugging");
+    LOGD (" ------------- PRINT PMEM STATS --------------");
+
+    cur = mList.head();
+    static uint32_t node_count;
+    static uint64_t allocated, free_space;
+
+    while (cur) {
+      LOGD (" Node %d -> Start Address : %u Size %u Free info %d",\
+              node_count++, cur->start, cur->size, cur->free);
+
+      // if cur-> free is 1 , the node is free
+      // calculate the total allocated and total free stats also
+
+      if (cur->free)
+         free_space += cur->size;
+      else
+         allocated += cur->size;
+      // read next node
+      cur = cur->next;
+    }
+    LOGD (" Total Allocated: %l Total Free: %l", allocated, free_space );
+
+    node_count = 0;
+    allocated = 0;
+    free_space = 0;
+    LOGD ("----------------------------------------------");
+    return -ENOMEM;
+}
+
+SimpleBestFitAllocator::chunk_t* SimpleBestFitAllocator::dealloc(size_t start)
+{
+    start = start / kMemoryAlign;
+    chunk_t* cur = mList.head();
+    while (cur) {
+        if (cur->start == start) {
+            LOG_FATAL_IF(cur->free,
+                "block at offset 0x%08lX of size 0x%08lX already freed",
+                cur->start*kMemoryAlign, cur->size*kMemoryAlign);
+
+            // merge freed blocks together
+            chunk_t* freed = cur;
+            cur->free = 1;
+            do {
+                chunk_t* const p = cur->prev;
+                chunk_t* const n = cur->next;
+                if (p && (p->free || !cur->size)) {
+                    freed = p;
+                    p->size += cur->size;
+                    mList.remove(cur);
+                    delete cur;
+                }
+                cur = n;
+            } while (cur && cur->free);
+
+            LOG_FATAL_IF(!freed->free,
+                "freed block at offset 0x%08lX of size 0x%08lX is not free!",
+                freed->start * kMemoryAlign, freed->size * kMemoryAlign);
+
+            return freed;
+        }
+        cur = cur->next;
+    }
+    return 0;
+}
diff --git a/libgralloc/pmem_bestfit_alloc.h b/libgralloc/pmem_bestfit_alloc.h
new file mode 100644
index 0000000..2ea8452
--- /dev/null
+++ b/libgralloc/pmem_bestfit_alloc.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (c) 2011 Code Aurora Forum. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.
+ */
+
+
+#ifndef GRALLOC_ALLOCATOR_H_
+#define GRALLOC_ALLOCATOR_H_
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "gr.h"
+#include "pmemalloc.h"
+
+// ----------------------------------------------------------------------------
+
+/*
+ * A simple templatized doubly linked-list implementation
+ */
+template <typename NODE>
+class LinkedList
+{
+    NODE*  mFirst;
+    NODE*  mLast;
+
+public:
+                LinkedList() : mFirst(0), mLast(0) { }
+    bool        isEmpty() const { return mFirst == 0; }
+    NODE const* head() const { return mFirst; }
+    NODE*       head() { return mFirst; }
+    NODE const* tail() const { return mLast; }
+    NODE*       tail() { return mLast; }
+
+    void insertAfter(NODE* node, NODE* newNode) {
+        newNode->prev = node;
+        newNode->next = node->next;
+        if (node->next == 0) mLast = newNode;
+        else                 node->next->prev = newNode;
+        node->next = newNode;
+    }
+
+    void insertBefore(NODE* node, NODE* newNode) {
+         newNode->prev = node->prev;
+         newNode->next = node;
+         if (node->prev == 0)   mFirst = newNode;
+         else                   node->prev->next = newNode;
+         node->prev = newNode;
+    }
+
+    void insertHead(NODE* newNode) {
+        if (mFirst == 0) {
+            mFirst = mLast = newNode;
+            newNode->prev = newNode->next = 0;
+        } else {
+            newNode->prev = 0;
+            newNode->next = mFirst;
+            mFirst->prev = newNode;
+            mFirst = newNode;
+        }
+    }
+
+    void insertTail(NODE* newNode) {
+        if (mLast == 0) {
+            insertHead(newNode);
+        } else {
+            newNode->prev = mLast;
+            newNode->next = 0;
+            mLast->next = newNode;
+            mLast = newNode;
+        }
+    }
+
+    NODE* remove(NODE* node) {
+        if (node->prev == 0)    mFirst = node->next;
+        else                    node->prev->next = node->next;
+        if (node->next == 0)    mLast = node->prev;
+        else                    node->next->prev = node->prev;
+        return node;
+    }
+};
+
+class SimpleBestFitAllocator : public gralloc::PmemUserspaceAlloc::Allocator
+{
+public:
+
+    SimpleBestFitAllocator();
+    SimpleBestFitAllocator(size_t size);
+    virtual ~SimpleBestFitAllocator();
+
+    virtual ssize_t setSize(size_t size);
+
+    virtual ssize_t allocate(size_t size, uint32_t flags = 0);
+    virtual ssize_t deallocate(size_t offset);
+    virtual size_t  size() const;
+
+private:
+    struct chunk_t {
+        chunk_t(size_t start, size_t size)
+            : start(start), size(size), free(1), prev(0), next(0) {
+        }
+        size_t              start;
+        size_t              size : 28;
+        int                 free : 4;
+        mutable chunk_t*    prev;
+        mutable chunk_t*    next;
+    };
+
+    ssize_t  alloc(size_t size, uint32_t flags);
+    chunk_t* dealloc(size_t start);
+
+    static const int    kMemoryAlign;
+    mutable Locker      mLock;
+    LinkedList<chunk_t> mList;
+    size_t              mHeapSize;
+};
+#endif /* GRALLOC_ALLOCATOR_H_ */
diff --git a/libgralloc/pmemalloc.cpp b/libgralloc/pmemalloc.cpp
new file mode 100644
index 0000000..ccbf127
--- /dev/null
+++ b/libgralloc/pmemalloc.cpp
@@ -0,0 +1,388 @@
+/*
+ * Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <stdlib.h>
+#include <cutils/log.h>
+#include <errno.h>
+#include <linux/android_pmem.h>
+#include "gralloc_priv.h"
+#include "pmemalloc.h"
+#include "pmem_bestfit_alloc.h"
+
+using namespace gralloc;
+using android::sp;
+
+// Common functions between userspace
+// and kernel allocators
+static int getPmemTotalSize(int fd, size_t* size)
+{
+    //XXX: 7x27
+    int err = 0;
+    pmem_region region;
+    if (ioctl(fd, PMEM_GET_TOTAL_SIZE, &region)) {
+        err = -errno;
+    } else {
+        *size = region.len;
+    }
+    return err;
+}
+
+static int getOpenFlags(bool uncached)
+{
+    if(uncached)
+        return O_RDWR | O_SYNC;
+    else
+        return O_RDWR;
+}
+
+static int connectPmem(int fd, int master_fd) {
+    if (ioctl(fd, PMEM_CONNECT, master_fd))
+        return -errno;
+    return 0;
+}
+
+static int mapSubRegion(int fd, int offset, size_t size) {
+    struct pmem_region sub = { offset, size };
+    if (ioctl(fd, PMEM_MAP, &sub))
+        return -errno;
+    return 0;
+}
+
+static int unmapSubRegion(int fd, int offset, size_t size) {
+    struct pmem_region sub = { offset, size };
+    if (ioctl(fd, PMEM_UNMAP, &sub))
+        return -errno;
+    return 0;
+}
+
+static int alignPmem(int fd, size_t size, int align) {
+    struct pmem_allocation allocation;
+    allocation.size = size;
+    allocation.align = align;
+    if (ioctl(fd, PMEM_ALLOCATE_ALIGNED, &allocation))
+        return -errno;
+    return 0;
+}
+
+static int cleanPmem(void *base, size_t size, int offset, int fd) {
+    struct pmem_addr pmem_addr;
+    pmem_addr.vaddr = (unsigned long) base;
+    pmem_addr.offset = offset;
+    pmem_addr.length = size;
+    if (ioctl(fd, PMEM_CLEAN_INV_CACHES, &pmem_addr))
+        return -errno;
+    return 0;
+}
+
+//-------------- PmemUserspaceAlloc-----------------------//
+PmemUserspaceAlloc::PmemUserspaceAlloc()
+{
+    mPmemDev = DEVICE_PMEM;
+    mMasterFd = FD_INIT;
+    mAllocator = new SimpleBestFitAllocator();
+    pthread_mutex_init(&mLock, NULL);
+}
+
+PmemUserspaceAlloc::~PmemUserspaceAlloc()
+{
+}
+
+int PmemUserspaceAlloc::init_pmem_area_locked()
+{
+    ALOGD("%s: Opening master pmem FD", __FUNCTION__);
+    int err = 0;
+    int fd = open(mPmemDev, O_RDWR, 0);
+    if (fd >= 0) {
+        size_t size = 0;
+        err = getPmemTotalSize(fd, &size);
+        ALOGD("%s: Total pmem size: %d", __FUNCTION__, size);
+        if (err < 0) {
+            ALOGE("%s: PMEM_GET_TOTAL_SIZE failed (%d), limp mode", mPmemDev,
+                    err);
+            size = 8<<20;   // 8 MiB
+        }
+        mAllocator->setSize(size);
+
+        void* base = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd,
+                0);
+        if (base == MAP_FAILED) {
+            err = -errno;
+            ALOGE("%s: Failed to map pmem master fd: %s", mPmemDev,
+                    strerror(errno));
+            base = 0;
+            close(fd);
+            fd = -1;
+        } else {
+            mMasterFd = fd;
+            mMasterBase = base;
+        }
+    } else {
+        err = -errno;
+        ALOGE("%s: Failed to open pmem device: %s", mPmemDev,
+                strerror(errno));
+    }
+    return err;
+}
+
+int  PmemUserspaceAlloc::init_pmem_area()
+{
+    pthread_mutex_lock(&mLock);
+    int err = mMasterFd;
+    if (err == FD_INIT) {
+        // first time, try to initialize pmem
+        ALOGD("%s: Initializing pmem area", __FUNCTION__);
+        err = init_pmem_area_locked();
+        if (err) {
+            ALOGE("%s: failed to initialize pmem area", mPmemDev);
+            mMasterFd = err;
+        }
+    } else if (err < 0) {
+        // pmem couldn't be initialized, never use it
+    } else {
+        // pmem OK
+        err = 0;
+    }
+    pthread_mutex_unlock(&mLock);
+    return err;
+
+}
+
+int PmemUserspaceAlloc::alloc_buffer(alloc_data& data)
+{
+    int err = init_pmem_area();
+    if (err == 0) {
+        void* base = mMasterBase;
+        size_t size = data.size;
+        int offset = mAllocator->allocate(size);
+        if (offset < 0) {
+            // no more pmem memory
+            ALOGE("%s: No more pmem available", mPmemDev);
+            err = -ENOMEM;
+        } else {
+            int openFlags = getOpenFlags(data.uncached);
+
+            // now create the "sub-heap"
+            int fd = open(mPmemDev, openFlags, 0);
+            err = fd < 0 ? fd : 0;
+
+            // and connect to it
+            if (err == 0)
+                err = connectPmem(fd, mMasterFd);
+
+            // and make it available to the client process
+            if (err == 0)
+                err = mapSubRegion(fd, offset, size);
+
+            if (err < 0) {
+                ALOGE("%s: Failed to initialize pmem sub-heap: %d", mPmemDev,
+                        err);
+                close(fd);
+                mAllocator->deallocate(offset);
+                fd = -1;
+            } else {
+                ALOGD("%s: Allocated buffer base:%p size:%d offset:%d fd:%d",
+                        mPmemDev, base, size, offset, fd);
+                memset((char*)base + offset, 0, size);
+                //Clean cache before flushing to ensure pmem is properly flushed
+                err = clean_buffer((void*)((intptr_t) base + offset), size, offset, fd);
+                if (err < 0) {
+                    ALOGE("cleanPmem failed: (%s)", strerror(errno));
+                }
+                cacheflush(intptr_t(base) + offset, intptr_t(base) + offset + size, 0);
+                data.base = base;
+                data.offset = offset;
+                data.fd = fd;
+            }
+        }
+    }
+    return err;
+
+}
+
+int PmemUserspaceAlloc::free_buffer(void* base, size_t size, int offset, int fd)
+{
+    ALOGD("%s: Freeing buffer base:%p size:%d offset:%d fd:%d",
+            mPmemDev, base, size, offset, fd);
+    int err = 0;
+    if (fd >= 0) {
+        int err = unmapSubRegion(fd, offset, size);
+        ALOGE_IF(err<0, "PMEM_UNMAP failed (%s), fd=%d, sub.offset=%u, "
+                "sub.size=%u", strerror(errno), fd, offset, size);
+        if (err == 0) {
+            // we can't deallocate the memory in case of UNMAP failure
+            // because it would give that process access to someone else's
+            // surfaces, which would be a security breach.
+            mAllocator->deallocate(offset);
+        }
+        close(fd);
+    }
+    return err;
+}
+
+int PmemUserspaceAlloc::map_buffer(void **pBase, size_t size, int offset, int fd)
+{
+    int err = 0;
+    size += offset;
+    void *base = mmap(0, size, PROT_READ| PROT_WRITE,
+            MAP_SHARED, fd, 0);
+    *pBase = base;
+    if(base == MAP_FAILED) {
+        err = -errno;
+        ALOGE("%s: Failed to map buffer size:%d offset:%d fd:%d Error: %s",
+                mPmemDev, size, offset, fd, strerror(errno));
+    } else {
+        ALOGD("%s: Mapped buffer base:%p size:%d offset:%d fd:%d",
+                mPmemDev, base, size, offset, fd);
+    }
+    return err;
+
+}
+
+int PmemUserspaceAlloc::unmap_buffer(void *base, size_t size, int offset)
+{
+    int err = 0;
+    //pmem hack
+    base = (void*)(intptr_t(base) - offset);
+    size += offset;
+    ALOGD("%s: Unmapping buffer base:%p size:%d offset:%d",
+            mPmemDev , base, size, offset);
+    if (munmap(base, size) < 0) {
+
+        err = -errno;
+        ALOGE("%s: Failed to unmap memory at %p :%s",
+                   mPmemDev, base, strerror(errno));
+
+    }
+
+   return err;
+}
+
+int PmemUserspaceAlloc::clean_buffer(void *base, size_t size, int offset, int fd)
+{
+    return cleanPmem(base, size, offset, fd);
+}
+
+
+//-------------- PmemKernelAlloc-----------------------//
+
+PmemKernelAlloc::PmemKernelAlloc(const char* pmemdev) :
+    mPmemDev(pmemdev)
+{
+}
+
+PmemKernelAlloc::~PmemKernelAlloc()
+{
+}
+
+int PmemKernelAlloc::alloc_buffer(alloc_data& data)
+{
+    int err, offset = 0;
+    int openFlags = getOpenFlags(data.uncached);
+    int size = data.size;
+
+    int fd = open(mPmemDev, openFlags, 0);
+    if (fd < 0) {
+        err = -errno;
+        ALOGE("%s: Error opening %s", __FUNCTION__, mPmemDev);
+        return err;
+    }
+
+    if (data.align == 8192) {
+        // Tile format buffers need physical alignment to 8K
+        // Default page size does not need this ioctl
+        err = alignPmem(fd, size, 8192);
+        if (err < 0) {
+            ALOGE("alignPmem failed");
+        }
+    }
+    void* base = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+    if (base == MAP_FAILED) {
+        err = -errno;
+        ALOGE("%s: failed to map pmem fd: %s", mPmemDev,
+                strerror(errno));
+        close(fd);
+        return err;
+    }
+    memset(base, 0, size);
+    clean_buffer((void*)((intptr_t) base + offset), size, offset, fd);
+    data.base = base;
+    data.offset = 0;
+    data.fd = fd;
+    ALOGD("%s: Allocated buffer base:%p size:%d fd:%d",
+                            mPmemDev, base, size, fd);
+    return 0;
+
+}
+
+int PmemKernelAlloc::free_buffer(void* base, size_t size, int offset, int fd)
+{
+    ALOGD("%s: Freeing buffer base:%p size:%d fd:%d",
+            mPmemDev, base, size, fd);
+
+    int err =  unmap_buffer(base, size, offset);
+    close(fd);
+    return err;
+}
+
+int PmemKernelAlloc::map_buffer(void **pBase, size_t size, int offset, int fd)
+{
+    int err = 0;
+    void *base = mmap(0, size, PROT_READ| PROT_WRITE,
+            MAP_SHARED, fd, 0);
+    *pBase = base;
+    if(base == MAP_FAILED) {
+        err = -errno;
+        ALOGE("%s: Failed to map memory in the client: %s",
+                mPmemDev, strerror(errno));
+    } else {
+        ALOGD("%s: Mapped buffer base:%p size:%d, fd:%d",
+                                mPmemDev, base, size, fd);
+    }
+    return err;
+
+}
+
+int PmemKernelAlloc::unmap_buffer(void *base, size_t size, int offset)
+{
+    int err = 0;
+    if (munmap(base, size)) {
+        err = -errno;
+        ALOGW("%s: Error unmapping memory at %p: %s",
+                                mPmemDev, base, strerror(err));
+    }
+    return err;
+
+}
+int PmemKernelAlloc::clean_buffer(void *base, size_t size, int offset, int fd)
+{
+    return cleanPmem(base, size, offset, fd);
+}
+
diff --git a/libgralloc/pmemalloc.h b/libgralloc/pmemalloc.h
new file mode 100644
index 0000000..4aed0b1
--- /dev/null
+++ b/libgralloc/pmemalloc.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GRALLOC_PMEMALLOC_H
+#define GRALLOC_PMEMALLOC_H
+
+#include <linux/ion.h>
+#include <utils/RefBase.h>
+#include "memalloc.h"
+
+namespace gralloc {
+    class PmemUserspaceAlloc : public IMemAlloc  {
+
+        public:
+            class Allocator: public android::RefBase {
+                public:
+                    virtual ~Allocator() {};
+                    virtual ssize_t setSize(size_t size) = 0;
+                    virtual size_t  size() const = 0;
+                    virtual ssize_t allocate(size_t size, uint32_t flags = 0) = 0;
+                    virtual ssize_t deallocate(size_t offset) = 0;
+            };
+
+            virtual int alloc_buffer(alloc_data& data);
+
+            virtual int free_buffer(void *base, size_t size,
+                    int offset, int fd);
+
+            virtual int map_buffer(void **pBase, size_t size,
+                    int offset, int fd);
+
+            virtual int unmap_buffer(void *base, size_t size,
+                    int offset);
+
+            virtual int clean_buffer(void*base, size_t size,
+                    int offset, int fd);
+
+            PmemUserspaceAlloc();
+
+            ~PmemUserspaceAlloc();
+
+        private:
+            int mMasterFd;
+            void* mMasterBase;
+            const char* mPmemDev;
+            android::sp<Allocator> mAllocator;
+            pthread_mutex_t mLock;
+            int init_pmem_area();
+            int init_pmem_area_locked();
+
+    };
+
+    class PmemKernelAlloc : public IMemAlloc  {
+
+        public:
+            virtual int alloc_buffer(alloc_data& data);
+
+            virtual int free_buffer(void *base, size_t size,
+                    int offset, int fd);
+
+            virtual int map_buffer(void **pBase, size_t size,
+                    int offset, int fd);
+
+            virtual int unmap_buffer(void *base, size_t size,
+                    int offset);
+
+            virtual int clean_buffer(void*base, size_t size,
+                    int offset, int fd);
+
+            PmemKernelAlloc(const char* device);
+
+            ~PmemKernelAlloc();
+        private:
+            const char* mPmemDev;
+
+
+    };
+
+}
+#endif /* GRALLOC_PMEMALLOC_H */
diff --git a/libhwcomposer/Android.mk b/libhwcomposer/Android.mk
new file mode 100644
index 0000000..a600f97
--- /dev/null
+++ b/libhwcomposer/Android.mk
@@ -0,0 +1,39 @@
+LOCAL_PATH := $(call my-dir)
+
+# HAL module implemenation, not prelinked and stored in
+# hw/<OVERLAY_HARDWARE_MODULE_ID>.<ro.product.board>.so
+include $(CLEAR_VARS)
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+LOCAL_SHARED_LIBRARIES := liblog libcutils libEGL libhardware libutils liboverlay
+LOCAL_SHARED_LIBRARIES += libgenlock libQcomUI libmemalloc
+
+LOCAL_SRC_FILES := 	\
+    hwcomposer.cpp \
+    external_display_only.h
+
+LOCAL_MODULE := hwcomposer.$(TARGET_BOARD_PLATFORM)
+LOCAL_CFLAGS:= -DLOG_TAG=\"$(TARGET_BOARD_PLATFORM).hwcomposer\" -DDEBUG_CALC_FPS
+
+LOCAL_C_INCLUDES += hardware/qcom/display/libgralloc
+LOCAL_C_INCLUDES += hardware/qcom/display/liboverlay
+LOCAL_C_INCLUDES += hardware/qcom/display/libcopybit
+LOCAL_C_INCLUDES += hardware/qcom/display/libgenlock
+LOCAL_C_INCLUDES += hardware/qcom/display/libqcomui
+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+ifeq ($(TARGET_HAVE_HDMI_OUT),true)
+LOCAL_CFLAGS += -DHDMI_DUAL_DISPLAY
+endif
+ifeq ($(TARGET_USES_OVERLAY),true)
+LOCAL_CFLAGS += -DUSE_OVERLAY
+endif
+ifeq ($(TARGET_HAVE_BYPASS),true)
+LOCAL_CFLAGS += -DCOMPOSITION_BYPASS
+endif
+ifeq ($(TARGET_USE_HDMI_AS_PRIMARY),true)
+LOCAL_CFLAGS += -DHDMI_AS_PRIMARY
+endif
+LOCAL_MODULE_TAGS := optional eng
+include $(BUILD_SHARED_LIBRARY)
diff --git a/libhwcomposer/external_display_only.h b/libhwcomposer/external_display_only.h
new file mode 100644
index 0000000..fa24642
--- /dev/null
+++ b/libhwcomposer/external_display_only.h
@@ -0,0 +1,498 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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 Code Aurora Forum, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define EXTDEBUG 0
+class ExtDispOnly {
+
+    enum ExternalOnlyMode {
+        EXT_ONLY_MODE_OFF = 0,
+        EXT_ONLY_MODE_ON = 1,
+    };
+
+    enum {
+        MAX_EXT_ONLY_LAYERS = 2,
+    };
+
+public:
+    /* Initialize, allocate data members */
+    static void init();
+
+    /* Deallocate data members */
+    static void destroy();
+
+    /* Closes all the overlay channels */
+    static void close();
+
+    /* Prepare overlay and configures mdp pipes */
+    static int prepare(hwc_context_t *ctx, hwc_layer_t *layer, int index,
+            bool waitForVsync);
+
+    /* Returns status of external-only mode */
+    static bool isModeOn();
+
+    /* Updates stats and pipe config related to external_only and external_block layers
+     * If we are staring or stopping this mode, update default mirroring.
+     */
+    static int update(hwc_context_t* ctx, hwc_layer_list_t* list);
+
+    /* Stores the locked handle for the buffer that was successfully queued */
+    static void storeLockedHandles(hwc_layer_list_t* list);
+
+    /* Queue buffers to mdp for display */
+    static int draw(hwc_context_t *ctx, hwc_layer_list_t *list);
+
+private:
+    /* Locks a buffer and marks it as locked */
+    static void lockBuffer(native_handle_t *hnd);
+
+    /* Unlocks a buffer and clears the locked flag */
+    static void unlockBuffer(native_handle_t *hnd);
+
+    /* Unlocks buffers queued in previous round (and displayed by now)
+     * Clears the handle cache.
+     */
+    static void unlockPreviousBuffers();
+
+    /* Closes the  a range of overlay channels */
+    static void closeRange(int start);
+
+    /* Start default external mirroring */
+    static void startDefaultMirror(hwc_context_t* ctx);
+
+    /* Stop default external mirroring */
+    static void stopDefaultMirror(hwc_context_t* ctx);
+
+    /* Checks if external-only mode is starting */
+    static bool isExtModeStarting(hwc_context_t* ctx, const int&
+        numExtLayers);
+
+    /* Checks if external-only mode is stopping */
+    static bool isExtModeStopping(hwc_context_t* ctx, const int&
+        numExtLayers);
+
+    //Data members
+#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
+    static overlay::OverlayUI* sOvExtUI[MAX_EXT_ONLY_LAYERS];
+    static native_handle_t* sPreviousExtHandle[MAX_EXT_ONLY_LAYERS];
+    static ExternalOnlyMode sExtOnlyMode;
+    static int sNumExtOnlyLayers;
+    static bool sSkipLayerPresent;
+    static bool sBlockLayerPresent;
+    static int sBlockLayerIndex;
+#endif
+}; //class ExtDispOnly
+
+void ExtDispOnly::lockBuffer(native_handle_t *hnd) {
+#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
+    private_handle_t* phnd = (private_handle_t*)hnd;
+
+    //Genlock is reference counted and recursive.
+    //Do not accidently lock a locked buffer.
+    if(phnd && (phnd->flags & private_handle_t::PRIV_FLAGS_HWC_LOCK)) {
+        LOGE_IF(EXTDEBUG, "%s: handle %p already locked", __func__, phnd);
+        return;
+    }
+    if (GENLOCK_FAILURE == genlock_lock_buffer(hnd, GENLOCK_READ_LOCK,
+            GENLOCK_MAX_TIMEOUT)) {
+        LOGE("%s: genlock_lock_buffer(READ) failed", __func__);
+        return;
+    }
+    phnd->flags |= private_handle_t::PRIV_FLAGS_HWC_LOCK;
+    LOGE_IF(EXTDEBUG, "%s: locked handle = %p", __func__, hnd);
+#endif
+}
+
+void ExtDispOnly::unlockBuffer(native_handle_t *hnd) {
+#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
+    //Check if buffer is still around
+    if(private_handle_t::validate(hnd) != 0) {
+        LOGE("%s Handle already deallocated", __func__);
+        return;
+    }
+
+    private_handle_t* phnd = (private_handle_t*)hnd;
+
+    //Check if buffer was locked in the first place
+    if((phnd->flags & private_handle_t::PRIV_FLAGS_HWC_LOCK) == 0) {
+        LOGE("%s Handle not locked, cannot unlock", __func__);
+        return;
+    }
+
+    //Actually try to unlock
+    if (GENLOCK_FAILURE == genlock_unlock_buffer(hnd)) {
+        LOGE("%s: genlock_unlock_buffer failed", __func__);
+        return;
+    }
+
+    //Clear the locked flag
+    phnd->flags &= ~private_handle_t::PRIV_FLAGS_HWC_LOCK;
+    LOGE_IF(EXTDEBUG, "%s: unlocked handle = %p", __func__, hnd);
+#endif
+}
+
+void ExtDispOnly::unlockPreviousBuffers() {
+#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
+    for(int i = 0; (i < MAX_EXT_ONLY_LAYERS) && sPreviousExtHandle[i]; i++) {
+        LOGE_IF(EXTDEBUG, "%s", __func__);
+        ExtDispOnly::unlockBuffer(sPreviousExtHandle[i]);
+        sPreviousExtHandle[i] = NULL;
+    }
+#endif
+}
+
+void ExtDispOnly::init() {
+#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
+    for(int i = 0; i < MAX_EXT_ONLY_LAYERS; i++) {
+        sOvExtUI[i] = new overlay::OverlayUI();
+        sPreviousExtHandle[i] = NULL;
+    }
+    sExtOnlyMode = EXT_ONLY_MODE_OFF;
+    sNumExtOnlyLayers = 0;
+    sSkipLayerPresent = false;
+    sBlockLayerPresent = false;
+    sBlockLayerIndex = -1;
+    LOGE_IF(EXTDEBUG, "%s", __func__);
+#endif
+}
+
+void ExtDispOnly::destroy() {
+#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
+    for(int i = 0; i < MAX_EXT_ONLY_LAYERS; i++) {
+        delete sOvExtUI[i];
+    }
+#endif
+}
+
+void ExtDispOnly::closeRange(int start) {
+#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
+    for (int index = start; index < MAX_EXT_ONLY_LAYERS; index++) {
+        if(sPreviousExtHandle[index]) {
+            LOGE_IF(EXTDEBUG, "%s", __func__);
+            ExtDispOnly::unlockBuffer(sPreviousExtHandle[index]);
+            sPreviousExtHandle[index] = NULL;
+        }
+        sOvExtUI[index]->closeChannel();
+    }
+#endif
+}
+
+void inline ExtDispOnly::close() {
+#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
+    closeRange(0);
+#endif
+}
+
+int ExtDispOnly::prepare(hwc_context_t *ctx, hwc_layer_t *layer, int index,
+        bool waitForVsync) {
+#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
+    if(ctx->mHDMIEnabled == EXT_DISPLAY_OFF ||
+        ctx->pendingHDMI == true)
+        return -1;
+
+    if (ctx && sOvExtUI[index]) {
+        private_hwc_module_t* hwcModule = reinterpret_cast<
+                private_hwc_module_t*>(ctx->device.common.module);
+        if (!hwcModule) {
+            LOGE("%s null module", __func__);
+            return -1;
+        }
+        private_handle_t *hnd = (private_handle_t *)layer->handle;
+        if(!hnd) {
+            LOGE("%s handle null", __func__);
+            return -1;
+        }
+        overlay::OverlayUI *ovUI = sOvExtUI[index];
+        int ret = 0;
+        //int orientation = layer->transform;
+        //Assuming layers will always be source landscape
+        const int orientation = 0;
+        overlay_buffer_info info;
+        hwc_rect_t sourceCrop = layer->sourceCrop;
+        info.width = sourceCrop.right - sourceCrop.left;
+        info.height = sourceCrop.bottom - sourceCrop.top;
+        info.format = hnd->format;
+        info.size = hnd->size;
+
+
+        const int fbnum = ctx->mHDMIEnabled; //HDMI or WFD
+        const bool isFg = false;
+        //Just to differentiate zorders for different layers
+        const int zorder = index;
+        const bool isVGPipe = true;
+        ovUI->setSource(info, orientation);
+        ovUI->setDisplayParams(fbnum, waitForVsync, isFg, zorder, isVGPipe);
+        const int fbWidth = ovUI->getFBWidth();
+        const int fbHeight = ovUI->getFBHeight();
+        ovUI->setPosition(0, 0, fbWidth, fbHeight);
+        if(ovUI->commit() != overlay::NO_ERROR) {
+            LOGE("%s: Overlay Commit failed", __func__);
+            return -1;
+        }
+    }
+    LOGE_IF(EXTDEBUG, "%s", __func__);
+#endif
+    return overlay::NO_ERROR;
+}
+
+inline void ExtDispOnly::startDefaultMirror(hwc_context_t* ctx) {
+#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
+    hwc_composer_device_t* dev = (hwc_composer_device_t*) ctx;
+    private_hwc_module_t* hwcModule =
+        reinterpret_cast<private_hwc_module_t*>(dev->common.module);
+    framebuffer_device_t *fbDev = hwcModule->fbDevice;
+    if (fbDev) {
+        //mHDMIEnabled could be HDMI/WFD/NO EXTERNAL
+        fbDev->enableHDMIOutput(fbDev, ctx->mHDMIEnabled);
+    }
+#endif
+}
+
+inline void ExtDispOnly::stopDefaultMirror(hwc_context_t* ctx) {
+#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
+    hwc_composer_device_t* dev = (hwc_composer_device_t*) ctx;
+    private_hwc_module_t* hwcModule =
+        reinterpret_cast<private_hwc_module_t*>(dev->common.module);
+    framebuffer_device_t *fbDev = hwcModule->fbDevice;
+    if (fbDev) {
+        fbDev->enableHDMIOutput(fbDev, EXT_DISPLAY_OFF);
+    }
+#endif
+}
+
+inline bool ExtDispOnly::isExtModeStarting(hwc_context_t* ctx, const int&
+        numExtLayers) {
+#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
+    return ((sExtOnlyMode == EXT_ONLY_MODE_OFF) && numExtLayers);
+#endif
+    return false;
+}
+
+inline bool ExtDispOnly::isExtModeStopping(hwc_context_t* ctx, const int&
+        numExtLayers) {
+#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
+    return ((sExtOnlyMode == EXT_ONLY_MODE_ON) && (numExtLayers == 0));
+#endif
+    return false;
+}
+
+inline bool ExtDispOnly::isModeOn() {
+#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
+    return (sExtOnlyMode == EXT_ONLY_MODE_ON);
+#endif
+    return false;
+}
+
+int ExtDispOnly::update(hwc_context_t* ctx, hwc_layer_list_t* list) {
+#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
+    int aNumExtLayers = 0;
+    bool aSkipLayerPresent = false;
+    bool aBlockLayerPresent = false;
+    int aBlockLayerIndex = -1;
+
+    //Book-keeping done each cycle
+    for (size_t i = 0; i < list->numHwLayers; i++) {
+        private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
+        // Dont draw in this round
+        if(list->hwLayers[i].flags & HWC_SKIP_LAYER) {
+            aSkipLayerPresent = true;
+        }
+        if(hnd && (hnd->flags & private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY)) {
+            aNumExtLayers++;
+            // No way we can let this be drawn by GPU to fb0
+            if(list->hwLayers[i].flags & HWC_SKIP_LAYER) {
+                list->hwLayers[i].flags &= ~ HWC_SKIP_LAYER;
+            }
+            list->hwLayers[i].flags |= HWC_USE_EXT_ONLY;
+            list->hwLayers[i].compositionType = HWC_USE_OVERLAY;
+            list->hwLayers[i].hints &= ~HWC_HINT_CLEAR_FB;
+            //EXTERNAL_BLOCK is always an add-on
+            if(hnd && (hnd->flags &
+                    private_handle_t::PRIV_FLAGS_EXTERNAL_BLOCK)) {
+                aBlockLayerPresent = true;
+                aBlockLayerIndex = i;
+                list->hwLayers[i].flags |= HWC_USE_EXT_BLOCK;
+            }
+        }
+    }
+
+    //Update Default mirroring state
+    if (isExtModeStarting(ctx, aNumExtLayers)) {
+        stopDefaultMirror(ctx);
+    } else if (isExtModeStopping(ctx, aNumExtLayers)) {
+        startDefaultMirror(ctx);
+    }
+
+    //Cache our stats
+    sExtOnlyMode = aNumExtLayers ? EXT_ONLY_MODE_ON : EXT_ONLY_MODE_OFF;
+    sNumExtOnlyLayers = aNumExtLayers;
+    sSkipLayerPresent = aSkipLayerPresent;
+    sBlockLayerPresent = aBlockLayerPresent;
+    sBlockLayerIndex = aBlockLayerIndex;
+
+    LOGE_IF(EXTDEBUG, "%s: numExtLayers = %d skipLayerPresent = %d", __func__,
+            aNumExtLayers, aSkipLayerPresent);
+    //If skip layer present return. Buffers to be unlocked in draw phase.
+    if(aSkipLayerPresent) {
+        return overlay::NO_ERROR;
+    }
+
+    //If External is not connected, dont setup pipes, just return
+    if(ctx->mHDMIEnabled == EXT_DISPLAY_OFF ||
+        ctx->pendingHDMI == true) {
+        ExtDispOnly::close();
+        return -1;
+    }
+
+
+    //Update pipes
+    bool waitForVsync = true;
+    bool index = 0;
+
+    if (aBlockLayerPresent) {
+        ExtDispOnly::closeRange(1);
+        ExtDispOnly::prepare(ctx, &(list->hwLayers[aBlockLayerIndex]),
+            index, waitForVsync);
+    } else if (aNumExtLayers) {
+        ExtDispOnly::closeRange(aNumExtLayers);
+        for (size_t i = 0; i < list->numHwLayers; i++) {
+            private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
+            if(hnd && hnd->flags & private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY) {
+                waitForVsync = (index == (aNumExtLayers - 1));
+                ExtDispOnly::prepare(ctx, &(list->hwLayers[i]),
+                    index, waitForVsync);
+                index++;
+            }
+        }
+    } else {
+        ExtDispOnly::close();
+    }
+#endif
+    return overlay::NO_ERROR;
+}
+
+void ExtDispOnly::storeLockedHandles(hwc_layer_list_t* list) {
+#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
+    int index = 0;
+    if(sBlockLayerPresent) {
+        private_handle_t *hnd = (private_handle_t *)
+            list->hwLayers[sBlockLayerIndex].handle;
+        if(list->hwLayers[sBlockLayerIndex].flags & HWC_USE_EXT_ONLY) {
+            if(!(hnd->flags & private_handle_t::PRIV_FLAGS_HWC_LOCK)) {
+                ExtDispOnly::lockBuffer(hnd);
+            }
+            sPreviousExtHandle[index] = hnd;
+            LOGE_IF(EXTDEBUG, "%s BLOCK: handle = %p", __func__, hnd);
+            return;
+        }
+    }
+    for(int i = 0; i < list->numHwLayers; i++) {
+        private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
+        if(list->hwLayers[i].flags & HWC_USE_EXT_ONLY) {
+            if(!(hnd->flags & private_handle_t::PRIV_FLAGS_HWC_LOCK)) {
+                ExtDispOnly::lockBuffer(hnd);
+            }
+            sPreviousExtHandle[index] = hnd;
+            index++;
+            LOGE_IF(EXTDEBUG, "%s: handle = %p", __func__, hnd);
+        }
+    }
+#endif
+}
+
+int ExtDispOnly::draw(hwc_context_t *ctx, hwc_layer_list_t *list) {
+#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
+    LOGE_IF(EXTDEBUG, "%s", __func__);
+    if(ctx->mHDMIEnabled == EXT_DISPLAY_OFF ||
+        ctx->pendingHDMI == true) {
+        ExtDispOnly::close();
+        return -1;
+    }
+
+    int ret = overlay::NO_ERROR;
+    int index = 0;
+
+    //If skip layer present or list invalid unlock and return.
+    if(sSkipLayerPresent || list == NULL) {
+        ExtDispOnly::unlockPreviousBuffers();
+        return overlay::NO_ERROR;
+    }
+
+    if(sBlockLayerPresent) {
+        private_handle_t *hnd = (private_handle_t*)
+            list->hwLayers[sBlockLayerIndex].handle;
+        ExtDispOnly::lockBuffer(hnd);
+        ret =  sOvExtUI[index]->queueBuffer(hnd);
+        if (ret) {
+            LOGE("%s queueBuffer failed", __func__);
+            // Unlock the locked buffer
+            ExtDispOnly::unlockBuffer(hnd);
+            ExtDispOnly::close();
+            return -1;
+        }
+        ExtDispOnly::unlockPreviousBuffers();
+        ExtDispOnly::storeLockedHandles(list);
+        return overlay::NO_ERROR;
+    }
+
+    for(int i = 0; i < list->numHwLayers; i++) {
+        private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
+        if(hnd && list->hwLayers[i].flags & HWC_USE_EXT_ONLY) {
+            overlay::OverlayUI *ovUI = sOvExtUI[index];
+            ExtDispOnly::lockBuffer(hnd);
+            ret = ovUI->queueBuffer(hnd);
+            if (ret) {
+                LOGE("%s queueBuffer failed", __func__);
+                // Unlock the all the currently locked buffers
+                for (int j = 0; j <= i; j++) {
+                    private_handle_t *tmphnd =
+                        (private_handle_t *)list->hwLayers[j].handle;
+                    if(hnd && list->hwLayers[j].flags & HWC_USE_EXT_ONLY)
+                        ExtDispOnly::unlockBuffer(tmphnd);
+                }
+                ExtDispOnly::close();
+                return -1;
+            }
+            index++;
+        }
+    }
+    ExtDispOnly::unlockPreviousBuffers();
+    ExtDispOnly::storeLockedHandles(list);
+#endif
+    return overlay::NO_ERROR;
+}
+
+#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
+overlay::OverlayUI* ExtDispOnly::sOvExtUI[MAX_EXT_ONLY_LAYERS];
+native_handle_t* ExtDispOnly::sPreviousExtHandle[MAX_EXT_ONLY_LAYERS];
+ExtDispOnly::ExternalOnlyMode ExtDispOnly::sExtOnlyMode;
+int ExtDispOnly::sNumExtOnlyLayers;
+bool ExtDispOnly::sSkipLayerPresent;
+bool ExtDispOnly::sBlockLayerPresent;
+int ExtDispOnly::sBlockLayerIndex;
+#endif
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;
+}
diff --git a/liboverlay/Android.mk b/liboverlay/Android.mk
new file mode 100755
index 0000000..79e4256
--- /dev/null
+++ b/liboverlay/Android.mk
@@ -0,0 +1,43 @@
+# Copyright (C) 2008 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
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)
+LOCAL_SHARED_LIBRARIES := liblog libcutils libutils libmemalloc
+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+LOCAL_C_INCLUDES += hardware/qcom/display/libgralloc
+LOCAL_SRC_FILES := \
+    overlayLib.cpp \
+    overlayLibUI.cpp \
+LOCAL_CFLAGS:= -DLOG_TAG=\"OverlayLib\"
+
+ifeq ($(TARGET_USE_HDMI_AS_PRIMARY),true)
+LOCAL_CFLAGS += -DHDMI_AS_PRIMARY
+endif
+ifeq ($(TARGET_USES_POST_PROCESSING),true)
+LOCAL_CFLAGS += -DUSES_POST_PROCESSING
+LOCAL_SHARED_LIBRARIES += libmm-abl
+LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/pp/inc
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/lib/
+endif
+LOCAL_MODULE := liboverlay
+
+#LGE_CHANGE, for userdebug mode
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_SHARED_LIBRARY)
diff --git a/liboverlay/overlayLib.cpp b/liboverlay/overlayLib.cpp
new file mode 100755
index 0000000..fe5c3d3
--- /dev/null
+++ b/liboverlay/overlayLib.cpp
@@ -0,0 +1,2352 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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 "overlayLib.h"
+#include "gralloc_priv.h"
+
+#define INTERLACE_MASK 0x80
+#define DEBUG_OVERLAY true
+/* Helper functions */
+static inline size_t ALIGN(size_t x, size_t align) {
+    return (x + align-1) & ~(align-1);
+}
+
+using namespace overlay;
+using android::sp;
+using gralloc::IMemAlloc;
+using gralloc::IonController;
+using gralloc::alloc_data;
+
+#ifdef HDMI_AS_PRIMARY
+bool Overlay::sHDMIAsPrimary = true;
+#else
+bool Overlay::sHDMIAsPrimary = false;
+#endif
+
+template <class Type>
+void swapWidthHeight(Type& width, Type& height) {
+    Type tmp = width;
+    width = height;
+    height = tmp;
+}
+
+int overlay::get_mdp_format(int format) {
+    switch (format) {
+    case HAL_PIXEL_FORMAT_RGBA_8888 :
+        return MDP_RGBA_8888;
+    case HAL_PIXEL_FORMAT_BGRA_8888:
+        return MDP_BGRA_8888;
+    case HAL_PIXEL_FORMAT_RGB_565:
+        return MDP_RGB_565;
+    case HAL_PIXEL_FORMAT_RGBX_8888:
+        return MDP_RGBX_8888;
+    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+        return MDP_Y_CBCR_H2V1;
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+        return MDP_Y_CRCB_H2V2;
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+        return MDP_Y_CBCR_H2V2;
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
+        return MDP_Y_CRCB_H2V2_TILE;
+    case HAL_PIXEL_FORMAT_YV12:
+        return MDP_Y_CR_CB_GH2V2;
+    default:
+        LOGE("%s: unknown color format [0x%x]", __FUNCTION__, format);
+        return -1;
+    }
+    return -1;
+}
+
+int overlay::get_mdp_orientation(int value) {
+    switch(value) {
+        case 0: return 0;
+        case HAL_TRANSFORM_FLIP_V:  return MDP_FLIP_UD;
+        case HAL_TRANSFORM_FLIP_H:  return MDP_FLIP_LR;
+        case HAL_TRANSFORM_ROT_90:  return MDP_ROT_90;
+        case HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_V:
+                                    return MDP_ROT_90|MDP_FLIP_LR;
+        case HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_H:
+                                    return MDP_ROT_90|MDP_FLIP_UD;
+        case HAL_TRANSFORM_ROT_180: return MDP_ROT_180;
+        case HAL_TRANSFORM_ROT_270: return MDP_ROT_270;
+        default:
+            LOGE("%s: invalid rotation value (value = 0x%x",
+                  __FUNCTION__, value);
+            return -1;
+    }
+    return -1;
+}
+
+// Rotator - input to output mapping
+int overlay::get_rot_output_format(int format) {
+    switch (format) {
+    case MDP_Y_CRCB_H2V2_TILE:
+        return MDP_Y_CRCB_H2V2;
+    case MDP_Y_CB_CR_H2V2:
+        return MDP_Y_CBCR_H2V2;
+    case MDP_Y_CR_CB_GH2V2:
+        return MDP_Y_CRCB_H2V2;
+    default:
+        return format;
+    }
+    return -1;
+}
+
+// This function normalizes the crop values to be all even
+void overlay::normalize_crop(uint32_t& xy, uint32_t& wh) {
+
+    if (xy & 0x0001) {
+        // x or y is odd, increment it's value
+        xy += 1;
+        // Since we've incremented x(y), we need to decrement
+        // w(h) accordingly
+        if (wh & 0x0001) {
+            // w or h is odd, decrement it by 1, to make it even
+            EVEN_OUT(wh);
+        } else {
+            // w(h) is already even, hence we decrement by 2
+            wh -=2;
+        }
+    } else {
+        EVEN_OUT(wh);
+    }
+}
+
+#define LOG_TAG "OverlayLIB"
+static void reportError(const char* message) {
+    LOGE( "%s", message);
+}
+
+void overlay::dump(mdp_overlay& mOVInfo) {
+    if (!DEBUG_OVERLAY)
+        return;
+    LOGE("mOVInfo:");
+    LOGE("src: width %d height %d format %s user_data[0] %d", mOVInfo.src.width,
+        mOVInfo.src.height, getFormatString(mOVInfo.src.format),
+        mOVInfo.user_data[0]);
+    LOGE("src_rect: x %d y %d w %d h %d", mOVInfo.src_rect.x,
+        mOVInfo.src_rect.y, mOVInfo.src_rect.w, mOVInfo.src_rect.h);
+    LOGE("dst_rect: x %d y %d w %d h %d", mOVInfo.dst_rect.x,
+        mOVInfo.dst_rect.y, mOVInfo.dst_rect.w, mOVInfo.dst_rect.h);
+    LOGE("z_order %d is_fg %d alpha %d transp_mask %d flags %x id %d",
+        mOVInfo.z_order, mOVInfo.is_fg, mOVInfo.alpha, mOVInfo.transp_mask,
+        mOVInfo.flags, mOVInfo.id);
+}
+
+void overlay::dump(msm_rotator_img_info& mRotInfo) {
+    if (!DEBUG_OVERLAY)
+        return;
+    LOGE("mRotInfo:");
+    LOGE("session_id %d dst_x %d dst_y %d rotations %d enable %d",
+        mRotInfo.session_id, mRotInfo.dst_x, mRotInfo.dst_y,
+        mRotInfo.rotations, mRotInfo.enable);
+    LOGE("src: width %d height %d format %s", mRotInfo.src.width,
+        mRotInfo.src.height, getFormatString(mRotInfo.src.format));
+    LOGE("dst: width %d height %d format %s", mRotInfo.dst.width,
+        mRotInfo.dst.height, getFormatString(mRotInfo.src.format));
+    LOGE("src_rect: x %d y %d w %d h %d", mRotInfo.src_rect.x,
+        mRotInfo.src_rect.y, mRotInfo.src_rect.w, mRotInfo.src_rect.h);
+}
+
+const char* overlay::getFormatString(int format){
+    static const char* formats[] = {
+             "MDP_RGB_565",
+             "MDP_XRGB_8888",
+             "MDP_Y_CBCR_H2V2",
+             "MDP_ARGB_8888",
+             "MDP_RGB_888",
+             "MDP_Y_CRCB_H2V2",
+             "MDP_YCRYCB_H2V1",
+             "MDP_Y_CRCB_H2V1",
+             "MDP_Y_CBCR_H2V1",
+             "MDP_RGBA_8888",
+             "MDP_BGRA_8888",
+             "MDP_RGBX_8888",
+             "MDP_Y_CRCB_H2V2_TILE",
+             "MDP_Y_CBCR_H2V2_TILE",
+             "MDP_Y_CR_CB_H2V2",
+             "MDP_Y_CR_CB_GH2V2",
+             "MDP_Y_CB_CR_H2V2",
+             "MDP_Y_CRCB_H1V1",
+             "MDP_Y_CBCR_H1V1",
+             "MDP_IMGTYPE_LIMIT",
+             "MDP_BGR_565",
+             "MDP_FB_FORMAT",
+             "MDP_IMGTYPE_LIMIT2"
+        };
+    return formats[format];
+}
+ZOrderManager* ZOrderManager::sInstance = 0;
+FrameBufferInfo* FrameBufferInfo::sFBInfoInstance = 0;
+
+int ZOrderManager::getZ(int fbnum){
+    int zorder = NO_PIPE;;
+    Mutex::Autolock objLock(mObjMutex);
+    if(mPipesInuse == mMaxPipes) {
+        LOGE("No free pipes available.. inUse = %d ", mPipesInuse);
+        return NO_PIPE;
+    }
+    switch(fbnum) {
+        case FRAMEBUFFER_0:
+            for (int i = 0;i < NUM_CHANNELS; i++) {
+                if(mFB0Pipes[i] == false) {
+                    mFB0Pipes[i]= true;
+                    zorder = i;
+                    break;
+                }
+            }
+            break;
+        case FRAMEBUFFER_1:
+        case FRAMEBUFFER_2:
+            for (int i = 0;i < mMaxPipes; i++) {
+                if(mFB1Pipes[i] == false) {
+                    mFB1Pipes[i]= true;
+                    zorder = i;
+                    break;
+                 }
+             }
+             break;
+         default:
+             LOGE("getZ: Invalid framebuffer..");
+             break;
+    }
+    mPipesInuse++;
+    LOGE("getZ: return zorder = %d for fbdev = %d, pipesinUse = %d",
+            zorder, fbnum, mPipesInuse);
+    return zorder;
+}
+
+void ZOrderManager::decZ(int fbnum, int zorder){
+   Mutex::Autolock objLock(mObjMutex);
+   switch(fbnum) {
+       case FRAMEBUFFER_0:
+           LOG_ASSERT(!mFB0Pipes[zorder],"channel with ZOrder does not exist");
+           LOGE("decZ: freeing the pipe with zorder = %d for fbdev = %d", zorder, fbnum);
+           mFB0Pipes[zorder] = false;
+           break;
+       case FRAMEBUFFER_1:
+       case FRAMEBUFFER_2:
+           LOG_ASSERT(!mFB1Pipes[zorder],"channel with ZOrder does not exist");
+           LOGE("decZ: freeing the pipe with zorder = %d for fbdev = %d", zorder, fbnum);
+           mFB1Pipes[zorder] = false;
+           break;
+       default:
+           LOGE("decZ: Invalid framebuffer ");
+           break;
+    }
+    if(mPipesInuse > 0)
+        mPipesInuse--;
+    LOGE("decZ: Pipes in use  = %d", mPipesInuse);
+}
+
+bool overlay::isHDMIConnected () {
+    char value[PROPERTY_VALUE_MAX];
+    property_get("hw.hdmiON", value, "0");
+    int isHDMI = atoi(value);
+    return isHDMI ? true : false;
+}
+
+bool overlay::is3DTV() {
+    char is3DTV = '0';
+    FILE *fp = fopen(EDID_3D_INFO_FILE, "r");
+    if (fp) {
+        fread(&is3DTV, 1, 1, fp);
+        fclose(fp);
+    }
+    LOGI("3DTV EDID flag: %c", is3DTV);
+    return (is3DTV == '0') ? false : true;
+}
+
+bool overlay::isPanel3D() {
+    int fd = open("/dev/graphics/fb0", O_RDWR, 0);
+    if (fd < 0) {
+        reportError("Can't open framebuffer 0");
+        return false;
+    }
+    fb_fix_screeninfo finfo;
+    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) {
+        reportError("FBIOGET_FSCREENINFO on fb0 failed");
+        close(fd);
+        fd = -1;
+        return false;
+    }
+    close(fd);
+    return (FB_TYPE_3D_PANEL == finfo.type) ? true : false;
+}
+
+bool overlay::usePanel3D() {
+    if (Overlay::sHDMIAsPrimary)
+        return is3DTV();
+
+    if(!isPanel3D())
+        return false;
+    char value[PROPERTY_VALUE_MAX];
+    property_get("persist.user.panel3D", value, "0");
+    int usePanel3D = atoi(value);
+    return usePanel3D ? true : false;
+}
+
+bool overlay::send3DInfoPacket (unsigned int format3D) {
+    FILE *fp = fopen(FORMAT_3D_FILE, "wb");
+    if (fp) {
+        fprintf(fp, "%d", format3D);
+        fclose(fp);
+        fp = NULL;
+        return true;
+    }
+    LOGE("%s:no sysfs entry for setting 3d mode!", __FUNCTION__);
+    return false;
+}
+
+bool overlay::enableBarrier (unsigned int orientation) {
+    FILE *fp = fopen(BARRIER_FILE, "wb");
+    if (fp) {
+        fprintf(fp, "%d", orientation);
+        fclose(fp);
+        fp = NULL;
+        return true;
+    }
+    LOGE("%s:no sysfs entry for enabling barriers on 3D panel!", __FUNCTION__);
+    return false;
+}
+
+int overlay::getColorFormat(int format)
+{
+    if (format == HAL_PIXEL_FORMAT_YV12)
+        return format;
+    else if (format & INTERLACE_MASK)
+        return format ^ HAL_PIXEL_FORMAT_INTERLACE;
+    else
+        return COLOR_FORMAT(format);
+}
+
+bool overlay::isInterlacedContent(int format)
+{
+    if ((format != HAL_PIXEL_FORMAT_YV12) &&
+        (format & INTERLACE_MASK))
+        return true;
+
+    return false;
+}
+
+unsigned int overlay::getOverlayConfig (unsigned int format3D, bool poll,
+        bool isHDMI) {
+    bool isTV3D = false;
+    unsigned int curState = 0;
+    if (poll)
+        isHDMI = isHDMIConnected();
+    if (isHDMI) {
+        LOGD("%s: HDMI connected... checking the TV type", __FUNCTION__);
+        if (format3D) {
+            if (is3DTV())
+                curState = OV_3D_VIDEO_3D_TV;
+            else
+                curState = OV_3D_VIDEO_2D_TV;
+        } else
+            curState = OV_2D_VIDEO_ON_TV;
+    } else {
+        LOGD("%s: HDMI not connected...", __FUNCTION__);
+        if(format3D) {
+            if (usePanel3D())
+                curState = OV_3D_VIDEO_3D_PANEL;
+            else
+                curState = OV_3D_VIDEO_2D_PANEL;
+        }
+        else
+            curState = OV_2D_VIDEO_ON_PANEL;
+    }
+    return curState;
+}
+
+/* clears any VG pipes allocated to the fb devices */
+int overlay::initOverlay() {
+    msmfb_mixer_info_req  req;
+    mdp_mixer_info *minfo = NULL;
+    char name[64];
+    int fd = -1;
+    for(int i = 0; i < NUM_FB_DEVICES; i++) {
+        snprintf(name, 64, FB_DEVICE_TEMPLATE, i);
+        LOGD("initoverlay:: opening the device:: %s", name);
+        fd = open(name, O_RDWR, 0);
+        if(fd < 0) {
+            LOGE("cannot open framebuffer(%d)", i);
+            return -1;
+        }
+        //Get the mixer configuration */
+        req.mixer_num = i;
+        if (ioctl(fd, MSMFB_MIXER_INFO, &req) == -1) {
+            LOGE("ERROR: MSMFB_MIXER_INFO ioctl failed");
+            close(fd);
+            return -1;
+        }
+        minfo = req.info;
+        for (int j = 0; j < req.cnt; j++) {
+            LOGD("ndx=%d num=%d z_order=%d", minfo->pndx, minfo->pnum,
+                    minfo->z_order);
+            // except the RGB base layer with z_order of -1, clear any
+            // other pipes connected to mixer.
+            if((minfo->z_order) != -1) {
+                int index = minfo->pndx;
+                LOGD("Unset overlay with index: %d at mixer %d", index, i);
+                if(ioctl(fd, MSMFB_OVERLAY_UNSET, &index) == -1) {
+                    LOGE("ERROR: MSMFB_OVERLAY_UNSET failed");
+                    close(fd);
+                    return -1;
+                }
+            }
+            minfo++;
+        }
+        close(fd);
+        fd = -1;
+    }
+    return 0;
+}
+
+Overlay::Overlay() : mChannelUP(false), mExternalDisplay(false),
+                     mS3DFormat(0), mCroppedSrcWidth(0),
+                     mCroppedSrcHeight(0), mState(-1) {
+    mOVBufferInfo.width = mOVBufferInfo.height = 0;
+    mOVBufferInfo.format = mOVBufferInfo.size = 0;
+}
+
+Overlay::~Overlay() {
+    closeChannel();
+}
+
+int Overlay::getFBWidth(int channel) const {
+    return objOvCtrlChannel[channel].getFBWidth();
+}
+
+int Overlay::getFBHeight(int channel) const {
+    return objOvCtrlChannel[channel].getFBHeight();
+}
+
+bool Overlay::startChannel(const overlay_buffer_info& info, int fbnum,
+                              bool norot, bool uichannel,
+                              unsigned int format3D, int channel,
+                              int flags, int num_buffers) {
+    int zorder = 0;
+    mCroppedSrcWidth = info.width;
+    mCroppedSrcHeight = info.height;
+    if (format3D)
+        zorder = channel;
+    if (mState == -1)
+        mState = OV_UI_MIRROR_TV;
+
+    mChannelUP = objOvCtrlChannel[channel].startControlChannel(info, fbnum,
+                                                       norot, uichannel,
+                                                       format3D, zorder, flags);
+    if (!mChannelUP) {
+        LOGE("startChannel for fb%d failed", fbnum);
+        return mChannelUP;
+    }
+    bool secure = flags & SECURE_OVERLAY_SESSION;
+    objOvCtrlChannel[channel].setSize(info.size);
+    return objOvDataChannel[channel].startDataChannel(objOvCtrlChannel[channel], fbnum,
+                                            norot, secure, uichannel, num_buffers);
+}
+
+bool Overlay::closeChannel() {
+
+    if (!mChannelUP)
+        return true;
+
+    if(mS3DFormat) {
+        if (mExternalDisplay)
+            overlay::send3DInfoPacket(0);
+        else if (mState == OV_3D_VIDEO_3D_PANEL) {
+            if (sHDMIAsPrimary)
+                overlay::send3DInfoPacket(0);
+            else
+                enableBarrier(0);
+        }
+    }
+    for (int i = 0; i < NUM_CHANNELS; i++) {
+        objOvCtrlChannel[i].closeControlChannel();
+        objOvDataChannel[i].closeDataChannel();
+    }
+    mChannelUP = false;
+    mS3DFormat = 0;
+    mOVBufferInfo.width = 0;
+    mOVBufferInfo.height = 0;
+    mOVBufferInfo.format = 0;
+    mOVBufferInfo.size = 0;
+    mState = -1;
+    return true;
+}
+
+void Overlay::closeExternalChannel() {
+    if (objOvCtrlChannel[VG1_PIPE].isChannelUP()) {
+        objOvCtrlChannel[VG1_PIPE].closeControlChannel();
+        objOvDataChannel[VG1_PIPE].closeDataChannel();
+    }
+}
+
+bool Overlay::getPosition(int& x, int& y, uint32_t& w, uint32_t& h, int channel) {
+    return objOvCtrlChannel[channel].getPosition(x, y, w, h);
+}
+
+bool Overlay::getOrientation(int& orientation, int channel) const {
+    return objOvCtrlChannel[channel].getOrientation(orientation);
+}
+
+bool Overlay::setDeviceOrientation(int orientation) {
+    // Use this to calculate the position on HDMI
+    mDevOrientation = orientation;
+    return true;
+}
+
+bool Overlay::setPosition(int x, int y, uint32_t w, uint32_t h) {
+    bool ret = false;
+    overlay_rect secDest;
+    overlay_rect priDest;
+    int currX, currY;
+    uint32_t currW, currH;
+    // Set even destination co-ordinates
+    EVEN_OUT(x); EVEN_OUT(y);
+    EVEN_OUT(w); EVEN_OUT(h);
+    objOvCtrlChannel[VG0_PIPE].getPosition(currX, currY, currW, currH);
+    priDest.x = x, priDest.y = y;
+    priDest.w = w, priDest.h = h;
+    if(x != currX || y != currY || w != currW || h != currH) {
+        switch (mState) {
+            case OV_UI_MIRROR_TV:
+            case OV_2D_VIDEO_ON_PANEL:
+            case OV_3D_VIDEO_2D_PANEL:
+                return setChannelPosition(x, y, w, h, VG0_PIPE);
+                break;
+            case OV_2D_VIDEO_ON_TV:
+                if (FrameBufferInfo::getInstance()->canSupportTrueMirroring()) {
+                    objOvCtrlChannel[VG1_PIPE].getAspectRatioPosition(
+                            mCroppedSrcWidth, mCroppedSrcHeight, mDevOrientation,
+                            &priDest, &secDest);
+                } else {
+                    objOvCtrlChannel[VG1_PIPE].getAspectRatioPosition(
+                            mCroppedSrcWidth, mCroppedSrcHeight, &secDest);
+                }
+                setChannelPosition(secDest.x, secDest.y, secDest.w, secDest.h,
+                            VG1_PIPE);
+                return setChannelPosition(x, y, w, h, VG0_PIPE);
+                break;
+            case OV_3D_VIDEO_3D_PANEL:
+                for (int i = 0; i < NUM_CHANNELS; i++) {
+                    if (sHDMIAsPrimary)
+                        objOvCtrlChannel[i].getPositionS3D(i, mS3DFormat, &secDest);
+                    else {
+                        if (!objOvCtrlChannel[i].useVirtualFB()) {
+                            LOGE("%s: failed virtual fb for channel %d", __FUNCTION__, i);
+                            return false;
+                        }
+                        objOvCtrlChannel[i].getPositionS3D(i, 0x1, &secDest);
+                    }
+                    if(!setChannelPosition(secDest.x, secDest.y, secDest.w,
+                                                               secDest.h, i)) {
+                        LOGE("%s: failed for channel %d", __FUNCTION__, i);
+                        return false;
+                    }
+                }
+                break;
+            case OV_3D_VIDEO_2D_TV:
+            case OV_3D_VIDEO_3D_TV:
+                for (int i = 0; i < NUM_CHANNELS; i++) {
+                    ret = objOvCtrlChannel[i].getPositionS3D(i, mS3DFormat,
+                                                                     &secDest);
+                    if (!ret)
+                        ret = setChannelPosition(x, y, w, h, i);
+                    else
+                        ret = setChannelPosition(secDest.x, secDest.y, secDest.w,
+                                                                  secDest.h, i);
+                    if (!ret) {
+                        LOGE("%s: failed for channel %d", __FUNCTION__, i);
+                        return ret;
+                    }
+                }
+                break;
+            default:
+                LOGE("%s:Unknown state %d", __FUNCTION__, mState);
+                break;
+        }
+    }
+    return true;
+}
+
+bool Overlay::setChannelPosition(int x, int y, uint32_t w, uint32_t h, int channel) {
+    return objOvCtrlChannel[channel].setPosition(x, y, w, h);
+}
+
+bool Overlay::updateOverlaySource(const overlay_buffer_info& info, int orientation,
+                                  int flags) {
+    bool ret = false;
+    int currentFlags = 0;
+
+    bool needUpdateFlags = false;
+    if (objOvCtrlChannel[0].isChannelUP()) {
+        needUpdateFlags = objOvCtrlChannel[0].doFlagsNeedUpdate(flags);
+    }
+
+    bool geometryChanged = true;
+    if (info.width == mOVBufferInfo.width &&
+        info.height == mOVBufferInfo.height &&
+        info.format == mOVBufferInfo.format) {
+        geometryChanged = false;
+    }
+
+    if (sHDMIAsPrimary)
+        needUpdateFlags = false;
+
+    if ((false == needUpdateFlags) && (false == geometryChanged)) {
+        return true;
+    }
+
+    // Disable rotation for the HDMI channels
+    int orientHdmi = 0;
+    int orientPrimary = sHDMIAsPrimary ? 0 : orientation;
+    int orient[2] = {orientPrimary, orientHdmi};
+    // disable waitForVsync on HDMI, since we call the wait ioctl
+    int ovFlagsExternal = 0;
+    int ovFlagsPrimary = sHDMIAsPrimary ? (flags |= WAIT_FOR_VSYNC): flags;
+    int ovFlags[2] = {flags, ovFlagsExternal};
+    switch(mState) {
+        case OV_3D_VIDEO_3D_PANEL:
+            orient[1] = sHDMIAsPrimary ? 0 : orientation;
+            break;
+        case OV_3D_VIDEO_3D_TV:
+            orient[0] = 0;
+            break;
+        default:
+            break;
+    }
+
+    int numChannelsToUpdate = NUM_CHANNELS;
+    if (!geometryChanged) {
+        // Only update the primary channel - we only need to update the
+        // wait/no-wait flags
+        if (objOvCtrlChannel[0].isChannelUP()) {
+            return objOvCtrlChannel[0].updateOverlayFlags(flags);
+        }
+    }
+
+    // Set the overlay source info
+    for (int i = 0; i < NUM_CHANNELS; i++) {
+        if (objOvCtrlChannel[i].isChannelUP()) {
+            ret = objOvCtrlChannel[i].updateOverlaySource(info, orient[i], ovFlags[i]);
+            if (!ret) {
+                LOGE("objOvCtrlChannel[%d].updateOverlaySource failed", i);
+                return false;
+            }
+            objOvCtrlChannel[i].setSize(info.size);
+            ret = objOvDataChannel[i].updateDataChannel(info.size);
+        }
+    }
+    if (ret) {
+        mOVBufferInfo = info;
+    } else
+        LOGE("update failed");
+    return ret;
+}
+
+bool Overlay::getAspectRatioPosition(int w, int h, overlay_rect *rect, int channel) {
+    return objOvCtrlChannel[channel].getAspectRatioPosition(w, h, rect);
+}
+
+int Overlay::getS3DFormat(int format) {
+    // The S3D is part of the HAL_PIXEL_FORMAT_YV12 value. Add
+    // an explicit check for the format
+    if (format == HAL_PIXEL_FORMAT_YV12) {
+        return 0;
+    }
+    int format3D = FORMAT_3D(format);
+    int fIn3D = FORMAT_3D_INPUT(format3D); // MSB 2 bytes are input format
+    int fOut3D = FORMAT_3D_OUTPUT(format3D); // LSB 2 bytes are output format
+    format3D = fIn3D | fOut3D;
+    if (!fIn3D) {
+        format3D |= fOut3D << SHIFT_3D; //Set the input format
+    }
+    if (!fOut3D) {
+        format3D |= fIn3D >> SHIFT_3D; //Set the output format
+    }
+    return format3D;
+}
+
+bool Overlay::setSource(const overlay_buffer_info& info, int orientation,
+                        int hdmiConnected, int flags, int num_buffers) {
+    // Separate the color format from the 3D format.
+    // If there is 3D content; the effective format passed by the client is:
+    // effectiveFormat = 3D_IN | 3D_OUT | ColorFormat
+    int newState = mState;
+    bool stateChange = false, ret = true;
+    bool isHDMIStateChange = (mExternalDisplay != hdmiConnected) && (mState != -1);
+    unsigned int format3D = getS3DFormat(info.format);
+    int colorFormat = getColorFormat(info.format);
+    if (isHDMIStateChange || -1 == mState) {
+        // we were mirroring UI. Also HDMI state stored was stale
+        newState = getOverlayConfig (format3D, false, hdmiConnected);
+        stateChange = (mState == newState) ? false : true;
+    }
+
+    if (stateChange) {
+        mExternalDisplay = hdmiConnected;
+        mState = newState;
+        mS3DFormat = format3D;
+        if (mState == OV_3D_VIDEO_2D_PANEL || mState == OV_3D_VIDEO_2D_TV) {
+            LOGI("3D content on 2D display: set the output format as monoscopic");
+            mS3DFormat = FORMAT_3D_INPUT(format3D) | HAL_3D_OUT_MONOSCOPIC_MASK;
+        }
+        // We always enable the rotator for the primary.
+        bool noRot = false;
+        bool uiChannel = false;
+        int fbnum = 0;
+        switch(mState) {
+            case OV_2D_VIDEO_ON_PANEL:
+                if(isHDMIStateChange) {
+                    //close HDMI Only
+                    closeExternalChannel();
+                    break;
+                }
+            case OV_3D_VIDEO_2D_PANEL:
+                closeChannel();
+                return startChannel(info, FRAMEBUFFER_0, noRot, false,
+                        mS3DFormat, VG0_PIPE, flags, num_buffers);
+                break;
+            case OV_3D_VIDEO_3D_PANEL:
+                closeChannel();
+                if (sHDMIAsPrimary) {
+                    noRot = true;
+                    flags |= WAIT_FOR_VSYNC;
+                    send3DInfoPacket(mS3DFormat & OUTPUT_MASK_3D);
+                }
+                for (int i=0; i<NUM_CHANNELS; i++) {
+                    if(!startChannel(info, FRAMEBUFFER_0, noRot, uiChannel,
+                                mS3DFormat, i, flags, num_buffers)) {
+                        LOGE("%s:failed to open channel %d", __FUNCTION__, i);
+                        return false;
+                    }
+                }
+                break;
+            case OV_2D_VIDEO_ON_TV:
+                if(isHDMIStateChange) {
+                   //start only HDMI channel
+                   noRot = true;
+                   bool waitForVsync = true;
+                   // External display connected, start corresponding channel
+                   // mExternalDisplay will hold the fbnum
+                   if(!startChannel(info, mExternalDisplay, noRot, false, mS3DFormat,
+                               VG1_PIPE, waitForVsync, num_buffers)) {
+                       LOGE("%s:failed to open channel %d", __func__, VG1_PIPE);
+                       return false;
+                   }
+                   int currX, currY;
+                   uint32_t currW, currH;
+                   overlay_rect priDest;
+                   overlay_rect secDest;
+                   objOvCtrlChannel[VG0_PIPE].getPosition(currX, currY, currW, currH);
+                   priDest.x = currX, priDest.y = currY;
+                   priDest.w = currW, priDest.h = currH;
+                   if (FrameBufferInfo::getInstance()->canSupportTrueMirroring()) {
+                       objOvCtrlChannel[VG1_PIPE].getAspectRatioPosition(
+                               mCroppedSrcWidth, mCroppedSrcHeight, mDevOrientation,
+                               &priDest, &secDest);
+                   } else {
+                       objOvCtrlChannel[VG1_PIPE].getAspectRatioPosition(
+                               mCroppedSrcWidth, mCroppedSrcHeight, &secDest);
+                   }
+                   return setChannelPosition(secDest.x, secDest.y, secDest.w, secDest.h, VG1_PIPE);
+                }
+            case OV_3D_VIDEO_2D_TV:
+                closeChannel();
+                for (int i=0; i<NUM_CHANNELS; i++) {
+                    fbnum = i;
+                    //start two channels for one for primary and external.
+                    if (fbnum) {
+                        // Disable rotation for external
+                        noRot = true;
+                        //set fbnum to hdmiConnected, which holds the ext display
+                        fbnum = hdmiConnected;
+                        flags &= ~WAIT_FOR_VSYNC;
+                    }
+                    if(!startChannel(info, fbnum, noRot, false, mS3DFormat,
+                                i, flags, num_buffers)) {
+                        LOGE("%s:failed to open channel %d", __FUNCTION__, i);
+                        return false;
+                    }
+                }
+                return true;
+                break;
+            case OV_3D_VIDEO_3D_TV:
+                closeChannel();
+                for (int i=0; i<NUM_CHANNELS; i++) {
+                    if(!startChannel(info, FRAMEBUFFER_1, true, false,
+                                mS3DFormat, i, flags, num_buffers)) {
+                        LOGE("%s:failed to open channel %d", __FUNCTION__, i);
+                        return false;
+                    }
+                    send3DInfoPacket(mS3DFormat & OUTPUT_MASK_3D);
+                }
+                break;
+            default:
+                LOGE("%s:Unknown state %d", __FUNCTION__, mState);
+                break;
+        }
+    } else {
+        ret = updateOverlaySource(info, orientation, flags);
+// LGE_CHANGE_S, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents {
+        return ret;
+// LGE_CHANGE_E, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents }
+    }
+    return true;
+}
+
+bool Overlay::setCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h) {
+    if (!mChannelUP) {
+        LOGE("%s: channel not set", __FUNCTION__);
+        return false;
+    }
+    overlay_rect rect, inRect;
+    inRect.x = x; inRect.y = y; inRect.w = w; inRect.h = h;
+    mCroppedSrcWidth = w;
+    mCroppedSrcHeight = h;
+    switch (mState) {
+        case OV_UI_MIRROR_TV:
+        case OV_2D_VIDEO_ON_PANEL:
+            return setChannelCrop(x, y, w, h, VG0_PIPE);
+            break;
+        case OV_3D_VIDEO_2D_PANEL:
+            objOvDataChannel[VG0_PIPE].getCropS3D(&inRect, VG0_PIPE, mS3DFormat, &rect);
+            return setChannelCrop(rect.x, rect.y, rect.w, rect.h, VG0_PIPE);
+            break;
+        case OV_2D_VIDEO_ON_TV:
+            for (int i=0; i<NUM_CHANNELS; i++) {
+                if(!setChannelCrop(x, y, w, h, i)) {
+                    LOGE("%s: failed for pipe %d", __FUNCTION__, i);
+                    return false;
+                }
+            }
+            break;
+        case OV_3D_VIDEO_3D_PANEL:
+        case OV_3D_VIDEO_2D_TV:
+        case OV_3D_VIDEO_3D_TV:
+            for (int i=0; i<NUM_CHANNELS; i++) {
+                objOvDataChannel[i].getCropS3D(&inRect, i, mS3DFormat, &rect);
+                if(!setChannelCrop(rect.x, rect.y, rect.w, rect.h, i)) {
+                    LOGE("%s: failed for pipe %d", __FUNCTION__, i);
+                    return false;
+                }
+            }
+            break;
+        default:
+            LOGE("%s:Unknown state %d", __FUNCTION__, mState);
+            break;
+    }
+    return true;
+}
+
+bool Overlay::setChannelCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h, int channel) {
+    return objOvDataChannel[channel].setCrop(x, y, w, h);
+}
+
+bool Overlay::updateOverlayFlags(int flags) {
+        return objOvCtrlChannel[VG0_PIPE].updateOverlayFlags(flags);
+}
+
+bool Overlay::setTransform(int value) {
+    int barrier = 0;
+    switch (mState) {
+        case OV_UI_MIRROR_TV:
+        case OV_2D_VIDEO_ON_PANEL:
+        case OV_3D_VIDEO_2D_PANEL:
+            return objOvCtrlChannel[VG0_PIPE].setTransform(value);
+            break;
+        case OV_2D_VIDEO_ON_TV:
+        case OV_3D_VIDEO_2D_TV:
+        case OV_3D_VIDEO_3D_TV:
+            for (int i=0; i<NUM_CHANNELS; i++) {
+                if(!objOvCtrlChannel[i].setTransform(value)) {
+                    LOGE("%s:failed for channel %d", __FUNCTION__, i);
+                    return false;
+                }
+            }
+            break;
+        case OV_3D_VIDEO_3D_PANEL:
+            switch (value) {
+                case HAL_TRANSFORM_ROT_90:
+                case HAL_TRANSFORM_ROT_270:
+                    barrier = BARRIER_LANDSCAPE;
+                    break;
+                default:
+                    barrier = BARRIER_PORTRAIT;
+                    break;
+                    if(!enableBarrier(barrier))
+                        LOGE("%s:failed to enable barriers for 3D video", __FUNCTION__);
+            }
+            for (int i=0; i<NUM_CHANNELS; i++) {
+                if(!objOvCtrlChannel[i].setTransform(value)) {
+                    LOGE("%s:failed for channel %d", __FUNCTION__, i);
+                    return false;
+               }
+            }
+            break;
+        default:
+            LOGE("%s:Unknown state %d", __FUNCTION__, mState);
+            break;
+    }
+    return true;
+}
+
+bool Overlay::setFd(int fd, int channel) {
+    return objOvDataChannel[channel].setFd(fd);
+}
+
+bool Overlay::queueBuffer(uint32_t offset, int channel) {
+    return objOvDataChannel[channel].queueBuffer(offset);
+}
+
+bool Overlay::waitForHdmiVsync(int channel) {
+    return objOvDataChannel[channel].waitForHdmiVsync();
+}
+
+bool Overlay::queueBuffer(buffer_handle_t buffer) {
+    private_handle_t const* hnd = reinterpret_cast
+                                   <private_handle_t const*>(buffer);
+    if (!hnd) {
+        LOGE("Overlay::queueBuffer invalid handle");
+        return false;
+    }
+    const size_t offset = hnd->offset;
+    const int fd = hnd->fd;
+    switch (mState) {
+        case OV_UI_MIRROR_TV:
+        case OV_2D_VIDEO_ON_PANEL:
+        case OV_3D_VIDEO_2D_PANEL:
+            if(!queueBuffer(fd, offset, VG0_PIPE)) {
+                LOGE("%s:failed for channel 0", __FUNCTION__);
+                return false;
+            }
+            break;
+        case OV_2D_VIDEO_ON_TV:
+        case OV_3D_VIDEO_3D_PANEL:
+        case OV_3D_VIDEO_2D_TV:
+        case OV_3D_VIDEO_3D_TV:
+            for (int i=NUM_CHANNELS-1; i>=0; i--) {
+                if(!queueBuffer(fd, offset, i)) {
+                    LOGE("%s:failed for channel %d", __FUNCTION__, i);
+                    return false;
+                }
+            }
+            //Wait for HDMI done..
+            if(!waitForHdmiVsync(VG1_PIPE)) {
+                LOGE("%s: waitforHdmiVsync failed", __FUNCTION__);
+                return false;
+            }
+            break;
+        default:
+            LOGE("%s:Unknown state %d", __FUNCTION__, mState);
+            break;
+    }
+    return true;
+}
+
+bool Overlay::queueBuffer(int fd, uint32_t offset, int channel) {
+    bool ret = false;
+    ret = setFd(fd, channel);
+    if(!ret) {
+        LOGE("Overlay::queueBuffer channel %d setFd failed", channel);
+        return false;
+    }
+    ret = queueBuffer(offset, channel);
+    if(!ret) {
+        LOGE("Overlay::queueBuffer channel %d queueBuffer failed", channel);
+        return false;
+    }
+    return ret;
+}
+
+OverlayControlChannel::OverlayControlChannel() : mNoRot(false), mFD(-1), mRotFD(-1),
+                                                 mFormat3D(0), mIsChannelUpdated(true) {
+    memset(&mOVInfo, 0, sizeof(mOVInfo));
+    memset(&m3DOVInfo, 0, sizeof(m3DOVInfo));
+    memset(&mRotInfo, 0, sizeof(mRotInfo));
+}
+
+
+OverlayControlChannel::~OverlayControlChannel() {
+    closeControlChannel();
+}
+
+bool OverlayControlChannel::getAspectRatioPosition(int w, int h, overlay_rect *rect)
+{
+    int width = w, height = h, x, y;
+    int fbWidth  = getFBWidth();
+    int fbHeight = getFBHeight();
+    // width and height for YUV TILE format
+    int tempWidth = w, tempHeight = h;
+    /* Calculate the width and height if it is YUV TILE format*/
+    if(getFormat() == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
+        tempWidth = w - ( (((w-1)/64 +1)*64) - w);
+        tempHeight = h - ((((h-1)/32 +1)*32) - h);
+    }
+    if (width * fbHeight > fbWidth * height) {
+        height = fbWidth * height / width;
+        EVEN_OUT(height);
+        width = fbWidth;
+    } else if (width * fbHeight < fbWidth * height) {
+        width = fbHeight * width / height;
+        EVEN_OUT(width);
+        height = fbHeight;
+    } else {
+        width = fbWidth;
+        height = fbHeight;
+    }
+    /* Scaling of upto a max of 8 times supported */
+    if(width >(tempWidth * HW_OVERLAY_MAGNIFICATION_LIMIT)){
+        width = HW_OVERLAY_MAGNIFICATION_LIMIT * tempWidth;
+    }
+    if(height >(tempHeight*HW_OVERLAY_MAGNIFICATION_LIMIT)) {
+        height = HW_OVERLAY_MAGNIFICATION_LIMIT * tempHeight;
+    }
+    if (width > fbWidth) width = fbWidth;
+    if (height > fbHeight) height = fbHeight;
+
+    char value[PROPERTY_VALUE_MAX];
+    property_get("hw.actionsafe.width", value, "0");
+    float asWidth = atof(value);
+    property_get("hw.actionsafe.height", value, "0");
+    float asHeight = atof(value);
+    width = width * (1.0f -  asWidth / 100.0f);
+    height = height * (1.0f -  asHeight / 100.0f);
+
+    x = (fbWidth - width) / 2;
+    y = (fbHeight - height) / 2;
+    rect->x = x;
+    rect->y = y;
+    rect->w = width;
+    rect->h = height;
+    return true;
+}
+
+
+// This function gets the destination position for Seconday display
+// based on the position and aspect ratio of the primary
+bool OverlayControlChannel::getAspectRatioPosition(int w, int h, int orientation,
+                                 overlay_rect *inRect, overlay_rect *outRect) {
+    float priWidth  = FrameBufferInfo::getInstance()->getWidth();
+    float priHeight = FrameBufferInfo::getInstance()->getHeight();
+    float fbWidth = getFBWidth();
+    float fbHeight = getFBHeight();
+    float wRatio = 1.0;
+    float hRatio = 1.0;
+    float xRatio = 1.0;
+    float yRatio = 1.0;
+
+    int xPos = 0;
+    int yPos = 0;
+    int tmp = 0;
+    overlay_rect rect;
+    switch(orientation) {
+        case MDP_ROT_NOP:
+        case MDP_ROT_180:
+            getAspectRatioPosition((int)priWidth, (int)priHeight, &rect);
+            xPos = rect.x;
+            yPos = rect.y;
+            fbWidth = rect.w;
+            fbHeight = rect.h;
+
+            if(orientation == MDP_ROT_180) {
+                inRect->x = priWidth - (inRect->x + inRect->w);
+                inRect->y = priHeight - (inRect->y + inRect->h);
+            }
+            break;
+        case MDP_ROT_90:
+        case MDP_ROT_270:
+            if(orientation == MDP_ROT_90) {
+                tmp = inRect->y;
+                inRect->y = priWidth - (inRect->x + inRect->w);
+                inRect->x = tmp;
+            }
+            else if(orientation == MDP_ROT_270) {
+                tmp = inRect->x;
+                inRect->x = priHeight - (inRect->y + inRect->h);
+                inRect->y = tmp;
+            }
+            //Swap the destination width/height
+            swapWidthHeight(inRect->w, inRect->h);
+            // Swap width/height for primary
+            swapWidthHeight(priWidth, priHeight);
+            getAspectRatioPosition((int)priWidth, (int)priHeight, &rect);
+            xPos = rect.x;
+            yPos = rect.y;
+            fbWidth = rect.w;
+            fbHeight = rect.h;
+            break;
+        default:
+            LOGE("In  %s: Unknown Orientation", __FUNCTION__);
+            break;
+    }
+    //Calculate the position...
+    xRatio = inRect->x/priWidth;
+    yRatio = inRect->y/priHeight;
+
+    wRatio = inRect->w/priWidth;
+    hRatio = inRect->h/priHeight;
+    outRect->x = (xRatio * fbWidth) + xPos;
+    outRect->y = (yRatio * fbHeight) + yPos;
+
+    outRect->w = (wRatio * fbWidth);
+    outRect->h = hRatio * fbHeight;
+    LOGD("Calculated AS Position for HDMI:  X= %d, y = %d w = %d h = %d",
+                                  outRect->x, outRect->y,outRect->w, outRect->h);
+    return true;
+}
+
+
+bool OverlayControlChannel::getPositionS3D(int channel, int format, overlay_rect *rect) {
+    int wDisp = getFBWidth();
+    int hDisp = getFBHeight();
+    switch (format & OUTPUT_MASK_3D) {
+    case HAL_3D_OUT_SIDE_BY_SIDE_MASK:
+        if (channel == VG0_PIPE) {
+            rect->x = 0;
+            rect->y = 0;
+            rect->w = wDisp/2;
+            rect->h = hDisp;
+        } else {
+            rect->x = wDisp/2;
+            rect->y = 0;
+            rect->w = wDisp/2;
+            rect->h = hDisp;
+        }
+        break;
+    case HAL_3D_OUT_TOP_BOTTOM_MASK:
+        if (channel == VG0_PIPE) {
+            rect->x = 0;
+            rect->y = 0;
+            rect->w = wDisp;
+            rect->h = hDisp/2;
+        } else {
+            rect->x = 0;
+            rect->y = hDisp/2;
+            rect->w = wDisp;
+            rect->h = hDisp/2;
+        }
+        break;
+    case HAL_3D_OUT_MONOSCOPIC_MASK:
+        if (channel == VG1_PIPE) {
+            rect->x = 0;
+            rect->y = 0;
+            rect->w = wDisp;
+            rect->h = hDisp;
+        }
+        else
+            return false;
+        break;
+    case HAL_3D_OUT_INTERLEAVE_MASK:
+        break;
+    default:
+        reportError("Unsupported 3D output format");
+        break;
+    }
+    return true;
+}
+
+bool OverlayControlChannel::openDevices(int fbnum) {
+    if (fbnum < 0)
+        return false;
+
+    char dev_name[64];
+    snprintf(dev_name, 64, FB_DEVICE_TEMPLATE, fbnum);
+    mFD = open(dev_name, O_RDWR, 0);
+    if (mFD < 0) {
+        reportError("Cant open framebuffer ");
+        return false;
+    }
+
+    fb_fix_screeninfo finfo;
+    if (ioctl(mFD, FBIOGET_FSCREENINFO, &finfo) == -1) {
+        reportError("FBIOGET_FSCREENINFO on fb1 failed");
+        close(mFD);
+        mFD = -1;
+        return false;
+    }
+
+    fb_var_screeninfo vinfo;
+    if (ioctl(mFD, FBIOGET_VSCREENINFO, &vinfo) == -1) {
+        reportError("FBIOGET_VSCREENINFO on fb1 failed");
+        close(mFD);
+        mFD = -1;
+        return false;
+    }
+    mFBWidth = vinfo.xres;
+    mFBHeight = vinfo.yres;
+    mFBbpp = vinfo.bits_per_pixel;
+    mFBystride = finfo.line_length;
+
+    if (!mNoRot) {
+        mRotFD = open("/dev/msm_rotator", O_RDWR, 0);
+        if (mRotFD < 0) {
+            reportError("Cant open rotator device");
+            close(mFD);
+            mFD = -1;
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool OverlayControlChannel::setOverlayInformation(const overlay_buffer_info& info,
+                                  int zorder, int flags, int requestType) {
+    int w = info.width;
+    int h = info.height;
+    int format = info.format;
+
+    mOVInfo.src.width  = w;
+    mOVInfo.src.height = h;
+    mOVInfo.src_rect.x = 0;
+    mOVInfo.src_rect.y = 0;
+    mOVInfo.dst_rect.x = 0;
+    mOVInfo.dst_rect.y = 0;
+    mOVInfo.dst_rect.w = w;
+    mOVInfo.dst_rect.h = h;
+    if(format == MDP_Y_CRCB_H2V2_TILE) {
+        if (mNoRot) {
+           mOVInfo.src_rect.w = w - ((((w-1)/64 +1)*64) - w);
+           mOVInfo.src_rect.h = h - ((((h-1)/32 +1)*32) - h);
+        } else {
+           mOVInfo.src_rect.w = w;
+           mOVInfo.src_rect.h = h;
+           mOVInfo.src.width  = (((w-1)/64 +1)*64);
+           mOVInfo.src.height = (((h-1)/32 +1)*32);
+           mOVInfo.src_rect.x = mOVInfo.src.width - w;
+           mOVInfo.src_rect.y = mOVInfo.src.height - h;
+        }
+    } else {
+        mOVInfo.src_rect.w = w;
+        mOVInfo.src_rect.h = h;
+    }
+
+    mOVInfo.src.format = format;
+    int dst_w = w;
+    int dst_h = h;
+
+    if (dst_w > mFBWidth) {
+        dst_w = mFBWidth;
+        dst_h = dst_h * mFBWidth / w;
+    }
+    if (dst_h > mFBHeight) {
+        dst_h = mFBHeight;
+        dst_w = dst_w * mFBHeight / h;
+    }
+    mOVInfo.dst_rect.w = dst_w;
+    mOVInfo.dst_rect.h = dst_h;
+    mOVInfo.user_data[0] = 0;
+    if (requestType == NEW_REQUEST) {
+        mOVInfo.id = MSMFB_NEW_REQUEST;
+        mOVInfo.z_order = zorder;
+        mOVInfo.alpha = 0xff;
+        mOVInfo.transp_mask = 0xffffffff;
+    }
+    mOVInfo.flags = 0;
+    setInformationFromFlags(flags, mOVInfo);
+    mOVInfo.dpp.sharp_strength = 0;
+    return true;
+}
+
+void OverlayControlChannel::setInformationFromFlags(int flags, mdp_overlay& ov)
+{
+    if (flags & INTERLACED_CONTENT) {
+        mOVInfo.flags |= MDP_DEINTERLACE;
+    } else {
+        mOVInfo.flags &= ~MDP_DEINTERLACE;
+    }
+
+    if ((flags & WAIT_FOR_VSYNC) == 0)
+        mOVInfo.flags |= MDP_OV_PLAY_NOWAIT;
+    else
+        mOVInfo.flags &= ~MDP_OV_PLAY_NOWAIT;
+
+    if(flags & SECURE_OVERLAY_SESSION)
+         mOVInfo.flags |= MDP_SECURE_OVERLAY_SESSION;
+    else
+         mOVInfo.flags &= ~MDP_SECURE_OVERLAY_SESSION;
+
+    //set the default sharpening settings
+    mOVInfo.flags |= MDP_SHARPENING;
+
+    if (flags & DISABLE_FRAMEBUFFER_FETCH)
+        mOVInfo.is_fg = 1;
+    else
+        mOVInfo.is_fg = 0;
+
+    if (flags & OVERLAY_PIPE_SHARE) {
+        mOVInfo.flags |= MDP_OV_PIPE_SHARE;
+    } else {
+        mOVInfo.flags &= ~MDP_OV_PIPE_SHARE;
+    }
+    mOVInfo.dpp.sharp_strength = 0;
+	
+}
+
+bool OverlayControlChannel::doFlagsNeedUpdate(int flags) {
+    bool needUpdate = false;
+
+    if ((flags & WAIT_FOR_VSYNC) == 0) {
+        if (!(mOVInfo.flags & MDP_OV_PLAY_NOWAIT)) {
+            needUpdate = true;
+        }
+    }
+    if (flags & WAIT_FOR_VSYNC) {
+        if (mOVInfo.flags & MDP_OV_PLAY_NOWAIT) {
+            needUpdate = true;
+        }
+    }
+
+    if ((flags & DISABLE_FRAMEBUFFER_FETCH) == 0) {
+        if (mOVInfo.is_fg == 1) {
+           needUpdate = true;
+        }
+    }
+    if (flags & DISABLE_FRAMEBUFFER_FETCH) {
+        if (mOVInfo.is_fg == 0) {
+            needUpdate = true;
+        }
+    }
+    return needUpdate;
+}
+
+bool OverlayControlChannel::startOVRotatorSessions(
+                           const overlay_buffer_info& info,
+                           int requestType) {
+    bool ret = true;
+    int w = info.width;
+    int h = info.height;
+    int format = info.format;
+
+    if (!mNoRot) {
+        mRotInfo.src.format = format;
+        mRotInfo.src.width = w;
+        mRotInfo.src.height = h;
+        mRotInfo.src_rect.w = w;
+        mRotInfo.src_rect.h = h;
+        mRotInfo.dst.width = w;
+        mRotInfo.dst.height = h;
+        if(format == MDP_Y_CRCB_H2V2_TILE) {
+            mRotInfo.src.width =  (((w-1)/64 +1)*64);
+            mRotInfo.src.height = (((h-1)/32 +1)*32);
+            mRotInfo.src_rect.w = (((w-1)/64 +1)*64);
+            mRotInfo.src_rect.h = (((h-1)/32 +1)*32);
+            mRotInfo.dst.width = (((w-1)/64 +1)*64);
+            mRotInfo.dst.height = (((h-1)/32 +1)*32);
+            mRotInfo.dst.format = MDP_Y_CRCB_H2V2;
+        }
+        mRotInfo.dst.format = get_rot_output_format(format);
+        mRotInfo.dst_x = 0;
+        mRotInfo.dst_y = 0;
+        mRotInfo.src_rect.x = 0;
+        mRotInfo.src_rect.y = 0;
+        mRotInfo.rotations = 0;
+
+        if (requestType == NEW_REQUEST) {
+            mRotInfo.enable = 0;
+            if(mUIChannel)
+                mRotInfo.enable = 1;
+            mRotInfo.session_id = 0;
+        } else
+            mRotInfo.enable = 1;
+
+        int result = ioctl(mRotFD, MSM_ROTATOR_IOCTL_START, &mRotInfo);
+        if (result) {
+            reportError("Rotator session failed");
+            dump(mRotInfo);
+            ret = false;
+        }
+    }
+
+    if (ret && ioctl(mFD, MSMFB_OVERLAY_SET, &mOVInfo)) {
+        reportError("startOVRotatorSessions, Overlay set failed");
+        dump(mOVInfo);
+        ret = false;
+    }
+
+    if (!ret)
+        closeControlChannel();
+    else
+        mIsChannelUpdated = true;
+    return ret;
+}
+
+bool OverlayControlChannel::updateOverlaySource(const overlay_buffer_info& info,
+                                                int orientation, int flags)
+{
+    int colorFormat = getColorFormat(info.format);
+    int hw_format = get_mdp_format(colorFormat);
+    overlay_buffer_info ovBufInfo;
+    ovBufInfo.width = info.width;
+    ovBufInfo.height = info.height;
+    ovBufInfo.format = hw_format;
+
+    if (isInterlacedContent(info.format)) {
+        flags |= INTERLACED_CONTENT;
+    }
+    if (!setOverlayInformation(ovBufInfo, 0, flags,
+                               UPDATE_REQUEST))
+        return false;
+
+    return startOVRotatorSessions(ovBufInfo, UPDATE_REQUEST);
+}
+
+bool OverlayControlChannel::startControlChannel(const overlay_buffer_info& info,
+                                           int fbnum, bool norot,
+                                           bool uichannel,
+                                           unsigned int format3D, int zorder,
+                                           int flags) {
+    int colorFormat = getColorFormat(info.format);
+    mNoRot = norot;
+    mFormat = colorFormat;
+    mUIChannel = uichannel;
+    mFBNum = fbnum;
+    fb_fix_screeninfo finfo;
+    fb_var_screeninfo vinfo;
+    int hw_format;
+
+    // The interlace mask is part of the HAL_PIXEL_FORMAT_YV12 value. Add
+    // an explicit check for the format
+    if (isInterlacedContent(colorFormat)) {
+        flags |= MDP_DEINTERLACE;
+
+        // Get the actual format
+        colorFormat = colorFormat ^ HAL_PIXEL_FORMAT_INTERLACE;
+    }
+    hw_format = get_mdp_format(colorFormat);
+    if (hw_format < 0) {
+        reportError("Unsupported format");
+        return false;
+    }
+
+    mFormat3D = format3D;
+    if ( !mFormat3D || (mFormat3D & HAL_3D_OUT_MONOSCOPIC_MASK) ) {
+        // Set the share bit for sharing the VG pipe
+        flags |= OVERLAY_PIPE_SHARE;
+    }
+    //do not set the PIPE SHARE bit for true mirroring
+    if(uichannel && FrameBufferInfo::getInstance()->canSupportTrueMirroring())
+        flags &= ~OVERLAY_PIPE_SHARE;
+    if (!openDevices(fbnum))
+        return false;
+
+   //get Z order
+    zorder = ZOrderManager::getInstance()->getZ(fbnum);
+    if (zorder == NO_PIPE)
+        return false;
+
+    overlay_buffer_info ovBufInfo;
+    ovBufInfo.width = info.width;
+    ovBufInfo.height = info.height;
+    ovBufInfo.format = hw_format;
+    if (!setOverlayInformation(ovBufInfo, zorder, flags, NEW_REQUEST))
+        return false;
+
+    return startOVRotatorSessions(ovBufInfo, NEW_REQUEST);
+}
+
+bool OverlayControlChannel::closeControlChannel() {
+    if (!isChannelUP())
+        return true;
+
+    if (!mNoRot && mRotFD > 0) {
+        ioctl(mRotFD, MSM_ROTATOR_IOCTL_FINISH, &(mRotInfo.session_id));
+        close(mRotFD);
+        mRotFD = -1;
+    }
+
+    int ovid = mOVInfo.id;
+    ioctl(mFD, MSMFB_OVERLAY_UNSET, &ovid);
+    if (m3DOVInfo.is_3d) {
+        m3DOVInfo.is_3d = 0;
+        ioctl(mFD, MSMFB_OVERLAY_3D, &m3DOVInfo);
+    }
+
+    close(mFD);
+
+    if(NO_PIPE != mOVInfo.z_order){
+        ZOrderManager::getInstance()->decZ(mFBNum, mOVInfo.z_order);
+    }
+    memset(&mOVInfo, 0, sizeof(mOVInfo));
+    memset(&mRotInfo, 0, sizeof(mRotInfo));
+    memset(&m3DOVInfo, 0, sizeof(m3DOVInfo));
+
+    mOVInfo.z_order = NO_PIPE;
+    mFD = -1;
+
+    return true;
+}
+
+bool OverlayControlChannel::updateOverlayFlags(int flags) {
+    if ((flags & WAIT_FOR_VSYNC) == 0)
+        mOVInfo.flags |= MDP_OV_PLAY_NOWAIT;
+    else
+        mOVInfo.flags &= ~MDP_OV_PLAY_NOWAIT;
+
+    if (flags & DISABLE_FRAMEBUFFER_FETCH)
+        mOVInfo.is_fg = 1;
+    else
+        mOVInfo.is_fg = 0;
+
+    if (ioctl(mFD, MSMFB_OVERLAY_SET, &mOVInfo)) {
+        LOGE("%s: OVERLAY_SET failed", __FUNCTION__);
+        dump(mOVInfo);
+        return false;
+    }
+    return true;
+}
+
+bool OverlayControlChannel::setPosition(int x, int y, uint32_t w, uint32_t h) {
+
+    if (!isChannelUP() ||
+           (x < 0) || (y < 0) || ((x + w) > mFBWidth) ||
+           ((y + h) > mFBHeight)) {
+        reportError("setPosition failed");
+        LOGW("x %d y %d (x+w) %d (y+h) %d FBWidth %d FBHeight %d", x, y, x+w, y+h,
+                                                        mFBWidth,mFBHeight);
+        return false;
+    }
+    if( x != mOVInfo.dst_rect.x || y != mOVInfo.dst_rect.y ||
+        w != mOVInfo.dst_rect.w || h !=  mOVInfo.dst_rect.h ) {
+        mdp_overlay ov;
+        ov.id = mOVInfo.id;
+        if (ioctl(mFD, MSMFB_OVERLAY_GET, &ov)) {
+            reportError("setPosition, overlay GET failed");
+            return false;
+        }
+		
+// LGE_CHANGE_S, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents {
+    // can not scale-up 8 times over original source
+    // return false to compose with GPU
+#if 1
+        if(w > (ov.src_rect.w * HW_OVERLAY_MAGNIFICATION_LIMIT)){
+            LOGE("[TJ] setPosition : too big width, back to GPU comp %d => %d", ov.src_rect.w, w);
+            return false;
+        }
+        if(h > (ov.src_rect.h * HW_OVERLAY_MAGNIFICATION_LIMIT)) {
+            LOGE("[TJ] setPosition : too big height, back to GPU comp %d => %d", ov.src_rect.h, h);
+            return false;
+        }
+#else
+// LGE_CHANGE_E, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents }
+
+        /* Scaling of upto a max of 8 times supported */
+        if(w >(ov.src_rect.w * HW_OVERLAY_MAGNIFICATION_LIMIT)){
+            w = HW_OVERLAY_MAGNIFICATION_LIMIT * ov.src_rect.w;
+            x = (mFBWidth - w) / 2;
+        }
+        if(h >(ov.src_rect.h * HW_OVERLAY_MAGNIFICATION_LIMIT)) {
+            h = HW_OVERLAY_MAGNIFICATION_LIMIT * ov.src_rect.h;
+            y = (mFBHeight - h) / 2;
+        }
+// LGE_CHANGE_S, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents {
+#endif
+// LGE_CHANGE_E, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents }
+
+        ov.dst_rect.x = x;
+        ov.dst_rect.y = y;
+        ov.dst_rect.w = w;
+        ov.dst_rect.h = h;
+        if (ioctl(mFD, MSMFB_OVERLAY_SET, &ov)) {
+            reportError("setPosition, Overlay SET failed");
+            dump(ov);
+            return false;
+        }
+        mOVInfo = ov;
+// LGE_CHANGE_S, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents {
+        LOGE("setPosition");
+        dump(ov);
+// LGE_CHANGE_E, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents }
+    }
+    return true;
+}
+
+void OverlayControlChannel::swapOVRotWidthHeight() {
+    int tmp = mOVInfo.src.width;
+    mOVInfo.src.width = mOVInfo.src.height;
+    mOVInfo.src.height = tmp;
+
+    tmp = mOVInfo.src_rect.h;
+    mOVInfo.src_rect.h = mOVInfo.src_rect.w;
+    mOVInfo.src_rect.w = tmp;
+
+    tmp = mRotInfo.dst.width;
+    mRotInfo.dst.width = mRotInfo.dst.height;
+    mRotInfo.dst.height = tmp;
+}
+
+bool OverlayControlChannel::useVirtualFB() {
+    if(!m3DOVInfo.is_3d) {
+        m3DOVInfo.is_3d = 1;
+        mFBWidth *= 2;
+        mFBHeight /= 2;
+        m3DOVInfo.width = mFBWidth;
+        m3DOVInfo.height = mFBHeight;
+        return ioctl(mFD, MSMFB_OVERLAY_3D, &m3DOVInfo) ? false : true;
+    }
+    return true;
+}
+
+bool OverlayControlChannel::setTransform(int value, bool fetch) {
+    if (!isChannelUP()) {
+        LOGE("%s: channel is not up", __FUNCTION__);
+        return false;
+    }
+
+    mdp_overlay ov = mOVInfo;
+    if (fetch && ioctl(mFD, MSMFB_OVERLAY_GET, &ov)) {
+        reportError("setParameter, overlay GET failed");
+        return false;
+    }
+    mOVInfo = ov;
+    if (!mIsChannelUpdated) {
+        int orientation = get_mdp_orientation(value);
+        if (orientation == mOVInfo.user_data[0]) {
+            return true;
+        }
+    }
+    mIsChannelUpdated = false;
+
+    int val = mOVInfo.user_data[0];
+    if (mNoRot)
+        return true;
+
+    int rot = value;
+
+    switch(rot) {
+        case 0:
+        case HAL_TRANSFORM_FLIP_H:
+        case HAL_TRANSFORM_FLIP_V:
+        {
+            if (val == MDP_ROT_90) {
+                    int tmp = mOVInfo.src_rect.y;
+                    mOVInfo.src_rect.y = mOVInfo.src.width -
+                            (mOVInfo.src_rect.x + mOVInfo.src_rect.w);
+                    mOVInfo.src_rect.x = tmp;
+                    swapOVRotWidthHeight();
+            }
+            else if (val == MDP_ROT_270) {
+                    int tmp = mOVInfo.src_rect.x;
+                    mOVInfo.src_rect.x = mOVInfo.src.height - (
+                            mOVInfo.src_rect.y + mOVInfo.src_rect.h);
+                    mOVInfo.src_rect.y = tmp;
+                    swapOVRotWidthHeight();
+            }
+            break;
+        }
+        case HAL_TRANSFORM_ROT_90:
+        case (HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_H):
+        case (HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_V):
+        {
+            if (val == MDP_ROT_270) {
+                    mOVInfo.src_rect.x = mOVInfo.src.width - (
+                            mOVInfo.src_rect.x + mOVInfo.src_rect.w);
+                    mOVInfo.src_rect.y = mOVInfo.src.height - (
+                    mOVInfo.src_rect.y + mOVInfo.src_rect.h);
+            }
+            else if (val == MDP_ROT_NOP || val == MDP_ROT_180) {
+                    int tmp = mOVInfo.src_rect.x;
+                    mOVInfo.src_rect.x = mOVInfo.src.height -
+                               (mOVInfo.src_rect.y + mOVInfo.src_rect.h);
+                    mOVInfo.src_rect.y = tmp;
+                    swapOVRotWidthHeight();
+            }
+            break;
+        }
+        case HAL_TRANSFORM_ROT_180:
+        {
+            if (val == MDP_ROT_270) {
+                    int tmp = mOVInfo.src_rect.y;
+                    mOVInfo.src_rect.y = mOVInfo.src.width -
+                               (mOVInfo.src_rect.x + mOVInfo.src_rect.w);
+                    mOVInfo.src_rect.x = tmp;
+                    swapOVRotWidthHeight();
+            }
+            else if (val == MDP_ROT_90) {
+                    int tmp = mOVInfo.src_rect.x;
+                    mOVInfo.src_rect.x = mOVInfo.src.height - (
+                             mOVInfo.src_rect.y + mOVInfo.src_rect.h);
+                    mOVInfo.src_rect.y = tmp;
+                    swapOVRotWidthHeight();
+            }
+            break;
+        }
+        case HAL_TRANSFORM_ROT_270:
+        {
+            if (val == MDP_ROT_90) {
+                    mOVInfo.src_rect.y = mOVInfo.src.height -
+                               (mOVInfo.src_rect.y + mOVInfo.src_rect.h);
+                    mOVInfo.src_rect.x = mOVInfo.src.width -
+                               (mOVInfo.src_rect.x + mOVInfo.src_rect.w);
+            }
+            else if (val == MDP_ROT_NOP || val == MDP_ROT_180) {
+                    int tmp = mOVInfo.src_rect.y;
+                    mOVInfo.src_rect.y = mOVInfo.src.width - (
+                        mOVInfo.src_rect.x + mOVInfo.src_rect.w);
+                    mOVInfo.src_rect.x = tmp;
+                    swapOVRotWidthHeight();
+            }
+            break;
+        }
+        default: return false;
+    }
+
+    int mdp_rotation = get_mdp_orientation(rot);
+    if (mdp_rotation == -1)
+        return false;
+
+    mOVInfo.user_data[0] = mdp_rotation;
+    mRotInfo.rotations = mOVInfo.user_data[0];
+
+    /* Rotator always outputs non-tiled formats.
+    If rotator is used, set Overlay input to non-tiled
+    Else, overlay input remains tiled */
+    if (mOVInfo.user_data[0]) {
+        mOVInfo.src.format = get_rot_output_format(mRotInfo.src.format);
+        mRotInfo.enable = 1;
+    }
+    else {
+        //We can switch between rotator ON and OFF. Reset overlay
+        //i/p format whenever this happens
+        if(mRotInfo.dst.format == mOVInfo.src.format)
+            mOVInfo.src.format = mRotInfo.src.format;
+        mRotInfo.enable = 0;
+        //Always enable rotation for UI mirror usecase
+        if(mUIChannel)
+            mRotInfo.enable = 1;
+    }
+
+// LGE_CHANGE_S, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents {
+    // can not scale-up 8 times over original source
+    // return false to compose with GPU
+#if 1
+    if(mOVInfo.dst_rect.w > (mOVInfo.src_rect.w * HW_OVERLAY_MAGNIFICATION_LIMIT)){
+        LOGE("[TJ] setTransform : too big width, back to GPU comp %d => %d", mOVInfo.src_rect.w, mOVInfo.dst_rect.w);
+        return false;
+    }
+    if(mOVInfo.dst_rect.h > (mOVInfo.src_rect.h * HW_OVERLAY_MAGNIFICATION_LIMIT)) {
+        LOGE("[TJ] setTransform : too big height, back to GPU comp %d => %d", mOVInfo.src_rect.h, mOVInfo.dst_rect.h);
+        return false;
+    }
+#endif
+// LGE_CHANGE_E, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents }
+
+    //dump(mRotInfo); // TJ
+    if (ioctl(mRotFD, MSM_ROTATOR_IOCTL_START, &mRotInfo)) {
+        reportError("setTransform, rotator start failed");
+        dump(mRotInfo);
+        return false;
+    }
+
+    if ((mOVInfo.user_data[0] == MDP_ROT_90) ||
+        (mOVInfo.user_data[0] == MDP_ROT_270))
+        mOVInfo.flags |= MDP_SOURCE_ROTATED_90;
+    else
+        mOVInfo.flags &= ~MDP_SOURCE_ROTATED_90;
+
+// LGE_CHANGE_S, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents {
+    LOGE("setTransform"); // TJ
+	dump(mOVInfo); // TJ
+// LGE_CHANGE_E, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents }
+
+    if (ioctl(mFD, MSMFB_OVERLAY_SET, &mOVInfo)) {
+        reportError("setTransform, overlay set failed");
+        dump(mOVInfo);
+        return false;
+    }
+
+    return true;
+}
+
+bool OverlayControlChannel::getPosition(int& x, int& y,
+                                  uint32_t& w, uint32_t& h) {
+    if (!isChannelUP())
+        return false;
+    //mOVInfo has the current Overlay Position
+    x = mOVInfo.dst_rect.x;
+    y = mOVInfo.dst_rect.y;
+    w = mOVInfo.dst_rect.w;
+    h = mOVInfo.dst_rect.h;
+
+    return true;
+}
+
+bool OverlayControlChannel::getOrientation(int& orientation) const {
+    if (!isChannelUP())
+        return false;
+    // mOVInfo has the current orientation
+    orientation = mOVInfo.user_data[0];
+    return true;
+}
+bool OverlayControlChannel::getOvSessionID(int& sessionID) const {
+    if (!isChannelUP())
+        return false;
+    sessionID = mOVInfo.id;
+    return true;
+}
+
+bool OverlayControlChannel::getRotSessionID(int& sessionID) const {
+    if (!isChannelUP())
+        return false;
+    sessionID = mRotInfo.session_id;
+    return true;
+}
+
+bool OverlayControlChannel::getSize(int& size) const {
+    if (!isChannelUP())
+        return false;
+    size = mSize;
+    return true;
+}
+
+OverlayDataChannel::OverlayDataChannel() : mNoRot(false), mFD(-1), mRotFD(-1),
+                                  mPmemFD(-1), mPmemAddr(0), mUpdateDataChannel(false)
+{
+    //XXX: getInstance(false) implies that it should only
+    // use the kernel allocator. Change it to something
+    // more descriptive later.
+    mAlloc = gralloc::IAllocController::getInstance(false);
+}
+
+OverlayDataChannel::~OverlayDataChannel() {
+    closeDataChannel();
+}
+
+bool OverlayDataChannel::startDataChannel(
+               const OverlayControlChannel& objOvCtrlChannel,
+               int fbnum, bool norot, bool secure, bool uichannel,
+               int num_buffers) {
+    int ovid, rotid, size;
+    mNoRot = norot;
+    mSecure = secure;
+    memset(&mOvData, 0, sizeof(mOvData));
+    memset(&mOvDataRot, 0, sizeof(mOvDataRot));
+    memset(&mRotData, 0, sizeof(mRotData));
+    if (objOvCtrlChannel.getOvSessionID(ovid) &&
+            objOvCtrlChannel.getRotSessionID(rotid) &&
+            objOvCtrlChannel.getSize(size)) {
+        return startDataChannel(ovid, rotid, size, fbnum,
+                      norot, uichannel, num_buffers);
+    }
+    else
+        return false;
+}
+
+bool OverlayDataChannel::openDevices(int fbnum, bool uichannel, int num_buffers) {
+    if (fbnum < 0)
+        return false;
+    char dev_name[64];
+    snprintf(dev_name, 64, FB_DEVICE_TEMPLATE, fbnum);
+
+    mFD = open(dev_name, O_RDWR, 0);
+    if (mFD < 0) {
+        reportError("Cant open framebuffer ");
+        return false;
+    }
+    if (!mNoRot) {
+        mRotFD = open("/dev/msm_rotator", O_RDWR, 0);
+        if (mRotFD < 0) {
+            reportError("Cant open rotator device");
+            close(mFD);
+            mFD = -1;
+            return false;
+        }
+
+        return mapRotatorMemory(num_buffers, uichannel, NEW_REQUEST);
+    }
+    return true;
+}
+
+bool OverlayDataChannel::mapRotatorMemory(int num_buffers, bool uiChannel, int requestType)
+{
+    mPmemAddr = MAP_FAILED;
+
+    alloc_data data;
+    data.base = 0;
+    data.fd = -1;
+    data.offset = 0;
+    data.size = mPmemOffset * num_buffers;
+    data.align = getpagesize();
+    data.uncached = true;
+
+    int allocFlags = GRALLOC_USAGE_PRIVATE_MM_HEAP       |
+                     GRALLOC_USAGE_PRIVATE_WRITEBACK_HEAP|
+                     GRALLOC_USAGE_PRIVATE_DO_NOT_MAP;
+
+    if(mSecure) {
+        allocFlags |= GRALLOC_USAGE_PROTECTED;
+    } else {
+        allocFlags |= GRALLOC_USAGE_PRIVATE_ADSP_HEAP        |
+                      GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
+        if((requestType == NEW_REQUEST) && !uiChannel)
+            allocFlags |= GRALLOC_USAGE_PRIVATE_SMI_HEAP;
+    }
+
+    int err = mAlloc->allocate(data, allocFlags, 0);
+    if(err) {
+        reportError("Cant allocate rotatory memory");
+        close(mFD);
+        mFD = -1;
+        close(mRotFD);
+        mRotFD = -1;
+        return false;
+    }
+    mPmemFD = data.fd;
+    mPmemAddr = data.base;
+    mBufferType = data.allocType;
+
+    // Set this flag if source memory is fb
+    if(uiChannel)
+        mRotData.src.flags |= MDP_MEMORY_ID_TYPE_FB;
+
+    mOvDataRot.data.memory_id = mPmemFD;
+    mRotData.dst.memory_id = mPmemFD;
+    mRotData.dst.offset = 0;
+    mNumBuffers = num_buffers;
+    mCurrentItem = 0;
+    for (int i = 0; i < num_buffers; i++)
+        mRotOffset[i] = i * mPmemOffset;
+
+    return true;
+}
+
+bool OverlayDataChannel::updateDataChannel(int size) {
+    mUpdateDataChannel = true;
+    mNewPmemOffset = size;
+    return true;
+}
+
+bool OverlayDataChannel::startDataChannel(int ovid, int rotid, int size,
+                                   int fbnum, bool norot,
+                                   bool uichannel, int num_buffers) {
+    memset(&mOvData, 0, sizeof(mOvData));
+    memset(&mOvDataRot, 0, sizeof(mOvDataRot));
+    memset(&mRotData, 0, sizeof(mRotData));
+    mNoRot = norot;
+    mOvData.data.memory_id = -1;
+    mOvData.id = ovid;
+    mOvDataRot = mOvData;
+    mPmemOffset = size;
+    mRotData.session_id = rotid;
+    mNumBuffers = 0;
+    mCurrentItem = 0;
+
+    return openDevices(fbnum, uichannel, num_buffers);
+}
+
+bool OverlayDataChannel::closeDataChannel() {
+    if (!isChannelUP())
+        return true;
+
+    if (!mNoRot && mRotFD > 0) {
+        sp<IMemAlloc> memalloc = mAlloc->getAllocator(mBufferType);
+        memalloc->free_buffer(mPmemAddr, mPmemOffset * mNumBuffers, 0, mPmemFD);
+        close(mPmemFD);
+        mPmemFD = -1;
+        close(mRotFD);
+        mRotFD = -1;
+    }
+    close(mFD);
+    mFD = -1;
+    memset(&mOvData, 0, sizeof(mOvData));
+    memset(&mOvDataRot, 0, sizeof(mOvDataRot));
+    memset(&mRotData, 0, sizeof(mRotData));
+
+    mNumBuffers = 0;
+    mCurrentItem = 0;
+
+    return true;
+}
+
+bool OverlayDataChannel::setFd(int fd) {
+    mOvData.data.memory_id = fd;
+    return true;
+}
+
+bool OverlayDataChannel::queueBuffer(uint32_t offset) {
+    if ((!isChannelUP()) || mOvData.data.memory_id < 0) {
+        reportError("QueueBuffer failed, either channel is not set or no file descriptor to read from");
+        return false;
+    }
+
+    int oldPmemFD = -1;
+    void* oldPmemAddr = MAP_FAILED;
+    uint32_t oldPmemOffset = -1;
+    bool result;
+    if (!mNoRot) {
+        if (mUpdateDataChannel) {
+            oldPmemFD = mPmemFD;
+            oldPmemAddr = mPmemAddr;
+            oldPmemOffset = mPmemOffset;
+            mPmemOffset = mNewPmemOffset;
+            mNewPmemOffset = -1;
+            // Map the new PMEM memory
+            result = mapRotatorMemory(mNumBuffers, 0, UPDATE_REQUEST);
+            if (!result) {
+                LOGE("queueBuffer: mapRotatorMemory failed");
+                return false;
+            }
+            mUpdateDataChannel = false;
+       }
+    }
+
+    result = queue(offset);
+
+    // Unmap the old PMEM memory after the queueBuffer has returned
+    if (oldPmemFD != -1 && oldPmemAddr != MAP_FAILED) {
+        sp<IMemAlloc> memalloc = mAlloc->getAllocator(mBufferType);
+        memalloc->free_buffer(oldPmemAddr, oldPmemOffset * mNumBuffers, 0, oldPmemFD);
+        oldPmemFD = -1;
+    }
+    return result;
+}
+
+bool OverlayDataChannel::queue(uint32_t offset) {
+    msmfb_overlay_data *odPtr;
+    mOvData.data.offset = offset;
+    odPtr = &mOvData;
+    if (!mNoRot) {
+        mRotData.src.memory_id = mOvData.data.memory_id;
+        mRotData.src.offset = offset;
+        mRotData.dst.offset = (mRotData.dst.offset) ? 0 : mPmemOffset;
+        mRotData.dst.offset = mRotOffset[mCurrentItem];
+        mCurrentItem = (mCurrentItem + 1) % mNumBuffers;
+
+        int result = ioctl(mRotFD,
+                       MSM_ROTATOR_IOCTL_ROTATE, &mRotData);
+
+        if (!result) {
+            mOvDataRot.data.offset = (uint32_t) mRotData.dst.offset;
+            odPtr = &mOvDataRot;
+        }
+    }
+
+    if (ioctl(mFD, MSMFB_OVERLAY_PLAY, odPtr)) {
+        reportError("overlay play failed.");
+        return false;
+    }
+
+    return true;
+}
+
+bool OverlayDataChannel::waitForHdmiVsync() {
+    if (!isChannelUP()) {
+        LOGE("%s: channel not up", __FUNCTION__);
+        return false;
+    }
+    if (ioctl(mFD, MSMFB_OVERLAY_PLAY_WAIT, &mOvData)) {
+        LOGE("%s: MSMFB_OVERLAY_PLAY_WAIT failed", __FUNCTION__);
+        return false;
+    }
+    return true;
+}
+
+bool OverlayDataChannel::getCropS3D(overlay_rect *inRect, int channel, int format,
+                                    overlay_rect *rect) {
+    // for the 3D usecase extract channels from a frame
+    switch (format & INPUT_MASK_3D) {
+    case HAL_3D_IN_SIDE_BY_SIDE_L_R:
+        if(channel == 0) {
+            rect->x = 0;
+            rect->y = 0;
+            rect->w = inRect->w/2;
+            rect->h = inRect->h;
+        } else {
+            rect->x = inRect->w/2;
+            rect->y = 0;
+            rect->w = inRect->w/2;
+            rect->h = inRect->h;
+        }
+        break;
+    case HAL_3D_IN_SIDE_BY_SIDE_R_L:
+         if(channel == 1) {
+            rect->x = 0;
+            rect->y = 0;
+            rect->w = inRect->w/2;
+            rect->h = inRect->h;
+        } else {
+            rect->x = inRect->w/2;
+            rect->y = 0;
+            rect->w = inRect->w/2;
+            rect->h = inRect->h;
+        }
+         break;
+    case HAL_3D_IN_TOP_BOTTOM:
+        if(channel == 0) {
+            rect->x = 0;
+            rect->y = 0;
+            rect->w = inRect->w;
+            rect->h = inRect->h/2;
+        } else {
+            rect->x = 0;
+            rect->y = inRect->h/2;
+            rect->w = inRect->w;
+            rect->h = inRect->h/2;
+        }
+        break;
+    case HAL_3D_IN_INTERLEAVE:
+      break;
+    default:
+        reportError("Unsupported 3D format...");
+        break;
+   }
+   return true;
+}
+
+bool OverlayDataChannel::setCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h) {
+    if (!isChannelUP()) {
+        reportError("Channel not set");
+        return false;
+    }
+
+    mdp_overlay ov;
+    ov.id = mOvData.id;
+    if (ioctl(mFD, MSMFB_OVERLAY_GET, &ov)) {
+        reportError("setCrop, overlay GET failed");
+        return false;
+    }
+
+    if ((ov.user_data[0] == MDP_ROT_90) ||
+        (ov.user_data[0] == (MDP_ROT_90 | MDP_FLIP_UD)) ||
+        (ov.user_data[0] == (MDP_ROT_90 | MDP_FLIP_LR))){
+        if (ov.src.width < (y + h))
+            return false;
+
+        uint32_t tmp = x;
+        x = ov.src.width - (y + h);
+        y = tmp;
+
+        tmp = w;
+        w = h;
+        h = tmp;
+    }
+    else if (ov.user_data[0] == MDP_ROT_270) {
+        if (ov.src.height < (x + w))
+            return false;
+
+        uint32_t tmp = y;
+        y = ov.src.height - (x + w);
+        x = tmp;
+
+        tmp = w;
+        w = h;
+        h = tmp;
+    }
+    else if(ov.user_data[0] == MDP_ROT_180) {
+        if ((ov.src.height < (y + h)) || (ov.src.width < ( x + w)))
+            return false;
+
+        x = ov.src.width - (x + w);
+        y = ov.src.height - (y + h);
+    }
+
+
+    normalize_crop(x, w);
+    normalize_crop(y, h);
+
+    if ((ov.src_rect.x == x) &&
+           (ov.src_rect.y == y) &&
+           (ov.src_rect.w == w) &&
+           (ov.src_rect.h == h))
+        return true;
+
+    ov.src_rect.x = x;
+    ov.src_rect.y = y;
+    ov.src_rect.w = w;
+    ov.src_rect.h = h;
+
+// LGE_CHANGE_S, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents {
+    // can not scale-up 8 times over original source
+    // return false to compose with GPU
+#if 1
+    if(ov.dst_rect.w > (ov.src_rect.w * HW_OVERLAY_MAGNIFICATION_LIMIT)){
+        LOGE("[TJ] setCrop : too big width, back to GPU comp %d => %d", ov.src_rect.w, ov.dst_rect.w);
+        return false;
+    }
+    if(ov.dst_rect.h > (ov.src_rect.h * HW_OVERLAY_MAGNIFICATION_LIMIT)) {
+        LOGE("[TJ] setCrop : too big height, back to GPU comp %d => %d", ov.src_rect.h, ov.dst_rect.h);
+        return false;
+    }
+#else
+// LGE_CHANGE_E, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents }
+
+    /* Scaling of upto a max of 8 times supported */
+    if(ov.dst_rect.w >(ov.src_rect.w * HW_OVERLAY_MAGNIFICATION_LIMIT)){
+        ov.dst_rect.w = HW_OVERLAY_MAGNIFICATION_LIMIT * ov.src_rect.w;
+    }
+    if(ov.dst_rect.h >(ov.src_rect.h * HW_OVERLAY_MAGNIFICATION_LIMIT)) {
+        ov.dst_rect.h = HW_OVERLAY_MAGNIFICATION_LIMIT * ov.src_rect.h;
+    }
+// LGE_CHANGE_S, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents {
+#endif
+
+    LOGE("setCrop");
+    dump(ov);
+// LGE_CHANGE_E, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents }
+	
+    if (ioctl(mFD, MSMFB_OVERLAY_SET, &ov)) {
+        reportError("setCrop, overlay set error");
+        dump(ov);
+        return false;
+    }
+
+    return true;
+}
+
+/* setVisualParam can be called to set the configuration value of a post
+ * processing feature (HUE,SATURATION,BRIGHTNESS,CONTRAST,SMOOTHING/SHARPENING)
+ * for the first 4, the setting will stay set until the parameter is changed
+ * by another call to setVisualParam with that same paramType */
+void Overlay::setVisualParam(int8_t paramType, float paramValue) {
+    switch (mState) {
+    case OV_UI_MIRROR_TV:
+    case OV_2D_VIDEO_ON_PANEL:
+    case OV_3D_VIDEO_2D_PANEL:
+        // set the parameter value for the given parameter type.
+        if(!objOvCtrlChannel[VG0_PIPE].setVisualParam(paramType, paramValue)) {
+            LOGE("Failed to set param %d for value %f", paramType, paramValue);
+        }
+        break;
+    case OV_2D_VIDEO_ON_TV:
+    case OV_3D_VIDEO_3D_PANEL:
+    case OV_3D_VIDEO_2D_TV:
+    case OV_3D_VIDEO_3D_TV:
+        for (int i=0; i<NUM_CHANNELS; i++) {
+            //setting the value for the given parameter on each pipe (i.e. for
+            //both video pipes)
+            if(!objOvCtrlChannel[i].setVisualParam(paramType, paramValue)) {
+                LOGE("Failed to set param %d for value %f", paramType, paramValue);
+            }
+        }
+        break;
+     default:
+        break;
+     }
+}
+
+/* Finalizes the parameter value in the hsic_cfg structure*/
+int OverlayControlChannel::commitVisualParam(int8_t paramType, float paramValue) {
+#ifdef USES_POST_PROCESSING
+    switch(paramType) {
+    case SET_HUE:
+        //API expects param within range -180 - 180
+        CAP_RANGE(paramValue, HUE_RANGE, -HUE_RANGE);
+        hsic_cfg.hue = (int32_t) paramValue;
+        break;
+    case SET_BRIGHTNESS:
+        //API expects param within range -255 - 255
+        CAP_RANGE(paramValue, BRIGHTNESS_RANGE, -BRIGHTNESS_RANGE);
+        hsic_cfg.intensity = (int32_t) paramValue;
+        break;
+    case SET_SATURATION:
+        //API expects param within range -1 - 1
+        CAP_RANGE(paramValue, CON_SAT_RANGE, -CON_SAT_RANGE);
+        hsic_cfg.sat = paramValue;
+        break;
+    case SET_CONTRAST:
+        //API expects param within range -1 - 1
+        CAP_RANGE(paramValue, CON_SAT_RANGE, -CON_SAT_RANGE);
+        hsic_cfg.contrast = paramValue;
+        break;
+    default:
+        return -1;
+    }
+    return 0;
+#endif
+    return -1;
+}
+
+/* Converts paramValue to the expected range for each paramType, */
+bool OverlayControlChannel::setVisualParam(int8_t paramType, float paramValue)
+{
+    if (!isChannelUP()) {
+        LOGE("%s: Channel not set", __FUNCTION__);
+        return false;
+    }
+
+    bool setFlag = false;
+
+    //Sharpness values range from -128 to 127
+    //Integer values must be converted accordingly
+
+    int8_t value;
+    if (paramType == SET_SHARPNESS) {
+        //binding paramValue to the limits of its range.
+        CAP_RANGE(paramValue, SHARPNESS_RANGE, -SHARPNESS_RANGE);
+        value = paramValue * NUM_SHARPNESS_VALS - (NUM_SHARPNESS_VALS / 2);
+    }
+
+    uint32_t block = MDP_BLOCK_MAX;
+
+    //tranlate mOVInfo.id into block type for pp_conv
+    switch(mOVInfo.id) {
+        case 3:
+            // 3 is the pipe_ndx given when OVERLAY_PIPE_VG1 is used
+            block = MDP_BLOCK_VG_1;
+            break;
+        case 4:
+            // 4 is the pipe_ndx given when OVERLAY_PIPE_VG2 is used
+            block = MDP_BLOCK_VG_2;
+            break;
+        default:
+            LOGE("%s: Invalid HSIC overlay id",__FUNCTION__);
+    }
+
+    //save the paramValue to hsic_cfg
+    commitVisualParam(paramType, paramValue);
+#ifdef USES_POST_PROCESSING
+    //calling our user space library to configure the post processing color
+    //conversion (does Hue, Saturation, Brightness, and Contrast adjustment)
+    display_pp_conv_set_cfg(block, &hsic_cfg);
+#endif
+    mdp_overlay overlay;
+
+    switch(paramType) {
+    case SET_NONE:
+        return true;
+    case SET_SHARPNESS:
+        if (ioctl(mFD, MSMFB_OVERLAY_GET, &overlay)) {
+            reportError("setVisualParam, overlay GET failed");
+            return false;
+        }
+        if (overlay.dpp.sharp_strength != value) {
+            mOVInfo.flags |= MDP_SHARPENING;
+            mOVInfo.dpp.sharp_strength = value;
+            setFlag = true;
+        }
+        break;
+    case RESET_ALL:
+        //set all visual params to a default value
+        //passed in from the app
+        mOVInfo.flags |= MDP_SHARPENING;
+        mOVInfo.dpp.sharp_strength = value;
+        setFlag = true;
+        break;
+    default:
+        return false;
+    }
+    if (setFlag) {
+        if (ioctl(mFD, MSMFB_OVERLAY_SET, &mOVInfo)) {
+            reportError("setVisualParam, overlay set failed");
+            dump(mOVInfo);
+            return false;
+        }
+    }
+    return true;
+}
diff --git a/liboverlay/overlayLib.h b/liboverlay/overlayLib.h
new file mode 100755
index 0000000..65b134c
--- /dev/null
+++ b/liboverlay/overlayLib.h
@@ -0,0 +1,451 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.
+ */
+
+#ifndef INCLUDE_OVERLAY_LIB
+#define INCLUDE_OVERLAY_LIB
+
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include <cutils/atomic.h>
+
+#include <hardware/hardware.h>
+#include <hardware/gralloc.h>
+
+#include <dlfcn.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+#include <linux/fb.h>
+#include <linux/msm_mdp.h>
+#include <linux/msm_rotator.h>
+#include <linux/android_pmem.h>
+
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <utils/threads.h>
+#include <utils/RefBase.h>
+#include <alloc_controller.h>
+#include <memalloc.h>
+
+#ifdef USES_POST_PROCESSING
+#include "lib-postproc.h"
+#endif
+
+#define HW_OVERLAY_MAGNIFICATION_LIMIT 8
+#define HW_OVERLAY_MINIFICATION_LIMIT HW_OVERLAY_MAGNIFICATION_LIMIT
+
+#define EVEN_OUT(x) if (x & 0x0001) {x--;}
+#define NO_PIPE -1
+#define VG0_PIPE 0
+#define VG1_PIPE 1
+#define NUM_CHANNELS 2
+#define NUM_FB_DEVICES 3
+#define FRAMEBUFFER_0 0
+#define FRAMEBUFFER_1 1
+#define FRAMEBUFFER_2 2
+#define NUM_SHARPNESS_VALS 256
+#define SHARPNESS_RANGE 1.0f
+#define HUE_RANGE 180
+#define BRIGHTNESS_RANGE 255
+#define CON_SAT_RANGE 1.0f
+#define CAP_RANGE(value,max,min) do { if (value - min < -0.0001)\
+                                          {value = min;}\
+                                      else if(value - max > 0.0001)\
+                                          {value = max;}\
+                                    } while(0);
+
+enum {
+    HDMI_OFF,
+    HDMI_ON
+};
+
+enum {
+    OVERLAY_CHANNEL_DOWN,
+    OVERLAY_CHANNEL_UP
+};
+
+enum {
+    NEW_REQUEST,
+    UPDATE_REQUEST
+};
+
+enum {
+    WAIT_FOR_VSYNC             = 1<<0,
+    DISABLE_FRAMEBUFFER_FETCH  = 1<<1,
+    INTERLACED_CONTENT         = 1<<2,
+    OVERLAY_PIPE_SHARE         = 1<<3,
+    SECURE_OVERLAY_SESSION     = 1<<4,
+};
+
+/* ------------------------------- 3D defines ---------------------------------------*/
+// The compound format passed to the overlay is
+// ABCCC where A is the input 3D format,
+// B is the output 3D format
+// CCC is the color format e.g YCbCr420SP YCrCb420SP etc.
+#define FORMAT_3D(x) (x & 0xFF000)
+#define COLOR_FORMAT(x) (x & 0xFFF)
+// in the final 3D format, the MSB 2Bytes are the input format and the
+// LSB 2bytes are the output format. Shift the output byte 12 bits.
+#define SHIFT_OUTPUT_3D 12
+#define FORMAT_3D_OUTPUT(x) ((x & 0xF000) >> SHIFT_OUTPUT_3D)
+#define FORMAT_3D_INPUT(x)  (x & 0xF0000)
+#define INPUT_MASK_3D  0xFFFF0000
+#define OUTPUT_MASK_3D 0x0000FFFF
+#define SHIFT_3D       16
+// The output format is the 2MSB bytes. Shift the format by 12 to reflect this
+#define HAL_3D_OUT_SIDE_BY_SIDE_MASK (HAL_3D_OUT_SIDE_BY_SIDE >> SHIFT_OUTPUT_3D)
+#define HAL_3D_OUT_TOP_BOTTOM_MASK   (HAL_3D_OUT_TOP_BOTTOM   >> SHIFT_OUTPUT_3D)
+#define HAL_3D_OUT_INTERLEAVE_MASK   (HAL_3D_OUT_INTERLEAVE   >> SHIFT_OUTPUT_3D)
+#define HAL_3D_OUT_MONOSCOPIC_MASK   (HAL_3D_OUT_MONOSCOPIC   >> SHIFT_OUTPUT_3D)
+
+// 3D panel barrier orientation
+#define BARRIER_LANDSCAPE 1
+#define BARRIER_PORTRAIT  2
+
+#ifdef HDMI_AS_PRIMARY
+#define FORMAT_3D_FILE        "/sys/class/graphics/fb0/format_3d"
+#define EDID_3D_INFO_FILE     "/sys/class/graphics/fb0/3d_present"
+#else
+#define FORMAT_3D_FILE        "/sys/class/graphics/fb1/format_3d"
+#define EDID_3D_INFO_FILE     "/sys/class/graphics/fb1/3d_present"
+#endif
+#define BARRIER_FILE          "/sys/devices/platform/mipi_novatek.0/enable_3d_barrier"
+/* -------------------------- end 3D defines ----------------------------------------*/
+
+// Struct to hold the buffer info: geometry and size
+struct overlay_buffer_info {
+    int width;
+    int height;
+    int format;
+    int size;
+};
+
+using android::Mutex;
+namespace overlay {
+
+#define FB_DEVICE_TEMPLATE "/dev/graphics/fb%u"
+
+    //Utility Class to query the framebuffer info
+    class FrameBufferInfo {
+        int mFBWidth;
+        int mFBHeight;
+        bool mBorderFillSupported;
+        static FrameBufferInfo *sFBInfoInstance;
+
+        FrameBufferInfo():mFBWidth(0),mFBHeight(0), mBorderFillSupported(false) {
+            char const * const device_name =
+                       "/dev/graphics/fb0";
+            int fd = open(device_name, O_RDWR, 0);
+            mdp_overlay ov;
+            memset(&ov, 0, sizeof(ov));
+            if (fd < 0) {
+               LOGE("FrameBufferInfo: Cant open framebuffer ");
+               return;
+            }
+            fb_var_screeninfo vinfo;
+            if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) == -1) {
+                  LOGE("FrameBufferInfo: FBIOGET_VSCREENINFO on fb0 failed");
+                  close(fd);
+                  fd = -1;
+                  return;
+            }
+            ov.id = 1;
+            if(ioctl(fd, MSMFB_OVERLAY_GET, &ov)) {
+                  LOGE("FrameBufferInfo: MSMFB_OVERLAY_GET on fb0 failed");
+                  close(fd);
+                  fd = -1;
+                  return;
+            }
+            close(fd);
+            fd = -1;
+            mFBWidth = vinfo.xres;
+            mFBHeight = vinfo.yres;
+            mBorderFillSupported = (ov.flags & MDP_BORDERFILL_SUPPORTED) ?
+                                                              true : false;
+        }
+        public:
+        static FrameBufferInfo* getInstance(){
+            if (!sFBInfoInstance){
+                sFBInfoInstance = new FrameBufferInfo;
+            }
+            return sFBInfoInstance;
+        }
+        int getWidth() const { return mFBWidth; }
+        int getHeight() const { return mFBHeight; }
+        bool canSupportTrueMirroring() const {
+            return mBorderFillSupported; }
+    };
+
+enum {
+    OV_UI_MIRROR_TV = 0,
+    OV_2D_VIDEO_ON_PANEL,
+    OV_2D_VIDEO_ON_TV,
+    OV_3D_VIDEO_2D_PANEL,
+    OV_3D_VIDEO_2D_TV,
+    OV_3D_VIDEO_3D_PANEL,
+    OV_3D_VIDEO_3D_TV
+};
+bool isHDMIConnected();
+bool is3DTV();
+bool isPanel3D();
+bool usePanel3D();
+bool send3DInfoPacket(unsigned int format3D);
+bool enableBarrier(unsigned int orientation);
+unsigned int  getOverlayConfig (unsigned int format3D, bool poll = true,
+                                bool isHDMI = false);
+int getColorFormat(int format);
+bool isInterlacedContent(int format);
+int get_mdp_format(int format);
+int get_size(int format, int w, int h);
+int get_rot_output_format(int format);
+int get_mdp_orientation(int value);
+void normalize_crop(uint32_t& xy, uint32_t& wh);
+//Initializes the overlay - cleans up any existing overlay pipes
+int initOverlay();
+
+/* Print values being sent to driver in case of ioctl failures
+   These logs are enabled only if DEBUG_OVERLAY is true       */
+void dump(msm_rotator_img_info& mRotInfo);
+void dump(mdp_overlay& mOvInfo);
+const char* getFormatString(int format);
+
+    //singleton class to decide the z order of new overlay surfaces
+    class ZOrderManager {
+        bool mFB0Pipes[NUM_CHANNELS];
+        bool mFB1Pipes[NUM_CHANNELS+1]; //FB1 can have 3 pipes
+        int  mPipesInuse; // Holds the number of pipes in use
+        int  mMaxPipes;   // Max number of pipes
+        static ZOrderManager *sInstance;
+        Mutex *mObjMutex;
+        ZOrderManager(){
+            mPipesInuse = 0;
+            // for true mirroring support there can be 3 pipes on secondary
+            mMaxPipes = FrameBufferInfo::getInstance()->canSupportTrueMirroring()?
+                                                  NUM_CHANNELS+1 : NUM_CHANNELS;
+            for (int i = 0; i < NUM_CHANNELS; i++)
+                mFB0Pipes[i] = false;
+            for (int j = 0; j < mMaxPipes; j++)
+                mFB1Pipes[j] = false;
+            mObjMutex = new Mutex();
+        }
+        ~ZOrderManager() {
+            delete sInstance;
+            delete mObjMutex;
+        }
+        public:
+        static ZOrderManager* getInstance(){
+            if (!sInstance){
+                sInstance = new ZOrderManager;
+            }
+            return sInstance;
+        }
+        int getZ(int fbnum);
+        void decZ(int fbnum, int zorder);
+    };
+const int max_num_buffers = 3;
+typedef struct mdp_rect overlay_rect;
+
+class OverlayControlChannel {
+
+enum {
+    SET_NONE = 0,
+    SET_SHARPNESS,
+#ifdef USES_POST_PROCESSING
+    SET_HUE,
+    SET_BRIGHTNESS,
+    SET_SATURATION,
+    SET_CONTRAST,
+#endif
+    RESET_ALL,
+};
+    bool mNoRot;
+    int mFBNum;
+    int mFBWidth;
+    int mFBHeight;
+    int mFBbpp;
+    int mFBystride;
+    int mFormat;
+    int mFD;
+    int mRotFD;
+    int mSize;
+    int mOrientation;
+    unsigned int mFormat3D;
+    bool mUIChannel;
+#ifdef USES_POST_PROCESSING
+    struct display_pp_conv_cfg hsic_cfg;
+#endif
+    mdp_overlay mOVInfo;
+    msm_rotator_img_info mRotInfo;
+    msmfb_overlay_3d m3DOVInfo;
+    bool mIsChannelUpdated;
+    bool openDevices(int fbnum = -1);
+    bool setOverlayInformation(const overlay_buffer_info& info,
+                               int zorder = 0, int flags = 0,
+                               int requestType = NEW_REQUEST);
+    bool startOVRotatorSessions(const overlay_buffer_info& info, int requestType);
+    void swapOVRotWidthHeight();
+    int commitVisualParam(int8_t paramType, float paramValue);
+    void setInformationFromFlags(int flags, mdp_overlay& ov);
+
+public:
+    OverlayControlChannel();
+    ~OverlayControlChannel();
+    bool startControlChannel(const overlay_buffer_info& info,
+                               int fbnum, bool norot = false,
+                               bool uichannel = false,
+                               unsigned int format3D = 0, int zorder = 0,
+                               int flags = 0);
+    bool closeControlChannel();
+    bool setPosition(int x, int y, uint32_t w, uint32_t h);
+    bool setTransform(int value, bool fetch = true);
+    void setSize (int size) { mSize = size; }
+    bool getPosition(int& x, int& y, uint32_t& w, uint32_t& h);
+    bool getOvSessionID(int& sessionID) const;
+    bool getRotSessionID(int& sessionID) const;
+    bool getSize(int& size) const;
+    bool isChannelUP() const { return (mFD > 0); }
+    int getFBWidth() const { return mFBWidth; }
+    int getFBHeight() const { return mFBHeight; }
+    int getFormat3D() const { return mFormat3D; }
+    bool getOrientation(int& orientation) const;
+    bool updateOverlayFlags(int flags);
+    bool getAspectRatioPosition(int w, int h, overlay_rect *rect);
+    // Calculates the aspect ratio for video on HDMI based on primary
+    //  aspect ratio used in case of true mirroring
+    bool getAspectRatioPosition(int w, int h, int orientation,
+                                overlay_rect *inRect, overlay_rect *outRect);
+    bool getPositionS3D(int channel, int format, overlay_rect *rect);
+    bool updateOverlaySource(const overlay_buffer_info& info, int orientation, int flags);
+    bool getFormat() const { return mFormat; }
+    bool setVisualParam(int8_t paramType, float paramValue);
+    bool useVirtualFB ();
+    bool doFlagsNeedUpdate(int flags);
+};
+
+class OverlayDataChannel {
+
+    bool mNoRot;
+    bool mSecure;
+    int mFD;
+    int mRotFD;
+    int mPmemFD;
+    void* mPmemAddr;
+    uint32_t mPmemOffset;
+    uint32_t mNewPmemOffset;
+    msmfb_overlay_data mOvData;
+    msmfb_overlay_data mOvDataRot;
+    msm_rotator_data_info mRotData;
+    int mRotOffset[max_num_buffers];
+    int mCurrentItem;
+    int mNumBuffers;
+    bool mUpdateDataChannel;
+    android::sp<gralloc::IAllocController> mAlloc;
+    int mBufferType;
+
+    bool openDevices(int fbnum = -1, bool uichannel = false, int num_buffers = 2);
+    bool mapRotatorMemory(int num_buffers, bool uiChannel, int requestType);
+    bool queue(uint32_t offset);
+
+public:
+    OverlayDataChannel();
+    ~OverlayDataChannel();
+    bool startDataChannel(const OverlayControlChannel& objOvCtrlChannel,
+                                int fbnum, bool norot = false, bool secure = false,
+                                bool uichannel = false, int num_buffers = 2);
+    bool startDataChannel(int ovid, int rotid, int size,
+                       int fbnum, bool norot = false, bool uichannel = false,
+                       int num_buffers = 2);
+    bool closeDataChannel();
+    bool setFd(int fd);
+    bool queueBuffer(uint32_t offset);
+    bool waitForHdmiVsync();
+    bool setCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h);
+    bool getCropS3D(overlay_rect *inRect, int channel, int format, overlay_rect *rect);
+    bool isChannelUP() const { return (mFD > 0); }
+    bool updateDataChannel(int size);
+};
+
+/*
+ * Overlay class for single thread application
+ * A multiple thread/process application need to use Overlay HAL
+ */
+class Overlay {
+
+    bool mChannelUP;
+    //stores the connected external display Ex: HDMI(1) WFD(2)
+    int mExternalDisplay;
+    unsigned int mS3DFormat;
+    //Actual cropped source width and height of overlay
+    int mCroppedSrcWidth;
+    int mCroppedSrcHeight;
+    overlay_buffer_info mOVBufferInfo;
+    int mState;
+    // Stores the current device orientation
+    int mDevOrientation;
+    OverlayControlChannel objOvCtrlChannel[2];
+    OverlayDataChannel    objOvDataChannel[2];
+
+public:
+    Overlay();
+    ~Overlay();
+
+    static bool sHDMIAsPrimary;
+    bool startChannel(const overlay_buffer_info& info, int fbnum, bool norot = false,
+                          bool uichannel = false, unsigned int format3D = 0,
+                          int channel = 0, int flags = 0,
+                          int num_buffers = 2);
+    bool closeChannel();
+    bool setDeviceOrientation(int orientation);
+    bool setPosition(int x, int y, uint32_t w, uint32_t h);
+    bool setTransform(int value);
+    bool setOrientation(int value, int channel = 0);
+    bool setFd(int fd, int channel = 0);
+    bool queueBuffer(uint32_t offset, int channel = 0);
+    bool getPosition(int& x, int& y, uint32_t& w, uint32_t& h, int channel = 0);
+    bool isChannelUP() const { return mChannelUP; }
+    int getFBWidth(int channel = 0) const;
+    int getFBHeight(int channel = 0) const;
+    bool getOrientation(int& orientation, int channel = 0) const;
+    bool queueBuffer(buffer_handle_t buffer);
+    bool setSource(const overlay_buffer_info& info, int orientation, int hdmiConnected,
+                    int flags, int numBuffers = 2);
+    bool getAspectRatioPosition(int w, int h, overlay_rect *rect, int channel = 0);
+    bool setCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h);
+    bool updateOverlayFlags(int flags);
+    void setVisualParam(int8_t paramType, float paramValue);
+    bool waitForHdmiVsync(int channel);
+    int  getChannelStatus() const { return (mChannelUP ? OVERLAY_CHANNEL_UP: OVERLAY_CHANNEL_DOWN); }
+    void closeExternalChannel();
+private:
+    bool setChannelPosition(int x, int y, uint32_t w, uint32_t h, int channel = 0);
+    bool setChannelCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h, int channel);
+    bool queueBuffer(int fd, uint32_t offset, int channel);
+    bool updateOverlaySource(const overlay_buffer_info& info, int orientation, int flags);
+    int getS3DFormat(int format);
+};
+
+struct overlay_shared_data {
+    volatile bool isControlSetup;
+    unsigned int state;
+    int rotid[2];
+    int ovid[2];
+};
+};
+#endif
diff --git a/liboverlay/overlayLibUI.cpp b/liboverlay/overlayLibUI.cpp
new file mode 100755
index 0000000..d3fd80a
--- /dev/null
+++ b/liboverlay/overlayLibUI.cpp
@@ -0,0 +1,482 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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 "overlayLibUI.h"
+#include "gralloc_priv.h"
+#define LOG_TAG "OverlayUI"
+
+using android::sp;
+using gralloc::IMemAlloc;
+using gralloc::alloc_data;
+
+namespace {
+/* helper functions */
+void swapOVRotWidthHeight(msm_rotator_img_info& rotInfo,
+                                 mdp_overlay& ovInfo) {
+    int srcWidth = ovInfo.src.width;
+    ovInfo.src.width = ovInfo.src.height;
+    ovInfo.src.height = srcWidth;
+
+    int srcRectWidth = ovInfo.src_rect.w;
+    ovInfo.src_rect.w = ovInfo.src_rect.h;
+    ovInfo.src_rect.h = srcRectWidth;
+
+    int dstWidth = rotInfo.dst.width;
+    rotInfo.dst.width = rotInfo.dst.height;
+    rotInfo.dst.height = dstWidth;
+}
+
+bool isRGBType(int format) {
+    bool ret = false;
+    switch(format) {
+        case MDP_RGBA_8888:
+        case MDP_BGRA_8888:
+        case MDP_RGBX_8888:
+        case MDP_RGB_565:
+            ret = true;
+            break;
+        default:
+            ret = false;
+            break;
+    }
+    return ret;
+}
+
+int getRGBBpp(int format) {
+    int ret = -1;
+    switch(format) {
+        case MDP_RGBA_8888:
+        case MDP_BGRA_8888:
+        case MDP_RGBX_8888:
+            ret = 4;
+            break;
+        case MDP_RGB_565:
+            ret = 2;
+            break;
+        default:
+            ret = -1;
+            break;
+    }
+
+    return ret;
+}
+
+bool turnOFFVSync() {
+    static int swapIntervalPropVal = -1;
+    if (swapIntervalPropVal == -1) {
+        char pval[PROPERTY_VALUE_MAX];
+        property_get("debug.gr.swapinterval", pval, "1");
+        swapIntervalPropVal = atoi(pval);
+    }
+    return (swapIntervalPropVal == 0);
+}
+
+};
+
+namespace overlay {
+
+status_t Display::openDisplay(int fbnum) {
+    if (mFD != NO_INIT)
+        return NO_ERROR;
+
+    status_t ret = NO_INIT;
+    char dev_name[64];
+    snprintf(dev_name, 64, FB_DEVICE_TEMPLATE, fbnum);
+
+    mFD = open(dev_name, O_RDWR, 0);
+    if (mFD < 0) {
+        LOGE("Failed to open FB %d", fbnum);
+        return ret;
+    }
+
+    fb_var_screeninfo vinfo;
+    if (ioctl(mFD, FBIOGET_VSCREENINFO, &vinfo)) {
+        LOGE("FBIOGET_VSCREENINFO on failed on FB %d", fbnum);
+        close(mFD);
+        mFD = NO_INIT;
+        return ret;
+    }
+
+    mFBWidth = vinfo.xres;
+    mFBHeight = vinfo.yres;
+    mFBBpp = vinfo.bits_per_pixel;
+    ret = NO_ERROR;
+
+    return ret;
+}
+
+void Display::closeDisplay() {
+    close(mFD);
+    mFD = NO_INIT;
+}
+
+Rotator::Rotator() : mFD(NO_INIT), mSessionID(NO_INIT), mPmemFD(NO_INIT)
+{
+    mAlloc = gralloc::IAllocController::getInstance(false);
+}
+
+Rotator::~Rotator()
+{
+    closeRotSession();
+}
+
+status_t Rotator::startRotSession(msm_rotator_img_info& rotInfo,
+                                   int size, int numBuffers) {
+    status_t ret = NO_ERROR;
+    if (mSessionID == NO_INIT && mFD == NO_INIT) {
+        mNumBuffers = numBuffers;
+        mFD = open("/dev/msm_rotator", O_RDWR, 0);
+        if (mFD < 0) {
+            LOGE("Couldnt open rotator device");
+            return NO_INIT;
+        }
+
+        if (ioctl(mFD, MSM_ROTATOR_IOCTL_START, &rotInfo)) {
+            close(mFD);
+            mFD = NO_INIT;
+            return NO_INIT;
+        }
+
+        mSessionID = rotInfo.session_id;
+        alloc_data data;
+        data.base = 0;
+        data.fd = -1;
+        data.offset = 0;
+        data.size = mSize * mNumBuffers;
+        data.align = getpagesize();
+        data.uncached = true;
+
+        int allocFlags = GRALLOC_USAGE_PRIVATE_MM_HEAP          |
+                         GRALLOC_USAGE_PRIVATE_WRITEBACK_HEAP   |
+                         GRALLOC_USAGE_PRIVATE_ADSP_HEAP        |
+                         GRALLOC_USAGE_PRIVATE_IOMMU_HEAP       |
+                         GRALLOC_USAGE_PRIVATE_SMI_HEAP         |
+                         GRALLOC_USAGE_PRIVATE_DO_NOT_MAP;
+
+        int err = mAlloc->allocate(data, allocFlags, 0);
+
+        if(err) {
+            LOGE("%s: Can't allocate rotator memory", __func__);
+            closeRotSession();
+            return NO_INIT;
+        }
+        mPmemFD = data.fd;
+        mPmemAddr = data.base;
+        mBufferType = data.allocType;
+
+        mCurrentItem = 0;
+        for (int i = 0; i < mNumBuffers; i++)
+            mRotOffset[i] = i * mSize;
+        ret = NO_ERROR;
+    }
+    return ret;
+}
+
+status_t Rotator::closeRotSession() {
+    if (mSessionID != NO_INIT && mFD != NO_INIT) {
+        ioctl(mFD, MSM_ROTATOR_IOCTL_FINISH, &mSessionID);
+        close(mFD);
+        if (NO_INIT != mPmemFD) {
+            sp<IMemAlloc> memalloc = mAlloc->getAllocator(mBufferType);
+            memalloc->free_buffer(mPmemAddr, mSize * mNumBuffers, 0, mPmemFD);
+            close(mPmemFD);
+        }
+    }
+
+    mFD = NO_INIT;
+    mSessionID = NO_INIT;
+    mPmemFD = NO_INIT;
+    mPmemAddr = MAP_FAILED;
+
+    return NO_ERROR;
+}
+
+status_t Rotator::rotateBuffer(msm_rotator_data_info& rotData) {
+    status_t ret = NO_INIT;
+    if (mSessionID != NO_INIT) {
+        rotData.dst.memory_id = mPmemFD;
+        rotData.dst.offset = mRotOffset[mCurrentItem];
+        rotData.session_id = mSessionID;
+        mCurrentItem = (mCurrentItem + 1) % mNumBuffers;
+        if (ioctl(mFD, MSM_ROTATOR_IOCTL_ROTATE, &rotData)) {
+            LOGE("Rotator failed to rotate");
+            return BAD_VALUE;
+        }
+        return NO_ERROR;
+    }
+
+    return ret;
+}
+
+//===================== OverlayUI =================//
+
+OverlayUI::OverlayUI() : mChannelState(CLOSED), mOrientation(NO_INIT),
+        mFBNum(NO_INIT), mZorder(NO_INIT), mWaitForVsync(false), mIsFg(false),
+        mSessionID(NO_INIT), mParamsChanged(false) {
+        memset(&mOvInfo, 0, sizeof(mOvInfo));
+        memset(&mRotInfo, 0, sizeof(mRotInfo));
+}
+
+OverlayUI::~OverlayUI() {
+    closeChannel();
+}
+
+void OverlayUI::setSource(const overlay_buffer_info& info, int orientation) {
+    status_t ret = NO_INIT;
+    int format3D = FORMAT_3D(info.format);
+    int colorFormat = COLOR_FORMAT(info.format);
+    int format = get_mdp_format(colorFormat);
+
+    if (format3D || !isRGBType(format)) {
+        LOGE("%s: Unsupported format", __func__);
+        return;
+    }
+
+    mParamsChanged |= (mSource.width ^ info.width) ||
+                      (mSource.height ^ info.height) ||
+                      (mSource.format ^ format) ||
+                      (mSource.size ^ info.size) ||
+                      (mOrientation ^ orientation);
+
+    mSource.width = info.width;
+    mSource.height = info.height;
+    mSource.format = format;
+    mSource.size = info.size;
+    mOrientation = orientation;
+    setupOvRotInfo();
+}
+
+void OverlayUI::setDisplayParams(int fbNum, bool waitForVsync, bool isFg, int
+        zorder, bool isVGPipe) {
+    int flags = 0;
+
+    if(false == waitForVsync)
+        flags |= MDP_OV_PLAY_NOWAIT;
+    else
+        flags &= ~MDP_OV_PLAY_NOWAIT;
+
+    if(isVGPipe)
+        flags |= MDP_OV_PIPE_SHARE;
+    else
+        flags &= ~MDP_OV_PIPE_SHARE;
+
+    if (turnOFFVSync())
+        flags |= MDP_OV_PLAY_NOWAIT;
+
+    mParamsChanged |= (mFBNum ^ fbNum) ||
+                      (mOvInfo.is_fg ^ isFg) ||
+                      (mOvInfo.flags ^ flags) ||
+                      (mOvInfo.z_order ^ zorder);
+
+    mFBNum = fbNum;
+    mOvInfo.is_fg = isFg;
+    mOvInfo.flags = flags;
+    mOvInfo.z_order = zorder;
+
+    mobjDisplay.openDisplay(mFBNum);
+}
+
+void OverlayUI::setPosition(int x, int y, int w, int h) {
+    mParamsChanged |= (mOvInfo.dst_rect.x ^ x) ||
+                      (mOvInfo.dst_rect.y ^ y) ||
+                      (mOvInfo.dst_rect.w ^ w) ||
+                      (mOvInfo.dst_rect.h ^ h);
+
+    mOvInfo.dst_rect.x = x;
+    mOvInfo.dst_rect.y = y;
+    mOvInfo.dst_rect.w = w;
+    mOvInfo.dst_rect.h = h;
+}
+
+void OverlayUI::setCrop(int x, int y, int w, int h) {
+    mParamsChanged |= (mOvInfo.src_rect.x ^ x) ||
+                      (mOvInfo.src_rect.y ^ y) ||
+                      (mOvInfo.src_rect.w ^ w) ||
+                      (mOvInfo.src_rect.h ^ h);
+
+    mOvInfo.src_rect.x = x;
+    mOvInfo.src_rect.y = y;
+    mOvInfo.src_rect.w = w;
+    mOvInfo.src_rect.h = h;
+}
+
+void OverlayUI::setupOvRotInfo() {
+    int w = mSource.width;
+    int h = mSource.height;
+    int format = mSource.format;
+    int srcw = (w + 31) & ~31;
+    int srch = (h + 31) & ~31;
+    mOvInfo.src.width = srcw;
+    mOvInfo.src.height = srch;
+    mOvInfo.src.format = format;
+    mOvInfo.src_rect.w = w;
+    mOvInfo.src_rect.h = h;
+    mOvInfo.alpha = 0xff;
+    mOvInfo.transp_mask = 0xffffffff;
+    mRotInfo.src.format = format;
+    mRotInfo.dst.format = format;
+    mRotInfo.src.width = srcw;
+    mRotInfo.src.height = srch;
+    mRotInfo.src_rect.w = srcw;
+    mRotInfo.src_rect.h = srch;
+    mRotInfo.dst.width = srcw;
+    mRotInfo.dst.height = srch;
+
+    int rot = mOrientation;
+    switch(rot) {
+        case 0:
+        case HAL_TRANSFORM_FLIP_H:
+        case HAL_TRANSFORM_FLIP_V:
+            rot = 0;
+            break;
+        case HAL_TRANSFORM_ROT_90:
+        case (HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_H):
+        case (HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_V): {
+            int tmp = mOvInfo.src_rect.x;
+            mOvInfo.src_rect.x = mOvInfo.src.height -
+                (mOvInfo.src_rect.y + mOvInfo.src_rect.h);
+            mOvInfo.src_rect.y = tmp;
+            swapOVRotWidthHeight(mRotInfo, mOvInfo);
+            rot = HAL_TRANSFORM_ROT_90;
+            break;
+        }
+        case HAL_TRANSFORM_ROT_180:
+            break;
+        case HAL_TRANSFORM_ROT_270: {
+            int tmp = mOvInfo.src_rect.y;
+            mOvInfo.src_rect.y = mOvInfo.src.width -
+                (mOvInfo.src_rect.x + mOvInfo.src_rect.w);
+            mOvInfo.src_rect.x = tmp;
+            swapOVRotWidthHeight(mRotInfo, mOvInfo);
+            break;
+        }
+        default:
+            break;
+    }
+    int mdp_rotation = overlay::get_mdp_orientation(rot);
+    if (mdp_rotation < 0)
+        mdp_rotation = 0;
+    mOvInfo.user_data[0] = mdp_rotation;
+    mRotInfo.rotations = mOvInfo.user_data[0];
+    if (mdp_rotation)
+        mRotInfo.enable = 1;
+}
+
+status_t OverlayUI::commit() {
+    status_t ret = BAD_VALUE;
+    if(mChannelState != UP)
+        mOvInfo.id = MSMFB_NEW_REQUEST;
+    ret = startOVSession();
+    if (ret == NO_ERROR && mOrientation) {
+        ret = mobjRotator.startRotSession(mRotInfo, mSource.size);
+    }
+    if (ret == NO_ERROR) {
+        mChannelState = UP;
+    } else {
+        LOGE("start channel failed.");
+    }
+    return ret;
+}
+
+status_t OverlayUI::closeChannel() {
+    if( mChannelState != UP ) {
+        return NO_ERROR;
+    }
+    if(NO_ERROR != closeOVSession()) {
+        LOGE("%s: closeOVSession() failed.", __FUNCTION__);
+        return BAD_VALUE;
+    }
+    if(NO_ERROR != mobjRotator.closeRotSession()) {
+        LOGE("%s: closeRotSession() failed.", __FUNCTION__);
+        return BAD_VALUE;
+    }
+    mChannelState = CLOSED;
+    mParamsChanged = false;
+    memset(&mOvInfo, 0, sizeof(mOvInfo));
+    memset(&mRotInfo, 0, sizeof(mRotInfo));
+    return NO_ERROR;
+}
+
+status_t OverlayUI::startOVSession() {
+    status_t ret = NO_INIT;
+    ret = mobjDisplay.openDisplay(mFBNum);
+
+    if (ret != NO_ERROR)
+        return ret;
+
+    if(mParamsChanged) {
+        mParamsChanged = false;
+        mdp_overlay ovInfo = mOvInfo;
+        if (ioctl(mobjDisplay.getFD(), MSMFB_OVERLAY_SET, &ovInfo)) {
+            LOGE("Overlay set failed..");
+            ret = BAD_VALUE;
+        } else {
+            mSessionID = ovInfo.id;
+            mOvInfo = ovInfo;
+            ret = NO_ERROR;
+        }
+    }
+    return ret;
+}
+
+status_t OverlayUI::closeOVSession() {
+    status_t ret = NO_ERROR;
+    int err = 0;
+    if(err = ioctl(mobjDisplay.getFD(), MSMFB_OVERLAY_UNSET, &mSessionID)) {
+        LOGE("%s: MSMFB_OVERLAY_UNSET failed. (%d)", __FUNCTION__, err);
+        ret = BAD_VALUE;
+    } else {
+        mobjDisplay.closeDisplay();
+        mSessionID = NO_INIT;
+    }
+    return ret;
+}
+
+status_t OverlayUI::queueBuffer(buffer_handle_t buffer) {
+    status_t ret = NO_INIT;
+
+    if (mChannelState != UP)
+        return ret;
+
+    msmfb_overlay_data ovData;
+    memset(&ovData, 0, sizeof(ovData));
+
+    private_handle_t const* hnd = reinterpret_cast
+                                        <private_handle_t const*>(buffer);
+    ovData.data.memory_id = hnd->fd;
+    ovData.data.offset = hnd->offset;
+    if (mOrientation) {
+        msm_rotator_data_info rotData;
+        memset(&rotData, 0, sizeof(rotData));
+        rotData.src.memory_id = hnd->fd;
+        rotData.src.offset = hnd->offset;
+        if (mobjRotator.rotateBuffer(rotData) != NO_ERROR) {
+            LOGE("Rotator failed.. ");
+            return BAD_VALUE;
+        }
+        ovData.data.memory_id = rotData.dst.memory_id;
+        ovData.data.offset = rotData.dst.offset;
+    }
+    ovData.id = mSessionID;
+    if (ioctl(mobjDisplay.getFD(), MSMFB_OVERLAY_PLAY, &ovData)) {
+        LOGE("Queuebuffer failed ");
+        return BAD_VALUE;
+    }
+    return NO_ERROR;
+}
+
+};
diff --git a/liboverlay/overlayLibUI.h b/liboverlay/overlayLibUI.h
new file mode 100644
index 0000000..d16a968
--- /dev/null
+++ b/liboverlay/overlayLibUI.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.
+ */
+
+#ifndef INCLUDE_OVERLAY_LIB_UI
+#define INCLUDE_OVERLAY_LIB_UI
+
+#include <errno.h>
+
+#include "overlayLib.h"
+
+namespace overlay {
+
+enum channel_state_t { UP, CLOSED, PENDING_CLOSE };
+enum status_t {
+                  NO_ERROR,
+                  INVALID_OPERATION = -ENOSYS,
+                  BAD_VALUE = -EINVAL,
+                  NO_INIT = -ENODEV,
+                  ALREADY_EXISTS = -EEXIST
+              };
+
+/*
+ * Display class provides following services
+ * Open FB
+ * FB information (Width, Height and Bpp)
+ */
+
+class Display {
+    int mFD;
+    int mFBWidth;
+    int mFBHeight;
+    int mFBBpp;
+    Display(const Display& objDisplay);
+    Display& operator=(const Display& objDisplay);
+
+public:
+    explicit Display() : mFD(NO_INIT) { };
+    ~Display() { close(mFD); };
+    int getFD() const { return mFD; };
+    int getFBWidth() const { return mFBWidth; };
+    int getFBHeight() const { return mFBHeight; };
+    int getFBBpp() const { return mFBBpp; };
+    status_t openDisplay(int fbnum);
+    void closeDisplay();
+};
+
+/*
+ * Rotator class, manages rotation of the buffers
+ * It communicates with Rotator driver, provides following services
+ * Start rotator session
+ * Rotate buffer
+ */
+
+class Rotator {
+    int mFD;
+    int mSessionID;
+    int mPmemFD;
+    void* mPmemAddr;
+    int mRotOffset[max_num_buffers];
+    int mCurrentItem;
+    int mNumBuffers;
+    int mSize;
+    android::sp<gralloc::IAllocController> mAlloc;
+    int mBufferType;
+    Rotator(const Rotator& objROtator);
+    Rotator& operator=(const Rotator& objRotator);
+
+public:
+    explicit Rotator();
+    ~Rotator();
+    status_t startRotSession(msm_rotator_img_info& rotInfo, int size,
+                             int numBuffers = max_num_buffers);
+    status_t closeRotSession();
+    status_t rotateBuffer(msm_rotator_data_info& rotData);
+};
+
+/*
+ * Overlay class for Comp. Bypass
+ * We merge control and data channel classes.
+ */
+
+class OverlayUI {
+    channel_state_t mChannelState;
+    overlay_buffer_info mSource;
+    int mZorder;
+    int mOrientation;
+    int mFBNum;
+    bool mWaitForVsync;
+    bool mIsFg;
+    int mSessionID;
+    Display mobjDisplay;
+    Rotator mobjRotator;
+
+    mdp_overlay mOvInfo;
+    msm_rotator_img_info mRotInfo;
+
+    bool mParamsChanged;
+
+    OverlayUI(const OverlayUI& objOverlay);
+    OverlayUI& operator=(const OverlayUI& objOverlay);
+
+    status_t startOVSession();
+    status_t closeOVSession();
+    void setupOvRotInfo();
+
+public:
+
+    enum fbnum_t { FB0, FB1 };
+
+    OverlayUI();
+    ~OverlayUI();
+    void setSource(const overlay_buffer_info& info, int orientation);
+    void setPosition(int x, int y, int w, int h);
+    void setCrop(int x, int y, int w, int h);
+    void setDisplayParams(int fbNum, bool waitForVsync, bool isFg, int zorder,
+            bool isVGPipe);
+    status_t commit();
+    status_t closeChannel();
+    channel_state_t isChannelUP() const { return mChannelState; };
+    int getFBWidth() const { return mobjDisplay.getFBWidth(); };
+    int getFBHeight() const { return mobjDisplay.getFBHeight(); };
+    status_t queueBuffer(buffer_handle_t buffer);
+};
+
+};
+#endif
diff --git a/libqcomui/Android.mk b/libqcomui/Android.mk
new file mode 100644
index 0000000..5897161
--- /dev/null
+++ b/libqcomui/Android.mk
@@ -0,0 +1,31 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+        qcom_ui.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+        libutils \
+        libcutils \
+        libui \
+        libEGL \
+        libskia
+
+LOCAL_C_INCLUDES := $(TOP)/hardware/qcom/display/libgralloc \
+                    $(TOP)/frameworks/native/services/surfaceflinger \
+                    $(TOP)/external/skia/include/core \
+                    $(TOP)/external/skia/include/images
+
+LOCAL_CFLAGS := -DLOG_TAG=\"libQcomUI\"
+
+ifneq ($(call is-vendor-board-platform,QCOM),true)
+    LOCAL_CFLAGS += -DNON_QCOM_TARGET
+else
+    LOCAL_SHARED_LIBRARIES += libmemalloc
+endif
+
+LOCAL_CFLAGS += -DDEBUG_CALC_FPS
+
+LOCAL_MODULE := libQcomUI
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_SHARED_LIBRARY)
diff --git a/libqcomui/qcom_ui.cpp b/libqcomui/qcom_ui.cpp
new file mode 100644
index 0000000..80ce25d
--- /dev/null
+++ b/libqcomui/qcom_ui.cpp
@@ -0,0 +1,937 @@
+/*
+ * Copyright (c) 2011-2012, Code Aurora Forum. 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 Code Aurora Forum, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <cutils/log.h>
+#include <cutils/memory.h>
+#include <qcom_ui.h>
+#include <gralloc_priv.h>
+#include <alloc_controller.h>
+#include <memalloc.h>
+#include <errno.h>
+#include <EGL/eglext.h>
+#include <sys/stat.h>
+#include <SkBitmap.h>
+#include <SkImageEncoder.h>
+#include <Transform.h>
+
+#include <EGL/egl.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+using gralloc::IMemAlloc;
+using gralloc::IonController;
+using gralloc::alloc_data;
+using android::sp;
+
+static int sCompositionType = -1;
+
+namespace {
+
+    static android::sp<gralloc::IAllocController> sAlloc = 0;
+
+    int reallocate_memory(native_handle_t *buffer_handle, int mReqSize, int usage)
+    {
+        int ret = 0;
+
+#ifndef NON_QCOM_TARGET
+        if (sAlloc == 0) {
+            sAlloc = gralloc::IAllocController::getInstance(true);
+        }
+        if (sAlloc == 0) {
+            ALOGE("sAlloc is still NULL");
+            return -EINVAL;
+        }
+
+        // Dealloc the old memory
+        private_handle_t *hnd = (private_handle_t *)buffer_handle;
+        sp<IMemAlloc> memalloc = sAlloc->getAllocator(hnd->flags);
+        ret = memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);
+
+        if (ret) {
+            ALOGE("%s: free_buffer failed", __FUNCTION__);
+            return -1;
+        }
+
+        // Realloc new memory
+        alloc_data data;
+        data.base = 0;
+        data.fd = -1;
+        data.offset = 0;
+        data.size = mReqSize;
+        data.align = getpagesize();
+        data.uncached = true;
+        int allocFlags = usage;
+
+        switch (hnd->format) {
+            case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
+            case (HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED^HAL_PIXEL_FORMAT_INTERLACE): {
+                data.align = 8192;
+            } break;
+            default: break;
+        }
+        ret = sAlloc->allocate(data, allocFlags, 0);
+        if (ret == 0) {
+            hnd->fd = data.fd;
+            hnd->base = (int)data.base;
+            hnd->offset = data.offset;
+            hnd->size = data.size;
+        } else {
+            ALOGE("%s: allocate failed", __FUNCTION__);
+            return -EINVAL;
+        }
+#endif
+        return ret;
+    }
+}; // ANONYNMOUS NAMESPACE
+
+/*
+ * Gets the number of arguments required for this operation.
+ *
+ * @param: operation whose argument count is required.
+ *
+ * @return -EINVAL if the operation is invalid.
+ */
+int getNumberOfArgsForOperation(int operation) {
+    int num_args = -EINVAL;
+    switch(operation) {
+        case NATIVE_WINDOW_SET_BUFFERS_SIZE:
+            num_args = 1;
+            break;
+        case  NATIVE_WINDOW_UPDATE_BUFFERS_GEOMETRY:
+            num_args = 3;
+            break;
+        default: ALOGE("%s: invalid operation(0x%x)", __FUNCTION__, operation);
+            break;
+    };
+    return num_args;
+}
+
+/*
+ * Checks if the format is supported by the GPU.
+ *
+ * @param: format to check
+ *
+ * @return true if the format is supported by the GPU.
+ */
+bool isGPUSupportedFormat(int format) {
+    if (format == HAL_PIXEL_FORMAT_YV12) {
+        // We check the YV12 formats, since some Qcom specific formats
+        // could have the bits set.
+        return true;
+    } else if (format & INTERLACE_MASK) {
+        // Interlaced content
+        return false;
+    } else if (format & S3D_FORMAT_MASK) {
+        // S3D Formats are not supported by the GPU
+       return false;
+    }
+    return true;
+}
+
+/* decide the texture target dynamically, based on the pixel format*/
+
+int decideTextureTarget(int pixel_format)
+{
+
+  // Default the return value to GL_TEXTURE_EXTERAL_OES
+  int retVal = GL_TEXTURE_EXTERNAL_OES;
+
+  // Change texture target to TEXTURE_2D for RGB formats
+  switch (pixel_format) {
+
+     case HAL_PIXEL_FORMAT_RGBA_8888:
+     case HAL_PIXEL_FORMAT_RGBX_8888:
+     case HAL_PIXEL_FORMAT_RGB_888:
+     case HAL_PIXEL_FORMAT_RGB_565:
+     case HAL_PIXEL_FORMAT_BGRA_8888:
+     case HAL_PIXEL_FORMAT_RGBA_5551:
+     case HAL_PIXEL_FORMAT_RGBA_4444:
+          retVal = GL_TEXTURE_2D;
+          break;
+     default:
+          retVal = GL_TEXTURE_EXTERNAL_OES;
+          break;
+  }
+  return retVal;
+}
+
+/*
+ * Function to check if the allocated buffer is of the correct size.
+ * Reallocate the buffer with the correct size, if the size doesn't
+ * match
+ *
+ * @param: handle of the allocated buffer
+ * @param: requested size for the buffer
+ * @param: usage flags
+ *
+ * return 0 on success
+ */
+int checkBuffer(native_handle_t *buffer_handle, int size, int usage)
+{
+    // If the client hasn't set a size, return
+    if (0 >= size) {
+        return 0;
+    }
+
+    // Validate the handle
+    if (private_handle_t::validate(buffer_handle)) {
+        ALOGE("%s: handle is invalid", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    // Obtain the private_handle from the native handle
+    private_handle_t *hnd = reinterpret_cast<private_handle_t*>(buffer_handle);
+    if (hnd->size != size) {
+        return reallocate_memory(hnd, size, usage);
+    }
+    return 0;
+}
+
+/*
+ * Checks if memory needs to be reallocated for this buffer.
+ *
+ * @param: Geometry of the current buffer.
+ * @param: Required Geometry.
+ * @param: Geometry of the updated buffer.
+ *
+ * @return True if a memory reallocation is required.
+ */
+bool needNewBuffer(const qBufGeometry currentGeometry,
+                   const qBufGeometry requiredGeometry,
+                   const qBufGeometry updatedGeometry)
+{
+    // If the current buffer info matches the updated info,
+    // we do not require any memory allocation.
+    if (updatedGeometry.width && updatedGeometry.height &&
+        updatedGeometry.format) {
+        return false;
+    }
+    if (currentGeometry.width != requiredGeometry.width ||
+        currentGeometry.height != requiredGeometry.height ||
+        currentGeometry.format != requiredGeometry.format) {
+        // Current and required geometry do not match. Allocation
+        // required.
+        return true;
+    }
+    return false;
+}
+
+/*
+ * Update the geometry of this buffer without reallocation.
+ *
+ * @param: buffer whose geometry needs to be updated.
+ * @param: Updated width
+ * @param: Updated height
+ * @param: Updated format
+ */
+int updateBufferGeometry(sp<GraphicBuffer> buffer, const qBufGeometry updatedGeometry)
+{
+    if (buffer == 0) {
+        ALOGE("%s: graphic buffer is NULL", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    if (!updatedGeometry.width || !updatedGeometry.height ||
+        !updatedGeometry.format) {
+        // No update required. Return.
+        return 0;
+    }
+    if (buffer->width == updatedGeometry.width &&
+        buffer->height == updatedGeometry.height &&
+        buffer->format == updatedGeometry.format) {
+        // The buffer has already been updated. Return.
+        return 0;
+    }
+
+    // Validate the handle
+    if (private_handle_t::validate(buffer->handle)) {
+        ALOGE("%s: handle is invalid", __FUNCTION__);
+        return -EINVAL;
+    }
+    buffer->width  = updatedGeometry.width;
+    buffer->height = updatedGeometry.height;
+    buffer->format = updatedGeometry.format;
+    private_handle_t *hnd = (private_handle_t*)(buffer->handle);
+    if (hnd) {
+        hnd->width  = updatedGeometry.width;
+        hnd->height = updatedGeometry.height;
+        hnd->format = updatedGeometry.format;
+    } else {
+        ALOGE("%s: hnd is NULL", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    return 0;
+}
+
+/* Update the S3D format of this buffer.
+*
+* @param: buffer whosei S3D format needs to be updated.
+* @param: Updated buffer S3D format
+*/
+int updateBufferS3DFormat(sp<GraphicBuffer> buffer, const int s3dFormat)
+{
+    if (buffer == 0) {
+        ALOGE("%s: graphic buffer is NULL", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    buffer->format |= s3dFormat;
+    return 0;
+}
+/*
+ * Updates the flags for the layer
+ *
+ * @param: Attribute
+ * @param: Identifies if the attribute was enabled or disabled.
+ *
+ * @return: -EINVAL if the attribute is invalid
+ */
+int updateLayerQcomFlags(eLayerAttrib attribute, bool enable, int& currentFlags)
+{
+    int ret = 0;
+    switch (attribute) {
+        case LAYER_UPDATE_STATUS: {
+            if (enable)
+                currentFlags |= LAYER_UPDATING;
+            else
+                currentFlags &= ~LAYER_UPDATING;
+        } break;
+        case LAYER_ASYNCHRONOUS_STATUS: {
+            if (enable)
+                currentFlags |= LAYER_ASYNCHRONOUS;
+            else
+                currentFlags &= ~LAYER_ASYNCHRONOUS;
+        } break;
+        default: ALOGE("%s: invalid attribute(0x%x)", __FUNCTION__, attribute);
+                 break;
+    }
+    return ret;
+}
+
+/*
+ * Gets the per frame HWC flags for this layer.
+ *
+ * @param: current hwcl flags
+ * @param: current layerFlags
+ *
+ * @return: the per frame flags.
+ */
+int getPerFrameFlags(int hwclFlags, int layerFlags) {
+    int flags = hwclFlags;
+    if (layerFlags & LAYER_UPDATING)
+        flags &= ~HWC_LAYER_NOT_UPDATING;
+    else
+        flags |= HWC_LAYER_NOT_UPDATING;
+
+    if (layerFlags & LAYER_ASYNCHRONOUS)
+        flags |= HWC_LAYER_ASYNCHRONOUS;
+    else
+        flags &= ~HWC_LAYER_ASYNCHRONOUS;
+
+    return flags;
+}
+
+
+/*
+ * Checks if FB is updated by this composition type
+ *
+ * @param: composition type
+ * @return: true if FB is updated, false if not
+ */
+
+bool isUpdatingFB(HWCCompositionType compositionType)
+{
+    switch(compositionType)
+    {
+        case HWC_USE_COPYBIT:
+            return true;
+        default:
+            ALOGE("%s: invalid composition type(%d)", __FUNCTION__, compositionType);
+            return false;
+    };
+}
+
+/*
+ * Get the current composition Type
+ *
+ * @return the compositon Type
+ */
+int getCompositionType() {
+    char property[PROPERTY_VALUE_MAX];
+    int compositionType = 0;
+    if (property_get("debug.sf.hw", property, NULL) > 0) {
+        if(atoi(property) == 0) {
+            compositionType = COMPOSITION_TYPE_CPU;
+        } else { //debug.sf.hw = 1
+            property_get("debug.composition.type", property, NULL);
+            if (property == NULL) {
+                compositionType = COMPOSITION_TYPE_GPU;
+            } else if ((strncmp(property, "mdp", 3)) == 0) {
+                compositionType = COMPOSITION_TYPE_MDP;
+            } else if ((strncmp(property, "c2d", 3)) == 0) {
+                compositionType = COMPOSITION_TYPE_C2D;
+            } else if ((strncmp(property, "dyn", 3)) == 0) {
+                compositionType = COMPOSITION_TYPE_DYN;
+            } else {
+                compositionType = COMPOSITION_TYPE_GPU;
+            }
+        }
+    } else { //debug.sf.hw is not set. Use cpu composition
+        compositionType = COMPOSITION_TYPE_CPU;
+    }
+    return compositionType;
+}
+
+/*
+ * Clear Region implementation for C2D/MDP versions.
+ *
+ * @param: region to be cleared
+ * @param: EGL Display
+ * @param: EGL Surface
+ *
+ * @return 0 on success
+ */
+int qcomuiClearRegion(Region region, EGLDisplay dpy, EGLSurface sur)
+{
+#if 0 /* FIXME DIE */
+    int ret = 0;
+
+    if (-1 == sCompositionType) {
+        sCompositionType = getCompositionType();
+    }
+
+    if ((COMPOSITION_TYPE_MDP != sCompositionType) &&
+        (COMPOSITION_TYPE_C2D != sCompositionType) &&
+        (COMPOSITION_TYPE_CPU != sCompositionType)) {
+        // For non CPU/C2D/MDP composition, return an error, so that SF can use
+        // the GPU to draw the wormhole.
+        return -1;
+    }
+
+    android_native_buffer_t *renderBuffer = (android_native_buffer_t *)
+                                        eglGetRenderBufferANDROID(dpy, sur);
+    if (!renderBuffer) {
+        ALOGE("%s: eglGetRenderBufferANDROID returned NULL buffer",
+            __FUNCTION__);
+            return -1;
+    }
+    private_handle_t *fbHandle = (private_handle_t *)renderBuffer->handle;
+    if(!fbHandle) {
+        ALOGE("%s: Framebuffer handle is NULL", __FUNCTION__);
+        return -1;
+    }
+
+    int bytesPerPixel = 4;
+    if (HAL_PIXEL_FORMAT_RGB_565 == fbHandle->format) {
+        bytesPerPixel = 2;
+    }
+
+    Region::const_iterator it = region.begin();
+    Region::const_iterator const end = region.end();
+    const int32_t stride = renderBuffer->stride*bytesPerPixel;
+    while (it != end) {
+        const Rect& r = *it++;
+        uint8_t* dst = (uint8_t*) fbHandle->base +
+                       (r.left + r.top*renderBuffer->stride)*bytesPerPixel;
+        int w = r.width()*bytesPerPixel;
+        int h = r.height();
+        do {
+            if(4 == bytesPerPixel)
+                android_memset32((uint32_t*)dst, 0, w);
+            else
+                android_memset16((uint16_t*)dst, 0, w);
+            dst += stride;
+        } while(--h);
+    }
+#endif
+    return 0;
+}
+
+/*
+ * Handles the externalDisplay event
+ * HDMI has highest priority compared to WifiDisplay
+ * Based on the current and the new display event, decides the
+ * external display to be enabled
+ *
+ * @param: newEvent - new external event
+ * @param: currEvent - currently enabled external event
+ * @return: external display to be enabled
+ *
+ */
+external_display handleEventHDMI(external_display newState, external_display
+                                                                   currState)
+{
+    external_display retState = currState;
+    switch(newState) {
+        case EXT_DISPLAY_HDMI:
+            retState = EXT_DISPLAY_HDMI;
+            break;
+        case EXT_DISPLAY_WIFI:
+            if(currState != EXT_DISPLAY_HDMI) {
+                retState = EXT_DISPLAY_WIFI;
+            }
+            break;
+        case EXT_DISPLAY_OFF:
+            retState = EXT_DISPLAY_OFF;
+            break;
+        default:
+            ALOGE("handleEventHDMI: unknown Event");
+            break;
+    }
+    return retState;
+}
+
+// Using global variables for layer dumping since "property_set("debug.sf.dump",
+// property)" does not work.
+int sfdump_countlimit_raw = 0;
+int sfdump_counter_raw = 1;
+char sfdump_propstr_persist_raw[PROPERTY_VALUE_MAX] = "";
+char sfdumpdir_raw[256] = "";
+int sfdump_countlimit_png = 0;
+int sfdump_counter_png = 1;
+char sfdump_propstr_persist_png[PROPERTY_VALUE_MAX] = "";
+char sfdumpdir_png[256] = "";
+
+bool needToDumpLayers()
+{
+    bool bDumpLayer = false;
+    char sfdump_propstr[PROPERTY_VALUE_MAX];
+    time_t timenow;
+    tm sfdump_time;
+
+    time(&timenow);
+    localtime_r(&timenow, &sfdump_time);
+
+    if ((property_get("debug.sf.dump.png", sfdump_propstr, NULL) > 0) &&
+            (strncmp(sfdump_propstr, sfdump_propstr_persist_png,
+                                                    PROPERTY_VALUE_MAX - 1))) {
+        // Strings exist & not equal implies it has changed, so trigger a dump
+        strncpy(sfdump_propstr_persist_png, sfdump_propstr,
+                                                    PROPERTY_VALUE_MAX - 1);
+        sfdump_countlimit_png = atoi(sfdump_propstr);
+        sfdump_countlimit_png = (sfdump_countlimit_png < 0) ? 0:
+                        (sfdump_countlimit_png >= LONG_MAX) ? (LONG_MAX - 1):
+                                                        sfdump_countlimit_png;
+        if (sfdump_countlimit_png) {
+            sprintf(sfdumpdir_png,"/data/sfdump.png%04d%02d%02d.%02d%02d%02d",
+            sfdump_time.tm_year + 1900, sfdump_time.tm_mon + 1,
+            sfdump_time.tm_mday, sfdump_time.tm_hour,
+            sfdump_time.tm_min, sfdump_time.tm_sec);
+            if (0 == mkdir(sfdumpdir_png, 0777))
+                sfdump_counter_png = 0;
+            else
+                ALOGE("sfdump: Error: %s. Failed to create sfdump directory"
+                ": %s", strerror(errno), sfdumpdir_png);
+        }
+    }
+
+    if (sfdump_counter_png <= sfdump_countlimit_png)
+        sfdump_counter_png++;
+
+    if ((property_get("debug.sf.dump", sfdump_propstr, NULL) > 0) &&
+            (strncmp(sfdump_propstr, sfdump_propstr_persist_raw,
+                                                    PROPERTY_VALUE_MAX - 1))) {
+        // Strings exist & not equal implies it has changed, so trigger a dump
+        strncpy(sfdump_propstr_persist_raw, sfdump_propstr,
+                                                    PROPERTY_VALUE_MAX - 1);
+        sfdump_countlimit_raw = atoi(sfdump_propstr);
+        sfdump_countlimit_raw = (sfdump_countlimit_raw < 0) ? 0:
+                        (sfdump_countlimit_raw >= LONG_MAX) ? (LONG_MAX - 1):
+                                                        sfdump_countlimit_raw;
+        if (sfdump_countlimit_raw) {
+            sprintf(sfdumpdir_raw,"/data/sfdump.raw%04d%02d%02d.%02d%02d%02d",
+            sfdump_time.tm_year + 1900, sfdump_time.tm_mon + 1,
+            sfdump_time.tm_mday, sfdump_time.tm_hour,
+            sfdump_time.tm_min, sfdump_time.tm_sec);
+            if (0 == mkdir(sfdumpdir_raw, 0777))
+                sfdump_counter_raw = 0;
+            else
+                ALOGE("sfdump: Error: %s. Failed to create sfdump directory"
+                ": %s", strerror(errno), sfdumpdir_raw);
+        }
+    }
+
+    if (sfdump_counter_raw <= sfdump_countlimit_raw)
+        sfdump_counter_raw++;
+
+    bDumpLayer = (sfdump_countlimit_png || sfdump_countlimit_raw)? true : false;
+    return bDumpLayer;
+}
+
+inline void getHalPixelFormatStr(int format, char pixelformatstr[])
+{
+    if (!pixelformatstr)
+        return;
+
+    switch(format) {
+    case HAL_PIXEL_FORMAT_RGBA_8888:
+        strcpy(pixelformatstr, "RGBA_8888");
+        break;
+    case HAL_PIXEL_FORMAT_RGBX_8888:
+        strcpy(pixelformatstr, "RGBX_8888");
+        break;
+    case HAL_PIXEL_FORMAT_RGB_888:
+        strcpy(pixelformatstr, "RGB_888");
+        break;
+    case HAL_PIXEL_FORMAT_RGB_565:
+        strcpy(pixelformatstr, "RGB_565");
+        break;
+    case HAL_PIXEL_FORMAT_BGRA_8888:
+        strcpy(pixelformatstr, "BGRA_8888");
+        break;
+    case HAL_PIXEL_FORMAT_RGBA_5551:
+        strcpy(pixelformatstr, "RGBA_5551");
+        break;
+    case HAL_PIXEL_FORMAT_RGBA_4444:
+        strcpy(pixelformatstr, "RGBA_4444");
+        break;
+    case HAL_PIXEL_FORMAT_YV12:
+        strcpy(pixelformatstr, "YV12");
+        break;
+    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+        strcpy(pixelformatstr, "YCbCr_422_SP_NV16");
+        break;
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+        strcpy(pixelformatstr, "YCrCb_420_SP_NV21");
+        break;
+    case HAL_PIXEL_FORMAT_YCbCr_422_I:
+        strcpy(pixelformatstr, "YCbCr_422_I_YUY2");
+        break;
+    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+        strcpy(pixelformatstr, "NV12_ENCODEABLE");
+        break;
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
+        strcpy(pixelformatstr, "YCbCr_420_SP_TILED_TILE_4x2");
+        break;
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+        strcpy(pixelformatstr, "YCbCr_420_SP");
+        break;
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
+        strcpy(pixelformatstr, "YCrCb_420_SP_ADRENO");
+        break;
+    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+        strcpy(pixelformatstr, "YCrCb_422_SP");
+        break;
+    case HAL_PIXEL_FORMAT_R_8:
+        strcpy(pixelformatstr, "R_8");
+        break;
+    case HAL_PIXEL_FORMAT_RG_88:
+        strcpy(pixelformatstr, "RG_88");
+        break;
+    case HAL_PIXEL_FORMAT_INTERLACE:
+        strcpy(pixelformatstr, "INTERLACE");
+        break;
+    default:
+        sprintf(pixelformatstr, "Unknown0x%X", format);
+        break;
+    }
+}
+
+void dumpLayer(int moduleCompositionType, int listFlags, size_t layerIndex,
+                                                        hwc_layer_t hwLayers[])
+{
+    char dumplogstr_png[128] = "";
+    char dumplogstr_raw[128] = "";
+    if (sfdump_counter_png <= sfdump_countlimit_png) {
+        sprintf(dumplogstr_png, "[png-dump-frame: %03d of %03d] ",
+                                    sfdump_counter_png, sfdump_countlimit_png);
+    }
+    if (sfdump_counter_raw <= sfdump_countlimit_raw) {
+        sprintf(dumplogstr_raw, "[raw-dump-frame: %03d of %03d]",
+                                    sfdump_counter_raw, sfdump_countlimit_raw);
+    }
+    if (NULL == hwLayers) {
+        ALOGE("sfdump: Error.%s%sLayer[%d] No hwLayers to dump.",
+                                dumplogstr_raw, dumplogstr_png, layerIndex);
+        return;
+    }
+    hwc_layer *layer = &hwLayers[layerIndex];
+    hwc_rect_t sourceCrop = layer->sourceCrop;
+    hwc_rect_t displayFrame = layer->displayFrame;
+    private_handle_t *hnd = (private_handle_t *)layer->handle;
+    char pixelformatstr[32] = "None";
+
+    if (hnd)
+        getHalPixelFormatStr(hnd->format, pixelformatstr);
+#if 0
+    ALOGE("sfdump: %s%s[%s]-Composition, Layer[%d] SrcBuff[%dx%d] "
+        "SrcCrop[%dl, %dt, %dr, %db] "
+        "DispFrame[%dl, %dt, %dr, %db] Composition-type = %s, Format = %s, "
+        "Orientation = %s, Flags = %s%s%s%s%s%s%s%s%s%s",
+        dumplogstr_raw, dumplogstr_png,
+        (moduleCompositionType == COMPOSITION_TYPE_GPU)? "GPU":
+        (moduleCompositionType == COMPOSITION_TYPE_MDP)? "MDP":
+        (moduleCompositionType == COMPOSITION_TYPE_C2D)? "C2D":
+        (moduleCompositionType == COMPOSITION_TYPE_CPU)? "CPU":
+        (moduleCompositionType == COMPOSITION_TYPE_DYN)? "DYN": "???",
+        layerIndex,
+        (hnd)? hnd->width : -1, (hnd)? hnd->height : -1,
+        sourceCrop.left, sourceCrop.top,
+        sourceCrop.right, sourceCrop.bottom,
+        displayFrame.left, displayFrame.top,
+        displayFrame.right, displayFrame.bottom,
+        (layer->compositionType == HWC_FRAMEBUFFER)? "Framebuffer (OpenGL ES)":
+        (layer->compositionType == HWC_OVERLAY)? "Overlay":
+        (layer->compositionType == HWC_USE_COPYBIT)? "Copybit": "???",
+        pixelformatstr,
+        (layer->transform == Transform::ROT_0)? "ROT_0":
+        (layer->transform == Transform::FLIP_H)? "FLIP_H":
+        (layer->transform == Transform::FLIP_V)? "FLIP_V":
+        (layer->transform == Transform::ROT_90)? "ROT_90":
+        (layer->transform == Transform::ROT_180)? "ROT_180":
+        (layer->transform == Transform::ROT_270)? "ROT_270":
+        (layer->transform == Transform::ROT_INVALID)? "ROT_INVALID":"???",
+        (layer->flags == 0)? "[None]":"",
+        (layer->flags & HWC_SKIP_LAYER)? "[Skip layer]":"",
+        (layer->flags & HWC_LAYER_NOT_UPDATING)? "[Layer not updating]":"",
+        (layer->flags & HWC_USE_ORIGINAL_RESOLUTION)? "[Original Resolution]":"",
+        (layer->flags & HWC_DO_NOT_USE_OVERLAY)? "[Do not use Overlay]":"",
+        (layer->flags & HWC_COMP_BYPASS)? "[Bypass]":"",
+        (layer->flags & HWC_BYPASS_RESERVE_0)? "[Bypass Reserve 0]":"",
+        (layer->flags & HWC_BYPASS_RESERVE_1)? "[Bypass Reserve 1]":"",
+        (listFlags & HWC_GEOMETRY_CHANGED)? "[List: Geometry Changed]":"",
+        (listFlags & HWC_SKIP_COMPOSITION)? "[List: Skip Composition]":"");
+#endif
+        if (NULL == hnd) {
+            ALOGE("sfdump: %s%sLayer[%d] private-handle is invalid.",
+                                dumplogstr_raw, dumplogstr_png, layerIndex);
+            return;
+        }
+
+        if ((sfdump_counter_png <= sfdump_countlimit_png) && hnd->base) {
+            bool bResult = false;
+            char sfdumpfile_name[256];
+            SkBitmap *tempSkBmp = new SkBitmap();
+            SkBitmap::Config tempSkBmpConfig = SkBitmap::kNo_Config;
+            sprintf(sfdumpfile_name, "%s/sfdump%03d_layer%d.png", sfdumpdir_png,
+                    sfdump_counter_png, layerIndex);
+
+            switch (hnd->format) {
+                case HAL_PIXEL_FORMAT_RGBA_8888:
+                case HAL_PIXEL_FORMAT_RGBX_8888:
+                case HAL_PIXEL_FORMAT_BGRA_8888:
+                    tempSkBmpConfig = SkBitmap::kARGB_8888_Config;
+                    break;
+                case HAL_PIXEL_FORMAT_RGB_565:
+                case HAL_PIXEL_FORMAT_RGBA_5551:
+                case HAL_PIXEL_FORMAT_RGBA_4444:
+                    tempSkBmpConfig = SkBitmap::kRGB_565_Config;
+                    break;
+                case HAL_PIXEL_FORMAT_RGB_888:
+                default:
+                    tempSkBmpConfig = SkBitmap::kNo_Config;
+                    break;
+            }
+            if (SkBitmap::kNo_Config != tempSkBmpConfig) {
+                tempSkBmp->setConfig(tempSkBmpConfig, hnd->width, hnd->height);
+                tempSkBmp->setPixels((void*)hnd->base);
+                bResult = SkImageEncoder::EncodeFile(sfdumpfile_name,
+                                *tempSkBmp, SkImageEncoder::kPNG_Type, 100);
+                ALOGE("sfdump: %sDumped Layer[%d] to %s: %s", dumplogstr_png,
+                    layerIndex, sfdumpfile_name, bResult ? "Success" : "Fail");
+            }
+            else {
+                ALOGE("sfdump: %sSkipping Layer[%d] dump: Unsupported layer "
+                    "format %s for png encoder.", dumplogstr_png, layerIndex,
+                                            pixelformatstr);
+            }
+            delete tempSkBmp; // Calls SkBitmap::freePixels() internally.
+        }
+
+        if ((sfdump_counter_raw <= sfdump_countlimit_raw) && hnd->base) {
+            char sfdumpfile_name[256];
+            bool bResult = false;
+            sprintf(sfdumpfile_name, "%s/sfdump%03d_layer%d_%dx%d_%s.raw",
+                sfdumpdir_raw,
+                sfdump_counter_raw, layerIndex, hnd->width, hnd->height,
+                pixelformatstr);
+            FILE* fp = fopen(sfdumpfile_name, "w+");
+            if (fp != NULL) {
+                bResult = (bool) fwrite((void*)hnd->base, hnd->size, 1, fp);
+                fclose(fp);
+            }
+            ALOGE("sfdump: %s Dumped Layer[%d] to %s: %s", dumplogstr_raw,
+                layerIndex, sfdumpfile_name, bResult ? "Success" : "Fail");
+        }
+}
+
+#ifdef DEBUG_CALC_FPS
+ANDROID_SINGLETON_STATIC_INSTANCE(CalcFps) ;
+
+CalcFps::CalcFps() {
+    debug_fps_level = 0;
+    Init();
+}
+
+CalcFps::~CalcFps() {
+}
+
+void CalcFps::Init() {
+    char prop[PROPERTY_VALUE_MAX];
+    property_get("debug.gr.calcfps", prop, "0");
+    debug_fps_level = atoi(prop);
+    if (debug_fps_level > MAX_DEBUG_FPS_LEVEL) {
+        ALOGW("out of range value for debug.gr.calcfps, using 0");
+        debug_fps_level = 0;
+    }
+
+    ALOGE("DEBUG_CALC_FPS: %d", debug_fps_level);
+    populate_debug_fps_metadata();
+}
+
+void CalcFps::Fps() {
+    if (debug_fps_level > 0)
+        calc_fps(ns2us(systemTime()));
+}
+
+void CalcFps::populate_debug_fps_metadata(void)
+{
+    char prop[PROPERTY_VALUE_MAX];
+
+    /*defaults calculation of fps to based on number of frames*/
+    property_get("debug.gr.calcfps.type", prop, "0");
+    debug_fps_metadata.type = (debug_fps_metadata_t::DfmType) atoi(prop);
+
+    /*defaults to 1000ms*/
+    property_get("debug.gr.calcfps.timeperiod", prop, "1000");
+    debug_fps_metadata.time_period = atoi(prop);
+
+    property_get("debug.gr.calcfps.period", prop, "10");
+    debug_fps_metadata.period = atoi(prop);
+
+    if (debug_fps_metadata.period > MAX_FPS_CALC_PERIOD_IN_FRAMES) {
+        debug_fps_metadata.period = MAX_FPS_CALC_PERIOD_IN_FRAMES;
+    }
+
+    /* default ignorethresh_us: 500 milli seconds */
+    property_get("debug.gr.calcfps.ignorethresh_us", prop, "500000");
+    debug_fps_metadata.ignorethresh_us = atoi(prop);
+
+    debug_fps_metadata.framearrival_steps =
+                       (debug_fps_metadata.ignorethresh_us / 16666);
+
+    if (debug_fps_metadata.framearrival_steps > MAX_FRAMEARRIVAL_STEPS) {
+        debug_fps_metadata.framearrival_steps = MAX_FRAMEARRIVAL_STEPS;
+        debug_fps_metadata.ignorethresh_us =
+                        debug_fps_metadata.framearrival_steps * 16666;
+    }
+
+    /* 2ms margin of error for the gettimeofday */
+    debug_fps_metadata.margin_us = 2000;
+
+    for (unsigned int i = 0; i < MAX_FRAMEARRIVAL_STEPS; i++)
+        debug_fps_metadata.accum_framearrivals[i] = 0;
+
+    ALOGE("period: %d", debug_fps_metadata.period);
+    ALOGE("ignorethresh_us: %lld", debug_fps_metadata.ignorethresh_us);
+}
+
+void CalcFps::print_fps(float fps)
+{
+    if (debug_fps_metadata_t::DFM_FRAMES == debug_fps_metadata.type)
+        ALOGE("FPS for last %d frames: %3.2f", debug_fps_metadata.period, fps);
+    else
+        ALOGE("FPS for last (%f ms, %d frames): %3.2f",
+             debug_fps_metadata.time_elapsed,
+             debug_fps_metadata.curr_frame, fps);
+
+    debug_fps_metadata.curr_frame = 0;
+    debug_fps_metadata.time_elapsed = 0.0;
+
+    if (debug_fps_level > 1) {
+        ALOGE("Frame Arrival Distribution:");
+        for (unsigned int i = 0;
+             i < ((debug_fps_metadata.framearrival_steps / 6) + 1);
+             i++) {
+            ALOGE("%lld %lld %lld %lld %lld %lld",
+                 debug_fps_metadata.accum_framearrivals[i*6],
+                 debug_fps_metadata.accum_framearrivals[i*6+1],
+                 debug_fps_metadata.accum_framearrivals[i*6+2],
+                 debug_fps_metadata.accum_framearrivals[i*6+3],
+                 debug_fps_metadata.accum_framearrivals[i*6+4],
+                 debug_fps_metadata.accum_framearrivals[i*6+5]);
+        }
+
+        /* We are done with displaying, now clear the stats */
+        for (unsigned int i = 0;
+             i < debug_fps_metadata.framearrival_steps;
+             i++)
+            debug_fps_metadata.accum_framearrivals[i] = 0;
+    }
+    return;
+}
+
+void CalcFps::calc_fps(nsecs_t currtime_us)
+{
+    static nsecs_t oldtime_us = 0;
+
+    nsecs_t diff = currtime_us - oldtime_us;
+
+    oldtime_us = currtime_us;
+
+    if (debug_fps_metadata_t::DFM_FRAMES == debug_fps_metadata.type &&
+        diff > debug_fps_metadata.ignorethresh_us) {
+        return;
+    }
+
+    if (debug_fps_metadata.curr_frame < MAX_FPS_CALC_PERIOD_IN_FRAMES) {
+        debug_fps_metadata.framearrivals[debug_fps_metadata.curr_frame] = diff;
+    }
+
+    debug_fps_metadata.curr_frame++;
+
+    if (debug_fps_level > 1) {
+        unsigned int currstep = (diff + debug_fps_metadata.margin_us) / 16666;
+
+        if (currstep < debug_fps_metadata.framearrival_steps) {
+            debug_fps_metadata.accum_framearrivals[currstep-1]++;
+        }
+    }
+
+    if (debug_fps_metadata_t::DFM_FRAMES == debug_fps_metadata.type) {
+        if (debug_fps_metadata.curr_frame == debug_fps_metadata.period) {
+            /* time to calculate and display FPS */
+            nsecs_t sum = 0;
+            for (unsigned int i = 0; i < debug_fps_metadata.period; i++)
+                sum += debug_fps_metadata.framearrivals[i];
+            print_fps((debug_fps_metadata.period * float(1000000))/float(sum));
+        }
+    }
+    else if (debug_fps_metadata_t::DFM_TIME == debug_fps_metadata.type) {
+        debug_fps_metadata.time_elapsed += ((float)diff/1000.0);
+        if (debug_fps_metadata.time_elapsed >= debug_fps_metadata.time_period) {
+            float fps = (1000.0 * debug_fps_metadata.curr_frame)/
+                        (float)debug_fps_metadata.time_elapsed;
+            print_fps(fps);
+        }
+    }
+    return;
+}
+#endif
diff --git a/libqcomui/qcom_ui.h b/libqcomui/qcom_ui.h
new file mode 100644
index 0000000..88462cc
--- /dev/null
+++ b/libqcomui/qcom_ui.h
@@ -0,0 +1,394 @@
+/*
+ * Copyright (c) 2011-2012, Code Aurora Forum. 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 Code Aurora Forum, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef INCLUDE_LIBQCOM_UI
+#define INCLUDE_LIBQCOM_UI
+
+#include <cutils/native_handle.h>
+#include <ui/GraphicBuffer.h>
+#include <hardware/hwcomposer.h>
+#include <hardware/hwcomposer_defs.h>
+#include <ui/Region.h>
+#include <EGL/egl.h>
+#include <utils/Singleton.h>
+#include <cutils/properties.h>
+#include "../libgralloc/gralloc_priv.h"
+
+using namespace android;
+using android::sp;
+using android::GraphicBuffer;
+
+#define HWC_BYPASS_INDEX_MASK 0x00000030
+
+/*
+ * Qcom specific Native Window perform operations
+ */
+enum {
+    NATIVE_WINDOW_SET_BUFFERS_SIZE        = 0x10000000,
+    NATIVE_WINDOW_UPDATE_BUFFERS_GEOMETRY = 0x20000000,
+    NATIVE_WINDOW_SET_S3D_FORMAT          = 0x40000000,
+};
+
+// Enum containing the supported composition types
+enum {
+    COMPOSITION_TYPE_GPU = 0,
+    COMPOSITION_TYPE_MDP = 0x1,
+    COMPOSITION_TYPE_C2D = 0x2,
+    COMPOSITION_TYPE_CPU = 0x4,
+    COMPOSITION_TYPE_DYN = 0x8
+};
+
+/*
+ * Layer Attributes
+ */
+enum eLayerAttrib {
+    LAYER_UPDATE_STATUS,
+    LAYER_ASYNCHRONOUS_STATUS,
+};
+
+/*
+ * Layer Flags
+ */
+enum {
+    LAYER_UPDATING     = 1<<0,
+    LAYER_ASYNCHRONOUS = 1<<1,
+};
+
+/*
+ * Flags set by the layer and sent to HWC
+ */
+enum {
+    HWC_LAYER_NOT_UPDATING      = 0x00000002,
+    HWC_LAYER_ASYNCHRONOUS      = 0x00000004,
+    HWC_USE_ORIGINAL_RESOLUTION = 0x10000000,
+    HWC_DO_NOT_USE_OVERLAY      = 0x20000000,
+    HWC_COMP_BYPASS             = 0x40000000,
+    HWC_USE_EXT_ONLY            = 0x80000000, //Layer displayed on external only
+    HWC_USE_EXT_BLOCK           = 0x01000000, //Layer displayed on external only
+    HWC_BYPASS_RESERVE_0        = 0x00000010,
+    HWC_BYPASS_RESERVE_1        = 0x00000020,
+};
+
+enum HWCCompositionType {
+    HWC_USE_GPU = HWC_FRAMEBUFFER, // This layer is to be handled by Surfaceflinger
+    HWC_USE_OVERLAY = HWC_OVERLAY, // This layer is to be handled by the overlay
+    HWC_USE_COPYBIT                // This layer is to be handled by copybit
+};
+
+enum external_display {
+    EXT_DISPLAY_OFF,
+    EXT_DISPLAY_HDMI,
+    EXT_DISPLAY_WIFI
+};
+
+/*
+ * Structure to hold the buffer geometry
+ */
+struct qBufGeometry {
+    int width;
+    int height;
+    int format;
+    void set(int w, int h, int f) {
+       width = w;
+       height = h;
+       format = f;
+    }
+};
+
+#ifndef DEBUG_CALC_FPS
+#define CALC_FPS() ((void)0)
+#define CALC_INIT() ((void)0)
+#else
+#define CALC_FPS() CalcFps::getInstance().Fps()
+#define CALC_INIT() CalcFps::getInstance().Init()
+
+class CalcFps : public Singleton<CalcFps> {
+public:
+    CalcFps();
+    ~CalcFps();
+
+    void Init();
+    void Fps();
+
+private:
+    static const unsigned int MAX_FPS_CALC_PERIOD_IN_FRAMES = 128;
+    static const unsigned int MAX_FRAMEARRIVAL_STEPS = 50;
+    static const unsigned int MAX_DEBUG_FPS_LEVEL = 2;
+
+    struct debug_fps_metadata_t {
+        /*fps calculation based on time or number of frames*/
+        enum DfmType {
+          DFM_FRAMES = 0,
+          DFM_TIME   = 1,
+        };
+
+        DfmType type;
+
+        /* indicates how much time do we wait till we calculate FPS */
+        unsigned long time_period;
+
+        /*indicates how much time elapsed since we report fps*/
+        float time_elapsed;
+
+        /* indicates how many frames do we wait till we calculate FPS */
+        unsigned int period;
+        /* current frame, will go upto period, and then reset */
+        unsigned int curr_frame;
+        /* frame will arrive at a multiple of 16666 us at the display.
+           This indicates how many steps to consider for our calculations.
+           For example, if framearrival_steps = 10, then the frame that arrived
+           after 166660 us or more will be ignored.
+        */
+        unsigned int framearrival_steps;
+        /* ignorethresh_us = framearrival_steps * 16666 */
+        nsecs_t      ignorethresh_us;
+        /* used to calculate the actual frame arrival step, the times might not be
+           accurate
+        */
+        unsigned int margin_us;
+
+        /* actual data storage */
+        nsecs_t      framearrivals[MAX_FPS_CALC_PERIOD_IN_FRAMES];
+        nsecs_t      accum_framearrivals[MAX_FRAMEARRIVAL_STEPS];
+    };
+
+private:
+    void populate_debug_fps_metadata(void);
+    void print_fps(float fps);
+    void calc_fps(nsecs_t currtime_us);
+
+private:
+    debug_fps_metadata_t debug_fps_metadata;
+    unsigned int debug_fps_level;
+};
+#endif
+
+#if 0
+class QCBaseLayer
+{
+//    int mS3DFormat;
+    int32_t mComposeS3DFormat;
+public:
+    QCBaseLayer()
+    {
+        mComposeS3DFormat = 0;
+    }
+    enum { // S3D formats
+        eS3D_SIDE_BY_SIDE   = 0x10000,
+        eS3D_TOP_BOTTOM     = 0x20000
+    };
+/*
+    virtual status_t setStereoscopic3DFormat(int format) { mS3DFormat = format; return 0; }
+    virtual int getStereoscopic3DFormat() const { return mS3DFormat; }
+ */
+    void setS3DComposeFormat (int32_t hints)
+    {
+        if (hints & HWC_HINT_DRAW_S3D_SIDE_BY_SIDE)
+            mComposeS3DFormat = eS3D_SIDE_BY_SIDE;
+        else if (hints & HWC_HINT_DRAW_S3D_TOP_BOTTOM)
+            mComposeS3DFormat = eS3D_TOP_BOTTOM;
+        else
+            mComposeS3DFormat = 0;
+    }
+    int32_t needsS3DCompose () const { return mComposeS3DFormat; }
+};
+#endif
+
+/*
+ * Function to check if the allocated buffer is of the correct size.
+ * Reallocate the buffer with the correct size, if the size doesn't
+ * match
+ *
+ * @param: handle of the allocated buffer
+ * @param: requested size for the buffer
+ * @param: usage flags
+ *
+ * return 0 on success
+ */
+int checkBuffer(native_handle_t *buffer_handle, int size, int usage);
+
+/*
+ * Checks if the format is supported by the GPU.
+ *
+ * @param: format to check
+ *
+ * @return true if the format is supported by the GPU.
+ */
+bool isGPUSupportedFormat(int format);
+
+/*
+ * Adreno is not optimized for GL_TEXTURE_EXTERNAL_OES
+ * texure target. DO NOT choose TEXTURE_EXTERNAL_OES
+ * target for RGB formats.
+ *
+ * Based on the pixel format, decide the texture target.
+ *
+ * @param : pixel format to check
+ *
+ * @return : GL_TEXTURE_2D for RGB formats, and
+ *           GL_TEXTURE_EXTERNAL_OES for YUV formats.
+ *
+*/
+
+int decideTextureTarget (const int pixel_format);
+
+/*
+ * Gets the number of arguments required for this operation.
+ *
+ * @param: operation whose argument count is required.
+ *
+ * @return -EINVAL if the operation is invalid.
+ */
+int getNumberOfArgsForOperation(int operation);
+
+/*
+ * Checks if memory needs to be reallocated for this buffer.
+ *
+ * @param: Geometry of the current buffer.
+ * @param: Required Geometry.
+ * @param: Geometry of the updated buffer.
+ *
+ * @return True if a memory reallocation is required.
+ */
+bool needNewBuffer(const qBufGeometry currentGeometry,
+                            const qBufGeometry requiredGeometry,
+                            const qBufGeometry updatedGeometry);
+
+/*
+ * Update the geometry of this buffer without reallocation.
+ *
+ * @param: buffer whose geometry needs to be updated.
+ * @param: Updated buffer geometry
+ */
+int updateBufferGeometry(sp<GraphicBuffer> buffer, const qBufGeometry bufGeometry);
+
+/*
+ * Update the S3D format of this buffer.
+ *
+ * @param: buffer whosei S3D format needs to be updated.
+ * @param: Updated buffer S3D format
+ */
+int updateBufferS3DFormat(sp<GraphicBuffer> buffer, const int s3dFormat);
+
+/*
+ * Updates the flags for the layer
+ *
+ * @param: Attribute
+ * @param: Identifies if the attribute was enabled or disabled.
+ * @param: current Layer flags.
+ *
+ * @return: Flags for the layer
+ */
+int updateLayerQcomFlags(eLayerAttrib attribute, bool enable, int& currentFlags);
+
+/*
+ * Gets the per frame HWC flags for this layer.
+ *
+ * @param: current hwcl flags
+ * @param: current layerFlags
+ *
+ * @return: the per frame flags.
+ */
+int getPerFrameFlags(int hwclFlags, int layerFlags);
+
+/*
+ * Checks if FB is updated by this composition type
+ *
+ * @param: composition type
+ * @return: true if FB is updated, false if not
+ */
+
+bool isUpdatingFB(HWCCompositionType compositionType);
+
+/*
+ * Get the current composition Type
+ *
+ * @return the compositon Type
+ */
+int getCompositionType();
+
+/*
+ * Clear region implementation for C2D/MDP versions.
+ *
+ * @param: region to be cleared
+ * @param: EGL Display
+ * @param: EGL Surface
+ *
+ * @return 0 on success
+ */
+int qcomuiClearRegion(Region region, EGLDisplay dpy, EGLSurface sur);
+
+/*
+ * Handles the externalDisplay event
+ * HDMI has highest priority compared to WifiDisplay
+ * Based on the current and the new display event, decides the
+ * external display to be enabled
+ *
+ * @param: newEvent - new external event
+ * @param: currEvent - currently enabled external event
+ * @return: external display to be enabled
+ *
+ */
+external_display handleEventHDMI(external_display newEvent, external_display
+                                                                   currEvent);
+
+/*
+ * Checks if layers need to be dumped based on system property "debug.sf.dump"
+ * for raw dumps and "debug.sf.dump.png" for png dumps.
+ *
+ * For example, to dump 25 frames in raw format, do,
+ *     adb shell setprop debug.sf.dump 25
+ * Layers are dumped in a time-stamped location: /data/sfdump*.
+ *
+ * To dump 10 frames in png format, do,
+ *     adb shell setprop debug.sf.dump.png 10
+ * To dump another 25 or so frames in raw format, do,
+ *     adb shell setprop debug.sf.dump 26
+ *
+ * To turn off logcat logging of layer-info, set both properties to 0,
+ *     adb shell setprop debug.sf.dump.png 0
+ *     adb shell setprop debug.sf.dump 0
+ *
+ * @return: true if layers need to be dumped (or logcat-ed).
+ */
+bool needToDumpLayers();
+
+/*
+ * Dumps a layer's info into logcat and its buffer into raw/png files.
+ *
+ * @param: moduleCompositionType - Composition type set in hwcomposer module.
+ * @param: listFlags - Flags used in hwcomposer's list.
+ * @param: layerIndex - Index of layer being dumped.
+ * @param: hwLayers - Address of hwc_layer_t to log and dump.
+ *
+ */
+void dumpLayer(int moduleCompositionType, int listFlags, size_t layerIndex,
+                                                    hwc_layer_t hwLayers[]);
+
+#endif // INCLUDE_LIBQCOM_UI
diff --git a/libtilerenderer/Android.mk b/libtilerenderer/Android.mk
new file mode 100644
index 0000000..e0bf342
--- /dev/null
+++ b/libtilerenderer/Android.mk
@@ -0,0 +1,26 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+ifeq ($(USE_OPENGL_RENDERER),true)
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)
+LOCAL_SHARED_LIBRARIES := libutils libcutils libGLESv2 libhwui
+
+LOCAL_C_INCLUDES += \
+	frameworks/base/include/utils \
+	frameworks/base/libs/hwui \
+	external/skia/include/core \
+	external/skia/include/effects \
+	external/skia/include/images \
+	external/skia/src/ports \
+	external/skia/include/utils \
+	hardware/libhardware/include/hardware \
+	frameworks/base/opengl/include/GLES2
+
+LOCAL_SRC_FILES := 	\
+	tilerenderer.cpp
+
+LOCAL_MODULE := libtilerenderer
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_SHARED_LIBRARY)
+endif
diff --git a/libtilerenderer/tilerenderer.cpp b/libtilerenderer/tilerenderer.cpp
new file mode 100644
index 0000000..6e8f847
--- /dev/null
+++ b/libtilerenderer/tilerenderer.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (c) 2011 Code Aurora Forum. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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 <GLES2/gl2.h>
+#include <EGL/egl.h>
+#include <gl2ext.h>
+#include <OpenGLRenderer.h>
+#include "tilerenderer.h"
+
+namespace android {
+ANDROID_SINGLETON_STATIC_INSTANCE(uirenderer::TileRenderer) ;
+namespace uirenderer {
+
+TileRenderer::TileRenderer() {
+    mIsTiled = false;
+}
+
+TileRenderer::~TileRenderer() {
+}
+
+void TileRenderer::startTileRendering(OpenGLRenderer* renderer,
+                                      int left, int top,
+                                      int right, int bottom) {
+    int width = 0;
+    int height = 0;
+    GLenum status = GL_NO_ERROR;
+
+    if (renderer != NULL) {
+        renderer->getViewport(width, height);
+    }
+
+    if (!left && !right && !top && !bottom) {
+        left = 0;
+        top = 0;
+        right = width;
+        bottom = height;
+    }
+
+    if (!left && !right && !top && !bottom) {
+        //can't do tile rendering
+        LOGE("can't tile render; drity region, width, height not available");
+        return;
+    }
+
+    int l = left, t = (height - bottom), w = (right - left), h = (bottom - top), preserve = 0;
+
+    if (l < 0 || t < 0) {
+        l = (l < 0) ? 0 : l;
+        t = (t < 0) ? 0 : t;
+        preserve = 1;
+    }
+
+    if (w > width || h > height) {
+        w = (w > width) ? width : w;
+        h = (h > height) ? height : h;
+        preserve = 1;
+    }
+
+    //clear off all errors before tiling, if any
+    while ((status = glGetError()) != GL_NO_ERROR);
+
+    if (preserve)
+        glStartTilingQCOM(l, t, w, h, GL_COLOR_BUFFER_BIT0_QCOM);
+    else
+        glStartTilingQCOM(l, t, w, h, GL_NONE);
+
+    status = glGetError();
+    if (status == GL_NO_ERROR)
+        mIsTiled = true;
+}
+
+void TileRenderer::endTileRendering(OpenGLRenderer*) {
+    if (!mIsTiled) {
+        return;
+    }
+    glEndTilingQCOM(GL_COLOR_BUFFER_BIT0_QCOM);
+    mIsTiled = false;
+    GLenum status = GL_NO_ERROR;
+    while ((status = glGetError()) != GL_NO_ERROR);
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libtilerenderer/tilerenderer.h b/libtilerenderer/tilerenderer.h
new file mode 100644
index 0000000..bec225d
--- /dev/null
+++ b/libtilerenderer/tilerenderer.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.
+ */
+#ifndef ANDROID_TILE_RENDERER_H
+#define ANDROID_TILE_RENDERER_H
+
+#include <utils/Singleton.h>
+
+namespace android {
+namespace uirenderer {
+
+class OpenGLRenderer;
+
+class TileRenderer: public Singleton<TileRenderer> {
+public:
+    TileRenderer();
+    ~TileRenderer();
+
+    void startTileRendering(OpenGLRenderer* renderer, int left, int top, int right, int bottom);
+    void endTileRendering(OpenGLRenderer*);
+
+private:
+    bool mIsTiled;
+};
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif
