msmcobalt: import from LA.UM.5.7.r1 06.00.01.253.019

Bug: 31420007
Change-Id: I968f2a5ac70e83473ef2f80503235bd76fba4b29
Signed-off-by: Thierry Strudel <tstrudel@google.com>
diff --git a/Android.mk b/Android.mk
index c8a8098..d9aa722 100644
--- a/Android.mk
+++ b/Android.mk
@@ -18,6 +18,10 @@
           else
             ifneq ($(filter msm8996,$(TARGET_BOARD_PLATFORM)),)
               include $(call all-named-subdir-makefiles,msm8996)
+            else
+              ifneq ($(filter msmcobalt,$(TARGET_BOARD_PLATFORM)),)
+                include $(call all-named-subdir-makefiles,msmcobalt)
+              endif
             endif
           endif
         endif
diff --git a/msmcobalt/Android.mk b/msmcobalt/Android.mk
new file mode 100644
index 0000000..b8b893c
--- /dev/null
+++ b/msmcobalt/Android.mk
@@ -0,0 +1,21 @@
+sdm-libs := sdm/libs
+display-hals := libqservice libqdutils $(sdm-libs)/utils $(sdm-libs)/core
+
+ifneq ($(TARGET_IS_HEADLESS), true)
+    display-hals += libcopybit liblight libmemtrack hdmi_cec \
+                    $(sdm-libs)/hwc $(sdm-libs)/hwc2
+endif
+
+ifneq ($(TARGET_USES_GRALLOC1), true)
+    display-hals += libgralloc
+else
+    display-hals += libgralloc1
+endif
+
+ifeq ($(call is-vendor-board-platform,QCOM),true)
+    include $(call all-named-subdir-makefiles,$(display-hals))
+else
+ifneq ($(filter msm% apq%,$(TARGET_BOARD_PLATFORM)),)
+    include $(call all-named-subdir-makefiles,$(display-hals))
+endif
+endif
diff --git a/msmcobalt/common.mk b/msmcobalt/common.mk
new file mode 100644
index 0000000..e49c8c2
--- /dev/null
+++ b/msmcobalt/common.mk
@@ -0,0 +1,75 @@
+#Common headers
+display_top := $(call my-dir)
+
+use_hwc2 := false
+ifeq ($(TARGET_USES_HWC2), true)
+    use_hwc2 := true
+endif
+
+common_includes := $(display_top)/libqdutils
+common_includes += $(display_top)/libqservice
+ifneq ($(TARGET_IS_HEADLESS), true)
+    common_includes += $(display_top)/libcopybit
+endif
+
+common_includes += $(display_top)/sdm/include
+
+common_header_export_path := qcom/display
+
+#Common libraries external to display HAL
+common_libs := liblog libutils libcutils libhardware
+
+ifeq ($(TARGET_IS_HEADLESS), true)
+    LOCAL_CLANG := false
+else
+    LOCAL_CLANG := true
+endif
+
+#Common C flags
+common_flags := -DDEBUG_CALC_FPS -Wno-missing-field-initializers
+common_flags += -Wconversion -Wall -Werror -std=c++11
+ifneq ($(TARGET_USES_GRALLOC1), true)
+    common_flags += -isystem $(display_top)/libgralloc
+else
+    common_flags += -isystem $(display_top)/libgralloc1
+endif
+
+ifeq ($(TARGET_USES_POST_PROCESSING),true)
+    common_flags     += -DUSES_POST_PROCESSING
+    common_includes  += $(TARGET_OUT_HEADERS)/pp/inc
+endif
+
+ifeq ($(ARCH_ARM_HAVE_NEON),true)
+    common_flags += -D__ARM_HAVE_NEON
+endif
+
+ifeq ($(call is-board-platform-in-list, $(MSM_VIDC_TARGET_LIST)), true)
+    common_flags += -DVENUS_COLOR_FORMAT
+endif
+
+ifeq ($(call is-board-platform-in-list, $(MASTER_SIDE_CP_TARGET_LIST)), true)
+    common_flags += -DMASTER_SIDE_CP
+endif
+
+common_deps  :=
+kernel_includes :=
+
+# Executed only on QCOM BSPs
+# ifeq ($(TARGET_USES_QCOM_BSP),true)
+# Enable QCOM Display features
+#    common_flags += -DQTI_BSP
+# endif
+
+ifeq ($(TARGET_IS_HEADLESS),true)
+    common_flags += -DTARGET_HEADLESS
+endif
+
+ifeq ($(TARGET_COMPILE_WITH_MSM_KERNEL),true)
+# This check is to pick the kernel headers from the right location.
+# If the macro above is defined, we make the assumption that we have the kernel
+# available in the build tree.
+# If the macro is not present, the headers are picked from hardware/qcom/msmXXXX
+# failing which, they are picked from bionic.
+    common_deps += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+    kernel_includes += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+endif
diff --git a/msmcobalt/hdmi_cec/Android.mk b/msmcobalt/hdmi_cec/Android.mk
new file mode 100644
index 0000000..3b794e3
--- /dev/null
+++ b/msmcobalt/hdmi_cec/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH := $(call my-dir)
+include $(LOCAL_PATH)/../common.mk
+include $(CLEAR_VARS)
+
+LOCAL_MODULE                  := hdmi_cec.$(TARGET_BOARD_PLATFORM)
+LOCAL_MODULE_RELATIVE_PATH    := hw
+LOCAL_MODULE_TAGS             := optional
+LOCAL_C_INCLUDES              := $(common_includes)
+LOCAL_SHARED_LIBRARIES        := $(common_libs) libqservice libbinder libqdutils
+
+LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdhdmi_cec\" -Wno-sign-conversion
+LOCAL_CLANG                   := true
+LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
+LOCAL_SRC_FILES               := qhdmi_cec.cpp \
+                                 QHDMIClient.cpp
+include $(BUILD_SHARED_LIBRARY)
diff --git a/msmcobalt/hdmi_cec/QHDMIClient.cpp b/msmcobalt/hdmi_cec/QHDMIClient.cpp
new file mode 100644
index 0000000..2b2b1e6
--- /dev/null
+++ b/msmcobalt/hdmi_cec/QHDMIClient.cpp
@@ -0,0 +1,66 @@
+/*
+* Copyright (c) 2014 The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of The Linux Foundation. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define DEBUG 0
+#include <QServiceUtils.h>
+#include "QHDMIClient.h"
+
+using namespace android;
+using namespace qhdmicec;
+using namespace qService;
+
+namespace qClient {
+
+void QHDMIClient::binderDied(const wp<IBinder>& who __unused)
+{
+    ALOGW("%s: Display QService died", __FUNCTION__);
+}
+
+void QHDMIClient::onHdmiHotplug(int connected)
+{
+    ALOGD("%s: HDMI connected event connected: %d", __FUNCTION__, connected);
+    cec_hdmi_hotplug(mCtx, connected);
+}
+
+void QHDMIClient::onCECMessageRecieved(char *msg, ssize_t len)
+{
+    ALOGD_IF(DEBUG, "%s: CEC message received len: %zd", __FUNCTION__, len);
+    cec_receive_message(mCtx, msg, len);
+}
+
+void QHDMIClient::registerClient(sp<QHDMIClient>& client)
+{
+    sp<IServiceManager> sm = defaultServiceManager();
+    sp<IBinder> binder = sm->getService(String16("display.qservice"));
+    binder->linkToDeath(client);
+    mQService = interface_cast<IQService>(binder);
+    mQService->connect(interface_cast<IQHDMIClient>(client));
+}
+
+};
diff --git a/msmcobalt/hdmi_cec/QHDMIClient.h b/msmcobalt/hdmi_cec/QHDMIClient.h
new file mode 100644
index 0000000..9e54f2f
--- /dev/null
+++ b/msmcobalt/hdmi_cec/QHDMIClient.h
@@ -0,0 +1,57 @@
+/*
+* Copyright (c) 2014 The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of The Linux Foundation. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "IQHDMIClient.h"
+#include "qhdmi_cec.h"
+#include <IQService.h>
+
+namespace qClient {
+
+class QHDMIClient: public android::IBinder::DeathRecipient,
+    public BnQHDMIClient
+{
+public:
+    QHDMIClient() {}
+
+    virtual void binderDied(const android::wp<android::IBinder>& who);
+
+    virtual void onHdmiHotplug(int connected);
+
+    virtual void onCECMessageRecieved(char *msg, ssize_t len);
+
+    void setCECContext(qhdmicec::cec_context_t* ctx) { mCtx = ctx; }
+
+    void registerClient(android::sp<QHDMIClient>& client);
+
+private:
+    qhdmicec::cec_context_t* mCtx;
+    android::sp<qService::IQService> mQService;
+
+};
+};
diff --git a/msmcobalt/hdmi_cec/qhdmi_cec.cpp b/msmcobalt/hdmi_cec/qhdmi_cec.cpp
new file mode 100644
index 0000000..f84cf80
--- /dev/null
+++ b/msmcobalt/hdmi_cec/qhdmi_cec.cpp
@@ -0,0 +1,518 @@
+/*
+* Copyright (c) 2014, 2016, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of The Linux Foundation. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define DEBUG 0
+#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
+#include <cstdlib>
+#include <cutils/log.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <hardware/hdmi_cec.h>
+#include <utils/Trace.h>
+#include "qhdmi_cec.h"
+#include "QHDMIClient.h"
+
+namespace qhdmicec {
+
+const int NUM_HDMI_PORTS = 1;
+const int MAX_SYSFS_DATA = 128;
+const int MAX_CEC_FRAME_SIZE = 20;
+const int MAX_SEND_MESSAGE_RETRIES = 1;
+
+enum {
+    LOGICAL_ADDRESS_SET   =  1,
+    LOGICAL_ADDRESS_UNSET = -1,
+};
+
+// Offsets of members of struct hdmi_cec_msg
+// drivers/video/msm/mdss/mdss_hdmi_cec.c
+// XXX: Get this from a driver header
+enum {
+    CEC_OFFSET_SENDER_ID,
+    CEC_OFFSET_RECEIVER_ID,
+    CEC_OFFSET_OPCODE,
+    CEC_OFFSET_OPERAND,
+    CEC_OFFSET_FRAME_LENGTH = 17,
+    CEC_OFFSET_RETRANSMIT,
+};
+
+//Forward declarations
+static void cec_close_context(cec_context_t* ctx __unused);
+static int cec_enable(cec_context_t *ctx, int enable);
+static int cec_is_connected(const struct hdmi_cec_device* dev, int port_id);
+
+static ssize_t read_node(const char *path, char *data)
+{
+    ssize_t err = 0;
+    FILE *fp = NULL;
+    err = access(path, R_OK);
+    if (!err) {
+        fp = fopen(path, "r");
+        if (fp) {
+            err = fread(data, sizeof(char), MAX_SYSFS_DATA ,fp);
+            fclose(fp);
+        }
+    }
+    return err;
+}
+
+static ssize_t write_node(const char *path, const char *data, size_t len)
+{
+    ssize_t err = 0;
+    int fd = -1;
+    err = access(path, W_OK);
+    if (!err) {
+        fd = open(path, O_WRONLY);
+        errno = 0;
+        err = write(fd, data, len);
+        if (err < 0) {
+            err = -errno;
+        }
+        close(fd);
+    } else {
+        ALOGE("%s: Failed to access path: %s error: %s",
+                __FUNCTION__, path, strerror(errno));
+        err = -errno;
+    }
+    return err;
+}
+
+// Helper function to write integer values to the full sysfs path
+static ssize_t write_int_to_node(cec_context_t *ctx,
+        const char *path_postfix,
+        const int value)
+{
+    char sysfs_full_path[MAX_PATH_LENGTH];
+    char sysfs_data[MAX_SYSFS_DATA];
+    snprintf(sysfs_data, sizeof(sysfs_data), "%d",value);
+    snprintf(sysfs_full_path,sizeof(sysfs_full_path), "%s/%s",
+            ctx->fb_sysfs_path, path_postfix);
+    ssize_t err = write_node(sysfs_full_path, sysfs_data, strlen(sysfs_data));
+    return err;
+}
+
+static void hex_to_string(const char *msg, ssize_t len, char *str)
+{
+    //Functions assumes sufficient memory in str
+    char *ptr = str;
+    for(int i=0; i < len ; i++) {
+        ptr += snprintf(ptr, 3,  "%02X", msg[i]);
+        // Overwrite null termination of snprintf in all except the last byte
+        if (i < len - 1)
+            *ptr = ':';
+        ptr++;
+    }
+}
+
+static ssize_t cec_get_fb_node_number(cec_context_t *ctx)
+{
+    //XXX: Do this from a common utility library across the display HALs
+    const int MAX_FB_DEVICES = 2;
+    ssize_t len = 0;
+    char fb_type_path[MAX_PATH_LENGTH];
+    char fb_type[MAX_SYSFS_DATA];
+    const char *dtv_panel_str = "dtv panel";
+
+    for(int num = 0; num < MAX_FB_DEVICES; num++) {
+        snprintf(fb_type_path, sizeof(fb_type_path),"%s%d/msm_fb_type",
+                SYSFS_BASE,num);
+        ALOGD_IF(DEBUG, "%s: num: %d fb_type_path: %s", __FUNCTION__, num, fb_type_path);
+        len = read_node(fb_type_path, fb_type);
+        ALOGD_IF(DEBUG, "%s: fb_type:%s", __FUNCTION__, fb_type);
+        if(len > 0 && (strncmp(fb_type, dtv_panel_str, strlen(dtv_panel_str)) == 0)){
+            ALOGD_IF(DEBUG, "%s: Found DTV panel at fb%d", __FUNCTION__, num);
+            ctx->fb_num = num;
+            snprintf(ctx->fb_sysfs_path, sizeof(ctx->fb_sysfs_path),
+                    "%s%d", SYSFS_BASE, num);
+            break;
+        }
+    }
+    if (len < 0)
+        return len;
+    else
+        return 0;
+}
+
+static int cec_add_logical_address(const struct hdmi_cec_device* dev,
+        cec_logical_address_t addr)
+{
+    if (addr <  CEC_ADDR_TV || addr > CEC_ADDR_BROADCAST) {
+        ALOGE("%s: Received invalid address: %d ", __FUNCTION__, addr);
+        return -EINVAL;
+    }
+    cec_context_t* ctx = (cec_context_t*)(dev);
+    ctx->logical_address[addr] = LOGICAL_ADDRESS_SET;
+
+    //XXX: We can get multiple logical addresses here but we can only send one
+    //to the driver. Store locally for now
+    ssize_t err = write_int_to_node(ctx, "cec/logical_addr", addr);
+    ALOGI("%s: Allocated logical address: %d ", __FUNCTION__, addr);
+    return (int) err;
+}
+
+static void cec_clear_logical_address(const struct hdmi_cec_device* dev)
+{
+    cec_context_t* ctx = (cec_context_t*)(dev);
+    memset(ctx->logical_address, LOGICAL_ADDRESS_UNSET,
+            sizeof(ctx->logical_address));
+    //XXX: Find logical_addr that needs to be reset
+    write_int_to_node(ctx, "cec/logical_addr", 15);
+    ALOGD_IF(DEBUG, "%s: Cleared logical addresses", __FUNCTION__);
+}
+
+static int cec_get_physical_address(const struct hdmi_cec_device* dev,
+        uint16_t* addr)
+{
+    cec_context_t* ctx = (cec_context_t*)(dev);
+    char pa_path[MAX_PATH_LENGTH];
+    char pa_data[MAX_SYSFS_DATA];
+    snprintf (pa_path, sizeof(pa_path),"%s/pa",
+            ctx->fb_sysfs_path);
+    int err = (int) read_node(pa_path, pa_data);
+    *addr = (uint16_t) atoi(pa_data);
+    ALOGD_IF(DEBUG, "%s: Physical Address: 0x%x", __FUNCTION__, *addr);
+    if (err < 0)
+        return err;
+    else
+        return 0;
+}
+
+static int cec_send_message(const struct hdmi_cec_device* dev,
+        const cec_message_t* msg)
+{
+    ATRACE_CALL();
+    if(cec_is_connected(dev, 0) <= 0)
+        return HDMI_RESULT_FAIL;
+
+    cec_context_t* ctx = (cec_context_t*)(dev);
+    ALOGD_IF(DEBUG, "%s: initiator: %d destination: %d length: %u",
+            __FUNCTION__, msg->initiator, msg->destination,
+            (uint32_t) msg->length);
+
+    // Dump message received from framework
+    char dump[128];
+    if(msg->length > 0) {
+        hex_to_string((char*)msg->body, msg->length, dump);
+        ALOGD_IF(DEBUG, "%s: message from framework: %s", __FUNCTION__, dump);
+    }
+
+    char write_msg_path[MAX_PATH_LENGTH];
+    char write_msg[MAX_CEC_FRAME_SIZE];
+    memset(write_msg, 0, sizeof(write_msg));
+    // See definition of struct hdmi_cec_msg in driver code
+    // drivers/video/msm/mdss/mdss_hdmi_cec.c
+    // Write header block
+    // XXX: Include this from header in kernel
+    write_msg[CEC_OFFSET_SENDER_ID] = msg->initiator;
+    write_msg[CEC_OFFSET_RECEIVER_ID] = msg->destination;
+    //Kernel splits opcode/operand, but Android sends it in one byte array
+    write_msg[CEC_OFFSET_OPCODE] = msg->body[0];
+    if(msg->length > 1) {
+        memcpy(&write_msg[CEC_OFFSET_OPERAND], &msg->body[1],
+                sizeof(char)*(msg->length - 1));
+    }
+    //msg length + initiator + destination
+    write_msg[CEC_OFFSET_FRAME_LENGTH] = (unsigned char) (msg->length + 1);
+    hex_to_string(write_msg, sizeof(write_msg), dump);
+    ALOGD_IF(DEBUG, "%s: message to driver: %s", __FUNCTION__, dump);
+    snprintf(write_msg_path, sizeof(write_msg_path), "%s/cec/wr_msg",
+            ctx->fb_sysfs_path);
+    int retry_count = 0;
+    ssize_t err = 0;
+    //HAL spec requires us to retry at least once.
+    while (true) {
+        err = write_node(write_msg_path, write_msg, sizeof(write_msg));
+        retry_count++;
+        if (err == -EAGAIN && retry_count <= MAX_SEND_MESSAGE_RETRIES) {
+            ALOGE("%s: CEC line busy, retrying", __FUNCTION__);
+        } else {
+            break;
+        }
+    }
+
+    if (err < 0) {
+       if (err == -ENXIO) {
+           ALOGI("%s: No device exists with the destination address",
+                   __FUNCTION__);
+           return HDMI_RESULT_NACK;
+       } else if (err == -EAGAIN) {
+            ALOGE("%s: CEC line is busy, max retry count exceeded",
+                    __FUNCTION__);
+            return HDMI_RESULT_BUSY;
+        } else {
+            return HDMI_RESULT_FAIL;
+            ALOGE("%s: Failed to send CEC message err: %zd - %s",
+                    __FUNCTION__, err, strerror(int(-err)));
+        }
+    } else {
+        ALOGD_IF(DEBUG, "%s: Sent CEC message - %zd bytes written",
+                __FUNCTION__, err);
+        return HDMI_RESULT_SUCCESS;
+    }
+}
+
+void cec_receive_message(cec_context_t *ctx, char *msg, ssize_t len)
+{
+    if(!ctx->system_control)
+        return;
+
+    char dump[128];
+    if(len > 0) {
+        hex_to_string(msg, len, dump);
+        ALOGD_IF(DEBUG, "%s: Message from driver: %s", __FUNCTION__, dump);
+    }
+
+    hdmi_event_t event;
+    event.type = HDMI_EVENT_CEC_MESSAGE;
+    event.dev = (hdmi_cec_device *) ctx;
+    // Remove initiator/destination from this calculation
+    event.cec.length = msg[CEC_OFFSET_FRAME_LENGTH] - 1;
+    event.cec.initiator = (cec_logical_address_t) msg[CEC_OFFSET_SENDER_ID];
+    event.cec.destination = (cec_logical_address_t) msg[CEC_OFFSET_RECEIVER_ID];
+    //Copy opcode and operand
+    memcpy(event.cec.body, &msg[CEC_OFFSET_OPCODE], event.cec.length);
+    hex_to_string((char *) event.cec.body, event.cec.length, dump);
+    ALOGD_IF(DEBUG, "%s: Message to framework: %s", __FUNCTION__, dump);
+    ctx->callback.callback_func(&event, ctx->callback.callback_arg);
+}
+
+void cec_hdmi_hotplug(cec_context_t *ctx, int connected)
+{
+    //Ignore unplug events when system control is disabled
+    if(!ctx->system_control && connected == 0)
+        return;
+    hdmi_event_t event;
+    event.type = HDMI_EVENT_HOT_PLUG;
+    event.dev = (hdmi_cec_device *) ctx;
+    event.hotplug.connected = connected ? HDMI_CONNECTED : HDMI_NOT_CONNECTED;
+    ctx->callback.callback_func(&event, ctx->callback.callback_arg);
+}
+
+static void cec_register_event_callback(const struct hdmi_cec_device* dev,
+            event_callback_t callback, void* arg)
+{
+    ALOGD_IF(DEBUG, "%s: Registering callback", __FUNCTION__);
+    cec_context_t* ctx = (cec_context_t*)(dev);
+    ctx->callback.callback_func = callback;
+    ctx->callback.callback_arg = arg;
+}
+
+static void cec_get_version(const struct hdmi_cec_device* dev, int* version)
+{
+    cec_context_t* ctx = (cec_context_t*)(dev);
+    *version = ctx->version;
+    ALOGD_IF(DEBUG, "%s: version: %d", __FUNCTION__, *version);
+}
+
+static void cec_get_vendor_id(const struct hdmi_cec_device* dev,
+        uint32_t* vendor_id)
+{
+    cec_context_t* ctx = (cec_context_t*)(dev);
+    *vendor_id = ctx->vendor_id;
+    ALOGD_IF(DEBUG, "%s: vendor id: %u", __FUNCTION__, *vendor_id);
+}
+
+static void cec_get_port_info(const struct hdmi_cec_device* dev,
+            struct hdmi_port_info* list[], int* total)
+{
+    ALOGD_IF(DEBUG, "%s: Get port info", __FUNCTION__);
+    cec_context_t* ctx = (cec_context_t*)(dev);
+    *total = NUM_HDMI_PORTS;
+    *list = ctx->port_info;
+}
+
+static void cec_set_option(const struct hdmi_cec_device* dev, int flag,
+        int value)
+{
+    cec_context_t* ctx = (cec_context_t*)(dev);
+    switch (flag) {
+        case HDMI_OPTION_WAKEUP:
+            ALOGD_IF(DEBUG, "%s: Wakeup: value: %d", __FUNCTION__, value);
+            //XXX
+            break;
+        case HDMI_OPTION_ENABLE_CEC:
+            ALOGD_IF(DEBUG, "%s: Enable CEC: value: %d", __FUNCTION__, value);
+            cec_enable(ctx, value? 1 : 0);
+            break;
+        case HDMI_OPTION_SYSTEM_CEC_CONTROL:
+            ALOGD_IF(DEBUG, "%s: system_control: value: %d",
+                    __FUNCTION__, value);
+            ctx->system_control = !!value;
+            break;
+    }
+}
+
+static void cec_set_audio_return_channel(const struct hdmi_cec_device* dev,
+        int port, int flag)
+{
+    cec_context_t* ctx = (cec_context_t*)(dev);
+    ctx->arc_enabled = flag ? true : false;
+    ALOGD_IF(DEBUG, "%s: ARC flag: %d port: %d", __FUNCTION__, flag, port);
+}
+
+static int cec_is_connected(const struct hdmi_cec_device* dev, int port_id)
+{
+    // Ignore port_id since we have only one port
+    int connected = 0;
+    cec_context_t* ctx = (cec_context_t*)(dev);
+    char connected_path[MAX_PATH_LENGTH];
+    char connected_data[MAX_SYSFS_DATA];
+    snprintf (connected_path, sizeof(connected_path),"%s/connected",
+            ctx->fb_sysfs_path);
+    ssize_t err = read_node(connected_path, connected_data);
+    connected = atoi(connected_data);
+
+    ALOGD_IF(DEBUG, "%s: HDMI at port %d is - %s", __FUNCTION__, port_id,
+            connected ? "connected":"disconnected");
+    if (err < 0)
+        return (int) err;
+    else
+        return connected;
+}
+
+static int cec_device_close(struct hw_device_t *dev)
+{
+    ALOGD_IF(DEBUG, "%s: Close CEC HAL ", __FUNCTION__);
+    if (!dev) {
+        ALOGE("%s: NULL device pointer", __FUNCTION__);
+        return -EINVAL;
+    }
+    cec_context_t* ctx = (cec_context_t*)(dev);
+    cec_close_context(ctx);
+    free(dev);
+    return 0;
+}
+
+static int cec_enable(cec_context_t *ctx, int enable)
+{
+    ssize_t err;
+    // Enable CEC
+    int value = enable ? 0x3 : 0x0;
+    err = write_int_to_node(ctx, "cec/enable", value);
+    if(err < 0) {
+        ALOGE("%s: Failed to toggle CEC: enable: %d",
+                __FUNCTION__, enable);
+        return (int) err;
+    }
+    ctx->enabled = enable;
+    return 0;
+}
+
+static void cec_init_context(cec_context_t *ctx)
+{
+    ALOGD_IF(DEBUG, "%s: Initializing context", __FUNCTION__);
+    cec_get_fb_node_number(ctx);
+
+    //Initialize ports - We support only one output port
+    ctx->port_info = new hdmi_port_info[NUM_HDMI_PORTS];
+    ctx->port_info[0].type = HDMI_OUTPUT;
+    ctx->port_info[0].port_id = 1;
+    ctx->port_info[0].cec_supported = 1;
+    //XXX: Enable ARC if supported
+    ctx->port_info[0].arc_supported = 0;
+    cec_get_physical_address((hdmi_cec_device *) ctx,
+            &ctx->port_info[0].physical_address );
+
+    ctx->version = 0x4;
+    ctx->vendor_id = 0xA47733;
+    cec_clear_logical_address((hdmi_cec_device_t*)ctx);
+
+    //Set up listener for HDMI events
+    ctx->disp_client = new qClient::QHDMIClient();
+    ctx->disp_client->setCECContext(ctx);
+    ctx->disp_client->registerClient(ctx->disp_client);
+
+    //Enable CEC - framework expects it to be enabled by default
+    cec_enable(ctx, true);
+
+    ALOGD("%s: CEC enabled", __FUNCTION__);
+}
+
+static void cec_close_context(cec_context_t* ctx __unused)
+{
+    ALOGD("%s: Closing context", __FUNCTION__);
+}
+
+static int cec_device_open(const struct hw_module_t* module,
+        const char* name,
+        struct hw_device_t** device)
+{
+    ALOGD_IF(DEBUG, "%s: name: %s", __FUNCTION__, name);
+    int status = -EINVAL;
+    if (!strcmp(name, HDMI_CEC_HARDWARE_INTERFACE )) {
+        struct cec_context_t *dev;
+        dev = (cec_context_t *) calloc (1, sizeof(*dev));
+        if (dev) {
+            cec_init_context(dev);
+
+            //Setup CEC methods
+            dev->device.common.tag       = HARDWARE_DEVICE_TAG;
+            dev->device.common.version   = HDMI_CEC_DEVICE_API_VERSION_1_0;
+            dev->device.common.module    = const_cast<hw_module_t* >(module);
+            dev->device.common.close     = cec_device_close;
+            dev->device.add_logical_address = cec_add_logical_address;
+            dev->device.clear_logical_address = cec_clear_logical_address;
+            dev->device.get_physical_address = cec_get_physical_address;
+            dev->device.send_message = cec_send_message;
+            dev->device.register_event_callback = cec_register_event_callback;
+            dev->device.get_version = cec_get_version;
+            dev->device.get_vendor_id = cec_get_vendor_id;
+            dev->device.get_port_info = cec_get_port_info;
+            dev->device.set_option = cec_set_option;
+            dev->device.set_audio_return_channel = cec_set_audio_return_channel;
+            dev->device.is_connected = cec_is_connected;
+
+            *device = &dev->device.common;
+            status = 0;
+        } else {
+            status = -EINVAL;
+        }
+    }
+    return status;
+}
+}; //namespace qhdmicec
+
+// Standard HAL module, should be outside qhdmicec namespace
+static struct hw_module_methods_t cec_module_methods = {
+        .open = qhdmicec::cec_device_open
+};
+
+hdmi_module_t HAL_MODULE_INFO_SYM = {
+    .common = {
+        .tag = HARDWARE_MODULE_TAG,
+        .version_major = 1,
+        .version_minor = 0,
+        .id = HDMI_CEC_HARDWARE_MODULE_ID,
+        .name = "QTI HDMI CEC module",
+        .author = "The Linux Foundation",
+        .methods = &cec_module_methods,
+    }
+};
+
+
diff --git a/msmcobalt/hdmi_cec/qhdmi_cec.h b/msmcobalt/hdmi_cec/qhdmi_cec.h
new file mode 100644
index 0000000..aa97620
--- /dev/null
+++ b/msmcobalt/hdmi_cec/qhdmi_cec.h
@@ -0,0 +1,74 @@
+/*
+* Copyright (c) 2014 The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of The Linux Foundation. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef QHDMI_CEC_H
+#define QHDMI_CEC_H
+
+#include <hardware/hdmi_cec.h>
+#include <utils/RefBase.h>
+
+namespace qClient {
+    class QHDMIClient;
+};
+
+namespace qhdmicec {
+
+#define SYSFS_BASE  "/sys/class/graphics/fb"
+#define MAX_PATH_LENGTH  128
+
+struct cec_callback_t {
+    // Function in HDMI service to call back on CEC messages
+    event_callback_t callback_func;
+    // This stores the object to pass back to the framework
+    void* callback_arg;
+
+};
+
+struct cec_context_t {
+    hdmi_cec_device_t device;    // Device for HW module
+    cec_callback_t callback;     // Struct storing callback object
+    bool enabled;
+    bool arc_enabled;
+    bool system_control;         // If true, HAL/driver handle CEC messages
+    int fb_num;                  // Framebuffer node for HDMI
+    char fb_sysfs_path[MAX_PATH_LENGTH];
+    hdmi_port_info *port_info;   // HDMI port info
+
+    // Logical address is stored in an array, the index of the array is the
+    // logical address and the value in the index shows whether it is set or not
+    int logical_address[CEC_ADDR_BROADCAST];
+    int version;
+    uint32_t vendor_id;
+    android::sp<qClient::QHDMIClient> disp_client;
+};
+
+void cec_receive_message(cec_context_t *ctx, char *msg, ssize_t len);
+void cec_hdmi_hotplug(cec_context_t *ctx, int connected);
+
+}; //namespace
+#endif /* end of include guard: QHDMI_CEC_H */
diff --git a/msmcobalt/libcopybit/Android.mk b/msmcobalt/libcopybit/Android.mk
new file mode 100644
index 0000000..a165826
--- /dev/null
+++ b/msmcobalt/libcopybit/Android.mk
@@ -0,0 +1,49 @@
+# 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 $(LOCAL_PATH)/../common.mk
+include $(CLEAR_VARS)
+
+LOCAL_COPY_HEADERS_TO         := $(common_header_export_path)
+LOCAL_COPY_HEADERS            := copybit.h copybit_priv.h c2d2.h
+#Copy the headers regardless of whether copybit is built
+include $(BUILD_COPY_HEADERS)
+
+LOCAL_MODULE                  := copybit.$(TARGET_BOARD_PLATFORM)
+LOCAL_MODULE_RELATIVE_PATH    := hw
+LOCAL_MODULE_TAGS             := optional
+LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes)
+LOCAL_SHARED_LIBRARIES        := $(common_libs) libdl libmemalloc
+LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdcopybit\" -Wno-sign-conversion
+LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
+LOCAL_CLANG                   := true
+
+ifeq ($(TARGET_USES_C2D_COMPOSITION),true)
+    LOCAL_CFLAGS += -DCOPYBIT_Z180=1 -DC2D_SUPPORT_DISPLAY=1
+    LOCAL_SRC_FILES := copybit_c2d.cpp software_converter.cpp
+    include $(BUILD_SHARED_LIBRARY)
+else
+    ifneq ($(call is-chipset-in-board-platform,msm7630),true)
+        ifeq ($(call is-board-platform-in-list,$(MSM7K_BOARD_PLATFORMS)),true)
+            LOCAL_CFLAGS += -DCOPYBIT_MSM7K=1
+            LOCAL_SRC_FILES := software_converter.cpp copybit.cpp
+            include $(BUILD_SHARED_LIBRARY)
+        endif
+        ifeq ($(call is-board-platform-in-list, msm8610 msm8909),true)
+            LOCAL_SRC_FILES := software_converter.cpp copybit.cpp
+            include $(BUILD_SHARED_LIBRARY)
+        endif
+    endif
+endif
diff --git a/msmcobalt/libcopybit/MODULE_LICENSE_APACHE2 b/msmcobalt/libcopybit/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/msmcobalt/libcopybit/MODULE_LICENSE_APACHE2
diff --git a/msmcobalt/libcopybit/NOTICE b/msmcobalt/libcopybit/NOTICE
new file mode 100644
index 0000000..9c1e63a
--- /dev/null
+++ b/msmcobalt/libcopybit/NOTICE
@@ -0,0 +1,189 @@
+
+   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.
+
+   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/msmcobalt/libcopybit/c2d2.h b/msmcobalt/libcopybit/c2d2.h
new file mode 100644
index 0000000..315a3ba
--- /dev/null
+++ b/msmcobalt/libcopybit/c2d2.h
@@ -0,0 +1,685 @@
+/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef __c2d2_h_
+#define __c2d2_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef C2D_API
+#define C2D_API /* define API export as needed */
+#endif
+#if !defined(int32) && !defined(_INT32_DEFINED)
+typedef int                     int32;
+#define _INT32_DEFINED
+#endif
+#if !defined(uint32) && !defined(_UINT32_DEFINED)
+typedef unsigned int            uint32;
+#define _UINT32_DEFINED
+#endif
+
+/*****************************************************************************/
+/*********************** Blit definitions *****************************/
+/*****************************************************************************/
+
+/* Status codes, returned by any blit function */
+typedef enum {
+    C2D_STATUS_OK              = 0,
+    C2D_STATUS_NOT_SUPPORTED   = 1,
+    C2D_STATUS_OUT_OF_MEMORY   = 2,
+    C2D_STATUS_INVALID_PARAM   = 3,
+    C2D_STATUS_SURFACE_IN_USE  = 4,
+} C2D_STATUS;
+
+
+/* Definitions of color format modes, used together with color formats */
+typedef enum {
+    C2D_FORMAT_PACK_INTO_32BIT   = (1 <<  8), /* pack into dword if set */
+    C2D_FORMAT_SWAP_ENDIANNESS   = (1 <<  9), /* swaps the order */
+    C2D_FORMAT_LINEAR_SPACE      = (1 << 10), /* linear color space */
+    C2D_FORMAT_PREMULTIPLIED     = (1 << 11), /* alpha premultiplied */
+    C2D_FORMAT_INVERT_ALPHA      = (1 << 12), /* inverts alpha */
+    C2D_FORMAT_DISABLE_ALPHA     = (1 << 13), /* disables alpha */
+    C2D_FORMAT_INTERLACED        = (1 << 14), /* YUV line-interlaced */
+    C2D_FORMAT_TRANSPARENT       = (1 << 15), /* YUV 1-bit alpha in Y */
+    C2D_FORMAT_MACROTILED        = (1 << 16), /* tiled in macro level */
+    C2D_FORMAT_TILED_4x4         = (1 << 17), /* 4x4 tiled format */
+    C2D_FORMAT_SWAP_RB           = (1 << 18), /* Swap R & B color components */
+    C2D_FORMAT_UBWC_COMPRESSED   = (1 << 23), /* UBWC compressed format */
+} C2D_FORMAT_MODE;
+
+/* Definitions of supported RGB formats, used in C2D_RGB_SURFACE_DEF.
+ * The bits of each color channel are packed into a machine word
+ * representing a single pixel from left to right (MSB to LSB) in the
+ * order indicated by format name. For the sub-byte formats the pixels
+ * are packed into bytes from left to right (MSbit to LSBit).
+ * If the C2D_FORMAT_PACK_INTO_32BIT bit is set, the minimal
+ * machine word used for pixel storage is 32-bit and the whole word
+ * is reversed if endianness is swapped.
+ * If the C2D_FORMAT_SWAP_ENDIANNESS bit is set, the order within a
+ * minimal machine word representing a pixel
+ * is reversed for both sub-byte and multi-byte formats.
+ * If the C2D_FORMAT_LINEAR_SPACE bit is set, the color space of
+ * the formats below is considered linear, if applicable.
+ * If the C2D_FORMAT_PREMULTIPLIED bit is set, the color channels
+ * are premultiplied with the alpha, if applicable.
+ * If the C2D_FORMAT_INVERT_ALPHA bit is set, the alpha interpretation
+ * is inverted: 0 - opaque, 1 - transparent, if applicable.
+ * If the C2D_FORMAT_DISABLE_ALPHA bit is set, the alpha channel serves
+ * as a placeholder and is ignored during blit, if applicable.
+ * If the C2D_FORMAT_MACROTILED bit is set, the surface is in the
+ * tiled format : 64x32 for 8bpp, 32x32 for 16bpp formats  */
+typedef enum {
+    C2D_COLOR_FORMAT_1            = 0,   /* 1-bit alpha/color expansion */
+
+    C2D_COLOR_FORMAT_2_PALETTE    = 1,   /* 2-bit indices for palette */
+    C2D_COLOR_FORMAT_4_PALETTE    = 2,   /* 4-bit indices for palette */
+    C2D_COLOR_FORMAT_8_PALETTE    = 3,   /* 8-bit indices for palette */
+
+    C2D_COLOR_FORMAT_2_L          = 4,   /* 2-bit grayscale */
+    C2D_COLOR_FORMAT_4_L          = 5,   /* 4-bit grayscale */
+    C2D_COLOR_FORMAT_8_L          = 6,   /* 8-bit grayscale */
+
+    C2D_COLOR_FORMAT_2_A          = 7,   /* 2-bit alpha only */
+    C2D_COLOR_FORMAT_4_A          = 8,   /* 4-bit alpha only */
+    C2D_COLOR_FORMAT_8_A          = 9,   /* 8-bit alpha only */
+
+    C2D_COLOR_FORMAT_444_RGB      = 10,  /* 12-bit colors */
+    C2D_COLOR_FORMAT_565_RGB      = 11,  /* 16-bit colors */
+    C2D_COLOR_FORMAT_888_RGB      = 12,  /* 24-bit colors */
+
+    C2D_COLOR_FORMAT_1555_ARGB    = 13,  /* 16-bit colors (1-bit alpha) */
+    C2D_COLOR_FORMAT_4444_ARGB    = 14,  /* 16-bit colors (4-bit alpha) */
+    C2D_COLOR_FORMAT_8565_ARGB    = 15,  /* 24-bit colors (8-bit alpha) */
+    C2D_COLOR_FORMAT_8888_ARGB    = 16,  /* 32-bit colors (8-bit alpha) */
+
+    C2D_COLOR_FORMAT_5551_RGBA    = 17,  /* 16-bit colors (1-bit alpha) */
+    C2D_COLOR_FORMAT_4444_RGBA    = 18,  /* 16-bit colors (4-bit alpha) */
+    C2D_COLOR_FORMAT_5658_RGBA    = 19,  /* 24-bit colors (8-bit alpha) */
+    C2D_COLOR_FORMAT_8888_RGBA    = 20,  /* 32-bit colors (8-bit alpha) */
+
+    /* derived RGB color formats (base format + mode bits) */
+
+} C2D_RGB_FORMAT;
+
+/* Definitions of supported YUV formats, used in C2D_YUV_SURFACE_DEF.
+ * Each of Y,U,V channels usually takes 1 byte and therefore is
+ * individually addressable. The definitions below show how Y,U,V
+ * channels are packed into macropixels for each particular format.
+ * The order is from left (smaller byte addresses) to right (larger
+ * byte addresses). The first three digits (4xx) denote the chroma
+ * subsampling in standard YUV notation. The digits in the macropixel
+ * denote that the whole block (from the previous digit or from the
+ * beginning) has to be repeated the number of times. Underscores
+ * between Y,U,V channels are used to describe separate planes for
+ * planar YUV formats. Formats are mapped to numbers so that future
+ * versions with various YUV permutations are easy to add.
+ * If the C2D_FORMAT_INTERLACED bit is set, the line order is
+ * interlaced: 0,2,4,...1,3,5... if applicable.
+ * If the C2D_FORMAT_TRANSPARENT bit is set, the least significant
+ * bit of Y channel serves as alpha: 0 - transparent, 1 - opaque. */
+typedef enum {
+    C2D_COLOR_FORMAT_411_YYUYYV   = 110, /* packed, 12-bit         */
+    C2D_COLOR_FORMAT_411_YUYYVY   = 111, /* packed, 12-bit         */
+    C2D_COLOR_FORMAT_411_UYYVYY   = 112, /* packed, 12-bit, "Y411" */
+    C2D_COLOR_FORMAT_411_YUYV2Y4  = 116, /* packed, 12-bit         */
+    C2D_COLOR_FORMAT_411_UYVY2Y4  = 117, /* packed, 12-bit, "Y41P" */
+
+    C2D_COLOR_FORMAT_422_YUYV     = 120, /* packed, 16-bit, "YUY2" */
+    C2D_COLOR_FORMAT_422_UYVY     = 121, /* packed, 16-bit, "UYVY" */
+    C2D_COLOR_FORMAT_422_YVYU     = 122, /* packed, 16-bit, "YVYU" */
+    C2D_COLOR_FORMAT_422_VYUY     = 123, /* packed, 16-bit         */
+
+    C2D_COLOR_FORMAT_444_YUV      = 130, /* packed, 24-bit         */
+    C2D_COLOR_FORMAT_444_UYV      = 131, /* packed, 24-bit, "IYU2" */
+    C2D_COLOR_FORMAT_444_AYUV     = 136, /* packed, 24-bit, "AYUV" */
+
+    C2D_COLOR_FORMAT_410_Y_UV     = 150, /* planar, Y + interleaved UV */
+    C2D_COLOR_FORMAT_411_Y_UV     = 151, /* planar, Y + interleaved UV */
+    C2D_COLOR_FORMAT_420_Y_UV     = 152, /* planar, Y + interleaved UV */
+    C2D_COLOR_FORMAT_422_Y_UV     = 153, /* planar, Y + interleaved UV */
+    C2D_COLOR_FORMAT_444_Y_UV     = 154, /* planar, Y + interleaved UV */
+
+    C2D_COLOR_FORMAT_410_Y_VU     = 160, /* planar, Y + interleaved VU */
+    C2D_COLOR_FORMAT_411_Y_VU     = 161, /* planar, Y + interleaved VU */
+    C2D_COLOR_FORMAT_420_Y_VU     = 162, /* planar, Y + interleaved VU */
+    C2D_COLOR_FORMAT_422_Y_VU     = 163, /* planar, Y + interleaved VU */
+    C2D_COLOR_FORMAT_444_Y_VU     = 164, /* planar, Y + interleaved VU */
+
+    C2D_COLOR_FORMAT_410_Y_U_V    = 170, /* planar, Y + U + V separate */
+    C2D_COLOR_FORMAT_411_Y_U_V    = 171, /* planar, Y + U + V separate */
+    C2D_COLOR_FORMAT_420_Y_V_U    = 172, /* planar, Y + V + U separate */
+    C2D_COLOR_FORMAT_420_Y_U_V    = 173, /* planar, Y + U + V separate */
+    C2D_COLOR_FORMAT_422_Y_U_V    = 174, /* planar, Y + U + V separate */
+    C2D_COLOR_FORMAT_444_Y_U_V    = 175, /* planar, Y + U + V separate */
+
+    C2D_COLOR_FORMAT_800_Y        = 190, /* planar, Y only, grayscale */
+
+    /* derived YUV color formats (base format + mode bits), FOURCC */
+
+    C2D_COLOR_FORMAT_411_Y411     = 112,
+    C2D_COLOR_FORMAT_411_Y41P     = 117,
+    C2D_COLOR_FORMAT_411_IY41     = 117 | (1 << 14),
+    C2D_COLOR_FORMAT_411_Y41T     = 117 | (1 << 15),
+
+    C2D_COLOR_FORMAT_422_YUY2     = 120,
+    C2D_COLOR_FORMAT_422_IUYV     = 121 | (1 << 14),
+    C2D_COLOR_FORMAT_422_Y42T     = 121 | (1 << 15),
+    C2D_COLOR_FORMAT_444_IYU2     = 131,
+
+    C2D_COLOR_FORMAT_420_NV12     = 152,
+    C2D_COLOR_FORMAT_420_NV21     = 162,
+
+    C2D_COLOR_FORMAT_410_YUV9     = 170,
+    C2D_COLOR_FORMAT_410_YVU9     = 170,
+    C2D_COLOR_FORMAT_411_Y41B     = 171,
+    C2D_COLOR_FORMAT_420_YV12     = 172,
+    C2D_COLOR_FORMAT_420_IYUV     = 173,
+    C2D_COLOR_FORMAT_420_I420     = 173,
+    C2D_COLOR_FORMAT_422_YV16     = 174,
+    C2D_COLOR_FORMAT_422_Y42B     = 174,
+
+    C2D_COLOR_FORMAT_800_Y800     = 190,
+
+} C2D_YUV_FORMAT;
+
+
+/* Configuration bits, used in the config_mask field of C2D_OBJECT struct */
+typedef enum {
+    C2D_SOURCE_RECT_BIT      = (1 <<  0), /* enables source_rect field */
+    C2D_MIRROR_H_BIT         = (1 <<  1), /* enables horizontal flipping */
+    C2D_MIRROR_V_BIT         = (1 <<  2), /* enables vertical flipping */
+    C2D_SOURCE_TILE_BIT      = (1 <<  3), /* enables source surface tiling */
+    C2D_TARGET_RECT_BIT      = (1 <<  4), /* enables target_rect field */
+    C2D_ROTATE_BIT           = (1 <<  5), /* enables all rotation fields */
+    C2D_SCISSOR_RECT_BIT     = (1 <<  6), /* enables scissor_rect field */
+    C2D_MASK_SURFACE_BIT     = (1 <<  7), /* enables mask_surface_id field */
+    C2D_MASK_ALIGN_BIT       = (1 <<  8), /* aligns mask to source_rect */
+    C2D_MASK_SCALE_BIT       = (1 <<  9), /* enables mask surface scaling */
+    C2D_MASK_TILE_BIT        = (1 << 10), /* enables mask surface tiling */
+    C2D_GLOBAL_ALPHA_BIT     = (1 << 11), /* enables global_alpha field */
+    C2D_COLOR_KEY_BIT        = (1 << 12), /* enables color_key field */
+    C2D_NO_PIXEL_ALPHA_BIT   = (1 << 13), /* disables source alpha channel */
+    C2D_NO_BILINEAR_BIT      = (1 << 14), /* disables bilinear on scaling */
+    C2D_NO_ANTIALIASING_BIT  = (1 << 15), /* disables antialiasing on edges */
+    C2D_DRAW_LINE_BIT        = (1 << 16), /* enables line drawing with source rectangle */
+    C2D_DRAW_LINE_NOLAST     = (1 << 17), /* disable last pixel draw for line */
+} C2D_SOURCE_CONFIG;
+
+
+/* Target configuration bits, defines rotation + mirroring.
+ * Mirror is applied prior to rotation if enabled. */
+typedef enum {
+    C2D_TARGET_MIRROR_H        = (1 << 0), /* horizontal flip */
+    C2D_TARGET_MIRROR_V        = (1 << 1), /* vertical flip */
+    C2D_TARGET_ROTATE_0        = (0 << 2), /* no rotation */
+    C2D_TARGET_ROTATE_90       = (1 << 2), /* 90 degree rotation */
+    C2D_TARGET_ROTATE_180      = (2 << 2), /* 180 degree rotation */
+    C2D_TARGET_ROTATE_270      = (3 << 2), /* 270 degree rotation, 90 + 180 */
+    C2D_TARGET_MASK_ALIGN      = (1 << 4), /* aligns mask to target scissor */
+    C2D_TARGET_MASK_SCALE      = (1 << 5), /* enables mask scaling */
+    C2D_TARGET_MASK_TILE       = (1 << 6), /* enables mask tiling */
+    C2D_TARGET_COLOR_KEY       = (1 << 7), /* enables target_color_key */
+    C2D_TARGET_NO_PIXEL_ALPHA  = (1 << 8), /* disables target alpha channel */
+} C2D_TARGET_CONFIG;
+
+#define C2D_TARGET_ROTATION_MASK  (C2D_TARGET_ROTATE_90*3)
+
+/* Additional blend modes, can be used with both source and target configs.
+   If none of the below is set, the default "SRC over DST" is applied. */
+typedef enum {
+    C2D_ALPHA_BLEND_SRC_OVER   = (0  << 20), /* Default, Porter-Duff "SRC over DST" */
+    C2D_ALPHA_BLEND_SRC        = (1  << 20), /* Porter-Duff "SRC" */
+    C2D_ALPHA_BLEND_SRC_IN     = (2  << 20), /* Porter-Duff "SRC in DST" */
+    C2D_ALPHA_BLEND_DST_IN     = (3  << 20), /* Porter-Duff "DST in SRC" */
+    C2D_ALPHA_BLEND_SRC_OUT    = (4  << 20), /* Porter-Duff "SRC out DST" */
+    C2D_ALPHA_BLEND_DST_OUT    = (5  << 20), /* Porter-Duff "DST out SRC" */
+    C2D_ALPHA_BLEND_DST_OVER   = (6  << 20), /* Porter-Duff "DST over SRC" */
+    C2D_ALPHA_BLEND_SRC_ATOP   = (7  << 20), /* Porter-Duff "SRC ATOP" */
+    C2D_ALPHA_BLEND_DST_ATOP   = (8  << 20), /* Porter-Duff "DST ATOP" */
+    C2D_ALPHA_BLEND_XOR        = (9  << 20), /* Xor */
+    C2D_ALPHA_BLEND_MULTIPLY   = (10 << 20), /* OpenVG "MULTIPLY" */
+    C2D_ALPHA_BLEND_SCREEN     = (11 << 20), /* OpenVG "SCREEN" */
+    C2D_ALPHA_BLEND_DARKEN     = (12 << 20), /* OpenVG "DARKEN" */
+    C2D_ALPHA_BLEND_LIGHTEN    = (13 << 20), /* OpenVG "LIGHTEN" */
+    C2D_ALPHA_BLEND_ADDITIVE   = (14 << 20), /* OpenVG "ADDITIVE" */
+    C2D_ALPHA_BLEND_DIRECT     = (15 << 20), /* Direct alpha blitting */
+    C2D_ALPHA_BLEND_INVERTC    = (16 << 20), /* Invert color */
+    C2D_ALPHA_BLEND_NONE       = (1  << 25), /* disables alpha blending */
+} C2D_ALPHA_BLEND_MODE;
+
+/* Configuration bits, used in the config_mask field of C2D_OBJECT struct */
+typedef enum {
+    C2D_OVERRIDE_GLOBAL_TARGET_ROTATE_CONFIG = (1 << 27), /* Overrides TARGET Config */
+    C2D_OVERRIDE_TARGET_ROTATE_0             = (0 << 28), /* no rotation             */
+    C2D_OVERRIDE_TARGET_ROTATE_90            = (1 << 28), /* 90 degree rotation      */
+    C2D_OVERRIDE_TARGET_ROTATE_180           = (2 << 28), /* 180 degree rotation     */
+    C2D_OVERRIDE_TARGET_ROTATE_270           = (3 << 28), /* 270 degree rotation     */
+} C2D_SOURCE_TARGET_CONFIG;
+
+#define C2D_OVERRIDE_SOURCE_CONFIG_TARGET_ROTATION_SHIFT_MASK  28
+#define C2D_OVERRIDE_TARGET_CONFIG_TARGET_ROTATION_SHIFT_MASK  2
+
+
+/* Surface caps enumeration */
+typedef enum {
+    C2D_SOURCE          = (1 << 0), /* allows to use as a source */
+    C2D_TARGET          = (1 << 1), /* allows to use as a target */
+    C2D_MASK            = (1 << 2), /* allows to use as a mask */
+    C2D_PALETTE         = (1 << 3), /* allows to use as a palette */
+} C2D_SURFACE_BITS;
+
+/* Surface type enumeration */
+typedef enum {
+    C2D_SURFACE_RGB_HOST        = 1, /* Host memory RGB surface */
+    C2D_SURFACE_RGB_EXT         = 2, /* External memory RGB surface */
+    C2D_SURFACE_YUV_HOST        = 3, /* Host memory YUV surface */
+    C2D_SURFACE_YUV_EXT         = 4, /* External memory YUV surface */
+    C2D_SURFACE_WITH_PHYS       = (1<<3), /* physical address already mapped */
+                                        /* this bit is valid with HOST types */
+    C2D_SURFACE_WITH_PHYS_DUMMY = (1<<4), /* physical address already mapped */
+                                        /* this bit is valid with HOST types */
+} C2D_SURFACE_TYPE;
+
+/* Structure for registering a RGB buffer as a blit surface */
+typedef struct {
+    uint32 format;   /* RGB color format plus additional mode bits */
+    uint32 width;    /* defines width in pixels */
+    uint32 height;   /* defines height in pixels */
+    void  *buffer;   /* pointer to the RGB buffer */
+    void  *phys;     /* physical address */
+    int32  stride;   /* defines stride in bytes, negative stride is allowed */
+} C2D_RGB_SURFACE_DEF;
+
+/* Structure for registering a YUV plane(s) as a blit surface */
+typedef struct {
+    uint32 format;   /* YUV color format plus additional mode bits */
+    uint32 width;    /* defines width in pixels */
+    uint32 height;   /* defines height in pixels */
+    void  *plane0;  /* holds the whole buffer if YUV format is not planar */
+    void  *phys0;   /* physical address */
+    int32  stride0; /* stride in bytes if YUV format is not planar */
+    void  *plane1;  /* holds UV or VU plane for planar interleaved */
+    void  *phys1;   /* physical address */
+    int32  stride1; /* stride for UV or VU plane for planar interleaved */
+    void  *plane2;  /* holds the 3. plane, ignored if YUV format is not planar */
+    void  *phys2;    /* physical address */
+    int32  stride2; /* stride for the 3. plane, ignored if YUV format is not planar */
+} C2D_YUV_SURFACE_DEF;
+
+
+/* Rectangle definition */
+typedef struct {
+    int32 x;        /* upper-left x */
+    int32 y;        /* upper-left y */
+    int32 width;    /* width */
+    int32 height;   /* height */
+} C2D_RECT;
+
+/* C2D_OBJECT encapsulates the blit parameters for a source surface.
+ * The fg_color defines color in target format for bits equal to 1
+ * in the source C2D_COLOR_FORMAT_1 format. It also defines rendering
+ * color for all alpha-only source formats. If the surface_id is 0
+ * the fg_color defines a constant fill color used instead of the surface.
+ * The bg_color defines color in target format for bits equal to 0
+ * in the source C2D_COLOR_FORMAT_1 format, otherwise both are ignored.
+ * The palette_id is used for all palette source formats, otherwise ignored.
+
+ * The source_rect first defines the content of the source surface,
+ * it is then horizontally/vertically flipped if C2D_MIRROR_*_BIT is set,
+ * then scaled with bilinear interpolation to exactly fit target_rect
+ * or repeated across target_rect if C2D_SOURCE_TILE_BIT is set,
+ * target_rect is then rotated clockwise by an arbitrary angle in degrees
+ * around the rot_orig_x/y, defined relative to target_rect's top left point,
+ * and then clipped to scissor_rect defined in target coordinate system.
+
+ * Finally alpha blending is applied before pixels get written into the target.
+ * Surface's pixel alpha is combined with mask alpha and with global alpha.
+ * Mask surface follows all transformations applied to the source surface.
+ * Source color key defines transparent color, applied together with alpha. */
+typedef struct C2D_OBJECT_STR {
+    uint32 surface_id;      /* source surface */
+
+    uint32 fg_color;        /* foreground color */
+    uint32 bg_color;        /* background color */
+    uint32 palette_id;      /* one-dimensional horizontal palette surface */
+
+    uint32 config_mask;     /* defines which fields below are enabled */
+
+    C2D_RECT source_rect;  /* region of the source surface,   16.16 fp */
+    C2D_RECT target_rect;  /* position and scaling in target, 16.16 fp */
+
+    int32 rot_orig_x;       /* rotation origin relative to target_rect's... */
+    int32 rot_orig_y;       /* ...top left point,     both are 16.16 fp */
+    int32 rotation;         /* clock-wise rotation in degrees, 16.16 fp */
+
+    C2D_RECT scissor_rect; /* defines the clip rectangle in target surface */
+
+    uint32 mask_surface_id; /* source alpha-mask surface */
+    uint32 global_alpha;    /* 0 = fully transparent, 255 = fully opaque */
+    uint32 color_key;       /* transparent color for the source surface */
+
+    struct C2D_OBJECT_STR *next; /* pointer to the next object or NULL */
+} C2D_OBJECT;
+
+/* Configuration bits, driver capabilities used by 2Dapplications */
+typedef enum {
+    C2D_DRIVER_SUPPORTS_GLOBAL_ALPHA_OP           = (1 << 0),
+    C2D_DRIVER_SUPPORTS_TILE_OP                   = (1 << 1),
+    C2D_DRIVER_SUPPORTS_COLOR_KEY_OP              = (1 << 2),
+    C2D_DRIVER_SUPPORTS_NO_PIXEL_ALPHA_OP         = (1 << 3),
+    C2D_DRIVER_SUPPORTS_TARGET_ROTATE_OP          = (1 << 4),
+    C2D_DRIVER_SUPPORTS_ANTI_ALIASING_OP          = (1 << 5), /* antialiasing */
+    C2D_DRIVER_SUPPORTS_BILINEAR_FILTER_OP        = (1 << 6),
+    C2D_DRIVER_SUPPORTS_LENS_CORRECTION_OP        = (1 << 7),
+    C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP = (1 << 8),
+    C2D_DRIVER_SUPPORTS_SHADER_BLOB_OP            = (1 << 9),
+    C2D_DRIVER_SUPPORTS_MASK_SURFACE_OP           = (1 << 10), /* mask surface */
+    C2D_DRIVER_SUPPORTS_MIRROR_H_OP               = (1 << 11), /* horizontal flip */
+    C2D_DRIVER_SUPPORTS_MIRROR_V_OP               = (1 << 12), /* vertical flip */
+    C2D_DRIVER_SUPPORTS_SCISSOR_RECT_OP           = (1 << 13),
+    C2D_DRIVER_SUPPORTS_SOURCE_RECT_OP            = (1 << 14),
+    C2D_DRIVER_SUPPORTS_TARGET_RECT_OP            = (1 << 15),
+    C2D_DRIVER_SUPPORTS_ROTATE_OP                 = (1 << 16), /* all rotations */
+    C2D_DRIVER_SUPPORTS_FLUSH_WITH_FENCE_FD_OP    = (1 << 17), /* all rotations */
+    C2D_DRIVER_SUPPORTS_UBWC_COMPRESSED_OP        = (1 << 18), /* UBWC Compression */
+    C2D_DRIVER_SUPPORTS_ALL_CAPABILITIES_OP       = ((0xFFFFFFFF) >> (31 - 18)) /* mask for all capabilities supported */
+} C2D_DRIVER_CAPABILITIES;
+
+/* 2D driver workaround bits used by the 2D applications */
+typedef enum {
+    C2D_DRIVER_WORKAROUND_NONE  = 0, /* NO workaround */
+    C2D_DRIVER_WORKAROUND_SWAP_UV_FOR_YUV_TARGET  = (1 << 0), /* Swap UV when this flag set */
+} C2D_DRIVER_WORKAROUND;
+
+/* Structure to query Driver information */
+typedef struct {
+    uint32 capabilities_mask;
+    uint32 workaround_mask;
+    uint32 reserved1;
+    uint32 reserved2;
+    uint32 reserved3;
+} C2D_DRIVER_INFO;
+
+/* Structure to query Driver information */
+typedef struct {
+    uint32          max_surface_template_needed;
+    uint32          reserved1;
+    uint32          reserved2;
+    uint32          reserved3;
+} C2D_DRIVER_SETUP_INFO;
+
+/*****************************************************************************/
+/**************************** C2D API 2.0 ********************************/
+/*****************************************************************************/
+
+/******************************************************************************
+ * Functions to create/destroy surfaces */
+
+/* Creates a generic blit surface according to its type.
+ * Pass a combination of desired surface bits according to planned usage.
+ * Accepted values for surface_bits may include bits from C2D_SURFACE_BITS,
+ * and also from C2D_DISPLAY for compatibility with HW display controller.
+ * For host memory types the memory is preallocated outside the API
+ * and should remain valid until surface is destroyed.
+ * For external memory types the memory is allocated within API.
+ * On success, the non-zero surface identifier is returned.
+ * All numbers greater that 0 are valid surface identifiers, 0 is invalid.
+
+ * Host memory RGB surface:
+ * surface_type       = C2D_SURFACE_RGB_HOST
+ * surface_definition = C2D_RGB_SURFACE_DEF
+ * all fields in definition structure should be set
+
+ * External memory RGB surface:
+ * surface_type       = C2D_SURFACE_RGB_EXT
+ * surface_definition = C2D_RGB_SURFACE_DEF
+ * buffer field in definition structure is ignored
+
+ * Host memory YUV surface:
+ * surface_type       = C2D_SURFACE_YUV_HOST
+ * surface_definition = C2D_YUV_SURFACE_DEF
+ * one or all plane and stride fields in definition structure
+ * should be set depending on whether the format is planar or not
+
+ * External memory YUV surface:
+ * surface_type       = C2D_SURFACE_YUV_EXT
+ * surface_definition = C2D_YUV_SURFACE_DEF
+ * all plane and stride fields in definition structure are ignored */
+C2D_API C2D_STATUS c2dCreateSurface( uint32 *surface_id,
+                         uint32 surface_bits,
+                         C2D_SURFACE_TYPE surface_type,
+                         void *surface_definition );
+
+/* Requests properties of the specified surface. */
+C2D_API C2D_STATUS c2dQuerySurface( uint32 surface_id,
+                         uint32 *surface_bits,
+                         C2D_SURFACE_TYPE *surface_type,
+                         uint32 *width, uint32 *height,
+                         uint32 *format );
+
+/* Destroys a generic blit surface.
+ * For external memory surfaces also deallocates the memory.
+ * It is safe to free any external resources associated with a given
+ * surface on c2dCreateSurface call after this function returns. */
+C2D_API C2D_STATUS c2dDestroySurface( uint32 surface_id );
+
+
+/******************************************************************************
+ * Functions to modify/exchange surface data */
+
+/* The format of fill_color is the same as color format being used
+ * for specified surface. If fill_rect is NULL the whole surface is filled.
+ * Alpha-blending is not performed while filling.
+ * The operation is complete when function returns. */
+C2D_API C2D_STATUS c2dFillSurface( uint32 surface_id,
+                         uint32 fill_color,
+                         C2D_RECT *fill_rect );
+
+/* Writes data located in host memory into the specified surface.
+ * The chunk of host memory is identified with surface_type and
+ * surface_definition, no surface registration needed in this case.
+ * Only C2D_SURFACE_RGB_HOST, C2D_SURFACE_YUV_HOST are accepted.
+ * If only part of the host memory buffer should be loaded, it should
+ * be configured in surface_definition using width, height and stride.
+ * The x and y are defined in target surface coordinate space.
+ * Color conversion has to be done, if color formats differ.
+ * Alpha-blending is not performed while writing.
+ * The operation is complete when function returns. */
+C2D_API C2D_STATUS c2dWriteSurface( uint32 surface_id,
+                         C2D_SURFACE_TYPE surface_type,
+                         void *surface_definition,
+                         int32 x, int32 y );
+
+/* Reads data from the specified surface into the host memory.
+ * The chunk of host memory is identified with surface_type and
+ * surface_definition, no surface registration needed in this case.
+ * Only C2D_SURFACE_RGB_HOST, C2D_SURFACE_YUV_HOST are accepted.
+ * If only part of the surface should be read, it should
+ * be configured in surface_definition using width, height and stride.
+ * The x and y are defined in source surface coordinate space.
+ * Color conversion has to be done, if color formats differ.
+ * Alpha-blending is not performed while reading.
+ * The operation is complete when function returns. */
+C2D_API C2D_STATUS c2dReadSurface( uint32 surface_id,
+                         C2D_SURFACE_TYPE surface_type,
+                         void *surface_definition,
+                         int32 x, int32 y );
+
+/* Notifies c2d imlementation that surface has been updated from outside the API,
+ * if updated_rect is NULL then the whole surface has been updated. */
+C2D_API C2D_STATUS c2dSurfaceUpdated( uint32 surface_id,
+                         C2D_RECT *updated_rect );
+
+/* Updates surface information.
+ * Could be called only for host surfaces set with parameter "C2D_SURFACE_WITH_PHYS".
+ * Count for surface planes have to be same than for already allocated surface */
+C2D_API C2D_STATUS c2dUpdateSurface( uint32 surface_id,
+                         uint32 surface_bits,
+                         C2D_SURFACE_TYPE surface_type,
+                         void *surface_definition );
+
+/******************************************************************************
+ * Functions to do actual blit */
+
+/* Draw a list of blit objects into the given target.
+ * The target_config is a bitwise OR of values from C2D_TARGET_CONFIG.
+ * The target transformation creates the effect that target surface
+ * is transformed before the blit and then transformed back
+ * after blit, however no physical target transform is performed.
+ * The objects_list is a linked list of blit objects, no more
+ * than num_objects is drawn from the given list.
+ * If num_objects is 0, the whole list is drawn.
+ * The blit is not guaranteed to complete after function returns. */
+C2D_API C2D_STATUS c2dDraw( uint32 target_id,
+                         uint32 target_config, C2D_RECT *target_scissor,
+                         uint32 target_mask_id, uint32 target_color_key,
+                         C2D_OBJECT *objects_list, uint32 num_objects );
+
+
+/* timstamp set in the blit commands flush */
+typedef void*                   c2d_ts_handle;
+
+/* Forces any pending blit to complete for a given target.
+ * Non-blocking. All input surfaces for this target except those
+ * which are shared with other targets are expected to be immediately
+ * writable after client has been waiting returned timestamp with
+ * c2dWaitTimestamp funtion or c2dFinish has been called for same target */
+C2D_API C2D_STATUS c2dFlush( uint32 target_id, c2d_ts_handle *timestamp);
+
+
+/* Waits the pending timestamp */
+C2D_API C2D_STATUS c2dWaitTimestamp( c2d_ts_handle timestamp );
+
+
+/* Forces any pending blit to complete for a given target.
+ * Blocking version, returns when blit is done.
+ * All input surfaces for this target except those which are shared with
+ * other targets are expected to be immediately
+ * writable after this function returns. */
+C2D_API C2D_STATUS c2dFinish( uint32 target_id );
+
+
+/*****************************************************************************/
+/****************************** Display API **********************************/
+/*****************************************************************************/
+
+
+/* Display input enumeration */
+typedef enum {
+    C2D_DISPLAY_INPUT_0      = 0,       /*!< default input */
+    C2D_DISPLAY_INPUT_1      = (1<<16), /*!< Overlay 1     */
+    C2D_DISPLAY_INPUT_2      = (1<<17), /*!< Overlay 2...    */
+} C2D_DISPLAY_INPUT;
+
+
+/******************************************************************************
+ * Functions for display output. */
+
+/* Functionality described in this section is optional and is
+ * provided only for the cases when blit HW
+ * is tightly bound to the display controller. */
+
+/* Display enumeration, may also be used in surface caps */
+typedef enum {
+    C2D_DISPLAY_MAIN         = (1 << 10), /* main display */
+    C2D_DISPLAY_SECONDARY    = (1 << 11), /* secondary display */
+    C2D_DISPLAY_TV_OUT       = (1 << 12), /* tv-out */
+} C2D_DISPLAY;
+
+/* Display window enumeration */
+typedef enum {
+    C2D_DISPLAY_OVERLAY      = C2D_DISPLAY_INPUT_1, /*!< Overlay window bit. This defines display input.
+                                                When defined the surface is set on the overlay window
+                                                otherwise the surface is set on the background window. */
+} C2D_DISPLAY_WINDOW;                    /*!< Window bit set with display parameter */
+
+
+/* Display update modes */
+typedef enum {
+    C2D_DISPLAY_MODE_TEAR_SYNC   = (1 << 0), /* enables tearing sync */
+    C2D_DISPLAY_MODE_SURF_REMOVE = (1 << 1), /* Remove surface from given display + input */
+} C2D_DISPLAY_MODE;
+
+
+/* Sets the given surface as a current display front buffer.
+ * Several displays can be specified as an output if supported.
+ * Still only one input can be specified at a time fro display/displays.
+ * The surface remains shown until it gets replaced with another one. */
+C2D_API C2D_STATUS c2dDisplaySetSurface( uint32 display,
+                         uint32 surface_id, uint32 mode );
+
+/* Returns the current surface for a particular display.
+ * Only one display can be specified at a time.
+ * The latest surface set with compDisplaySetSurface or
+ * the default pre-allocated surface is returned. */
+C2D_API C2D_STATUS c2dDisplayGetSurface( uint32 display,
+                         uint32 *surface_id );
+
+/* Returns the properties for a particular display.
+ * Only one display can be specified at a time. */
+C2D_API C2D_STATUS c2dDisplayGetProperties( uint32 display,
+                         uint32 *width, uint32 *height,
+                         uint32 *format );
+
+/* Sets the properties for a particular display input.
+ * Only one display + input can be specified at a time.
+ * C2D_OBJECT used to set input rect(target rect),
+ * blending operations, rotation...etc for display source */
+C2D_API C2D_STATUS c2dDisplaySetObject( uint32 display,
+                         uint32 target_config, uint32 target_color_key,
+                         C2D_OBJECT * c2dObject, uint32 mode);
+
+/* allows user to map a memory region to the gpu. only supported on linux
+ * mem_fd is the fd of the memory region, hostptr is the host pointer to the region,
+ * len and offset are the size and offset of the memory.
+ * flags is one of the memory types supported by gsl
+ * gpaddr is passed by refernce back to the user
+ */
+C2D_API C2D_STATUS c2dMapAddr ( int mem_fd, void * hostptr, uint32 len, uint32 offset, uint32 flags, void ** gpuaddr);
+
+/* allows user to unmap memory region mapped by c2dMapAddr.
+ * gpaddr is the gpuaddr to unmap */
+C2D_API C2D_STATUS c2dUnMapAddr (void * gpuaddr);
+
+/* allows user to query driver capabilities.
+ * driver_info is the information about driver */
+C2D_API C2D_STATUS c2dGetDriverCapabilities( C2D_DRIVER_INFO * driver_info);
+
+/* create a fence fd for the timestamp */
+C2D_API C2D_STATUS c2dCreateFenceFD( uint32 target_id, c2d_ts_handle timestamp, int32 *fd);
+
+/*****************************************************************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __c2d2_h_ */
diff --git a/msmcobalt/libcopybit/copybit.cpp b/msmcobalt/libcopybit/copybit.cpp
new file mode 100644
index 0000000..10f5943
--- /dev/null
+++ b/msmcobalt/libcopybit/copybit.cpp
@@ -0,0 +1,792 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2010 - 2014, The Linux Foundation. All rights reserved.
+ *
+ * Not a Contribution, Apache license notifications and license are retained
+ * for attribution purposes only.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      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 <linux/msm_mdp.h>
+#include <linux/fb.h>
+
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <copybit.h>
+
+#include "gralloc_priv.h"
+#include "software_converter.h"
+#include <qdMetaData.h>
+
+#define DEBUG_MDP_ERRORS 1
+
+/******************************************************************************/
+
+#define MAX_SCALE_FACTOR    (4)
+#define MAX_DIMENSION       (4096)
+
+/******************************************************************************/
+struct blitReq{
+    struct  mdp_buf_sync sync;
+    uint32_t count;
+    struct mdp_blit_req req[10];
+};
+
+/** State information for each device instance */
+struct copybit_context_t {
+    struct copybit_device_t device;
+    int     mFD;
+    uint8_t mAlpha;
+    int     mFlags;
+    bool    mBlitToFB;
+    int     acqFence[MDP_MAX_FENCE_FD];
+    int     relFence;
+    struct  mdp_buf_sync sync;
+    struct  blitReq list;
+    uint8_t dynamic_fps;
+};
+
+/**
+ * Common hardware methods
+ */
+
+static int open_copybit(const struct hw_module_t* module, const char* name,
+                        struct hw_device_t** device);
+
+static struct hw_module_methods_t copybit_module_methods = {
+open:  open_copybit
+};
+
+/*
+ * The COPYBIT Module
+ */
+struct copybit_module_t HAL_MODULE_INFO_SYM = {
+common: {
+tag: HARDWARE_MODULE_TAG,
+     version_major: 1,
+     version_minor: 0,
+     id: COPYBIT_HARDWARE_MODULE_ID,
+     name: "QCT MSM7K COPYBIT Module",
+     author: "Google, Inc.",
+     methods: &copybit_module_methods
+        }
+};
+
+/******************************************************************************/
+
+/** 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;
+}
+
+/** scale each parameter by mul/div. Assume div isn't 0 */
+static inline void MULDIV(uint32_t *a, uint32_t *b, int mul, int div) {
+    if (mul != div) {
+        *a = (mul * *a) / div;
+        *b = (mul * *b) / div;
+    }
+}
+
+/** Determine the intersection of lhs & rhs store in out */
+static void intersect(struct copybit_rect_t *out,
+                      const struct copybit_rect_t *lhs,
+                      const struct copybit_rect_t *rhs) {
+    out->l = max(lhs->l, rhs->l);
+    out->t = max(lhs->t, rhs->t);
+    out->r = min(lhs->r, rhs->r);
+    out->b = min(lhs->b, rhs->b);
+}
+
+static bool validateCopybitRect(struct copybit_rect_t *rect) {
+    return ((rect->b > rect->t) && (rect->r > rect->l)) ;
+}
+
+/** convert COPYBIT_FORMAT to MDP format */
+static int get_format(int format) {
+    switch (format) {
+        case HAL_PIXEL_FORMAT_RGB_565:       return MDP_RGB_565;
+        case HAL_PIXEL_FORMAT_RGBA_5551:     return MDP_RGBA_5551;
+        case HAL_PIXEL_FORMAT_RGBA_4444:     return MDP_RGBA_4444;
+        case HAL_PIXEL_FORMAT_RGBX_8888:     return MDP_RGBX_8888;
+        case HAL_PIXEL_FORMAT_BGRX_8888:     return MDP_BGRX_8888;
+        case HAL_PIXEL_FORMAT_RGB_888:       return MDP_RGB_888;
+        case HAL_PIXEL_FORMAT_RGBA_8888:     return MDP_RGBA_8888;
+        case HAL_PIXEL_FORMAT_BGRA_8888:     return MDP_BGRA_8888;
+        case HAL_PIXEL_FORMAT_YCrCb_422_I:   return MDP_YCRYCB_H2V1;
+        case HAL_PIXEL_FORMAT_YCbCr_422_I:   return MDP_YCBYCR_H2V1;
+        case HAL_PIXEL_FORMAT_YCrCb_422_SP:  return MDP_Y_CRCB_H2V1;
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP:  return MDP_Y_CRCB_H2V2;
+        case HAL_PIXEL_FORMAT_YCbCr_422_SP:  return MDP_Y_CBCR_H2V1;
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP:  return MDP_Y_CBCR_H2V2;
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: return MDP_Y_CBCR_H2V2_ADRENO;
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: return MDP_Y_CBCR_H2V2_VENUS;
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: return MDP_Y_CRCB_H2V2_VENUS;
+        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: return MDP_Y_CBCR_H2V2;
+    }
+    return -1;
+}
+
+/** convert from copybit image to mdp image structure */
+static void set_image(struct mdp_img *img, const struct copybit_image_t *rhs)
+{
+    private_handle_t* hnd = (private_handle_t*)rhs->handle;
+    if(hnd == NULL){
+        ALOGE("copybit: Invalid handle");
+        return;
+    }
+    img->width      = rhs->w;
+    img->height     = rhs->h;
+    img->format     = get_format(rhs->format);
+    img->offset     = (uint32_t)hnd->offset;
+    img->memory_id  = hnd->fd;
+}
+/** setup rectangles */
+static bool set_rects(struct copybit_context_t *dev,
+                      struct mdp_blit_req *e,
+                      const struct copybit_rect_t *dst,
+                      const struct copybit_rect_t *src,
+                      const struct copybit_rect_t *scissor) {
+    struct copybit_rect_t clip;
+    intersect(&clip, scissor, dst);
+
+    if (!validateCopybitRect(&clip))
+       return false;
+
+    e->dst_rect.x  = clip.l;
+    e->dst_rect.y  = clip.t;
+    e->dst_rect.w  = clip.r - clip.l;
+    e->dst_rect.h  = clip.b - clip.t;
+
+    uint32_t W, H, delta_x, delta_y;
+    if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) {
+        delta_x = (clip.t - dst->t);
+        delta_y = (dst->r - clip.r);
+        e->src_rect.w = (clip.b - clip.t);
+        e->src_rect.h = (clip.r - clip.l);
+        W = dst->b - dst->t;
+        H = dst->r - dst->l;
+    } else {
+        delta_x  = (clip.l - dst->l);
+        delta_y  = (clip.t - dst->t);
+        e->src_rect.w  = (clip.r - clip.l);
+        e->src_rect.h  = (clip.b - clip.t);
+        W = dst->r - dst->l;
+        H = dst->b - dst->t;
+    }
+
+    MULDIV(&delta_x, &e->src_rect.w, src->r - src->l, W);
+    MULDIV(&delta_y, &e->src_rect.h, src->b - src->t, H);
+
+    e->src_rect.x = delta_x + src->l;
+    e->src_rect.y = delta_y + src->t;
+
+    if (dev->mFlags & COPYBIT_TRANSFORM_FLIP_V) {
+        if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) {
+            e->src_rect.x = (src->l + src->r) - (e->src_rect.x + e->src_rect.w);
+        }else{
+            e->src_rect.y = (src->t + src->b) - (e->src_rect.y + e->src_rect.h);
+        }
+    }
+
+    if (dev->mFlags & COPYBIT_TRANSFORM_FLIP_H) {
+        if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) {
+            e->src_rect.y = (src->t + src->b) - (e->src_rect.y + e->src_rect.h);
+        }else{
+            e->src_rect.x = (src->l + src->r) - (e->src_rect.x + e->src_rect.w);
+        }
+    }
+    return true;
+}
+
+/** setup mdp request */
+static void set_infos(struct copybit_context_t *dev,
+                      struct mdp_blit_req *req, int flags)
+{
+    req->alpha = dev->mAlpha;
+    req->fps = dev->dynamic_fps;
+    req->transp_mask = MDP_TRANSP_NOP;
+    req->flags = dev->mFlags | flags;
+    // check if we are blitting to f/b
+    if (COPYBIT_ENABLE == dev->mBlitToFB) {
+        req->flags |= MDP_MEMORY_ID_TYPE_FB;
+    }
+#if defined(COPYBIT_QSD8K)
+    req->flags |= MDP_BLEND_FG_PREMULT;
+#endif
+}
+
+/** copy the bits */
+static int msm_copybit(struct copybit_context_t *dev, void const *list)
+{
+    int err;
+    if (dev->relFence != -1) {
+        close(dev->relFence);
+        dev->relFence = -1;
+    }
+    err = ioctl(dev->mFD, MSMFB_ASYNC_BLIT,
+                    (struct mdp_async_blit_req_list const*)list);
+    ALOGE_IF(err<0, "copyBits failed (%s)", strerror(errno));
+    if (err == 0) {
+        return 0;
+    } else {
+#if DEBUG_MDP_ERRORS
+        struct mdp_async_blit_req_list const* l =
+            (struct mdp_async_blit_req_list const*)list;
+        for (unsigned int i=0 ; i<l->count ; i++) {
+            ALOGE("%d: src={w=%d, h=%d, f=%d, rect={%d,%d,%d,%d}}\n"
+                  "    dst={w=%d, h=%d, f=%d, rect={%d,%d,%d,%d}}\n"
+                  "    flags=%08x, fps=%d"
+                  ,
+                  i,
+                  l->req[i].src.width,
+                  l->req[i].src.height,
+                  l->req[i].src.format,
+                  l->req[i].src_rect.x,
+                  l->req[i].src_rect.y,
+                  l->req[i].src_rect.w,
+                  l->req[i].src_rect.h,
+                  l->req[i].dst.width,
+                  l->req[i].dst.height,
+                  l->req[i].dst.format,
+                  l->req[i].dst_rect.x,
+                  l->req[i].dst_rect.y,
+                  l->req[i].dst_rect.w,
+                  l->req[i].dst_rect.h,
+                  l->req[i].flags,
+                  l->req[i].fps
+                 );
+        }
+#endif
+        return -errno;
+    }
+}
+
+/*****************************************************************************/
+
+/** Set a parameter to value */
+static int set_parameter_copybit(
+    struct copybit_device_t *dev,
+    int name,
+    int value)
+{
+    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    int status = 0;
+    if (ctx) {
+        switch(name) {
+            case COPYBIT_ROTATION_DEG:
+                switch (value) {
+                    case 0:
+                        ctx->mFlags &= ~0x7;
+                        break;
+                    case 90:
+                        ctx->mFlags &= ~0x7;
+                        ctx->mFlags |= MDP_ROT_90;
+                        break;
+                    case 180:
+                        ctx->mFlags &= ~0x7;
+                        ctx->mFlags |= MDP_ROT_180;
+                        break;
+                    case 270:
+                        ctx->mFlags &= ~0x7;
+                        ctx->mFlags |= MDP_ROT_270;
+                        break;
+                    default:
+                        ALOGE("Invalid value for COPYBIT_ROTATION_DEG");
+                        status = -EINVAL;
+                        break;
+                }
+                break;
+            case COPYBIT_PLANE_ALPHA:
+                if (value < 0)      value = MDP_ALPHA_NOP;
+                if (value >= 256)   value = 255;
+                ctx->mAlpha = (uint8_t)value;
+                break;
+            case COPYBIT_DYNAMIC_FPS:
+                ctx->dynamic_fps = (uint8_t)value;
+                break;
+            case COPYBIT_DITHER:
+                if (value == COPYBIT_ENABLE) {
+                    ctx->mFlags |= MDP_DITHER;
+                } else if (value == COPYBIT_DISABLE) {
+                    ctx->mFlags &= ~MDP_DITHER;
+                }
+                break;
+            case COPYBIT_BLUR:
+                if (value == COPYBIT_ENABLE) {
+                    ctx->mFlags |= MDP_BLUR;
+                } else if (value == COPYBIT_DISABLE) {
+                    ctx->mFlags &= ~MDP_BLUR;
+                }
+                break;
+            case COPYBIT_BLEND_MODE:
+                if(value == COPYBIT_BLENDING_PREMULT) {
+                    ctx->mFlags |= MDP_BLEND_FG_PREMULT;
+                } else {
+                    ctx->mFlags &= ~MDP_BLEND_FG_PREMULT;
+                }
+                break;
+            case COPYBIT_TRANSFORM:
+                ctx->mFlags &= ~0x7;
+                ctx->mFlags |= value & 0x7;
+                break;
+            case COPYBIT_BLIT_TO_FRAMEBUFFER:
+                if (COPYBIT_ENABLE == value) {
+                    ctx->mBlitToFB = value;
+                } else if (COPYBIT_DISABLE == value) {
+                    ctx->mBlitToFB = value;
+                } else {
+                    ALOGE ("%s:Invalid input for COPYBIT_BLIT_TO_FRAMEBUFFER : %d",
+                            __FUNCTION__, value);
+                }
+                break;
+            case COPYBIT_FG_LAYER:
+                if(value == COPYBIT_ENABLE) {
+                     ctx->mFlags |= MDP_IS_FG;
+                } else if (value == COPYBIT_DISABLE) {
+                    ctx->mFlags &= ~MDP_IS_FG;
+                }
+                break ;
+            default:
+                status = -EINVAL;
+                break;
+        }
+    } else {
+        status = -EINVAL;
+    }
+    return status;
+}
+
+/** Get a static info value */
+static int get(struct copybit_device_t *dev, int name)
+{
+    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    int value;
+    if (ctx) {
+        switch(name) {
+            case COPYBIT_MINIFICATION_LIMIT:
+                value = MAX_SCALE_FACTOR;
+                break;
+            case COPYBIT_MAGNIFICATION_LIMIT:
+                value = MAX_SCALE_FACTOR;
+                break;
+            case COPYBIT_SCALING_FRAC_BITS:
+                value = 32;
+                break;
+            case COPYBIT_ROTATION_STEP_DEG:
+                value = 90;
+                break;
+            default:
+                value = -EINVAL;
+        }
+    } else {
+        value = -EINVAL;
+    }
+    return value;
+}
+
+static int set_sync_copybit(struct copybit_device_t *dev,
+    int acquireFenceFd)
+{
+    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    if (acquireFenceFd != -1) {
+        if (ctx->list.sync.acq_fen_fd_cnt < (MDP_MAX_FENCE_FD - 1)) {
+            ctx->acqFence[ctx->list.sync.acq_fen_fd_cnt++] = acquireFenceFd;
+        } else {
+            int ret = -EINVAL;
+            struct blitReq *list = &ctx->list;
+
+            // Since fence is full kick off what is already in the list
+            ret = msm_copybit(ctx, list);
+            if (ret < 0) {
+                ALOGE("%s: Blit call failed", __FUNCTION__);
+                return -EINVAL;
+            }
+            list->count = 0;
+            list->sync.acq_fen_fd_cnt = 0;
+            ctx->acqFence[list->sync.acq_fen_fd_cnt++] = acquireFenceFd;
+        }
+    }
+    return 0;
+}
+
+/** do a stretch blit type operation */
+static int stretch_copybit(
+    struct copybit_device_t *dev,
+    struct copybit_image_t const *dst,
+    struct copybit_image_t const *src,
+    struct copybit_rect_t const *dst_rect,
+    struct copybit_rect_t const *src_rect,
+    struct copybit_region_t const *region)
+{
+    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    struct blitReq *list;
+    int status = 0;
+    private_handle_t *yv12_handle = NULL;
+
+    if (ctx) {
+        list = &ctx->list;
+
+        if (ctx->mAlpha < 255) {
+            switch (src->format) {
+                // we don't support plane alpha with RGBA formats
+                case HAL_PIXEL_FORMAT_RGBA_8888:
+                case HAL_PIXEL_FORMAT_BGRA_8888:
+                case HAL_PIXEL_FORMAT_RGBA_5551:
+                case HAL_PIXEL_FORMAT_RGBA_4444:
+                    ALOGE ("%s : Unsupported Pixel format %d", __FUNCTION__,
+                           src->format);
+                    return -EINVAL;
+            }
+        }
+
+        if (src_rect->l < 0 || (uint32_t)src_rect->r > src->w ||
+            src_rect->t < 0 || (uint32_t)src_rect->b > src->h) {
+            // this is always invalid
+            ALOGE ("%s : Invalid source rectangle : src_rect l %d t %d r %d b %d",\
+                   __FUNCTION__, src_rect->l, src_rect->t, src_rect->r, src_rect->b);
+
+            return -EINVAL;
+        }
+
+        if (src->w > MAX_DIMENSION || src->h > MAX_DIMENSION) {
+            ALOGE ("%s : Invalid source dimensions w %d h %d", __FUNCTION__, src->w, src->h);
+            return -EINVAL;
+        }
+
+        if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) {
+            ALOGE ("%s : Invalid DST dimensions w %d h %d", __FUNCTION__, dst->w, dst->h);
+            return -EINVAL;
+        }
+
+        if(src->format ==  HAL_PIXEL_FORMAT_YV12) {
+            int usage =
+            GRALLOC_USAGE_PRIVATE_IOMMU_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED;
+            if (0 == alloc_buffer(&yv12_handle,src->w,src->h,
+                                  src->format, usage)){
+                if(0 == convertYV12toYCrCb420SP(src,yv12_handle)){
+                    (const_cast<copybit_image_t *>(src))->format =
+                        HAL_PIXEL_FORMAT_YCrCb_420_SP;
+                    (const_cast<copybit_image_t *>(src))->handle =
+                        yv12_handle;
+                    (const_cast<copybit_image_t *>(src))->base =
+                        (void *)yv12_handle->base;
+                }
+                else{
+                    ALOGE("Error copybit conversion from yv12 failed");
+                    if(yv12_handle)
+                        free_buffer(yv12_handle);
+                    return -EINVAL;
+                }
+            }
+            else{
+                ALOGE("Error:unable to allocate memeory for yv12 software conversion");
+                return -EINVAL;
+            }
+        }
+        const uint32_t maxCount =
+                (uint32_t)(sizeof(list->req)/sizeof(list->req[0]));
+        const struct copybit_rect_t bounds = { 0, 0, (int)dst->w, (int)dst->h };
+        struct copybit_rect_t clip;
+        status = 0;
+        while ((status == 0) && region->next(region, &clip)) {
+            intersect(&clip, &bounds, &clip);
+            mdp_blit_req* req = &list->req[list->count];
+            int flags = 0;
+
+            private_handle_t* src_hnd = (private_handle_t*)src->handle;
+            if(src_hnd != NULL &&
+                (!(src_hnd->flags & private_handle_t::PRIV_FLAGS_CACHED))) {
+                flags |=  MDP_BLIT_NON_CACHED;
+            }
+
+            // Set Color Space for MDP to configure CSC matrix
+            req->color_space = ITU_R_601;
+            MetaData_t *metadata = NULL;
+
+            if (src_hnd != NULL)
+                metadata = (MetaData_t *)src_hnd->base_metadata;
+
+            if (metadata && (metadata->operation & UPDATE_COLOR_SPACE)) {
+                req->color_space = metadata->colorSpace;
+            }
+
+            set_infos(ctx, req, flags);
+            set_image(&req->dst, dst);
+            set_image(&req->src, src);
+            if (set_rects(ctx, req, dst_rect, src_rect, &clip) == false)
+                continue;
+
+            if (req->src_rect.w<=0 || req->src_rect.h<=0)
+                continue;
+
+            if (req->dst_rect.w<=0 || req->dst_rect.h<=0)
+                continue;
+
+            if (++list->count == maxCount) {
+                status = msm_copybit(ctx, list);
+                list->sync.acq_fen_fd_cnt = 0;
+                list->count = 0;
+            }
+        }
+        if(yv12_handle) {
+            //Before freeing the buffer we need buffer passed through blit call
+            if (list->count != 0) {
+                status = msm_copybit(ctx, list);
+                list->sync.acq_fen_fd_cnt = 0;
+                list->count = 0;
+            }
+            free_buffer(yv12_handle);
+        }
+    } else {
+        ALOGE ("%s : Invalid COPYBIT context", __FUNCTION__);
+        status = -EINVAL;
+    }
+    return status;
+}
+
+/** Perform a blit type operation */
+static int blit_copybit(
+    struct copybit_device_t *dev,
+    struct copybit_image_t const *dst,
+    struct copybit_image_t const *src,
+    struct copybit_region_t const *region)
+{
+    struct copybit_rect_t dr = { 0, 0, (int)dst->w, (int)dst->h };
+    struct copybit_rect_t sr = { 0, 0, (int)src->w, (int)src->h };
+    return stretch_copybit(dev, dst, src, &dr, &sr, region);
+}
+
+static int finish_copybit(struct copybit_device_t *dev)
+{
+    // NOP for MDP copybit
+    if(!dev)
+       return -EINVAL;
+
+    return 0;
+}
+static int clear_copybit(struct copybit_device_t *dev,
+                         struct copybit_image_t const *buf,
+                         struct copybit_rect_t *rect)
+{
+    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    uint32_t color = 0; // black color
+
+    if (!ctx) {
+        ALOGE ("%s: Invalid copybit context", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    struct blitReq list1;
+    memset((char *)&list1 , 0 ,sizeof (struct blitReq) );
+    list1.count = 1;
+    int my_tmp_get_fence = -1;
+
+    list1.sync.acq_fen_fd  =  ctx->acqFence;
+    list1.sync.rel_fen_fd  =  &my_tmp_get_fence;
+    list1.sync.acq_fen_fd_cnt = ctx->list.sync.acq_fen_fd_cnt;
+    mdp_blit_req* req = &list1.req[0];
+
+    if(!req) {
+        ALOGE ("%s : Invalid request", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    set_image(&req->dst, buf);
+    set_image(&req->src, buf);
+
+    if (rect->l < 0 || (uint32_t)(rect->r - rect->l) > req->dst.width ||
+       rect->t < 0 || (uint32_t)(rect->b - rect->t) > req->dst.height) {
+       ALOGE ("%s : Invalid rect : src_rect l %d t %d r %d b %d",\
+       __FUNCTION__, rect->l, rect->t, rect->r, rect->b);
+       return -EINVAL;
+    }
+
+    req->dst_rect.x  = rect->l;
+    req->dst_rect.y  = rect->t;
+    req->dst_rect.w  = rect->r - rect->l;
+    req->dst_rect.h  = rect->b - rect->t;
+
+    req->src_rect = req->dst_rect;
+
+    req->const_color.b = (uint32_t)((color >> 16) & 0xff);
+    req->const_color.g = (uint32_t)((color >> 8) & 0xff);
+    req->const_color.r = (uint32_t)((color >> 0) & 0xff);
+    req->const_color.alpha = MDP_ALPHA_NOP;
+
+    req->transp_mask = MDP_TRANSP_NOP;
+    req->flags = MDP_SOLID_FILL | MDP_MEMORY_ID_TYPE_FB | MDP_BLEND_FG_PREMULT;
+    int status = msm_copybit(ctx, &list1);
+
+    ctx->list.sync.acq_fen_fd_cnt = 0;
+    if (my_tmp_get_fence !=  -1)
+        close(my_tmp_get_fence);
+
+    return status;
+}
+
+/** Fill the rect on dst with RGBA color **/
+static int fill_color(struct copybit_device_t *dev,
+                      struct copybit_image_t const *dst,
+                      struct copybit_rect_t const *rect,
+                      uint32_t color)
+{
+    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    if (!ctx) {
+        ALOGE("%s: Invalid copybit context", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) {
+        ALOGE("%s: Invalid DST w=%d h=%d", __FUNCTION__, dst->w, dst->h);
+        return -EINVAL;
+    }
+
+    if (rect->l < 0 || (uint32_t)(rect->r - rect->l) > dst->w ||
+        rect->t < 0 || (uint32_t)(rect->b - rect->t) > dst->h) {
+        ALOGE("%s: Invalid destination rect: l=%d t=%d r=%d b=%d",
+                __FUNCTION__, rect->l, rect->t, rect->r, rect->b);
+        return -EINVAL;
+    }
+
+    int status = 0;
+    struct blitReq* list = &ctx->list;
+    mdp_blit_req* req = &list->req[list->count++];
+    set_infos(ctx, req, MDP_SOLID_FILL);
+    set_image(&req->src, dst);
+    set_image(&req->dst, dst);
+
+    req->dst_rect.x = rect->l;
+    req->dst_rect.y = rect->t;
+    req->dst_rect.w = rect->r - rect->l;
+    req->dst_rect.h = rect->b - rect->t;
+    req->src_rect = req->dst_rect;
+
+    req->const_color.r = (uint32_t)((color >> 0) & 0xff);
+    req->const_color.g = (uint32_t)((color >> 8) & 0xff);
+    req->const_color.b = (uint32_t)((color >> 16) & 0xff);
+    req->const_color.alpha = (uint32_t)((color >> 24) & 0xff);
+
+    if (list->count == sizeof(list->req)/sizeof(list->req[0])) {
+        status = msm_copybit(ctx, list);
+        list->sync.acq_fen_fd_cnt = 0;
+        list->count = 0;
+    }
+    return status;
+}
+
+/*****************************************************************************/
+
+/** Close the copybit device */
+static int close_copybit(struct hw_device_t *dev)
+{
+    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    if (ctx) {
+        close(ctx->mFD);
+        free(ctx);
+    }
+    return 0;
+}
+
+static int flush_get_fence(struct copybit_device_t *dev, int* fd)
+{
+    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    struct blitReq *list = &ctx->list;
+    int ret = -EINVAL;
+
+    if (list->count) {
+        ret = msm_copybit(ctx, list);
+        if (ret < 0)
+            ALOGE("%s: Blit call failed", __FUNCTION__);
+        list->count = 0;
+    }
+    *fd = ctx->relFence;
+    list->sync.acq_fen_fd_cnt = 0;
+    ctx->relFence = -1;
+    return ret;
+}
+
+/** Open a new instance of a copybit device using name */
+static int open_copybit(const struct hw_module_t* module, const char* name,
+                        struct hw_device_t** device)
+{
+    int status = -EINVAL;
+
+    if (strcmp(name, COPYBIT_HARDWARE_COPYBIT0)) {
+        return COPYBIT_FAILURE;
+    }
+    copybit_context_t *ctx;
+    ctx = (copybit_context_t *)malloc(sizeof(copybit_context_t));
+
+    if (ctx == NULL ) {
+       return COPYBIT_FAILURE;
+    }
+
+    memset(ctx, 0, sizeof(*ctx));
+
+    ctx->device.common.tag = HARDWARE_DEVICE_TAG;
+    ctx->device.common.version = 1;
+    ctx->device.common.module = const_cast<hw_module_t*>(module);
+    ctx->device.common.close = close_copybit;
+    ctx->device.set_parameter = set_parameter_copybit;
+    ctx->device.get = get;
+    ctx->device.blit = blit_copybit;
+    ctx->device.set_sync = set_sync_copybit;
+    ctx->device.stretch = stretch_copybit;
+    ctx->device.finish = finish_copybit;
+    ctx->device.fill_color = fill_color;
+    ctx->device.flush_get_fence = flush_get_fence;
+    ctx->device.clear = clear_copybit;
+    ctx->mAlpha = MDP_ALPHA_NOP;
+    //dynamic_fps is zero means default
+    //panel refresh rate for driver.
+    ctx->dynamic_fps = 0;
+    ctx->mFlags = 0;
+    ctx->sync.flags = 0;
+    ctx->relFence = -1;
+    for (int i=0; i < MDP_MAX_FENCE_FD; i++) {
+        ctx->acqFence[i] = -1;
+    }
+    ctx->sync.acq_fen_fd = ctx->acqFence;
+    ctx->sync.rel_fen_fd = &ctx->relFence;
+    ctx->list.count = 0;
+    ctx->list.sync.acq_fen_fd_cnt = 0;
+    ctx->list.sync.rel_fen_fd = ctx->sync.rel_fen_fd;
+    ctx->list.sync.acq_fen_fd = ctx->sync.acq_fen_fd;
+    ctx->mFD = open("/dev/graphics/fb0", O_RDWR, 0);
+    if (ctx->mFD < 0) {
+        status = errno;
+        ALOGE("Error opening frame buffer errno=%d (%s)",
+              status, strerror(status));
+        status = -status;
+    } else {
+        status = 0;
+        *device = &ctx->device.common;
+    }
+    return status;
+}
diff --git a/msmcobalt/libcopybit/copybit.h b/msmcobalt/libcopybit/copybit.h
new file mode 100644
index 0000000..de585ee
--- /dev/null
+++ b/msmcobalt/libcopybit/copybit.h
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+ *
+ * Not a Contribution, Apache license notifications and license are retained
+ * for attribution purposes only.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      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_COPYBIT_INTERFACE_H
+#define ANDROID_COPYBIT_INTERFACE_H
+
+#include <hardware/hardware.h>
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <gralloc_priv.h>
+
+__BEGIN_DECLS
+
+/**
+ * The id of this module
+ */
+#define COPYBIT_HARDWARE_MODULE_ID "copybit"
+
+/**
+ * Name of the graphics device to open
+ */
+#define COPYBIT_HARDWARE_COPYBIT0 "copybit0"
+
+/* supported pixel-formats. these must be compatible with
+ * graphics/PixelFormat.java, ui/PixelFormat.h, pixelflinger/format.h
+ */
+enum {
+    COPYBIT_FORMAT_RGBA_8888    = HAL_PIXEL_FORMAT_RGBA_8888,
+    COPYBIT_FORMAT_RGBX_8888    = HAL_PIXEL_FORMAT_RGBX_8888,
+    COPYBIT_FORMAT_RGB_888      = HAL_PIXEL_FORMAT_RGB_888,
+    COPYBIT_FORMAT_RGB_565      = HAL_PIXEL_FORMAT_RGB_565,
+    COPYBIT_FORMAT_BGRA_8888    = HAL_PIXEL_FORMAT_BGRA_8888,
+    COPYBIT_FORMAT_RGBA_5551    = HAL_PIXEL_FORMAT_RGBA_5551,
+    COPYBIT_FORMAT_RGBA_4444    = HAL_PIXEL_FORMAT_RGBA_4444,
+    COPYBIT_FORMAT_YCbCr_422_SP = 0x10,
+    COPYBIT_FORMAT_YCrCb_420_SP = 0x11,
+};
+
+/* name for copybit_set_parameter */
+enum {
+    /* Default blit destination is offline buffer */
+    /* clients to set this to '1', if blitting to framebuffer */
+    /* and reset to '0', after calling blit/stretch */
+    COPYBIT_BLIT_TO_FRAMEBUFFER = 0,
+    /* rotation of the source image in degrees (0 to 359) */
+    COPYBIT_ROTATION_DEG    = 1,
+    /* plane alpha value */
+    COPYBIT_PLANE_ALPHA     = 2,
+    /* enable or disable dithering */
+    COPYBIT_DITHER          = 3,
+    /* transformation applied (this is a superset of COPYBIT_ROTATION_DEG) */
+    COPYBIT_TRANSFORM       = 4,
+    /* blurs the copied bitmap. The amount of blurring cannot be changed
+     * at this time. */
+    COPYBIT_BLUR            = 5,
+    /* Blend mode */
+    COPYBIT_BLEND_MODE  = 6,
+    /* FB width */
+    COPYBIT_FRAMEBUFFER_WIDTH = 7,
+    /* FB height */
+    COPYBIT_FRAMEBUFFER_HEIGHT = 8,
+    COPYBIT_FG_LAYER = 9,
+    COPYBIT_DYNAMIC_FPS = 10,
+    /* Source Format Mode */
+    COPYBIT_SRC_FORMAT_MODE = 11,
+    /* Destination Format Mode */
+    COPYBIT_DST_FORMAT_MODE = 12,
+};
+
+/* values for copybit_set_parameter(COPYBIT_TRANSFORM) */
+enum {
+    /* flip source image horizontally */
+    COPYBIT_TRANSFORM_FLIP_H    = HAL_TRANSFORM_FLIP_H,
+    /* flip source image vertically */
+    COPYBIT_TRANSFORM_FLIP_V    = HAL_TRANSFORM_FLIP_V,
+    /* rotate source image 90 degres */
+    COPYBIT_TRANSFORM_ROT_90    = HAL_TRANSFORM_ROT_90,
+    /* rotate source image 180 degres */
+    COPYBIT_TRANSFORM_ROT_180   = HAL_TRANSFORM_ROT_180,
+    /* rotate source image 270 degres */
+    COPYBIT_TRANSFORM_ROT_270   = HAL_TRANSFORM_ROT_270,
+};
+
+/* enable/disable value copybit_set_parameter */
+enum {
+    COPYBIT_DISABLE = 0,
+    COPYBIT_ENABLE  = 1
+};
+
+/*
+ * copybit blending values. same as HWC blending values
+ */
+enum {
+    /* no blending */
+    COPYBIT_BLENDING_NONE     = 0x0100,
+
+    /* ONE / ONE_MINUS_SRC_ALPHA */
+    COPYBIT_BLENDING_PREMULT  = 0x0105,
+
+    /* SRC_ALPHA / ONE_MINUS_SRC_ALPHA */
+    COPYBIT_BLENDING_COVERAGE = 0x0405
+};
+
+enum {
+    /* Linear format mode*/
+    COPYBIT_LINEAR = 0x0000,
+    /* UBWC format mode*/
+    COPYBIT_UBWC_COMPRESSED = 0x0001,
+};
+
+/* use get_static_info() to query static informations about the hardware */
+enum {
+    /* Maximum amount of minification supported by the hardware*/
+    COPYBIT_MINIFICATION_LIMIT  = 1,
+    /* Maximum amount of magnification supported by the hardware */
+    COPYBIT_MAGNIFICATION_LIMIT = 2,
+    /* Number of fractional bits support by the scaling engine */
+    COPYBIT_SCALING_FRAC_BITS   = 3,
+    /* Supported rotation step in degres. */
+    COPYBIT_ROTATION_STEP_DEG   = 4,
+    /* UBWC support*/
+    COPYBIT_UBWC_SUPPORT        = 5,
+};
+
+/* Image structure */
+struct copybit_image_t {
+    /* width */
+    uint32_t    w;
+    /* height */
+    uint32_t    h;
+    /* format COPYBIT_FORMAT_xxx */
+    int32_t     format;
+    /* base of buffer with image */
+    void        *base;
+    /* handle to the image */
+    native_handle_t* handle;
+    /* number of pixels added for the stride */
+    uint32_t    horiz_padding;
+    /* number of pixels added for the vertical stride */
+    uint32_t    vert_padding;
+};
+
+/* Rectangle */
+struct copybit_rect_t {
+    /* left */
+    int l;
+    /* top */
+    int t;
+    /* right */
+    int r;
+    /* bottom */
+    int b;
+};
+
+/* Region */
+struct copybit_region_t {
+    int (*next)(struct copybit_region_t const *region, struct copybit_rect_t *rect);
+};
+
+/**
+ * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM
+ * and the fields of this data structure must begin with hw_module_t
+ * followed by module specific information.
+ */
+struct copybit_module_t {
+    struct hw_module_t common;
+};
+
+/**
+ * Every device data structure must begin with hw_device_t
+ * followed by module specific public methods and attributes.
+ */
+struct copybit_device_t {
+    struct hw_device_t common;
+
+    /**
+     * Set a copybit parameter.
+     *
+     * @param dev from open
+     * @param name one for the COPYBIT_NAME_xxx
+     * @param value one of the COPYBIT_VALUE_xxx
+     *
+     * @return 0 if successful
+     */
+    int (*set_parameter)(struct copybit_device_t *dev, int name, int value);
+
+    /**
+     * Get a static copybit information.
+     *
+     * @param dev from open
+     * @param name one of the COPYBIT_STATIC_xxx
+     *
+     * @return value or -EINVAL if error
+     */
+    int (*get)(struct copybit_device_t *dev, int name);
+
+    /**
+     * Execute the bit blit copy operation
+     *
+     * @param dev from open
+     * @param dst is the destination image
+     * @param src is the source image
+     * @param region the clip region
+     *
+     * @return 0 if successful
+     */
+    int (*blit)(struct copybit_device_t *dev,
+                struct copybit_image_t const *dst,
+                struct copybit_image_t const *src,
+                struct copybit_region_t const *region);
+
+    /**
+     * Give acquire fence to copybit to be used in upcoming stretch
+     * call
+     *
+     * @param dev from open
+     * @param acquireFenceFd is the acquire fence
+     *
+     * @return 0 if successful
+     */
+    int (*set_sync)(struct copybit_device_t *dev,
+                   int acquireFenceFd);
+
+    /**
+     * Execute the stretch bit blit copy operation
+     *
+     * @param dev from open
+     * @param dst is the destination image
+     * @param src is the source image
+     * @param dst_rect is the destination rectangle
+     * @param src_rect is the source rectangle
+     * @param region the clip region
+     *
+     * @return 0 if successful
+     */
+    int (*stretch)(struct copybit_device_t *dev,
+                   struct copybit_image_t const *dst,
+                   struct copybit_image_t const *src,
+                   struct copybit_rect_t const *dst_rect,
+                   struct copybit_rect_t const *src_rect,
+                   struct copybit_region_t const *region);
+
+    /**
+     * Fill the rect on dst with RGBA color
+     *
+     * @param dev from open
+     * @param dst is destination image
+     * @param rect is destination rectangle
+     * @param color is RGBA color to fill
+     *
+     * @return 0 if successful
+     */
+    int (*fill_color)(struct copybit_device_t *dev,
+                      struct copybit_image_t const *dst,
+                      struct copybit_rect_t const *rect,
+                      uint32_t color);
+
+  /**
+    * Execute the completion of the copybit draw operation.
+    *
+    * @param dev from open
+    *
+    * @return 0 if successful
+    */
+  int (*finish)(struct copybit_device_t *dev);
+
+  /**
+    * Trigger the copybit draw operation(async).
+    *
+    * @param dev from open
+    *
+    * @param fd - gets the fencefd
+    *
+    * @return 0 if successful
+    */
+  int (*flush_get_fence)(struct copybit_device_t *dev, int* fd);
+
+  /* Clears the buffer
+   */
+  int (*clear)(struct copybit_device_t *dev, struct copybit_image_t const *buf,
+               struct copybit_rect_t *rect);
+};
+
+
+/** convenience API for opening and closing a device */
+
+static inline int copybit_open(const struct hw_module_t* module,
+                               struct copybit_device_t** device) {
+    return module->methods->open(module,
+                                 COPYBIT_HARDWARE_COPYBIT0, (struct hw_device_t**)device);
+}
+
+static inline int copybit_close(struct copybit_device_t* device) {
+    return device->common.close(&device->common);
+}
+
+
+__END_DECLS
+
+#endif  // ANDROID_COPYBIT_INTERFACE_H
diff --git a/msmcobalt/libcopybit/copybit_c2d.cpp b/msmcobalt/libcopybit/copybit_c2d.cpp
new file mode 100644
index 0000000..240ba26
--- /dev/null
+++ b/msmcobalt/libcopybit/copybit_c2d.cpp
@@ -0,0 +1,1776 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
+ *
+ * Not a Contribution, Apache license notifications and license are retained
+ * for attribution purposes only.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      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 <sys/resource.h>
+#include <sys/prctl.h>
+
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <linux/msm_kgsl.h>
+
+#include <EGL/eglplatform.h>
+#include <cutils/native_handle.h>
+
+#include <copybit.h>
+#include <alloc_controller.h>
+#include <memalloc.h>
+
+#include "c2d2.h"
+#include "software_converter.h"
+
+#include <dlfcn.h>
+
+using gralloc::IMemAlloc;
+using gralloc::IonController;
+using gralloc::alloc_data;
+
+C2D_STATUS (*LINK_c2dCreateSurface)( uint32 *surface_id,
+                                     uint32 surface_bits,
+                                     C2D_SURFACE_TYPE surface_type,
+                                     void *surface_definition );
+
+C2D_STATUS (*LINK_c2dUpdateSurface)( uint32 surface_id,
+                                     uint32 surface_bits,
+                                     C2D_SURFACE_TYPE surface_type,
+                                     void *surface_definition );
+
+C2D_STATUS (*LINK_c2dReadSurface)( uint32 surface_id,
+                                   C2D_SURFACE_TYPE surface_type,
+                                   void *surface_definition,
+                                   int32 x, int32 y );
+
+C2D_STATUS (*LINK_c2dDraw)( uint32 target_id,
+                            uint32 target_config, C2D_RECT *target_scissor,
+                            uint32 target_mask_id, uint32 target_color_key,
+                            C2D_OBJECT *objects_list, uint32 num_objects );
+
+C2D_STATUS (*LINK_c2dFinish)( uint32 target_id);
+
+C2D_STATUS (*LINK_c2dFlush)( uint32 target_id, c2d_ts_handle *timestamp);
+
+C2D_STATUS (*LINK_c2dWaitTimestamp)( c2d_ts_handle timestamp );
+
+C2D_STATUS (*LINK_c2dDestroySurface)( uint32 surface_id );
+
+C2D_STATUS (*LINK_c2dMapAddr) ( int mem_fd, void * hostptr, size_t len,
+                                size_t offset, uint32 flags, void ** gpuaddr);
+
+C2D_STATUS (*LINK_c2dUnMapAddr) ( void * gpuaddr);
+
+C2D_STATUS (*LINK_c2dGetDriverCapabilities) ( C2D_DRIVER_INFO * driver_info);
+
+/* create a fence fd for the timestamp */
+C2D_STATUS (*LINK_c2dCreateFenceFD) ( uint32 target_id, c2d_ts_handle timestamp,
+                                                            int32 *fd);
+
+C2D_STATUS (*LINK_c2dFillSurface) ( uint32 surface_id, uint32 fill_color,
+                                    C2D_RECT * fill_rect);
+
+/******************************************************************************/
+
+#if defined(COPYBIT_Z180)
+#define MAX_SCALE_FACTOR    (4096)
+#define MAX_DIMENSION       (4096)
+#else
+#error "Unsupported HW version"
+#endif
+
+// The following defines can be changed as required i.e. as we encounter
+// complex use cases.
+#define MAX_RGB_SURFACES 32       // Max. RGB layers currently supported per draw
+#define MAX_YUV_2_PLANE_SURFACES 4// Max. 2-plane YUV layers currently supported per draw
+#define MAX_YUV_3_PLANE_SURFACES 1// Max. 3-plane YUV layers currently supported per draw
+// +1 for the destination surface. We cannot have multiple destination surfaces.
+#define MAX_SURFACES (MAX_RGB_SURFACES + MAX_YUV_2_PLANE_SURFACES + MAX_YUV_3_PLANE_SURFACES + 1)
+#define NUM_SURFACE_TYPES 3      // RGB_SURFACE + YUV_SURFACE_2_PLANES + YUV_SURFACE_3_PLANES
+#define MAX_BLIT_OBJECT_COUNT 50 // Max. blit objects that can be passed per draw
+
+enum {
+    RGB_SURFACE,
+    YUV_SURFACE_2_PLANES,
+    YUV_SURFACE_3_PLANES
+};
+
+enum eConversionType {
+    CONVERT_TO_ANDROID_FORMAT,
+    CONVERT_TO_C2D_FORMAT
+};
+
+enum eC2DFlags {
+    FLAGS_PREMULTIPLIED_ALPHA  = 1<<0,
+    FLAGS_YUV_DESTINATION      = 1<<1,
+    FLAGS_TEMP_SRC_DST         = 1<<2,
+    FLAGS_UBWC_FORMAT_MODE     = 1<<3
+};
+
+static gralloc::IAllocController* sAlloc = 0;
+/******************************************************************************/
+
+/** State information for each device instance */
+struct copybit_context_t {
+    struct copybit_device_t device;
+    // Templates for the various source surfaces. These templates are created
+    // to avoid the expensive create/destroy C2D Surfaces
+    C2D_OBJECT_STR blit_rgb_object[MAX_RGB_SURFACES];
+    C2D_OBJECT_STR blit_yuv_2_plane_object[MAX_YUV_2_PLANE_SURFACES];
+    C2D_OBJECT_STR blit_yuv_3_plane_object[MAX_YUV_3_PLANE_SURFACES];
+    C2D_OBJECT_STR blit_list[MAX_BLIT_OBJECT_COUNT]; // Z-ordered list of blit objects
+    C2D_DRIVER_INFO c2d_driver_info;
+    void *libc2d2;
+    alloc_data temp_src_buffer;
+    alloc_data temp_dst_buffer;
+    unsigned int dst[NUM_SURFACE_TYPES]; // dst surfaces
+    uintptr_t mapped_gpu_addr[MAX_SURFACES]; // GPU addresses mapped inside copybit
+    int blit_rgb_count;         // Total RGB surfaces being blit
+    int blit_yuv_2_plane_count; // Total 2 plane YUV surfaces being
+    int blit_yuv_3_plane_count; // Total 3 plane YUV  surfaces being blit
+    int blit_count;             // Total blit objects.
+    unsigned int trg_transform;      /* target transform */
+    int fb_width;
+    int fb_height;
+    int src_global_alpha;
+    int config_mask;
+    int dst_surface_type;
+    bool is_premultiplied_alpha;
+    void* time_stamp;
+    bool dst_surface_mapped; // Set when dst surface is mapped to GPU addr
+    void* dst_surface_base; // Stores the dst surface addr
+    bool is_src_ubwc_format;
+    bool is_dst_ubwc_format;
+
+    // used for signaling the wait thread
+    bool wait_timestamp;
+    pthread_t wait_thread_id;
+    bool stop_thread;
+    pthread_mutex_t wait_cleanup_lock;
+    pthread_cond_t wait_cleanup_cond;
+
+};
+
+struct bufferInfo {
+    int width;
+    int height;
+    int format;
+};
+
+struct yuvPlaneInfo {
+    int yStride;       //luma stride
+    int plane1_stride;
+    int plane2_stride;
+    size_t plane1_offset;
+    size_t plane2_offset;
+};
+
+/**
+ * Common hardware methods
+ */
+
+static int open_copybit(const struct hw_module_t* module, const char* name,
+                        struct hw_device_t** device);
+
+static struct hw_module_methods_t copybit_module_methods = {
+    .open = open_copybit,
+};
+
+/*
+ * The COPYBIT Module
+ */
+struct copybit_module_t HAL_MODULE_INFO_SYM = {
+    .common = {
+        .tag =  HARDWARE_MODULE_TAG,
+        .version_major = 1,
+        .version_minor = 0,
+        .id = COPYBIT_HARDWARE_MODULE_ID,
+        .name = "QCT COPYBIT C2D 2.0 Module",
+        .author = "Qualcomm",
+        .methods =  &copybit_module_methods
+    }
+};
+
+
+/* thread function which waits on the timeStamp and cleans up the surfaces */
+static void* c2d_wait_loop(void* ptr) {
+    copybit_context_t* ctx = (copybit_context_t*)(ptr);
+    char thread_name[64] = "copybitWaitThr";
+    prctl(PR_SET_NAME, (unsigned long) &thread_name, 0, 0, 0);
+    setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
+
+    while(ctx->stop_thread == false) {
+        pthread_mutex_lock(&ctx->wait_cleanup_lock);
+        while(ctx->wait_timestamp == false && !ctx->stop_thread) {
+            pthread_cond_wait(&(ctx->wait_cleanup_cond),
+                              &(ctx->wait_cleanup_lock));
+        }
+        if(ctx->wait_timestamp) {
+            if(LINK_c2dWaitTimestamp(ctx->time_stamp)) {
+                ALOGE("%s: LINK_c2dWaitTimeStamp ERROR!!", __FUNCTION__);
+            }
+            ctx->wait_timestamp = false;
+            // Unmap any mapped addresses.
+            for (int i = 0; i < MAX_SURFACES; i++) {
+                if (ctx->mapped_gpu_addr[i]) {
+                    LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[i]);
+                    ctx->mapped_gpu_addr[i] = 0;
+                }
+            }
+            // Reset the counts after the draw.
+            ctx->blit_rgb_count = 0;
+            ctx->blit_yuv_2_plane_count = 0;
+            ctx->blit_yuv_3_plane_count = 0;
+            ctx->blit_count = 0;
+            ctx->dst_surface_mapped = false;
+            ctx->dst_surface_base = 0;
+        }
+        pthread_mutex_unlock(&ctx->wait_cleanup_lock);
+        if(ctx->stop_thread)
+            break;
+    }
+    pthread_exit(NULL);
+    return NULL;
+}
+
+
+/* convert COPYBIT_FORMAT to C2D format */
+static int get_format(int format) {
+    switch (format) {
+        case HAL_PIXEL_FORMAT_RGB_565:        return C2D_COLOR_FORMAT_565_RGB;
+        case HAL_PIXEL_FORMAT_RGB_888:        return C2D_COLOR_FORMAT_888_RGB |
+                                              C2D_FORMAT_SWAP_RB;
+        case HAL_PIXEL_FORMAT_RGBX_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
+                                              C2D_FORMAT_SWAP_RB |
+                                                  C2D_FORMAT_DISABLE_ALPHA;
+        case HAL_PIXEL_FORMAT_RGBA_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
+                                              C2D_FORMAT_SWAP_RB;
+        case HAL_PIXEL_FORMAT_BGRA_8888:      return C2D_COLOR_FORMAT_8888_ARGB;
+        case HAL_PIXEL_FORMAT_RGBA_5551:      return C2D_COLOR_FORMAT_5551_RGBA;
+        case HAL_PIXEL_FORMAT_RGBA_4444:      return C2D_COLOR_FORMAT_4444_RGBA;
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP:   return C2D_COLOR_FORMAT_420_NV12;
+        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV12;
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP:   return C2D_COLOR_FORMAT_420_NV21;
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: return C2D_COLOR_FORMAT_420_NV12 |
+                                                  C2D_FORMAT_MACROTILED;
+        default:                              ALOGE("%s: invalid format (0x%x",
+                                                     __FUNCTION__, format);
+                                              return -EINVAL;
+    }
+    return -EINVAL;
+}
+
+/* Get the C2D formats needed for conversion to YUV */
+static int get_c2d_format_for_yuv_destination(int halFormat) {
+    switch (halFormat) {
+        // We do not swap the RB when the target is YUV
+        case HAL_PIXEL_FORMAT_RGBX_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
+                                              C2D_FORMAT_DISABLE_ALPHA;
+        case HAL_PIXEL_FORMAT_RGBA_8888:      return C2D_COLOR_FORMAT_8888_ARGB;
+        // The U and V need to be interchanged when the target is YUV
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP:   return C2D_COLOR_FORMAT_420_NV21;
+        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV21;
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP:   return C2D_COLOR_FORMAT_420_NV12;
+        default:                              return get_format(halFormat);
+    }
+    return -EINVAL;
+}
+
+/* ------------------------------------------------------------------- *//*!
+ * \internal
+ * \brief Get the bpp for a particular color format
+ * \param color format
+ * \return bits per pixel
+ *//* ------------------------------------------------------------------- */
+int c2diGetBpp(int32 colorformat)
+{
+
+    int c2dBpp = 0;
+
+    switch(colorformat&0xFF)
+    {
+        case C2D_COLOR_FORMAT_4444_RGBA:
+        case C2D_COLOR_FORMAT_4444_ARGB:
+        case C2D_COLOR_FORMAT_1555_ARGB:
+        case C2D_COLOR_FORMAT_565_RGB:
+        case C2D_COLOR_FORMAT_5551_RGBA:
+            c2dBpp = 16;
+            break;
+        case C2D_COLOR_FORMAT_8888_RGBA:
+        case C2D_COLOR_FORMAT_8888_ARGB:
+            c2dBpp = 32;
+            break;
+        case C2D_COLOR_FORMAT_888_RGB:
+            c2dBpp = 24;
+            break;
+        case C2D_COLOR_FORMAT_8_L:
+        case C2D_COLOR_FORMAT_8_A:
+            c2dBpp = 8;
+            break;
+        case C2D_COLOR_FORMAT_4_A:
+            c2dBpp = 4;
+            break;
+        case C2D_COLOR_FORMAT_1:
+            c2dBpp = 1;
+            break;
+        default:
+            ALOGE("%s ERROR", __func__);
+            break;
+    }
+    return c2dBpp;
+}
+
+static size_t c2d_get_gpuaddr(copybit_context_t* ctx,
+                              struct private_handle_t *handle, int &mapped_idx)
+{
+    uint32 memtype;
+    size_t *gpuaddr = 0;
+    C2D_STATUS rc;
+    int freeindex = 0;
+    bool mapaddr = false;
+
+    if(!handle)
+        return 0;
+
+    if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ION)
+        memtype = KGSL_USER_MEM_TYPE_ION;
+    else {
+        ALOGE("Invalid handle flags: 0x%x", handle->flags);
+        return 0;
+    }
+
+    // Check for a freeindex in the mapped_gpu_addr list
+    for (freeindex = 0; freeindex < MAX_SURFACES; freeindex++) {
+        if (ctx->mapped_gpu_addr[freeindex] == 0) {
+            // free index is available
+            // map GPU addr and use this as mapped_idx
+            mapaddr = true;
+            break;
+        }
+    }
+
+    if(mapaddr) {
+        rc = LINK_c2dMapAddr(handle->fd, (void*)handle->base, handle->size,
+                             handle->offset, memtype, (void**)&gpuaddr);
+
+        if (rc == C2D_STATUS_OK) {
+            // We have mapped the GPU address inside copybit. We need to unmap
+            // this address after the blit. Store this address
+            ctx->mapped_gpu_addr[freeindex] = (size_t)gpuaddr;
+            mapped_idx = freeindex;
+        }
+    }
+    return (size_t)gpuaddr;
+}
+
+static void unmap_gpuaddr(copybit_context_t* ctx, int mapped_idx)
+{
+    if (!ctx || (mapped_idx == -1))
+        return;
+
+    if (ctx->mapped_gpu_addr[mapped_idx]) {
+        LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[mapped_idx]);
+        ctx->mapped_gpu_addr[mapped_idx] = 0;
+    }
+}
+
+static int is_supported_rgb_format(int format)
+{
+    switch(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: {
+            return COPYBIT_SUCCESS;
+        }
+        default:
+            return COPYBIT_FAILURE;
+    }
+}
+
+static int get_num_planes(int format)
+{
+    switch(format) {
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
+            return 2;
+        }
+        case HAL_PIXEL_FORMAT_YV12: {
+            return 3;
+        }
+        default:
+            return COPYBIT_FAILURE;
+    }
+}
+
+static int is_supported_yuv_format(int format)
+{
+    switch(format) {
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
+            return COPYBIT_SUCCESS;
+        }
+        default:
+            return COPYBIT_FAILURE;
+    }
+}
+
+static int is_valid_destination_format(int format)
+{
+    if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
+        // C2D does not support NV12Tile as a destination format.
+        return COPYBIT_FAILURE;
+    }
+    return COPYBIT_SUCCESS;
+}
+
+static int calculate_yuv_offset_and_stride(const bufferInfo& info,
+                                           yuvPlaneInfo& yuvInfo)
+{
+    int width  = info.width;
+    int height = info.height;
+    int format = info.format;
+
+    int aligned_height = 0;
+    int aligned_width = 0, size = 0;
+
+    switch (format) {
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
+            /* NV12 Tile buffers have their luma height aligned to 32bytes and width
+             * aligned to 128 bytes. The chroma offset starts at an 8K boundary
+             */
+            aligned_height = ALIGN(height, 32);
+            aligned_width  = ALIGN(width, 128);
+            size = aligned_width * aligned_height;
+            yuvInfo.plane1_offset = ALIGN(size,8192);
+            yuvInfo.yStride = aligned_width;
+            yuvInfo.plane1_stride = aligned_width;
+            break;
+        }
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP: {
+            aligned_width = ALIGN(width, 32);
+            yuvInfo.yStride = aligned_width;
+            yuvInfo.plane1_stride = aligned_width;
+            if (HAL_PIXEL_FORMAT_NV12_ENCODEABLE == format) {
+                // The encoder requires a 2K aligned chroma offset
+                yuvInfo.plane1_offset = ALIGN(aligned_width * height, 2048);
+            } else
+                yuvInfo.plane1_offset = aligned_width * height;
+
+            break;
+        }
+        default: {
+            return COPYBIT_FAILURE;
+        }
+    }
+    return COPYBIT_SUCCESS;
+}
+
+/** create C2D surface from copybit image */
+static int set_image(copybit_context_t* ctx, uint32 surfaceId,
+                      const struct copybit_image_t *rhs,
+                      const eC2DFlags flags, int &mapped_idx)
+{
+    struct private_handle_t* handle = (struct private_handle_t*)rhs->handle;
+    C2D_SURFACE_TYPE surfaceType;
+    int status = COPYBIT_SUCCESS;
+    uint64_t gpuaddr = 0;
+    int c2d_format;
+    mapped_idx = -1;
+
+    if (flags & FLAGS_YUV_DESTINATION) {
+        c2d_format = get_c2d_format_for_yuv_destination(rhs->format);
+    } else {
+        c2d_format = get_format(rhs->format);
+    }
+
+    if(c2d_format == -EINVAL) {
+        ALOGE("%s: invalid format", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    if(handle == NULL) {
+        ALOGE("%s: invalid handle", __func__);
+        return -EINVAL;
+    }
+
+    if (handle->gpuaddr == 0) {
+        gpuaddr = c2d_get_gpuaddr(ctx, handle, mapped_idx);
+        if(!gpuaddr) {
+            ALOGE("%s: c2d_get_gpuaddr failed", __FUNCTION__);
+            return COPYBIT_FAILURE;
+        }
+    } else {
+        gpuaddr = handle->gpuaddr;
+    }
+
+    /* create C2D surface */
+    if(is_supported_rgb_format(rhs->format) == COPYBIT_SUCCESS) {
+        /* RGB */
+        C2D_RGB_SURFACE_DEF surfaceDef;
+
+        surfaceType = (C2D_SURFACE_TYPE) (C2D_SURFACE_RGB_HOST | C2D_SURFACE_WITH_PHYS);
+
+        surfaceDef.phys = (void*) gpuaddr;
+        surfaceDef.buffer = (void*) (handle->base);
+
+        surfaceDef.format = c2d_format |
+            ((flags & FLAGS_PREMULTIPLIED_ALPHA) ? C2D_FORMAT_PREMULTIPLIED : 0);
+
+        surfaceDef.format = surfaceDef.format |
+            ((flags & FLAGS_UBWC_FORMAT_MODE) ? C2D_FORMAT_UBWC_COMPRESSED : 0);
+
+        surfaceDef.width = rhs->w;
+        surfaceDef.height = rhs->h;
+        int aligned_width = ALIGN((int)surfaceDef.width,32);
+        surfaceDef.stride = (aligned_width * c2diGetBpp(surfaceDef.format))>>3;
+
+        if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType,
+                                  &surfaceDef)) {
+            ALOGE("%s: RGB Surface c2dUpdateSurface ERROR", __FUNCTION__);
+            unmap_gpuaddr(ctx, mapped_idx);
+            status = COPYBIT_FAILURE;
+        }
+    } else if (is_supported_yuv_format(rhs->format) == COPYBIT_SUCCESS) {
+        C2D_YUV_SURFACE_DEF surfaceDef;
+        memset(&surfaceDef, 0, sizeof(surfaceDef));
+        surfaceType = (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS);
+        surfaceDef.format = c2d_format;
+
+        bufferInfo info;
+        info.width = rhs->w;
+        info.height = rhs->h;
+        info.format = rhs->format;
+
+        yuvPlaneInfo yuvInfo = {0};
+        status = calculate_yuv_offset_and_stride(info, yuvInfo);
+        if(status != COPYBIT_SUCCESS) {
+            ALOGE("%s: calculate_yuv_offset_and_stride error", __FUNCTION__);
+            unmap_gpuaddr(ctx, mapped_idx);
+        }
+
+        surfaceDef.width = rhs->w;
+        surfaceDef.height = rhs->h;
+        surfaceDef.plane0 = (void*) (handle->base);
+        surfaceDef.phys0 = (void*) (gpuaddr);
+        surfaceDef.stride0 = yuvInfo.yStride;
+
+        surfaceDef.plane1 = (void*) (handle->base + yuvInfo.plane1_offset);
+        surfaceDef.phys1 = (void*) (gpuaddr + yuvInfo.plane1_offset);
+        surfaceDef.stride1 = yuvInfo.plane1_stride;
+        if (3 == get_num_planes(rhs->format)) {
+            surfaceDef.plane2 = (void*) (handle->base + yuvInfo.plane2_offset);
+            surfaceDef.phys2 = (void*) (gpuaddr + yuvInfo.plane2_offset);
+            surfaceDef.stride2 = yuvInfo.plane2_stride;
+        }
+
+        if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType,
+                                  &surfaceDef)) {
+            ALOGE("%s: YUV Surface c2dUpdateSurface ERROR", __FUNCTION__);
+            unmap_gpuaddr(ctx, mapped_idx);
+            status = COPYBIT_FAILURE;
+        }
+    } else {
+        ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format);
+        unmap_gpuaddr(ctx, mapped_idx);
+        status = COPYBIT_FAILURE;
+    }
+
+    return status;
+}
+
+/** copy the bits */
+static int msm_copybit(struct copybit_context_t *ctx, unsigned int target)
+{
+    if (ctx->blit_count == 0) {
+        return COPYBIT_SUCCESS;
+    }
+
+    for (int i = 0; i < ctx->blit_count; i++)
+    {
+        ctx->blit_list[i].next = &(ctx->blit_list[i+1]);
+    }
+    ctx->blit_list[ctx->blit_count-1].next = NULL;
+    uint32_t target_transform = ctx->trg_transform;
+    if (ctx->c2d_driver_info.capabilities_mask &
+        C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP) {
+        // For A3xx - set 0x0 as the transform is set in the config_mask
+        target_transform = 0x0;
+    }
+    if(LINK_c2dDraw(target, target_transform, 0x0, 0, 0, ctx->blit_list,
+                    ctx->blit_count)) {
+        ALOGE("%s: LINK_c2dDraw ERROR", __FUNCTION__);
+        return COPYBIT_FAILURE;
+    }
+    return COPYBIT_SUCCESS;
+}
+
+
+
+static int flush_get_fence_copybit (struct copybit_device_t *dev, int* fd)
+{
+    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    int status = COPYBIT_FAILURE;
+    if (!ctx)
+        return COPYBIT_FAILURE;
+    pthread_mutex_lock(&ctx->wait_cleanup_lock);
+    status = msm_copybit(ctx, ctx->dst[ctx->dst_surface_type]);
+
+    if(LINK_c2dFlush(ctx->dst[ctx->dst_surface_type], &ctx->time_stamp)) {
+        ALOGE("%s: LINK_c2dFlush ERROR", __FUNCTION__);
+        // unlock the mutex and return failure
+        pthread_mutex_unlock(&ctx->wait_cleanup_lock);
+        return COPYBIT_FAILURE;
+    }
+    if(LINK_c2dCreateFenceFD(ctx->dst[ctx->dst_surface_type], ctx->time_stamp,
+                                                                        fd)) {
+        ALOGE("%s: LINK_c2dCreateFenceFD ERROR", __FUNCTION__);
+        status = COPYBIT_FAILURE;
+    }
+    if(status == COPYBIT_SUCCESS) {
+        //signal the wait_thread
+        ctx->wait_timestamp = true;
+        pthread_cond_signal(&ctx->wait_cleanup_cond);
+    }
+    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
+    return status;
+}
+
+static int finish_copybit(struct copybit_device_t *dev)
+{
+    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    if (!ctx)
+        return COPYBIT_FAILURE;
+
+   int status = msm_copybit(ctx, ctx->dst[ctx->dst_surface_type]);
+
+   if(LINK_c2dFinish(ctx->dst[ctx->dst_surface_type])) {
+        ALOGE("%s: LINK_c2dFinish ERROR", __FUNCTION__);
+        return COPYBIT_FAILURE;
+    }
+
+    // Unmap any mapped addresses.
+    for (int i = 0; i < MAX_SURFACES; i++) {
+        if (ctx->mapped_gpu_addr[i]) {
+            LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[i]);
+            ctx->mapped_gpu_addr[i] = 0;
+        }
+    }
+
+    // Reset the counts after the draw.
+    ctx->blit_rgb_count = 0;
+    ctx->blit_yuv_2_plane_count = 0;
+    ctx->blit_yuv_3_plane_count = 0;
+    ctx->blit_count = 0;
+    ctx->dst_surface_mapped = false;
+    ctx->dst_surface_base = 0;
+
+    return status;
+}
+
+static int clear_copybit(struct copybit_device_t *dev,
+                         struct copybit_image_t const *buf,
+                         struct copybit_rect_t *rect)
+{
+    int ret = COPYBIT_SUCCESS;
+    int flags = FLAGS_PREMULTIPLIED_ALPHA;
+    int mapped_dst_idx = -1;
+    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    if (ctx->is_dst_ubwc_format)
+        flags |= FLAGS_UBWC_FORMAT_MODE;
+    C2D_RECT c2drect = {rect->l, rect->t, rect->r - rect->l, rect->b - rect->t};
+    pthread_mutex_lock(&ctx->wait_cleanup_lock);
+    if(!ctx->dst_surface_mapped) {
+        ret = set_image(ctx, ctx->dst[RGB_SURFACE], buf,
+                        (eC2DFlags)flags, mapped_dst_idx);
+        if(ret) {
+            ALOGE("%s: set_image error", __FUNCTION__);
+            unmap_gpuaddr(ctx, mapped_dst_idx);
+            pthread_mutex_unlock(&ctx->wait_cleanup_lock);
+            return COPYBIT_FAILURE;
+        }
+        //clear_copybit is the first call made by HWC for each composition
+        //with the dest surface, hence set dst_surface_mapped.
+        ctx->dst_surface_mapped = true;
+        ctx->dst_surface_base = buf->base;
+        ret = LINK_c2dFillSurface(ctx->dst[RGB_SURFACE], 0x0, &c2drect);
+    }
+    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
+    return ret;
+}
+
+
+/** setup rectangles */
+static void set_rects(struct copybit_context_t *ctx,
+                      C2D_OBJECT *c2dObject,
+                      const struct copybit_rect_t *dst,
+                      const struct copybit_rect_t *src,
+                      const struct copybit_rect_t *scissor)
+{
+    // Set the target rect.
+    if((ctx->trg_transform & C2D_TARGET_ROTATE_90) &&
+       (ctx->trg_transform & C2D_TARGET_ROTATE_180)) {
+        /* target rotation is 270 */
+        c2dObject->target_rect.x        = (dst->t)<<16;
+        c2dObject->target_rect.y        = ctx->fb_width?
+                (ALIGN(ctx->fb_width,32)- dst->r):dst->r;
+        c2dObject->target_rect.y        = c2dObject->target_rect.y<<16;
+        c2dObject->target_rect.height   = ((dst->r) - (dst->l))<<16;
+        c2dObject->target_rect.width    = ((dst->b) - (dst->t))<<16;
+    } else if(ctx->trg_transform & C2D_TARGET_ROTATE_90) {
+        c2dObject->target_rect.x        = ctx->fb_height?(ctx->fb_height - dst->b):dst->b;
+        c2dObject->target_rect.x        = c2dObject->target_rect.x<<16;
+        c2dObject->target_rect.y        = (dst->l)<<16;
+        c2dObject->target_rect.height   = ((dst->r) - (dst->l))<<16;
+        c2dObject->target_rect.width    = ((dst->b) - (dst->t))<<16;
+    } else if(ctx->trg_transform & C2D_TARGET_ROTATE_180) {
+        c2dObject->target_rect.y        = ctx->fb_height?(ctx->fb_height - dst->b):dst->b;
+        c2dObject->target_rect.y        = c2dObject->target_rect.y<<16;
+        c2dObject->target_rect.x        = ctx->fb_width?
+                (ALIGN(ctx->fb_width,32) - dst->r):dst->r;
+        c2dObject->target_rect.x        = c2dObject->target_rect.x<<16;
+        c2dObject->target_rect.height   = ((dst->b) - (dst->t))<<16;
+        c2dObject->target_rect.width    = ((dst->r) - (dst->l))<<16;
+    } else {
+        c2dObject->target_rect.x        = (dst->l)<<16;
+        c2dObject->target_rect.y        = (dst->t)<<16;
+        c2dObject->target_rect.height   = ((dst->b) - (dst->t))<<16;
+        c2dObject->target_rect.width    = ((dst->r) - (dst->l))<<16;
+    }
+    c2dObject->config_mask |= C2D_TARGET_RECT_BIT;
+
+    // Set the source rect
+    c2dObject->source_rect.x        = (src->l)<<16;
+    c2dObject->source_rect.y        = (src->t)<<16;
+    c2dObject->source_rect.height   = ((src->b) - (src->t))<<16;
+    c2dObject->source_rect.width    = ((src->r) - (src->l))<<16;
+    c2dObject->config_mask |= C2D_SOURCE_RECT_BIT;
+
+    // Set the scissor rect
+    c2dObject->scissor_rect.x       = scissor->l;
+    c2dObject->scissor_rect.y       = scissor->t;
+    c2dObject->scissor_rect.height  = (scissor->b) - (scissor->t);
+    c2dObject->scissor_rect.width   = (scissor->r) - (scissor->l);
+    c2dObject->config_mask |= C2D_SCISSOR_RECT_BIT;
+}
+
+/*****************************************************************************/
+
+/** Set a parameter to value */
+static int set_parameter_copybit(
+    struct copybit_device_t *dev,
+    int name,
+    int value)
+{
+    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    int status = COPYBIT_SUCCESS;
+    if (!ctx) {
+        ALOGE("%s: null context", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    pthread_mutex_lock(&ctx->wait_cleanup_lock);
+    switch(name) {
+        case COPYBIT_PLANE_ALPHA:
+        {
+            if (value < 0)      value = 0;
+            if (value >= 256)   value = 255;
+
+            ctx->src_global_alpha = value;
+            if (value < 255)
+                ctx->config_mask |= C2D_GLOBAL_ALPHA_BIT;
+            else
+                ctx->config_mask &= ~C2D_GLOBAL_ALPHA_BIT;
+        }
+        break;
+        case COPYBIT_BLEND_MODE:
+        {
+            if (value == COPYBIT_BLENDING_NONE) {
+                ctx->config_mask |= C2D_ALPHA_BLEND_NONE;
+                ctx->is_premultiplied_alpha = true;
+            } else if (value == COPYBIT_BLENDING_PREMULT) {
+                ctx->is_premultiplied_alpha = true;
+            } else {
+                ctx->config_mask &= ~C2D_ALPHA_BLEND_NONE;
+            }
+        }
+        break;
+        case COPYBIT_TRANSFORM:
+        {
+            unsigned int transform = 0;
+            uint32 config_mask = 0;
+            config_mask |= C2D_OVERRIDE_GLOBAL_TARGET_ROTATE_CONFIG;
+            if((value & 0x7) == COPYBIT_TRANSFORM_ROT_180) {
+                transform = C2D_TARGET_ROTATE_180;
+                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_180;
+            } else if((value & 0x7) == COPYBIT_TRANSFORM_ROT_270) {
+                transform = C2D_TARGET_ROTATE_90;
+                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_90;
+            } else if(value == COPYBIT_TRANSFORM_ROT_90) {
+                transform = C2D_TARGET_ROTATE_270;
+                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_270;
+            } else {
+                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_0;
+                if(value & COPYBIT_TRANSFORM_FLIP_H) {
+                    config_mask |= C2D_MIRROR_H_BIT;
+                } else if(value & COPYBIT_TRANSFORM_FLIP_V) {
+                    config_mask |= C2D_MIRROR_V_BIT;
+                }
+            }
+
+            if (ctx->c2d_driver_info.capabilities_mask &
+                C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP) {
+                ctx->config_mask |= config_mask;
+            } else {
+                // The transform for this surface does not match the current
+                // target transform. Draw all previous surfaces. This will be
+                // changed once we have a new mechanism to send different
+                // target rotations to c2d.
+                finish_copybit(dev);
+            }
+            ctx->trg_transform = transform;
+        }
+        break;
+        case COPYBIT_FRAMEBUFFER_WIDTH:
+            ctx->fb_width = value;
+            break;
+        case COPYBIT_FRAMEBUFFER_HEIGHT:
+            ctx->fb_height = value;
+            break;
+        case COPYBIT_ROTATION_DEG:
+        case COPYBIT_DITHER:
+        case COPYBIT_BLUR:
+        case COPYBIT_BLIT_TO_FRAMEBUFFER:
+            // Do nothing
+            break;
+        case COPYBIT_SRC_FORMAT_MODE:
+            ctx->is_src_ubwc_format = (value == COPYBIT_UBWC_COMPRESSED);
+            break;
+        case COPYBIT_DST_FORMAT_MODE:
+            ctx->is_dst_ubwc_format = (value == COPYBIT_UBWC_COMPRESSED);
+            break;
+        default:
+            ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
+            status = -EINVAL;
+            break;
+    }
+    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
+    return status;
+}
+
+/** Get a static info value */
+static int get(struct copybit_device_t *dev, int name)
+{
+    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    int value;
+
+    if (!ctx) {
+        ALOGE("%s: null context error", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    switch(name) {
+        case COPYBIT_MINIFICATION_LIMIT:
+            value = MAX_SCALE_FACTOR;
+            break;
+        case COPYBIT_MAGNIFICATION_LIMIT:
+            value = MAX_SCALE_FACTOR;
+            break;
+        case COPYBIT_SCALING_FRAC_BITS:
+            value = 32;
+            break;
+        case COPYBIT_ROTATION_STEP_DEG:
+            value = 1;
+            break;
+        case COPYBIT_UBWC_SUPPORT:
+            value = 0;
+            if (ctx->c2d_driver_info.capabilities_mask & C2D_DRIVER_SUPPORTS_UBWC_COMPRESSED_OP) {
+                value = 1;
+            }
+            break;
+        default:
+            ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
+            value = -EINVAL;
+    }
+    return value;
+}
+
+/* Function to check if we need a temporary buffer for the blit.
+ * This would happen if the requested destination stride and the
+ * C2D stride do not match. We ignore RGB buffers, since their
+ * stride is always aligned to 32.
+ */
+static bool need_temp_buffer(struct copybit_image_t const *img)
+{
+    if (COPYBIT_SUCCESS == is_supported_rgb_format(img->format))
+        return false;
+
+    struct private_handle_t* handle = (struct private_handle_t*)img->handle;
+
+    // The width parameter in the handle contains the aligned_w. We check if we
+    // need to convert based on this param. YUV formats have bpp=1, so checking
+    // if the requested stride is aligned should suffice.
+    if (0 == (handle->width)%32) {
+        return false;
+    }
+
+    return true;
+}
+
+/* Function to extract the information from the copybit image and set the corresponding
+ * values in the bufferInfo struct.
+ */
+static void populate_buffer_info(struct copybit_image_t const *img, bufferInfo& info)
+{
+    info.width = img->w;
+    info.height = img->h;
+    info.format = img->format;
+}
+
+/* Function to get the required size for a particular format, inorder for C2D to perform
+ * the blit operation.
+ */
+static int get_size(const bufferInfo& info)
+{
+    int size = 0;
+    int w = info.width;
+    int h = info.height;
+    int aligned_w = ALIGN(w, 32);
+    switch(info.format) {
+        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+            {
+                // Chroma for this format is aligned to 2K.
+                size = ALIGN((aligned_w*h), 2048) +
+                        ALIGN(aligned_w/2, 32) * (h/2) *2;
+                size = ALIGN(size, 4096);
+            } break;
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+            {
+                size = aligned_w * h +
+                       ALIGN(aligned_w/2, 32) * (h/2) * 2;
+                size = ALIGN(size, 4096);
+            } break;
+        default: break;
+    }
+    return size;
+}
+
+/* Function to allocate memory for the temporary buffer. This memory is
+ * allocated from Ashmem. It is the caller's responsibility to free this
+ * memory.
+ */
+static int get_temp_buffer(const bufferInfo& info, alloc_data& data)
+{
+    ALOGD("%s E", __FUNCTION__);
+    // Alloc memory from system heap
+    data.base = 0;
+    data.fd = -1;
+    data.offset = 0;
+    data.size = get_size(info);
+    data.align = getpagesize();
+    data.uncached = true;
+    int allocFlags = 0;
+
+    if (sAlloc == 0) {
+        sAlloc = gralloc::IAllocController::getInstance();
+    }
+
+    if (sAlloc == 0) {
+        ALOGE("%s: sAlloc is still NULL", __FUNCTION__);
+        return COPYBIT_FAILURE;
+    }
+
+    int err = sAlloc->allocate(data, allocFlags);
+    if (0 != err) {
+        ALOGE("%s: allocate failed", __FUNCTION__);
+        return COPYBIT_FAILURE;
+    }
+
+    ALOGD("%s X", __FUNCTION__);
+    return err;
+}
+
+/* Function to free the temporary allocated memory.*/
+static void free_temp_buffer(alloc_data &data)
+{
+    if (-1 != data.fd) {
+        IMemAlloc* memalloc = sAlloc->getAllocator(data.allocType);
+        memalloc->free_buffer(data.base, data.size, 0, data.fd);
+    }
+}
+
+/* Function to perform the software color conversion. Convert the
+ * C2D compatible format to the Android compatible format
+ */
+static int copy_image(private_handle_t *src_handle,
+                      struct copybit_image_t const *rhs,
+                      eConversionType conversionType)
+{
+    if (src_handle->fd == -1) {
+        ALOGE("%s: src_handle fd is invalid", __FUNCTION__);
+        return COPYBIT_FAILURE;
+    }
+
+    // Copy the info.
+    int ret = COPYBIT_SUCCESS;
+    switch(rhs->format) {
+        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+            {
+                if (CONVERT_TO_ANDROID_FORMAT == conversionType) {
+                    return convert_yuv_c2d_to_yuv_android(src_handle, rhs);
+                } else {
+                    return convert_yuv_android_to_yuv_c2d(src_handle, rhs);
+                }
+
+            } break;
+        default: {
+            ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format);
+            ret = COPYBIT_FAILURE;
+        } break;
+    }
+    return ret;
+}
+
+static void delete_handle(private_handle_t *handle)
+{
+    if (handle) {
+        delete handle;
+        handle = 0;
+    }
+}
+
+static bool need_to_execute_draw(eC2DFlags flags)
+{
+    if (flags & FLAGS_TEMP_SRC_DST) {
+        return true;
+    }
+    if (flags & FLAGS_YUV_DESTINATION) {
+        return true;
+    }
+    return false;
+}
+
+/** do a stretch blit type operation */
+static int stretch_copybit_internal(
+    struct copybit_device_t *dev,
+    struct copybit_image_t const *dst,
+    struct copybit_image_t const *src,
+    struct copybit_rect_t const *dst_rect,
+    struct copybit_rect_t const *src_rect,
+    struct copybit_region_t const *region,
+    bool enableBlend)
+{
+    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    int status = COPYBIT_SUCCESS;
+    int flags = 0;
+    int src_surface_type;
+    int mapped_src_idx = -1, mapped_dst_idx = -1;
+    C2D_OBJECT_STR src_surface;
+
+    if (!ctx) {
+        ALOGE("%s: null context error", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    if (src->w > MAX_DIMENSION || src->h > MAX_DIMENSION) {
+        ALOGE("%s: src dimension error", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) {
+        ALOGE("%s : dst dimension error dst w %d h %d",  __FUNCTION__, dst->w,
+                                                         dst->h);
+        return -EINVAL;
+    }
+
+    if (is_valid_destination_format(dst->format) == COPYBIT_FAILURE) {
+        ALOGE("%s: Invalid destination format format = 0x%x", __FUNCTION__,
+                                                              dst->format);
+        return COPYBIT_FAILURE;
+    }
+
+    int dst_surface_type;
+    if (ctx->is_dst_ubwc_format)
+        flags |= FLAGS_UBWC_FORMAT_MODE;
+
+    if (is_supported_rgb_format(dst->format) == COPYBIT_SUCCESS) {
+        dst_surface_type = RGB_SURFACE;
+        flags |= FLAGS_PREMULTIPLIED_ALPHA;
+    } else if (is_supported_yuv_format(dst->format) == COPYBIT_SUCCESS) {
+        int num_planes = get_num_planes(dst->format);
+        flags |= FLAGS_YUV_DESTINATION;
+        if (num_planes == 2) {
+            dst_surface_type = YUV_SURFACE_2_PLANES;
+        } else if (num_planes == 3) {
+            dst_surface_type = YUV_SURFACE_3_PLANES;
+        } else {
+            ALOGE("%s: dst number of YUV planes is invalid dst format = 0x%x",
+                  __FUNCTION__, dst->format);
+            return COPYBIT_FAILURE;
+        }
+    } else {
+        ALOGE("%s: Invalid dst surface format 0x%x", __FUNCTION__,
+                                                     dst->format);
+        return COPYBIT_FAILURE;
+    }
+
+    if (ctx->blit_rgb_count == MAX_RGB_SURFACES ||
+        ctx->blit_yuv_2_plane_count == MAX_YUV_2_PLANE_SURFACES ||
+        ctx->blit_yuv_3_plane_count == MAX_YUV_2_PLANE_SURFACES ||
+        ctx->blit_count == MAX_BLIT_OBJECT_COUNT ||
+        ctx->dst_surface_type != dst_surface_type) {
+        // we have reached the max. limits of our internal structures or
+        // changed the target.
+        // Draw the remaining surfaces. We need to do the finish here since
+        // we need to free up the surface templates.
+        finish_copybit(dev);
+    }
+
+    ctx->dst_surface_type = dst_surface_type;
+
+    // Update the destination
+    copybit_image_t dst_image;
+    dst_image.w = dst->w;
+    dst_image.h = dst->h;
+    dst_image.format = dst->format;
+    dst_image.handle = dst->handle;
+    // Check if we need a temp. copy for the destination. We'd need this the destination
+    // width is not aligned to 32. This case occurs for YUV formats. RGB formats are
+    // aligned to 32.
+    bool need_temp_dst = need_temp_buffer(dst);
+    bufferInfo dst_info;
+    populate_buffer_info(dst, dst_info);
+    private_handle_t* dst_hnd = new private_handle_t(-1, 0, 0, 0, dst_info.format,
+                                                     dst_info.width, dst_info.height);
+    if (dst_hnd == NULL) {
+        ALOGE("%s: dst_hnd is null", __FUNCTION__);
+        return COPYBIT_FAILURE;
+    }
+    if (need_temp_dst) {
+        if (get_size(dst_info) != (int) ctx->temp_dst_buffer.size) {
+            free_temp_buffer(ctx->temp_dst_buffer);
+            // Create a temp buffer and set that as the destination.
+            if (COPYBIT_FAILURE == get_temp_buffer(dst_info, ctx->temp_dst_buffer)) {
+                ALOGE("%s: get_temp_buffer(dst) failed", __FUNCTION__);
+                delete_handle(dst_hnd);
+                return COPYBIT_FAILURE;
+            }
+        }
+        dst_hnd->fd = ctx->temp_dst_buffer.fd;
+        dst_hnd->size = ctx->temp_dst_buffer.size;
+        dst_hnd->flags = ctx->temp_dst_buffer.allocType;
+        dst_hnd->base = (uintptr_t)(ctx->temp_dst_buffer.base);
+        dst_hnd->offset = ctx->temp_dst_buffer.offset;
+        dst_hnd->gpuaddr = 0;
+        dst_image.handle = dst_hnd;
+    }
+    if(!ctx->dst_surface_mapped) {
+        //map the destination surface to GPU address
+        status = set_image(ctx, ctx->dst[ctx->dst_surface_type], &dst_image,
+                           (eC2DFlags)flags, mapped_dst_idx);
+        if(status) {
+            ALOGE("%s: dst: set_image error", __FUNCTION__);
+            delete_handle(dst_hnd);
+            unmap_gpuaddr(ctx, mapped_dst_idx);
+            return COPYBIT_FAILURE;
+        }
+        ctx->dst_surface_mapped = true;
+        ctx->dst_surface_base = dst->base;
+    } else if(ctx->dst_surface_mapped && ctx->dst_surface_base != dst->base) {
+        // Destination surface for the operation should be same for multiple
+        // requests, this check is catch if there is any case when the
+        // destination changes
+        ALOGE("%s: a different destination surface!!", __FUNCTION__);
+    }
+
+    // Update the source
+    flags = 0;
+    if(is_supported_rgb_format(src->format) == COPYBIT_SUCCESS) {
+        src_surface_type = RGB_SURFACE;
+        src_surface = ctx->blit_rgb_object[ctx->blit_rgb_count];
+    } else if (is_supported_yuv_format(src->format) == COPYBIT_SUCCESS) {
+        int num_planes = get_num_planes(src->format);
+        if (num_planes == 2) {
+            src_surface_type = YUV_SURFACE_2_PLANES;
+            src_surface = ctx->blit_yuv_2_plane_object[ctx->blit_yuv_2_plane_count];
+        } else if (num_planes == 3) {
+            src_surface_type = YUV_SURFACE_3_PLANES;
+            src_surface = ctx->blit_yuv_3_plane_object[ctx->blit_yuv_2_plane_count];
+        } else {
+            ALOGE("%s: src number of YUV planes is invalid src format = 0x%x",
+                  __FUNCTION__, src->format);
+            delete_handle(dst_hnd);
+            unmap_gpuaddr(ctx, mapped_dst_idx);
+            return -EINVAL;
+        }
+    } else {
+        ALOGE("%s: Invalid source surface format 0x%x", __FUNCTION__,
+                                                        src->format);
+        delete_handle(dst_hnd);
+        unmap_gpuaddr(ctx, mapped_dst_idx);
+        return -EINVAL;
+    }
+
+    copybit_image_t src_image;
+    src_image.w = src->w;
+    src_image.h = src->h;
+    src_image.format = src->format;
+    src_image.handle = src->handle;
+
+    bool need_temp_src = need_temp_buffer(src);
+    bufferInfo src_info;
+    populate_buffer_info(src, src_info);
+    private_handle_t* src_hnd = new private_handle_t(-1, 0, 0, 0, src_info.format,
+                                                 src_info.width, src_info.height);
+    if (NULL == src_hnd) {
+        ALOGE("%s: src_hnd is null", __FUNCTION__);
+        delete_handle(dst_hnd);
+        unmap_gpuaddr(ctx, mapped_dst_idx);
+        return COPYBIT_FAILURE;
+    }
+    if (need_temp_src) {
+        if (get_size(src_info) != (int) ctx->temp_src_buffer.size) {
+            free_temp_buffer(ctx->temp_src_buffer);
+            // Create a temp buffer and set that as the destination.
+            if (COPYBIT_SUCCESS != get_temp_buffer(src_info,
+                                               ctx->temp_src_buffer)) {
+                ALOGE("%s: get_temp_buffer(src) failed", __FUNCTION__);
+                delete_handle(dst_hnd);
+                delete_handle(src_hnd);
+                unmap_gpuaddr(ctx, mapped_dst_idx);
+                return COPYBIT_FAILURE;
+            }
+        }
+        src_hnd->fd = ctx->temp_src_buffer.fd;
+        src_hnd->size = ctx->temp_src_buffer.size;
+        src_hnd->flags = ctx->temp_src_buffer.allocType;
+        src_hnd->base = (uintptr_t)(ctx->temp_src_buffer.base);
+        src_hnd->offset = ctx->temp_src_buffer.offset;
+        src_hnd->gpuaddr = 0;
+        src_image.handle = src_hnd;
+
+        // Copy the source.
+        status = copy_image((private_handle_t *)src->handle, &src_image,
+                                CONVERT_TO_C2D_FORMAT);
+        if (status == COPYBIT_FAILURE) {
+            ALOGE("%s:copy_image failed in temp source",__FUNCTION__);
+            delete_handle(dst_hnd);
+            delete_handle(src_hnd);
+            unmap_gpuaddr(ctx, mapped_dst_idx);
+            return status;
+        }
+
+        // Clean the cache
+        IMemAlloc* memalloc = sAlloc->getAllocator(src_hnd->flags);
+        if (memalloc->clean_buffer((void *)(src_hnd->base), src_hnd->size,
+                                   src_hnd->offset, src_hnd->fd,
+                                   gralloc::CACHE_CLEAN)) {
+            ALOGE("%s: clean_buffer failed", __FUNCTION__);
+            delete_handle(dst_hnd);
+            delete_handle(src_hnd);
+            unmap_gpuaddr(ctx, mapped_dst_idx);
+            return COPYBIT_FAILURE;
+        }
+    }
+
+    flags |= (ctx->is_premultiplied_alpha) ? FLAGS_PREMULTIPLIED_ALPHA : 0;
+    flags |= (ctx->dst_surface_type != RGB_SURFACE) ? FLAGS_YUV_DESTINATION : 0;
+    flags |= (ctx->is_src_ubwc_format) ? FLAGS_UBWC_FORMAT_MODE : 0;
+    status = set_image(ctx, src_surface.surface_id, &src_image,
+                       (eC2DFlags)flags, mapped_src_idx);
+    if(status) {
+        ALOGE("%s: set_image (src) error", __FUNCTION__);
+        delete_handle(dst_hnd);
+        delete_handle(src_hnd);
+        unmap_gpuaddr(ctx, mapped_dst_idx);
+        unmap_gpuaddr(ctx, mapped_src_idx);
+        return COPYBIT_FAILURE;
+    }
+
+    src_surface.config_mask = C2D_NO_ANTIALIASING_BIT | ctx->config_mask;
+    src_surface.global_alpha = ctx->src_global_alpha;
+    if (enableBlend) {
+        if(src_surface.config_mask & C2D_GLOBAL_ALPHA_BIT) {
+            src_surface.config_mask &= ~C2D_ALPHA_BLEND_NONE;
+            if(!(src_surface.global_alpha)) {
+                // src alpha is zero
+                delete_handle(dst_hnd);
+                delete_handle(src_hnd);
+                unmap_gpuaddr(ctx, mapped_dst_idx);
+                unmap_gpuaddr(ctx, mapped_src_idx);
+                return COPYBIT_FAILURE;
+            }
+        }
+    } else {
+        src_surface.config_mask |= C2D_ALPHA_BLEND_NONE;
+    }
+
+    if (src_surface_type == RGB_SURFACE) {
+        ctx->blit_rgb_object[ctx->blit_rgb_count] = src_surface;
+        ctx->blit_rgb_count++;
+    } else if (src_surface_type == YUV_SURFACE_2_PLANES) {
+        ctx->blit_yuv_2_plane_object[ctx->blit_yuv_2_plane_count] = src_surface;
+        ctx->blit_yuv_2_plane_count++;
+    } else {
+        ctx->blit_yuv_3_plane_object[ctx->blit_yuv_3_plane_count] = src_surface;
+        ctx->blit_yuv_3_plane_count++;
+    }
+
+    struct copybit_rect_t clip;
+    while ((status == 0) && region->next(region, &clip)) {
+        set_rects(ctx, &(src_surface), dst_rect, src_rect, &clip);
+        if (ctx->blit_count == MAX_BLIT_OBJECT_COUNT) {
+            ALOGW("Reached end of blit count");
+            finish_copybit(dev);
+        }
+        ctx->blit_list[ctx->blit_count] = src_surface;
+        ctx->blit_count++;
+    }
+
+    // Check if we need to perform an early draw-finish.
+    flags |= (need_temp_dst || need_temp_src) ? FLAGS_TEMP_SRC_DST : 0;
+    if (need_to_execute_draw((eC2DFlags)flags))
+    {
+        finish_copybit(dev);
+    }
+
+    if (need_temp_dst) {
+        // copy the temp. destination without the alignment to the actual
+        // destination.
+        status = copy_image(dst_hnd, dst, CONVERT_TO_ANDROID_FORMAT);
+        if (status == COPYBIT_FAILURE) {
+            ALOGE("%s:copy_image failed in temp Dest",__FUNCTION__);
+            delete_handle(dst_hnd);
+            delete_handle(src_hnd);
+            unmap_gpuaddr(ctx, mapped_dst_idx);
+            unmap_gpuaddr(ctx, mapped_src_idx);
+            return status;
+        }
+        // Clean the cache.
+        IMemAlloc* memalloc = sAlloc->getAllocator(dst_hnd->flags);
+        memalloc->clean_buffer((void *)(dst_hnd->base), dst_hnd->size,
+                               dst_hnd->offset, dst_hnd->fd,
+                               gralloc::CACHE_CLEAN);
+    }
+    delete_handle(dst_hnd);
+    delete_handle(src_hnd);
+
+    ctx->is_premultiplied_alpha = false;
+    ctx->fb_width = 0;
+    ctx->fb_height = 0;
+    ctx->config_mask = 0;
+    return status;
+}
+
+static int set_sync_copybit(struct copybit_device_t *dev,
+    int /*acquireFenceFd*/)
+{
+    if(!dev)
+        return -EINVAL;
+
+    return 0;
+}
+
+static int stretch_copybit(
+    struct copybit_device_t *dev,
+    struct copybit_image_t const *dst,
+    struct copybit_image_t const *src,
+    struct copybit_rect_t const *dst_rect,
+    struct copybit_rect_t const *src_rect,
+    struct copybit_region_t const *region)
+{
+    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    int status = COPYBIT_SUCCESS;
+    bool needsBlending = (ctx->src_global_alpha != 0);
+    pthread_mutex_lock(&ctx->wait_cleanup_lock);
+    status = stretch_copybit_internal(dev, dst, src, dst_rect, src_rect,
+                                    region, needsBlending);
+    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
+    return status;
+}
+
+/** Perform a blit type operation */
+static int blit_copybit(
+    struct copybit_device_t *dev,
+    struct copybit_image_t const *dst,
+    struct copybit_image_t const *src,
+    struct copybit_region_t const *region)
+{
+    int status = COPYBIT_SUCCESS;
+    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    struct copybit_rect_t dr = { 0, 0, (int)dst->w, (int)dst->h };
+    struct copybit_rect_t sr = { 0, 0, (int)src->w, (int)src->h };
+    pthread_mutex_lock(&ctx->wait_cleanup_lock);
+    status = stretch_copybit_internal(dev, dst, src, &dr, &sr, region, false);
+    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
+    return status;
+}
+
+/** Fill the rect on dst with RGBA color **/
+static int fill_color(struct copybit_device_t *dev,
+                      struct copybit_image_t const *dst,
+                      struct copybit_rect_t const *rect,
+                      uint32_t /*color*/)
+{
+    // TODO: Implement once c2d driver supports color fill
+    if(!dev || !dst || !rect)
+       return -EINVAL;
+
+    return -EINVAL;
+}
+
+/*****************************************************************************/
+
+static void clean_up(copybit_context_t* ctx)
+{
+    void* ret;
+    if (!ctx)
+        return;
+
+    // stop the wait_cleanup_thread
+    pthread_mutex_lock(&ctx->wait_cleanup_lock);
+    ctx->stop_thread = true;
+    // Signal waiting thread
+    pthread_cond_signal(&ctx->wait_cleanup_cond);
+    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
+    // waits for the cleanup thread to exit
+    pthread_join(ctx->wait_thread_id, &ret);
+    pthread_mutex_destroy(&ctx->wait_cleanup_lock);
+    pthread_cond_destroy (&ctx->wait_cleanup_cond);
+
+    for (int i = 0; i < NUM_SURFACE_TYPES; i++) {
+        if (ctx->dst[i])
+            LINK_c2dDestroySurface(ctx->dst[i]);
+    }
+
+    for (int i = 0; i < MAX_RGB_SURFACES; i++) {
+        if (ctx->blit_rgb_object[i].surface_id)
+            LINK_c2dDestroySurface(ctx->blit_rgb_object[i].surface_id);
+    }
+
+    for (int i = 0; i < MAX_YUV_2_PLANE_SURFACES; i++) {
+        if (ctx->blit_yuv_2_plane_object[i].surface_id)
+            LINK_c2dDestroySurface(ctx->blit_yuv_2_plane_object[i].surface_id);
+    }
+
+    for (int i = 0; i < MAX_YUV_3_PLANE_SURFACES; i++) {
+        if (ctx->blit_yuv_3_plane_object[i].surface_id)
+            LINK_c2dDestroySurface(ctx->blit_yuv_3_plane_object[i].surface_id);
+    }
+
+    if (ctx->libc2d2) {
+        ::dlclose(ctx->libc2d2);
+        ALOGV("dlclose(libc2d2)");
+    }
+
+    free(ctx);
+}
+
+/** Close the copybit device */
+static int close_copybit(struct hw_device_t *dev)
+{
+    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    if (ctx) {
+        free_temp_buffer(ctx->temp_src_buffer);
+        free_temp_buffer(ctx->temp_dst_buffer);
+    }
+    clean_up(ctx);
+    return 0;
+}
+
+/** Open a new instance of a copybit device using name */
+static int open_copybit(const struct hw_module_t* module, const char* name,
+                        struct hw_device_t** device)
+{
+    int status = COPYBIT_SUCCESS;
+    if (strcmp(name, COPYBIT_HARDWARE_COPYBIT0)) {
+        return COPYBIT_FAILURE;
+    }
+
+    C2D_RGB_SURFACE_DEF surfDefinition = {0};
+    C2D_YUV_SURFACE_DEF yuvSurfaceDef = {0} ;
+    struct copybit_context_t *ctx;
+
+    ctx = (struct copybit_context_t *)malloc(sizeof(struct copybit_context_t));
+    if(!ctx) {
+        ALOGE("%s: malloc failed", __FUNCTION__);
+        return COPYBIT_FAILURE;
+    }
+
+    /* initialize drawstate */
+    memset(ctx, 0, sizeof(*ctx));
+    ctx->libc2d2 = ::dlopen("libC2D2.so", RTLD_NOW);
+    if (!ctx->libc2d2) {
+        ALOGE("FATAL ERROR: could not dlopen libc2d2.so: %s", dlerror());
+        clean_up(ctx);
+        status = COPYBIT_FAILURE;
+        *device = NULL;
+        return status;
+    }
+    *(void **)&LINK_c2dCreateSurface = ::dlsym(ctx->libc2d2,
+                                               "c2dCreateSurface");
+    *(void **)&LINK_c2dUpdateSurface = ::dlsym(ctx->libc2d2,
+                                               "c2dUpdateSurface");
+    *(void **)&LINK_c2dReadSurface = ::dlsym(ctx->libc2d2,
+                                             "c2dReadSurface");
+    *(void **)&LINK_c2dDraw = ::dlsym(ctx->libc2d2, "c2dDraw");
+    *(void **)&LINK_c2dFlush = ::dlsym(ctx->libc2d2, "c2dFlush");
+    *(void **)&LINK_c2dFinish = ::dlsym(ctx->libc2d2, "c2dFinish");
+    *(void **)&LINK_c2dWaitTimestamp = ::dlsym(ctx->libc2d2,
+                                               "c2dWaitTimestamp");
+    *(void **)&LINK_c2dDestroySurface = ::dlsym(ctx->libc2d2,
+                                                "c2dDestroySurface");
+    *(void **)&LINK_c2dMapAddr = ::dlsym(ctx->libc2d2,
+                                         "c2dMapAddr");
+    *(void **)&LINK_c2dUnMapAddr = ::dlsym(ctx->libc2d2,
+                                           "c2dUnMapAddr");
+    *(void **)&LINK_c2dGetDriverCapabilities = ::dlsym(ctx->libc2d2,
+                                           "c2dGetDriverCapabilities");
+    *(void **)&LINK_c2dCreateFenceFD = ::dlsym(ctx->libc2d2,
+                                           "c2dCreateFenceFD");
+    *(void **)&LINK_c2dFillSurface = ::dlsym(ctx->libc2d2,
+                                           "c2dFillSurface");
+
+    if (!LINK_c2dCreateSurface || !LINK_c2dUpdateSurface || !LINK_c2dReadSurface
+        || !LINK_c2dDraw || !LINK_c2dFlush || !LINK_c2dWaitTimestamp ||
+        !LINK_c2dFinish  || !LINK_c2dDestroySurface ||
+        !LINK_c2dGetDriverCapabilities || !LINK_c2dCreateFenceFD ||
+        !LINK_c2dFillSurface) {
+        ALOGE("%s: dlsym ERROR", __FUNCTION__);
+        clean_up(ctx);
+        status = COPYBIT_FAILURE;
+        *device = NULL;
+        return status;
+    }
+
+    ctx->device.common.tag = HARDWARE_DEVICE_TAG;
+    ctx->device.common.version = 1;
+    ctx->device.common.module = (hw_module_t*)(module);
+    ctx->device.common.close = close_copybit;
+    ctx->device.set_parameter = set_parameter_copybit;
+    ctx->device.get = get;
+    ctx->device.blit = blit_copybit;
+    ctx->device.set_sync = set_sync_copybit;
+    ctx->device.stretch = stretch_copybit;
+    ctx->device.finish = finish_copybit;
+    ctx->device.flush_get_fence = flush_get_fence_copybit;
+    ctx->device.clear = clear_copybit;
+    ctx->device.fill_color = fill_color;
+
+    /* Create RGB Surface */
+    surfDefinition.buffer = (void*)0xdddddddd;
+    surfDefinition.phys = (void*)0xdddddddd;
+    surfDefinition.stride = 1 * 4;
+    surfDefinition.width = 1;
+    surfDefinition.height = 1;
+    surfDefinition.format = C2D_COLOR_FORMAT_8888_ARGB;
+    if (LINK_c2dCreateSurface(&(ctx->dst[RGB_SURFACE]), C2D_TARGET | C2D_SOURCE,
+                              (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST |
+                                                 C2D_SURFACE_WITH_PHYS |
+                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
+                                                 &surfDefinition)) {
+        ALOGE("%s: create ctx->dst_surface[RGB_SURFACE] failed", __FUNCTION__);
+        ctx->dst[RGB_SURFACE] = 0;
+        clean_up(ctx);
+        status = COPYBIT_FAILURE;
+        *device = NULL;
+        return status;
+    }
+
+    unsigned int surface_id = 0;
+    for (int i = 0; i < MAX_RGB_SURFACES; i++)
+    {
+        if (LINK_c2dCreateSurface(&surface_id, C2D_TARGET | C2D_SOURCE,
+                              (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST |
+                                                 C2D_SURFACE_WITH_PHYS |
+                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
+                                                 &surfDefinition)) {
+            ALOGE("%s: create RGB source surface %d failed", __FUNCTION__, i);
+            ctx->blit_rgb_object[i].surface_id = 0;
+            status = COPYBIT_FAILURE;
+            break;
+        } else {
+            ctx->blit_rgb_object[i].surface_id = surface_id;
+            ALOGW("%s i = %d surface_id=%d",  __FUNCTION__, i,
+                                          ctx->blit_rgb_object[i].surface_id);
+        }
+    }
+
+    if (status == COPYBIT_FAILURE) {
+        clean_up(ctx);
+        status = COPYBIT_FAILURE;
+        *device = NULL;
+        return status;
+    }
+
+    // Create 2 plane YUV surfaces
+    yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_NV12;
+    yuvSurfaceDef.width = 4;
+    yuvSurfaceDef.height = 4;
+    yuvSurfaceDef.plane0 = (void*)0xaaaaaaaa;
+    yuvSurfaceDef.phys0 = (void*) 0xaaaaaaaa;
+    yuvSurfaceDef.stride0 = 4;
+
+    yuvSurfaceDef.plane1 = (void*)0xaaaaaaaa;
+    yuvSurfaceDef.phys1 = (void*) 0xaaaaaaaa;
+    yuvSurfaceDef.stride1 = 4;
+    if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_2_PLANES]),
+                              C2D_TARGET | C2D_SOURCE,
+                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
+                               C2D_SURFACE_WITH_PHYS |
+                               C2D_SURFACE_WITH_PHYS_DUMMY),
+                              &yuvSurfaceDef)) {
+        ALOGE("%s: create ctx->dst[YUV_SURFACE_2_PLANES] failed", __FUNCTION__);
+        ctx->dst[YUV_SURFACE_2_PLANES] = 0;
+        clean_up(ctx);
+        status = COPYBIT_FAILURE;
+        *device = NULL;
+        return status;
+    }
+
+    for (int i=0; i < MAX_YUV_2_PLANE_SURFACES; i++)
+    {
+        if (LINK_c2dCreateSurface(&surface_id, C2D_TARGET | C2D_SOURCE,
+                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
+                                                 C2D_SURFACE_WITH_PHYS |
+                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
+                              &yuvSurfaceDef)) {
+            ALOGE("%s: create YUV source %d failed", __FUNCTION__, i);
+            ctx->blit_yuv_2_plane_object[i].surface_id = 0;
+            status = COPYBIT_FAILURE;
+            break;
+        } else {
+            ctx->blit_yuv_2_plane_object[i].surface_id = surface_id;
+            ALOGW("%s: 2 Plane YUV i=%d surface_id=%d",  __FUNCTION__, i,
+                                   ctx->blit_yuv_2_plane_object[i].surface_id);
+        }
+    }
+
+    if (status == COPYBIT_FAILURE) {
+        clean_up(ctx);
+        status = COPYBIT_FAILURE;
+        *device = NULL;
+        return status;
+    }
+
+    // Create YUV 3 plane surfaces
+    yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_YV12;
+    yuvSurfaceDef.plane2 = (void*)0xaaaaaaaa;
+    yuvSurfaceDef.phys2 = (void*) 0xaaaaaaaa;
+    yuvSurfaceDef.stride2 = 4;
+
+    if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_3_PLANES]),
+                              C2D_TARGET | C2D_SOURCE,
+                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
+                                                 C2D_SURFACE_WITH_PHYS |
+                                                 C2D_SURFACE_WITH_PHYS_DUMMY),
+                              &yuvSurfaceDef)) {
+        ALOGE("%s: create ctx->dst[YUV_SURFACE_3_PLANES] failed", __FUNCTION__);
+        ctx->dst[YUV_SURFACE_3_PLANES] = 0;
+        clean_up(ctx);
+        status = COPYBIT_FAILURE;
+        *device = NULL;
+        return status;
+    }
+
+    for (int i=0; i < MAX_YUV_3_PLANE_SURFACES; i++)
+    {
+        if (LINK_c2dCreateSurface(&(surface_id),
+                              C2D_TARGET | C2D_SOURCE,
+                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
+                                                 C2D_SURFACE_WITH_PHYS |
+                                                 C2D_SURFACE_WITH_PHYS_DUMMY),
+                              &yuvSurfaceDef)) {
+            ALOGE("%s: create 3 plane YUV surface %d failed", __FUNCTION__, i);
+            ctx->blit_yuv_3_plane_object[i].surface_id = 0;
+            status = COPYBIT_FAILURE;
+            break;
+        } else {
+            ctx->blit_yuv_3_plane_object[i].surface_id = surface_id;
+            ALOGW("%s: 3 Plane YUV i=%d surface_id=%d",  __FUNCTION__, i,
+                                   ctx->blit_yuv_3_plane_object[i].surface_id);
+        }
+    }
+
+    if (status == COPYBIT_FAILURE) {
+        clean_up(ctx);
+        status = COPYBIT_FAILURE;
+        *device = NULL;
+        return status;
+    }
+
+    if (LINK_c2dGetDriverCapabilities(&(ctx->c2d_driver_info))) {
+         ALOGE("%s: LINK_c2dGetDriverCapabilities failed", __FUNCTION__);
+         clean_up(ctx);
+         status = COPYBIT_FAILURE;
+        *device = NULL;
+        return status;
+    }
+    // Initialize context variables.
+    ctx->trg_transform = C2D_TARGET_ROTATE_0;
+
+    ctx->temp_src_buffer.fd = -1;
+    ctx->temp_src_buffer.base = 0;
+    ctx->temp_src_buffer.size = 0;
+
+    ctx->temp_dst_buffer.fd = -1;
+    ctx->temp_dst_buffer.base = 0;
+    ctx->temp_dst_buffer.size = 0;
+
+    ctx->fb_width = 0;
+    ctx->fb_height = 0;
+
+    ctx->blit_rgb_count = 0;
+    ctx->blit_yuv_2_plane_count = 0;
+    ctx->blit_yuv_3_plane_count = 0;
+    ctx->blit_count = 0;
+
+    ctx->wait_timestamp = false;
+    ctx->stop_thread = false;
+    pthread_mutex_init(&(ctx->wait_cleanup_lock), NULL);
+    pthread_cond_init(&(ctx->wait_cleanup_cond), NULL);
+    /* Start the wait thread */
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+
+    pthread_create(&ctx->wait_thread_id, &attr, &c2d_wait_loop,
+                                                            (void *)ctx);
+    pthread_attr_destroy(&attr);
+
+    *device = &ctx->device.common;
+    return status;
+}
diff --git a/msmcobalt/libcopybit/copybit_priv.h b/msmcobalt/libcopybit/copybit_priv.h
new file mode 100644
index 0000000..68dfac4
--- /dev/null
+++ b/msmcobalt/libcopybit/copybit_priv.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2011, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <copybit.h>
+struct copybit_iterator : public copybit_region_t {
+    copybit_iterator(const copybit_rect_t& rect) {
+        mRect = rect;
+        mCount = 1;
+        this->next = iterate;
+    }
+private:
+    static int iterate(copybit_region_t const * self, copybit_rect_t* rect) {
+        if (!self || !rect) {
+            return 0;
+        }
+
+        copybit_iterator const* me = static_cast<copybit_iterator const*>(self);
+        if (me->mCount) {
+            rect->l = me->mRect.l;
+            rect->t = me->mRect.t;
+            rect->r = me->mRect.r;
+            rect->b = me->mRect.b;
+            me->mCount--;
+            return 1;
+        }
+        return 0;
+    }
+    copybit_rect_t mRect;
+    mutable int mCount;
+};
diff --git a/msmcobalt/libcopybit/software_converter.cpp b/msmcobalt/libcopybit/software_converter.cpp
new file mode 100644
index 0000000..e5c03b5
--- /dev/null
+++ b/msmcobalt/libcopybit/software_converter.cpp
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <cutils/log.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "software_converter.h"
+
+/** Convert YV12 to YCrCb_420_SP */
+int convertYV12toYCrCb420SP(const copybit_image_t *src, private_handle_t *yv12_handle)
+{
+    private_handle_t* hnd = (private_handle_t*)src->handle;
+
+    if(hnd == NULL || yv12_handle == NULL){
+        ALOGE("Invalid handle");
+        return -1;
+    }
+
+    // Please refer to the description of YV12 in hardware.h
+    // for the formulae used to calculate buffer sizes and offsets
+
+    // In a copybit_image_t, w is the stride and
+    // stride - horiz_padding is the actual width
+    // vertical stride is the same as height, so not considered
+    unsigned int   stride  = src->w;
+    unsigned int   width   = src->w - src->horiz_padding;
+    unsigned int   height  = src->h;
+    unsigned int   y_size  = stride * src->h;
+    unsigned int   c_width = ALIGN(stride/2, (unsigned int)16);
+    unsigned int   c_size  = c_width * src->h/2;
+    unsigned int   chromaPadding = c_width - width/2;
+    unsigned int   chromaSize = c_size * 2;
+    unsigned char* newChroma = (unsigned char *)(yv12_handle->base + y_size);
+    unsigned char* oldChroma = (unsigned char*)(hnd->base + y_size);
+    memcpy((char *)yv12_handle->base,(char *)hnd->base,y_size);
+
+#if defined(__ARM_HAVE_NEON) && !defined(__aarch64__)
+   /* interleave */
+    if(!chromaPadding) {
+        unsigned char * t1 = newChroma;
+        unsigned char * t2 = oldChroma;
+        unsigned char * t3 = t2 + chromaSize/2;
+        for(unsigned int i=0; i < (chromaSize/2)>>3; i++) {
+            __asm__ __volatile__ (
+                                    "vld1.u8 d0, [%0]! \n"
+                                    "vld1.u8 d1, [%1]! \n"
+                                    "vst2.u8 {d0, d1}, [%2]! \n"
+                                    :"+r"(t2), "+r"(t3), "+r"(t1)
+                                    :
+                                    :"memory","d0","d1"
+                                 );
+
+        }
+    }
+#else  //__ARM_HAVE_NEON
+    if(!chromaPadding) {
+        for(unsigned int i = 0; i< chromaSize/2; i++) {
+            newChroma[i*2]   = oldChroma[i];
+            newChroma[i*2+1] = oldChroma[i+chromaSize/2];
+        }
+
+    }
+#endif
+    // If the image is not aligned to 16 pixels,
+    // convert using the C routine below
+    // r1 tracks the row of the source buffer
+    // r2 tracks the row of the destination buffer
+    // The width/2 checks are to avoid copying
+    // from the padding
+
+    if(chromaPadding) {
+        unsigned int r1 = 0, r2 = 0, i = 0, j = 0;
+        while(r1 < height/2) {
+            if(j == width) {
+                j = 0;
+                r2++;
+                continue;
+            }
+            if (j+1 == width) {
+                newChroma[r2*width + j] = oldChroma[r1*c_width+i];
+                r2++;
+                newChroma[r2*width] = oldChroma[r1*c_width+i+c_size];
+                j = 1;
+            } else {
+                newChroma[r2*width + j] = oldChroma[r1*c_width+i];
+                newChroma[r2*width + j + 1] = oldChroma[r1*c_width+i+c_size];
+                j+=2;
+            }
+            i++;
+            if (i == width/2 ) {
+                i = 0;
+                r1++;
+            }
+        }
+    }
+
+  return 0;
+}
+
+struct copyInfo{
+    int width;
+    int height;
+    int src_stride;
+    int dst_stride;
+    size_t src_plane1_offset;
+    size_t src_plane2_offset;
+    size_t dst_plane1_offset;
+    size_t dst_plane2_offset;
+};
+
+/* Internal function to do the actual copy of source to destination */
+static int copy_source_to_destination(const uintptr_t src_base,
+                                      const uintptr_t dst_base,
+                                      copyInfo& info)
+{
+    if (!src_base || !dst_base) {
+        ALOGE("%s: invalid memory src_base = 0x%p dst_base=0x%p",
+             __FUNCTION__, (void*)src_base, (void*)dst_base);
+         return COPYBIT_FAILURE;
+    }
+
+    int width = info.width;
+    int height = info.height;
+    unsigned char *src = (unsigned char*)src_base;
+    unsigned char *dst = (unsigned char*)dst_base;
+
+    // Copy the luma
+    for (int i = 0; i < height; i++) {
+        memcpy(dst, src, width);
+        src += info.src_stride;
+        dst += info.dst_stride;
+    }
+
+    // Copy plane 1
+    src = (unsigned char*)(src_base + info.src_plane1_offset);
+    dst = (unsigned char*)(dst_base + info.dst_plane1_offset);
+    width = width/2;
+    height = height/2;
+    for (int i = 0; i < height; i++) {
+        memcpy(dst, src, info.src_stride);
+        src += info.src_stride;
+        dst += info.dst_stride;
+    }
+    return 0;
+}
+
+
+/*
+ * Function to convert the c2d format into an equivalent Android format
+ *
+ * @param: source buffer handle
+ * @param: destination image
+ *
+ * @return: return status
+ */
+int convert_yuv_c2d_to_yuv_android(private_handle_t *hnd,
+                                   struct copybit_image_t const *rhs)
+{
+    ALOGD("Enter %s", __FUNCTION__);
+    if (!hnd || !rhs) {
+        ALOGE("%s: invalid inputs hnd=%p rhs=%p", __FUNCTION__, hnd, rhs);
+        return COPYBIT_FAILURE;
+    }
+
+    int ret = COPYBIT_SUCCESS;
+    private_handle_t *dst_hnd = (private_handle_t *)rhs->handle;
+
+    copyInfo info;
+    info.width = rhs->w;
+    info.height = rhs->h;
+    info.src_stride = ALIGN(info.width, 32);
+    info.dst_stride = ALIGN(info.width, 16);
+    switch(rhs->format) {
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP: {
+            info.src_plane1_offset = info.src_stride*info.height;
+            info.dst_plane1_offset = info.dst_stride*info.height;
+        } break;
+        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: {
+            // Chroma is 2K aligned for the NV12 encodeable format.
+            info.src_plane1_offset = ALIGN(info.src_stride*info.height, 2048);
+            info.dst_plane1_offset = ALIGN(info.dst_stride*info.height, 2048);
+        } break;
+        default:
+            ALOGE("%s: unsupported format (format=0x%x)", __FUNCTION__,
+                 rhs->format);
+            return COPYBIT_FAILURE;
+    }
+
+    ret = copy_source_to_destination((uintptr_t) hnd->base, (uintptr_t) dst_hnd->base, info);
+    return ret;
+}
+
+/*
+ * Function to convert the Android format into an equivalent C2D format
+ *
+ * @param: source buffer handle
+ * @param: destination image
+ *
+ * @return: return status
+ */
+int convert_yuv_android_to_yuv_c2d(private_handle_t *hnd,
+                                   struct copybit_image_t const *rhs)
+{
+    if (!hnd || !rhs) {
+        ALOGE("%s: invalid inputs hnd=%p rhs=%p", __FUNCTION__, hnd, rhs);
+        return COPYBIT_FAILURE;
+    }
+
+    int ret = COPYBIT_SUCCESS;
+    private_handle_t *dst_hnd = (private_handle_t *)rhs->handle;
+
+    copyInfo info;
+    info.width = rhs->w;
+    info.height = rhs->h;
+    info.src_stride = ALIGN(hnd->width, 16);
+    info.dst_stride = ALIGN(info.width, 32);
+    switch(rhs->format) {
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP: {
+            info.src_plane1_offset = info.src_stride*info.height;
+            info.dst_plane1_offset = info.dst_stride*info.height;
+        } break;
+        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: {
+            // Chroma is 2K aligned for the NV12 encodeable format.
+            info.src_plane1_offset = ALIGN(info.src_stride*info.height, 2048);
+            info.dst_plane1_offset = ALIGN(info.dst_stride*info.height, 2048);
+        } break;
+        default:
+            ALOGE("%s: unsupported format (format=0x%x)", __FUNCTION__,
+                 rhs->format);
+            return -1;
+    }
+
+    ret = copy_source_to_destination((uintptr_t) hnd->base, (uintptr_t) dst_hnd->base, info);
+    return ret;
+}
diff --git a/msmcobalt/libcopybit/software_converter.h b/msmcobalt/libcopybit/software_converter.h
new file mode 100644
index 0000000..cc6ae34
--- /dev/null
+++ b/msmcobalt/libcopybit/software_converter.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2011, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+
+#include <copybit.h>
+#include "gralloc_priv.h"
+
+#define COPYBIT_SUCCESS 0
+#define COPYBIT_FAILURE -1
+
+#define ALIGN(x, y) (((x) + y - 1) & (~(y - 1)))
+
+int convertYV12toYCrCb420SP(const copybit_image_t *src,private_handle_t *yv12_handle);
+
+/*
+ * Function to convert the c2d format into an equivalent Android format
+ *
+ * @param: source buffer handle
+ * @param: destination image
+ *
+ * @return: return status
+ */
+int convert_yuv_c2d_to_yuv_android(private_handle_t *hnd,
+                                   struct copybit_image_t const *rhs);
+
+
+/*
+ * Function to convert the Android format into an equivalent C2D format
+ *
+ * @param: source buffer handle
+ * @param: destination image
+ *
+ * @return: return status
+ */
+int convert_yuv_android_to_yuv_c2d(private_handle_t *hnd,
+                                   struct copybit_image_t const *rhs);
diff --git a/msmcobalt/libgralloc/Android.mk b/msmcobalt/libgralloc/Android.mk
new file mode 100644
index 0000000..5e499b3
--- /dev/null
+++ b/msmcobalt/libgralloc/Android.mk
@@ -0,0 +1,48 @@
+# 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.
+
+# Gralloc module
+LOCAL_PATH := $(call my-dir)
+include $(LOCAL_PATH)/../common.mk
+include $(CLEAR_VARS)
+
+LOCAL_MODULE                  := gralloc.$(TARGET_BOARD_PLATFORM)
+LOCAL_MODULE_RELATIVE_PATH    := hw
+LOCAL_MODULE_TAGS             := optional
+LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes)
+LOCAL_SHARED_LIBRARIES        := $(common_libs) libmemalloc libqdMetaData libqdutils
+ifneq ($(TARGET_IS_HEADLESS), true)
+LOCAL_SHARED_LIBRARIES        += libGLESv1_CM
+endif
+LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion
+LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
+LOCAL_SRC_FILES               := gpu.cpp gralloc.cpp framebuffer.cpp mapper.cpp
+LOCAL_COPY_HEADERS_TO         := $(common_header_export_path)
+LOCAL_COPY_HEADERS            := gralloc_priv.h gr.h
+
+include $(BUILD_SHARED_LIBRARY)
+
+# MemAlloc Library
+include $(CLEAR_VARS)
+
+LOCAL_MODULE                  := libmemalloc
+LOCAL_MODULE_TAGS             := optional
+LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes)
+LOCAL_SHARED_LIBRARIES        := $(common_libs) libqdutils libdl
+LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdmemalloc\" -Wno-sign-conversion
+LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
+LOCAL_SRC_FILES               := ionalloc.cpp alloc_controller.cpp
+LOCAL_COPY_HEADERS            := alloc_controller.h memalloc.h
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/msmcobalt/libgralloc/MODULE_LICENSE_APACHE2 b/msmcobalt/libgralloc/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/msmcobalt/libgralloc/MODULE_LICENSE_APACHE2
diff --git a/msmcobalt/libgralloc/NOTICE b/msmcobalt/libgralloc/NOTICE
new file mode 100644
index 0000000..3237da6
--- /dev/null
+++ b/msmcobalt/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/msmcobalt/libgralloc/adreno_utils.h b/msmcobalt/libgralloc/adreno_utils.h
new file mode 100644
index 0000000..8ea7f70
--- /dev/null
+++ b/msmcobalt/libgralloc/adreno_utils.h
@@ -0,0 +1,58 @@
+/*
+* Copyright (c) 2015 - 2016, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+*    * Redistributions of source code must retain the above copyright notice, this list of
+*      conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above copyright notice, this list of
+*      conditions and the following disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+*      endorse or promote products derived from this software without specific prior written
+*      permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// Adreno Pixel Formats
+typedef enum {
+
+    ADRENO_PIXELFORMAT_UNKNOWN       = 0,
+    ADRENO_PIXELFORMAT_R10G10B10A2_UNORM = 24,  // Vertex, Normalized GL_UNSIGNED_INT_10_10_10_2_OES
+    ADRENO_PIXELFORMAT_R8G8B8A8      = 28,
+    ADRENO_PIXELFORMAT_R8G8B8A8_SRGB = 29,
+    ADRENO_PIXELFORMAT_B5G6R5        = 85,
+    ADRENO_PIXELFORMAT_B5G5R5A1      = 86,
+    ADRENO_PIXELFORMAT_B8G8R8A8      = 90,
+    ADRENO_PIXELFORMAT_B8G8R8A8_SRGB = 91,
+    ADRENO_PIXELFORMAT_B8G8R8X8_SRGB = 93,
+    ADRENO_PIXELFORMAT_NV12          = 103,
+    ADRENO_PIXELFORMAT_YUY2          = 107,
+    ADRENO_PIXELFORMAT_B4G4R4A4      = 115,
+    ADRENO_PIXELFORMAT_NV12_EXT      = 506,  // NV12 with non-std alignment and offsets
+    ADRENO_PIXELFORMAT_R8G8B8X8      = 507,  // GL_RGB8 (Internal)
+    ADRENO_PIXELFORMAT_R8G8B8        = 508,  // GL_RGB8
+    ADRENO_PIXELFORMAT_A1B5G5R5      = 519,  // GL_RGB5_A1
+    ADRENO_PIXELFORMAT_R8G8B8X8_SRGB = 520,  // GL_SRGB8
+    ADRENO_PIXELFORMAT_R8G8B8_SRGB   = 521,  // GL_SRGB8
+    ADRENO_PIXELFORMAT_A2B10G10R10_UNORM = 532,
+                                             // Vertex, Normalized GL_UNSIGNED_INT_10_10_10_2_OES
+    ADRENO_PIXELFORMAT_R10G10B10X2_UNORM = 537,
+                                             // Vertex, Normalized GL_UNSIGNED_INT_10_10_10_2_OES
+    ADRENO_PIXELFORMAT_R5G6B5        = 610,  // RGBA version of B5G6R5
+    ADRENO_PIXELFORMAT_R5G5B5A1      = 611,  // RGBA version of B5G5R5A1
+    ADRENO_PIXELFORMAT_R4G4B4A4      = 612,  // RGBA version of B4G4R4A4
+    ADRENO_PIXELFORMAT_UYVY          = 614,  // YUV 4:2:2 packed progressive (1 plane)
+    ADRENO_PIXELFORMAT_NV21          = 619,
+    ADRENO_PIXELFORMAT_Y8U8V8A8      = 620,  // YUV 4:4:4 packed (1 plane)
+    ADRENO_PIXELFORMAT_Y8            = 625,  // Single 8-bit luma only channel YUV format
+    ADRENO_PIXELFORMAT_TP10          = 648,
+} ADRENOPIXELFORMAT;
diff --git a/msmcobalt/libgralloc/alloc_controller.cpp b/msmcobalt/libgralloc/alloc_controller.cpp
new file mode 100644
index 0000000..0ef0a9a
--- /dev/null
+++ b/msmcobalt/libgralloc/alloc_controller.cpp
@@ -0,0 +1,1116 @@
+/*
+ * Copyright (c) 2011 - 2016, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <cutils/log.h>
+#include <fcntl.h>
+#include <dlfcn.h>
+#include "gralloc_priv.h"
+#include "alloc_controller.h"
+#include "memalloc.h"
+#include "ionalloc.h"
+#include "gr.h"
+#include "qd_utils.h"
+#include <qdMetaData.h>
+#include <utils/Singleton.h>
+#include <utils/Mutex.h>
+#include <algorithm>
+
+#ifdef VENUS_COLOR_FORMAT
+#include <media/msm_media_info.h>
+#else
+#define VENUS_Y_STRIDE(args...) 0
+#define VENUS_Y_SCANLINES(args...) 0
+#define VENUS_BUFFER_SIZE(args...) 0
+#endif
+
+#define ASTC_BLOCK_SIZE 16
+
+#ifndef ION_FLAG_CP_PIXEL
+#define ION_FLAG_CP_PIXEL 0
+#endif
+
+#ifndef ION_FLAG_ALLOW_NON_CONTIG
+#define ION_FLAG_ALLOW_NON_CONTIG 0
+#endif
+
+#ifdef MASTER_SIDE_CP
+#define CP_HEAP_ID ION_SECURE_HEAP_ID
+#define SD_HEAP_ID ION_SECURE_DISPLAY_HEAP_ID
+#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_CP_PIXEL)
+#define ION_SD_FLAGS (ION_SECURE | ION_FLAG_CP_SEC_DISPLAY)
+#else // SLAVE_SIDE_CP
+#define CP_HEAP_ID ION_CP_MM_HEAP_ID
+#define SD_HEAP_ID CP_HEAP_ID
+#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_ALLOW_NON_CONTIG)
+#define ION_SD_FLAGS ION_SECURE
+#endif
+
+using namespace gralloc;
+using namespace qdutils;
+using namespace android;
+
+ANDROID_SINGLETON_STATIC_INSTANCE(AdrenoMemInfo);
+ANDROID_SINGLETON_STATIC_INSTANCE(MDPCapabilityInfo);
+
+static void getYuvUBwcWidthHeight(int, int, int, int&, int&);
+static unsigned int getUBwcSize(int, int, int, const int, const int);
+
+//Common functions
+
+/* The default policy is to return cached buffers unless the client explicity
+ * sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely
+ * read or written in software. Any combination with a _RARELY_ flag will be
+ * treated as uncached. */
+static bool useUncached(const int& usage) {
+    if ((usage & GRALLOC_USAGE_PROTECTED) or
+        (usage & GRALLOC_USAGE_PRIVATE_UNCACHED) or
+        ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY) or
+        ((usage & GRALLOC_USAGE_SW_READ_MASK) ==  GRALLOC_USAGE_SW_READ_RARELY))
+        return true;
+
+    return false;
+}
+
+//------------- MDPCapabilityInfo-----------------------//
+MDPCapabilityInfo :: MDPCapabilityInfo() {
+  qdutils::querySDEInfo(HAS_MACRO_TILE, &isMacroTileSupported);
+  qdutils::querySDEInfo(HAS_UBWC, &isUBwcSupported);
+  qdutils::querySDEInfo(HAS_WB_UBWC, &isWBUBWCSupported);
+}
+
+//------------- AdrenoMemInfo-----------------------//
+AdrenoMemInfo::AdrenoMemInfo()
+{
+    LINK_adreno_compute_aligned_width_and_height = NULL;
+    LINK_adreno_compute_padding = NULL;
+    LINK_adreno_isMacroTilingSupportedByGpu = NULL;
+    LINK_adreno_compute_compressedfmt_aligned_width_and_height = NULL;
+    LINK_adreno_isUBWCSupportedByGpu = NULL;
+    LINK_adreno_get_gpu_pixel_alignment = NULL;
+
+    libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW);
+    if (libadreno_utils) {
+        *(void **)&LINK_adreno_compute_aligned_width_and_height =
+                ::dlsym(libadreno_utils, "compute_aligned_width_and_height");
+        *(void **)&LINK_adreno_compute_padding =
+                ::dlsym(libadreno_utils, "compute_surface_padding");
+        *(void **)&LINK_adreno_isMacroTilingSupportedByGpu =
+                ::dlsym(libadreno_utils, "isMacroTilingSupportedByGpu");
+        *(void **)&LINK_adreno_compute_compressedfmt_aligned_width_and_height =
+                ::dlsym(libadreno_utils,
+                        "compute_compressedfmt_aligned_width_and_height");
+        *(void **)&LINK_adreno_isUBWCSupportedByGpu =
+                ::dlsym(libadreno_utils, "isUBWCSupportedByGpu");
+        *(void **)&LINK_adreno_get_gpu_pixel_alignment =
+                ::dlsym(libadreno_utils, "get_gpu_pixel_alignment");
+    }
+
+    // Check if the overriding property debug.gralloc.gfx_ubwc_disable
+    // that disables UBWC allocations for the graphics stack is set
+    gfx_ubwc_disable = 0;
+    char property[PROPERTY_VALUE_MAX];
+    property_get("debug.gralloc.gfx_ubwc_disable", property, "0");
+    if(!(strncmp(property, "1", PROPERTY_VALUE_MAX)) ||
+       !(strncmp(property, "true", PROPERTY_VALUE_MAX))) {
+        gfx_ubwc_disable = 1;
+    }
+}
+
+AdrenoMemInfo::~AdrenoMemInfo()
+{
+    if (libadreno_utils) {
+        ::dlclose(libadreno_utils);
+    }
+}
+
+int AdrenoMemInfo::isMacroTilingSupportedByGPU()
+{
+    if ((libadreno_utils)) {
+        if(LINK_adreno_isMacroTilingSupportedByGpu) {
+            return LINK_adreno_isMacroTilingSupportedByGpu();
+        }
+    }
+    return 0;
+}
+
+void AdrenoMemInfo::getAlignedWidthAndHeight(const private_handle_t *hnd, int& aligned_w,
+                          int& aligned_h) {
+    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+    if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
+        int w = metadata->bufferDim.sliceWidth;
+        int h = metadata->bufferDim.sliceHeight;
+        int f = hnd->format;
+        int usage = 0;
+
+        if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
+            usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
+        }
+
+        getAlignedWidthAndHeight(w, h, f, usage, aligned_w, aligned_h);
+    } else {
+        aligned_w = hnd->width;
+        aligned_h = hnd->height;
+    }
+
+}
+
+bool isUncompressedRgbFormat(int format)
+{
+    bool is_rgb_format = false;
+
+    switch (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_BGR_565:
+        case HAL_PIXEL_FORMAT_BGRA_8888:
+        case HAL_PIXEL_FORMAT_RGBA_5551:
+        case HAL_PIXEL_FORMAT_RGBA_4444:
+        case HAL_PIXEL_FORMAT_R_8:
+        case HAL_PIXEL_FORMAT_RG_88:
+        case HAL_PIXEL_FORMAT_BGRX_8888:
+        case HAL_PIXEL_FORMAT_RGBA_1010102:
+        case HAL_PIXEL_FORMAT_ARGB_2101010:
+        case HAL_PIXEL_FORMAT_RGBX_1010102:
+        case HAL_PIXEL_FORMAT_XRGB_2101010:
+        case HAL_PIXEL_FORMAT_BGRA_1010102:
+        case HAL_PIXEL_FORMAT_ABGR_2101010:
+        case HAL_PIXEL_FORMAT_BGRX_1010102:
+        case HAL_PIXEL_FORMAT_XBGR_2101010:    // Intentional fallthrough
+            is_rgb_format = true;
+            break;
+        default:
+            break;
+    }
+
+    return is_rgb_format;
+}
+
+void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format,
+                            int usage, int& aligned_w, int& aligned_h)
+{
+    bool ubwc_enabled = isUBwcEnabled(format, usage);
+
+    // Currently surface padding is only computed for RGB* surfaces.
+    if (isUncompressedRgbFormat(format) == true) {
+        int tileEnabled = ubwc_enabled || isMacroTileEnabled(format, usage);
+        getGpuAlignedWidthHeight(width, height, format, tileEnabled, aligned_w, aligned_h);
+    } else if (ubwc_enabled) {
+        getYuvUBwcWidthHeight(width, height, format, aligned_w, aligned_h);
+    } else {
+        aligned_w = width;
+        aligned_h = height;
+        int alignment = 32;
+        switch (format)
+        {
+            case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+            case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+                if (LINK_adreno_get_gpu_pixel_alignment) {
+                  alignment = LINK_adreno_get_gpu_pixel_alignment();
+                }
+                aligned_w = ALIGN(width, alignment);
+                break;
+            case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
+                aligned_w = ALIGN(width, alignment);
+                break;
+            case HAL_PIXEL_FORMAT_RAW16:
+                aligned_w = ALIGN(width, 16);
+                break;
+            case HAL_PIXEL_FORMAT_RAW10:
+                aligned_w = ALIGN(width * 10 / 8, 8);
+                break;
+            case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
+                aligned_w = ALIGN(width, 128);
+                break;
+            case HAL_PIXEL_FORMAT_YV12:
+            case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+            case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+            case HAL_PIXEL_FORMAT_YCbCr_422_I:
+            case HAL_PIXEL_FORMAT_YCrCb_422_I:
+                aligned_w = ALIGN(width, 16);
+                break;
+            case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+            case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+                aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
+                aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
+                break;
+            case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
+                aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV21, width);
+                aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV21, height);
+                break;
+            case HAL_PIXEL_FORMAT_BLOB:
+            case HAL_PIXEL_FORMAT_RAW_OPAQUE:
+                break;
+            case HAL_PIXEL_FORMAT_NV21_ZSL:
+                aligned_w = ALIGN(width, 64);
+                aligned_h = ALIGN(height, 64);
+                break;
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
+            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
+                if(LINK_adreno_compute_compressedfmt_aligned_width_and_height) {
+                    int bytesPerPixel = 0;
+                    int raster_mode         = 0;   //Adreno unknown raster mode.
+                    int padding_threshold   = 512; //Threshold for padding
+                    //surfaces.
+
+                    LINK_adreno_compute_compressedfmt_aligned_width_and_height(
+                        width, height, format, 0,raster_mode, padding_threshold,
+                        &aligned_w, &aligned_h, &bytesPerPixel);
+                } else {
+                    ALOGW("%s: Warning!! Symbols" \
+                          " compute_compressedfmt_aligned_width_and_height" \
+                          " not found", __FUNCTION__);
+                }
+                break;
+            default: break;
+        }
+    }
+}
+
+void AdrenoMemInfo::getGpuAlignedWidthHeight(int width, int height, int format,
+                            int tile_enabled, int& aligned_w, int& aligned_h)
+{
+    aligned_w = ALIGN(width, 32);
+    aligned_h = ALIGN(height, 32);
+
+    // Don't add any additional padding if debug.gralloc.map_fb_memory
+    // is enabled
+    char property[PROPERTY_VALUE_MAX];
+    if((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
+       (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
+       (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
+        return;
+    }
+
+    int bpp = 4;
+    switch(format)
+    {
+        case HAL_PIXEL_FORMAT_RGB_888:
+            bpp = 3;
+            break;
+        case HAL_PIXEL_FORMAT_RGB_565:
+        case HAL_PIXEL_FORMAT_BGR_565:
+        case HAL_PIXEL_FORMAT_RGBA_5551:
+        case HAL_PIXEL_FORMAT_RGBA_4444:
+            bpp = 2;
+            break;
+        default: break;
+    }
+
+    if (libadreno_utils) {
+        int raster_mode         = 0;   // Adreno unknown raster mode.
+        int padding_threshold   = 512; // Threshold for padding surfaces.
+        // the function below computes aligned width and aligned height
+        // based on linear or macro tile mode selected.
+        if(LINK_adreno_compute_aligned_width_and_height) {
+            LINK_adreno_compute_aligned_width_and_height(width,
+                                 height, bpp, tile_enabled,
+                                 raster_mode, padding_threshold,
+                                 &aligned_w, &aligned_h);
+
+        } else if(LINK_adreno_compute_padding) {
+            int surface_tile_height = 1;   // Linear surface
+            aligned_w = LINK_adreno_compute_padding(width, bpp,
+                                 surface_tile_height, raster_mode,
+                                 padding_threshold);
+            ALOGW("%s: Warning!! Old GFX API is used to calculate stride",
+                                                            __FUNCTION__);
+        } else {
+            ALOGW("%s: Warning!! Symbols compute_surface_padding and " \
+                 "compute_aligned_width_and_height not found", __FUNCTION__);
+        }
+   }
+}
+
+int AdrenoMemInfo::isUBWCSupportedByGPU(int format)
+{
+    if (!gfx_ubwc_disable && libadreno_utils) {
+        if (LINK_adreno_isUBWCSupportedByGpu) {
+            ADRENOPIXELFORMAT gpu_format = getGpuPixelFormat(format);
+            return LINK_adreno_isUBWCSupportedByGpu(gpu_format);
+        }
+    }
+    return 0;
+}
+
+ADRENOPIXELFORMAT AdrenoMemInfo::getGpuPixelFormat(int hal_format)
+{
+    switch (hal_format) {
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+            return ADRENO_PIXELFORMAT_R8G8B8A8;
+        case HAL_PIXEL_FORMAT_RGBX_8888:
+            return ADRENO_PIXELFORMAT_R8G8B8X8;
+        case HAL_PIXEL_FORMAT_RGB_565:
+            return ADRENO_PIXELFORMAT_B5G6R5;
+        case HAL_PIXEL_FORMAT_BGR_565:
+            return ADRENO_PIXELFORMAT_R5G6B5;
+        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+            return ADRENO_PIXELFORMAT_NV12;
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+            return ADRENO_PIXELFORMAT_NV12_EXT;
+        case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+            return ADRENO_PIXELFORMAT_TP10;
+        case HAL_PIXEL_FORMAT_RGBA_1010102:
+            return ADRENO_PIXELFORMAT_R10G10B10A2_UNORM;
+        case HAL_PIXEL_FORMAT_RGBX_1010102:
+            return ADRENO_PIXELFORMAT_R10G10B10X2_UNORM;
+        case HAL_PIXEL_FORMAT_ABGR_2101010:
+            return ADRENO_PIXELFORMAT_A2B10G10R10_UNORM;
+        default:
+            ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format);
+            break;
+    }
+    return ADRENO_PIXELFORMAT_UNKNOWN;
+}
+
+//-------------- IAllocController-----------------------//
+IAllocController* IAllocController::sController = NULL;
+IAllocController* IAllocController::getInstance(void)
+{
+    if(sController == NULL) {
+        sController = new IonController();
+    }
+    return sController;
+}
+
+
+//-------------- IonController-----------------------//
+IonController::IonController()
+{
+    allocateIonMem();
+
+    char property[PROPERTY_VALUE_MAX];
+    property_get("video.disable.ubwc", property, "0");
+    mDisableUBWCForEncode = atoi(property);
+}
+
+void IonController::allocateIonMem()
+{
+   mIonAlloc = new IonAlloc();
+}
+
+int IonController::allocate(alloc_data& data, int usage)
+{
+    int ionFlags = 0;
+    int ionHeapId = 0;
+    int ret;
+
+    data.uncached = useUncached(usage);
+    data.allocType = 0;
+
+    if(usage & GRALLOC_USAGE_PROTECTED) {
+        if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
+            ionHeapId = ION_HEAP(SD_HEAP_ID);
+            /*
+             * There is currently no flag in ION for Secure Display
+             * VM. Please add it to the define once available.
+             */
+            ionFlags |= ION_SD_FLAGS;
+        } else {
+            ionHeapId = ION_HEAP(CP_HEAP_ID);
+            ionFlags |= ION_CP_FLAGS;
+        }
+    } else if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
+        //MM Heap is exclusively a secure heap.
+        //If it is used for non secure cases, fallback to IOMMU heap
+        ALOGW("GRALLOC_USAGE_PRIVATE_MM_HEAP \
+                                cannot be used as an insecure heap!\
+                                trying to use system heap instead !!");
+        ionHeapId |= ION_HEAP(ION_SYSTEM_HEAP_ID);
+    }
+
+    if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
+        ionHeapId |= ION_HEAP(ION_CAMERA_HEAP_ID);
+
+    if(usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP)
+        ionHeapId |= ION_HEAP(ION_ADSP_HEAP_ID);
+
+    if(ionFlags & ION_SECURE)
+         data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
+
+    // if no ion heap flags are set, default to system heap
+    if(!ionHeapId)
+        ionHeapId = ION_HEAP(ION_SYSTEM_HEAP_ID);
+
+    //At this point we should have the right heap set, there is no fallback
+    data.flags = ionFlags;
+    data.heapId = ionHeapId;
+    ret = mIonAlloc->alloc_buffer(data);
+
+    if(ret >= 0 ) {
+        data.allocType |= private_handle_t::PRIV_FLAGS_USES_ION;
+    } else {
+        ALOGE("%s: Failed to allocate buffer - heap: 0x%x flags: 0x%x",
+                __FUNCTION__, ionHeapId, ionFlags);
+    }
+
+    return ret;
+}
+
+IMemAlloc* IonController::getAllocator(int flags)
+{
+    IMemAlloc* memalloc = NULL;
+    if (flags & private_handle_t::PRIV_FLAGS_USES_ION) {
+        memalloc = mIonAlloc;
+    } else {
+        ALOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags);
+    }
+
+    return memalloc;
+}
+
+bool isMacroTileEnabled(int format, int usage)
+{
+    bool tileEnabled = false;
+    // Check whether GPU & MDSS supports MacroTiling feature
+    if(AdrenoMemInfo::getInstance().isMacroTilingSupportedByGPU() &&
+       MDPCapabilityInfo::getInstance().isMacroTilingSupportedByMDP())
+    {
+        // check the format
+        switch(format)
+        {
+            case  HAL_PIXEL_FORMAT_RGBA_8888:
+            case  HAL_PIXEL_FORMAT_RGBX_8888:
+            case  HAL_PIXEL_FORMAT_BGRA_8888:
+            case  HAL_PIXEL_FORMAT_RGB_565:
+            case  HAL_PIXEL_FORMAT_BGR_565:
+                {
+                    tileEnabled = true;
+                    // check the usage flags
+                    if (usage & (GRALLOC_USAGE_SW_READ_MASK |
+                                GRALLOC_USAGE_SW_WRITE_MASK)) {
+                        // Application intends to use CPU for rendering
+                        tileEnabled = false;
+                    }
+                    break;
+                }
+            default:
+                break;
+        }
+    }
+    return tileEnabled;
+}
+
+// helper function
+unsigned int getSize(int format, int width, int height, int usage,
+        const int alignedw, const int alignedh) {
+
+    if (isUBwcEnabled(format, usage)) {
+        return getUBwcSize(width, height, format, alignedw, alignedh);
+    }
+
+    unsigned int size = 0;
+    switch (format) {
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+        case HAL_PIXEL_FORMAT_RGBX_8888:
+        case HAL_PIXEL_FORMAT_BGRA_8888:
+        case HAL_PIXEL_FORMAT_RGBA_1010102:
+        case HAL_PIXEL_FORMAT_ARGB_2101010:
+        case HAL_PIXEL_FORMAT_RGBX_1010102:
+        case HAL_PIXEL_FORMAT_XRGB_2101010:
+        case HAL_PIXEL_FORMAT_BGRA_1010102:
+        case HAL_PIXEL_FORMAT_ABGR_2101010:
+        case HAL_PIXEL_FORMAT_BGRX_1010102:
+        case HAL_PIXEL_FORMAT_XBGR_2101010:
+            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_BGR_565:
+        case HAL_PIXEL_FORMAT_RGBA_5551:
+        case HAL_PIXEL_FORMAT_RGBA_4444:
+        case HAL_PIXEL_FORMAT_RAW16:
+            size = alignedw * alignedh * 2;
+            break;
+        case HAL_PIXEL_FORMAT_RAW10:
+            size = ALIGN(alignedw * alignedh, 4096);
+            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
+            size  = ALIGN( alignedw * alignedh, 8192);
+            size += ALIGN( alignedw * ALIGN(height/2, 32), 8192);
+            break;
+        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 0;
+            }
+            size = alignedw*alignedh +
+                    (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
+            size = ALIGN(size, (unsigned int)4096);
+            break;
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+            size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2 + 1, 4096);
+            break;
+        case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+        case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+        case HAL_PIXEL_FORMAT_YCbCr_422_I:
+        case HAL_PIXEL_FORMAT_YCrCb_422_I:
+            if(width & 1) {
+                ALOGE("width is odd for the YUV422_SP format");
+                return 0;
+            }
+            size = ALIGN(alignedw * alignedh * 2, 4096);
+            break;
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+            size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
+            break;
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
+            size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height);
+            break;
+        case HAL_PIXEL_FORMAT_BLOB:
+        case HAL_PIXEL_FORMAT_RAW_OPAQUE:
+            if(height != 1) {
+                ALOGE("%s: Buffers with format HAL_PIXEL_FORMAT_BLOB \
+                      must have height==1 ", __FUNCTION__);
+                return 0;
+            }
+            size = width;
+            break;
+        case HAL_PIXEL_FORMAT_NV21_ZSL:
+            size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2, 4096);
+            break;
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
+        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
+            size = alignedw * alignedh * ASTC_BLOCK_SIZE;
+            break;
+        default:
+            ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
+            return 0;
+    }
+    return size;
+}
+
+unsigned int getBufferSizeAndDimensions(int width, int height, int format,
+        int& alignedw, int &alignedh)
+{
+    unsigned int size;
+
+    AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
+            height,
+            format,
+            0,
+            alignedw,
+            alignedh);
+
+    size = getSize(format, width, height, 0 /* usage */, alignedw, alignedh);
+
+    return size;
+}
+
+
+unsigned int getBufferSizeAndDimensions(int width, int height, int format,
+        int usage, int& alignedw, int &alignedh)
+{
+    unsigned int size;
+
+    AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
+            height,
+            format,
+            usage,
+            alignedw,
+            alignedh);
+
+    size = getSize(format, width, height, usage, alignedw, alignedh);
+
+    return size;
+}
+
+
+void getBufferAttributes(int width, int height, int format, int usage,
+        int& alignedw, int &alignedh, int& tiled, unsigned int& size)
+{
+    tiled = isUBwcEnabled(format, usage) || isMacroTileEnabled(format, usage);
+
+    AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
+            height,
+            format,
+            usage,
+            alignedw,
+            alignedh);
+    size = getSize(format, width, height, usage, alignedw, alignedh);
+}
+
+void getYuvUbwcSPPlaneInfo(uint64_t base, int width, int height,
+                           int color_format, struct android_ycbcr* ycbcr)
+{
+    // UBWC buffer has these 4 planes in the following sequence:
+    // Y_Meta_Plane, Y_Plane, UV_Meta_Plane, UV_Plane
+    unsigned int y_meta_stride, y_meta_height, y_meta_size;
+    unsigned int y_stride, y_height, y_size;
+    unsigned int c_meta_stride, c_meta_height, c_meta_size;
+    unsigned int alignment = 4096;
+
+    y_meta_stride = VENUS_Y_META_STRIDE(color_format, width);
+    y_meta_height = VENUS_Y_META_SCANLINES(color_format, height);
+    y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);
+
+    y_stride = VENUS_Y_STRIDE(color_format, width);
+    y_height = VENUS_Y_SCANLINES(color_format, height);
+    y_size = ALIGN((y_stride * y_height), alignment);
+
+    c_meta_stride = VENUS_UV_META_STRIDE(color_format, width);
+    c_meta_height = VENUS_UV_META_SCANLINES(color_format, height);
+    c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
+
+    ycbcr->y  = (void*)(base + y_meta_size);
+    ycbcr->cb = (void*)(base + y_meta_size + y_size + c_meta_size);
+    ycbcr->cr = (void*)(base + y_meta_size + y_size +
+                        c_meta_size + 1);
+    ycbcr->ystride = y_stride;
+    ycbcr->cstride = VENUS_UV_STRIDE(color_format, width);
+}
+
+void getYuvSPPlaneInfo(uint64_t base, int width, int height, int bpp,
+                       struct android_ycbcr* ycbcr)
+{
+    unsigned int ystride, cstride;
+
+    ystride = cstride = width * bpp;
+    ycbcr->y  = (void*)base;
+    ycbcr->cb = (void*)(base + ystride * height);
+    ycbcr->cr = (void*)(base + ystride * height + 1);
+    ycbcr->ystride = ystride;
+    ycbcr->cstride = cstride;
+    ycbcr->chroma_step = 2 * bpp;
+}
+
+int getYUVPlaneInfo(private_handle_t* hnd, struct android_ycbcr* ycbcr)
+{
+    int err = 0;
+    int width = hnd->width;
+    int height = hnd->height;
+    int format = hnd->format;
+
+    unsigned int ystride, cstride;
+
+    memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
+    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+
+    // Check if UBWC buffer has been rendered in linear format.
+    if (metadata && (metadata->operation & LINEAR_FORMAT)) {
+        format = metadata->linearFormat;
+    }
+
+    // Check metadata if the geometry has been updated.
+    if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
+        int usage = 0;
+
+        if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
+            usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
+        }
+
+        AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(metadata->bufferDim.sliceWidth,
+                   metadata->bufferDim.sliceHeight, format, usage, width, height);
+    }
+
+    // Get the chroma offsets from the handle width/height. We take advantage
+    // of the fact the width _is_ the stride
+    switch (format) {
+        //Semiplanar
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+        case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: //Same as YCbCr_420_SP_VENUS
+            getYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
+        break;
+
+        case HAL_PIXEL_FORMAT_YCbCr_420_P010:
+            getYuvSPPlaneInfo(hnd->base, width, height, 2, ycbcr);
+        break;
+
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+            getYuvUbwcSPPlaneInfo(hnd->base, width, height,
+                                  COLOR_FMT_NV12_UBWC, ycbcr);
+            ycbcr->chroma_step = 2;
+        break;
+
+        case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+            getYuvUbwcSPPlaneInfo(hnd->base, width, height,
+                                  COLOR_FMT_NV12_BPP10_UBWC, ycbcr);
+            ycbcr->chroma_step = 3;
+        break;
+
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+        case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
+        case HAL_PIXEL_FORMAT_NV21_ZSL:
+        case HAL_PIXEL_FORMAT_RAW16:
+        case HAL_PIXEL_FORMAT_RAW10:
+            getYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
+            std::swap(ycbcr->cb, ycbcr->cr);
+        break;
+
+        //Planar
+        case HAL_PIXEL_FORMAT_YV12:
+            ystride = width;
+            cstride = ALIGN(width/2, 16);
+            ycbcr->y  = (void*)hnd->base;
+            ycbcr->cr = (void*)(hnd->base + ystride * height);
+            ycbcr->cb = (void*)(hnd->base + ystride * height +
+                    cstride * height/2);
+            ycbcr->ystride = ystride;
+            ycbcr->cstride = cstride;
+            ycbcr->chroma_step = 1;
+        break;
+        //Unsupported formats
+        case HAL_PIXEL_FORMAT_YCbCr_422_I:
+        case HAL_PIXEL_FORMAT_YCrCb_422_I:
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
+        default:
+        ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
+        err = -EINVAL;
+    }
+    return err;
+
+}
+
+
+
+// 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;
+    gralloc::IAllocController* sAlloc =
+        gralloc::IAllocController::getInstance();
+    data.base = 0;
+    data.fd = -1;
+    data.offset = 0;
+    data.size = getBufferSizeAndDimensions(w, h, format, usage, alignedw,
+                                            alignedh);
+
+    data.align = getpagesize();
+    data.uncached = useUncached(usage);
+    int allocFlags = usage;
+
+    int err = sAlloc->allocate(data, allocFlags);
+    if (0 != err) {
+        ALOGE("%s: allocate failed", __FUNCTION__);
+        return -ENOMEM;
+    }
+
+    if(isUBwcEnabled(format, usage)) {
+      data.allocType |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+    }
+
+    private_handle_t* hnd = new private_handle_t(data.fd, data.size,
+                                                 data.allocType, 0, format,
+                                                 alignedw, alignedh);
+    hnd->base = (uint64_t) data.base;
+    hnd->offset = data.offset;
+    hnd->gpuaddr = 0;
+    *pHnd = hnd;
+    return 0;
+}
+
+void free_buffer(private_handle_t *hnd)
+{
+    gralloc::IAllocController* sAlloc =
+        gralloc::IAllocController::getInstance();
+    if (hnd && hnd->fd > 0) {
+        IMemAlloc* memalloc = sAlloc->getAllocator(hnd->flags);
+        memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);
+    }
+    if(hnd)
+        delete hnd;
+
+}
+
+// UBWC helper functions
+static bool isUBwcFormat(int format)
+{
+    // Explicitly defined UBWC formats
+    switch(format)
+    {
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+        case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+            return true;
+        default:
+            return false;
+    }
+}
+
+static bool isUBwcSupported(int format)
+{
+    if (MDPCapabilityInfo::getInstance().isUBwcSupportedByMDP()) {
+        // Existing HAL formats with UBWC support
+        switch(format)
+        {
+            case HAL_PIXEL_FORMAT_BGR_565:
+            case HAL_PIXEL_FORMAT_RGBA_8888:
+            case HAL_PIXEL_FORMAT_RGBX_8888:
+            case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+            case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+            case HAL_PIXEL_FORMAT_RGBA_1010102:
+            case HAL_PIXEL_FORMAT_RGBX_1010102:
+                return true;
+            default:
+                break;
+        }
+    }
+    return false;
+}
+
+bool isUBwcEnabled(int format, int usage)
+{
+    // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
+    if (isUBwcFormat(format))
+        return true;
+
+    if ((usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) &&
+        gralloc::IAllocController::getInstance()->isDisableUBWCForEncoder()) {
+            return false;
+    }
+
+    // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
+    // support the format. OR if a non-OpenGL client like Rotator, sets UBWC
+    // usage flag and MDP supports the format.
+    if ((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) && isUBwcSupported(format)) {
+        bool enable = true;
+        // Query GPU for UBWC only if buffer is intended to be used by GPU.
+        if (usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER)) {
+            enable = AdrenoMemInfo::getInstance().isUBWCSupportedByGPU(format);
+        }
+        // Allow UBWC, only if CPU usage flags are not set
+        if (enable && !(usage & (GRALLOC_USAGE_SW_READ_MASK |
+            GRALLOC_USAGE_SW_WRITE_MASK))) {
+            return true;
+        }
+    }
+    return false;
+}
+
+static void getYuvUBwcWidthHeight(int width, int height, int format,
+        int& aligned_w, int& aligned_h)
+{
+    switch (format)
+    {
+        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+            aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
+            aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
+            break;
+        case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+            aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, width);
+            aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, height);
+            break;
+        default:
+            ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
+            aligned_w = 0;
+            aligned_h = 0;
+            break;
+    }
+}
+
+static void getRgbUBwcBlockSize(int bpp, int& block_width, int& block_height)
+{
+    block_width = 0;
+    block_height = 0;
+
+    switch(bpp)
+    {
+         case 2:
+         case 4:
+             block_width = 16;
+             block_height = 4;
+             break;
+         case 8:
+             block_width = 8;
+             block_height = 4;
+             break;
+         case 16:
+             block_width = 4;
+             block_height = 4;
+             break;
+         default:
+             ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
+             break;
+    }
+}
+
+static unsigned int getRgbUBwcMetaBufferSize(int width, int height, int bpp)
+{
+    unsigned int size = 0;
+    int meta_width, meta_height;
+    int block_width, block_height;
+
+    getRgbUBwcBlockSize(bpp, block_width, block_height);
+
+    if (!block_width || !block_height) {
+        ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
+        return size;
+    }
+
+    // Align meta buffer height to 16 blocks
+    meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
+
+    // Align meta buffer width to 64 blocks
+    meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
+
+    // Align meta buffer size to 4K
+    size = ALIGN((meta_width * meta_height), 4096);
+    return size;
+}
+
+static unsigned int getUBwcSize(int width, int height, int format,
+        const int alignedw, const int alignedh) {
+
+    unsigned int size = 0;
+    switch (format) {
+        case HAL_PIXEL_FORMAT_BGR_565:
+            size = alignedw * alignedh * 2;
+            size += getRgbUBwcMetaBufferSize(width, height, 2);
+            break;
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+        case HAL_PIXEL_FORMAT_RGBX_8888:
+        case HAL_PIXEL_FORMAT_RGBA_1010102:
+        case HAL_PIXEL_FORMAT_RGBX_1010102:
+            size = alignedw * alignedh * 4;
+            size += getRgbUBwcMetaBufferSize(width, height, 4);
+            break;
+        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+            size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
+            break;
+        case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+            size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height);
+            break;
+        default:
+            ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
+            break;
+    }
+    return size;
+}
+
+int getRgbDataAddress(private_handle_t* hnd, void** rgb_data)
+{
+    int err = 0;
+
+    // This api is for RGB* formats
+    if (!isUncompressedRgbFormat(hnd->format)) {
+        return -EINVAL;
+    }
+
+    // linear buffer
+    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
+        *rgb_data = (void*)hnd->base;
+        return err;
+    }
+
+    unsigned int meta_size = 0;
+    switch (hnd->format) {
+        case HAL_PIXEL_FORMAT_BGR_565:
+            meta_size = getRgbUBwcMetaBufferSize(hnd->width, hnd->height, 2);
+            break;
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+        case HAL_PIXEL_FORMAT_RGBX_8888:
+            meta_size = getRgbUBwcMetaBufferSize(hnd->width, hnd->height, 4);
+            break;
+        default:
+            ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format);
+            err = -EINVAL;
+            break;
+    }
+
+    *rgb_data = (void*)(hnd->base + meta_size);
+    return err;
+}
diff --git a/msmcobalt/libgralloc/alloc_controller.h b/msmcobalt/libgralloc/alloc_controller.h
new file mode 100644
index 0000000..8216b0c
--- /dev/null
+++ b/msmcobalt/libgralloc/alloc_controller.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef GRALLOC_ALLOCCONTROLLER_H
+#define GRALLOC_ALLOCCONTROLLER_H
+
+#define SZ_2M 0x200000
+#define SZ_1M 0x100000
+#define SZ_4K 0x1000
+
+/* TODO: Move this to the common makefile */
+#ifdef MASTER_SIDE_CP
+#define SECURE_ALIGN SZ_4K
+#else
+#define SECURE_ALIGN SZ_1M
+#endif
+
+namespace gralloc {
+
+struct alloc_data;
+class IMemAlloc;
+class IonAlloc;
+
+class IAllocController {
+
+    public:
+    /* Allocate using a suitable method
+     * Returns the type of buffer allocated
+     */
+    virtual int allocate(alloc_data& data, int usage) = 0;
+
+    virtual IMemAlloc* getAllocator(int flags) = 0;
+
+    virtual bool isDisableUBWCForEncoder();
+
+    virtual ~IAllocController() {};
+
+    static IAllocController* getInstance(void);
+
+    private:
+    static IAllocController* sController;
+
+};
+
+class IonController : public IAllocController {
+
+    public:
+    virtual int allocate(alloc_data& data, int usage);
+
+    virtual IMemAlloc* getAllocator(int flags);
+
+    virtual bool isDisableUBWCForEncoder() {
+        return mDisableUBWCForEncode;
+    }
+
+    IonController();
+
+    private:
+    IonAlloc* mIonAlloc;
+    bool mDisableUBWCForEncode;
+    void allocateIonMem();
+
+};
+} //end namespace gralloc
+#endif // GRALLOC_ALLOCCONTROLLER_H
diff --git a/msmcobalt/libgralloc/fb_priv.h b/msmcobalt/libgralloc/fb_priv.h
new file mode 100644
index 0000000..e2eba6a
--- /dev/null
+++ b/msmcobalt/libgralloc/fb_priv.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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 FB_PRIV_H
+#define FB_PRIV_H
+#include <linux/fb.h>
+#include <linux/msm_mdp.h>
+
+#define NUM_FRAMEBUFFERS_MIN  2
+#define NUM_FRAMEBUFFERS_MAX  3
+
+#define NO_SURFACEFLINGER_SWAPINTERVAL
+#define COLOR_FORMAT(x) (x & 0xFFF) // Max range for colorFormats is 0 - FFF
+
+struct private_handle_t;
+
+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,
+};
+
+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;
+    struct fb_var_screeninfo info;
+    struct fb_fix_screeninfo finfo;
+    float xdpi;
+    float ydpi;
+    float fps;
+    uint32_t swapInterval;
+};
+
+
+
+#endif /* FB_PRIV_H */
diff --git a/msmcobalt/libgralloc/framebuffer.cpp b/msmcobalt/libgralloc/framebuffer.cpp
new file mode 100644
index 0000000..dd4842f
--- /dev/null
+++ b/msmcobalt/libgralloc/framebuffer.cpp
@@ -0,0 +1,457 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2010-2014 The Linux Foundation. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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 <cutils/log.h>
+#include <cutils/properties.h>
+#include <dlfcn.h>
+
+#include <hardware/hardware.h>
+
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <cutils/atomic.h>
+
+#include <linux/fb.h>
+#include <linux/msm_mdp.h>
+
+#ifndef TARGET_HEADLESS
+#include <GLES/gl.h>
+#endif
+
+#include "gralloc_priv.h"
+#include "fb_priv.h"
+#include "gr.h"
+#include <cutils/properties.h>
+#include <profiler.h>
+
+#define EVEN_OUT(x) if (x & 0x0001) {x--;}
+
+enum {
+    PAGE_FLIP = 0x00000001,
+};
+
+struct fb_context_t {
+    framebuffer_device_t  device;
+    //fd - which is returned on open
+    int fbFd;
+};
+
+static int fb_setSwapInterval(struct framebuffer_device_t* dev,
+                              int interval)
+{
+    //XXX: Get the value here and implement along with
+    //single vsync in HWC
+    char pval[PROPERTY_VALUE_MAX];
+    property_get("debug.egl.swapinterval", pval, "-1");
+    int property_interval = atoi(pval);
+    if (property_interval >= 0)
+        interval = property_interval;
+
+    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_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
+{
+    private_module_t* m =
+        reinterpret_cast<private_module_t*>(dev->common.module);
+    private_handle_t *hnd = static_cast<private_handle_t*>
+        (const_cast<native_handle_t*>(buffer));
+    fb_context_t *ctx = reinterpret_cast<fb_context_t*>(dev);
+    const unsigned int offset = (unsigned int) (hnd->base -
+            m->framebuffer->base);
+    m->info.activate = FB_ACTIVATE_VBL;
+    m->info.yoffset = (int)(offset / m->finfo.line_length);
+    if (ioctl(ctx->fbFd, FBIOPUT_VSCREENINFO, &m->info) == -1) {
+        ALOGE("%s: FBIOPUT_VSCREENINFO for primary failed, str: %s",
+                __FUNCTION__, strerror(errno));
+        return -errno;
+    }
+    return 0;
+}
+
+static int fb_compositionComplete(struct framebuffer_device_t* dev)
+{
+    // TODO: Properly implement composition complete callback
+    if(!dev) {
+        return -1;
+    }
+#ifndef TARGET_HEADLESS
+    glFinish();
+#endif
+
+    return 0;
+}
+
+int mapFrameBufferLocked(framebuffer_device_t *dev)
+{
+    private_module_t* module =
+        reinterpret_cast<private_module_t*>(dev->common.module);
+    fb_context_t *ctx = reinterpret_cast<fb_context_t*>(dev);
+    // 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) {
+        close(fd);
+        return -errno;
+    }
+
+    struct fb_var_screeninfo info;
+    if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) {
+        close(fd);
+        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
+    unsigned int size = roundUpToPageSize(info.yres * info.xres *
+                                               (info.bits_per_pixel/8));
+
+    /*
+     * Request NUM_BUFFERS screens (at least 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 = (uint32_t) ((size * numberOfBuffers) / line_length);
+
+    uint32_t flags = PAGE_FLIP;
+
+    if (info.yres_virtual < ((size * 2) / line_length) ) {
+        // we need at least 2 for page-flipping
+        info.yres_virtual = (int)(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) {
+        close(fd);
+        return -errno;
+    }
+
+    if (int(info.width) <= 0 || int(info.height) <= 0) {
+        // the driver doesn't return that information
+        // default to 160 dpi
+        info.width  = (uint32_t)(((float)(info.xres) * 25.4f)/160.0f + 0.5f);
+        info.height = (uint32_t)(((float)(info.yres) * 25.4f)/160.0f + 0.5f);
+    }
+
+    float xdpi = ((float)(info.xres) * 25.4f) / (float)info.width;
+    float ydpi = ((float)(info.yres) * 25.4f) / (float)info.height;
+
+#ifdef MSMFB_METADATA_GET
+    struct msmfb_metadata metadata;
+    memset(&metadata, 0 , sizeof(metadata));
+    metadata.op = metadata_op_frame_rate;
+    if (ioctl(fd, MSMFB_METADATA_GET, &metadata) == -1) {
+        ALOGE("Error retrieving panel frame rate");
+        close(fd);
+        return -errno;
+    }
+    float fps = (float)metadata.data.panel_frame_rate;
+#else
+    //XXX: Remove reserved field usage on all baselines
+    //The reserved[3] field is used to store FPS by the driver.
+    float fps  = info.reserved[3] & 0xFF;
+#endif
+    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) {
+        close(fd);
+        return -errno;
+    }
+
+    if (finfo.smem_len <= 0) {
+        close(fd);
+        return -errno;
+    }
+
+    module->flags = flags;
+    module->info = info;
+    module->finfo = finfo;
+    module->xdpi = xdpi;
+    module->ydpi = ydpi;
+    module->fps = fps;
+    module->swapInterval = 1;
+
+    CALC_INIT();
+
+    /*
+     * map the framebuffer
+     */
+
+    module->numBuffers = info.yres_virtual / info.yres;
+    module->bufferMask = 0;
+    //adreno needs page aligned offsets. Align the fbsize to pagesize.
+    unsigned int fbSize = roundUpToPageSize(finfo.line_length * info.yres)*
+                    module->numBuffers;
+    void* vaddr = mmap(0, fbSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+    if (vaddr == MAP_FAILED) {
+        ALOGE("Error mapping the framebuffer (%s)", strerror(errno));
+        close(fd);
+        return -errno;
+    }
+    //store the framebuffer fd in the ctx
+    ctx->fbFd = fd;
+#ifdef MSMFB_METADATA_GET
+    memset(&metadata, 0 , sizeof(metadata));
+    metadata.op = metadata_op_get_ion_fd;
+    // get the ION fd for the framebuffer, as GPU needs ION fd
+    if (ioctl(fd, MSMFB_METADATA_GET, &metadata) == -1) {
+        ALOGE("Error getting ION fd (%s)", strerror(errno));
+        close(fd);
+        return -errno;
+    }
+    if(metadata.data.fbmem_ionfd < 0) {
+        ALOGE("Error: Ioctl returned invalid ION fd = %d",
+                                        metadata.data.fbmem_ionfd);
+        close(fd);
+        return -errno;
+    }
+    fd = metadata.data.fbmem_ionfd;
+#endif
+    // Create framebuffer handle using the ION fd
+    module->framebuffer = new private_handle_t(fd, fbSize,
+                                        private_handle_t::PRIV_FLAGS_USES_ION,
+                                        BUFFER_TYPE_UI,
+                                        module->fbFormat, info.xres, info.yres);
+    module->framebuffer->base = uint64_t(vaddr);
+    memset(vaddr, 0, fbSize);
+    //Enable vsync
+    int enable = 1;
+    ioctl(ctx->fbFd, MSMFB_OVERLAY_VSYNC_CTRL, &enable);
+    return 0;
+}
+
+static int mapFrameBuffer(framebuffer_device_t *dev)
+{
+    int err = -1;
+    char property[PROPERTY_VALUE_MAX];
+    if((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
+       (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
+        (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
+        private_module_t* module =
+            reinterpret_cast<private_module_t*>(dev->common.module);
+        pthread_mutex_lock(&module->lock);
+        err = mapFrameBufferLocked(dev);
+        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 (ctx) {
+#ifdef MSMFB_METADATA_GET
+        if(ctx->fbFd >=0) {
+            close(ctx->fbFd);
+        }
+#endif
+        //Hack until fbdev is removed. Framework could close this causing hwc a
+        //pain.
+        //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));
+        if(dev == NULL) {
+            gralloc_close(gralloc_device);
+            return status;
+        }
+        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;
+
+        status = mapFrameBuffer((framebuffer_device_t*)dev);
+        private_module_t* m = (private_module_t*)dev->device.common.module;
+        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) =
+                                                        PRIV_MIN_SWAP_INTERVAL;
+            const_cast<int&>(dev->device.maxSwapInterval) =
+                                                        PRIV_MAX_SWAP_INTERVAL;
+            const_cast<int&>(dev->device.numFramebuffers) = m->numBuffers;
+            dev->device.setUpdateRect = 0;
+
+            *device = &dev->device.common;
+        }
+
+        // Close the gralloc module
+        gralloc_close(gralloc_device);
+    }
+    return status;
+}
diff --git a/msmcobalt/libgralloc/gpu.cpp b/msmcobalt/libgralloc/gpu.cpp
new file mode 100644
index 0000000..c62cec0
--- /dev/null
+++ b/msmcobalt/libgralloc/gpu.cpp
@@ -0,0 +1,415 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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 "gr.h"
+#include "gpu.h"
+#include "memalloc.h"
+#include "alloc_controller.h"
+#include <qdMetaData.h>
+#include <linux/msm_ion.h>
+
+using namespace gralloc;
+
+gpu_context_t::gpu_context_t(const private_module_t* module,
+                             IAllocController* alloc_ctrl ) :
+    mAllocCtrl(alloc_ctrl)
+{
+    // Zero out the alloc_device_t
+    memset(static_cast<alloc_device_t*>(this), 0, sizeof(alloc_device_t));
+
+    // 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;
+    free           = gralloc_free;
+
+}
+
+int gpu_context_t::gralloc_alloc_buffer(unsigned int 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;
+    if(format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED)
+        data.align = 8192;
+    else
+        data.align = getpagesize();
+
+    if (usage & GRALLOC_USAGE_PROTECTED) {
+            if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
+                /* The alignment here reflects qsee mmu V7L/V8L requirement */
+                data.align = SZ_2M;
+            } else {
+                data.align = SECURE_ALIGN;
+            }
+        size = ALIGN(size, data.align);
+    }
+
+    data.size = size;
+    data.pHandle = (uintptr_t) pHandle;
+    err = mAllocCtrl->allocate(data, usage);
+
+    if (!err) {
+        /* allocate memory for enhancement data */
+        alloc_data eData;
+        eData.fd = -1;
+        eData.base = 0;
+        eData.offset = 0;
+        eData.size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
+        eData.pHandle = data.pHandle;
+        eData.align = getpagesize();
+        int eDataUsage = 0;
+        int eDataErr = mAllocCtrl->allocate(eData, eDataUsage);
+        ALOGE_IF(eDataErr, "gralloc failed for eDataErr=%s",
+                                          strerror(-eDataErr));
+
+        if (usage & GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY) {
+            flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY;
+        }
+
+        if (usage & GRALLOC_USAGE_PRIVATE_INTERNAL_ONLY) {
+            flags |= private_handle_t::PRIV_FLAGS_INTERNAL_ONLY;
+        }
+
+        if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER ) {
+            flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
+        }
+
+        if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
+            flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
+        }
+
+        if (usage & GRALLOC_USAGE_HW_CAMERA_READ) {
+            flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
+        }
+
+        if (usage & GRALLOC_USAGE_HW_COMPOSER) {
+            flags |= private_handle_t::PRIV_FLAGS_HW_COMPOSER;
+        }
+
+        if (usage & GRALLOC_USAGE_HW_TEXTURE) {
+            flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
+        }
+
+        if(usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
+            flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
+        }
+
+        if(isMacroTileEnabled(format, usage)) {
+            flags |= private_handle_t::PRIV_FLAGS_TILE_RENDERED;
+        }
+
+        if (isUBwcEnabled(format, usage)) {
+            flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+        }
+
+        if(usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
+            flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
+        }
+
+        if (usage & (GRALLOC_USAGE_HW_VIDEO_ENCODER |
+                GRALLOC_USAGE_HW_CAMERA_WRITE |
+                GRALLOC_USAGE_HW_RENDER |
+                GRALLOC_USAGE_HW_FB)) {
+            flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
+        }
+
+        if(usage & GRALLOC_USAGE_HW_COMPOSER) {
+            flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER;
+        }
+
+        if(false == data.uncached) {
+            flags |= private_handle_t::PRIV_FLAGS_CACHED;
+        }
+
+        flags |= data.allocType;
+        uint64_t eBaseAddr = (uint64_t)(eData.base) + eData.offset;
+        private_handle_t *hnd = new private_handle_t(data.fd, size, flags,
+                bufferType, format, width, height, eData.fd, eData.offset,
+                eBaseAddr);
+
+        hnd->offset = data.offset;
+        hnd->base = (uint64_t)(data.base) + data.offset;
+        hnd->gpuaddr = 0;
+        ColorSpace_t colorSpace = ITU_R_601_FR;
+        setMetaData(hnd, UPDATE_COLOR_SPACE, (void*) &colorSpace);
+
+        *pHandle = hnd;
+    }
+
+    ALOGE_IF(err, "gralloc failed err=%s", strerror(-err));
+
+    return err;
+}
+
+void gpu_context_t::getGrallocInformationFromFormat(int inputFormat,
+                                                    int *bufferType)
+{
+    *bufferType = BUFFER_TYPE_VIDEO;
+
+    if (isUncompressedRgbFormat(inputFormat) == TRUE) {
+        // RGB formats
+        *bufferType = BUFFER_TYPE_UI;
+    }
+}
+
+int gpu_context_t::gralloc_alloc_framebuffer_locked(int usage,
+                                                    buffer_handle_t* pHandle)
+{
+    private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
+
+    // This allocation will only happen when gralloc is in fb mode
+
+    if (m->framebuffer == NULL) {
+        ALOGE("%s: Invalid framebuffer", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    const unsigned int bufferMask = m->bufferMask;
+    const uint32_t numBuffers = m->numBuffers;
+    unsigned int 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" handle for it
+    uint64_t vaddr = uint64_t(m->framebuffer->base);
+    // As GPU needs ION FD, the private handle is created
+    // using ION fd and ION flags are set
+    private_handle_t* hnd = new private_handle_t(
+        dup(m->framebuffer->fd), bufferSize,
+        private_handle_t::PRIV_FLAGS_USES_ION |
+        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 |= (uint32_t)(1LU<<i);
+            break;
+        }
+        vaddr += bufferSize;
+    }
+    hnd->base = vaddr;
+    hnd->offset = (unsigned int)(vaddr - m->framebuffer->base);
+    *pHandle = hnd;
+    return 0;
+}
+
+
+int gpu_context_t::gralloc_alloc_framebuffer(int usage,
+                                             buffer_handle_t* pHandle)
+{
+    private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
+    pthread_mutex_lock(&m->lock);
+    int err = gralloc_alloc_framebuffer_locked(usage, pHandle);
+    pthread_mutex_unlock(&m->lock);
+    return err;
+}
+
+int gpu_context_t::alloc_impl(int w, int h, int format, int usage,
+                              buffer_handle_t* pHandle, int* pStride,
+                              unsigned int bufferSize) {
+    if (!pHandle || !pStride)
+        return -EINVAL;
+
+    unsigned int size;
+    int alignedw, alignedh;
+    int grallocFormat = format;
+    int bufferType;
+
+    //If input format is HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED then based on
+    //the usage bits, gralloc assigns a format.
+    if(format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
+       format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+        if (usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC)
+            grallocFormat = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
+        else if(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
+            if(MDPCapabilityInfo::getInstance().isWBUBWCSupportedByMDP() &&
+               usage & GRALLOC_USAGE_HW_COMPOSER)
+              grallocFormat = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
+            else
+              grallocFormat = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; //NV12
+        } else if((usage & GRALLOC_USAGE_HW_CAMERA_MASK)
+                == GRALLOC_USAGE_HW_CAMERA_ZSL)
+            grallocFormat = HAL_PIXEL_FORMAT_NV21_ZSL; //NV21 ZSL
+        else if(usage & GRALLOC_USAGE_HW_CAMERA_READ)
+            grallocFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP; //NV21
+        else if(usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
+           if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+               grallocFormat = HAL_PIXEL_FORMAT_NV21_ZSL; //NV21
+           } else {
+               grallocFormat = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS; //NV12 preview
+           }
+        } else if(usage & GRALLOC_USAGE_HW_COMPOSER)
+            //XXX: If we still haven't set a format, default to RGBA8888
+            grallocFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+        else if(format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+            //If no other usage flags are detected, default the
+            //flexible YUV format to NV21_ZSL
+            grallocFormat = HAL_PIXEL_FORMAT_NV21_ZSL;
+        }
+    }
+
+    bool useFbMem = false;
+    char property[PROPERTY_VALUE_MAX];
+    char isUBWC[PROPERTY_VALUE_MAX];
+    if (usage & GRALLOC_USAGE_HW_FB) {
+        if ((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
+            (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
+            (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
+            useFbMem = true;
+        } else {
+            usage &= ~GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
+            if (property_get("debug.gralloc.enable_fb_ubwc", isUBWC, NULL) > 0){
+                if ((!strncmp(isUBWC, "1", PROPERTY_VALUE_MAX)) ||
+                    (!strncasecmp(isUBWC, "true", PROPERTY_VALUE_MAX))) {
+                    // Allocate UBWC aligned framebuffer
+                    usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
+                }
+            }
+        }
+    }
+
+    getGrallocInformationFromFormat(grallocFormat, &bufferType);
+    size = getBufferSizeAndDimensions(w, h, grallocFormat, usage, alignedw,
+                   alignedh);
+
+    if ((unsigned int)size <= 0)
+        return -EINVAL;
+    size = (bufferSize >= size)? bufferSize : size;
+
+    int err = 0;
+    if(useFbMem) {
+        err = gralloc_alloc_framebuffer(usage, pHandle);
+    } else {
+        err = gralloc_alloc_buffer(size, usage, pHandle, bufferType,
+                                   grallocFormat, alignedw, alignedh);
+    }
+
+    if (err < 0) {
+        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) {
+        const unsigned int bufferSize = m->finfo.line_length * m->info.yres;
+        unsigned int index = (unsigned int) ((hnd->base - m->framebuffer->base)
+                / bufferSize);
+        m->bufferMask &= (uint32_t)~(1LU<<index);
+    } else {
+
+        terminateBuffer(&m->base, const_cast<private_handle_t*>(hnd));
+        IMemAlloc* memalloc = mAllocCtrl->getAllocator(hnd->flags);
+        int err = memalloc->free_buffer((void*)hnd->base, hnd->size,
+                                        hnd->offset, hnd->fd);
+        if(err)
+            return err;
+        // free the metadata space
+        unsigned int size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
+        err = memalloc->free_buffer((void*)hnd->base_metadata,
+                                    size, hnd->offset_metadata,
+                                    hnd->fd_metadata);
+        if (err)
+            return err;
+    }
+    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/msmcobalt/libgralloc/gpu.h b/msmcobalt/libgralloc/gpu.h
new file mode 100644
index 0000000..2248d30
--- /dev/null
+++ b/msmcobalt/libgralloc/gpu.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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 "gralloc_priv.h"
+#include "fb_priv.h"
+
+namespace gralloc {
+class IAllocController;
+class gpu_context_t : public alloc_device_t {
+    public:
+    gpu_context_t(const private_module_t* module,
+                  IAllocController* alloc_ctrl);
+
+    int gralloc_alloc_buffer(unsigned int 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,
+                   unsigned int bufferSize = 0);
+
+    static int gralloc_alloc(alloc_device_t* dev, int w, int h,
+                             int format, int usage,
+                             buffer_handle_t* pHandle,
+                             int* pStride);
+    int gralloc_alloc_framebuffer_locked(int usage,
+                                         buffer_handle_t* pHandle);
+
+    int gralloc_alloc_framebuffer(int usage,
+                                  buffer_handle_t* pHandle);
+
+    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);
+
+    private:
+   IAllocController* mAllocCtrl;
+    void getGrallocInformationFromFormat(int inputFormat,
+                                         int *bufferType);
+};
+}
+#endif  // GRALLOC_GPU_H
diff --git a/msmcobalt/libgralloc/gr.h b/msmcobalt/libgralloc/gr.h
new file mode 100644
index 0000000..578240a
--- /dev/null
+++ b/msmcobalt/libgralloc/gr.h
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2011 - 2016, The Linux Foundation. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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>
+#include <limits.h>
+#include <sys/cdefs.h>
+#include <hardware/gralloc.h>
+#include <pthread.h>
+#include <errno.h>
+
+#include <cutils/native_handle.h>
+#include <utils/Singleton.h>
+#include "adreno_utils.h"
+
+/*****************************************************************************/
+
+struct private_module_t;
+struct private_handle_t;
+
+inline unsigned int roundUpToPageSize(unsigned int x) {
+    return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
+}
+
+template <class Type>
+inline Type ALIGN(Type x, Type 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);
+unsigned int getBufferSizeAndDimensions(int width, int height, int format,
+        int usage, int& alignedw, int &alignedh);
+unsigned int getBufferSizeAndDimensions(int width, int height, int format,
+        int& alignedw, int &alignedh);
+
+
+// Attributes include aligned width, aligned height, tileEnabled and size of the buffer
+void getBufferAttributes(int width, int height, int format, int usage,
+                           int& alignedw, int &alignedh,
+                           int& tileEnabled, unsigned int &size);
+
+
+bool isMacroTileEnabled(int format, int usage);
+
+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);
+int getYUVPlaneInfo(private_handle_t* pHnd, struct android_ycbcr* ycbcr);
+int getRgbDataAddress(private_handle_t* pHnd, void** rgb_data);
+
+// To query if UBWC is enabled, based on format and usage flags
+bool isUBwcEnabled(int format, int usage);
+
+// Function to check if the format is an RGB format
+bool isUncompressedRgbFormat(int format);
+
+/*****************************************************************************/
+
+class Locker {
+    pthread_mutex_t mutex;
+    pthread_cond_t cond;
+    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);
+        pthread_cond_init(&cond, 0);
+    }
+    inline ~Locker()       {
+        pthread_mutex_destroy(&mutex);
+        pthread_cond_destroy(&cond);
+    }
+    inline void lock()     { pthread_mutex_lock(&mutex); }
+    inline void wait()     { pthread_cond_wait(&cond, &mutex); }
+    inline void unlock()   { pthread_mutex_unlock(&mutex); }
+    inline void signal()   { pthread_cond_signal(&cond); }
+};
+
+
+class AdrenoMemInfo : public android::Singleton <AdrenoMemInfo>
+{
+    public:
+    AdrenoMemInfo();
+
+    ~AdrenoMemInfo();
+
+    /*
+     * Function to compute aligned width and aligned height based on
+     * width, height, format and usage flags.
+     *
+     * @return aligned width, aligned height
+     */
+    void getAlignedWidthAndHeight(int width, int height, int format,
+                            int usage, int& aligned_w, int& aligned_h);
+
+    /*
+     * Function to compute aligned width and aligned height based on
+     * private handle
+     *
+     * @return aligned width, aligned height
+     */
+    void getAlignedWidthAndHeight(const private_handle_t *hnd, int& aligned_w, int& aligned_h);
+
+    /*
+     * Function to compute the adreno aligned width and aligned height
+     * based on the width and format.
+     *
+     * @return aligned width, aligned height
+     */
+    void getGpuAlignedWidthHeight(int width, int height, int format,
+                            int tileEnabled, int& alignedw, int &alignedh);
+
+    /*
+     * Function to return whether GPU support MacroTile feature
+     *
+     * @return >0 : supported
+     *          0 : not supported
+     */
+    int isMacroTilingSupportedByGPU();
+
+    /*
+     * Function to query whether GPU supports UBWC for given HAL format
+     * @return > 0 : supported
+     *           0 : not supported
+     */
+    int isUBWCSupportedByGPU(int format);
+
+    /*
+     * Function to get the corresponding Adreno format for given HAL format
+     */
+    ADRENOPIXELFORMAT getGpuPixelFormat(int hal_format);
+
+    private:
+        // Overriding flag to disable UBWC alloc for graphics stack
+        int  gfx_ubwc_disable;
+        // Pointer to the padding library.
+        void *libadreno_utils;
+
+        // link(s)to adreno surface padding library.
+        int (*LINK_adreno_compute_padding) (int width, int bpp,
+                                                int surface_tile_height,
+                                                int screen_tile_height,
+                                                int padding_threshold);
+
+        void (*LINK_adreno_compute_aligned_width_and_height) (int width,
+                                                int height,
+                                                int bpp,
+                                                int tile_mode,
+                                                int raster_mode,
+                                                int padding_threshold,
+                                                int *aligned_w,
+                                                int *aligned_h);
+
+        int (*LINK_adreno_isMacroTilingSupportedByGpu) (void);
+
+        void(*LINK_adreno_compute_compressedfmt_aligned_width_and_height)(
+                                                int width,
+                                                int height,
+                                                int format,
+                                                int tile_mode,
+                                                int raster_mode,
+                                                int padding_threshold,
+                                                int *aligned_w,
+                                                int *aligned_h,
+                                                int *bpp);
+
+        int (*LINK_adreno_isUBWCSupportedByGpu) (ADRENOPIXELFORMAT format);
+
+        unsigned int (*LINK_adreno_get_gpu_pixel_alignment) ();
+};
+
+
+class MDPCapabilityInfo : public android::Singleton <MDPCapabilityInfo>
+{
+    int isMacroTileSupported = 0;
+    int isUBwcSupported = 0;
+    int isWBUBWCSupported = 0;
+
+    public:
+        MDPCapabilityInfo();
+        /*
+        * Function to return whether MDP support MacroTile feature
+        *
+        * @return  1 : supported
+        *          0 : not supported
+        */
+        int isMacroTilingSupportedByMDP() { return isMacroTileSupported; }
+        /*
+        * Function to return whether MDP supports UBWC feature
+        *
+        * @return  1 : supported
+        *          0 : not supported
+        */
+        int isUBwcSupportedByMDP() { return isUBwcSupported; }
+        /*
+        * Function to return whether MDP WB block outputs UBWC format
+        *
+        * @return  1 : supported
+        *          0 : not supported
+        */
+        int isWBUBWCSupportedByMDP() { return isWBUBWCSupported; }
+};
+
+#endif /* GR_H_ */
diff --git a/msmcobalt/libgralloc/gralloc.cpp b/msmcobalt/libgralloc/gralloc.cpp
new file mode 100644
index 0000000..237b8a8
--- /dev/null
+++ b/msmcobalt/libgralloc/gralloc.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2008, The Android Open Source Project
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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 "gr.h"
+#include "gpu.h"
+#include "memalloc.h"
+#include "alloc_controller.h"
+
+using namespace gralloc;
+
+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_lock_ycbcr(gralloc_module_t const* module,
+                        buffer_handle_t handle, int usage,
+                        int l, int t, int w, int h,
+                        struct android_ycbcr *ycbcr);
+
+extern int gralloc_unlock(gralloc_module_t const* module,
+                          buffer_handle_t handle);
+
+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,
+        .lock_ycbcr = gralloc_lock_ycbcr,
+    },
+    .framebuffer = 0,
+    .fbFormat = 0,
+    .flags = 0,
+    .numBuffers = 0,
+    .bufferMask = 0,
+    .lock = PTHREAD_MUTEX_INITIALIZER,
+};
+
+// 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;
+        IAllocController* alloc_ctrl = IAllocController::getInstance();
+        dev = new gpu_context_t(m, alloc_ctrl);
+        if(!dev)
+            return status;
+
+        *device = &dev->common;
+        status = 0;
+    } else {
+        status = fb_device_open(module, name, device);
+    }
+    return status;
+}
diff --git a/msmcobalt/libgralloc/gralloc_priv.h b/msmcobalt/libgralloc/gralloc_priv.h
new file mode 100644
index 0000000..613c066
--- /dev/null
+++ b/msmcobalt/libgralloc/gralloc_priv.h
@@ -0,0 +1,304 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2011 - 2016, The Linux Foundation. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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 <cutils/log.h>
+
+#define ROUND_UP_PAGESIZE(x) ( (((unsigned long)(x)) + PAGE_SIZE-1)  & \
+                               (~(PAGE_SIZE-1)) )
+
+/* Gralloc usage bits indicating the type of allocation that should be used */
+/* SYSTEM heap comes from kernel vmalloc (ION_SYSTEM_HEAP_ID)
+ * is cached by default and
+ * is not secured */
+
+/* GRALLOC_USAGE_PRIVATE_0 is unused */
+
+/* Non linear, Universal Bandwidth Compression */
+#define GRALLOC_USAGE_PRIVATE_ALLOC_UBWC      GRALLOC_USAGE_PRIVATE_1
+
+/* IOMMU heap comes from manually allocated pages, can be cached/uncached,
+ * is not secured */
+#define GRALLOC_USAGE_PRIVATE_IOMMU_HEAP      GRALLOC_USAGE_PRIVATE_2
+
+/* MM heap is a carveout heap for video, can be secured */
+#define GRALLOC_USAGE_PRIVATE_MM_HEAP         GRALLOC_USAGE_PRIVATE_3
+
+/* ADSP heap is a carveout heap, is not secured */
+#define GRALLOC_USAGE_PRIVATE_ADSP_HEAP       0x01000000
+
+/* Set this for allocating uncached memory (using O_DSYNC),
+ * cannot be used with noncontiguous heaps */
+#define GRALLOC_USAGE_PRIVATE_UNCACHED        0x02000000
+
+/* Buffer content should be displayed on an primary display only */
+#define GRALLOC_USAGE_PRIVATE_INTERNAL_ONLY   0x04000000
+
+/* Buffer content should be displayed on an external display only */
+#define GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY   0x08000000
+
+/* This flag is set for WFD usecase */
+#define GRALLOC_USAGE_PRIVATE_WFD             0x00200000
+
+/* CAMERA heap is a carveout heap for camera, is not secured */
+#define GRALLOC_USAGE_PRIVATE_CAMERA_HEAP     0x00400000
+
+/* This flag is used for SECURE display usecase */
+#define GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY  0x00800000
+
+/* define Gralloc perform */
+#define GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER 1
+// This will be used by the graphics drivers to know if certain features
+// are defined in this display HAL.
+// Ex: Newer GFX libraries + Older Display HAL
+#define GRALLOC_MODULE_PERFORM_GET_STRIDE 2
+#define GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE 3
+#define GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE 4
+#define GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES 5
+#define GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE 6
+#define GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO 7
+#define GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO 8
+#define GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG 9
+#define GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS 10
+#define GRALLOC_MODULE_PERFORM_GET_IGC 11
+#define GRALLOC_MODULE_PERFORM_SET_IGC 12
+#define GRALLOC_MODULE_PERFORM_SET_SINGLE_BUFFER_MODE 13
+
+/* OEM specific HAL formats */
+
+#define HAL_PIXEL_FORMAT_RGBA_5551               6
+#define HAL_PIXEL_FORMAT_RGBA_4444               7
+#define HAL_PIXEL_FORMAT_NV12_ENCODEABLE         0x102
+#define HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS      0x7FA30C04
+#define HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED      0x7FA30C03
+#define HAL_PIXEL_FORMAT_YCbCr_420_SP            0x109
+#define HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO     0x7FA30C01
+#define HAL_PIXEL_FORMAT_YCrCb_422_SP            0x10B
+#define HAL_PIXEL_FORMAT_R_8                     0x10D
+#define HAL_PIXEL_FORMAT_RG_88                   0x10E
+#define HAL_PIXEL_FORMAT_YCbCr_444_SP            0x10F
+#define HAL_PIXEL_FORMAT_YCrCb_444_SP            0x110
+#define HAL_PIXEL_FORMAT_YCrCb_422_I             0x111
+#define HAL_PIXEL_FORMAT_BGRX_8888               0x112
+#define HAL_PIXEL_FORMAT_NV21_ZSL                0x113
+#define HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS      0x114
+#define HAL_PIXEL_FORMAT_BGR_565                 0x115
+#define HAL_PIXEL_FORMAT_RGBA_1010102            0x116
+#define HAL_PIXEL_FORMAT_ARGB_2101010            0x117
+#define HAL_PIXEL_FORMAT_RGBX_1010102            0x118
+#define HAL_PIXEL_FORMAT_XRGB_2101010            0x119
+#define HAL_PIXEL_FORMAT_BGRA_1010102            0x11A
+#define HAL_PIXEL_FORMAT_ABGR_2101010            0x11B
+#define HAL_PIXEL_FORMAT_BGRX_1010102            0x11C
+#define HAL_PIXEL_FORMAT_XBGR_2101010            0x11D
+#define HAL_PIXEL_FORMAT_YCbCr_420_P010          0x11F
+#define HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC     0x120
+
+#define HAL_PIXEL_FORMAT_INTERLACE               0x180
+
+//v4l2_fourcc('Y', 'U', 'Y', 'L'). 24 bpp YUYV 4:2:2 10 bit per component
+#define HAL_PIXEL_FORMAT_YCbCr_422_I_10BIT       0x4C595559
+
+//v4l2_fourcc('Y', 'B', 'W', 'C'). 10 bit per component. This compressed
+//format reduces the memory access bandwidth
+#define HAL_PIXEL_FORMAT_YCbCr_422_I_10BIT_COMPRESSED  0x43574259
+
+// UBWC aligned Venus format
+#define HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC 0x7FA30C06
+
+//Khronos ASTC formats
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR             0x93B0
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR             0x93B1
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR             0x93B2
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR             0x93B3
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR             0x93B4
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR             0x93B5
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR             0x93B6
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR             0x93B7
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR            0x93B8
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR            0x93B9
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR            0x93BA
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR           0x93BB
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR           0x93BC
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR           0x93BD
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR     0x93D0
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR     0x93D1
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR     0x93D2
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR     0x93D3
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR     0x93D4
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR     0x93D5
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR     0x93D6
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR     0x93D7
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR    0x93D8
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR    0x93D9
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR    0x93DA
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR   0x93DB
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR   0x93DC
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR   0x93DD
+
+/* possible values for inverse gamma correction */
+#define HAL_IGC_NOT_SPECIFIED     0
+#define HAL_IGC_s_RGB             1
+
+/* possible formats for 3D content*/
+enum {
+    HAL_NO_3D                      = 0x0,
+    HAL_3D_SIDE_BY_SIDE_L_R        = 0x1,
+    HAL_3D_SIDE_BY_SIDE_R_L        = 0x2,
+    HAL_3D_TOP_BOTTOM              = 0x4,
+    HAL_3D_IN_SIDE_BY_SIDE_L_R     = 0x10000, //unused legacy format
+};
+
+enum {
+    BUFFER_TYPE_UI = 0,
+    BUFFER_TYPE_VIDEO
+};
+
+#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_ION           = 0x00000008,
+            PRIV_FLAGS_USES_ASHMEM        = 0x00000010,
+            PRIV_FLAGS_NEEDS_FLUSH        = 0x00000020,
+            PRIV_FLAGS_INTERNAL_ONLY      = 0x00000040,
+            PRIV_FLAGS_NON_CPU_WRITER     = 0x00000080,
+            PRIV_FLAGS_NONCONTIGUOUS_MEM  = 0x00000100,
+            PRIV_FLAGS_CACHED             = 0x00000200,
+            PRIV_FLAGS_SECURE_BUFFER      = 0x00000400,
+            // Display on external only
+            PRIV_FLAGS_EXTERNAL_ONLY      = 0x00002000,
+            // Set by HWC for protected non secure buffers
+            PRIV_FLAGS_PROTECTED_BUFFER   = 0x00004000,
+            PRIV_FLAGS_VIDEO_ENCODER      = 0x00010000,
+            PRIV_FLAGS_CAMERA_WRITE       = 0x00020000,
+            PRIV_FLAGS_CAMERA_READ        = 0x00040000,
+            PRIV_FLAGS_HW_COMPOSER        = 0x00080000,
+            PRIV_FLAGS_HW_TEXTURE         = 0x00100000,
+            PRIV_FLAGS_ITU_R_601          = 0x00200000, //Unused from display
+            PRIV_FLAGS_ITU_R_601_FR       = 0x00400000, //Unused from display
+            PRIV_FLAGS_ITU_R_709          = 0x00800000, //Unused from display
+            PRIV_FLAGS_SECURE_DISPLAY     = 0x01000000,
+            // Buffer is rendered in Tile Format
+            PRIV_FLAGS_TILE_RENDERED      = 0x02000000,
+            // Buffer rendered using CPU/SW renderer
+            PRIV_FLAGS_CPU_RENDERED       = 0x04000000,
+            // Buffer is allocated with UBWC alignment
+            PRIV_FLAGS_UBWC_ALIGNED       = 0x08000000,
+            // Buffer allocated will be consumed by SF/HWC
+            PRIV_FLAGS_DISP_CONSUMER      = 0x10000000
+        };
+
+        // file-descriptors
+        int     fd;
+        int     fd_metadata;          // fd for the meta-data
+        // ints
+        int     magic;
+        int     flags;
+        unsigned int  size;
+        unsigned int  offset;
+        int     bufferType;
+        uint64_t base __attribute__((aligned(8)));
+        unsigned int  offset_metadata;
+        // The gpu address mapped into the mmu.
+        uint64_t gpuaddr __attribute__((aligned(8)));
+        int     format;
+        int     width;
+        int     height;
+        uint64_t base_metadata __attribute__((aligned(8)));
+
+#ifdef __cplusplus
+        static const int sNumFds = 2;
+        static inline int sNumInts() {
+            return ((sizeof(private_handle_t) - sizeof(native_handle_t)) /
+                    sizeof(int)) - sNumFds;
+        }
+        static const int sMagic = 'gmsm';
+
+        private_handle_t(int fd, unsigned int size, int flags, int bufferType,
+                         int format, int width, int height, int eFd = -1,
+                         unsigned int eOffset = 0, uint64_t eBase = 0) :
+            fd(fd), fd_metadata(eFd), magic(sMagic),
+            flags(flags), size(size), offset(0), bufferType(bufferType),
+            base(0), offset_metadata(eOffset), gpuaddr(0),
+            format(format), width(width), height(height),
+            base_metadata(eBase)
+        {
+            version = (int) sizeof(native_handle);
+            numInts = sNumInts();
+            numFds = sNumFds;
+        }
+        ~private_handle_t() {
+            magic = 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)
+            {
+                ALOGD("Invalid gralloc handle (at %p): "
+                      "ver(%d/%zu) ints(%d/%d) fds(%d/%d)"
+                      "magic(%c%c%c%c/%c%c%c%c)",
+                      h,
+                      h ? h->version : -1, sizeof(native_handle),
+                      h ? h->numInts : -1, sNumInts(),
+                      h ? h->numFds : -1, sNumFds,
+                      hnd ? (((hnd->magic >> 24) & 0xFF)?
+                             ((hnd->magic >> 24) & 0xFF) : '-') : '?',
+                      hnd ? (((hnd->magic >> 16) & 0xFF)?
+                             ((hnd->magic >> 16) & 0xFF) : '-') : '?',
+                      hnd ? (((hnd->magic >> 8) & 0xFF)?
+                             ((hnd->magic >> 8) & 0xFF) : '-') : '?',
+                      hnd ? (((hnd->magic >> 0) & 0xFF)?
+                             ((hnd->magic >> 0) & 0xFF) : '-') : '?',
+                      (sMagic >> 24) & 0xFF,
+                      (sMagic >> 16) & 0xFF,
+                      (sMagic >> 8) & 0xFF,
+                      (sMagic >> 0) & 0xFF);
+                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/msmcobalt/libgralloc/ionalloc.cpp b/msmcobalt/libgralloc/ionalloc.cpp
new file mode 100644
index 0000000..96e0e3e
--- /dev/null
+++ b/msmcobalt/libgralloc/ionalloc.cpp
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define DEBUG 0
+#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <cutils/log.h>
+#include <errno.h>
+#include <utils/Trace.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)
+{
+    ATRACE_CALL();
+    Locker::Autolock _l(mLock);
+    int err = 0;
+    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.heap_id_mask = data.heapId;
+    ionAllocData.flags = data.flags;
+    ionAllocData.flags |= data.uncached ? 0 : ION_FLAG_CACHED;
+    err = open_device();
+    if (err)
+        return err;
+    if(ioctl(mIonFd, ION_IOC_ALLOC, &ionAllocData)) {
+        err = -errno;
+        ALOGE("ION_IOC_ALLOC failed with error - %s", strerror(errno));
+        return err;
+    }
+
+    fd_data.handle = ionAllocData.handle;
+    handle_data.handle = ionAllocData.handle;
+    if(ioctl(mIonFd, 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);
+        return err;
+    }
+
+    if(!(data.flags & ION_SECURE)) {
+        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);
+            return err;
+        }
+    }
+
+    data.base = base;
+    data.fd = fd_data.fd;
+    ioctl(mIonFd, ION_IOC_FREE, &handle_data);
+    ALOGD_IF(DEBUG, "ion: Allocated buffer base:%p size:%zu fd:%d",
+          data.base, ionAllocData.len, data.fd);
+    return 0;
+}
+
+
+int IonAlloc::free_buffer(void* base, unsigned int size, unsigned int offset,
+        int fd)
+{
+    ATRACE_CALL();
+    Locker::Autolock _l(mLock);
+    ALOGD_IF(DEBUG, "ion: Freeing buffer base:%p size:%u 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, unsigned int size, unsigned int offset,
+        int fd)
+{
+    ATRACE_CALL();
+    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;
+        ALOGE("ion: Failed to map memory in the client: %s",
+              strerror(errno));
+    } else {
+        ALOGD_IF(DEBUG, "ion: Mapped buffer base:%p size:%u offset:%u fd:%d",
+              base, size, offset, fd);
+    }
+    return err;
+}
+
+int IonAlloc::unmap_buffer(void *base, unsigned int size,
+        unsigned int /*offset*/)
+{
+    ATRACE_CALL();
+    ALOGD_IF(DEBUG, "ion: Unmapping buffer  base:%p size:%u", 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, unsigned int size, unsigned int offset,
+        int fd, int op)
+{
+    ATRACE_CALL();
+    ATRACE_INT("operation id", op);
+    struct ion_flush_data flush_data;
+    struct ion_fd_data fd_data;
+    struct ion_handle_data handle_data;
+    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;
+    // offset and length are unsigned int
+    flush_data.offset  = offset;
+    flush_data.length  = size;
+
+    struct ion_custom_data d;
+    switch(op) {
+    case CACHE_CLEAN:
+        d.cmd = ION_IOC_CLEAN_CACHES;
+        break;
+    case CACHE_INVALIDATE:
+            d.cmd = ION_IOC_INV_CACHES;
+        break;
+    case CACHE_CLEAN_AND_INVALIDATE:
+    default:
+        d.cmd = ION_IOC_CLEAN_INV_CACHES;
+    }
+
+    d.arg = (unsigned long int)&flush_data;
+
+    if(ioctl(mIonFd, ION_IOC_CUSTOM, &d)) {
+        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/msmcobalt/libgralloc/ionalloc.h b/msmcobalt/libgralloc/ionalloc.h
new file mode 100644
index 0000000..635bda5
--- /dev/null
+++ b/msmcobalt/libgralloc/ionalloc.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GRALLOC_IONALLOC_H
+#define GRALLOC_IONALLOC_H
+
+#include <linux/msm_ion.h>
+#include "memalloc.h"
+#include "gr.h"
+
+namespace gralloc {
+
+class IonAlloc : public IMemAlloc  {
+
+    public:
+    virtual int alloc_buffer(alloc_data& data);
+
+    virtual int free_buffer(void *base, unsigned int size,
+                            unsigned int offset, int fd);
+
+    virtual int map_buffer(void **pBase, unsigned int size,
+                           unsigned int offset, int fd);
+
+    virtual int unmap_buffer(void *base, unsigned int size,
+                             unsigned int offset);
+
+    virtual int clean_buffer(void*base, unsigned int size,
+                             unsigned int offset, int fd, int op);
+
+    IonAlloc() { mIonFd = FD_INIT; }
+
+    ~IonAlloc() { close_device(); }
+
+    private:
+    int mIonFd;
+
+    int open_device();
+
+    void close_device();
+
+    mutable Locker mLock;
+
+};
+
+}
+
+#endif /* GRALLOC_IONALLOC_H */
+
diff --git a/msmcobalt/libgralloc/mapper.cpp b/msmcobalt/libgralloc/mapper.cpp
new file mode 100644
index 0000000..24a0aa1
--- /dev/null
+++ b/msmcobalt/libgralloc/mapper.cpp
@@ -0,0 +1,495 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.
+ */
+
+#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
+#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 <cutils/log.h>
+#include <cutils/atomic.h>
+#include <utils/Trace.h>
+
+#include <hardware/hardware.h>
+#include <hardware/gralloc.h>
+
+#include "gralloc_priv.h"
+#include "gr.h"
+#include "alloc_controller.h"
+#include "memalloc.h"
+#include <qdMetaData.h>
+
+
+using namespace gralloc;
+/*****************************************************************************/
+
+// Return the type of allocator -
+// these are used for mapping/unmapping
+static IMemAlloc* getAllocator(int flags)
+{
+    IMemAlloc* memalloc;
+    IAllocController* alloc_ctrl = IAllocController::getInstance();
+    memalloc = alloc_ctrl->getAllocator(flags);
+    return memalloc;
+}
+
+static int gralloc_map_metadata(buffer_handle_t handle) {
+    private_handle_t* hnd = (private_handle_t*)handle;
+    hnd->base_metadata = 0;
+    IMemAlloc* memalloc = getAllocator(hnd->flags) ;
+    void *mappedAddress = MAP_FAILED;
+    unsigned int size = 0;
+    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
+        mappedAddress = MAP_FAILED;
+        size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
+        int ret = memalloc->map_buffer(&mappedAddress, size,
+                                       hnd->offset_metadata, hnd->fd_metadata);
+        if(ret || mappedAddress == MAP_FAILED) {
+            ALOGE("Could not mmap metadata for handle %p, fd=%d (%s)",
+                  hnd, hnd->fd_metadata, strerror(errno));
+            return -errno;
+        }
+        hnd->base_metadata = uint64_t(mappedAddress) + hnd->offset_metadata;
+    }
+    return 0;
+}
+
+static int gralloc_map(gralloc_module_t const* module,
+                       buffer_handle_t handle)
+{
+    ATRACE_CALL();
+    if(!module)
+        return -EINVAL;
+
+    private_handle_t* hnd = (private_handle_t*)handle;
+    unsigned int size = 0;
+    int err = 0;
+    IMemAlloc* memalloc = getAllocator(hnd->flags) ;
+    void *mappedAddress = MAP_FAILED;
+    hnd->base = 0;
+
+    // Dont map framebuffer and secure buffers
+    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) &&
+        !(hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER)) {
+        size = hnd->size;
+        err = memalloc->map_buffer(&mappedAddress, size,
+                                       hnd->offset, hnd->fd);
+        if(err || mappedAddress == MAP_FAILED) {
+            ALOGE("Could not mmap handle %p, fd=%d (%s)",
+                  handle, hnd->fd, strerror(errno));
+            return -errno;
+        }
+
+        hnd->base = uint64_t(mappedAddress) + hnd->offset;
+    } else {
+        // Cannot map secure buffers or framebuffers, but still need to map
+        // metadata for secure buffers.
+        // If mapping a secure buffers fails, the framework needs to get
+        // an error code.
+        err = -EINVAL;
+    }
+
+    //Allow mapping of metadata for all buffers including secure ones, but not
+    //of framebuffer
+    int metadata_err = gralloc_map_metadata(handle);
+    if (!err) {
+        err = metadata_err;
+    }
+    return err;
+}
+
+static int gralloc_unmap(gralloc_module_t const* module,
+                         buffer_handle_t handle)
+{
+    ATRACE_CALL();
+    int err = -EINVAL;
+    if(!module)
+        return err;
+
+    private_handle_t* hnd = (private_handle_t*)handle;
+    IMemAlloc* memalloc = getAllocator(hnd->flags) ;
+    if(!memalloc)
+        return err;
+
+    if(hnd->base) {
+        err = memalloc->unmap_buffer((void*)hnd->base, hnd->size, hnd->offset);
+        if (err) {
+            ALOGE("Could not unmap memory at address %p, %s", (void*) hnd->base,
+                    strerror(errno));
+            return -errno;
+        }
+        hnd->base = 0;
+    }
+
+    if(hnd->base_metadata) {
+        unsigned int size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
+        err = memalloc->unmap_buffer((void*)hnd->base_metadata,
+                size, hnd->offset_metadata);
+        if (err) {
+            ALOGE("Could not unmap memory at address %p, %s",
+                    (void*) hnd->base_metadata, strerror(errno));
+            return -errno;
+        }
+        hnd->base_metadata = 0;
+    }
+
+    return 0;
+}
+
+/*****************************************************************************/
+
+static pthread_mutex_t sMapLock = PTHREAD_MUTEX_INITIALIZER;
+
+/*****************************************************************************/
+
+int gralloc_register_buffer(gralloc_module_t const* module,
+                            buffer_handle_t handle)
+{
+    ATRACE_CALL();
+    if (!module || private_handle_t::validate(handle) < 0)
+        return -EINVAL;
+    // The base address received via IPC is invalid in this process
+    // Reset it to 0 here since it will be mapped in lock()
+    private_handle_t* hnd = (private_handle_t*)handle;
+    hnd->base = 0;
+    return gralloc_map_metadata(handle);
+}
+
+int gralloc_unregister_buffer(gralloc_module_t const* module,
+                              buffer_handle_t handle)
+{
+    ATRACE_CALL();
+    if (!module || 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.
+     * Also base and base_metadata are reset.
+     */
+    return gralloc_unmap(module, handle);
+}
+
+int terminateBuffer(gralloc_module_t const* module,
+                    private_handle_t* hnd)
+{
+    ATRACE_CALL();
+    if(!module)
+        return -EINVAL;
+
+    /*
+     * If the buffer has been mapped during a lock operation, it's time
+     * to un-map it. It's an error to be here with a locked buffer.
+     * NOTE: the framebuffer is handled differently and is never unmapped.
+     * Also base and base_metadata are reset.
+     */
+    return gralloc_unmap(module, hnd);
+}
+
+static int gralloc_map_and_invalidate (gralloc_module_t const* module,
+                                       buffer_handle_t handle, int usage)
+{
+    ATRACE_CALL();
+    if (!module || 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);
+            pthread_mutex_unlock(lock);
+        }
+        if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION and
+                hnd->flags & private_handle_t::PRIV_FLAGS_CACHED) {
+            //Invalidate if CPU reads in software and there are non-CPU
+            //writers. No need to do this for the metadata buffer as it is
+            //only read/written in software.
+            if ((usage & GRALLOC_USAGE_SW_READ_MASK) and
+                    (hnd->flags & private_handle_t::PRIV_FLAGS_NON_CPU_WRITER))
+            {
+                IMemAlloc* memalloc = getAllocator(hnd->flags) ;
+                err = memalloc->clean_buffer((void*)hnd->base,
+                        hnd->size, hnd->offset, hnd->fd,
+                        CACHE_INVALIDATE);
+            }
+            //Mark the buffer to be flushed after CPU write.
+            if (usage & GRALLOC_USAGE_SW_WRITE_MASK) {
+                hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
+            }
+        }
+    }
+
+    return err;
+}
+
+int gralloc_lock(gralloc_module_t const* module,
+                 buffer_handle_t handle, int usage,
+                 int /*l*/, int /*t*/, int /*w*/, int /*h*/,
+                 void** vaddr)
+{
+    ATRACE_CALL();
+    private_handle_t* hnd = (private_handle_t*)handle;
+    int err = gralloc_map_and_invalidate(module, handle, usage);
+    if(!err)
+        *vaddr = (void*)hnd->base;
+    return err;
+}
+
+int gralloc_lock_ycbcr(gralloc_module_t const* module,
+                 buffer_handle_t handle, int usage,
+                 int /*l*/, int /*t*/, int /*w*/, int /*h*/,
+                 struct android_ycbcr *ycbcr)
+{
+    ATRACE_CALL();
+    private_handle_t* hnd = (private_handle_t*)handle;
+    int err = gralloc_map_and_invalidate(module, handle, usage);
+    if(!err)
+        err = getYUVPlaneInfo(hnd, ycbcr);
+    return err;
+}
+
+int gralloc_unlock(gralloc_module_t const* module,
+                   buffer_handle_t handle)
+{
+    ATRACE_CALL();
+    if (!module || private_handle_t::validate(handle) < 0)
+        return -EINVAL;
+
+    int err = 0;
+    private_handle_t* hnd = (private_handle_t*)handle;
+
+    IMemAlloc* memalloc = getAllocator(hnd->flags);
+    if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
+        err = memalloc->clean_buffer((void*)hnd->base,
+                hnd->size, hnd->offset, hnd->fd,
+                CACHE_CLEAN);
+        hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
+    }
+
+    return err;
+}
+
+/*****************************************************************************/
+
+int gralloc_perform(struct gralloc_module_t const* module,
+                    int operation, ... )
+{
+    int res = -EINVAL;
+    va_list args;
+    if(!module)
+        return res;
+
+    va_start(args, operation);
+    switch (operation) {
+        case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER:
+            {
+                int fd = va_arg(args, int);
+                unsigned int size = va_arg(args, unsigned int);
+                unsigned int offset = va_arg(args, unsigned int);
+                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**);
+                private_handle_t* hnd = (private_handle_t*)native_handle_create(
+                    private_handle_t::sNumFds, private_handle_t::sNumInts());
+                if (hnd) {
+                  hnd->magic = private_handle_t::sMagic;
+                  hnd->fd = fd;
+                  hnd->flags =  private_handle_t::PRIV_FLAGS_USES_ION;
+                  hnd->size = size;
+                  hnd->offset = offset;
+                  hnd->base = uint64_t(base) + offset;
+                  hnd->gpuaddr = 0;
+                  hnd->width = width;
+                  hnd->height = height;
+                  hnd->format = format;
+                  *handle = (native_handle_t *)hnd;
+                  res = 0;
+                }
+                break;
+
+            }
+        case GRALLOC_MODULE_PERFORM_GET_STRIDE:
+            {
+                int width   = va_arg(args, int);
+                int format  = va_arg(args, int);
+                int *stride = va_arg(args, int *);
+                int alignedw = 0, alignedh = 0;
+                AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
+                        0, format, 0, alignedw, alignedh);
+                *stride = alignedw;
+                res = 0;
+            } break;
+
+        case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE:
+            {
+                const private_handle_t* hnd =  va_arg(args, private_handle_t*);
+                int *stride = va_arg(args, int *);
+                if (private_handle_t::validate(hnd)) {
+                    return res;
+                }
+
+                int alignedw = 0, alignedh = 0;
+                AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(hnd, alignedw, alignedh);
+                *stride = alignedw;
+
+                res = 0;
+            } break;
+
+        case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE:
+            {
+                const private_handle_t* hnd =  va_arg(args, private_handle_t*);
+                int *stride = va_arg(args, int *);
+                int *height = va_arg(args, int *);
+                if (private_handle_t::validate(hnd)) {
+                    return res;
+                }
+
+                int alignedw = 0, alignedh = 0;
+                AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(hnd, alignedw, alignedh);
+                *stride = alignedw;
+                *height = alignedh;
+
+                res = 0;
+            } break;
+
+        case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES:
+            {
+                int width   = va_arg(args, int);
+                int height  = va_arg(args, int);
+                int format  = va_arg(args, int);
+                int usage   = va_arg(args, int);
+                int *alignedWidth = va_arg(args, int *);
+                int *alignedHeight = va_arg(args, int *);
+                int *tileEnabled = va_arg(args,int *);
+                *tileEnabled = isUBwcEnabled(format, usage) ||
+                               isMacroTileEnabled(format, usage);
+                AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
+                        height, format, usage, *alignedWidth, *alignedHeight);
+                res = 0;
+            } break;
+
+        case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE:
+            {
+                private_handle_t* hnd =  va_arg(args, private_handle_t*);
+                int *color_space = va_arg(args, int *);
+                if (private_handle_t::validate(hnd)) {
+                    return res;
+                }
+                MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+                if(metadata && metadata->operation & UPDATE_COLOR_SPACE) {
+                    *color_space = metadata->colorSpace;
+                    res = 0;
+                }
+            } break;
+
+        case GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO:
+            {
+                private_handle_t* hnd =  va_arg(args, private_handle_t*);
+                android_ycbcr* ycbcr = va_arg(args, struct android_ycbcr *);
+                if (!private_handle_t::validate(hnd)) {
+                    res = getYUVPlaneInfo(hnd, ycbcr);
+                }
+            } break;
+
+        case GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO:
+            {
+                private_handle_t* hnd =  va_arg(args, private_handle_t*);
+                int *map_secure_buffer = va_arg(args, int *);
+                if (private_handle_t::validate(hnd)) {
+                    return res;
+                }
+                MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+                if(metadata && metadata->operation & MAP_SECURE_BUFFER) {
+                    *map_secure_buffer = metadata->mapSecureBuffer;
+                    res = 0;
+                } else {
+                    *map_secure_buffer = 0;
+                }
+            } break;
+
+        case GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG:
+            {
+                private_handle_t* hnd =  va_arg(args, private_handle_t*);
+                int *flag = va_arg(args, int *);
+                if (private_handle_t::validate(hnd)) {
+                    return res;
+                }
+                *flag = hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+                MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+                if (metadata && (metadata->operation & LINEAR_FORMAT)) {
+                    *flag = 0;
+                }
+                res = 0;
+            } break;
+
+        case GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS:
+            {
+                private_handle_t* hnd = va_arg(args, private_handle_t*);
+                void** rgb_data = va_arg(args, void**);
+                if (!private_handle_t::validate(hnd)) {
+                    res = getRgbDataAddress(hnd, rgb_data);
+                }
+            } break;
+
+        case GRALLOC_MODULE_PERFORM_GET_IGC:
+            {
+                private_handle_t* hnd = va_arg(args, private_handle_t*);
+                uint32_t *igc = va_arg(args, uint32_t *);
+                if (!private_handle_t::validate(hnd) && igc) {
+                    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+                    if (metadata && (metadata->operation & SET_IGC)) {
+                        *igc = metadata->igc;
+                        res = 0;
+                    }
+                }
+            } break;
+
+        case GRALLOC_MODULE_PERFORM_SET_IGC:
+            res = 0;
+            break;
+
+        case GRALLOC_MODULE_PERFORM_SET_SINGLE_BUFFER_MODE:
+            {
+                private_handle_t* hnd =  va_arg(args, private_handle_t*);
+                uint32_t *enable = va_arg(args, uint32_t*);
+                if (!private_handle_t::validate(hnd)) {
+                    setMetaData(hnd, SET_SINGLE_BUFFER_MODE, enable);
+                    res = 0;
+                }
+            } break;
+        default:
+            break;
+    }
+    va_end(args);
+    return res;
+}
diff --git a/msmcobalt/libgralloc/memalloc.h b/msmcobalt/libgralloc/memalloc.h
new file mode 100644
index 0000000..598d983
--- /dev/null
+++ b/msmcobalt/libgralloc/memalloc.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GRALLOC_MEMALLOC_H
+#define GRALLOC_MEMALLOC_H
+
+#include <stdlib.h>
+
+namespace gralloc {
+
+enum {
+    CACHE_CLEAN = 0x1,
+    CACHE_INVALIDATE,
+    CACHE_CLEAN_AND_INVALIDATE,
+};
+
+struct alloc_data {
+    void           *base;
+    int            fd;
+    unsigned int   offset;
+    unsigned int   size;
+    unsigned int   align;
+    uintptr_t      pHandle;
+    bool           uncached;
+    unsigned int   flags;
+    unsigned int   heapId;
+    int            allocType;
+};
+
+class IMemAlloc {
+
+    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, unsigned int size,
+                            unsigned int offset, int fd) = 0;
+
+    // Map buffer
+    virtual int map_buffer(void **pBase, unsigned int size,
+                           unsigned int offset, int fd) = 0;
+
+    // Unmap buffer
+    virtual int unmap_buffer(void *base, unsigned int size,
+                             unsigned int offset) = 0;
+
+    // Clean and invalidate
+    virtual int clean_buffer(void *base, unsigned int size,
+                             unsigned int offset, int fd, int op) = 0;
+
+    // Destructor
+    virtual ~IMemAlloc() {};
+
+    enum {
+        FD_INIT = -1,
+    };
+
+};
+
+} // end gralloc namespace
+#endif // GRALLOC_MEMALLOC_H
diff --git a/msmcobalt/libgralloc1/Android.mk b/msmcobalt/libgralloc1/Android.mk
new file mode 100644
index 0000000..b66a027
--- /dev/null
+++ b/msmcobalt/libgralloc1/Android.mk
@@ -0,0 +1,25 @@
+# Gralloc module
+LOCAL_PATH := $(call my-dir)
+include $(LOCAL_PATH)/../common.mk
+include $(CLEAR_VARS)
+
+LOCAL_MODULE                  := gralloc.$(TARGET_BOARD_PLATFORM)
+LOCAL_MODULE_RELATIVE_PATH    := hw
+LOCAL_MODULE_TAGS             := optional
+LOCAL_C_INCLUDES              := $(common_includes) \
+                                 external/libcxx/include/
+
+LOCAL_SHARED_LIBRARIES        := $(common_libs) libqdMetaData libsync libqdutils
+LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wall -std=c++11 -Werror
+LOCAL_CFLAGS                  += -isystem  $(kernel_includes)
+LOCAL_CLANG                   := true
+LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
+LOCAL_SRC_FILES               := gr_utils.cpp \
+                                 gr_ion_alloc.cpp \
+                                 gr_adreno_info.cpp \
+                                 gr_allocator.cpp \
+                                 gr_buf_mgr.cpp \
+                                 gr_device_impl.cpp
+LOCAL_COPY_HEADERS_TO         := $(common_header_export_path)
+LOCAL_COPY_HEADERS            := gr_device_impl.h gralloc_priv.h gr_priv_handle.h
+include $(BUILD_SHARED_LIBRARY)
diff --git a/msmcobalt/libgralloc1/gr_adreno_info.cpp b/msmcobalt/libgralloc1/gr_adreno_info.cpp
new file mode 100644
index 0000000..adb59f0
--- /dev/null
+++ b/msmcobalt/libgralloc1/gr_adreno_info.cpp
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include <dlfcn.h>
+
+#include "gralloc_priv.h"
+#include "gr_adreno_info.h"
+#include "gr_utils.h"
+
+namespace gralloc1 {
+
+AdrenoMemInfo::AdrenoMemInfo() {
+}
+
+bool AdrenoMemInfo::Init() {
+  libadreno_utils_ = ::dlopen("libadreno_utils.so", RTLD_NOW);
+  if (libadreno_utils_) {
+    *reinterpret_cast<void **>(&LINK_adreno_compute_aligned_width_and_height) =
+        ::dlsym(libadreno_utils_, "compute_aligned_width_and_height");
+    *reinterpret_cast<void **>(&LINK_adreno_compute_padding) =
+        ::dlsym(libadreno_utils_, "compute_surface_padding");
+    *reinterpret_cast<void **>(&LINK_adreno_isMacroTilingSupportedByGpu) =
+        ::dlsym(libadreno_utils_, "isMacroTilingSupportedByGpu");
+    *reinterpret_cast<void **>(&LINK_adreno_compute_compressedfmt_aligned_width_and_height) =
+        ::dlsym(libadreno_utils_, "compute_compressedfmt_aligned_width_and_height");
+    *reinterpret_cast<void **>(&LINK_adreno_isUBWCSupportedByGpu) =
+        ::dlsym(libadreno_utils_, "isUBWCSupportedByGpu");
+    *reinterpret_cast<void **>(&LINK_adreno_get_gpu_pixel_alignment) =
+        ::dlsym(libadreno_utils_, "get_gpu_pixel_alignment");
+  } else {
+    ALOGE(" Failed to load libadreno_utils.so");
+    return false;
+  }
+
+  // Check if the overriding property debug.gralloc.gfx_ubwc_disable_
+  // that disables UBWC allocations for the graphics stack is set
+  char property[PROPERTY_VALUE_MAX];
+  property_get("debug.gralloc.gfx_ubwc_disable_", property, "0");
+  if (!(strncmp(property, "1", PROPERTY_VALUE_MAX)) ||
+      !(strncmp(property, "true", PROPERTY_VALUE_MAX))) {
+    gfx_ubwc_disable_ = true;
+  }
+
+  if ((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
+      (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
+       (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
+    map_fb_ = true;
+  }
+
+  return true;
+}
+
+AdrenoMemInfo::~AdrenoMemInfo() {
+  if (libadreno_utils_) {
+    ::dlclose(libadreno_utils_);
+  }
+}
+
+bool AdrenoMemInfo::IsMacroTilingSupportedByGPU() {
+  if (LINK_adreno_isMacroTilingSupportedByGpu) {
+    return LINK_adreno_isMacroTilingSupportedByGpu();
+  }
+
+  return false;
+}
+
+void AdrenoMemInfo::AlignUnCompressedRGB(int width, int height, int format, int tile_enabled,
+                                         unsigned int *aligned_w, unsigned int *aligned_h) {
+  *aligned_w = (unsigned int)ALIGN(width, 32);
+  *aligned_h = (unsigned int)ALIGN(height, 32);
+
+  // Don't add any additional padding if debug.gralloc.map_fb_memory
+  // is enabled
+  if (map_fb_) {
+    return;
+  }
+
+  int bpp = 4;
+  switch (format) {
+    case HAL_PIXEL_FORMAT_RGB_888:
+      bpp = 3;
+      break;
+    case HAL_PIXEL_FORMAT_RGB_565:
+    case HAL_PIXEL_FORMAT_BGR_565:
+    case HAL_PIXEL_FORMAT_RGBA_5551:
+    case HAL_PIXEL_FORMAT_RGBA_4444:
+      bpp = 2;
+      break;
+    default:
+      break;
+  }
+
+  int raster_mode = 0;          // Adreno unknown raster mode.
+  int padding_threshold = 512;  // Threshold for padding surfaces.
+  // the function below computes aligned width and aligned height
+  // based on linear or macro tile mode selected.
+  if (LINK_adreno_compute_aligned_width_and_height) {
+    LINK_adreno_compute_aligned_width_and_height(
+        width, height, bpp, tile_enabled, raster_mode, padding_threshold,
+        reinterpret_cast<int *>(aligned_w), reinterpret_cast<int *>(aligned_h));
+  } else if (LINK_adreno_compute_padding) {
+    int surface_tile_height = 1;  // Linear surface
+    *aligned_w = UINT(LINK_adreno_compute_padding(width, bpp, surface_tile_height, raster_mode,
+                                                  padding_threshold));
+    ALOGW("%s: Warning!! Old GFX API is used to calculate stride", __FUNCTION__);
+  } else {
+    ALOGW(
+        "%s: Warning!! Symbols compute_surface_padding and "
+        "compute_aligned_width_and_height not found",
+        __FUNCTION__);
+  }
+}
+
+void AdrenoMemInfo::AlignCompressedRGB(int width, int height, int format, unsigned int *aligned_w,
+                                       unsigned int *aligned_h) {
+  if (LINK_adreno_compute_compressedfmt_aligned_width_and_height) {
+    int bytesPerPixel = 0;
+    int raster_mode = 0;          // Adreno unknown raster mode.
+    int padding_threshold = 512;  // Threshold for padding
+    // surfaces.
+
+    LINK_adreno_compute_compressedfmt_aligned_width_and_height(
+        width, height, format, 0, raster_mode, padding_threshold,
+        reinterpret_cast<int *>(aligned_w), reinterpret_cast<int *>(aligned_h), &bytesPerPixel);
+  } else {
+    ALOGW("%s: Warning!! compute_compressedfmt_aligned_width_and_height not found", __FUNCTION__);
+  }
+}
+
+bool AdrenoMemInfo::IsUBWCSupportedByGPU(int format) {
+  if (!gfx_ubwc_disable_ && LINK_adreno_isUBWCSupportedByGpu) {
+    ADRENOPIXELFORMAT gpu_format = GetGpuPixelFormat(format);
+    return LINK_adreno_isUBWCSupportedByGpu(gpu_format);
+  }
+
+  return false;
+}
+
+uint32_t AdrenoMemInfo::GetGpuPixelAlignment() {
+  if (LINK_adreno_get_gpu_pixel_alignment) {
+    return LINK_adreno_get_gpu_pixel_alignment();
+  }
+
+  return 1;
+}
+
+ADRENOPIXELFORMAT AdrenoMemInfo::GetGpuPixelFormat(int hal_format) {
+  switch (hal_format) {
+    case HAL_PIXEL_FORMAT_RGBA_8888:
+      return ADRENO_PIXELFORMAT_R8G8B8A8;
+    case HAL_PIXEL_FORMAT_RGBX_8888:
+      return ADRENO_PIXELFORMAT_R8G8B8X8;
+    case HAL_PIXEL_FORMAT_RGB_565:
+      return ADRENO_PIXELFORMAT_B5G6R5;
+    case HAL_PIXEL_FORMAT_BGR_565:
+      return ADRENO_PIXELFORMAT_R5G6B5;
+    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+      return ADRENO_PIXELFORMAT_NV12;
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+      return ADRENO_PIXELFORMAT_NV12_EXT;
+    default:
+      ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format);
+      break;
+  }
+
+  return ADRENO_PIXELFORMAT_UNKNOWN;
+}
+
+}  // namespace gralloc1
diff --git a/msmcobalt/libgralloc1/gr_adreno_info.h b/msmcobalt/libgralloc1/gr_adreno_info.h
new file mode 100644
index 0000000..7b053ad
--- /dev/null
+++ b/msmcobalt/libgralloc1/gr_adreno_info.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __GR_ADRENO_INFO_H__
+#define __GR_ADRENO_INFO_H__
+
+#ifdef VENUS_COLOR_FORMAT
+#include <media/msm_media_info.h>
+#else
+#define VENUS_Y_STRIDE(args...) 0
+#define VENUS_Y_SCANLINES(args...) 0
+#define VENUS_BUFFER_SIZE(args...) 0
+#endif
+
+namespace gralloc1 {
+
+// Adreno Pixel Formats
+typedef enum {
+  ADRENO_PIXELFORMAT_UNKNOWN = 0,
+  ADRENO_PIXELFORMAT_R8G8B8A8 = 28,
+  ADRENO_PIXELFORMAT_R8G8B8A8_SRGB = 29,
+  ADRENO_PIXELFORMAT_B5G6R5 = 85,
+  ADRENO_PIXELFORMAT_B5G5R5A1 = 86,
+  ADRENO_PIXELFORMAT_B8G8R8A8 = 90,
+  ADRENO_PIXELFORMAT_B8G8R8A8_SRGB = 91,
+  ADRENO_PIXELFORMAT_B8G8R8X8_SRGB = 93,
+  ADRENO_PIXELFORMAT_NV12 = 103,
+  ADRENO_PIXELFORMAT_YUY2 = 107,
+  ADRENO_PIXELFORMAT_B4G4R4A4 = 115,
+  ADRENO_PIXELFORMAT_NV12_EXT = 506,       // NV12 with non-std alignment and offsets
+  ADRENO_PIXELFORMAT_R8G8B8X8 = 507,       //  GL_RGB8 (Internal)
+  ADRENO_PIXELFORMAT_R8G8B8 = 508,         //  GL_RGB8
+  ADRENO_PIXELFORMAT_A1B5G5R5 = 519,       //  GL_RGB5_A1
+  ADRENO_PIXELFORMAT_R8G8B8X8_SRGB = 520,  //  GL_SRGB8
+  ADRENO_PIXELFORMAT_R8G8B8_SRGB = 521,    //  GL_SRGB8
+  ADRENO_PIXELFORMAT_R5G6B5 = 610,         //  RGBA version of B5G6R5
+  ADRENO_PIXELFORMAT_R5G5B5A1 = 611,       //  RGBA version of B5G5R5A1
+  ADRENO_PIXELFORMAT_R4G4B4A4 = 612,       //  RGBA version of B4G4R4A4
+  ADRENO_PIXELFORMAT_UYVY = 614,           //  YUV 4:2:2 packed progressive (1 plane)
+  ADRENO_PIXELFORMAT_NV21 = 619,
+  ADRENO_PIXELFORMAT_Y8U8V8A8 = 620,  // YUV 4:4:4 packed (1 plane)
+  ADRENO_PIXELFORMAT_Y8 = 625,        //  Single 8-bit luma only channel YUV format
+} ADRENOPIXELFORMAT;
+
+class AdrenoMemInfo {
+ public:
+  AdrenoMemInfo();
+
+  ~AdrenoMemInfo();
+
+  bool Init();
+
+  /*
+   * Function to compute aligned width and aligned height based on
+   * width, height, format and usage flags.
+   *
+   * @return aligned width, aligned height
+   */
+  void GetAlignedWidthAndHeight(int width, int height, int format, int usage,
+                                unsigned int *aligned_w, unsigned int *aligned_h, bool ubwc_enabled,
+                                bool tile_enabled);
+
+  /*
+   * Function to compute the adreno aligned width and aligned height
+   * based on the width and format.
+   *
+   * @return aligned width, aligned height
+   */
+  void AlignUnCompressedRGB(int width, int height, int format, int tileEnabled,
+                            unsigned int *aligned_w, unsigned int *aligned_h);
+
+  /*
+   * Function to compute the adreno aligned width and aligned height
+   * based on the width and format.
+   *
+   * @return aligned width, aligned height
+   */
+  void AlignCompressedRGB(int width, int height, int format, unsigned int *aligned_w,
+                          unsigned int *aligned_h);
+
+  /*
+   * Function to compute the pixel alignment requirement.
+   *
+   * @return alignment
+   */
+  uint32_t GetGpuPixelAlignment();
+
+  /*
+   * Function to return whether GPU support MacroTile feature
+   *
+   * @return >0 : supported
+   *          0 : not supported
+   */
+  bool IsMacroTilingSupportedByGPU();
+
+  /*
+   * Function to query whether GPU supports UBWC for given HAL format
+   * @return > 0 : supported
+   *           0 : not supported
+   */
+  bool IsUBWCSupportedByGPU(int format);
+
+  /*
+   * Function to get the corresponding Adreno format for given HAL format
+   */
+  ADRENOPIXELFORMAT GetGpuPixelFormat(int hal_format);
+
+ private:
+  // link(s)to adreno surface padding library.
+  int (*LINK_adreno_compute_padding)(int width, int bpp, int surface_tile_height,
+                                     int screen_tile_height, int padding_threshold) = NULL;
+  void (*LINK_adreno_compute_aligned_width_and_height)(int width, int height, int bpp,
+                                                       int tile_mode, int raster_mode,
+                                                       int padding_threshold, int *aligned_w,
+                                                       int *aligned_h) = NULL;
+  int (*LINK_adreno_isMacroTilingSupportedByGpu)(void) = NULL;
+  void (*LINK_adreno_compute_compressedfmt_aligned_width_and_height)(
+      int width, int height, int format, int tile_mode, int raster_mode, int padding_threshold,
+      int *aligned_w, int *aligned_h, int *bpp) = NULL;
+  int (*LINK_adreno_isUBWCSupportedByGpu)(ADRENOPIXELFORMAT format) = NULL;
+  unsigned int (*LINK_adreno_get_gpu_pixel_alignment)() = NULL;
+
+  bool gfx_ubwc_disable_ = false;
+  bool map_fb_ = false;
+  void *libadreno_utils_ = NULL;
+};
+
+}  // namespace gralloc1
+
+#endif  // __GR_ADRENO_INFO_H__
diff --git a/msmcobalt/libgralloc1/gr_allocator.cpp b/msmcobalt/libgralloc1/gr_allocator.cpp
new file mode 100644
index 0000000..b45ba83
--- /dev/null
+++ b/msmcobalt/libgralloc1/gr_allocator.cpp
@@ -0,0 +1,871 @@
+/*
+ * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <cutils/log.h>
+#include <algorithm>
+
+#include "gr_utils.h"
+#include "gr_allocator.h"
+#include "gr_adreno_info.h"
+#include "gralloc_priv.h"
+
+#include "qd_utils.h"
+#include "qdMetaData.h"
+
+#define ASTC_BLOCK_SIZE 16
+
+#ifndef ION_FLAG_CP_PIXEL
+#define ION_FLAG_CP_PIXEL 0
+#endif
+
+#ifndef ION_FLAG_ALLOW_NON_CONTIG
+#define ION_FLAG_ALLOW_NON_CONTIG 0
+#endif
+
+#ifdef MASTER_SIDE_CP
+#define CP_HEAP_ID ION_SECURE_HEAP_ID
+#define SD_HEAP_ID ION_SECURE_DISPLAY_HEAP_ID
+#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_CP_PIXEL)
+#define ION_SD_FLAGS (ION_SECURE | ION_FLAG_CP_SEC_DISPLAY)
+#else  // SLAVE_SIDE_CP
+#define CP_HEAP_ID ION_CP_MM_HEAP_ID
+#define SD_HEAP_ID CP_HEAP_ID
+#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_ALLOW_NON_CONTIG)
+#define ION_SD_FLAGS ION_SECURE
+#endif
+
+namespace gralloc1 {
+
+Allocator::Allocator() : ion_allocator_(NULL), adreno_helper_(NULL) {
+}
+
+bool Allocator::Init() {
+  ion_allocator_ = new IonAlloc();
+  if (!ion_allocator_->Init()) {
+    return false;
+  }
+
+  adreno_helper_ = new AdrenoMemInfo();
+  if (!adreno_helper_->Init()) {
+    return false;
+  }
+
+  gpu_support_macrotile = adreno_helper_->IsMacroTilingSupportedByGPU();
+  int supports_macrotile = 0;
+  qdutils::querySDEInfo(qdutils::HAS_MACRO_TILE, &supports_macrotile);
+  display_support_macrotile = !!supports_macrotile;
+
+  return true;
+}
+
+Allocator::~Allocator() {
+  if (ion_allocator_) {
+    delete ion_allocator_;
+  }
+
+  if (adreno_helper_) {
+    delete adreno_helper_;
+  }
+}
+
+int Allocator::AllocateMem(AllocData *alloc_data, gralloc1_producer_usage_t prod_usage,
+                           gralloc1_consumer_usage_t cons_usage) {
+  int ret;
+  alloc_data->uncached = UseUncached(prod_usage);
+
+  // After this point we should have the right heap set, there is no fallback
+  GetIonHeapInfo(prod_usage, cons_usage, &alloc_data->heap_id, &alloc_data->alloc_type,
+                 &alloc_data->flags);
+
+  ret = ion_allocator_->AllocBuffer(alloc_data);
+  if (ret >= 0) {
+    alloc_data->alloc_type |= private_handle_t::PRIV_FLAGS_USES_ION;
+  } else {
+    ALOGE("%s: Failed to allocate buffer - heap: 0x%x flags: 0x%x", __FUNCTION__,
+          alloc_data->heap_id, alloc_data->flags);
+  }
+
+  return ret;
+}
+
+// Allocates buffer from width, height and format into a
+// private_handle_t. It is the responsibility of the caller
+// to free the buffer using the FreeBuffer function
+int Allocator::AllocateBuffer(const BufferDescriptor &descriptor, private_handle_t **pHnd) {
+  AllocData data;
+  unsigned int aligned_w, aligned_h;
+  data.base = 0;
+  data.fd = -1;
+  data.offset = 0;
+  data.align = (unsigned int)getpagesize();
+  int format = descriptor.GetFormat();
+  gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
+  gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
+  GetBufferSizeAndDimensions(descriptor, &data.size, &aligned_w, &aligned_h);
+
+  int err = AllocateMem(&data, prod_usage, cons_usage);
+  if (0 != err) {
+    ALOGE("%s: allocate failed", __FUNCTION__);
+    return -ENOMEM;
+  }
+
+  if (IsUBwcEnabled(format, prod_usage, cons_usage)) {
+    data.alloc_type |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+  }
+
+  // Metadata is not allocated. would be empty
+  private_handle_t *hnd = new private_handle_t(
+      data.fd, data.size, INT(data.alloc_type), 0, INT(format), INT(aligned_w), INT(aligned_h), -1,
+      0, 0, descriptor.GetWidth(), descriptor.GetHeight(), prod_usage, cons_usage);
+  hnd->base = (uint64_t)data.base;
+  hnd->offset = data.offset;
+  hnd->gpuaddr = 0;
+  *pHnd = hnd;
+
+  return 0;
+}
+
+int Allocator::MapBuffer(void **base, unsigned int size, unsigned int offset, int fd) {
+  if (ion_allocator_) {
+    return ion_allocator_->MapBuffer(base, size, offset, fd);
+  }
+
+  return -EINVAL;
+}
+
+int Allocator::FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd) {
+  if (ion_allocator_) {
+    return ion_allocator_->FreeBuffer(base, size, offset, fd);
+  }
+
+  return -EINVAL;
+}
+
+int Allocator::CleanBuffer(void *base, unsigned int size, unsigned int offset, int fd, int op) {
+  if (ion_allocator_) {
+    return ion_allocator_->CleanBuffer(base, size, offset, fd, op);
+  }
+
+  return -EINVAL;
+}
+
+bool Allocator::CheckForBufferSharing(uint32_t num_descriptors, const BufferDescriptor *descriptors,
+                                      int *max_index) {
+  unsigned int cur_heap_id = 0, prev_heap_id = 0;
+  unsigned int cur_alloc_type = 0, prev_alloc_type = 0;
+  unsigned int cur_ion_flags = 0, prev_ion_flags = 0;
+  bool cur_uncached = false, prev_uncached = false;
+  unsigned int alignedw, alignedh;
+  unsigned int max_size = 0;
+
+  *max_index = -1;
+  for (uint32_t i = 0; i < num_descriptors; i++) {
+    // Check Cached vs non-cached and all the ION flags
+    cur_uncached = UseUncached(descriptors[i].GetProducerUsage());
+    GetIonHeapInfo(descriptors[i].GetProducerUsage(), descriptors[i].GetConsumerUsage(),
+                   &cur_heap_id, &cur_alloc_type, &cur_ion_flags);
+
+    if (i > 0 && (cur_heap_id != prev_heap_id || cur_alloc_type != prev_alloc_type ||
+                  cur_ion_flags != prev_ion_flags)) {
+      return false;
+    }
+
+    // For same format type, find the descriptor with bigger size
+    GetAlignedWidthAndHeight(descriptors[i], &alignedw, &alignedh);
+    unsigned int size = GetSize(descriptors[i], alignedw, alignedh);
+    if (max_size < size) {
+      *max_index = INT(i);
+      max_size = size;
+    }
+
+    prev_heap_id = cur_heap_id;
+    prev_uncached = cur_uncached;
+    prev_ion_flags = cur_ion_flags;
+    prev_alloc_type = cur_alloc_type;
+  }
+
+  return true;
+}
+
+bool Allocator::IsMacroTileEnabled(int format, gralloc1_producer_usage_t prod_usage,
+                                   gralloc1_consumer_usage_t cons_usage) {
+  bool tile_enabled = false;
+
+  // Check whether GPU & MDSS supports MacroTiling feature
+  if (!adreno_helper_->IsMacroTilingSupportedByGPU() || !display_support_macrotile) {
+    return tile_enabled;
+  }
+
+  // check the format
+  switch (format) {
+    case HAL_PIXEL_FORMAT_RGBA_8888:
+    case HAL_PIXEL_FORMAT_RGBX_8888:
+    case HAL_PIXEL_FORMAT_BGRA_8888:
+    case HAL_PIXEL_FORMAT_RGB_565:
+    case HAL_PIXEL_FORMAT_BGR_565:
+      if (!CpuCanAccess(prod_usage, cons_usage)) {
+        // not touched by CPU
+        tile_enabled = true;
+      }
+      break;
+    default:
+      break;
+  }
+
+  return tile_enabled;
+}
+
+// helper function
+unsigned int Allocator::GetSize(const BufferDescriptor &descriptor, unsigned int alignedw,
+                                unsigned int alignedh) {
+  unsigned int size = 0;
+  int format = descriptor.GetFormat();
+  int width = descriptor.GetWidth();
+  int height = descriptor.GetHeight();
+  gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
+  gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
+
+  if (IsUBwcEnabled(format, prod_usage, cons_usage)) {
+    return GetUBwcSize(width, height, format, alignedw, alignedh);
+  }
+
+  if (IsUncompressedRGBFormat(format)) {
+    uint32_t bpp = GetBppForUncompressedRGB(format);
+    size = alignedw * alignedh * bpp;
+    return size;
+  }
+
+  if (IsCompressedRGBFormat(format)) {
+    size = alignedw * alignedh * ASTC_BLOCK_SIZE;
+    return size;
+  }
+
+  // Below switch should be for only YUV/custom formats
+  switch (format) {
+    case HAL_PIXEL_FORMAT_RAW16:
+      size = alignedw * alignedh * 2;
+      break;
+    case HAL_PIXEL_FORMAT_RAW10:
+      size = ALIGN(alignedw * alignedh, SIZE_4K);
+      break;
+
+    // adreno formats
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:  // NV21
+      size = ALIGN(alignedw * alignedh, SIZE_4K);
+      size += (unsigned int)ALIGN(2 * ALIGN(width / 2, 32) * ALIGN(height / 2, 32), SIZE_4K);
+      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
+      size = ALIGN(alignedw * alignedh, SIZE_8K);
+      size += ALIGN(alignedw * (unsigned int)ALIGN(height / 2, 32), SIZE_8K);
+      break;
+    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 0;
+      }
+      size = alignedw * alignedh + (ALIGN(alignedw / 2, 16) * (alignedh / 2)) * 2;
+      size = ALIGN(size, (unsigned int)SIZE_4K);
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+      size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2 + 1, SIZE_4K);
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+    case HAL_PIXEL_FORMAT_YCbCr_422_I:
+    case HAL_PIXEL_FORMAT_YCrCb_422_I:
+      if (width & 1) {
+        ALOGE("width is odd for the YUV422_SP format");
+        return 0;
+      }
+      size = ALIGN(alignedw * alignedh * 2, SIZE_4K);
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+      size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
+      break;
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
+      size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height);
+      break;
+    case HAL_PIXEL_FORMAT_BLOB:
+    case HAL_PIXEL_FORMAT_RAW_OPAQUE:
+      if (height != 1) {
+        ALOGE("%s: Buffers with HAL_PIXEL_FORMAT_BLOB must have height 1 ", __FUNCTION__);
+        return 0;
+      }
+      size = (unsigned int)width;
+      break;
+    case HAL_PIXEL_FORMAT_NV21_ZSL:
+      size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2, SIZE_4K);
+      break;
+    default:
+      ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
+      return 0;
+  }
+
+  return size;
+}
+
+void Allocator::GetBufferSizeAndDimensions(int width, int height, int format, unsigned int *size,
+                                           unsigned int *alignedw, unsigned int *alignedh) {
+  BufferDescriptor descriptor = BufferDescriptor(width, height, format);
+  GetAlignedWidthAndHeight(descriptor, alignedw, alignedh);
+
+  *size = GetSize(descriptor, *alignedw, *alignedh);
+}
+
+void Allocator::GetBufferSizeAndDimensions(const BufferDescriptor &descriptor, unsigned int *size,
+                                           unsigned int *alignedw, unsigned int *alignedh) {
+  GetAlignedWidthAndHeight(descriptor, alignedw, alignedh);
+
+  *size = GetSize(descriptor, *alignedw, *alignedh);
+}
+
+void Allocator::GetBufferAttributes(const BufferDescriptor &descriptor, unsigned int *alignedw,
+                                    unsigned int *alignedh, int *tiled, unsigned int *size) {
+  int format = descriptor.GetFormat();
+  gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
+  gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
+
+  *tiled = false;
+  if (IsUBwcEnabled(format, prod_usage, cons_usage) ||
+      IsMacroTileEnabled(format, prod_usage, cons_usage)) {
+    *tiled = true;
+  }
+
+  GetAlignedWidthAndHeight(descriptor, alignedw, alignedh);
+  *size = GetSize(descriptor, *alignedw, *alignedh);
+}
+
+void Allocator::GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
+                                      int color_format, struct android_ycbcr *ycbcr) {
+  // UBWC buffer has these 4 planes in the following sequence:
+  // Y_Meta_Plane, Y_Plane, UV_Meta_Plane, UV_Plane
+  unsigned int y_meta_stride, y_meta_height, y_meta_size;
+  unsigned int y_stride, y_height, y_size;
+  unsigned int c_meta_stride, c_meta_height, c_meta_size;
+  unsigned int alignment = 4096;
+
+  y_meta_stride = VENUS_Y_META_STRIDE(color_format, INT(width));
+  y_meta_height = VENUS_Y_META_SCANLINES(color_format, INT(height));
+  y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);
+
+  y_stride = VENUS_Y_STRIDE(color_format, INT(width));
+  y_height = VENUS_Y_SCANLINES(color_format, INT(height));
+  y_size = ALIGN((y_stride * y_height), alignment);
+
+  c_meta_stride = VENUS_UV_META_STRIDE(color_format, INT(width));
+  c_meta_height = VENUS_UV_META_SCANLINES(color_format, INT(height));
+  c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
+
+  ycbcr->y = reinterpret_cast<void *>(base + y_meta_size);
+  ycbcr->cb = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size);
+  ycbcr->cr = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size + 1);
+  ycbcr->ystride = y_stride;
+  ycbcr->cstride = VENUS_UV_STRIDE(color_format, INT(width));
+}
+
+void Allocator::GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp,
+                                  struct android_ycbcr *ycbcr) {
+  unsigned int ystride, cstride;
+
+  ystride = cstride = UINT(width) * bpp;
+  ycbcr->y = reinterpret_cast<void *>(base);
+  ycbcr->cb = reinterpret_cast<void *>(base + ystride * UINT(height));
+  ycbcr->cr = reinterpret_cast<void *>(base + ystride * UINT(height) + 1);
+  ycbcr->ystride = ystride;
+  ycbcr->cstride = cstride;
+  ycbcr->chroma_step = 2 * bpp;
+}
+
+int Allocator::GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr *ycbcr) {
+  int err = 0;
+  uint32_t width = UINT(hnd->width);
+  uint32_t height = UINT(hnd->height);
+  int format = hnd->format;
+  gralloc1_producer_usage_t prod_usage = hnd->GetProducerUsage();
+  gralloc1_consumer_usage_t cons_usage = hnd->GetConsumerUsage();
+  unsigned int ystride, cstride;
+
+  memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
+  MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
+
+  // Check if UBWC buffer has been rendered in linear format.
+  if (metadata && (metadata->operation & LINEAR_FORMAT)) {
+    format = INT(metadata->linearFormat);
+  }
+
+  // Check metadata if the geometry has been updated.
+  if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
+    int usage = 0;
+
+    if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
+      usage = GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC;
+    }
+
+    BufferDescriptor descriptor =
+        BufferDescriptor(metadata->bufferDim.sliceWidth, metadata->bufferDim.sliceHeight, format,
+                         prod_usage, cons_usage);
+    GetAlignedWidthAndHeight(descriptor, &width, &height);
+  }
+
+  // Get the chroma offsets from the handle width/height. We take advantage
+  // of the fact the width _is_ the stride
+  switch (format) {
+    // Semiplanar
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+      // Same as YCbCr_420_SP_VENUS
+      GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
+      break;
+
+    case HAL_PIXEL_FORMAT_YCbCr_420_P010:
+      GetYuvSPPlaneInfo(hnd->base, width, height, 2, ycbcr);
+      break;
+
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+      GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr);
+      ycbcr->chroma_step = 2;
+      break;
+
+    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+      GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_BPP10_UBWC, ycbcr);
+      ycbcr->chroma_step = 3;
+      break;
+
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
+    case HAL_PIXEL_FORMAT_NV21_ZSL:
+    case HAL_PIXEL_FORMAT_RAW16:
+    case HAL_PIXEL_FORMAT_RAW10:
+      GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
+      std::swap(ycbcr->cb, ycbcr->cr);
+      break;
+
+    // Planar
+    case HAL_PIXEL_FORMAT_YV12:
+      ystride = width;
+      cstride = ALIGN(width / 2, 16);
+      ycbcr->y = reinterpret_cast<void *>(hnd->base);
+      ycbcr->cr = reinterpret_cast<void *>(hnd->base + ystride * height);
+      ycbcr->cb = reinterpret_cast<void *>(hnd->base + ystride * height + cstride * height / 2);
+      ycbcr->ystride = ystride;
+      ycbcr->cstride = cstride;
+      ycbcr->chroma_step = 1;
+      break;
+
+    // Unsupported formats
+    case HAL_PIXEL_FORMAT_YCbCr_422_I:
+    case HAL_PIXEL_FORMAT_YCrCb_422_I:
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
+    default:
+      ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
+      err = -EINVAL;
+  }
+
+  return err;
+}
+
+int Allocator::GetImplDefinedFormat(gralloc1_producer_usage_t prod_usage,
+                                    gralloc1_consumer_usage_t cons_usage, int format) {
+  int gr_format = format;
+
+  // If input format is HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED then based on
+  // the usage bits, gralloc assigns a format.
+  if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
+      format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+    if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC) {
+      gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
+    } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) {
+      gr_format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE;  // NV12
+    } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_ZSL) {
+      gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;  // NV21 ZSL
+    } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_CAMERA) {
+      gr_format = HAL_PIXEL_FORMAT_YCrCb_420_SP;  // NV21
+    } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
+      if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+        gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;  // NV21
+      } else {
+        gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS;  // NV12 preview
+      }
+    } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
+      // XXX: If we still haven't set a format, default to RGBA8888
+      gr_format = HAL_PIXEL_FORMAT_RGBA_8888;
+    } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+      // If no other usage flags are detected, default the
+      // flexible YUV format to NV21_ZSL
+      gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;
+    }
+  }
+
+  return gr_format;
+}
+
+// Explicitly defined UBWC formats
+bool Allocator::IsUBwcFormat(int format) {
+  switch (format) {
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+      return true;
+    default:
+      return false;
+  }
+}
+
+bool Allocator::IsUBwcSupported(int format) {
+  // Existing HAL formats with UBWC support
+  switch (format) {
+    case HAL_PIXEL_FORMAT_BGR_565:
+    case HAL_PIXEL_FORMAT_RGBA_8888:
+    case HAL_PIXEL_FORMAT_RGBX_8888:
+    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+      return true;
+    default:
+      break;
+  }
+
+  return false;
+}
+
+/* The default policy is to return cached buffers unless the client explicity
+ * sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely
+ * read or written in software. */
+// TODO(user) : As of now relying only on producer usage
+bool Allocator::UseUncached(gralloc1_producer_usage_t usage) {
+  if ((usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_UNCACHED) ||
+      (usage & GRALLOC1_PRODUCER_USAGE_PROTECTED)) {
+    return true;
+  }
+
+  // CPU read rarely
+  if ((usage & GRALLOC1_PRODUCER_USAGE_CPU_READ) &&
+      !(usage & GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN)) {
+    return true;
+  }
+
+  // CPU  write rarely
+  if ((usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE) &&
+      !(usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN)) {
+    return true;
+  }
+
+  return false;
+}
+
+void Allocator::GetIonHeapInfo(gralloc1_producer_usage_t prod_usage,
+                               gralloc1_consumer_usage_t cons_usage, unsigned int *ion_heap_id,
+                               unsigned int *alloc_type, unsigned int *ion_flags) {
+  unsigned int heap_id = 0;
+  unsigned int type = 0;
+  int flags = 0;
+  if (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) {
+    if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) {
+      heap_id = ION_HEAP(SD_HEAP_ID);
+      /*
+       * There is currently no flag in ION for Secure Display
+       * VM. Please add it to the define once available.
+       */
+      flags |= ION_SD_FLAGS;
+    } else {
+      heap_id = ION_HEAP(CP_HEAP_ID);
+      flags |= ION_CP_FLAGS;
+    }
+  } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_MM_HEAP) {
+    // MM Heap is exclusively a secure heap.
+    // If it is used for non secure cases, fallback to IOMMU heap
+    ALOGW("MM_HEAP cannot be used as an insecure heap. Using system heap instead!!");
+    heap_id |= ION_HEAP(ION_SYSTEM_HEAP_ID);
+  }
+
+  if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_HEAP) {
+    heap_id |= ION_HEAP(ION_CAMERA_HEAP_ID);
+  }
+
+  if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ADSP_HEAP) {
+    heap_id |= ION_HEAP(ION_ADSP_HEAP_ID);
+  }
+
+  if (flags & ION_SECURE) {
+    type |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
+  }
+
+  // if no ion heap flags are set, default to system heap
+  if (!heap_id) {
+    heap_id = ION_HEAP(ION_SYSTEM_HEAP_ID);
+  }
+
+  *alloc_type = type;
+  *ion_flags = (unsigned int)flags;
+  *ion_heap_id = heap_id;
+
+  return;
+}
+
+bool Allocator::IsUBwcEnabled(int format, gralloc1_producer_usage_t prod_usage,
+                              gralloc1_consumer_usage_t cons_usage) {
+  // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
+  if (IsUBwcFormat(format)) {
+    return true;
+  }
+
+  // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
+  // support the format. OR if a non-OpenGL client like Rotator, sets UBWC
+  // usage flag and MDP supports the format.
+  if ((prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC) && IsUBwcSupported(format)) {
+    bool enable = true;
+    // Query GPU for UBWC only if buffer is intended to be used by GPU.
+    if ((cons_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) ||
+        (prod_usage & GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET)) {
+      enable = adreno_helper_->IsUBWCSupportedByGPU(format);
+    }
+
+    // Allow UBWC, only if CPU usage flags are not set
+    if (enable && !(CpuCanAccess(prod_usage, cons_usage))) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+void Allocator::GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
+                                         unsigned int *aligned_h) {
+  switch (format) {
+    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+      *aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
+      *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
+      break;
+    default:
+      ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
+      *aligned_w = 0;
+      *aligned_h = 0;
+      break;
+  }
+}
+
+void Allocator::GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height) {
+  *block_width = 0;
+  *block_height = 0;
+
+  switch (bpp) {
+    case 2:
+    case 4:
+      *block_width = 16;
+      *block_height = 4;
+      break;
+    case 8:
+      *block_width = 8;
+      *block_height = 4;
+      break;
+    case 16:
+      *block_width = 4;
+      *block_height = 4;
+      break;
+    default:
+      ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
+      break;
+  }
+}
+
+unsigned int Allocator::GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp) {
+  unsigned int size = 0;
+  int meta_width, meta_height;
+  int block_width, block_height;
+
+  GetRgbUBwcBlockSize(bpp, &block_width, &block_height);
+  if (!block_width || !block_height) {
+    ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
+    return size;
+  }
+
+  // Align meta buffer height to 16 blocks
+  meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
+
+  // Align meta buffer width to 64 blocks
+  meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
+
+  // Align meta buffer size to 4K
+  size = (unsigned int)ALIGN((meta_width * meta_height), 4096);
+
+  return size;
+}
+
+unsigned int Allocator::GetUBwcSize(int width, int height, int format, unsigned int alignedw,
+                                    unsigned int alignedh) {
+  unsigned int size = 0;
+  uint32_t bpp = 0;
+  switch (format) {
+    case HAL_PIXEL_FORMAT_BGR_565:
+    case HAL_PIXEL_FORMAT_RGBA_8888:
+    case HAL_PIXEL_FORMAT_RGBX_8888:
+    case HAL_PIXEL_FORMAT_RGBA_1010102:
+    case HAL_PIXEL_FORMAT_RGBX_1010102:
+      bpp = GetBppForUncompressedRGB(format);
+      size = alignedw * alignedh * bpp;
+      size += GetRgbUBwcMetaBufferSize(width, height, bpp);
+      break;
+    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+      size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+      size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height);
+      break;
+    default:
+      ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
+      break;
+  }
+
+  return size;
+}
+
+int Allocator::GetRgbDataAddress(private_handle_t *hnd, void **rgb_data) {
+  int err = 0;
+
+  // This api is for RGB* formats
+  if (!gralloc1::IsUncompressedRGBFormat(hnd->format)) {
+    return -EINVAL;
+  }
+
+  // linear buffer, nothing to do further
+  if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
+    *rgb_data = reinterpret_cast<void *>(hnd->base);
+    return err;
+  }
+
+  unsigned int meta_size = 0;
+  uint32_t bpp = GetBppForUncompressedRGB(hnd->format);
+  switch (hnd->format) {
+    case HAL_PIXEL_FORMAT_BGR_565:
+    case HAL_PIXEL_FORMAT_RGBA_8888:
+    case HAL_PIXEL_FORMAT_RGBX_8888:
+      meta_size = GetRgbUBwcMetaBufferSize(hnd->width, hnd->height, bpp);
+      break;
+    default:
+      ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format);
+      err = -EINVAL;
+      break;
+  }
+  *rgb_data = reinterpret_cast<void *>(hnd->base + meta_size);
+
+  return err;
+}
+
+void Allocator::GetAlignedWidthAndHeight(const BufferDescriptor &descriptor, unsigned int *alignedw,
+                                         unsigned int *alignedh) {
+  int width = descriptor.GetWidth();
+  int height = descriptor.GetHeight();
+  int format = descriptor.GetFormat();
+  gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
+  gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
+
+  // Currently surface padding is only computed for RGB* surfaces.
+  bool ubwc_enabled = IsUBwcEnabled(format, prod_usage, cons_usage);
+  int tile = ubwc_enabled || IsMacroTileEnabled(format, prod_usage, cons_usage);
+
+  if (IsUncompressedRGBFormat(format)) {
+    adreno_helper_->AlignUnCompressedRGB(width, height, format, tile, alignedw, alignedh);
+    return;
+  }
+
+  if (ubwc_enabled) {
+    GetYuvUBwcWidthAndHeight(width, height, format, alignedw, alignedh);
+    return;
+  }
+
+  if (IsCompressedRGBFormat(format)) {
+    adreno_helper_->AlignCompressedRGB(width, height, format, alignedw, alignedh);
+    return;
+  }
+
+  int aligned_w = width;
+  int aligned_h = height;
+  unsigned int alignment = 32;
+
+  // Below should be only YUV family
+  switch (format) {
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+      alignment = adreno_helper_->GetGpuPixelAlignment();
+      aligned_w = ALIGN(width, alignment);
+      break;
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
+      aligned_w = ALIGN(width, alignment);
+      break;
+    case HAL_PIXEL_FORMAT_RAW16:
+      aligned_w = ALIGN(width, 16);
+      break;
+    case HAL_PIXEL_FORMAT_RAW10:
+      aligned_w = ALIGN(width * 10 / 8, 16);
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
+      aligned_w = ALIGN(width, 128);
+      break;
+    case HAL_PIXEL_FORMAT_YV12:
+    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+    case HAL_PIXEL_FORMAT_YCbCr_422_I:
+    case HAL_PIXEL_FORMAT_YCrCb_422_I:
+      aligned_w = ALIGN(width, 16);
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+      aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV12, width));
+      aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV12, height));
+      break;
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
+      aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV21, width));
+      aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV21, height));
+      break;
+    case HAL_PIXEL_FORMAT_BLOB:
+    case HAL_PIXEL_FORMAT_RAW_OPAQUE:
+      break;
+    case HAL_PIXEL_FORMAT_NV21_ZSL:
+      aligned_w = ALIGN(width, 64);
+      aligned_h = ALIGN(height, 64);
+      break;
+    default:
+      break;
+  }
+
+  *alignedw = (unsigned int)aligned_w;
+  *alignedh = (unsigned int)aligned_h;
+}
+
+}  // namespace gralloc1
diff --git a/msmcobalt/libgralloc1/gr_allocator.h b/msmcobalt/libgralloc1/gr_allocator.h
new file mode 100644
index 0000000..583b2d7
--- /dev/null
+++ b/msmcobalt/libgralloc1/gr_allocator.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __GR_ALLOCATOR_H__
+#define __GR_ALLOCATOR_H__
+
+#ifdef MASTER_SIDE_CP
+#define SECURE_ALIGN SZ_4K
+#else
+#define SECURE_ALIGN SZ_1M
+#endif
+
+#include "gralloc_priv.h"
+#include "gr_buf_descriptor.h"
+#include "gr_adreno_info.h"
+#include "gr_ion_alloc.h"
+
+namespace gralloc1 {
+
+class Allocator {
+ public:
+  Allocator();
+  ~Allocator();
+  bool Init();
+  int AllocateBuffer(const BufferDescriptor &descriptor, private_handle_t **pHnd);
+  int MapBuffer(void **base, unsigned int size, unsigned int offset, int fd);
+  int FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd);
+  int CleanBuffer(void *base, unsigned int size, unsigned int offset, int fd, int op);
+  int AllocateMem(AllocData *data, gralloc1_producer_usage_t prod_usage,
+                  gralloc1_consumer_usage_t cons_usage);
+  bool IsMacroTileEnabled(int format, gralloc1_producer_usage_t prod_usage,
+                          gralloc1_consumer_usage_t cons_usage);
+  // @return : index of the descriptor with maximum buffer size req
+  bool CheckForBufferSharing(uint32_t num_descriptors, const BufferDescriptor *descriptors,
+                             int *max_index);
+  int GetImplDefinedFormat(gralloc1_producer_usage_t prod_usage,
+                           gralloc1_consumer_usage_t cons_usage, int format);
+  unsigned int GetSize(const BufferDescriptor &d, unsigned int alignedw, unsigned int alignedh);
+  void GetBufferSizeAndDimensions(const BufferDescriptor &d, unsigned int *size,
+                                  unsigned int *alignedw, unsigned int *alignedh);
+  void GetBufferSizeAndDimensions(int width, int height, int format, unsigned int *size,
+                                  unsigned int *alignedw, unsigned int *alignedh);
+  void GetAlignedWidthAndHeight(const BufferDescriptor &d, unsigned int *aligned_w,
+                                unsigned int *aligned_h);
+  void GetBufferAttributes(const BufferDescriptor &d, unsigned int *alignedw,
+                           unsigned int *alignedh, int *tiled, unsigned int *size);
+  int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr *ycbcr);
+  int GetRgbDataAddress(private_handle_t *hnd, void **rgb_data);
+  bool UseUncached(gralloc1_producer_usage_t usage);
+  bool IsUBwcFormat(int format);
+  bool IsUBwcSupported(int format);
+  bool IsUBwcEnabled(int format, gralloc1_producer_usage_t prod_usage,
+                     gralloc1_consumer_usage_t cons_usage);
+
+ private:
+  void GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
+                                unsigned int *aligned_h);
+  void GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp,
+                         struct android_ycbcr *ycbcr);
+  void GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, int color_format,
+                             struct android_ycbcr *ycbcr);
+  void GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height);
+  unsigned int GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp);
+  unsigned int GetUBwcSize(int width, int height, int format, unsigned int alignedw,
+                           unsigned int alignedh);
+  void GetIonHeapInfo(gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage,
+                      unsigned int *ion_heap_id, unsigned int *alloc_type, unsigned int *ion_flags);
+
+  bool gpu_support_macrotile = false;
+  bool display_support_macrotile = false;
+  IonAlloc *ion_allocator_ = NULL;
+  AdrenoMemInfo *adreno_helper_ = NULL;
+};
+
+}  // namespace gralloc1
+
+#endif  // __GR_ALLOCATOR_H__
diff --git a/msmcobalt/libgralloc1/gr_buf_descriptor.h b/msmcobalt/libgralloc1/gr_buf_descriptor.h
new file mode 100644
index 0000000..1c3572d
--- /dev/null
+++ b/msmcobalt/libgralloc1/gr_buf_descriptor.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __GR_BUF_DESCRIPTOR_H__
+#define __GR_BUF_DESCRIPTOR_H__
+
+#include <hardware/gralloc1.h>
+
+#define BUF_DESCRIPTOR(exp) reinterpret_cast<BufferDescriptor *>(exp)
+
+class BufferDescriptor {
+ public:
+  BufferDescriptor() {}
+
+  BufferDescriptor(int w, int h, int f)
+      : width_(w),
+        height_(h),
+        format_(f),
+        producer_usage_(GRALLOC1_PRODUCER_USAGE_NONE),
+        consumer_usage_(GRALLOC1_CONSUMER_USAGE_NONE) {}
+
+  BufferDescriptor(int w, int h, int f, gralloc1_producer_usage_t prod_usage,
+                   gralloc1_consumer_usage_t cons_usage)
+      : width_(w),
+        height_(h),
+        format_(f),
+        producer_usage_(prod_usage),
+        consumer_usage_(cons_usage) {}
+
+  bool IsValid() { return (magic == kMagic); }
+
+  void SetConsumerUsage(gralloc1_consumer_usage_t usage) { consumer_usage_ = usage; }
+
+  void SetProducerUsage(gralloc1_producer_usage_t usage) { producer_usage_ = usage; }
+
+  void SetDimensions(int w, int h) {
+    width_ = w;
+    height_ = h;
+  }
+
+  void SetColorFormat(int format) { format_ = format; }
+
+  gralloc1_consumer_usage_t GetConsumerUsage() const { return consumer_usage_; }
+
+  gralloc1_producer_usage_t GetProducerUsage() const { return producer_usage_; }
+
+  int GetWidth() const { return width_; }
+
+  int GetHeight() const { return height_; }
+
+  int GetFormat() const { return format_; }
+
+ private:
+  static const int kMagic = 'gr1d';
+
+  int magic = kMagic;
+  int width_ = -1;
+  int height_ = -1;
+  int format_ = -1;
+  gralloc1_producer_usage_t producer_usage_ = GRALLOC1_PRODUCER_USAGE_NONE;
+  gralloc1_consumer_usage_t consumer_usage_ = GRALLOC1_CONSUMER_USAGE_NONE;
+};
+
+#endif  // __GR_BUF_DESCRIPTOR_H__
diff --git a/msmcobalt/libgralloc1/gr_buf_mgr.cpp b/msmcobalt/libgralloc1/gr_buf_mgr.cpp
new file mode 100644
index 0000000..33abd40
--- /dev/null
+++ b/msmcobalt/libgralloc1/gr_buf_mgr.cpp
@@ -0,0 +1,641 @@
+/*
+ * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ *
+ * 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 <utility>
+
+#include "qd_utils.h"
+#include "gr_priv_handle.h"
+#include "gr_buf_descriptor.h"
+#include "gr_utils.h"
+#include "gr_buf_mgr.h"
+#include "qdMetaData.h"
+
+namespace gralloc1 {
+
+BufferManager::BufferManager() {
+  char property[PROPERTY_VALUE_MAX];
+
+  // Map framebuffer memory
+  if ((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
+      (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
+       (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
+    map_fb_mem_ = true;
+  }
+
+  // Enable UBWC for framebuffer
+  if ((property_get("debug.gralloc.enable_fb_ubwc", property, NULL) > 0) &&
+      (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
+       (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
+    ubwc_for_fb_ = true;
+  }
+
+  handles_map_.clear();
+}
+
+BufferManager::~BufferManager() {
+  if (allocator_) {
+    delete allocator_;
+  }
+}
+
+bool BufferManager::Init() {
+  allocator_ = new Allocator();
+
+  return allocator_->Init();
+}
+
+gralloc1_error_t BufferManager::AllocateBuffers(uint32_t num_descriptors,
+                                                const BufferDescriptor *descriptors,
+                                                buffer_handle_t *out_buffers) {
+  bool shared = true;
+  gralloc1_error_t status = GRALLOC1_ERROR_NONE;
+
+  // since GRALLOC1_CAPABILITY_TEST_ALLOCATE capability is supported
+  // client can ask to test the allocation by passing NULL out_buffers
+  bool test_allocate = !out_buffers;
+
+  // Check if input descriptors can be supported AND
+  // Find out if a single buffer can be shared for all the given input descriptors
+  uint32_t i = 0;
+  int max_buf_index = -1;
+  shared = allocator_->CheckForBufferSharing(num_descriptors, descriptors, &max_buf_index);
+
+  if (test_allocate) {
+    status = shared ? GRALLOC1_ERROR_NOT_SHARED : status;
+    return status;
+  }
+
+  if (shared && (max_buf_index >= 0)) {
+    // Allocate one and duplicate/copy the handles for each descriptor
+    if (AllocateBuffer(descriptors[max_buf_index], &out_buffers[max_buf_index])) {
+      return GRALLOC1_ERROR_NO_RESOURCES;
+    }
+
+    for (i = 0; i < num_descriptors; i++) {
+      // Create new handle for a given descriptor.
+      // Current assumption is even MetaData memory would be same
+      // Need to revisit if there is a need for own metadata memory
+      if (i != UINT(max_buf_index)) {
+        CreateSharedHandle(out_buffers[max_buf_index], descriptors[i], &out_buffers[i]);
+
+        // since we just created handle out of existing handle add it to map
+        locker_.lock();
+        handles_map_.insert(std::pair<private_handle_t const *, int>(
+            reinterpret_cast<private_handle_t const *>(out_buffers[i]), 1));
+        locker_.unlock();
+      }
+    }
+  } else {
+    // Buffer sharing is not feasible.
+    // Allocate seperate buffer for each descriptor
+    for (i = 0; i < num_descriptors; i++) {
+      if (AllocateBuffer(descriptors[i], &out_buffers[i])) {
+        return GRALLOC1_ERROR_NO_RESOURCES;
+      }
+    }
+  }
+
+  // Allocation is successful. If backstore is not shared inform the client.
+  if (!shared) {
+    return GRALLOC1_ERROR_NOT_SHARED;
+  }
+
+  return status;
+}
+
+void BufferManager::CreateSharedHandle(buffer_handle_t inbuffer, const BufferDescriptor &descriptor,
+                                       buffer_handle_t *outbuffer) {
+  private_handle_t const *input = reinterpret_cast<private_handle_t const *>(inbuffer);
+
+  // Get Buffer attributes or dimension
+  unsigned int alignedw = 0, alignedh = 0;
+  allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
+
+  // create new handle from input reference handle and given descriptor
+  int flags = GetHandleFlags(descriptor.GetFormat(), descriptor.GetProducerUsage(),
+                             descriptor.GetConsumerUsage());
+  int buffer_type = GetBufferType(descriptor.GetFormat());
+
+  // Duplicate the fds
+  private_handle_t *out_hnd = new private_handle_t(
+      dup(input->fd), input->size, flags, buffer_type, descriptor.GetFormat(), INT(alignedw),
+      INT(alignedh), dup(input->fd_metadata), input->offset_metadata, input->base_metadata,
+      descriptor.GetWidth(), descriptor.GetHeight(), descriptor.GetProducerUsage(),
+      descriptor.GetConsumerUsage());
+
+  *outbuffer = out_hnd;
+}
+
+gralloc1_error_t BufferManager::FreeBuffer(private_handle_t const *hnd) {
+  if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
+                             hnd->fd) != 0) {
+    return GRALLOC1_ERROR_BAD_HANDLE;
+  }
+
+  unsigned int meta_size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
+  if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base_metadata), meta_size,
+                             hnd->offset_metadata, hnd->fd_metadata) != 0) {
+    return GRALLOC1_ERROR_BAD_HANDLE;
+  }
+
+  // delete handle also
+  private_handle_t *handle = const_cast<private_handle_t *>(hnd);
+  delete handle;
+
+  return GRALLOC1_ERROR_NONE;
+}
+
+gralloc1_error_t BufferManager::MapBuffer(private_handle_t const *handle) {
+  private_handle_t *hnd = const_cast<private_handle_t *>(handle);
+
+  hnd->base = 0;
+  hnd->base_metadata = 0;
+  if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base), hnd->size, hnd->offset,
+                            hnd->fd) != 0) {
+    return GRALLOC1_ERROR_BAD_HANDLE;
+  }
+
+  unsigned int size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
+  if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base_metadata), size,
+                            hnd->offset_metadata, hnd->fd_metadata) != 0) {
+    return GRALLOC1_ERROR_BAD_HANDLE;
+  }
+
+  return GRALLOC1_ERROR_NONE;
+}
+
+gralloc1_error_t BufferManager::RetainBuffer(private_handle_t const *hnd) {
+  locker_.lock();
+
+  // find if this handle is already in map
+  auto it = handles_map_.find(hnd);
+  if (it != handles_map_.end()) {
+    // It's already in map, Just increment refcnt
+    // No need to mmap the memory.
+    it->second = it->second + 1;
+  } else {
+    // not present in the map. mmap and then add entry to map
+    if (MapBuffer(hnd) == GRALLOC1_ERROR_NONE) {
+      handles_map_.insert(std::pair<private_handle_t const *, int>(hnd, 1));
+    }
+  }
+
+  locker_.unlock();
+  return GRALLOC1_ERROR_NONE;
+}
+
+gralloc1_error_t BufferManager::ReleaseBuffer(private_handle_t const *hnd) {
+  locker_.lock();
+
+  // find if this handle is already in map
+  auto it = handles_map_.find(hnd);
+  if (it == handles_map_.end()) {
+    // Corrupt handle or map.
+    locker_.unlock();
+    return GRALLOC1_ERROR_BAD_HANDLE;
+  } else {
+    it->second = it->second - 1;
+  }
+
+  if (!it->second) {
+    handles_map_.erase(it);
+    FreeBuffer(hnd);
+  }
+
+  locker_.unlock();
+  return GRALLOC1_ERROR_NONE;
+}
+
+gralloc1_error_t BufferManager::LockBuffer(const private_handle_t *hnd,
+                                           gralloc1_producer_usage_t prod_usage,
+                                           gralloc1_consumer_usage_t cons_usage) {
+  gralloc1_error_t err = GRALLOC1_ERROR_NONE;
+
+  // If buffer is not meant for CPU return err
+  if (!CpuCanAccess(prod_usage, cons_usage)) {
+    return GRALLOC1_ERROR_BAD_VALUE;
+  }
+
+  if (hnd->base == 0) {
+    // we need to map for real
+    locker_.lock();
+    err = MapBuffer(hnd);
+    locker_.unlock();
+  }
+
+  // Invalidate if CPU reads in software and there are non-CPU
+  // writers. No need to do this for the metadata buffer as it is
+  // only read/written in software.
+  if (!err && (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) &&
+      (hnd->flags & private_handle_t::PRIV_FLAGS_CACHED)) {
+    if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
+                                hnd->fd, CACHE_INVALIDATE)) {
+      return GRALLOC1_ERROR_BAD_HANDLE;
+    }
+  }
+
+  // Mark the buffer to be flushed after CPU write.
+  if (!err && CpuCanWrite(prod_usage)) {
+    private_handle_t *handle = const_cast<private_handle_t *>(hnd);
+    handle->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
+  }
+
+  return err;
+}
+
+gralloc1_error_t BufferManager::UnlockBuffer(const private_handle_t *handle) {
+  gralloc1_error_t status = GRALLOC1_ERROR_NONE;
+
+  locker_.lock();
+  private_handle_t *hnd = const_cast<private_handle_t *>(handle);
+
+  if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
+    if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
+                                hnd->fd, CACHE_CLEAN) != 0) {
+      status = GRALLOC1_ERROR_BAD_HANDLE;
+    }
+    hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
+  }
+
+  locker_.unlock();
+  return status;
+}
+
+int BufferManager::GetDataAlignment(int format, gralloc1_producer_usage_t prod_usage,
+                                    gralloc1_consumer_usage_t cons_usage) {
+  int align = getpagesize();
+  if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
+    align = 8192;
+  }
+
+  if (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) {
+    if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) {
+      // The alignment here reflects qsee mmu V7L/V8L requirement
+      align = SZ_2M;
+    } else {
+      align = SECURE_ALIGN;
+    }
+  }
+
+  return align;
+}
+
+int BufferManager::GetHandleFlags(int format, gralloc1_producer_usage_t prod_usage,
+                                  gralloc1_consumer_usage_t cons_usage) {
+  int flags = 0;
+  if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_EXTERNAL_ONLY) {
+    flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY;
+  }
+
+  if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_INTERNAL_ONLY) {
+    flags |= private_handle_t::PRIV_FLAGS_INTERNAL_ONLY;
+  }
+
+  if (cons_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) {
+    flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
+  }
+
+  if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
+    flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
+  }
+
+  if (prod_usage & GRALLOC1_CONSUMER_USAGE_CAMERA) {
+    flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
+  }
+
+  if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
+    flags |= private_handle_t::PRIV_FLAGS_HW_COMPOSER;
+  }
+
+  if (prod_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) {
+    flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
+  }
+
+  if (prod_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) {
+    flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
+  }
+
+  if (allocator_->IsMacroTileEnabled(format, prod_usage, cons_usage)) {
+    flags |= private_handle_t::PRIV_FLAGS_TILE_RENDERED;
+  }
+
+  if (allocator_->IsUBwcEnabled(format, prod_usage, cons_usage)) {
+    flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+  }
+
+  if (prod_usage & (GRALLOC1_PRODUCER_USAGE_CPU_READ | GRALLOC1_PRODUCER_USAGE_CPU_WRITE)) {
+    flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
+  }
+
+  // TODO(user): is this correct???
+  if ((cons_usage &
+       (GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER | GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET)) ||
+      (prod_usage & (GRALLOC1_PRODUCER_USAGE_CAMERA | GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET))) {
+    flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
+  }
+
+  if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
+    flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER;
+  }
+
+  if (!allocator_->UseUncached(prod_usage)) {
+    flags |= private_handle_t::PRIV_FLAGS_CACHED;
+  }
+
+  return flags;
+}
+
+int BufferManager::AllocateBuffer(unsigned int size, int aligned_w, int aligned_h, int real_w,
+                                  int real_h, int format, int bufferType,
+                                  gralloc1_producer_usage_t prod_usage,
+                                  gralloc1_consumer_usage_t cons_usage, buffer_handle_t *handle) {
+  int err = 0;
+  int flags = 0;
+  size = ALIGN(size, PAGE_SIZE);
+  AllocData data;
+  data.align = (unsigned int)GetDataAlignment(format, prod_usage, cons_usage);
+  size = ALIGN(size, data.align);
+  data.size = size;
+  data.handle = (uintptr_t)handle;
+
+  // Allocate memory
+  data.uncached = allocator_->UseUncached(prod_usage);
+  err = allocator_->AllocateMem(&data, prod_usage, cons_usage);
+  if (err) {
+    ALOGE("gralloc failed to allocate err=%s", strerror(-err));
+    *handle = 0;
+    return err;
+  }
+
+  // allocate memory for MetaData
+  AllocData e_data;
+  e_data.size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
+  e_data.handle = data.handle;
+  e_data.align = (unsigned int)getpagesize();
+
+  ColorSpace_t colorSpace = ITU_R_601;
+  if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
+    colorSpace = ITU_R_601_FR;
+  }
+
+  err =
+      allocator_->AllocateMem(&e_data, GRALLOC1_PRODUCER_USAGE_NONE, GRALLOC1_CONSUMER_USAGE_NONE);
+  ALOGE_IF(err, "gralloc failed for e_daata error=%s", strerror(-err));
+
+  flags = GetHandleFlags(format, prod_usage, cons_usage);
+  flags |= data.alloc_type;
+
+  // Create handle
+  uint64_t eBaseAddr = (uint64_t)(e_data.base) + e_data.offset;
+  private_handle_t *hnd = new private_handle_t(data.fd, size, flags, bufferType, format, aligned_w,
+                                               aligned_h, e_data.fd, e_data.offset, eBaseAddr,
+                                               real_w, real_h, prod_usage, cons_usage);
+
+  hnd->offset = data.offset;
+  hnd->base = (uint64_t)(data.base) + data.offset;
+  hnd->gpuaddr = 0;
+
+  setMetaData(hnd, UPDATE_COLOR_SPACE, reinterpret_cast<void *>(&colorSpace));
+
+  *handle = hnd;
+
+  // we have just allocated the buffer & mmapped. Add to map
+  locker_.lock();
+  handles_map_.insert(std::pair<private_handle_t const *, int>(hnd, 1));
+  locker_.unlock();
+
+  return err;
+}
+
+int BufferManager::GetBufferType(int inputFormat) {
+  int buffer_type = BUFFER_TYPE_VIDEO;
+  if (IsUncompressedRGBFormat(inputFormat)) {
+    // RGB formats
+    buffer_type = BUFFER_TYPE_UI;
+  }
+
+  return buffer_type;
+}
+
+int BufferManager::AllocateBuffer(const BufferDescriptor &descriptor, buffer_handle_t *handle,
+                                  unsigned int bufferSize) {
+  if (!handle)
+    return -EINVAL;
+
+  int format = descriptor.GetFormat();
+  gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
+  gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
+
+  // Get implementation defined format
+  int gralloc_format = allocator_->GetImplDefinedFormat(prod_usage, cons_usage, format);
+
+  bool use_fb_mem = false;
+  if ((cons_usage & GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET) && map_fb_mem_) {
+    use_fb_mem = true;
+  }
+
+  if ((cons_usage & GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET) && ubwc_for_fb_) {
+    prod_usage =
+        (gralloc1_producer_usage_t)(prod_usage | GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC);
+  }
+
+  unsigned int size;
+  unsigned int alignedw, alignedh;
+  int buffer_type = GetBufferType(gralloc_format);
+  allocator_->GetBufferSizeAndDimensions(descriptor, &size, &alignedw, &alignedh);
+
+  size = (bufferSize >= size) ? bufferSize : size;
+
+  int err = 0;
+  if (use_fb_mem) {
+    // TODO(user): TBD Framebuffer specific implementation in a seperate file/class
+  } else {
+    err = AllocateBuffer(size, INT(alignedw), INT(alignedh), descriptor.GetWidth(),
+                         descriptor.GetHeight(), format, buffer_type, descriptor.GetProducerUsage(),
+                         descriptor.GetConsumerUsage(), handle);
+  }
+
+  if (err < 0) {
+    return err;
+  }
+
+  return 0;
+}
+
+gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
+  switch (operation) {
+    case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER: {
+      int fd = va_arg(args, int);
+      unsigned int size = va_arg(args, unsigned int);
+      unsigned int offset = va_arg(args, unsigned int);
+      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 **);
+      private_handle_t *hnd = reinterpret_cast<private_handle_t *>(
+          native_handle_create(private_handle_t::kNumFds, private_handle_t::NumInts()));
+      if (hnd) {
+        hnd->magic = private_handle_t::kMagic;
+        hnd->fd = fd;
+        hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION;
+        hnd->size = size;
+        hnd->offset = offset;
+        hnd->base = uint64_t(base) + offset;
+        hnd->gpuaddr = 0;
+        hnd->width = width;
+        hnd->height = height;
+        hnd->format = format;
+        *handle = reinterpret_cast<native_handle_t *>(hnd);
+      }
+    } break;
+
+    case GRALLOC_MODULE_PERFORM_GET_STRIDE: {
+      int width = va_arg(args, int);
+      int format = va_arg(args, int);
+      int *stride = va_arg(args, int *);
+      unsigned int alignedw = 0, alignedh = 0;
+      BufferDescriptor descriptor(width, width, format);
+      allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
+      *stride = INT(alignedw);
+    } break;
+
+    case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE: {
+      private_handle_t *hnd = va_arg(args, private_handle_t *);
+      int *stride = va_arg(args, int *);
+      if (private_handle_t::validate(hnd) != 0) {
+        return GRALLOC1_ERROR_BAD_HANDLE;
+      }
+
+      MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
+      if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
+        *stride = metadata->bufferDim.sliceWidth;
+      } else {
+        *stride = hnd->width;
+      }
+    } break;
+
+    // TODO(user) : this alone should be sufficient, ask gfx to get rid of above
+    case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE: {
+      private_handle_t *hnd = va_arg(args, private_handle_t *);
+      int *stride = va_arg(args, int *);
+      int *height = va_arg(args, int *);
+      if (private_handle_t::validate(hnd) != 0) {
+        return GRALLOC1_ERROR_BAD_HANDLE;
+      }
+
+      MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
+      if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
+        *stride = metadata->bufferDim.sliceWidth;
+        *height = metadata->bufferDim.sliceHeight;
+      } else {
+        *stride = hnd->width;
+        *height = hnd->height;
+      }
+    } break;
+
+    case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES: {
+      // TODO(user): Usage is split now. take care of it from Gfx client.
+      // see if we can directly expect descriptor from gfx client.
+      int width = va_arg(args, int);
+      int height = va_arg(args, int);
+      int format = va_arg(args, int);
+      uint64_t producer_usage = va_arg(args, uint64_t);
+      uint64_t consumer_usage = va_arg(args, uint64_t);
+      gralloc1_producer_usage_t prod_usage = static_cast<gralloc1_producer_usage_t>(producer_usage);
+      gralloc1_consumer_usage_t cons_usage = static_cast<gralloc1_consumer_usage_t>(consumer_usage);
+
+      int *aligned_width = va_arg(args, int *);
+      int *aligned_height = va_arg(args, int *);
+      int *tile_enabled = va_arg(args, int *);
+      unsigned int alignedw, alignedh;
+      BufferDescriptor descriptor(width, height, format, prod_usage, cons_usage);
+      *tile_enabled = allocator_->IsUBwcEnabled(format, prod_usage, cons_usage) ||
+                      allocator_->IsMacroTileEnabled(format, prod_usage, cons_usage);
+
+      allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
+      *aligned_width = INT(alignedw);
+      *aligned_height = INT(alignedh);
+    } break;
+
+    case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE: {
+      private_handle_t *hnd = va_arg(args, private_handle_t *);
+      int *color_space = va_arg(args, int *);
+      if (private_handle_t::validate(hnd) != 0) {
+        return GRALLOC1_ERROR_BAD_HANDLE;
+      }
+      MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
+      if (metadata && metadata->operation & UPDATE_COLOR_SPACE) {
+        *color_space = metadata->colorSpace;
+      }
+    } break;
+    case GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO: {
+      private_handle_t *hnd = va_arg(args, private_handle_t *);
+      android_ycbcr *ycbcr = va_arg(args, struct android_ycbcr *);
+      if (private_handle_t::validate(hnd) != 0) {
+        return GRALLOC1_ERROR_BAD_HANDLE;
+      }
+      if (allocator_->GetYUVPlaneInfo(hnd, ycbcr)) {
+        return GRALLOC1_ERROR_UNDEFINED;
+      }
+    } break;
+
+    case GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO: {
+      private_handle_t *hnd = va_arg(args, private_handle_t *);
+      int *map_secure_buffer = va_arg(args, int *);
+      if (private_handle_t::validate(hnd) != 0) {
+        return GRALLOC1_ERROR_BAD_HANDLE;
+      }
+      MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
+      if (metadata && metadata->operation & MAP_SECURE_BUFFER) {
+        *map_secure_buffer = metadata->mapSecureBuffer;
+      } else {
+        *map_secure_buffer = 0;
+      }
+    } break;
+
+    case GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG: {
+      private_handle_t *hnd = va_arg(args, private_handle_t *);
+      int *flag = va_arg(args, int *);
+      if (private_handle_t::validate(hnd) != 0) {
+        return GRALLOC1_ERROR_BAD_HANDLE;
+      }
+      *flag = hnd->flags &private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+    } break;
+
+    case GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS: {
+      private_handle_t *hnd = va_arg(args, private_handle_t *);
+      void **rgb_data = va_arg(args, void **);
+      if (private_handle_t::validate(hnd) != 0) {
+        return GRALLOC1_ERROR_BAD_HANDLE;
+      }
+      if (allocator_->GetRgbDataAddress(hnd, rgb_data)) {
+        return GRALLOC1_ERROR_UNDEFINED;
+      }
+    } break;
+
+    default:
+      break;
+  }
+
+  return GRALLOC1_ERROR_NONE;
+}
+
+}  //  namespace gralloc1
diff --git a/msmcobalt/libgralloc1/gr_buf_mgr.h b/msmcobalt/libgralloc1/gr_buf_mgr.h
new file mode 100644
index 0000000..d3c0e67
--- /dev/null
+++ b/msmcobalt/libgralloc1/gr_buf_mgr.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ *
+ * 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.
+ */
+
+#ifndef __GR_BUF_MGR_H__
+#define __GR_BUF_MGR_H__
+
+#include <pthread.h>
+#include <unordered_map>
+#include <mutex>
+
+#include "gralloc_priv.h"
+#include "gr_allocator.h"
+
+namespace gralloc1 {
+
+class BufferManager {
+ public:
+  BufferManager();
+  ~BufferManager();
+  bool Init();
+  gralloc1_error_t AllocateBuffers(uint32_t numDescriptors, const BufferDescriptor *descriptors,
+                                   buffer_handle_t *outBuffers);
+  gralloc1_error_t RetainBuffer(private_handle_t const *hnd);
+  gralloc1_error_t ReleaseBuffer(private_handle_t const *hnd);
+  gralloc1_error_t LockBuffer(const private_handle_t *hnd, gralloc1_producer_usage_t prod_usage,
+                              gralloc1_consumer_usage_t cons_usage);
+  gralloc1_error_t UnlockBuffer(const private_handle_t *hnd);
+  gralloc1_error_t Perform(int operation, va_list args);
+
+ private:
+  gralloc1_error_t MapBuffer(private_handle_t const *hnd);
+  gralloc1_error_t FreeBuffer(private_handle_t const *hnd);
+  int GetBufferType(int format);
+  int AllocateBuffer(const BufferDescriptor &descriptor, buffer_handle_t *handle,
+                     unsigned int bufferSize = 0);
+  int AllocateBuffer(unsigned int size, int aligned_w, int aligned_h, int real_w, int real_h,
+                     int format, int bufferType, gralloc1_producer_usage_t prod_usage,
+                     gralloc1_consumer_usage_t cons_usage, buffer_handle_t *handle);
+  int GetDataAlignment(int format, gralloc1_producer_usage_t prod_usage,
+                       gralloc1_consumer_usage_t cons_usage);
+  int GetHandleFlags(int format, gralloc1_producer_usage_t prod_usage,
+                     gralloc1_consumer_usage_t cons_usage);
+  void CreateSharedHandle(buffer_handle_t inbuffer, const BufferDescriptor &descriptor,
+                          buffer_handle_t *out_buffer);
+
+  bool map_fb_mem_ = false;
+  bool ubwc_for_fb_ = false;
+  Allocator *allocator_ = NULL;
+  std::mutex locker_;
+  std::unordered_map<private_handle_t const *, int> handles_map_ = {};
+};
+
+}  // namespace gralloc1
+
+#endif  // __GR_BUF_MGR_H__
diff --git a/msmcobalt/libgralloc1/gr_device_impl.cpp b/msmcobalt/libgralloc1/gr_device_impl.cpp
new file mode 100644
index 0000000..6258941
--- /dev/null
+++ b/msmcobalt/libgralloc1/gr_device_impl.cpp
@@ -0,0 +1,458 @@
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <cutils/log.h>
+#include <sync/sync.h>
+
+#include "gr_device_impl.h"
+#include "gr_buf_descriptor.h"
+#include "gralloc_priv.h"
+#include "qd_utils.h"
+#include "qdMetaData.h"
+#include "gr_utils.h"
+
+int gralloc_device_open(const struct hw_module_t *module, const char *name, hw_device_t **device);
+
+int gralloc_device_close(struct hw_device_t *device);
+
+static struct hw_module_methods_t gralloc_module_methods = {.open = gralloc_device_open};
+
+struct hw_module_t gralloc_module = {};
+
+struct private_module_t HAL_MODULE_INFO_SYM = {
+  .base = {
+    .tag = HARDWARE_MODULE_TAG,
+    .version_major = 1,
+    .version_minor = 0,
+    .id = GRALLOC_HARDWARE_MODULE_ID,
+    .name = "Graphics Memory Module",
+    .author = "Code Aurora Forum",
+    .methods = &gralloc_module_methods,
+    .dso = 0,
+    .reserved = {0},
+  },
+};
+
+int gralloc_device_open(const struct hw_module_t *module, const char *name, hw_device_t **device) {
+  int status = -EINVAL;
+  if (!strcmp(name, GRALLOC_HARDWARE_MODULE_ID)) {
+    const private_module_t *m = reinterpret_cast<const private_module_t *>(module);
+    gralloc1::GrallocImpl * /*gralloc1_device_t*/ dev = new gralloc1::GrallocImpl(m);
+    *device = reinterpret_cast<hw_device_t *>(dev);
+
+    if (dev->Init()) {
+      status = 0;
+    } else {
+      ALOGE(" Error in opening gralloc1 device");
+      return status;
+    }
+  }
+
+  return status;
+}
+
+namespace gralloc1 {
+
+GrallocImpl::GrallocImpl(const private_module_t *module) {
+  common.tag = HARDWARE_DEVICE_TAG;
+  common.version = 1;  // TODO(user): cross check version
+  common.module = const_cast<hw_module_t *>(&module->base);
+  common.close = CloseDevice;
+  getFunction = GetFunction;
+  getCapabilities = GetCapabilities;
+}
+
+bool GrallocImpl::Init() {
+  buf_mgr_ = new BufferManager();
+
+  return buf_mgr_->Init();
+}
+
+GrallocImpl::~GrallocImpl() {
+  if (buf_mgr_) {
+    delete buf_mgr_;
+  }
+}
+
+int GrallocImpl::CloseDevice(hw_device_t *device) {
+  GrallocImpl *impl = reinterpret_cast<GrallocImpl *>(device);
+  delete impl;
+
+  return 0;
+}
+
+void GrallocImpl::GetCapabilities(struct gralloc1_device *device, uint32_t *out_count,
+                                  int32_t /*gralloc1_capability_t*/ *out_capabilities) {
+  if (!device) {
+    // Need to plan for adding more capabilities
+    if (out_capabilities == NULL) {
+      *out_count = 1;
+    } else {
+      *out_capabilities = GRALLOC1_CAPABILITY_TEST_ALLOCATE;
+    }
+  }
+
+  return;
+}
+
+gralloc1_function_pointer_t GrallocImpl::GetFunction(gralloc1_device_t *device, int32_t function) {
+  if (!device) {
+    return NULL;
+  }
+
+  switch (function) {
+    case GRALLOC1_FUNCTION_CREATE_DESCRIPTOR:
+      return reinterpret_cast<gralloc1_function_pointer_t>(CreateBufferDescriptor);
+    case GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR:
+      return reinterpret_cast<gralloc1_function_pointer_t>(DestroyBufferDescriptor);
+    case GRALLOC1_FUNCTION_SET_CONSUMER_USAGE:
+      return reinterpret_cast<gralloc1_function_pointer_t>(SetConsumerUsage);
+    case GRALLOC1_FUNCTION_SET_DIMENSIONS:
+      return reinterpret_cast<gralloc1_function_pointer_t>(SetBufferDimensions);
+    case GRALLOC1_FUNCTION_SET_FORMAT:
+      return reinterpret_cast<gralloc1_function_pointer_t>(SetColorFormat);
+    case GRALLOC1_FUNCTION_SET_PRODUCER_USAGE:
+      return reinterpret_cast<gralloc1_function_pointer_t>(SetProducerUsage);
+    case GRALLOC1_FUNCTION_GET_BACKING_STORE:
+      return reinterpret_cast<gralloc1_function_pointer_t>(GetBackingStore);
+    case GRALLOC1_FUNCTION_GET_CONSUMER_USAGE:
+      return reinterpret_cast<gralloc1_function_pointer_t>(GetConsumerUsage);
+    case GRALLOC1_FUNCTION_GET_DIMENSIONS:
+      return reinterpret_cast<gralloc1_function_pointer_t>(GetBufferDimensions);
+    case GRALLOC1_FUNCTION_GET_FORMAT:
+      return reinterpret_cast<gralloc1_function_pointer_t>(GetColorFormat);
+    case GRALLOC1_FUNCTION_GET_PRODUCER_USAGE:
+      return reinterpret_cast<gralloc1_function_pointer_t>(GetProducerUsage);
+    case GRALLOC1_FUNCTION_GET_STRIDE:
+      return reinterpret_cast<gralloc1_function_pointer_t>(GetBufferStride);
+    case GRALLOC1_FUNCTION_ALLOCATE:
+      return reinterpret_cast<gralloc1_function_pointer_t>(AllocateBuffers);
+    case GRALLOC1_FUNCTION_RETAIN:
+      return reinterpret_cast<gralloc1_function_pointer_t>(RetainBuffer);
+    case GRALLOC1_FUNCTION_RELEASE:
+      return reinterpret_cast<gralloc1_function_pointer_t>(ReleaseBuffer);
+    /*  TODO(user) :definition of flex plane is not known yet
+     *  Need to implement after clarification from Google.
+    * case GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES:
+      return reinterpret_cast<gralloc1_function_pointer_t> (; */
+    case GRALLOC1_FUNCTION_LOCK:
+      return reinterpret_cast<gralloc1_function_pointer_t>(LockBuffer);
+    /*  TODO(user) : LOCK_YCBCR changed to LOCK_FLEX but structure is not known yet.
+     *  Need to implement after clarification from Google.
+    case GRALLOC1_PFN_LOCK_FLEX:
+      return reinterpret_cast<gralloc1_function_pointer_t> (LockYCbCrBuffer;
+    */
+    case GRALLOC1_FUNCTION_UNLOCK:
+      return reinterpret_cast<gralloc1_function_pointer_t>(UnlockBuffer);
+    case GRALLOC1_FUNCTION_PERFORM:
+      return reinterpret_cast<gralloc1_function_pointer_t>(Gralloc1Perform);
+    default:
+      ALOGE("%s:Gralloc Error. Client Requested for unsupported function", __FUNCTION__);
+      return NULL;
+  }
+
+  return NULL;
+}
+
+gralloc1_error_t GrallocImpl::CheckDeviceAndDescriptor(gralloc1_device_t *device,
+                                                       gralloc1_buffer_descriptor_t descriptor) {
+  if (!device || !BUF_DESCRIPTOR(descriptor)->IsValid()) {
+    ALOGE("Gralloc Error : device=%p, descriptor=%p", (void *)device, (void *)descriptor);
+    return GRALLOC1_ERROR_BAD_DESCRIPTOR;
+  }
+
+  return GRALLOC1_ERROR_NONE;
+}
+
+gralloc1_error_t GrallocImpl::CheckDeviceAndHandle(gralloc1_device_t *device,
+                                                   buffer_handle_t buffer) {
+  const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
+  if (!device || (private_handle_t::validate(hnd) != 0)) {
+    ALOGE("Gralloc Error : device= %p, buffer-handle=%p", (void *)device, (void *)buffer);
+    return GRALLOC1_ERROR_BAD_HANDLE;
+  }
+
+  return GRALLOC1_ERROR_NONE;
+}
+
+gralloc1_error_t GrallocImpl::CreateBufferDescriptor(gralloc1_device_t *device,
+                                                     gralloc1_buffer_descriptor_t *out_descriptor) {
+  if (!device) {
+    return GRALLOC1_ERROR_BAD_DESCRIPTOR;
+  }
+
+  BufferDescriptor *descriptor = new BufferDescriptor();
+  if (descriptor == NULL) {
+    return GRALLOC1_ERROR_NO_RESOURCES;
+  }
+
+  *out_descriptor = reinterpret_cast<gralloc1_buffer_descriptor_t>(descriptor);
+
+  return GRALLOC1_ERROR_NONE;
+}
+
+gralloc1_error_t GrallocImpl::DestroyBufferDescriptor(gralloc1_device_t *device,
+                                                      gralloc1_buffer_descriptor_t descriptor) {
+  gralloc1_error_t status = CheckDeviceAndDescriptor(device, descriptor);
+  if (status == GRALLOC1_ERROR_NONE) {
+    delete reinterpret_cast<BufferDescriptor *>(descriptor);
+  }
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::SetConsumerUsage(gralloc1_device_t *device,
+                                               gralloc1_buffer_descriptor_t descriptor,
+                                               gralloc1_consumer_usage_t usage) {
+  gralloc1_error_t status = CheckDeviceAndDescriptor(device, descriptor);
+  if (status == GRALLOC1_ERROR_NONE) {
+    BUF_DESCRIPTOR(descriptor)->SetConsumerUsage(usage);
+  }
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::SetBufferDimensions(gralloc1_device_t *device,
+                                                  gralloc1_buffer_descriptor_t descriptor,
+                                                  uint32_t width, uint32_t height) {
+  gralloc1_error_t status = CheckDeviceAndDescriptor(device, descriptor);
+  if (status == GRALLOC1_ERROR_NONE) {
+    BUF_DESCRIPTOR(descriptor)->SetDimensions(INT(width), INT(height));
+  }
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::SetColorFormat(gralloc1_device_t *device,
+                                             gralloc1_buffer_descriptor_t descriptor,
+                                             int32_t format) {
+  gralloc1_error_t status = CheckDeviceAndDescriptor(device, descriptor);
+  if (status == GRALLOC1_ERROR_NONE) {
+    BUF_DESCRIPTOR(descriptor)->SetColorFormat(format);
+  }
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::SetProducerUsage(gralloc1_device_t *device,
+                                               gralloc1_buffer_descriptor_t descriptor,
+                                               gralloc1_producer_usage_t usage) {
+  gralloc1_error_t status = CheckDeviceAndDescriptor(device, descriptor);
+  if (status == GRALLOC1_ERROR_NONE) {
+    BUF_DESCRIPTOR(descriptor)->SetProducerUsage(usage);
+  }
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::GetBackingStore(gralloc1_device_t *device, buffer_handle_t buffer,
+                                              gralloc1_backing_store_t *out_backstore) {
+  if (!device || !buffer) {
+    return GRALLOC1_ERROR_BAD_HANDLE;
+  }
+
+  *out_backstore =
+      static_cast<gralloc1_backing_store_t>(PRIV_HANDLE_CONST(buffer)->GetBackingstore());
+
+  return GRALLOC1_ERROR_NONE;
+}
+
+gralloc1_error_t GrallocImpl::GetConsumerUsage(gralloc1_device_t *device, buffer_handle_t buffer,
+                                               gralloc1_consumer_usage_t *outUsage) {
+  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
+  if (status == GRALLOC1_ERROR_NONE) {
+    *outUsage = PRIV_HANDLE_CONST(buffer)->GetConsumerUsage();
+  }
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::GetBufferDimensions(gralloc1_device_t *device, buffer_handle_t buffer,
+                                                  uint32_t *outWidth, uint32_t *outHeight) {
+  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
+  if (status == GRALLOC1_ERROR_NONE) {
+    const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
+    *outWidth = UINT(hnd->GetRealWidth());
+    *outHeight = UINT(hnd->GetRealHeight());
+  }
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::GetColorFormat(gralloc1_device_t *device, buffer_handle_t buffer,
+                                             int32_t *outFormat) {
+  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
+  if (status == GRALLOC1_ERROR_NONE) {
+    *outFormat = PRIV_HANDLE_CONST(buffer)->GetColorFormat();
+  }
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::GetProducerUsage(gralloc1_device_t *device, buffer_handle_t buffer,
+                                               gralloc1_producer_usage_t *outUsage) {
+  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
+  if (status == GRALLOC1_ERROR_NONE) {
+    const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
+    *outUsage = hnd->GetProducerUsage();
+  }
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::GetBufferStride(gralloc1_device_t *device, buffer_handle_t buffer,
+                                              uint32_t *outStride) {
+  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
+  if (status == GRALLOC1_ERROR_NONE) {
+    *outStride = UINT(PRIV_HANDLE_CONST(buffer)->GetStride());
+  }
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::AllocateBuffers(gralloc1_device_t *device, uint32_t num_dptors,
+                                              const gralloc1_buffer_descriptor_t *dptors,
+                                              buffer_handle_t *outBuffers) {
+  if (!num_dptors || !dptors) {
+    return GRALLOC1_ERROR_BAD_DESCRIPTOR;
+  }
+
+  GrallocImpl const *dev = GRALLOC_IMPL(device);
+  const BufferDescriptor *descriptors = reinterpret_cast<const BufferDescriptor *>(dptors);
+  gralloc1_error_t status = dev->buf_mgr_->AllocateBuffers(num_dptors, descriptors, outBuffers);
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::RetainBuffer(gralloc1_device_t *device, buffer_handle_t buffer) {
+  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
+  if (status == GRALLOC1_ERROR_NONE) {
+    const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
+    GrallocImpl const *dev = GRALLOC_IMPL(device);
+    status = dev->buf_mgr_->RetainBuffer(hnd);
+  }
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::ReleaseBuffer(gralloc1_device_t *device, buffer_handle_t buffer) {
+  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
+  if (status == GRALLOC1_ERROR_NONE) {
+    const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
+    GrallocImpl const *dev = GRALLOC_IMPL(device);
+    status = dev->buf_mgr_->ReleaseBuffer(hnd);
+  }
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::LockBuffer(gralloc1_device_t *device, buffer_handle_t buffer,
+                                         gralloc1_producer_usage_t prod_usage,
+                                         gralloc1_consumer_usage_t cons_usage,
+                                         const gralloc1_rect_t *region, void **out_data,
+                                         int32_t acquire_fence) {
+  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
+  if (status == GRALLOC1_ERROR_NONE && (acquire_fence > 0)) {
+    int error = sync_wait(acquire_fence, 1000);
+    if (error < 0) {
+      ALOGE("%s: sync_wait timedout! error = %s", __FUNCTION__, strerror(errno));
+      return GRALLOC1_ERROR_UNDEFINED;
+    }
+  }
+
+  const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
+  GrallocImpl const *dev = GRALLOC_IMPL(device);
+
+  // Either producer usage or consumer usage must be *_USAGE_NONE
+  if ((prod_usage != GRALLOC1_PRODUCER_USAGE_NONE) &&
+      (cons_usage != GRALLOC1_CONSUMER_USAGE_NONE)) {
+    return GRALLOC1_ERROR_BAD_VALUE;
+  }
+
+  // currently we ignore the region/rect client wants to lock
+  if (region == NULL) {
+    return GRALLOC1_ERROR_BAD_VALUE;
+  }
+
+  status = dev->buf_mgr_->LockBuffer(hnd, prod_usage, cons_usage);
+
+  *out_data = reinterpret_cast<void *>(hnd->base);
+
+  return status;
+}
+
+/*  TODO(user) : LOCK_YCBCR changed to LOCK_FLEX but structure definition is not known yet.
+ *  Need to implement after clarification from Google.
+gralloc1_error_t GrallocImpl::LockYCbCrBuffer(gralloc1_device_t* device, buffer_handle_t buffer,
+    gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage,
+    const gralloc1_rect_t* region, struct android_ycbcr* outYCbCr, int32_t* outAcquireFence) {
+  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
+
+  if (status == GRALLOC1_ERROR_NONE) {
+    void **outData = 0;
+    status = LockBuffer(device, buffer, prod_usage, cons_usage, region, outData, outAcquireFence);
+  }
+
+  if (status == GRALLOC1_ERROR_NONE) {
+    const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
+    GrallocImpl const *dev = GRALLOC_IMPL(device);
+    dev->allocator_->GetYUVPlaneInfo(hnd, outYCbCr);
+  }
+
+  return status;
+}
+ */
+
+gralloc1_error_t GrallocImpl::UnlockBuffer(gralloc1_device_t *device, buffer_handle_t buffer,
+                                           int32_t *release_fence) {
+  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
+
+  if (status != GRALLOC1_ERROR_NONE) {
+    return status;
+  }
+
+  const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
+  GrallocImpl const *dev = GRALLOC_IMPL(device);
+
+  *release_fence = -1;
+
+  return dev->buf_mgr_->UnlockBuffer(hnd);
+}
+
+gralloc1_error_t GrallocImpl::Gralloc1Perform(gralloc1_device_t *device, int operation, ...) {
+  va_list args;
+  va_start(args, operation);
+  GrallocImpl const *dev = GRALLOC_IMPL(device);
+  gralloc1_error_t err = dev->buf_mgr_->Perform(operation, args);
+  va_end(args);
+
+  return err;
+}
+
+}  // namespace gralloc1
diff --git a/msmcobalt/libgralloc1/gr_device_impl.h b/msmcobalt/libgralloc1/gr_device_impl.h
new file mode 100644
index 0000000..4fc8e3c
--- /dev/null
+++ b/msmcobalt/libgralloc1/gr_device_impl.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __GR_DEVICE_IMPL_H__
+#define __GR_DEVICE_IMPL_H__
+
+#include <hardware/hardware.h>
+#include <hardware/gralloc1.h>
+#include "gr_buf_mgr.h"
+
+struct private_module_t {
+  hw_module_t base;
+};
+
+#define GRALLOC_IMPL(exp) reinterpret_cast<GrallocImpl const *>(exp)
+
+namespace gralloc1 {
+
+class GrallocImpl : public gralloc1_device_t {
+ public:
+  explicit GrallocImpl(const private_module_t *module);
+  ~GrallocImpl();
+  bool Init();
+  static int CloseDevice(hw_device_t *device);
+  static void GetCapabilities(struct gralloc1_device *device, uint32_t *out_count,
+                              int32_t * /*gralloc1_capability_t*/ out_capabilities);
+  static gralloc1_function_pointer_t GetFunction(
+      struct gralloc1_device *device, int32_t /*gralloc1_function_descriptor_t*/ descriptor);
+
+ private:
+  static inline gralloc1_error_t CheckDeviceAndDescriptor(gralloc1_device_t *device,
+                                                          gralloc1_buffer_descriptor_t descriptor);
+  static inline gralloc1_error_t CheckDeviceAndHandle(gralloc1_device_t *device,
+                                                      buffer_handle_t buffer);
+  static gralloc1_error_t CreateBufferDescriptor(gralloc1_device_t *device,
+                                                 gralloc1_buffer_descriptor_t *out_descriptor);
+  static gralloc1_error_t DestroyBufferDescriptor(gralloc1_device_t *device,
+                                                  gralloc1_buffer_descriptor_t descriptor);
+  static gralloc1_error_t SetConsumerUsage(gralloc1_device_t *device,
+                                           gralloc1_buffer_descriptor_t descriptor,
+                                           gralloc1_consumer_usage_t usage);
+  static gralloc1_error_t SetBufferDimensions(gralloc1_device_t *device,
+                                              gralloc1_buffer_descriptor_t descriptor,
+                                              uint32_t width, uint32_t height);
+  static gralloc1_error_t SetColorFormat(gralloc1_device_t *device,
+                                         gralloc1_buffer_descriptor_t descriptor, int32_t format);
+  static gralloc1_error_t SetProducerUsage(gralloc1_device_t *device,
+                                           gralloc1_buffer_descriptor_t descriptor,
+                                           gralloc1_producer_usage_t usage);
+  static gralloc1_error_t GetBackingStore(gralloc1_device_t *device, buffer_handle_t buffer,
+                                          gralloc1_backing_store_t *out_store);
+  static gralloc1_error_t GetConsumerUsage(gralloc1_device_t *device, buffer_handle_t buffer,
+                                           gralloc1_consumer_usage_t *out_usage);
+  static gralloc1_error_t GetBufferDimensions(gralloc1_device_t *device, buffer_handle_t buffer,
+                                              uint32_t *out_width, uint32_t *out_height);
+  static gralloc1_error_t GetColorFormat(gralloc1_device_t *device, buffer_handle_t descriptor,
+                                         int32_t *outFormat);
+  static gralloc1_error_t GetProducerUsage(gralloc1_device_t *device, buffer_handle_t buffer,
+                                           gralloc1_producer_usage_t *out_usage);
+  static gralloc1_error_t GetBufferStride(gralloc1_device_t *device, buffer_handle_t buffer,
+                                          uint32_t *out_stride);
+  static gralloc1_error_t AllocateBuffers(gralloc1_device_t *device, uint32_t num_dptors,
+                                          const gralloc1_buffer_descriptor_t *descriptors,
+                                          buffer_handle_t *out_buffers);
+  static gralloc1_error_t RetainBuffer(gralloc1_device_t *device, buffer_handle_t buffer);
+  static gralloc1_error_t ReleaseBuffer(gralloc1_device_t *device, buffer_handle_t buffer);
+  static gralloc1_error_t getNumFlexPlanes(gralloc1_device_t *device, buffer_handle_t buffer,
+                                           uint32_t *out_num_planes);
+  static gralloc1_error_t LockBuffer(gralloc1_device_t *device, buffer_handle_t buffer,
+                                     gralloc1_producer_usage_t prod_usage,
+                                     gralloc1_consumer_usage_t cons_usage,
+                                     const gralloc1_rect_t *access_region, void **out_data,
+                                     int32_t acquire_fence);
+  static gralloc1_error_t LockFlex(gralloc1_device_t *device, buffer_handle_t buffer,
+                                   gralloc1_producer_usage_t prod_usage,
+                                   gralloc1_consumer_usage_t cons_usage,
+                                   const gralloc1_rect_t *access_region,
+                                   struct android_flex_layout *out_flex_layout,
+                                   int32_t acquireFence);
+  /*  TODO(user) : LOCK_YCBCR changed to LOCK_FLEX but structure is not known yet.
+   *  Need to implement after clarification from Google.
+  static gralloc1_error_t LockYCbCrBuffer(gralloc1_device_t* device, buffer_handle_t buffer,
+      gralloc1_producer_usage_t producerUsage, gralloc1_consumer_usage_t consumerUsage,
+      const gralloc1_rect_t* Region, struct android_ycbcr* outYCbCr, int32_t* outAcquireFence);
+   */
+  static gralloc1_error_t UnlockBuffer(gralloc1_device_t *device, buffer_handle_t buffer,
+                                       int32_t *release_fence);
+  static gralloc1_error_t Gralloc1Perform(gralloc1_device_t *device, int operation, ...);
+
+  BufferManager *buf_mgr_ = NULL;
+};
+
+}  // namespace gralloc1
+
+#endif  // __GR_DEVICE_IMPL_H__
diff --git a/msmcobalt/libgralloc1/gr_ion_alloc.cpp b/msmcobalt/libgralloc1/gr_ion_alloc.cpp
new file mode 100644
index 0000000..ca93a63
--- /dev/null
+++ b/msmcobalt/libgralloc1/gr_ion_alloc.cpp
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define DEBUG 0
+#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <cutils/log.h>
+#include <errno.h>
+#include <utils/Trace.h>
+
+#include "gralloc_priv.h"
+#include "gr_utils.h"
+#include "gr_ion_alloc.h"
+
+namespace gralloc1 {
+
+bool IonAlloc::Init() {
+  if (ion_dev_fd_ == FD_INIT) {
+    ion_dev_fd_ = open(kIonDevice, O_RDONLY);
+  }
+
+  if (ion_dev_fd_ < 0) {
+    ALOGE("%s: Failed to open ion device - %s", __FUNCTION__, strerror(errno));
+    ion_dev_fd_ = FD_INIT;
+    return false;
+  }
+
+  return true;
+}
+
+void IonAlloc::CloseIonDevice() {
+  if (ion_dev_fd_ > FD_INIT) {
+    close(ion_dev_fd_);
+  }
+
+  ion_dev_fd_ = FD_INIT;
+}
+
+int IonAlloc::AllocBuffer(AllocData *data) {
+  ATRACE_CALL();
+  int err = 0;
+  struct ion_handle_data handle_data;
+  struct ion_fd_data fd_data;
+  struct ion_allocation_data ion_alloc_data;
+  void *base = NULL;
+
+  ion_alloc_data.len = data->size;
+  ion_alloc_data.align = data->align;
+  ion_alloc_data.heap_id_mask = data->heap_id;
+  ion_alloc_data.flags = data->flags;
+  ion_alloc_data.flags |= data->uncached ? 0 : ION_FLAG_CACHED;
+
+  if (ioctl(ion_dev_fd_, INT(ION_IOC_ALLOC), &ion_alloc_data)) {
+    err = -errno;
+    ALOGE("ION_IOC_ALLOC failed with error - %s", strerror(errno));
+    return err;
+  }
+
+  fd_data.handle = ion_alloc_data.handle;
+  handle_data.handle = ion_alloc_data.handle;
+  if (ioctl(ion_dev_fd_, INT(ION_IOC_MAP), &fd_data)) {
+    err = -errno;
+    ALOGE("%s: ION_IOC_MAP failed with error - %s", __FUNCTION__, strerror(errno));
+    ioctl(ion_dev_fd_, INT(ION_IOC_FREE), &handle_data);
+    return err;
+  }
+
+  if (!(INT(data->flags) & INT(ION_SECURE))) {
+    base = mmap(0, ion_alloc_data.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(ion_dev_fd_, INT(ION_IOC_FREE), &handle_data);
+      return err;
+    }
+  }
+
+  data->base = base;
+  data->fd = fd_data.fd;
+  ioctl(ion_dev_fd_, INT(ION_IOC_FREE), &handle_data);
+  ALOGD_IF(DEBUG, "ion: Allocated buffer base:%p size:%zu fd:%d", data->base, ion_alloc_data.len,
+           data->fd);
+
+  return 0;
+}
+
+int IonAlloc::FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd) {
+  ATRACE_CALL();
+  int err = 0;
+  ALOGD_IF(DEBUG, "ion: Freeing buffer base:%p size:%u fd:%d", base, size, fd);
+
+  if (base) {
+    err = UnmapBuffer(base, size, offset);
+  }
+  close(fd);
+
+  return err;
+}
+
+int IonAlloc::MapBuffer(void **base, unsigned int size, unsigned int offset, int fd) {
+  ATRACE_CALL();
+  int err = 0;
+  void *addr = 0;
+
+  // It is a (quirky) requirement of ION to have opened the
+  // ion fd in the process that is doing the mapping
+  addr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+  *base = addr;
+  if (addr == MAP_FAILED) {
+    err = -errno;
+    ALOGE("ion: Failed to map memory in the client: %s", strerror(errno));
+  } else {
+    ALOGD_IF(DEBUG, "ion: Mapped buffer base:%p size:%u offset:%u fd:%d", addr, size, offset, fd);
+  }
+
+  return err;
+}
+
+int IonAlloc::UnmapBuffer(void *base, unsigned int size, unsigned int /*offset*/) {
+  ATRACE_CALL();
+  ALOGD_IF(DEBUG, "ion: Unmapping buffer  base:%p size:%u", 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::CleanBuffer(void *base, unsigned int size, unsigned int offset, int fd, int op) {
+  ATRACE_CALL();
+  ATRACE_INT("operation id", op);
+  struct ion_flush_data flush_data;
+  struct ion_fd_data fd_data;
+  struct ion_handle_data handle_data;
+  int err = 0;
+
+  fd_data.fd = fd;
+  if (ioctl(ion_dev_fd_, INT(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;
+  // offset and length are unsigned int
+  flush_data.offset = offset;
+  flush_data.length = size;
+
+  struct ion_custom_data d;
+  switch (op) {
+    case CACHE_CLEAN:
+      d.cmd = ION_IOC_CLEAN_CACHES;
+      break;
+    case CACHE_INVALIDATE:
+      d.cmd = ION_IOC_INV_CACHES;
+      break;
+    case CACHE_CLEAN_AND_INVALIDATE:
+    default:
+      d.cmd = ION_IOC_CLEAN_INV_CACHES;
+  }
+
+  d.arg = (unsigned long)(&flush_data);  // NOLINT
+  if (ioctl(ion_dev_fd_, INT(ION_IOC_CUSTOM), &d)) {
+    err = -errno;
+    ALOGE("%s: ION_IOC_CLEAN_INV_CACHES failed with error - %s", __FUNCTION__, strerror(errno));
+    ioctl(ion_dev_fd_, INT(ION_IOC_FREE), &handle_data);
+    return err;
+  }
+
+  ioctl(ion_dev_fd_, INT(ION_IOC_FREE), &handle_data);
+
+  return 0;
+}
+
+}  // namespace gralloc1
diff --git a/msmcobalt/libgralloc1/gr_ion_alloc.h b/msmcobalt/libgralloc1/gr_ion_alloc.h
new file mode 100644
index 0000000..baef8aa
--- /dev/null
+++ b/msmcobalt/libgralloc1/gr_ion_alloc.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __GR_ION_ALLOC_H__
+#define __GR_ION_ALLOC_H__
+
+#include <linux/msm_ion.h>
+
+#define FD_INIT -1
+
+namespace gralloc1 {
+
+enum {
+  CACHE_CLEAN = 0x1,
+  CACHE_INVALIDATE,
+  CACHE_CLEAN_AND_INVALIDATE,
+};
+
+struct AllocData {
+  void *base = NULL;
+  int fd = -1;
+  unsigned int offset = 0;
+  unsigned int size = 0;
+  unsigned int align = 1;
+  uintptr_t handle = 0;
+  bool uncached = false;
+  unsigned int flags = 0x0;
+  unsigned int heap_id = 0x0;
+  unsigned int alloc_type = 0x0;
+};
+
+class IonAlloc {
+ public:
+  IonAlloc() { ion_dev_fd_ = FD_INIT; }
+
+  ~IonAlloc() { CloseIonDevice(); }
+
+  bool Init();
+  int AllocBuffer(AllocData *data);
+  int FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd);
+  int MapBuffer(void **base, unsigned int size, unsigned int offset, int fd);
+  int UnmapBuffer(void *base, unsigned int size, unsigned int offset);
+  int CleanBuffer(void *base, unsigned int size, unsigned int offset, int fd, int op);
+
+ private:
+  const char *kIonDevice = "/dev/ion";
+
+  int OpenIonDevice();
+  void CloseIonDevice();
+
+  int ion_dev_fd_;
+};
+
+}  // namespace gralloc1
+
+#endif  // __GR_ION_ALLOC_H__
diff --git a/msmcobalt/libgralloc1/gr_priv_handle.h b/msmcobalt/libgralloc1/gr_priv_handle.h
new file mode 100644
index 0000000..444fc80
--- /dev/null
+++ b/msmcobalt/libgralloc1/gr_priv_handle.h
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ *
+ * 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.
+ */
+
+#ifndef __GR_PRIV_HANDLE_H__
+#define __GR_PRIV_HANDLE_H__
+
+#include <cutils/log.h>
+#include <hardware/gralloc1.h>
+
+#define GRALLOC1_FUNCTION_PERFORM 0x00001000
+
+#define DBG_HANDLE false
+
+typedef gralloc1_error_t (*GRALLOC1_PFN_PERFORM)(gralloc1_device_t *device, int operation, ...);
+
+typedef int BackStoreFd;
+
+#define PRIV_HANDLE_CONST(exp) static_cast<const private_handle_t *>(exp)
+
+struct private_handle_t : public native_handle_t {
+  // TODO(user): Moving PRIV_FLAGS to #defs & check for each PRIV_FLAG and remove unused.
+  enum {
+    PRIV_FLAGS_FRAMEBUFFER = 0x00000001,
+    PRIV_FLAGS_USES_ION = 0x00000008,
+    PRIV_FLAGS_USES_ASHMEM = 0x00000010,
+    PRIV_FLAGS_NEEDS_FLUSH = 0x00000020,
+    PRIV_FLAGS_INTERNAL_ONLY = 0x00000040,
+    PRIV_FLAGS_NON_CPU_WRITER = 0x00000080,
+    PRIV_FLAGS_NONCONTIGUOUS_MEM = 0x00000100,
+    PRIV_FLAGS_CACHED = 0x00000200,
+    PRIV_FLAGS_SECURE_BUFFER = 0x00000400,
+    PRIV_FLAGS_EXTERNAL_ONLY = 0x00002000,
+    PRIV_FLAGS_PROTECTED_BUFFER = 0x00004000,
+    PRIV_FLAGS_VIDEO_ENCODER = 0x00010000,
+    PRIV_FLAGS_CAMERA_WRITE = 0x00020000,
+    PRIV_FLAGS_CAMERA_READ = 0x00040000,
+    PRIV_FLAGS_HW_COMPOSER = 0x00080000,
+    PRIV_FLAGS_HW_TEXTURE = 0x00100000,
+    PRIV_FLAGS_ITU_R_601 = 0x00200000,     // Unused from display
+    PRIV_FLAGS_ITU_R_601_FR = 0x00400000,  // Unused from display
+    PRIV_FLAGS_ITU_R_709 = 0x00800000,     // Unused from display
+    PRIV_FLAGS_SECURE_DISPLAY = 0x01000000,
+    PRIV_FLAGS_TILE_RENDERED = 0x02000000,
+    PRIV_FLAGS_CPU_RENDERED = 0x04000000,
+    PRIV_FLAGS_UBWC_ALIGNED = 0x08000000,
+    PRIV_FLAGS_DISP_CONSUMER = 0x10000000
+  };
+
+  // file-descriptors
+  int fd;
+  int fd_metadata;
+
+  // ints
+  int magic;
+  int flags;
+  unsigned int size;
+  unsigned int offset;
+  int buffer_type;
+  uint64_t base __attribute__((aligned(8)));
+  unsigned int offset_metadata;
+
+  // The gpu address mapped into the mmu.
+  uint64_t gpuaddr __attribute__((aligned(8)));
+
+  int format;
+  int width;   // holds width of the actual buffer allocated
+  int height;  // holds height of the  actual buffer allocated
+
+  int stride;
+  uint64_t base_metadata __attribute__((aligned(8)));
+
+  // added for gralloc1
+  int real_width;   // holds width client asked to allocate
+  int real_height;  // holds height client asked to allocate// holds width client asked to allocate
+  gralloc1_producer_usage_t producer_usage __attribute__((aligned(8)));
+  gralloc1_consumer_usage_t consumer_usage __attribute__((aligned(8)));
+
+  static const int kNumFds = 2;
+  static const int kMagic = 'gmsm';
+
+  static inline int NumInts() {
+    return ((sizeof(private_handle_t) - sizeof(native_handle_t)) / sizeof(int)) - kNumFds;
+  }
+
+  private_handle_t(int fd, unsigned int size, int flags, int buf_type, int format, int width,
+                   int height, int meta_fd = -1, unsigned int meta_offset = 0,
+                   uint64_t meta_base = 0, int rw = 0, int rh = 0,
+                   gralloc1_producer_usage_t prod_usage = GRALLOC1_PRODUCER_USAGE_NONE,
+                   gralloc1_consumer_usage_t cons_usage = GRALLOC1_CONSUMER_USAGE_NONE)
+      : fd(fd),
+        fd_metadata(meta_fd),
+        magic(kMagic),
+        flags(flags),
+        size(size),
+        offset(0),
+        buffer_type(buf_type),
+        base(0),
+        offset_metadata(meta_offset),
+        gpuaddr(0),
+        format(format),
+        width(width),
+        height(height),
+        base_metadata(meta_base),
+        real_width(rw),
+        real_height(rh),
+        producer_usage(prod_usage),
+        consumer_usage(cons_usage) {
+    version = static_cast<int>(sizeof(native_handle));
+    numInts = NumInts();
+    numFds = kNumFds;
+  }
+
+  ~private_handle_t() {
+    magic = 0;
+    ALOGE_IF(DBG_HANDLE, "deleting buffer handle %p", this);
+  }
+
+  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 != NumInts() ||
+        h->numFds != kNumFds || hnd->magic != kMagic) {
+      ALOGE(
+          "Invalid gralloc handle (at %p): ver(%d/%zu) ints(%d/%d) fds(%d/%d) "
+          "magic(%c%c%c%c/%c%c%c%c)",
+          h, h ? h->version : -1, sizeof(native_handle), h ? h->numInts : -1, NumInts(),
+          h ? h->numFds : -1, kNumFds,
+          hnd ? (((hnd->magic >> 24) & 0xFF) ? ((hnd->magic >> 24) & 0xFF) : '-') : '?',
+          hnd ? (((hnd->magic >> 16) & 0xFF) ? ((hnd->magic >> 16) & 0xFF) : '-') : '?',
+          hnd ? (((hnd->magic >> 8) & 0xFF) ? ((hnd->magic >> 8) & 0xFF) : '-') : '?',
+          hnd ? (((hnd->magic >> 0) & 0xFF) ? ((hnd->magic >> 0) & 0xFF) : '-') : '?',
+          (kMagic >> 24) & 0xFF, (kMagic >> 16) & 0xFF, (kMagic >> 8) & 0xFF, (kMagic >> 0) & 0xFF);
+      return -EINVAL;
+    }
+
+    return 0;
+  }
+
+  int GetRealWidth() const { return real_width; }
+
+  int GetRealHeight() const { return real_height; }
+
+  int GetColorFormat() const { return format; }
+
+  int GetStride() const {
+    // In handle we are storing aligned width after allocation.
+    // Why GetWidth & GetStride?? Are we supposed to maintain unaligned values??
+    return width;
+  }
+
+  gralloc1_consumer_usage_t GetConsumerUsage() const { return consumer_usage; }
+
+  gralloc1_producer_usage_t GetProducerUsage() const { return producer_usage; }
+
+  BackStoreFd GetBackingstore() const { return fd; }
+};
+
+#endif  // __GR_PRIV_HANDLE_H__
diff --git a/msmcobalt/libgralloc1/gr_utils.cpp b/msmcobalt/libgralloc1/gr_utils.cpp
new file mode 100644
index 0000000..98b6889
--- /dev/null
+++ b/msmcobalt/libgralloc1/gr_utils.cpp
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "gr_utils.h"
+
+namespace gralloc1 {
+
+bool IsUncompressedRGBFormat(int format) {
+  switch (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_BGR_565:
+    case HAL_PIXEL_FORMAT_BGRA_8888:
+    case HAL_PIXEL_FORMAT_RGBA_5551:
+    case HAL_PIXEL_FORMAT_RGBA_4444:
+    case HAL_PIXEL_FORMAT_R_8:
+    case HAL_PIXEL_FORMAT_RG_88:
+    case HAL_PIXEL_FORMAT_BGRX_8888:
+    case HAL_PIXEL_FORMAT_RGBA_1010102:
+    case HAL_PIXEL_FORMAT_ARGB_2101010:
+    case HAL_PIXEL_FORMAT_RGBX_1010102:
+    case HAL_PIXEL_FORMAT_XRGB_2101010:
+    case HAL_PIXEL_FORMAT_BGRA_1010102:
+    case HAL_PIXEL_FORMAT_ABGR_2101010:
+    case HAL_PIXEL_FORMAT_BGRX_1010102:
+    case HAL_PIXEL_FORMAT_XBGR_2101010:
+      return true;
+    default:
+      break;
+  }
+
+  return false;
+}
+
+bool IsCompressedRGBFormat(int format) {
+  switch (format) {
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
+      return true;
+    default:
+      break;
+  }
+
+  return false;
+}
+
+uint32_t GetBppForUncompressedRGB(int format) {
+  uint32_t bpp = 0;
+  switch (format) {
+    case HAL_PIXEL_FORMAT_RGBA_8888:
+    case HAL_PIXEL_FORMAT_RGBX_8888:
+    case HAL_PIXEL_FORMAT_BGRA_8888:
+    case HAL_PIXEL_FORMAT_BGRX_8888:
+      bpp = 4;
+      break;
+    case HAL_PIXEL_FORMAT_RGB_888:
+      bpp = 3;
+      break;
+    case HAL_PIXEL_FORMAT_RGB_565:
+    case HAL_PIXEL_FORMAT_BGR_565:
+    case HAL_PIXEL_FORMAT_RGBA_5551:
+    case HAL_PIXEL_FORMAT_RGBA_4444:
+      bpp = 2;
+      break;
+    default:
+      ALOGE("Error : %s New format request", __FUNCTION__);
+      break;
+  }
+
+  return bpp;
+}
+
+bool CpuCanAccess(gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage) {
+  return CpuCanRead(prod_usage, cons_usage) || CpuCanWrite(prod_usage);
+}
+
+bool CpuCanRead(gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage) {
+  if (prod_usage & GRALLOC1_PRODUCER_USAGE_CPU_READ) {
+    return true;
+  }
+
+  if (cons_usage & GRALLOC1_CONSUMER_USAGE_CPU_READ) {
+    return true;
+  }
+
+  return false;
+}
+
+bool CpuCanWrite(gralloc1_producer_usage_t prod_usage) {
+  if (prod_usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE) {
+    // Application intends to use CPU for rendering
+    return true;
+  }
+
+  return false;
+}
+
+}  // namespace gralloc1
diff --git a/msmcobalt/libgralloc1/gr_utils.h b/msmcobalt/libgralloc1/gr_utils.h
new file mode 100644
index 0000000..20f0be5
--- /dev/null
+++ b/msmcobalt/libgralloc1/gr_utils.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __GR_UTILS_H__
+#define __GR_UTILS_H__
+
+#include "gralloc_priv.h"
+
+#define SZ_2M 0x200000
+#define SZ_1M 0x100000
+#define SZ_4K 0x1000
+
+#define SIZE_4K 4096
+#define SIZE_8K 4096
+
+#define INT(exp) static_cast<int>(exp)
+#define UINT(exp) static_cast<unsigned int>(exp)
+
+namespace gralloc1 {
+
+template <class Type1, class Type2>
+inline Type1 ALIGN(Type1 x, Type2 align) {
+  return (Type1)((x + (Type1)align - 1) & ~((Type1)align - 1));
+}
+
+bool IsCompressedRGBFormat(int format);
+bool IsUncompressedRGBFormat(int format);
+uint32_t GetBppForUncompressedRGB(int format);
+bool CpuCanAccess(gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage);
+bool CpuCanRead(gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage);
+bool CpuCanWrite(gralloc1_producer_usage_t prod_usage);
+
+}  // namespace gralloc1
+
+#endif  // __GR_UTILS_H__
diff --git a/msmcobalt/libgralloc1/gralloc_priv.h b/msmcobalt/libgralloc1/gralloc_priv.h
new file mode 100644
index 0000000..64cb1f5
--- /dev/null
+++ b/msmcobalt/libgralloc1/gralloc_priv.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ *
+ * 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.
+ */
+
+#ifndef __GRALLOC_PRIV_H__
+#define __GRALLOC_PRIV_H__
+
+#include "gr_priv_handle.h"
+
+#define ROUND_UP_PAGESIZE(x) ((((unsigned int)(x)) + PAGE_SIZE - 1) & (~(PAGE_SIZE - 1)))
+
+/* Gralloc usage bits indicating the type of allocation that should be used */
+/* Refer gralloc1_producer_usage_t & gralloc1_consumer_usage-t in gralloc1.h */
+
+/* GRALLOC_USAGE_PRIVATE_0 is unused */
+
+/* Non linear, Universal Bandwidth Compression */
+#define GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC GRALLOC1_PRODUCER_USAGE_PRIVATE_1
+
+/* IOMMU heap comes from manually allocated pages, can be cached/uncached, is not secured */
+#define GRALLOC1_PRODUCER_USAGE_PRIVATE_IOMMU_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_2
+
+/* MM heap is a carveout heap for video, can be secured */
+#define GRALLOC1_PRODUCER_USAGE_PRIVATE_MM_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_3
+
+/* ADSP heap is a carveout heap, is not secured */
+#define GRALLOC1_PRODUCER_USAGE_PRIVATE_ADSP_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_4
+
+/* CAMERA heap is a carveout heap for camera, is not secured */
+#define GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_5
+
+/* Set this for allocating uncached memory (using O_DSYNC),
+ * cannot be used with noncontiguous heaps */
+#define GRALLOC1_PRODUCER_USAGE_PRIVATE_UNCACHED GRALLOC1_PRODUCER_USAGE_PRIVATE_6
+
+#define GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_ZSL GRALLOC1_PRODUCER_USAGE_PRIVATE_7
+
+/* Buffer content should be displayed on a primary display only */
+#define GRALLOC1_CONSUMER_USAGE_PRIVATE_INTERNAL_ONLY GRALLOC1_CONSUMER_USAGE_PRIVATE_1
+
+/* Buffer content should be displayed on an external display only */
+#define GRALLOC1_CONSUMER_USAGE_PRIVATE_EXTERNAL_ONLY GRALLOC1_CONSUMER_USAGE_PRIVATE_2
+
+/* This flag is set for WFD usecase */
+#define GRALLOC1_CONSUMER_USAGE_PRIVATE_WFD GRALLOC1_CONSUMER_USAGE_PRIVATE_3
+
+/* This flag is used for SECURE display usecase */
+#define GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY GRALLOC1_CONSUMER_USAGE_PRIVATE_4
+
+// for PERFORM API :
+// TODO(user): Move it to enum if it's ookay for gfx
+#define GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER 1
+#define GRALLOC_MODULE_PERFORM_GET_STRIDE 2
+#define GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE 3
+#define GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE 4
+#define GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES 5
+#define GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE 6
+#define GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO 7
+#define GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO 8
+#define GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG 9
+#define GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS 10
+#define GRALLOC_MODULE_PERFORM_GET_IGC 11
+#define GRALLOC_MODULE_PERFORM_SET_IGC 12
+#define GRALLOC_MODULE_PERFORM_SET_SINGLE_BUFFER_MODE 13
+
+// OEM specific HAL formats
+#define HAL_PIXEL_FORMAT_RGBA_5551 6
+#define HAL_PIXEL_FORMAT_RGBA_4444 7
+#define HAL_PIXEL_FORMAT_NV12_ENCODEABLE 0x102
+#define HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS 0x7FA30C04
+#define HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED 0x7FA30C03
+#define HAL_PIXEL_FORMAT_YCbCr_420_SP 0x109
+#define HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO 0x7FA30C01
+#define HAL_PIXEL_FORMAT_YCrCb_422_SP 0x10B
+#define HAL_PIXEL_FORMAT_R_8 0x10D
+#define HAL_PIXEL_FORMAT_RG_88 0x10E
+#define HAL_PIXEL_FORMAT_YCbCr_444_SP 0x10F
+#define HAL_PIXEL_FORMAT_YCrCb_444_SP 0x110
+#define HAL_PIXEL_FORMAT_YCrCb_422_I 0x111
+#define HAL_PIXEL_FORMAT_BGRX_8888 0x112
+#define HAL_PIXEL_FORMAT_NV21_ZSL 0x113
+#define HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS 0x114
+#define HAL_PIXEL_FORMAT_BGR_565 0x115
+
+// 10 bit
+#define HAL_PIXEL_FORMAT_RGBA_1010102 0x116
+#define HAL_PIXEL_FORMAT_ARGB_2101010 0x117
+#define HAL_PIXEL_FORMAT_RGBX_1010102 0x118
+#define HAL_PIXEL_FORMAT_XRGB_2101010 0x119
+#define HAL_PIXEL_FORMAT_BGRA_1010102 0x11A
+#define HAL_PIXEL_FORMAT_ABGR_2101010 0x11B
+#define HAL_PIXEL_FORMAT_BGRX_1010102 0x11C
+#define HAL_PIXEL_FORMAT_XBGR_2101010 0x11D
+#define HAL_PIXEL_FORMAT_YCbCr_420_P010 0x11F
+#define HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC 0x120
+
+#define HAL_PIXEL_FORMAT_INTERLACE 0x180
+
+// v4l2_fourcc('Y', 'U', 'Y', 'L'). 24 bpp YUYV 4:2:2 10 bit per component
+#define HAL_PIXEL_FORMAT_YCbCr_422_I_10BIT 0x4C595559
+
+// v4l2_fourcc('Y', 'B', 'W', 'C'). 10 bit per component. This compressed
+// format reduces the memory access bandwidth
+#define HAL_PIXEL_FORMAT_YCbCr_422_I_10BIT_COMPRESSED 0x43574259
+
+// UBWC aligned Venus format
+#define HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC 0x7FA30C06
+
+// Khronos ASTC formats
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD
+
+/* possible values for inverse gamma correction */
+#define HAL_IGC_NOT_SPECIFIED 0
+#define HAL_IGC_s_RGB 1
+
+/* possible formats for 3D content*/
+enum {
+  HAL_NO_3D = 0x0,
+  HAL_3D_SIDE_BY_SIDE_L_R = 0x1,
+  HAL_3D_SIDE_BY_SIDE_R_L = 0x2,
+  HAL_3D_TOP_BOTTOM = 0x4,
+  HAL_3D_IN_SIDE_BY_SIDE_L_R = 0x10000,  // unused legacy format
+};
+
+enum { BUFFER_TYPE_UI = 0, BUFFER_TYPE_VIDEO };
+
+#endif  // __GRALLOC_PRIV_H__
diff --git a/msmcobalt/liblight/Android.mk b/msmcobalt/liblight/Android.mk
new file mode 100644
index 0000000..ff4825b
--- /dev/null
+++ b/msmcobalt/liblight/Android.mk
@@ -0,0 +1,28 @@
+# 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)
+# HAL module implemenation stored in
+# hw/<COPYPIX_HARDWARE_MODULE_ID>.<ro.board.platform>.so
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := lights.c
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_CFLAGS := -DLOG_TAG=\"qdlights\"
+LOCAL_CLANG  := true
+LOCAL_MODULE := lights.$(TARGET_BOARD_PLATFORM)
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/msmcobalt/liblight/NOTICE b/msmcobalt/liblight/NOTICE
new file mode 100644
index 0000000..7340b9e
--- /dev/null
+++ b/msmcobalt/liblight/NOTICE
@@ -0,0 +1,190 @@
+
+   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.
+
+   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/msmcobalt/liblight/lights.c b/msmcobalt/liblight/lights.c
new file mode 100644
index 0000000..7a3775e
--- /dev/null
+++ b/msmcobalt/liblight/lights.c
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2014 The  Linux Foundation. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.
+ */
+
+
+// #define LOG_NDEBUG 0
+
+#include <cutils/log.h>
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+
+#include <hardware/lights.h>
+
+/******************************************************************************/
+
+static pthread_once_t g_init = PTHREAD_ONCE_INIT;
+static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;
+static struct light_state_t g_notification;
+static struct light_state_t g_battery;
+static int g_attention = 0;
+
+char const*const RED_LED_FILE
+        = "/sys/class/leds/red/brightness";
+
+char const*const GREEN_LED_FILE
+        = "/sys/class/leds/green/brightness";
+
+char const*const BLUE_LED_FILE
+        = "/sys/class/leds/blue/brightness";
+
+char const*const LCD_FILE
+        = "/sys/class/leds/lcd-backlight/brightness";
+
+char const*const BUTTON_FILE
+        = "/sys/class/leds/button-backlight/brightness";
+
+char const*const RED_BLINK_FILE
+        = "/sys/class/leds/red/blink";
+
+char const*const GREEN_BLINK_FILE
+        = "/sys/class/leds/green/blink";
+
+char const*const BLUE_BLINK_FILE
+        = "/sys/class/leds/blue/blink";
+
+/**
+ * device methods
+ */
+
+void init_globals(void)
+{
+    // init the mutex
+    pthread_mutex_init(&g_lock, NULL);
+}
+
+static int
+write_int(char const* path, int value)
+{
+    int fd;
+    static int already_warned = 0;
+
+    fd = open(path, O_RDWR);
+    if (fd >= 0) {
+        char buffer[20];
+        int bytes = snprintf(buffer, sizeof(buffer), "%d\n", value);
+        ssize_t amt = write(fd, buffer, (size_t)bytes);
+        close(fd);
+        return amt == -1 ? -errno : 0;
+    } else {
+        if (already_warned == 0) {
+            ALOGE("write_int failed to open %s\n", path);
+            already_warned = 1;
+        }
+        return -errno;
+    }
+}
+
+static int
+is_lit(struct light_state_t const* state)
+{
+    return state->color & 0x00ffffff;
+}
+
+static int
+rgb_to_brightness(struct light_state_t const* state)
+{
+    int color = state->color & 0x00ffffff;
+    return ((77*((color>>16)&0x00ff))
+            + (150*((color>>8)&0x00ff)) + (29*(color&0x00ff))) >> 8;
+}
+
+static int
+set_light_backlight(struct light_device_t* dev,
+        struct light_state_t const* state)
+{
+    int err = 0;
+    int brightness = rgb_to_brightness(state);
+    if(!dev) {
+        return -1;
+    }
+    pthread_mutex_lock(&g_lock);
+    err = write_int(LCD_FILE, brightness);
+    pthread_mutex_unlock(&g_lock);
+    return err;
+}
+
+static int
+set_speaker_light_locked(struct light_device_t* dev,
+        struct light_state_t const* state)
+{
+    int red, green, blue;
+    int blink;
+    int onMS, offMS;
+    unsigned int colorRGB;
+
+    if(!dev) {
+        return -1;
+    }
+
+    switch (state->flashMode) {
+        case LIGHT_FLASH_TIMED:
+            onMS = state->flashOnMS;
+            offMS = state->flashOffMS;
+            break;
+        case LIGHT_FLASH_NONE:
+        default:
+            onMS = 0;
+            offMS = 0;
+            break;
+    }
+
+    colorRGB = state->color;
+
+#if 0
+    ALOGD("set_speaker_light_locked mode %d, colorRGB=%08X, onMS=%d, offMS=%d\n",
+            state->flashMode, colorRGB, onMS, offMS);
+#endif
+
+    red = (colorRGB >> 16) & 0xFF;
+    green = (colorRGB >> 8) & 0xFF;
+    blue = colorRGB & 0xFF;
+
+    if (onMS > 0 && offMS > 0) {
+        /*
+         * if ON time == OFF time
+         *   use blink mode 2
+         * else
+         *   use blink mode 1
+         */
+        if (onMS == offMS)
+            blink = 2;
+        else
+            blink = 1;
+    } else {
+        blink = 0;
+    }
+
+    if (blink) {
+        if (red) {
+            if (write_int(RED_BLINK_FILE, blink))
+                write_int(RED_LED_FILE, 0);
+	}
+        if (green) {
+            if (write_int(GREEN_BLINK_FILE, blink))
+                write_int(GREEN_LED_FILE, 0);
+	}
+        if (blue) {
+            if (write_int(BLUE_BLINK_FILE, blink))
+                write_int(BLUE_LED_FILE, 0);
+	}
+    } else {
+        write_int(RED_LED_FILE, red);
+        write_int(GREEN_LED_FILE, green);
+        write_int(BLUE_LED_FILE, blue);
+    }
+
+    return 0;
+}
+
+static void
+handle_speaker_battery_locked(struct light_device_t* dev)
+{
+    if (is_lit(&g_battery)) {
+        set_speaker_light_locked(dev, &g_battery);
+    } else {
+        set_speaker_light_locked(dev, &g_notification);
+    }
+}
+
+static int
+set_light_battery(struct light_device_t* dev,
+        struct light_state_t const* state)
+{
+    pthread_mutex_lock(&g_lock);
+    g_battery = *state;
+    handle_speaker_battery_locked(dev);
+    pthread_mutex_unlock(&g_lock);
+    return 0;
+}
+
+static int
+set_light_notifications(struct light_device_t* dev,
+        struct light_state_t const* state)
+{
+    pthread_mutex_lock(&g_lock);
+    g_notification = *state;
+    handle_speaker_battery_locked(dev);
+    pthread_mutex_unlock(&g_lock);
+    return 0;
+}
+
+static int
+set_light_attention(struct light_device_t* dev,
+        struct light_state_t const* state)
+{
+    pthread_mutex_lock(&g_lock);
+    if (state->flashMode == LIGHT_FLASH_HARDWARE) {
+        g_attention = state->flashOnMS;
+    } else if (state->flashMode == LIGHT_FLASH_NONE) {
+        g_attention = 0;
+    }
+    handle_speaker_battery_locked(dev);
+    pthread_mutex_unlock(&g_lock);
+    return 0;
+}
+
+static int
+set_light_buttons(struct light_device_t* dev,
+        struct light_state_t const* state)
+{
+    int err = 0;
+    if(!dev) {
+        return -1;
+    }
+    pthread_mutex_lock(&g_lock);
+    err = write_int(BUTTON_FILE, state->color & 0xFF);
+    pthread_mutex_unlock(&g_lock);
+    return err;
+}
+
+/** Close the lights device */
+static int
+close_lights(struct light_device_t *dev)
+{
+    if (dev) {
+        free(dev);
+    }
+    return 0;
+}
+
+
+/******************************************************************************/
+
+/**
+ * module methods
+ */
+
+/** Open a new instance of a lights device using name */
+static int open_lights(const struct hw_module_t* module, char const* name,
+        struct hw_device_t** device)
+{
+    int (*set_light)(struct light_device_t* dev,
+            struct light_state_t const* state);
+
+    if (0 == strcmp(LIGHT_ID_BACKLIGHT, name))
+        set_light = set_light_backlight;
+    else if (0 == strcmp(LIGHT_ID_BATTERY, name))
+        set_light = set_light_battery;
+    else if (0 == strcmp(LIGHT_ID_NOTIFICATIONS, name))
+        set_light = set_light_notifications;
+    else if (0 == strcmp(LIGHT_ID_BUTTONS, name))
+        set_light = set_light_buttons;
+    else if (0 == strcmp(LIGHT_ID_ATTENTION, name))
+        set_light = set_light_attention;
+    else
+        return -EINVAL;
+
+    pthread_once(&g_init, init_globals);
+
+    struct light_device_t *dev = malloc(sizeof(struct light_device_t));
+
+    if(!dev)
+        return -ENOMEM;
+
+    memset(dev, 0, sizeof(*dev));
+
+    dev->common.tag = HARDWARE_DEVICE_TAG;
+    dev->common.version = 0;
+    dev->common.module = (struct hw_module_t*)module;
+    dev->common.close = (int (*)(struct hw_device_t*))close_lights;
+    dev->set_light = set_light;
+
+    *device = (struct hw_device_t*)dev;
+    return 0;
+}
+
+static struct hw_module_methods_t lights_module_methods = {
+    .open =  open_lights,
+};
+
+/*
+ * The lights Module
+ */
+struct hw_module_t HAL_MODULE_INFO_SYM = {
+    .tag = HARDWARE_MODULE_TAG,
+    .version_major = 1,
+    .version_minor = 0,
+    .id = LIGHTS_HARDWARE_MODULE_ID,
+    .name = "lights Module",
+    .author = "Google, Inc.",
+    .methods = &lights_module_methods,
+};
diff --git a/msmcobalt/libmemtrack/Android.mk b/msmcobalt/libmemtrack/Android.mk
new file mode 100644
index 0000000..4e7a09f
--- /dev/null
+++ b/msmcobalt/libmemtrack/Android.mk
@@ -0,0 +1,28 @@
+# Copyright (C) 2013 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)
+
+# HAL module implemenation stored in
+# hw/<POWERS_HARDWARE_MODULE_ID>.<ro.hardware>.so
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_C_INCLUDES += hardware/libhardware/include
+LOCAL_CFLAGS := -Wconversion -Wall -Werror -Wno-sign-conversion
+LOCAL_CLANG  := true
+LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_SRC_FILES := memtrack_msm.c kgsl.c
+LOCAL_MODULE := memtrack.$(TARGET_BOARD_PLATFORM)
+include $(BUILD_SHARED_LIBRARY)
diff --git a/msmcobalt/libmemtrack/kgsl.c b/msmcobalt/libmemtrack/kgsl.c
new file mode 100644
index 0000000..11c7e8a
--- /dev/null
+++ b/msmcobalt/libmemtrack/kgsl.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2013 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 <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/mman.h>
+
+#include <hardware/memtrack.h>
+
+#include "memtrack_msm.h"
+
+#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
+#define min(x, y) ((x) < (y) ? (x) : (y))
+
+struct memtrack_record record_templates[] = {
+    {
+        .flags = MEMTRACK_FLAG_SMAPS_ACCOUNTED |
+                 MEMTRACK_FLAG_PRIVATE |
+                 MEMTRACK_FLAG_NONSECURE,
+    },
+    {
+        .flags = MEMTRACK_FLAG_SMAPS_UNACCOUNTED |
+                 MEMTRACK_FLAG_PRIVATE |
+                 MEMTRACK_FLAG_NONSECURE,
+    },
+};
+
+int kgsl_memtrack_get_memory(pid_t pid, enum memtrack_type type,
+                             struct memtrack_record *records,
+                             size_t *num_records)
+{
+    size_t allocated_records = min(*num_records, ARRAY_SIZE(record_templates));
+    FILE *fp;
+    char line[1024];
+    char tmp[128];
+    bool is_surfaceflinger = false;
+    size_t accounted_size = 0;
+    size_t unaccounted_size = 0;
+
+    *num_records = ARRAY_SIZE(record_templates);
+
+    /* fastpath to return the necessary number of records */
+    if (allocated_records == 0) {
+        return 0;
+    }
+
+    snprintf(tmp, sizeof(tmp), "/proc/%d/cmdline", pid);
+    fp = fopen(tmp, "r");
+    if (fp != NULL) {
+        if (fgets(line, sizeof(line), fp)) {
+            if (strcmp(line, "/system/bin/surfaceflinger") == 0)
+                is_surfaceflinger = true;
+        }
+        fclose(fp);
+    }
+
+    memcpy(records, record_templates,
+           sizeof(struct memtrack_record) * allocated_records);
+
+    snprintf(tmp, sizeof(tmp), "/d/kgsl/proc/%d/mem", pid);
+    fp = fopen(tmp, "r");
+    if (fp == NULL) {
+        return -errno;
+    }
+
+    /* Go through each line of <pid>/mem file and for every entry of type "gpumem"
+     * check if the gpubuffer entry is usermapped or not. If the entry is usermapped
+     * count the entry as accounted else count the entry as unaccounted.
+     */
+    while (1) {
+        unsigned long size, mapsize;
+        char line_type[7];
+        char flags[9];
+        char line_usage[19];
+        int ret;
+
+        if (fgets(line, sizeof(line), fp) == NULL) {
+            break;
+        }
+
+        /* Format:
+         *  gpuaddr useraddr     size    id flags       type            usage sglen mapsize
+         * 545ba000 545ba000     4096     1 -----pY     gpumem      arraybuffer     1  4096
+         */
+        ret = sscanf(line, "%*x %*x %lu %*d %8s %6s %18s %*d %lu\n",
+                     &size, flags, line_type, line_usage, &mapsize);
+        if (ret != 5) {
+            continue;
+        }
+
+        if (type == MEMTRACK_TYPE_GL && strcmp(line_type, "gpumem") == 0) {
+
+            if (flags[6] == 'Y') {
+                accounted_size += mapsize;
+		unaccounted_size += size - mapsize;
+	    } else
+                unaccounted_size += size;
+
+        } else if (type == MEMTRACK_TYPE_GRAPHICS && strcmp(line_type, "ion") == 0) {
+            if ( !(is_surfaceflinger == false && strcmp(line_usage, "egl_surface") == 0)) {
+                unaccounted_size += size;
+            }
+        }
+    }
+
+    if (allocated_records > 0) {
+        records[0].size_in_bytes = accounted_size;
+    }
+    if (allocated_records > 1) {
+        records[1].size_in_bytes = unaccounted_size;
+    }
+
+    fclose(fp);
+
+    return 0;
+}
diff --git a/msmcobalt/libmemtrack/memtrack_msm.c b/msmcobalt/libmemtrack/memtrack_msm.c
new file mode 100644
index 0000000..e369d5f
--- /dev/null
+++ b/msmcobalt/libmemtrack/memtrack_msm.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2013 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 <errno.h>
+
+#include <hardware/memtrack.h>
+
+#include "memtrack_msm.h"
+
+int msm_memtrack_init(const struct memtrack_module *module)
+{
+    if(!module)
+        return -1;
+    return 0;
+}
+
+int msm_memtrack_get_memory(const struct memtrack_module *module,
+                                pid_t pid,
+                                int type,
+                                struct memtrack_record *records,
+                                size_t *num_records)
+{
+    if(!module)
+        return -1;
+    if (type == MEMTRACK_TYPE_GL || type == MEMTRACK_TYPE_GRAPHICS) {
+        return kgsl_memtrack_get_memory(pid, type, records, num_records);
+    }
+
+    return -EINVAL;
+}
+
+static struct hw_module_methods_t memtrack_module_methods = {
+    .open = NULL,
+};
+
+struct memtrack_module HAL_MODULE_INFO_SYM = {
+    .common = {
+        .tag = HARDWARE_MODULE_TAG,
+        .module_api_version = MEMTRACK_MODULE_API_VERSION_0_1,
+        .hal_api_version = HARDWARE_HAL_API_VERSION,
+        .id = MEMTRACK_HARDWARE_MODULE_ID,
+        .name = "MSM Memory Tracker HAL",
+        .author = "The Android Open Source Project",
+        .methods = &memtrack_module_methods,
+    },
+
+    .init = msm_memtrack_init,
+    .getMemory = msm_memtrack_get_memory,
+};
+
diff --git a/msmcobalt/libmemtrack/memtrack_msm.h b/msmcobalt/libmemtrack/memtrack_msm.h
new file mode 100644
index 0000000..74aa576
--- /dev/null
+++ b/msmcobalt/libmemtrack/memtrack_msm.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#ifndef _MEMTRACK_MSM_H_
+#define _MEMTRACK_MSM_H_
+
+int kgsl_memtrack_get_memory(pid_t pid, enum memtrack_type type,
+                             struct memtrack_record *records,
+                             size_t *num_records);
+
+#endif
diff --git a/msmcobalt/libqdutils/Android.mk b/msmcobalt/libqdutils/Android.mk
new file mode 100644
index 0000000..db6509c
--- /dev/null
+++ b/msmcobalt/libqdutils/Android.mk
@@ -0,0 +1,32 @@
+LOCAL_PATH := $(call my-dir)
+include $(LOCAL_PATH)/../common.mk
+include $(CLEAR_VARS)
+
+LOCAL_MODULE                  := libqdutils
+LOCAL_MODULE_TAGS             := optional
+LOCAL_SHARED_LIBRARIES        := $(common_libs) libbinder libqservice
+LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes)
+LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdutils\" -Wno-sign-conversion
+LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
+LOCAL_COPY_HEADERS_TO         := $(common_header_export_path)
+LOCAL_COPY_HEADERS            := display_config.h
+LOCAL_SRC_FILES               := profiler.cpp \
+                                 qd_utils.cpp \
+                                 display_config.cpp
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_COPY_HEADERS_TO           := $(common_header_export_path)
+LOCAL_COPY_HEADERS              := qdMetaData.h
+LOCAL_SHARED_LIBRARIES          := liblog libcutils
+LOCAL_C_INCLUDES                := $(common_includes)
+LOCAL_ADDITIONAL_DEPENDENCIES   := $(common_deps)
+LOCAL_SRC_FILES                 := qdMetaData.cpp
+LOCAL_CFLAGS                    := $(common_flags) -Wno-sign-conversion
+LOCAL_CFLAGS                    += -DLOG_TAG=\"DisplayMetaData\"
+
+LOCAL_MODULE_TAGS               := optional
+LOCAL_MODULE                    := libqdMetaData
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/msmcobalt/libqdutils/display_config.cpp b/msmcobalt/libqdutils/display_config.cpp
new file mode 100644
index 0000000..3415ac6
--- /dev/null
+++ b/msmcobalt/libqdutils/display_config.cpp
@@ -0,0 +1,368 @@
+/*
+* Copyright (c) 2013-2014, 2016, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of The Linux Foundation. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <display_config.h>
+#include <QServiceUtils.h>
+#include <qd_utils.h>
+
+using namespace android;
+using namespace qService;
+
+namespace qdutils {
+
+//=============================================================================
+// The functions below run in the client process and wherever necessary
+// do a binder call to HWC to get/set data.
+
+int isExternalConnected(void) {
+    int ret;
+    status_t err = (status_t) FAILED_TRANSACTION;
+    sp<IQService> binder = getBinder();
+    Parcel inParcel, outParcel;
+    if(binder != NULL) {
+        err = binder->dispatch(IQService::CHECK_EXTERNAL_STATUS,
+                &inParcel , &outParcel);
+    }
+    if(err) {
+        ALOGE("%s: Failed to get external status err=%d", __FUNCTION__, err);
+        ret = err;
+    } else {
+        ret = outParcel.readInt32();
+    }
+    return ret;
+}
+
+int getDisplayAttributes(int dpy, DisplayAttributes_t& dpyattr) {
+    status_t err = (status_t) FAILED_TRANSACTION;
+    sp<IQService> binder = getBinder();
+    Parcel inParcel, outParcel;
+    inParcel.writeInt32(dpy);
+    if(binder != NULL) {
+        err = binder->dispatch(IQService::GET_DISPLAY_ATTRIBUTES,
+                &inParcel, &outParcel);
+    }
+    if(!err) {
+        dpyattr.vsync_period = outParcel.readInt32();
+        dpyattr.xres = outParcel.readInt32();
+        dpyattr.yres = outParcel.readInt32();
+        dpyattr.xdpi = outParcel.readFloat();
+        dpyattr.ydpi = outParcel.readFloat();
+        dpyattr.panel_type = (char) outParcel.readInt32();
+    } else {
+        ALOGE("%s() failed with err %d", __FUNCTION__, err);
+    }
+    return err;
+}
+
+int setHSIC(int dpy, const HSICData_t& hsic_data) {
+    status_t err = (status_t) FAILED_TRANSACTION;
+    sp<IQService> binder = getBinder();
+    Parcel inParcel, outParcel;
+    inParcel.writeInt32(dpy);
+    inParcel.writeInt32(hsic_data.hue);
+    inParcel.writeFloat(hsic_data.saturation);
+    inParcel.writeInt32(hsic_data.intensity);
+    inParcel.writeFloat(hsic_data.contrast);
+    if(binder != NULL) {
+        err = binder->dispatch(IQService::SET_HSIC_DATA, &inParcel, &outParcel);
+    }
+    if(err)
+        ALOGE("%s: Failed to get external status err=%d", __FUNCTION__, err);
+    return err;
+}
+
+int getDisplayVisibleRegion(int dpy, hwc_rect_t &rect) {
+    status_t err = (status_t) FAILED_TRANSACTION;
+    sp<IQService> binder = getBinder();
+    Parcel inParcel, outParcel;
+    inParcel.writeInt32(dpy);
+    if(binder != NULL) {
+        err = binder->dispatch(IQService::GET_DISPLAY_VISIBLE_REGION,
+                &inParcel, &outParcel);
+    }
+    if(!err) {
+        rect.left = outParcel.readInt32();
+        rect.top = outParcel.readInt32();
+        rect.right = outParcel.readInt32();
+        rect.bottom = outParcel.readInt32();
+    } else {
+        ALOGE("%s: Failed to getVisibleRegion for dpy =%d: err = %d",
+              __FUNCTION__, dpy, err);
+    }
+    return err;
+}
+
+int setViewFrame(int dpy, int l, int t, int r, int b) {
+    status_t err = (status_t) FAILED_TRANSACTION;
+    sp<IQService> binder = getBinder();
+    Parcel inParcel, outParcel;
+    inParcel.writeInt32(dpy);
+    inParcel.writeInt32(l);
+    inParcel.writeInt32(t);
+    inParcel.writeInt32(r);
+    inParcel.writeInt32(b);
+
+    if(binder != NULL) {
+        err = binder->dispatch(IQService::SET_VIEW_FRAME,
+                &inParcel, &outParcel);
+    }
+    if(err)
+        ALOGE("%s: Failed to set view frame for dpy %d err=%d",
+                            __FUNCTION__, dpy, err);
+
+    return err;
+}
+
+int setSecondaryDisplayStatus(int dpy, uint32_t status) {
+    status_t err = (status_t) FAILED_TRANSACTION;
+    sp<IQService> binder = getBinder();
+    Parcel inParcel, outParcel;
+    inParcel.writeInt32(dpy);
+    inParcel.writeInt32(status);
+
+    if(binder != NULL) {
+        err = binder->dispatch(IQService::SET_SECONDARY_DISPLAY_STATUS,
+                &inParcel, &outParcel);
+    }
+    if(err)
+        ALOGE("%s: Failed for dpy %d status = %d err=%d", __FUNCTION__, dpy,
+                                                        status, err);
+
+    return err;
+}
+
+int configureDynRefreshRate(uint32_t op, uint32_t refreshRate) {
+    status_t err = (status_t) FAILED_TRANSACTION;
+    sp<IQService> binder = getBinder();
+    Parcel inParcel, outParcel;
+    inParcel.writeInt32(op);
+    inParcel.writeInt32(refreshRate);
+
+    if(binder != NULL) {
+        err = binder->dispatch(IQService::CONFIGURE_DYN_REFRESH_RATE,
+                               &inParcel, &outParcel);
+    }
+
+    if(err)
+        ALOGE("%s: Failed setting op %d err=%d", __FUNCTION__, op, err);
+
+    return err;
+}
+
+int getConfigCount(int /*dpy*/) {
+    int numConfigs = -1;
+    sp<IQService> binder = getBinder();
+    if(binder != NULL) {
+        Parcel inParcel, outParcel;
+        inParcel.writeInt32(DISPLAY_PRIMARY);
+        status_t err = binder->dispatch(IQService::GET_CONFIG_COUNT,
+                &inParcel, &outParcel);
+        if(!err) {
+            numConfigs = outParcel.readInt32();
+            ALOGI("%s() Received num configs %d", __FUNCTION__, numConfigs);
+        } else {
+            ALOGE("%s() failed with err %d", __FUNCTION__, err);
+        }
+    }
+    return numConfigs;
+}
+
+int getActiveConfig(int /*dpy*/) {
+    int configIndex = -1;
+    sp<IQService> binder = getBinder();
+    if(binder != NULL) {
+        Parcel inParcel, outParcel;
+        inParcel.writeInt32(DISPLAY_PRIMARY);
+        status_t err = binder->dispatch(IQService::GET_ACTIVE_CONFIG,
+                &inParcel, &outParcel);
+        if(!err) {
+            configIndex = outParcel.readInt32();
+            ALOGI("%s() Received active config index %d", __FUNCTION__,
+                    configIndex);
+        } else {
+            ALOGE("%s() failed with err %d", __FUNCTION__, err);
+        }
+    }
+    return configIndex;
+}
+
+int setActiveConfig(int configIndex, int /*dpy*/) {
+    status_t err = (status_t) FAILED_TRANSACTION;
+    sp<IQService> binder = getBinder();
+    if(binder != NULL) {
+        Parcel inParcel, outParcel;
+        inParcel.writeInt32(configIndex);
+        inParcel.writeInt32(DISPLAY_PRIMARY);
+        err = binder->dispatch(IQService::SET_ACTIVE_CONFIG,
+                &inParcel, &outParcel);
+        if(!err) {
+            ALOGI("%s() Successfully set active config index %d", __FUNCTION__,
+                    configIndex);
+        } else {
+            ALOGE("%s() failed with err %d", __FUNCTION__, err);
+        }
+    }
+    return err;
+}
+
+DisplayAttributes getDisplayAttributes(int configIndex, int /*dpy*/) {
+    DisplayAttributes dpyattr;
+    sp<IQService> binder = getBinder();
+    if(binder != NULL) {
+        Parcel inParcel, outParcel;
+        inParcel.writeInt32(configIndex);
+        inParcel.writeInt32(DISPLAY_PRIMARY);
+        status_t err = binder->dispatch(
+                IQService::GET_DISPLAY_ATTRIBUTES_FOR_CONFIG, &inParcel,
+                &outParcel);
+        if(!err) {
+            dpyattr.vsync_period = outParcel.readInt32();
+            dpyattr.xres = outParcel.readInt32();
+            dpyattr.yres = outParcel.readInt32();
+            dpyattr.xdpi = outParcel.readFloat();
+            dpyattr.ydpi = outParcel.readFloat();
+            dpyattr.panel_type = (char) outParcel.readInt32();
+            dpyattr.is_yuv = outParcel.readInt32();
+            ALOGI("%s() Received attrs for index %d: xres %d, yres %d",
+                    __FUNCTION__, configIndex, dpyattr.xres, dpyattr.yres);
+        } else {
+            ALOGE("%s() failed with err %d", __FUNCTION__, err);
+        }
+    }
+    return dpyattr;
+}
+
+int setPanelMode(int mode) {
+    status_t err = (status_t) FAILED_TRANSACTION;
+    sp<IQService> binder = getBinder();
+    if(binder != NULL) {
+        Parcel inParcel, outParcel;
+        inParcel.writeInt32(mode);
+        err = binder->dispatch(IQService::SET_DISPLAY_MODE,
+                               &inParcel, &outParcel);
+        if(!err) {
+            ALOGI("%s() Successfully set the display mode to %d", __FUNCTION__,
+                  mode);
+        } else {
+            ALOGE("%s() failed with err %d", __FUNCTION__, err);
+        }
+    }
+    return err;
+}
+
+int setPanelBrightness(int level) {
+    status_t err = (status_t) FAILED_TRANSACTION;
+    sp<IQService> binder = getBinder();
+    Parcel inParcel, outParcel;
+
+    if(binder != NULL) {
+        inParcel.writeInt32(level);
+        status_t err = binder->dispatch(IQService::SET_PANEL_BRIGHTNESS,
+                &inParcel, &outParcel);
+        if(err) {
+            ALOGE("%s() failed with err %d", __FUNCTION__, err);
+        }
+    }
+    return err;
+}
+
+int getPanelBrightness() {
+    int panel_brightness = -1;
+    sp<IQService> binder = getBinder();
+    Parcel inParcel, outParcel;
+
+    if(binder != NULL) {
+        status_t err = binder->dispatch(IQService::GET_PANEL_BRIGHTNESS,
+                &inParcel, &outParcel);
+        if(!err) {
+            panel_brightness = outParcel.readInt32();
+            ALOGI("%s() Current panel brightness value %d", __FUNCTION__,
+                    panel_brightness);
+        } else {
+            ALOGE("%s() failed with err %d", __FUNCTION__, err);
+        }
+    }
+    return panel_brightness;
+}
+
+}// namespace
+
+// ----------------------------------------------------------------------------
+// Functions for linking dynamically to libqdutils
+// ----------------------------------------------------------------------------
+extern "C" int minHdcpEncryptionLevelChanged(int dpy, int min_enc_level) {
+    status_t err = (status_t) FAILED_TRANSACTION;
+    sp<IQService> binder = getBinder();
+    Parcel inParcel, outParcel;
+    inParcel.writeInt32(dpy);
+    inParcel.writeInt32(min_enc_level);
+
+    if(binder != NULL) {
+        err = binder->dispatch(IQService::MIN_HDCP_ENCRYPTION_LEVEL_CHANGED,
+                &inParcel, &outParcel);
+    }
+
+    if(err) {
+        ALOGE("%s: Failed for dpy %d err=%d", __FUNCTION__, dpy, err);
+    } else {
+        err = outParcel.readInt32();
+    }
+
+    return err;
+}
+
+extern "C" int refreshScreen() {
+    int ret = 0;
+    ret = screenRefresh();
+    return ret;
+}
+
+extern "C" int controlPartialUpdate(int dpy, int mode) {
+    status_t err = (status_t) FAILED_TRANSACTION;
+    sp<IQService> binder = getBinder();
+    if(binder != NULL) {
+        Parcel inParcel, outParcel;
+        inParcel.writeInt32(dpy);
+        inParcel.writeInt32(mode);
+        err = binder->dispatch(IQService::CONTROL_PARTIAL_UPDATE, &inParcel, &outParcel);
+        if(err != 0) {
+            ALOGE("%s() failed with err %d", __FUNCTION__, err);
+        } else {
+            return outParcel.readInt32();
+        }
+    }
+
+    return err;
+}
+
diff --git a/msmcobalt/libqdutils/display_config.h b/msmcobalt/libqdutils/display_config.h
new file mode 100644
index 0000000..15aba94
--- /dev/null
+++ b/msmcobalt/libqdutils/display_config.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2013 - 2016 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *    * Neither the name of The Linux Foundation. nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DISPLAY_CONFIG_H
+#define _DISPLAY_CONFIG_H
+
+#include <gralloc_priv.h>
+#include <qdMetaData.h>
+#include <hardware/hwcomposer.h>
+
+// This header is for clients to use to set/get global display configuration.
+// Only primary and external displays are supported here.
+
+namespace qdutils {
+
+
+/* TODO: Have all the common enums that need be exposed to clients and which
+ * are also needed in hwc defined here. Remove such definitions we have in
+ * hwc_utils.h
+ */
+
+// Use this enum to specify the dpy parameters where needed
+enum {
+    DISPLAY_PRIMARY = HWC_DISPLAY_PRIMARY,
+    DISPLAY_EXTERNAL = HWC_DISPLAY_EXTERNAL,
+#ifdef QTI_BSP
+    DISPLAY_TERTIARY = HWC_DISPLAY_TERTIARY,
+#endif
+    DISPLAY_VIRTUAL = HWC_DISPLAY_VIRTUAL,
+};
+
+// External Display states - used in setSecondaryDisplayStatus()
+// To be consistent with the same defined in hwc_utils.h
+enum {
+    EXTERNAL_OFFLINE = 0,
+    EXTERNAL_ONLINE,
+    EXTERNAL_PAUSE,
+    EXTERNAL_RESUME,
+};
+
+enum {
+    DISABLE_METADATA_DYN_REFRESH_RATE = 0,
+    ENABLE_METADATA_DYN_REFRESH_RATE,
+    SET_BINDER_DYN_REFRESH_RATE,
+};
+
+enum {
+    DEFAULT_MODE = 0,
+    VIDEO_MODE,
+    COMMAND_MODE,
+};
+
+// Display Attributes that are available to clients of this library
+// Not to be confused with a similar struct in hwc_utils (in the hwc namespace)
+typedef struct DisplayAttributes {
+    uint32_t vsync_period; //nanoseconds
+    uint32_t xres;
+    uint32_t yres;
+    float xdpi;
+    float ydpi;
+    char panel_type;
+    bool is_yuv;
+    DisplayAttributes() : vsync_period(0), xres(0), yres(0), xdpi(0.0f),
+            ydpi(0.0f), panel_type(0), is_yuv(false) {}
+} DisplayAttributes_t;
+
+//=============================================================================
+// The functions below run in the client process and wherever necessary
+// do a binder call to HWC to get/set data.
+
+// Check if external display is connected. Useful to check before making
+// calls for external displays
+// Returns 1 if connected, 0 if disconnected, negative values on errors
+int isExternalConnected(void);
+
+// Get display vsync period which is in nanoseconds
+// i.e vsync_period = 1000000000l / fps
+// Returns 0 on success, negative values on errors
+int getDisplayAttributes(int dpy, DisplayAttributes_t& dpyattr);
+
+// Set HSIC data on a given display ID
+// Returns 0 on success, negative values on errors
+int setHSIC(int dpy, const HSICData_t& hsic_data);
+
+// get the active visible region for the display
+// Returns 0 on success, negative values on errors
+int getDisplayVisibleRegion(int dpy, hwc_rect_t &rect);
+
+// set the view frame information in hwc context from surfaceflinger
+int setViewFrame(int dpy, int l, int t, int r, int b);
+
+// Set the secondary display status(pause/resume/offline etc.,)
+int setSecondaryDisplayStatus(int dpy, uint32_t status);
+
+// Enable/Disable/Set refresh rate dynamically
+int configureDynRefreshRate(uint32_t op, uint32_t refreshRate);
+
+// Returns the number of configs supported for the display on success.
+// Returns -1 on error.
+// Only primary display supported for now, value of dpy ignored.
+int getConfigCount(int dpy);
+
+// Returns the index of config that is current set for the display on success.
+// Returns -1 on error.
+// Only primary display supported for now, value of dpy ignored.
+int getActiveConfig(int dpy);
+
+// Sets the config for the display on success and returns 0.
+// Returns -1 on error.
+// Only primary display supported for now, value of dpy ignored
+int setActiveConfig(int configIndex, int dpy);
+
+// Returns the attributes for the specified config for the display on success.
+// Returns xres and yres as 0 on error.
+// Only primary display supported for now, value of dpy ignored
+DisplayAttributes getDisplayAttributes(int configIndex, int dpy);
+
+// Set the primary display mode to command or video mode
+int setDisplayMode(int mode);
+
+// Sets the panel brightness of the primary display
+int setPanelBrightness(int level);
+
+// Retrieves the current panel brightness value
+int getPanelBrightness();
+
+}; //namespace
+
+#endif
diff --git a/msmcobalt/libqdutils/profiler.cpp b/msmcobalt/libqdutils/profiler.cpp
new file mode 100644
index 0000000..810b019
--- /dev/null
+++ b/msmcobalt/libqdutils/profiler.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LOG_NDDEBUG 0
+#define __STDC_FORMAT_MACROS 1
+#include <inttypes.h>
+
+#include "profiler.h"
+
+#ifdef DEBUG_CALC_FPS
+
+
+ANDROID_SINGLETON_STATIC_INSTANCE(qdutils::CalcFps) ;
+
+namespace qdutils {
+
+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;
+    }
+
+    ALOGD("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) {