diff --git a/Android.mk b/Android.mk
index 127a6de..73024a0 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,11 +1,9 @@
 #Enables the listed display HAL modules
 
-#Libs to be built for all targets (including SDK)
 display-hals := libqcomui
-
 #libs to be built for QCOM targets only
 #ifeq ($(call is-vendor-board-platform,QCOM),true)
-display-hals += libgralloc libgenlock libcopybit
+display-hals += libgralloc libgenlock libcopybit libhwcomposer liboverlay
 #endif
 
 include $(call all-named-subdir-makefiles,$(display-hals))
diff --git a/libcopybit/Android.mk b/libcopybit/Android.mk
new file mode 100644
index 0000000..24663b7
--- /dev/null
+++ b/libcopybit/Android.mk
@@ -0,0 +1,59 @@
+# 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, not prelinked and stored in
+# hw/<COPYPIX_HARDWARE_MODULE_ID>.<ro.board.platform>.so
+
+ifeq ($(TARGET_USES_C2D_COMPOSITION),true)
+    include $(CLEAR_VARS)
+    LOCAL_PRELINK_MODULE := false
+    LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+    LOCAL_SHARED_LIBRARIES := liblog libdl libcutils libmemalloc libutils
+    LOCAL_SRC_FILES := copybit_c2d.cpp software_converter.cpp
+    LOCAL_MODULE := copybit.$(TARGET_BOARD_PLATFORM)
+    LOCAL_C_INCLUDES += hardware/qcom/display/libgralloc
+    LOCAL_CFLAGS += -DCOPYBIT_Z180=1 -DC2D_SUPPORT_DISPLAY=1
+    LOCAL_MODULE_TAGS := optional
+    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)
+            include $(CLEAR_VARS)
+            ifeq ($(ARCH_ARM_HAVE_NEON),true)
+                LOCAL_CFLAGS += -D__ARM_HAVE_NEON
+            endif
+            ifeq ($(call is-board-platform,msm7627a),true)
+                LOCAL_CFLAGS += -DTARGET_7x27A
+            endif
+            ifeq ($(TARGET_GRALLOC_USES_ASHMEM),true)
+                LOCAL_CFLAGS += -DUSE_ASHMEM
+                ifeq ($(call is-chipset-prefix-in-board-platform,msm7627),true)
+                   LOCAL_CFLAGS += -DTARGET_7x27
+                endif
+            endif
+
+            LOCAL_PRELINK_MODULE := false
+            LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+            LOCAL_SHARED_LIBRARIES := liblog libmemalloc
+            LOCAL_SRC_FILES := software_converter.cpp copybit.cpp
+            LOCAL_MODULE := copybit.$(TARGET_BOARD_PLATFORM)
+            LOCAL_MODULE_TAGS := optional
+            LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qcom/display/libgralloc
+            LOCAL_CFLAGS += -DCOPYBIT_MSM7K=1
+            include $(BUILD_SHARED_LIBRARY)
+        endif
+    endif
+endif
diff --git a/libcopybit/MODULE_LICENSE_APACHE2 b/libcopybit/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libcopybit/MODULE_LICENSE_APACHE2
diff --git a/libcopybit/NOTICE b/libcopybit/NOTICE
new file mode 100644
index 0000000..9c1e63a
--- /dev/null
+++ b/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/libcopybit/c2d2.h b/libcopybit/c2d2.h
new file mode 100644
index 0000000..8c7d05b
--- /dev/null
+++ b/libcopybit/c2d2.h
@@ -0,0 +1,618 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef __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_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;
+
+
+/* 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;
+
+
+/*****************************************************************************/
+/**************************** 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);
+
+/*****************************************************************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __c2d2_h_ */
diff --git a/libcopybit/copybit.cpp b/libcopybit/copybit.cpp
new file mode 100644
index 0000000..886d12b
--- /dev/null
+++ b/libcopybit/copybit.cpp
@@ -0,0 +1,553 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2010 - 2011, Code Aurora Forum. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#define LOG_TAG "copybit"
+
+#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"
+
+#define DEBUG_MDP_ERRORS 1
+
+/******************************************************************************/
+
+#if defined(COPYBIT_MSM7K)
+#define MAX_SCALE_FACTOR    (4)
+#define MAX_DIMENSION       (4096)
+#elif defined(COPYBIT_QSD8K)
+#define MAX_SCALE_FACTOR    (8)
+#define MAX_DIMENSION       (2048)
+#else
+#error "Unsupported MDP version"
+#endif
+
+/******************************************************************************/
+
+/** State information for each device instance */
+struct copybit_context_t {
+    struct copybit_device_t device;
+    int     mFD;
+    uint8_t mAlpha;
+    int     mFlags;
+};
+
+/**
+ * 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);
+}
+
+/** 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_RGBX_8888:     return MDP_RGBX_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_SP:  return MDP_Y_CBCR_H2V1;
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP:  return MDP_Y_CBCR_H2V2;
+        case HAL_PIXEL_FORMAT_YCbCr_422_SP:  return MDP_Y_CRCB_H2V1;
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP:  return MDP_Y_CRCB_H2V2;
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: return MDP_Y_CBCR_H2V2_ADRENO;
+    }
+    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     = hnd->offset;
+    img->memory_id  = hnd->fd;
+}
+/** setup rectangles */
+static void 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,
+                      uint32_t horiz_padding,
+                      uint32_t vert_padding) {
+    struct copybit_rect_t clip;
+    intersect(&clip, scissor, dst);
+
+    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);
+        }
+    }
+}
+
+/** setup mdp request */
+static void set_infos(struct copybit_context_t *dev,
+                      struct mdp_blit_req *req, int flags)
+{
+    req->alpha = dev->mAlpha;
+    req->transp_mask = MDP_TRANSP_NOP;
+    req->flags = dev->mFlags | flags;
+#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 = ioctl(dev->mFD, MSMFB_BLIT,
+                    (struct mdp_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_blit_req_list const* l =
+            (struct mdp_blit_req_list const*)list;
+        for (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=%08lx"
+                  ,
+                  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
+                 );
+        }
+#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 = 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_PREMULTIPLIED_ALPHA:
+                if(value == COPYBIT_ENABLE) {
+                    ctx->mFlags |= MDP_BLEND_FG_PREMULT;
+                } else if (value == COPYBIT_DISABLE) {
+                    ctx->mFlags &= ~MDP_BLEND_FG_PREMULT;
+                }
+                break;
+            case COPYBIT_TRANSFORM:
+                ctx->mFlags &= ~0x7;
+                ctx->mFlags |= value & 0x7;
+                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;
+}
+
+/** 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;
+    int status = 0;
+    private_handle_t *yv12_handle = NULL;
+    if (ctx) {
+        struct {
+            uint32_t count;
+            struct mdp_blit_req req[12];
+        } 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 || src_rect->r > src->w ||
+            src_rect->t < 0 || 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_ADSP_HEAP |
+                GRALLOC_USAGE_PRIVATE_MM_HEAP;
+            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 = sizeof(list.req)/sizeof(list.req[0]);
+        const struct copybit_rect_t bounds = { 0, 0, dst->w, dst->h };
+        struct copybit_rect_t clip;
+        list.count = 0;
+        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_DO_NOT_FLUSH) {
+                flags |=  MDP_BLIT_NON_CACHED;
+            }
+
+            set_infos(ctx, req, flags);
+            set_image(&req->dst, dst);
+            set_image(&req->src, src);
+            set_rects(ctx, req, dst_rect, src_rect, &clip, src->horiz_padding, src->vert_padding);
+
+            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.count = 0;
+            }
+        }
+        if ((status == 0) && list.count) {
+            status = msm_copybit(ctx, &list);
+        }
+    } else {
+        ALOGE ("%s : Invalid COPYBIT context", __FUNCTION__);
+        status = -EINVAL;
+    }
+    if(yv12_handle)
+        free_buffer(yv12_handle);
+    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, dst->w, dst->h };
+    struct copybit_rect_t sr = { 0, 0, src->w, src->h };
+    return stretch_copybit(dev, dst, src, &dr, &sr, region);
+}
+
+/*****************************************************************************/
+
+/** 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;
+}
+
+/** 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;
+    copybit_context_t *ctx;
+    ctx = (copybit_context_t *)malloc(sizeof(copybit_context_t));
+    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.stretch = stretch_copybit;
+    ctx->mAlpha = MDP_ALPHA_NOP;
+    ctx->mFlags = 0;
+    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 {
+        struct fb_fix_screeninfo finfo;
+        if (ioctl(ctx->mFD, FBIOGET_FSCREENINFO, &finfo) == 0) {
+            if (strncmp(finfo.id, "msmfb", 5) == 0) {
+                /* Success */
+                status = 0;
+            } else {
+                ALOGE("Error not msm frame buffer");
+                status = -EINVAL;
+            }
+        } else {
+            ALOGE("Error executing ioctl for screen info");
+            status = -errno;
+        }
+    }
+
+    if (status == 0) {
+        *device = &ctx->device.common;
+    } else {
+        close_copybit(&ctx->device.common);
+    }
+    return status;
+}
diff --git a/libcopybit/copybit.h b/libcopybit/copybit.h
new file mode 100644
index 0000000..6384dfe
--- /dev/null
+++ b/libcopybit/copybit.h
@@ -0,0 +1,230 @@
+/*
+ * 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 ANDROID_COPYBIT_INTERFACE_H
+#define ANDROID_COPYBIT_INTERFACE_H
+
+#include <hardware/hardware.h>
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+#include <sys/types.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 {
+    /* 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,
+    /* Informs the copybit that the source and destination contains
+       premultiplied alpha */
+    COPYBIT_PREMULTIPLIED_ALPHA  = 6,
+    /* FB width */
+    COPYBIT_FRAMEBUFFER_WIDTH = 7,
+    /* FB height */
+    COPYBIT_FRAMEBUFFER_HEIGHT = 8,
+};
+
+/* 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
+};
+
+/* 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,
+};
+
+/* 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);
+
+    /**
+     * 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);
+};
+
+
+/** 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/libcopybit/copybit_c2d.cpp b/libcopybit/copybit_c2d.cpp
new file mode 100644
index 0000000..72aa279
--- /dev/null
+++ b/libcopybit/copybit_c2d.cpp
@@ -0,0 +1,1477 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "copybit_c2d"
+
+#include <cutils/log.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 <cutils/ashmem.h>
+#include <linux/ashmem.h>
+#include <gralloc_priv.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;
+using android::sp;
+
+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, uint32 len, uint32 offset, uint32 flags, void ** gpuaddr);
+
+C2D_STATUS (*LINK_c2dUnMapAddr) ( void * gpuaddr);
+
+/******************************************************************************/
+
+#if defined(COPYBIT_Z180)
+#define MAX_SCALE_FACTOR    (4096)
+#define MAX_DIMENSION       (4096)
+#else
+#error "Unsupported HW version"
+#endif
+
+#define NUM_SURFACES 3
+
+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
+};
+
+static android::sp<gralloc::IAllocController> sAlloc = 0;
+/******************************************************************************/
+
+/** State information for each device instance */
+struct copybit_context_t {
+    struct copybit_device_t device;
+    unsigned int src[NUM_SURFACES];  /* src surfaces */
+    unsigned int dst[NUM_SURFACES];  /* dst surfaces */
+    unsigned int trg_transform;      /* target transform */
+    C2D_OBJECT blitState;
+    void *libc2d2;
+    alloc_data temp_src_buffer;
+    alloc_data temp_dst_buffer;
+    int fb_width;
+    int fb_height;
+    bool isPremultipliedAlpha;
+};
+
+struct blitlist{
+    uint32_t count;
+    C2D_OBJECT blitObjects[12];
+};
+
+struct bufferInfo {
+    int width;
+    int height;
+    int format;
+};
+
+struct yuvPlaneInfo {
+    int yStride;       //luma stride
+    int plane1_stride;
+    int plane2_stride;
+    int plane1_offset;
+    int 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
+        }
+};
+
+
+/* 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_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_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 uint32 c2d_get_gpuaddr( struct private_handle_t *handle)
+{
+    uint32 memtype, *gpuaddr;
+    C2D_STATUS rc;
+
+    if(!handle)
+        return 0;
+
+    if (handle->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM |
+                         private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP))
+        memtype = KGSL_USER_MEM_TYPE_PMEM;
+    else if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ASHMEM)
+        memtype = KGSL_USER_MEM_TYPE_ASHMEM;
+    else 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;
+    }
+
+    rc = LINK_c2dMapAddr(handle->fd, (void*)handle->base, handle->size, handle->offset, memtype, (void**)&gpuaddr);
+    if (rc == C2D_STATUS_OK) {
+        return (uint32) gpuaddr;
+    }
+    return 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_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( uint32 surfaceId, const struct copybit_image_t *rhs,
+                      int *cformat, uint32_t *mapped, const eC2DFlags flags)
+{
+    struct private_handle_t* handle = (struct private_handle_t*)rhs->handle;
+    C2D_SURFACE_TYPE surfaceType;
+    int status = COPYBIT_SUCCESS;
+
+    if (flags & FLAGS_YUV_DESTINATION) {
+        *cformat = get_c2d_format_for_yuv_destination(rhs->format);
+    } else {
+        *cformat = get_format(rhs->format);
+    }
+
+    if(*cformat == -EINVAL) {
+        ALOGE("%s: invalid format", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    if(handle == NULL) {
+        ALOGE("%s: invalid handle", __func__);
+        return -EINVAL;
+    }
+
+    if (handle->gpuaddr == 0) {
+        handle->gpuaddr = c2d_get_gpuaddr(handle);
+        if(!handle->gpuaddr) {
+            ALOGE("%s: c2d_get_gpuaddr failed", __FUNCTION__);
+            return COPYBIT_FAILURE;
+        }
+        *mapped = 1;
+    }
+
+    /* 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*) handle->gpuaddr;
+        surfaceDef.buffer = (void*) (handle->base);
+
+        surfaceDef.format = *cformat |
+            ((flags & FLAGS_PREMULTIPLIED_ALPHA) ? C2D_FORMAT_PREMULTIPLIED : 0);
+        surfaceDef.width = rhs->w;
+        surfaceDef.height = rhs->h;
+        int aligned_width = ALIGN(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__);
+            goto error;
+            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 = *cformat;
+
+        bufferInfo info;
+        info.width = rhs->w;
+        info.height = rhs->h;
+        info.format = rhs->format;
+
+        yuvPlaneInfo yuvInfo;
+        status = calculate_yuv_offset_and_stride(info, yuvInfo);
+        if(status != COPYBIT_SUCCESS) {
+            ALOGE("%s: calculate_yuv_offset_and_stride error", __FUNCTION__);
+            goto error;
+        }
+
+        surfaceDef.width = rhs->w;
+        surfaceDef.height = rhs->h;
+        surfaceDef.plane0 = (void*) (handle->base);
+        surfaceDef.phys0 = (void*) (handle->gpuaddr);
+        surfaceDef.stride0 = yuvInfo.yStride;
+
+        surfaceDef.plane1 = (void*) (handle->base + yuvInfo.plane1_offset);
+        surfaceDef.phys1 = (void*) (handle->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*) (handle->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__);
+            goto error;
+            status = COPYBIT_FAILURE;
+        }
+    } else {
+        ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format);
+        goto error;
+        status = COPYBIT_FAILURE;
+    }
+
+    return status;
+
+error:
+    if(*mapped == 1) {
+        LINK_c2dUnMapAddr( (void*) handle->gpuaddr);
+        handle->gpuaddr = 0;
+        *mapped = 0;
+    }
+    return status;
+}
+
+static int set_src_image( uint32 *surfaceId, const struct copybit_image_t *rhs,
+                          int *cformat, uint32 *mapped)
+{
+    struct private_handle_t* handle = (struct private_handle_t*)rhs->handle;
+    *cformat  = get_format(rhs->format);
+    C2D_SURFACE_TYPE surfaceType;
+    uint32 gpuaddr = (uint32)handle->gpuaddr;
+    int status = COPYBIT_SUCCESS;
+
+    if (handle->gpuaddr == 0)
+    {
+        handle->gpuaddr = c2d_get_gpuaddr( handle);
+        if(!handle->gpuaddr)
+            return COPYBIT_FAILURE;
+
+        *mapped = 1;
+    }
+
+    /* 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 | C2D_SURFACE_WITH_PHYS_DUMMY);
+
+        surfaceDef.phys = (void*) handle->gpuaddr;
+        surfaceDef.buffer = (void*) (handle->base);
+        surfaceDef.buffer = (void*) (handle->base + handle->offset);
+
+        surfaceDef.format = get_format(rhs->format);
+        surfaceDef.width = rhs->w;
+        surfaceDef.height = rhs->h;
+        surfaceDef.stride = ALIGN(((surfaceDef.width * c2diGetBpp(surfaceDef.format))>>3), 32);
+
+        if(LINK_c2dCreateSurface( surfaceId, C2D_TARGET, surfaceType,(void*)&surfaceDef)) {
+            ALOGE("%s: LINK_c2dCreateSurface error", __FUNCTION__);
+            status = COPYBIT_FAILURE;
+            goto error;
+        }
+    } else if(is_supported_yuv_format(rhs->format) == COPYBIT_SUCCESS) {
+        /* YUV */
+        C2D_YUV_SURFACE_DEF surfaceDef;
+        int offset = 0;
+        int yStride = 0;
+        int uvStride = 0;
+        memset(&surfaceDef, 0, sizeof(surfaceDef));
+
+        surfaceType = (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS | C2D_SURFACE_WITH_PHYS_DUMMY);
+        surfaceDef.format = get_format(rhs->format);
+        bufferInfo info;
+        info.width = rhs->w;
+        info.height = rhs->h;
+        info.format = rhs->format;
+
+        yuvPlaneInfo yuvInfo;
+        status = calculate_yuv_offset_and_stride(info, yuvInfo);
+        if(status != COPYBIT_SUCCESS) {
+            ALOGE("%s: calculate_yuv_offset_and_stride error", __FUNCTION__);
+            goto error;
+        }
+
+        surfaceDef.width = rhs->w;
+        surfaceDef.height = rhs->h;
+        surfaceDef.plane0 = (void*) (handle->base);
+        surfaceDef.phys0 = (void*) handle->gpuaddr;
+        surfaceDef.stride0 = yuvInfo.yStride;
+
+        surfaceDef.plane1 = (void*) (handle->base + yuvInfo.plane1_offset);
+        surfaceDef.phys1 = (void*) (handle->gpuaddr + yuvInfo.plane1_offset);
+        surfaceDef.stride1 = yuvInfo.plane1_stride;
+
+        if(LINK_c2dCreateSurface( surfaceId, C2D_TARGET | C2D_SOURCE, surfaceType,
+                                  (void*)&surfaceDef)) {
+            ALOGE("%s: YUV surface LINK_c2dCreateSurface error", __func__);
+            status = COPYBIT_FAILURE;
+            goto error;
+        }
+    } else {
+        ALOGE("%s: Invalid format 0x%x", __FUNCTION__, rhs->format);
+        status = COPYBIT_FAILURE;
+    }
+
+    return COPYBIT_SUCCESS;
+
+error:
+    if(*mapped == 1) {
+        LINK_c2dUnMapAddr( (void*) handle->gpuaddr);
+        handle->gpuaddr = 0;
+        *mapped = 0;
+    }
+    return status;
+}
+
+void unset_image( uint32 surfaceId, const struct copybit_image_t *rhs,
+                  uint32 mmapped)
+{
+    struct private_handle_t* handle = (struct private_handle_t*)rhs->handle;
+
+    if (mmapped && handle->gpuaddr) {
+        // Unmap this gpuaddr
+        LINK_c2dUnMapAddr( (void*) handle->gpuaddr);
+        handle->gpuaddr = 0;
+    }
+}
+
+static int blit_to_target( uint32 surfaceId, const struct copybit_image_t *rhs)
+{
+    struct private_handle_t* handle = (struct private_handle_t*)rhs->handle;
+    uint32 cformat  = get_format(rhs->format);
+    C2D_SURFACE_TYPE surfaceType;
+    uint32 memoryMapped = 0;
+    int status = COPYBIT_SUCCESS;
+
+    if (!handle->gpuaddr) {
+        handle->gpuaddr = c2d_get_gpuaddr(handle);
+        if(!handle->gpuaddr)
+            return COPYBIT_FAILURE;
+
+        memoryMapped = 1;
+    }
+
+    /* create C2D surface */
+
+    if(cformat) {
+        /* RGB */
+        C2D_RGB_SURFACE_DEF surfaceDef;
+        memset(&surfaceDef, 0, sizeof(surfaceDef));
+
+        surfaceDef.buffer = (void*) handle->base;
+        surfaceDef.phys = (void*) handle->gpuaddr;
+
+        surfaceType = C2D_SURFACE_RGB_HOST;
+        surfaceDef.format = get_format(rhs->format);
+        surfaceDef.width = rhs->w;
+        surfaceDef.height = rhs->h;
+        surfaceDef.stride = ALIGN(((surfaceDef.width * c2diGetBpp(surfaceDef.format))>>3), 32);
+
+        if(LINK_c2dReadSurface(surfaceId, surfaceType, (void*)&surfaceDef, 0, 0)) {
+            ALOGE("%s: LINK_c2dReadSurface ERROR", __func__);
+            status = COPYBIT_FAILURE;
+            goto done;
+        }
+    }
+    else {
+        /* YUV */
+        /* TODO */
+    }
+
+done:
+    if (memoryMapped) {
+        LINK_c2dUnMapAddr( (void*) handle->gpuaddr);
+        handle->gpuaddr = 0;
+    }
+    return status;
+}
+
+/** 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;
+}
+
+/** copy the bits */
+static int msm_copybit(struct copybit_context_t *dev, blitlist *list, uint32 target)
+{
+    int objects;
+
+    for(objects = 0; objects < list->count; objects++) {
+        list->blitObjects[objects].next = &(list->blitObjects[objects+1]);
+    }
+
+    if(LINK_c2dDraw(target,dev->trg_transform, 0x0, 0, 0, list->blitObjects,
+                    list->count)) {
+        ALOGE("%s: LINK_c2dDraw ERROR", __FUNCTION__);
+        return COPYBIT_FAILURE;
+    }
+
+    return COPYBIT_SUCCESS;
+}
+
+/*****************************************************************************/
+
+/** 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;
+    if (!ctx) {
+        ALOGE("%s: null context", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    switch(name) {
+        case COPYBIT_ROTATION_DEG:
+            ctx->blitState.rotation = value<<16;
+            /* SRC rotation */
+            if(!value)
+                ctx->blitState.config_mask &=~C2D_ROTATE_BIT;;
+            break;
+        case COPYBIT_PLANE_ALPHA:
+            if (value < 0)      value = 0;
+            if (value >= 256)   value = 255;
+
+            ctx->blitState.global_alpha = value;
+
+            if(ctx->blitState.global_alpha<255)
+                ctx->blitState.config_mask |= C2D_GLOBAL_ALPHA_BIT;
+            else
+                ctx->blitState.config_mask &=~C2D_GLOBAL_ALPHA_BIT;
+            break;
+        case COPYBIT_DITHER:
+            /* TODO */
+            break;
+        case COPYBIT_BLUR:
+            /* TODO */
+            break;
+        case COPYBIT_TRANSFORM:
+            ctx->blitState.config_mask &=~C2D_ROTATE_BIT;
+            ctx->blitState.config_mask &=~C2D_MIRROR_H_BIT;
+            ctx->blitState.config_mask &=~C2D_MIRROR_V_BIT;
+            ctx->trg_transform = C2D_TARGET_ROTATE_0;
+
+            if((value&0x7) == COPYBIT_TRANSFORM_ROT_180)
+                ctx->trg_transform = C2D_TARGET_ROTATE_180;
+            else if((value&0x7) == COPYBIT_TRANSFORM_ROT_270)
+                ctx->trg_transform = C2D_TARGET_ROTATE_90;
+            else {
+                if(value&COPYBIT_TRANSFORM_FLIP_H)
+                    ctx->blitState.config_mask |= C2D_MIRROR_H_BIT;
+                if(value&COPYBIT_TRANSFORM_FLIP_V)
+                    ctx->blitState.config_mask |= C2D_MIRROR_V_BIT;
+                if(value&COPYBIT_TRANSFORM_ROT_90)
+                    ctx->trg_transform = C2D_TARGET_ROTATE_270;
+            }
+            break;
+        case COPYBIT_PREMULTIPLIED_ALPHA:
+            (value == COPYBIT_ENABLE) ? ctx->isPremultipliedAlpha = true :
+                ctx->isPremultipliedAlpha = false;
+            break;
+        case COPYBIT_FRAMEBUFFER_WIDTH:
+            ctx->fb_width = value;
+            break;
+        case COPYBIT_FRAMEBUFFER_HEIGHT:
+            ctx->fb_height = value;
+            break;
+        default:
+            ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
+            return -EINVAL;
+            break;
+    }
+
+    return COPYBIT_SUCCESS;
+}
+
+/** 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;
+        default:
+            ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
+            value = -EINVAL;
+    }
+    return value;
+}
+
+static int is_alpha(int cformat)
+{
+    int alpha = 0;
+    switch (cformat & 0xFF) {
+        case C2D_COLOR_FORMAT_8888_ARGB:
+        case C2D_COLOR_FORMAT_8888_RGBA:
+        case C2D_COLOR_FORMAT_5551_RGBA:
+        case C2D_COLOR_FORMAT_4444_ARGB:
+            alpha = 1;
+            break;
+        default:
+            alpha = 0;
+            break;
+    }
+
+    if(alpha && (cformat&C2D_FORMAT_DISABLE_ALPHA))
+        alpha = 0;
+
+    return alpha;
+}
+
+/* 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 size_t get_size(const bufferInfo& info)
+{
+    size_t 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(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(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 = GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP;
+
+    if (sAlloc == 0) {
+        sAlloc = gralloc::IAllocController::getInstance(false);
+    }
+
+    if (sAlloc == 0) {
+        ALOGE("%s: sAlloc is still NULL", __FUNCTION__);
+        return COPYBIT_FAILURE;
+    }
+
+    int err = sAlloc->allocate(data, allocFlags, 0);
+    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) {
+        sp<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;
+    }
+}
+/** 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;
+    uint32 maxCount;
+    uint32 src_mapped = 0, trg_mapped = 0;
+    blitlist list;
+    C2D_OBJECT *req;
+    memset(&list, 0, sizeof(list));
+    int cformat;
+    c2d_ts_handle timestamp;
+    uint32 src_surface_index = 0, dst_surface_index = 0;
+
+    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;
+    }
+
+    maxCount = sizeof(list.blitObjects)/sizeof(C2D_OBJECT);
+
+    struct copybit_rect_t clip;
+    list.count = 0;
+
+    if (is_valid_destination_format(dst->format) == COPYBIT_FAILURE) {
+        ALOGE("%s: Invalid destination format format = 0x%x", __FUNCTION__, dst->format);
+        return COPYBIT_FAILURE;
+    }
+
+    bool isYUVDestination = false;
+    if (is_supported_rgb_format(dst->format) == COPYBIT_SUCCESS) {
+        dst_surface_index = RGB_SURFACE;
+    } else if (is_supported_yuv_format(dst->format) == COPYBIT_SUCCESS) {
+        isYUVDestination = true;
+        int num_planes = get_num_planes(dst->format);
+        if (num_planes == 2) {
+            dst_surface_index = YUV_SURFACE_2_PLANES;
+        } else if (num_planes == 3) {
+            dst_surface_index = 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;
+    }
+
+    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 needTempDestination = 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 (needTempDestination) {
+        if (get_size(dst_info) != 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 = (int)(ctx->temp_dst_buffer.base);
+        dst_hnd->offset = ctx->temp_dst_buffer.offset;
+        dst_hnd->gpuaddr = 0;
+        dst_image.handle = dst_hnd;
+    }
+
+    int flags = 0;
+    flags |= (ctx->isPremultipliedAlpha) ? FLAGS_PREMULTIPLIED_ALPHA : 0;
+    flags |= (isYUVDestination) ? FLAGS_YUV_DESTINATION : 0;
+
+    status = set_image( ctx->dst[dst_surface_index], &dst_image,
+                        &cformat, &trg_mapped, (eC2DFlags)flags);
+    if(status) {
+        ALOGE("%s: dst: set_image error", __FUNCTION__);
+        delete_handle(dst_hnd);
+        return COPYBIT_FAILURE;
+    }
+
+    if(is_supported_rgb_format(src->format) == COPYBIT_SUCCESS) {
+        src_surface_index = RGB_SURFACE;
+    } else if (is_supported_yuv_format(src->format) == COPYBIT_SUCCESS) {
+        int num_planes = get_num_planes(src->format);
+        if (num_planes == 2) {
+            src_surface_index = YUV_SURFACE_2_PLANES;
+        } else if (num_planes == 3) {
+            src_surface_index = YUV_SURFACE_3_PLANES;
+        } else {
+            ALOGE("%s: src number of YUV planes is invalid src format = 0x%x",
+                  __FUNCTION__, src->format);
+            delete_handle(dst_hnd);
+            return -EINVAL;
+        }
+    } else {
+        ALOGE("%s: Invalid source surface format 0x%x", __FUNCTION__, src->format);
+        delete_handle(dst_hnd);
+        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 needTempSource = 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);
+        return COPYBIT_FAILURE;
+    }
+    if (needTempSource) {
+        if (get_size(src_info) != 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);
+                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 = (int)(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.
+        copy_image((private_handle_t *)src->handle, &src_image, CONVERT_TO_C2D_FORMAT);
+
+        // Flush the cache
+        sp<IMemAlloc> memalloc = sAlloc->getAllocator(src_hnd->flags);
+        if (memalloc->clean_buffer((void *)(src_hnd->base), src_hnd->size,
+                                   src_hnd->offset, src_hnd->fd)) {
+            ALOGE("%s: clean_buffer failed", __FUNCTION__);
+            delete_handle(dst_hnd);
+            delete_handle(src_hnd);
+            return COPYBIT_FAILURE;
+        }
+    }
+
+    status = set_image( ctx->src[src_surface_index], &src_image,
+                        &cformat, &src_mapped, (eC2DFlags)flags);
+    if(status) {
+        ALOGE("%s: set_src_image error", __FUNCTION__);
+        delete_handle(dst_hnd);
+        delete_handle(src_hnd);
+        return COPYBIT_FAILURE;
+    }
+
+    if (enableBlend) {
+        if(ctx->blitState.config_mask & C2D_GLOBAL_ALPHA_BIT) {
+            ctx->blitState.config_mask &= ~C2D_ALPHA_BLEND_NONE;
+            if(!(ctx->blitState.global_alpha)) {
+                // src alpha is zero
+                unset_image( ctx->src[src_surface_index],
+                             &src_image, src_mapped);
+                unset_image( ctx->dst[dst_surface_index],
+                             &dst_image, trg_mapped);
+                delete_handle(dst_hnd);
+                delete_handle(src_hnd);
+                return status;
+            }
+        } else {
+            if(is_alpha(cformat))
+                ctx->blitState.config_mask &= ~C2D_ALPHA_BLEND_NONE;
+            else
+                ctx->blitState.config_mask |= C2D_ALPHA_BLEND_NONE;
+        }
+    } else {
+        ctx->blitState.config_mask |= C2D_ALPHA_BLEND_NONE;
+    }
+
+    ctx->blitState.surface_id = ctx->src[src_surface_index];
+
+    while ((status == 0) && region->next(region, &clip)) {
+        req = &(list.blitObjects[list.count]);
+        memcpy(req,&ctx->blitState,sizeof(C2D_OBJECT));
+
+        set_rects(ctx, req, dst_rect, src_rect, &clip);
+
+        if (++list.count == maxCount) {
+            status = msm_copybit(ctx, &list, ctx->dst[dst_surface_index]);
+            list.count = 0;
+        }
+    }
+    if ((status == 0) && list.count) {
+        status = msm_copybit(ctx, &list, ctx->dst[dst_surface_index]);
+    }
+
+    if(LINK_c2dFinish(ctx->dst[dst_surface_index])) {
+        ALOGE("%s: LINK_c2dFinish ERROR", __FUNCTION__);
+    }
+
+    unset_image( ctx->src[src_surface_index], &src_image,
+                 src_mapped);
+    unset_image( ctx->dst[dst_surface_index], &dst_image,
+                 trg_mapped);
+    if (needTempDestination) {
+        // copy the temp. destination without the alignment to the actual destination.
+        copy_image(dst_hnd, dst, CONVERT_TO_ANDROID_FORMAT);
+        // Invalidate the cache.
+        sp<IMemAlloc> memalloc = sAlloc->getAllocator(dst_hnd->flags);
+        memalloc->clean_buffer((void *)(dst_hnd->base), dst_hnd->size,
+                               dst_hnd->offset, dst_hnd->fd);
+    }
+    delete_handle(dst_hnd);
+    delete_handle(src_hnd);
+    ctx->isPremultipliedAlpha = false;
+    ctx->fb_width = 0;
+    ctx->fb_height = 0;
+    return status;
+}
+
+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;
+    bool needsBlending = (ctx->blitState.global_alpha != 0);
+    return stretch_copybit_internal(dev, dst, src, dst_rect, src_rect,
+                                    region, needsBlending);
+}
+
+/** 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, dst->w, dst->h };
+    struct copybit_rect_t sr = { 0, 0, src->w, src->h };
+    return stretch_copybit_internal(dev, dst, src, &dr, &sr, region, false);
+}
+
+/*****************************************************************************/
+
+/** 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) {
+        for(int i = 0; i <NUM_SURFACES; i++) {
+            LINK_c2dDestroySurface(ctx->dst[i]);
+            LINK_c2dDestroySurface(ctx->src[i]);
+        }
+
+        if (ctx->libc2d2) {
+            ::dlclose(ctx->libc2d2);
+            ALOGV("dlclose(libc2d2)");
+        }
+
+        free_temp_buffer(ctx->temp_src_buffer);
+        free_temp_buffer(ctx->temp_dst_buffer);
+        free(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;
+    C2D_RGB_SURFACE_DEF surfDefinition = {0};
+    C2D_YUV_SURFACE_DEF yuvSurfaceDef = {0} ;
+    struct copybit_context_t *ctx;
+    char fbName[64];
+
+    ctx = (struct copybit_context_t *)malloc(sizeof(struct copybit_context_t));
+    if(!ctx) {
+        ALOGE("%s: malloc failed", __FUNCTION__);
+        return COPYBIT_FAILURE;
+    }
+
+    /* initialize drawstate */
+    memset(ctx, 0, sizeof(*ctx));
+
+    for (int i=0; i< NUM_SURFACES; i++) {
+        ctx->dst[i] = -1;
+        ctx->src[i] = -1;
+    }
+
+    ctx->libc2d2 = ::dlopen("libC2D2.so", RTLD_NOW);
+    if (!ctx->libc2d2) {
+        ALOGE("FATAL ERROR: could not dlopen libc2d2.so: %s", dlerror());
+        goto error;
+    }
+    *(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");
+
+    if (!LINK_c2dCreateSurface || !LINK_c2dUpdateSurface || !LINK_c2dReadSurface
+        || !LINK_c2dDraw || !LINK_c2dFlush || !LINK_c2dWaitTimestamp || !LINK_c2dFinish
+        || !LINK_c2dDestroySurface) {
+        ALOGE("%s: dlsym ERROR", __FUNCTION__);
+        goto error;
+    }
+
+    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.stretch = stretch_copybit;
+    ctx->blitState.config_mask = C2D_NO_BILINEAR_BIT | C2D_NO_ANTIALIASING_BIT;
+    ctx->trg_transform = C2D_TARGET_ROTATE_0;
+
+    /* 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[RGB_SURFACE] failed", __FUNCTION__);
+        ctx->dst[RGB_SURFACE] = -1;
+        goto error;
+    }
+
+
+    if (LINK_c2dCreateSurface(&(ctx->src[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->src[RGB_SURFACE] failed", __FUNCTION__);
+        ctx->src[RGB_SURFACE] = -1;
+        goto error;
+    }
+
+    /* Create YUV source surface */
+    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->src[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->src[YUV_SURFACE_2_PLANES] failed", __FUNCTION__);
+        ctx->src[YUV_SURFACE_2_PLANES] = -1;
+        goto error;
+    }
+
+    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] = -1;
+        goto error;
+    }
+
+    yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_YV12;
+    yuvSurfaceDef.plane2 = (void*)0xaaaaaaaa;
+    yuvSurfaceDef.phys2 = (void*) 0xaaaaaaaa;
+    yuvSurfaceDef.stride2 = 4;
+
+    if (LINK_c2dCreateSurface(&(ctx->src[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->src[YUV_SURFACE_3_PLANES] failed", __FUNCTION__);
+        ctx->src[YUV_SURFACE_3_PLANES] = -1;
+        goto error;
+    }
+
+    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] = -1;
+        goto error;
+    }
+
+    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->isPremultipliedAlpha = false;
+
+    *device = &ctx->device.common;
+    return status;
+
+error:
+    for (int i = 0; i<NUM_SURFACES; i++) {
+        if (-1 != (ctx->src[i])) {
+            LINK_c2dDestroySurface(ctx->src[i]);
+            ctx->src[i] = -1;
+        }
+        if (-1 != (ctx->dst[i])) {
+            LINK_c2dDestroySurface(ctx->dst[i]);
+            ctx->dst[i] = -1;
+        }
+    }
+    if (ctx->libc2d2)
+        ::dlclose(ctx->libc2d2);
+    if (ctx)
+        free(ctx);
+    status = COPYBIT_FAILURE;
+    *device = NULL;
+
+    return status;
+}
diff --git a/libcopybit/copybit_priv.h b/libcopybit/copybit_priv.h
new file mode 100644
index 0000000..fd1b27e
--- /dev/null
+++ b/libcopybit/copybit_priv.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#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/libcopybit/software_converter.cpp b/libcopybit/software_converter.cpp
new file mode 100644
index 0000000..c9bb674
--- /dev/null
+++ b/libcopybit/software_converter.cpp
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LOG_TAG "copybit"
+#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, 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);
+
+#ifdef __ARM_HAVE_NEON
+   /* 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;
+    int src_plane1_offset;
+    int src_plane2_offset;
+    int dst_plane1_offset;
+    int dst_plane2_offset;
+};
+
+/* Internal function to do the actual copy of source to destination */
+static int copy_source_to_destination(const int src_base, const int dst_base,
+                                      copyInfo& info)
+{
+    if (!src_base || !dst_base) {
+        ALOGE("%s: invalid memory src_base = 0x%x dst_base=0x%x",
+             __FUNCTION__, src_base, 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(hnd->base, 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(hnd->base, dst_hnd->base, info);
+    return ret;
+}
diff --git a/libcopybit/software_converter.h b/libcopybit/software_converter.h
new file mode 100644
index 0000000..54b503d
--- /dev/null
+++ b/libcopybit/software_converter.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+
+#include <copybit.h>
+#include "gralloc_priv.h"
+#include "gr.h"
+
+#define COPYBIT_SUCCESS 0
+#define COPYBIT_FAILURE -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/libgenlock/Android.mk b/libgenlock/Android.mk
index 740d6ce..6ae8909 100644
--- a/libgenlock/Android.mk
+++ b/libgenlock/Android.mk
@@ -4,8 +4,7 @@
 LOCAL_PRELINK_MODULE := false
 LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)
 LOCAL_SHARED_LIBRARIES := liblog libcutils
-LOCAL_C_INCLUDES :=
-LOCAL_C_INCLUDES += hardware/qcom/display/libgralloc
+LOCAL_C_INCLUDES := hardware/qcom/display/libgralloc
 LOCAL_ADDITIONAL_DEPENDENCIES :=
 LOCAL_SRC_FILES := genlock.cpp
 LOCAL_CFLAGS:= -DLOG_TAG=\"libgenlock\"
diff --git a/libgenlock/genlock.cpp b/libgenlock/genlock.cpp
index 5d5536b..bfec641 100644
--- a/libgenlock/genlock.cpp
+++ b/libgenlock/genlock.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -43,7 +43,7 @@
 #endif
 
 namespace {
-    /* Internal function to map the userspace locks to the kernel lock types */
+/* Internal function to map the userspace locks to the kernel lock types */
     int get_kernel_lock_type(genlock_lock_type lockType)
     {
         int kLockType = 0;
@@ -62,7 +62,7 @@
 
     /* Internal function to perform the actual lock/unlock operations */
     genlock_status_t perform_lock_unlock_operation(native_handle_t *buffer_handle,
-            int lockType, int timeout)
+                                                   int lockType, int timeout)
     {
         if (private_handle_t::validate(buffer_handle)) {
             ALOGE("%s: handle is invalid", __FUNCTION__);
@@ -73,7 +73,7 @@
         if ((hnd->flags & private_handle_t::PRIV_FLAGS_UNSYNCHRONIZED) == 0) {
             if (hnd->genlockPrivFd < 0) {
                 ALOGE("%s: the lock has not been created, or has not been attached",
-                        __FUNCTION__);
+                      __FUNCTION__);
                 return GENLOCK_FAILURE;
             }
 
@@ -85,7 +85,7 @@
 
             if (ioctl(hnd->genlockPrivFd, GENLOCK_IOC_LOCK, &lock)) {
                 ALOGE("%s: GENLOCK_IOC_LOCK failed (lockType0x%x, err=%s fd=%d)", __FUNCTION__,
-                        lockType, strerror(errno), hnd->fd);
+                      lockType, strerror(errno), hnd->fd);
                 if (ETIMEDOUT == errno)
                     return GENLOCK_TIMEDOUT;
 
@@ -132,7 +132,7 @@
         int fd = open(GENLOCK_DEVICE, O_RDWR);
         if (fd < 0) {
             ALOGE("%s: open genlock device failed (err=%s)", __FUNCTION__,
-                    strerror(errno));
+                  strerror(errno));
             return GENLOCK_FAILURE;
         }
 
@@ -140,7 +140,7 @@
         genlock_lock lock;
         if (ioctl(fd, GENLOCK_IOC_NEW, NULL)) {
             ALOGE("%s: GENLOCK_IOC_NEW failed (error=%s)", __FUNCTION__,
-                    strerror(errno));
+                  strerror(errno));
             close_genlock_fd_and_handle(fd, lock.fd);
             ret = GENLOCK_FAILURE;
         }
@@ -149,7 +149,7 @@
         if (GENLOCK_FAILURE != ret) {
             if (ioctl(fd, GENLOCK_IOC_EXPORT, &lock)) {
                 ALOGE("%s: GENLOCK_IOC_EXPORT failed (error=%s)", __FUNCTION__,
-                        strerror(errno));
+                      strerror(errno));
                 close_genlock_fd_and_handle(fd, lock.fd);
                 ret = GENLOCK_FAILURE;
             }
@@ -219,7 +219,7 @@
         int fd = open(GENLOCK_DEVICE, O_RDWR);
         if (fd < 0) {
             ALOGE("%s: open genlock device failed (err=%s)", __FUNCTION__,
-                    strerror(errno));
+                  strerror(errno));
             return GENLOCK_FAILURE;
         }
 
@@ -228,7 +228,7 @@
         lock.fd = hnd->genlockHandle;
         if (ioctl(fd, GENLOCK_IOC_ATTACH, &lock)) {
             ALOGE("%s: GENLOCK_IOC_ATTACH failed (err=%s)", __FUNCTION__,
-                    strerror(errno));
+                  strerror(errno));
             close_genlock_fd_and_handle(fd, lock.fd);
             ret = GENLOCK_FAILURE;
         }
@@ -253,8 +253,8 @@
  * @return error status.
  */
 genlock_status_t genlock_lock_buffer(native_handle_t *buffer_handle,
-        genlock_lock_type_t lockType,
-        int timeout)
+                                     genlock_lock_type_t lockType,
+                                     int timeout)
 {
     genlock_status_t ret = GENLOCK_NO_ERROR;
 #ifdef USE_GENLOCK
@@ -280,7 +280,7 @@
  *
  * @param: handle of the buffer to be unlocked.
  * @return: error status.
-*/
+ */
 genlock_status_t genlock_unlock_buffer(native_handle_t *buffer_handle)
 {
     genlock_status_t ret = GENLOCK_NO_ERROR;
diff --git a/libgenlock/genlock.h b/libgenlock/genlock.h
index b394410..0995557 100644
--- a/libgenlock/genlock.h
+++ b/libgenlock/genlock.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -36,80 +36,80 @@
 extern "C" {
 #endif
 
-/* Genlock lock types */
-typedef enum genlock_lock_type{
-    GENLOCK_READ_LOCK  = 1<<0,  // Read lock
-    GENLOCK_WRITE_LOCK = 1<<1,  // Write lock
-}genlock_lock_type_t;
+    /* Genlock lock types */
+    typedef enum genlock_lock_type{
+        GENLOCK_READ_LOCK  = 1<<0,  // Read lock
+        GENLOCK_WRITE_LOCK = 1<<1,  // Write lock
+    }genlock_lock_type_t;
 
-/* Genlock return values */
-typedef enum genlock_status{
-    GENLOCK_NO_ERROR = 0,
-    GENLOCK_TIMEDOUT,
-    GENLOCK_FAILURE,
-} genlock_status_t;
+    /* Genlock return values */
+    typedef enum genlock_status{
+        GENLOCK_NO_ERROR = 0,
+        GENLOCK_TIMEDOUT,
+        GENLOCK_FAILURE,
+    } genlock_status_t;
 
-/* Genlock defines */
+    /* Genlock defines */
 #define GENLOCK_MAX_TIMEOUT 1000 // Max 1s timeout
 
-/*
- * Create a genlock lock. The genlock lock file descriptor and the lock
- * handle are stored in the buffer_handle.
- *
- * @param: handle of the buffer
- * @return error status.
- */
-genlock_status_t genlock_create_lock(native_handle_t *buffer_handle);
+    /*
+     * Create a genlock lock. The genlock lock file descriptor and the lock
+     * handle are stored in the buffer_handle.
+     *
+     * @param: handle of the buffer
+     * @return error status.
+     */
+    genlock_status_t genlock_create_lock(native_handle_t *buffer_handle);
 
 
-/*
- * Release a genlock lock associated with the handle.
- *
- * @param: handle of the buffer
- * @return error status.
- */
-genlock_status_t genlock_release_lock(native_handle_t *buffer_handle);
+    /*
+     * Release a genlock lock associated with the handle.
+     *
+     * @param: handle of the buffer
+     * @return error status.
+     */
+    genlock_status_t genlock_release_lock(native_handle_t *buffer_handle);
 
-/*
- * Attach a lock to the buffer handle passed via an IPC.
- *
- * @param: handle of the buffer
- * @return error status.
- */
-genlock_status_t genlock_attach_lock(native_handle_t *buffer_handle);
+    /*
+     * Attach a lock to the buffer handle passed via an IPC.
+     *
+     * @param: handle of the buffer
+     * @return error status.
+     */
+    genlock_status_t genlock_attach_lock(native_handle_t *buffer_handle);
 
-/*
- * Lock the buffer specified by the buffer handle. The lock held by the buffer
- * is specified by the lockType. This function will block if a write lock is
- * requested on the buffer which has previously been locked for a read or write
- * operation. A buffer can be locked by multiple clients for read. An optional
- * timeout value can be specified. By default, there is no timeout.
- *
- * @param: handle of the buffer
- * @param: type of lock to be acquired by the buffer.
- * @param: timeout value in ms. GENLOCK_MAX_TIMEOUT is the maximum timeout value.
- * @return error status.
- */
-genlock_status_t genlock_lock_buffer(native_handle_t *buffer_handle,
-                                     genlock_lock_type_t lockType,
-                                     int timeout);
+    /*
+     * Lock the buffer specified by the buffer handle. The lock held by the buffer
+     * is specified by the lockType. This function will block if a write lock is
+     * requested on the buffer which has previously been locked for a read or write
+     * operation. A buffer can be locked by multiple clients for read. An optional
+     * timeout value can be specified. By default, there is no timeout.
+     *
+     * @param: handle of the buffer
+     * @param: type of lock to be acquired by the buffer.
+     * @param: timeout value in ms. GENLOCK_MAX_TIMEOUT is the maximum timeout value.
+     * @return error status.
+     */
+    genlock_status_t genlock_lock_buffer(native_handle_t *buffer_handle,
+                                         genlock_lock_type_t lockType,
+                                         int timeout);
 
-/*
- * Unlocks a buffer that has previously been locked by the client.
- *
- * @param: handle of the buffer to be unlocked.
- * @return: error status.
-*/
-genlock_status_t genlock_unlock_buffer(native_handle_t *buffer_handle);
+    /*
+     * Unlocks a buffer that has previously been locked by the client.
+     *
+     * @param: handle of the buffer to be unlocked.
+     * @return: error status.
+     */
+    genlock_status_t genlock_unlock_buffer(native_handle_t *buffer_handle);
 
-/*
- * Blocks the calling process until the lock held on the handle is unlocked.
- *
- * @param: handle of the buffer
- * @param: timeout value for the wait.
- * return: error status.
- */
-genlock_status_t genlock_wait(native_handle_t *buffer_handle, int timeout);
+    /*
+     * Blocks the calling process until the lock held on the handle is unlocked.
+     *
+     * @param: handle of the buffer
+     * @param: timeout value for the wait.
+     * return: error status.
+     */
+    genlock_status_t genlock_wait(native_handle_t *buffer_handle, int timeout);
 
 #ifdef __cplusplus
 }
diff --git a/libgralloc/Android.mk b/libgralloc/Android.mk
index 5377d86..44108c7 100644
--- a/libgralloc/Android.mk
+++ b/libgralloc/Android.mk
@@ -11,65 +11,48 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-
-# Use this flag until pmem/ashmem is implemented in the new gralloc
 LOCAL_PATH := $(call my-dir)
 
 # HAL module implemenation, not prelinked and stored in
 # hw/<OVERLAY_HARDWARE_MODULE_ID>.<ro.product.board>.so
 include $(CLEAR_VARS)
-LOCAL_PRELINK_MODULE := false
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
-LOCAL_SHARED_LIBRARIES := liblog libcutils libGLESv1_CM libutils libmemalloc libQcomUI
-LOCAL_SHARED_LIBRARIES += libgenlock
+LOCAL_PRELINK_MODULE   := false
+LOCAL_MODULE_PATH      := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+LOCAL_SHARED_LIBRARIES := liblog libcutils libutils libmemalloc
+LOCAL_SHARED_LIBRARIES += libgenlock libQcomUI libGLESv1_CM
+LOCAL_C_INCLUDES       := hardware/qcom/display/liboverlay/
+LOCAL_C_INCLUDES       += hardware/qcom/display/libgenlock
+LOCAL_C_INCLUDES       += hardware/qcom/display/libqcomui
+LOCAL_MODULE           := gralloc.$(TARGET_BOARD_PLATFORM)
+LOCAL_MODULE_TAGS      := optional
+LOCAL_CFLAGS           := -DLOG_TAG=\"$(TARGET_BOARD_PLATFORM).gralloc\" \
+                          -DDEBUG_CALC_FPS
+LOCAL_SRC_FILES :=  gpu.cpp gralloc.cpp framebuffer.cpp mapper.cpp
 
-LOCAL_C_INCLUDES += hardware/qcom/display/libgenlock
-LOCAL_C_INCLUDES += hardware/qcom/display/libqcomui
-LOCAL_ADDITIONAL_DEPENDENCIES +=
-LOCAL_SRC_FILES :=  framebuffer.cpp \
-                    gpu.cpp         \
-                    gralloc.cpp     \
-                    mapper.cpp
+ifeq ($(TARGET_USES_POST_PROCESSING),true)
+    LOCAL_CFLAGS     += -DUSES_POST_PROCESSING
+    LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/pp/inc
+endif
 
-LOCAL_MODULE := gralloc.$(TARGET_BOARD_PLATFORM)
-LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS:= -DLOG_TAG=\"$(TARGET_BOARD_PLATFORM).gralloc\" -DHOST -DDEBUG_CALC_FPS
-
-ifeq ($(call is-board-platform,msm7627_surf msm7627_6x),true)
-    LOCAL_CFLAGS += -DTARGET_MSM7x27
+ifeq ($(TARGET_USES_MDP3), true)
+    LOCAL_CFLAGS += -DUSE_MDP3
 endif
 
 ifeq ($(TARGET_HAVE_HDMI_OUT),true)
     LOCAL_CFLAGS += -DHDMI_DUAL_DISPLAY
-    LOCAL_C_INCLUDES += hardware/qcom/display/liboverlay
     LOCAL_SHARED_LIBRARIES += liboverlay
 endif
-
-ifeq ($(TARGET_USES_SF_BYPASS),true)
-    LOCAL_CFLAGS += -DSF_BYPASS
-endif
-
-ifeq ($(TARGET_GRALLOC_USES_ASHMEM),true)
-    LOCAL_CFLAGS += -DUSE_ASHMEM
-endif
-
 include $(BUILD_SHARED_LIBRARY)
 
 #MemAlloc Library
 include $(CLEAR_VARS)
 LOCAL_PRELINK_MODULE := false
 LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)
-LOCAL_C_INCLUDES += hardware/qcom/display/libqcomui
-LOCAL_ADDITIONAL_DEPENDENCIES +=
+LOCAL_C_INCLUDES := hardware/qcom/display/libqcomui
 LOCAL_SHARED_LIBRARIES := liblog libcutils libutils
-LOCAL_SRC_FILES :=  ionalloc.cpp \
-                    alloc_controller.cpp
+LOCAL_SRC_FILES :=  ionalloc.cpp alloc_controller.cpp
 LOCAL_CFLAGS:= -DLOG_TAG=\"memalloc\"
-
-ifeq ($(TARGET_USES_ION),true)
-    LOCAL_CFLAGS += -DUSE_ION
-endif
-
+LOCAL_CFLAGS += -DUSE_ION
 LOCAL_MODULE := libmemalloc
 LOCAL_MODULE_TAGS := optional
 include $(BUILD_SHARED_LIBRARY)
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 47cdc68..1356b2f 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -34,24 +34,26 @@
 #include "alloc_controller.h"
 #include "memalloc.h"
 #include "ionalloc.h"
+#include "pmemalloc.h"
 #include "ashmemalloc.h"
 #include "gr.h"
+#include "qcomutils/comptype.h"
 
 using namespace gralloc;
 using android::sp;
 
-const int GRALLOC_HEAP_MASK = GRALLOC_USAGE_PRIVATE_ADSP_HEAP      |
-                              GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP |
-                              GRALLOC_USAGE_PRIVATE_SMI_HEAP       |
-                              GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP    |
-                              GRALLOC_USAGE_PRIVATE_IOMMU_HEAP     |
-                              GRALLOC_USAGE_PRIVATE_MM_HEAP        |
-                              GRALLOC_USAGE_PRIVATE_WRITEBACK_HEAP |
-                              GRALLOC_USAGE_PRIVATE_CAMERA_HEAP;
+const int GRALLOC_HEAP_MASK  =  GRALLOC_USAGE_PRIVATE_ADSP_HEAP      |
+                                GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP |
+                                GRALLOC_USAGE_PRIVATE_SMI_HEAP       |
+                                GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP    |
+                                GRALLOC_USAGE_PRIVATE_IOMMU_HEAP     |
+                                GRALLOC_USAGE_PRIVATE_MM_HEAP        |
+                                GRALLOC_USAGE_PRIVATE_WRITEBACK_HEAP |
+                                GRALLOC_USAGE_PRIVATE_CAMERA_HEAP;
 
 
 //Common functions
-static bool canFallback(int compositionType, int usage, bool triedSystem)
+static bool canFallback(int usage, bool triedSystem)
 {
     // Fallback to system heap when alloc fails unless
     // 1. Composition type is MDP
@@ -60,11 +62,12 @@
     // 4. The heap type is protected
     // 5. The buffer is meant for external display only
 
-    if(compositionType == MDP_COMPOSITION)
+    if(QCCompositionType::getInstance().getCompositionType() & COMPOSITION_TYPE_MDP)
         return false;
     if(triedSystem)
         return false;
-    if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PROTECTED))
+    if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PROTECTED |
+                GRALLOC_USAGE_PRIVATE_CP_BUFFER))
         return false;
     if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_EXTERNAL_ONLY))
         return false;
@@ -107,13 +110,15 @@
 }
 
 int IonController::allocate(alloc_data& data, int usage,
-        int compositionType)
+                            int compositionType)
 {
     int ionFlags = 0;
     int ret;
     bool noncontig = false;
 
     data.uncached = useUncached(usage);
+    data.allocType = 0;
+
     if(usage & GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP)
         ionFlags |= ION_HEAP(ION_SF_HEAP_ID);
 
@@ -134,11 +139,13 @@
     if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
         ionFlags |= ION_HEAP(ION_CAMERA_HEAP_ID);
 
-    if(usage & GRALLOC_USAGE_PROTECTED)
+    if(usage & GRALLOC_USAGE_PRIVATE_CP_BUFFER)
         ionFlags |= ION_SECURE;
 
     if(usage & GRALLOC_USAGE_PRIVATE_DO_NOT_MAP)
-        data.allocType  =  private_handle_t::PRIV_FLAGS_NOT_MAPPED;
+        data.allocType  |=  private_handle_t::PRIV_FLAGS_NOT_MAPPED;
+    else
+        data.allocType  &=  ~(private_handle_t::PRIV_FLAGS_NOT_MAPPED);
 
     // if no flags are set, default to
     // SF + IOMMU heaps, so that bypass can work
@@ -149,9 +156,9 @@
 
     data.flags = ionFlags;
     ret = mIonAlloc->alloc_buffer(data);
+
     // Fallback
-    if(ret < 0 && canFallback(compositionType,
-                              usage,
+    if(ret < 0 && canFallback(usage,
                               (ionFlags & ION_SYSTEM_HEAP_ID)))
     {
         ALOGW("Falling back to system heap");
@@ -161,7 +168,7 @@
     }
 
     if(ret >= 0 ) {
-        data.allocType = private_handle_t::PRIV_FLAGS_USES_ION;
+        data.allocType |= private_handle_t::PRIV_FLAGS_USES_ION;
         if(noncontig)
             data.allocType |= private_handle_t::PRIV_FLAGS_NONCONTIGUOUS_MEM;
         if(ionFlags & ION_SECURE)
@@ -183,14 +190,14 @@
     return memalloc;
 }
 
-#if 0
 //-------------- PmemKernelController-----------------------//
-
+//XXX: Remove - we're not using pmem anymore
+#if 0
 PmemKernelController::PmemKernelController()
 {
-     mPmemAdspAlloc = new PmemKernelAlloc(DEVICE_PMEM_ADSP);
-     // XXX: Right now, there is no need to maintain an instance
-     // of the SMI allocator as we need it only in a few cases
+    mPmemAdspAlloc = new PmemKernelAlloc(DEVICE_PMEM_ADSP);
+    // XXX: Right now, there is no need to maintain an instance
+    // of the SMI allocator as we need it only in a few cases
 }
 
 PmemKernelController::~PmemKernelController()
@@ -198,7 +205,7 @@
 }
 
 int PmemKernelController::allocate(alloc_data& data, int usage,
-        int compositionType)
+                                   int compositionType)
 {
     int ret = 0;
     bool adspFallback = false;
@@ -258,12 +265,13 @@
 }
 
 int PmemAshmemController::allocate(alloc_data& data, int usage,
-        int compositionType)
+                                   int compositionType)
 {
     int ret = 0;
+    data.allocType = 0;
 
     // Make buffers cacheable by default
-        data.uncached = false;
+    data.uncached = false;
 
     // Override if we explicitly need uncached buffers
     if (usage & GRALLOC_USAGE_PRIVATE_UNCACHED)
@@ -298,7 +306,7 @@
     // Fallback
     if(ret >= 0 ) {
         data.allocType = private_handle_t::PRIV_FLAGS_USES_PMEM;
-    } else if(ret < 0 && canFallback(compositionType, usage, false)) {
+    } else if(ret < 0 && canFallback(usage, false)) {
         ALOGW("Falling back to ashmem");
         ret = mAshmemAlloc->alloc_buffer(data);
         if(ret >= 0) {
@@ -327,9 +335,8 @@
     return memalloc;
 }
 #endif
-
 size_t getBufferSizeAndDimensions(int width, int height, int format,
-                        int& alignedw, int &alignedh)
+                                  int& alignedw, int &alignedh)
 {
     size_t size;
 
@@ -376,16 +383,25 @@
             if (HAL_PIXEL_FORMAT_NV12_ENCODEABLE == format) {
                 // The encoder requires a 2K aligned chroma offset.
                 size = ALIGN(alignedw*alignedh, 2048) +
-                       (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
+                    (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
             } else {
                 size = alignedw*alignedh +
                     (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
             }
             size = ALIGN(size, 4096);
             break;
-
+        case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+        case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+            if(width & 1) {
+                ALOGE("width is odd for the YUV422_SP format");
+                return -EINVAL;
+            }
+            alignedw = ALIGN(width, 16);
+            alignedh = height;
+            size = ALIGN(alignedw * alignedh * 2, 4096);
+            break;
         default:
-            ALOGE("unrecognized pixel format: %d", format);
+            ALOGE("unrecognized pixel format: 0x%x", format);
             return -EINVAL;
     }
 
@@ -397,31 +413,31 @@
 // to free the buffer using the free_buffer function
 int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage)
 {
-     alloc_data data;
-     int alignedw, alignedh;
-     android::sp<gralloc::IAllocController> sAlloc =
-         gralloc::IAllocController::getInstance(false);
-     data.base = 0;
-     data.fd = -1;
-     data.offset = 0;
-     data.size = getBufferSizeAndDimensions(w, h, format, alignedw, alignedh);
-     data.align = getpagesize();
-     data.uncached = useUncached(usage);
-     int allocFlags = usage;
+    alloc_data data;
+    int alignedw, alignedh;
+    android::sp<gralloc::IAllocController> sAlloc =
+        gralloc::IAllocController::getInstance(false);
+    data.base = 0;
+    data.fd = -1;
+    data.offset = 0;
+    data.size = getBufferSizeAndDimensions(w, h, format, alignedw, alignedh);
+    data.align = getpagesize();
+    data.uncached = useUncached(usage);
+    int allocFlags = usage;
 
-     int err = sAlloc->allocate(data, allocFlags, 0);
-     if (0 != err) {
-         ALOGE("%s: allocate failed", __FUNCTION__);
-         return -ENOMEM;
-     }
+    int err = sAlloc->allocate(data, allocFlags, 0);
+    if (0 != err) {
+        ALOGE("%s: allocate failed", __FUNCTION__);
+        return -ENOMEM;
+    }
 
-     private_handle_t* hnd = new private_handle_t(data.fd, data.size,
-                             data.allocType, 0, format, alignedw, alignedh);
-     hnd->base = (int) data.base;
-     hnd->offset = data.offset;
-     hnd->gpuaddr = 0;
-     *pHnd = hnd;
-     return 0;
+    private_handle_t* hnd = new private_handle_t(data.fd, data.size,
+                                                 data.allocType, 0, format, alignedw, alignedh);
+    hnd->base = (int) data.base;
+    hnd->offset = data.offset;
+    hnd->gpuaddr = 0;
+    *pHnd = hnd;
+    return 0;
 }
 
 void free_buffer(private_handle_t *hnd)
diff --git a/libgralloc/alloc_controller.h b/libgralloc/alloc_controller.h
index 6c907d1..134ad40 100644
--- a/libgralloc/alloc_controller.h
+++ b/libgralloc/alloc_controller.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -33,82 +33,82 @@
 
 namespace gralloc {
 
-    struct alloc_data;
-    class IMemAlloc;
-    class IonAlloc;
+struct alloc_data;
+class IMemAlloc;
+class IonAlloc;
 
-    class IAllocController : public android::RefBase {
+class IAllocController : public android::RefBase {
 
-        public:
-            /* Allocate using a suitable method
-             * Returns the type of buffer allocated
-             */
-            virtual int allocate(alloc_data& data, int usage,
-                    int compositionType) = 0;
+    public:
+    /* Allocate using a suitable method
+     * Returns the type of buffer allocated
+     */
+    virtual int allocate(alloc_data& data, int usage,
+                         int compositionType) = 0;
 
-            virtual android::sp<IMemAlloc> getAllocator(int flags) = 0;
+    virtual android::sp<IMemAlloc> getAllocator(int flags) = 0;
 
-            virtual ~IAllocController() {};
+    virtual ~IAllocController() {};
 
-            static android::sp<IAllocController> getInstance(bool useMasterHeap);
+    static android::sp<IAllocController> getInstance(bool useMasterHeap);
 
-        private:
-            static android::sp<IAllocController> sController;
+    private:
+    static android::sp<IAllocController> sController;
 
-    };
+};
 
-    class IonController : public IAllocController {
+class IonController : public IAllocController {
 
-        public:
-            virtual int allocate(alloc_data& data, int usage,
-                    int compositionType);
+    public:
+    virtual int allocate(alloc_data& data, int usage,
+                         int compositionType);
 
-            virtual android::sp<IMemAlloc> getAllocator(int flags);
+    virtual android::sp<IMemAlloc> getAllocator(int flags);
 
-            IonController();
+    IonController();
 
-        private:
-            android::sp<IonAlloc> mIonAlloc;
+    private:
+    android::sp<IonAlloc> mIonAlloc;
 
-    };
+};
 
-    class PmemKernelController : public IAllocController {
+class PmemKernelController : public IAllocController {
 
-        public:
-            virtual int allocate(alloc_data& data, int usage,
-                    int compositionType);
+    public:
+    virtual int allocate(alloc_data& data, int usage,
+                         int compositionType);
 
-            virtual android::sp<IMemAlloc> getAllocator(int flags);
+    virtual android::sp<IMemAlloc> getAllocator(int flags);
 
-            PmemKernelController ();
+    PmemKernelController ();
 
-            ~PmemKernelController ();
+    ~PmemKernelController ();
 
-        private:
-            android::sp<IMemAlloc> mPmemAdspAlloc;
+    private:
+    android::sp<IMemAlloc> mPmemAdspAlloc;
 
-    };
+};
 
-    // Main pmem controller - this should only
-    // be used within gralloc
-    class PmemAshmemController : public IAllocController {
+// Main pmem controller - this should only
+// be used within gralloc
+class PmemAshmemController : public IAllocController {
 
-        public:
-            virtual int allocate(alloc_data& data, int usage,
-                    int compositionType);
+    public:
+    virtual int allocate(alloc_data& data, int usage,
+                         int compositionType);
 
-            virtual android::sp<IMemAlloc> getAllocator(int flags);
+    virtual android::sp<IMemAlloc> getAllocator(int flags);
 
-            PmemAshmemController();
+    PmemAshmemController();
 
-            ~PmemAshmemController();
+    ~PmemAshmemController();
 
-        private:
-            android::sp<IMemAlloc> mPmemUserspaceAlloc;
-            android::sp<IMemAlloc> mAshmemAlloc;
-            android::sp<IAllocController> mPmemKernelCtrl;
+    private:
+    android::sp<IMemAlloc> mPmemUserspaceAlloc;
+    android::sp<IMemAlloc> mAshmemAlloc;
+    android::sp<IAllocController> mPmemKernelCtrl;
 
-    };
+};
 
 } //end namespace gralloc
 #endif // GRALLOC_ALLOCCONTROLLER_H
diff --git a/libgralloc/ashmemalloc.cpp b/libgralloc/ashmemalloc.cpp
index 8397e21..b659d90 100644
--- a/libgralloc/ashmemalloc.cpp
+++ b/libgralloc/ashmemalloc.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -53,14 +53,14 @@
     } else {
         if (ashmem_set_prot_region(fd, prot) < 0) {
             ALOGE("ashmem_set_prot_region(fd=%d, prot=%x) failed (%s)",
-                 fd, prot, strerror(errno));
+                  fd, prot, strerror(errno));
             close(fd);
             err = -errno;
         } else {
             base = mmap(0, data.size, prot, MAP_SHARED|MAP_POPULATE|MAP_LOCKED, fd, 0);
             if (base == MAP_FAILED) {
                 ALOGE("alloc mmap(fd=%d, size=%d, prot=%x) failed (%s)",
-                     fd, data.size, prot, strerror(errno));
+                      fd, data.size, prot, strerror(errno));
                 close(fd);
                 err = -errno;
             } else {
@@ -74,7 +74,7 @@
         data.offset = offset;
         clean_buffer(base, data.size, offset, fd);
         ALOGD("ashmem: Allocated buffer base:%p size:%d fd:%d",
-                                base, data.size, fd);
+              base, data.size, fd);
 
     }
     return err;
@@ -84,7 +84,7 @@
 int AshmemAlloc::free_buffer(void* base, size_t size, int offset, int fd)
 {
     ALOGD("ashmem: Freeing buffer base:%p size:%d fd:%d",
-                            base, size, fd);
+          base, size, fd);
     int err = 0;
 
     if(!base) {
@@ -102,15 +102,15 @@
     void *base = 0;
 
     base = mmap(0, size, PROT_READ| PROT_WRITE,
-            MAP_SHARED|MAP_POPULATE, fd, 0);
+                MAP_SHARED|MAP_POPULATE, fd, 0);
     *pBase = base;
     if(base == MAP_FAILED) {
         ALOGE("ashmem: Failed to map memory in the client: %s",
-                                strerror(errno));
+              strerror(errno));
         err = -errno;
     } else {
         ALOGD("ashmem: Mapped buffer base:%p size:%d fd:%d",
-                 base, size, fd);
+              base, size, fd);
     }
     return err;
 }
@@ -121,7 +121,7 @@
     int err = munmap(base, size);
     if(err) {
         ALOGE("ashmem: Failed to unmap memory at %p: %s",
-                                base, strerror(errno));
+              base, strerror(errno));
     }
     return err;
 
diff --git a/libgralloc/ashmemalloc.h b/libgralloc/ashmemalloc.h
index 051dcd1..50daf04 100644
--- a/libgralloc/ashmemalloc.h
+++ b/libgralloc/ashmemalloc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -34,23 +34,23 @@
 #include <linux/ion.h>
 
 namespace gralloc {
-    class AshmemAlloc : public IMemAlloc  {
+class AshmemAlloc : public IMemAlloc  {
 
-        public:
-            virtual int alloc_buffer(alloc_data& data);
+    public:
+    virtual int alloc_buffer(alloc_data& data);
 
-            virtual int free_buffer(void *base, size_t size,
-                    int offset, int fd);
+    virtual int free_buffer(void *base, size_t size,
+                            int offset, int fd);
 
-            virtual int map_buffer(void **pBase, size_t size,
-                    int offset, int fd);
+    virtual int map_buffer(void **pBase, size_t size,
+                           int offset, int fd);
 
-            virtual int unmap_buffer(void *base, size_t size,
-                    int offset);
+    virtual int unmap_buffer(void *base, size_t size,
+                             int offset);
 
-            virtual int clean_buffer(void*base, size_t size,
-                    int offset, int fd);
+    virtual int clean_buffer(void*base, size_t size,
+                             int offset, int fd);
 
-    };
+};
 }
 #endif /* GRALLOC_ASHMEMALLOC_H */
diff --git a/libgralloc/fb_priv.h b/libgralloc/fb_priv.h
new file mode 100644
index 0000000..677d1c1
--- /dev/null
+++ b/libgralloc/fb_priv.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FB_PRIV_H
+#define FB_PRIV_H
+#include <linux/fb.h>
+
+#define NUM_FRAMEBUFFERS_MIN  2
+//XXX: Enable triple framebuffers
+#define NUM_FRAMEBUFFERS_MAX  2
+
+#define NO_SURFACEFLINGER_SWAPINTERVAL
+#define COLOR_FORMAT(x) (x & 0xFFF) // Max range for colorFormats is 0 - FFF
+
+#ifdef __cplusplus
+template <class T>
+struct Node
+{
+    T data;
+    Node<T> *next;
+};
+
+template <class T>
+class Queue
+{
+    public:
+    Queue(): front(NULL), back(NULL), len(0) {dummy = new T;}
+    ~Queue()
+    {
+        clear();
+        delete dummy;
+    }
+    void push(const T& item)   //add an item to the back of the queue
+    {
+        if(len != 0) {         //if the queue is not empty
+            back->next = new Node<T>; //create a new node
+            back = back->next; //set the new node as the back node
+            back->data = item;
+            back->next = NULL;
+        } else {
+            back = new Node<T>;
+            back->data = item;
+            back->next = NULL;
+            front = back;
+        }
+        len++;
+    }
+    void pop()                 //remove the first item from the queue
+    {
+        if (isEmpty())
+            return;            //if the queue is empty, no node to dequeue
+        T item = front->data;
+        Node<T> *tmp = front;
+        front = front->next;
+        delete tmp;
+        if(front == NULL)      //if the queue is empty, update the back pointer
+            back = NULL;
+        len--;
+        return;
+    }
+    T& getHeadValue() const    //return the value of the first item in the queue
+    {                          //without modification to the structure
+        if (isEmpty()) {
+            ALOGE("Error can't get head of empty queue");
+            return *dummy;
+        }
+        return front->data;
+    }
+
+    bool isEmpty() const       //returns true if no elements are in the queue
+    {
+        return (front == NULL);
+    }
+
+    size_t size() const        //returns the amount of elements in the queue
+    {
+        return len;
+    }
+
+    private:
+    Node<T> *front;
+    Node<T> *back;
+    size_t len;
+    void clear()
+    {
+        while (!isEmpty())
+            pop();
+    }
+    T *dummy;
+};
+#endif
+
+enum hdmi_mirroring_state {
+    HDMI_NO_MIRRORING,
+    HDMI_UI_MIRRORING,
+};
+
+struct private_handle_t;
+
+struct qbuf_t {
+    buffer_handle_t buf;
+    int  idx;
+};
+
+enum buf_state {
+    SUB,
+    REF,
+    AVL
+};
+
+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 avail_t {
+    pthread_mutex_t lock;
+    pthread_cond_t cond;
+    bool is_avail;
+    buf_state state;
+};
+
+struct private_module_t {
+    gralloc_module_t base;
+
+    struct private_handle_t* framebuffer;
+    uint32_t fbFormat;
+    uint32_t flags;
+    uint32_t numBuffers;
+    uint32_t bufferMask;
+    pthread_mutex_t lock;
+    buffer_handle_t currentBuffer;
+
+    struct fb_var_screeninfo info;
+    struct fb_fix_screeninfo finfo;
+    float xdpi;
+    float ydpi;
+    float fps;
+    uint32_t swapInterval;
+    Queue<struct qbuf_t> disp; // non-empty when buffer is ready for display
+    int currentIdx;
+    struct avail_t avail[NUM_FRAMEBUFFERS_MAX];
+    pthread_mutex_t qlock;
+    pthread_cond_t qpost;
+#if defined(__cplusplus) && defined(HDMI_DUAL_DISPLAY)
+    int orientation;
+    int videoOverlay; // VIDEO_OVERLAY - 2D or 3D
+    int secureVideoOverlay; // VideoOverlay is secure
+    uint32_t currentOffset;
+    int enableHDMIOutput; // holds the type of external display
+    bool trueMirrorSupport;
+    bool exitHDMIUILoop;
+    float actionsafeWidthRatio;
+    float actionsafeHeightRatio;
+    bool hdmiStateChanged;
+    hdmi_mirroring_state hdmiMirroringState;
+    pthread_mutex_t overlayLock;
+    pthread_cond_t overlayPost;
+#endif
+};
+
+
+
+#endif /* FB_PRIV_H */
diff --git a/libgralloc/framebuffer.cpp b/libgralloc/framebuffer.cpp
index b6b4a8f..4935785 100644
--- a/libgralloc/framebuffer.cpp
+++ b/libgralloc/framebuffer.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 The Android Open Source Project
-* Copyright (c) 2010-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012 Code Aurora Forum. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,15 +17,11 @@
 
 #include <sys/mman.h>
 
-#include <dlfcn.h>
-
-#include <cutils/ashmem.h>
 #include <cutils/log.h>
 #include <cutils/properties.h>
-#include <utils/Timers.h>
+#include <dlfcn.h>
 
 #include <hardware/hardware.h>
-#include <hardware/gralloc.h>
 
 #include <fcntl.h>
 #include <errno.h>
@@ -33,9 +29,6 @@
 #include <string.h>
 #include <stdlib.h>
 #include <pthread.h>
-#include <utils/Timers.h>
-
-#include <cutils/log.h>
 #include <cutils/atomic.h>
 
 #include <linux/fb.h>
@@ -44,18 +37,15 @@
 #include <GLES/gl.h>
 
 #include "gralloc_priv.h"
+#include "fb_priv.h"
 #include "gr.h"
-#ifdef NO_SURFACEFLINGER_SWAPINTERVAL
 #include <cutils/properties.h>
-#endif
+#include <qcomutils/profiler.h>
 
-#include <qcom_ui.h>
+#include "overlay.h"
+namespace ovutils = overlay::utils;
 
-#define FB_DEBUG 0
-
-#if defined(HDMI_DUAL_DISPLAY)
 #define EVEN_OUT(x) if (x & 0x0001) {x--;}
-using overlay::Overlay;
 /** min of int a, b */
 static inline int min(int a, int b) {
     return (a<b) ? a : b;
@@ -64,50 +54,31 @@
 static inline int max(int a, int b) {
     return (a>b) ? a : b;
 }
-#endif
 
 char framebufferStateName[] = {'S', 'R', 'A'};
 
-/*****************************************************************************/
-
-enum {
-    MDDI_PANEL = '1',
-    EBI2_PANEL = '2',
-    LCDC_PANEL = '3',
-    EXT_MDDI_PANEL = '4',
-    TV_PANEL = '5'
-};
-
 enum {
     PAGE_FLIP = 0x00000001,
-    LOCKED = 0x00000002
+    LOCKED    = 0x00000002
 };
 
 struct fb_context_t {
     framebuffer_device_t  device;
 };
 
-static int neworientation;
-
-/*****************************************************************************/
-
-static void
-msm_copy_buffer(buffer_handle_t handle, int fd,
-                int width, int height, int format,
-                int x, int y, int w, int h);
 
 static int fb_setSwapInterval(struct framebuffer_device_t* dev,
-            int interval)
+                              int interval)
 {
     char pval[PROPERTY_VALUE_MAX];
-    property_get("debug.gr.swapinterval", pval, "-1");
+    property_get("debug.egl.swapinterval", pval, "-1");
     int property_interval = atoi(pval);
     if (property_interval >= 0)
         interval = property_interval;
 
     fb_context_t* ctx = (fb_context_t*)dev;
     private_module_t* m = reinterpret_cast<private_module_t*>(
-            dev->common.module);
+        dev->common.module);
     if (interval < dev->minSwapInterval || interval > dev->maxSwapInterval)
         return -EINVAL;
 
@@ -116,13 +87,13 @@
 }
 
 static int fb_setUpdateRect(struct framebuffer_device_t* dev,
-        int l, int t, int w, int h)
+                            int l, int t, int w, int h)
 {
     if (((w|h) <= 0) || ((l|t)<0))
         return -EINVAL;
     fb_context_t* ctx = (fb_context_t*)dev;
     private_module_t* m = reinterpret_cast<private_module_t*>(
-            dev->common.module);
+        dev->common.module);
     m->info.reserved[0] = 0x54445055; // "UPDT";
     m->info.reserved[1] = (uint16_t)l | ((uint32_t)t << 16);
     m->info.reserved[2] = (uint16_t)(l+w) | ((uint32_t)(t+h) << 16);
@@ -150,7 +121,7 @@
 
         // post buf out to display synchronously
         private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>
-                                                (nxtBuf.buf);
+            (nxtBuf.buf);
         const size_t offset = hnd->base - m->framebuffer->base;
         m->info.activate = FB_ACTIVATE_VBL;
         m->info.yoffset = offset / m->finfo.line_length;
@@ -173,28 +144,30 @@
             int nxtAvail = ((nxtBuf.idx + 1) % m->numBuffers);
             pthread_mutex_lock(&(m->avail[nxtBuf.idx].lock));
             m->avail[nxtBuf.idx].is_avail = true;
-            m->avail[nxtBuf.idx].state = REF;
-            pthread_cond_broadcast(&(m->avail[nxtBuf.idx].cond));
+            m->avail[nxtBuf.idx].state = SUB;
+            pthread_cond_signal(&(m->avail[nxtBuf.idx].cond));
             pthread_mutex_unlock(&(m->avail[nxtBuf.idx].lock));
         } else {
+#if 0 //XXX: Triple FB
             pthread_mutex_lock(&(m->avail[nxtBuf.idx].lock));
             if (m->avail[nxtBuf.idx].state != SUB) {
                 ALOGE_IF(m->swapInterval != 0, "[%d] state %c, expected %c", nxtBuf.idx,
-                    framebufferStateName[m->avail[nxtBuf.idx].state],
-                    framebufferStateName[SUB]);
+                         framebufferStateName[m->avail[nxtBuf.idx].state],
+                         framebufferStateName[SUB]);
             }
+
             m->avail[nxtBuf.idx].state = REF;
             pthread_mutex_unlock(&(m->avail[nxtBuf.idx].lock));
-
-            pthread_mutex_lock(&(m->avail[cur_buf].lock));
-            m->avail[cur_buf].is_avail = true;
             if (m->avail[cur_buf].state != REF) {
                 ALOGE_IF(m->swapInterval != 0, "[%d] state %c, expected %c", cur_buf,
-                    framebufferStateName[m->avail[cur_buf].state],
-                    framebufferStateName[REF]);
+                         framebufferStateName[m->avail[cur_buf].state],
+                         framebufferStateName[SUB]);
             }
             m->avail[cur_buf].state = AVL;
-            pthread_cond_broadcast(&(m->avail[cur_buf].cond));
+#endif
+            pthread_mutex_lock(&(m->avail[cur_buf].lock));
+            m->avail[cur_buf].is_avail = true;
+            pthread_cond_signal(&(m->avail[cur_buf].cond));
             pthread_mutex_unlock(&(m->avail[cur_buf].lock));
         }
         cur_buf = nxtBuf.idx;
@@ -205,14 +178,19 @@
 #if defined(HDMI_DUAL_DISPLAY)
 static int closeHDMIChannel(private_module_t* m)
 {
+    // XXX - when enabling HDMI
+#if 0
     Overlay* pTemp = m->pobjOverlay;
     if(pTemp != NULL)
         pTemp->closeChannel();
+#endif
     return 0;
 }
 
+// XXX - Complete when enabling HDMI
+#if 0
 static void getSecondaryDisplayDestinationInfo(private_module_t* m, overlay_rect&
-                                rect, int& orientation)
+                                               rect, int& orientation)
 {
     Overlay* pTemp = m->pobjOverlay;
     int width = pTemp->getFBWidth();
@@ -224,10 +202,10 @@
     switch(rot) {
         // ROT_0
         case 0:
-        // ROT_180
+            // ROT_180
         case HAL_TRANSFORM_ROT_180:
             pTemp->getAspectRatioPosition(fbwidth, fbheight,
-                                                   &rect);
+                                          &rect);
             if(rot ==  HAL_TRANSFORM_ROT_180)
                 orientation = HAL_TRANSFORM_ROT_180;
             else
@@ -242,7 +220,7 @@
             //Width and height will be swapped as there
             //is rotation
             pTemp->getAspectRatioPosition(fbheight, fbwidth,
-                    &rect);
+                                          &rect);
 
             if(rot == HAL_TRANSFORM_ROT_90)
                 orientation = HAL_TRANSFORM_ROT_270;
@@ -252,82 +230,175 @@
     }
     return;
 }
+#endif
+
+/* Determine overlay state based on whether hardware supports true UI
+   mirroring and whether video is playing or not */
+static ovutils::eOverlayState getOverlayState(struct private_module_t* module)
+{
+    overlay2::Overlay& ov = *(Overlay::getInstance());
+
+    // Default to existing state
+    ovutils::eOverlayState state = ov.getState();
+
+    // Sanity check
+    if (!module) {
+        ALOGE("%s: NULL module", __FUNCTION__);
+        return state;
+    }
+
+    // Check if video is playing or not
+    if (module->videoOverlay) {
+        // Video is playing, check if hardware supports true UI mirroring
+        if (module->trueMirrorSupport) {
+            // True UI mirroring is supported by hardware
+            if (ov.getState() == ovutils::OV_2D_VIDEO_ON_PANEL) {
+                // Currently playing 2D video
+                state = ovutils::OV_2D_TRUE_UI_MIRROR;
+            } else if (ov.getState() == ovutils::OV_3D_VIDEO_ON_2D_PANEL) {
+                // Currently playing M3D video
+                // FIXME: Support M3D true UI mirroring
+                state = ovutils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV;
+            }
+        } else {
+            // True UI mirroring is not supported by hardware
+            if (ov.getState() == ovutils::OV_2D_VIDEO_ON_PANEL) {
+                // Currently playing 2D video
+                state = ovutils::OV_2D_VIDEO_ON_PANEL_TV;
+            } else if (ov.getState() == ovutils::OV_3D_VIDEO_ON_2D_PANEL) {
+                // Currently playing M3D video
+                state = ovutils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV;
+            }
+        }
+    } else {
+        // Video is not playing, true UI mirroring support is irrelevant
+        state = ovutils::OV_UI_MIRROR;
+    }
+
+    return state;
+}
+
+/* Set overlay state */
+static void setOverlayState(ovutils::eOverlayState state)
+{
+    overlay2::Overlay& ov = *(Overlay::getInstance());
+    ov.setState(state);
+}
 
 static void *hdmi_ui_loop(void *ptr)
 {
-    private_module_t* m = reinterpret_cast<private_module_t*>(
-            ptr);
+    private_module_t* m = reinterpret_cast<private_module_t*>(ptr);
     while (1) {
         pthread_mutex_lock(&m->overlayLock);
         while(!(m->hdmiStateChanged))
             pthread_cond_wait(&(m->overlayPost), &(m->overlayLock));
+
         m->hdmiStateChanged = false;
         if (m->exitHDMIUILoop) {
             pthread_mutex_unlock(&m->overlayLock);
             return NULL;
         }
-        bool waitForVsync = true;
-        int flags = WAIT_FOR_VSYNC;
-        if (m->pobjOverlay) {
-            Overlay* pTemp = m->pobjOverlay;
-            if (m->hdmiMirroringState == HDMI_NO_MIRRORING)
-                closeHDMIChannel(m);
-            else if(m->hdmiMirroringState == HDMI_UI_MIRRORING) {
-                if (!pTemp->isChannelUP()) {
-                   int alignedW = ALIGN(m->info.xres, 32);
 
-                   private_handle_t const* hnd =
-                      reinterpret_cast<private_handle_t const*>(m->framebuffer);
-                   overlay_buffer_info info;
-                   info.width = alignedW;
-                   info.height = hnd->height;
-                   info.format = hnd->format;
-                   info.size = hnd->size;
+        // No need to mirror UI if HDMI is not on
+        if (!m->enableHDMIOutput) {
+            ALOGE_IF(FB_DEBUG, "%s: hdmi not ON", __FUNCTION__);
+            pthread_mutex_unlock(&m->overlayLock);
+            continue;
+        }
 
-                   if (m->trueMirrorSupport)
-                       flags &= ~WAIT_FOR_VSYNC;
-                   // start the overlay Channel for mirroring
-                   // m->enableHDMIOutput corresponds to the fbnum
-                   if (pTemp->startChannel(info, m->enableHDMIOutput,
-                                           false, true, 0, VG0_PIPE, flags)) {
-                        pTemp->setFd(m->framebuffer->fd);
-                        pTemp->setCrop(0, 0, m->info.xres, m->info.yres);
-                   } else
-                       closeHDMIChannel(m);
-                }
+        overlay2::OverlayMgr* ovMgr =
+            overlay2::OverlayMgrSingleton::getOverlayMgr();
+        overlay2::Overlay& ov = ovMgr->ov();
 
-                if (pTemp->isChannelUP()) {
-                    overlay_rect destRect;
-                    int rot = 0;
-                    int currOrientation = 0;
-                    getSecondaryDisplayDestinationInfo(m, destRect, rot);
-                    pTemp->getOrientation(currOrientation);
-                    if(rot != currOrientation) {
-                        pTemp->setTransform(rot);
-                    }
-                    EVEN_OUT(destRect.x);
-                    EVEN_OUT(destRect.y);
-                    EVEN_OUT(destRect.w);
-                    EVEN_OUT(destRect.h);
-                    int currentX = 0, currentY = 0;
-                    uint32_t currentW = 0, currentH = 0;
-                    if (pTemp->getPosition(currentX, currentY, currentW, currentH)) {
-                        if ((currentX != destRect.x) || (currentY != destRect.y) ||
-                                (currentW != destRect.w) || (currentH != destRect.h)) {
-                            pTemp->setPosition(destRect.x, destRect.y, destRect.w,
-                                                                    destRect.h);
-                        }
-                    }
-                    if (m->trueMirrorSupport) {
-                        // if video is started the UI channel should be NO_WAIT.
-                        flags = !m->videoOverlay ? WAIT_FOR_VSYNC : 0;
-                        pTemp->updateOverlayFlags(flags);
-                    }
-                    pTemp->queueBuffer(m->currentOffset);
-                }
+        // Set overlay state
+        ovutils::eOverlayState state = getOverlayState(m);
+        setOverlayState(state);
+
+        // Determine the RGB pipe for UI depending on the state
+        ovutils::eDest dest = ovutils::OV_PIPE_ALL;
+        if (state == ovutils::OV_2D_TRUE_UI_MIRROR) {
+            // True UI mirroring state: external RGB pipe is OV_PIPE2
+            dest = ovutils::OV_PIPE2;
+        } else if (state == ovutils::OV_UI_MIRROR) {
+            // UI-only mirroring state: external RGB pipe is OV_PIPE0
+            dest = ovutils::OV_PIPE0;
+        } else {
+            // No UI in this case
+            pthread_mutex_unlock(&m->overlayLock);
+            continue;
+        }
+
+        if (m->hdmiMirroringState == HDMI_UI_MIRRORING) {
+            int alignedW = ALIGN(m->info.xres, 32);
+
+            private_handle_t const* hnd =
+                reinterpret_cast<private_handle_t const*>(m->framebuffer);
+            unsigned int width = alignedW;
+            unsigned int height = hnd->height;
+            unsigned int format = hnd->format;
+            unsigned int size = hnd->size/m->numBuffers;
+
+            ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
+            // External display connected during secure video playback
+            // Open secure UI session
+            // NOTE: when external display is already connected and then secure
+            // playback is started, we dont have to do anything
+            if (m->secureVideoOverlay) {
+                ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
             }
-            else
-                closeHDMIChannel(m);
+
+            ovutils::Whf whf(width, height, format, size);
+            ovutils::PipeArgs parg(mdpFlags,
+                                   ovutils::OVERLAY_TRANSFORM_0,
+                                   whf,
+                                   ovutils::WAIT,
+                                   ovutils::ZORDER_0,
+                                   ovutils::IS_FG_OFF,
+                                   ovutils::ROT_FLAG_ENABLED);
+            ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg };
+            bool ret = ov.setSource(pargs, dest);
+            if (!ret) {
+                ALOGE("%s setSource failed", __FUNCTION__);
+            }
+
+            // we need to communicate m->orientation that will get some
+            // modifications within setParameter func.
+            // FIXME that is ugly.
+            const ovutils::Params prms (ovutils::OVERLAY_TRANSFORM_UI,
+                                        m->orientation);
+            ov.setParameter(prms, dest);
+            if (!ret) {
+                ALOGE("%s setParameter failed transform", __FUNCTION__);
+            }
+
+            // x,y,w,h
+            ovutils::Dim dcrop(0, 0, m->info.xres, m->info.yres);
+            ov.setMemoryId(m->framebuffer->fd, dest);
+            ret = ov.setCrop(dcrop, dest);
+            if (!ret) {
+                ALOGE("%s setCrop failed", __FUNCTION__);
+            }
+
+            ovutils::Dim pdim (m->info.xres,
+                               m->info.yres,
+                               0,
+                               0,
+                               m->orientation);
+            ret = ov.setPosition(pdim, dest);
+            if (!ret) {
+                ALOGE("%s setPosition failed", __FUNCTION__);
+            }
+
+            if (!ov.commit(dest)) {
+                ALOGE("%s commit fails", __FUNCTION__);
+            }
+
+            ret = ov.queueBuffer(m->currentOffset, dest);
+            if (!ret) {
+                ALOGE("%s queueBuffer failed", __FUNCTION__);
+            }
+        } else {
+            setOverlayState(ovutils::OV_CLOSED);
         }
         pthread_mutex_unlock(&m->overlayLock);
     }
@@ -336,20 +407,30 @@
 
 static int fb_videoOverlayStarted(struct framebuffer_device_t* dev, int started)
 {
+    ALOGE_IF(FB_DEBUG, "%s started=%d", __FUNCTION__, started);
     private_module_t* m = reinterpret_cast<private_module_t*>(
-            dev->common.module);
+        dev->common.module);
     pthread_mutex_lock(&m->overlayLock);
-    Overlay* pTemp = m->pobjOverlay;
     if(started != m->videoOverlay) {
         m->videoOverlay = started;
+        m->hdmiStateChanged = true;
         if (!m->trueMirrorSupport) {
-            m->hdmiStateChanged = true;
-            if (started && pTemp) {
+            if (started) {
                 m->hdmiMirroringState = HDMI_NO_MIRRORING;
-                closeHDMIChannel(m);
+                ovutils::eOverlayState state = getOverlayState(m);
+                setOverlayState(state);
             } else if (m->enableHDMIOutput)
                 m->hdmiMirroringState = HDMI_UI_MIRRORING;
-            pthread_cond_signal(&(m->overlayPost));
+        } else {
+            if (m->videoOverlay == VIDEO_3D_OVERLAY_STARTED) {
+                ALOGE_IF(FB_DEBUG, "3D Video Started, stop mirroring!");
+                m->hdmiMirroringState = HDMI_NO_MIRRORING;
+                ovutils::eOverlayState state = getOverlayState(m);
+                setOverlayState(state);
+            }
+            else if (m->enableHDMIOutput) {
+                m->hdmiMirroringState = HDMI_UI_MIRRORING;
+            }
         }
     }
     pthread_mutex_unlock(&m->overlayLock);
@@ -358,14 +439,13 @@
 
 static int fb_enableHDMIOutput(struct framebuffer_device_t* dev, int externaltype)
 {
+    ALOGE_IF(FB_DEBUG, "%s externaltype=%d", __FUNCTION__, externaltype);
     private_module_t* m = reinterpret_cast<private_module_t*>(
-            dev->common.module);
+        dev->common.module);
     pthread_mutex_lock(&m->overlayLock);
-    Overlay* pTemp = m->pobjOverlay;
     //Check if true mirroring can be supported
-    m->trueMirrorSupport = FrameBufferInfo::getInstance()->canSupportTrueMirroring();
+    m->trueMirrorSupport = ovutils::FrameBufferInfo::getInstance()->supportTrueMirroring();
     m->enableHDMIOutput = externaltype;
-    ALOGE("In fb_enableHDMIOutput: externaltype = %d", m->enableHDMIOutput);
     if(externaltype) {
         if (m->trueMirrorSupport) {
             m->hdmiMirroringState = HDMI_UI_MIRRORING;
@@ -373,9 +453,11 @@
             if(!m->videoOverlay)
                 m->hdmiMirroringState = HDMI_UI_MIRRORING;
         }
-    } else if (!externaltype && pTemp) {
+    } else if (!externaltype) {
+        // Either HDMI is disconnected or suspend occurred
         m->hdmiMirroringState = HDMI_NO_MIRRORING;
-        closeHDMIChannel(m);
+        ovutils::eOverlayState state = getOverlayState(m);
+        setOverlayState(state);
     }
     m->hdmiStateChanged = true;
     pthread_cond_signal(&(m->overlayPost));
@@ -383,58 +465,132 @@
     return 0;
 }
 
-
-static int fb_setActionSafeWidthRatio(struct framebuffer_device_t* dev, float asWidthRatio)
-{
-    private_module_t* m = reinterpret_cast<private_module_t*>(
-            dev->common.module);
-    pthread_mutex_lock(&m->overlayLock);
-    m->actionsafeWidthRatio = asWidthRatio;
-    pthread_mutex_unlock(&m->overlayLock);
-    return 0;
-}
-
-static int fb_setActionSafeHeightRatio(struct framebuffer_device_t* dev, float asHeightRatio)
-{
-    private_module_t* m = reinterpret_cast<private_module_t*>(
-                    dev->common.module);
-    pthread_mutex_lock(&m->overlayLock);
-    m->actionsafeHeightRatio = asHeightRatio;
-    pthread_mutex_unlock(&m->overlayLock);
-    return 0;
-}
-
 static int fb_orientationChanged(struct framebuffer_device_t* dev, int orientation)
 {
     private_module_t* m = reinterpret_cast<private_module_t*>(
-            dev->common.module);
+        dev->common.module);
     pthread_mutex_lock(&m->overlayLock);
     neworientation = orientation;
     pthread_mutex_unlock(&m->overlayLock);
     return 0;
 }
+
+static int handle_open_secure_start(private_module_t* m) {
+    pthread_mutex_lock(&m->overlayLock);
+    m->hdmiMirroringState = HDMI_NO_MIRRORING;
+    m->secureVideoOverlay = true;
+    pthread_mutex_unlock(&m->overlayLock);
+    return 0;
+}
+
+static int handle_open_secure_end(private_module_t* m) {
+    pthread_mutex_lock(&m->overlayLock);
+    if (m->enableHDMIOutput) {
+        if (m->trueMirrorSupport) {
+            m->hdmiMirroringState = HDMI_UI_MIRRORING;
+        } else if(!m->videoOverlay) {
+            m->hdmiMirroringState = HDMI_UI_MIRRORING;
+        }
+        m->hdmiStateChanged = true;
+        pthread_cond_signal(&(m->overlayPost));
+    }
+    pthread_mutex_unlock(&m->overlayLock);
+    return 0;
+}
+
+static int handle_close_secure_start(private_module_t* m) {
+    pthread_mutex_lock(&m->overlayLock);
+    m->hdmiMirroringState = HDMI_NO_MIRRORING;
+    m->secureVideoOverlay = false;
+    pthread_mutex_unlock(&m->overlayLock);
+    return 0;
+}
+
+static int handle_close_secure_end(private_module_t* m) {
+    pthread_mutex_lock(&m->overlayLock);
+    if (m->enableHDMIOutput) {
+        if (m->trueMirrorSupport) {
+            m->hdmiMirroringState = HDMI_UI_MIRRORING;
+        } else if(!m->videoOverlay) {
+            m->hdmiMirroringState = HDMI_UI_MIRRORING;
+        }
+        m->hdmiStateChanged = true;
+        pthread_cond_signal(&(m->overlayPost));
+    }
+    pthread_mutex_unlock(&m->overlayLock);
+    return 0;
+}
 #endif
 
+
+
+/* fb_perform - used to add custom event and handle them in fb HAL
+ * Used for external display related functions as of now
+ */
+static int fb_perform(struct framebuffer_device_t* dev, int event, int value)
+{
+    private_module_t* m = reinterpret_cast<private_module_t*>(
+        dev->common.module);
+    switch(event) {
+#if defined(HDMI_DUAL_DISPLAY)
+        case EVENT_EXTERNAL_DISPLAY:
+            fb_enableHDMIOutput(dev, value);
+            break;
+        case EVENT_VIDEO_OVERLAY:
+            fb_videoOverlayStarted(dev, value);
+            break;
+        case EVENT_ORIENTATION_CHANGE:
+            fb_orientationChanged(dev, value);
+            break;
+        case EVENT_OVERLAY_STATE_CHANGE:
+            if (value == OVERLAY_STATE_CHANGE_START) {
+                // When state change starts, get a lock on overlay
+                pthread_mutex_lock(&m->overlayLock);
+            } else if (value == OVERLAY_STATE_CHANGE_END) {
+                // When state change is complete, unlock overlay
+                pthread_mutex_unlock(&m->overlayLock);
+            }
+            break;
+        case EVENT_OPEN_SECURE_START:
+            handle_open_secure_start(m);
+            break;
+        case EVENT_OPEN_SECURE_END:
+            handle_open_secure_end(m);
+            break;
+        case EVENT_CLOSE_SECURE_START:
+            handle_close_secure_start(m);
+            break;
+        case EVENT_CLOSE_SECURE_END:
+            handle_close_secure_end(m);
+            break;
+#endif
+        default:
+            ALOGE("In %s: UNKNOWN Event = %d!!!", __FUNCTION__, event);
+            break;
+    }
+    return 0;
+}
+
+
 static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
 {
     if (private_handle_t::validate(buffer) < 0)
         return -EINVAL;
 
-    int nxtIdx, futureIdx = -1;
+    int nxtIdx;//, futureIdx = -1;
     bool reuse;
     struct qbuf_t qb;
     fb_context_t* ctx = (fb_context_t*)dev;
 
     private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(buffer);
     private_module_t* m = reinterpret_cast<private_module_t*>(
-            dev->common.module);
+        dev->common.module);
 
     if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
 
         reuse = false;
         nxtIdx = (m->currentIdx + 1) % m->numBuffers;
-        futureIdx = (nxtIdx + 1) % m->numBuffers;
-
+        //futureIdx = (nxtIdx + 1) % m->numBuffers;
         if (m->swapInterval == 0) {
             // if SwapInterval = 0 and no buffers available then reuse
             // current buf for next rendering so don't post new buffer
@@ -450,24 +606,25 @@
         if(!reuse){
             // unlock previous ("current") Buffer and lock the new buffer
             m->base.lock(&m->base, buffer,
-                    private_module_t::PRIV_USAGE_LOCKED_FOR_POST,
-                    0,0, m->info.xres, m->info.yres, NULL);
+                         PRIV_USAGE_LOCKED_FOR_POST,
+                         0,0, m->info.xres, m->info.yres, NULL);
 
             // post/queue the new buffer
             pthread_mutex_lock(&(m->avail[nxtIdx].lock));
-            if (m->avail[nxtIdx].is_avail != true) {
-                ALOGE_IF(m->swapInterval != 0, "Found %d buf to be not avail", nxtIdx);
-            }
-
             m->avail[nxtIdx].is_avail = false;
+#if 0 //XXX: Triple FB
+            if (m->avail[nxtIdx].is_avail != true) {
+               ALOGE_IF(m->swapInterval != 0, "Found %d buf to be not avail", nxtIdx);
+            }
 
             if (m->avail[nxtIdx].state != AVL) {
                 ALOGD("[%d] state %c, expected %c", nxtIdx,
-                    framebufferStateName[m->avail[nxtIdx].state],
-                    framebufferStateName[AVL]);
+                      framebufferStateName[m->avail[nxtIdx].state],
+                      framebufferStateName[AVL]);
             }
 
             m->avail[nxtIdx].state = SUB;
+#endif
             pthread_mutex_unlock(&(m->avail[nxtIdx].lock));
 
             qb.idx = nxtIdx;
@@ -486,40 +643,12 @@
             if (m->currentBuffer)
                 m->base.unlock(&m->base, m->currentBuffer);
             m->base.lock(&m->base, buffer,
-                         private_module_t::PRIV_USAGE_LOCKED_FOR_POST,
+                         PRIV_USAGE_LOCKED_FOR_POST,
                          0,0, m->info.xres, m->info.yres, NULL);
             m->currentBuffer = buffer;
         }
 
-    } else {
-        void* fb_vaddr;
-        void* buffer_vaddr;
-        m->base.lock(&m->base, m->framebuffer,
-                GRALLOC_USAGE_SW_WRITE_RARELY,
-                0, 0, m->info.xres, m->info.yres,
-                &fb_vaddr);
-
-        m->base.lock(&m->base, buffer,
-                GRALLOC_USAGE_SW_READ_RARELY,
-                0, 0, m->info.xres, m->info.yres,
-                &buffer_vaddr);
-
-        //memcpy(fb_vaddr, buffer_vaddr, m->finfo.line_length * m->info.yres);
-
-        msm_copy_buffer(
-                m->framebuffer, m->framebuffer->fd,
-                m->info.xres, m->info.yres, m->fbFormat,
-                m->info.xoffset, m->info.yoffset,
-                m->info.width, m->info.height);
-
-        m->base.unlock(&m->base, buffer);
-        m->base.unlock(&m->base, m->framebuffer);
     }
-
-    ALOGD_IF(FB_DEBUG, "Framebuffer state: [0] = %c [1] = %c [2] = %c",
-        framebufferStateName[m->avail[0].state],
-        framebufferStateName[m->avail[1].state],
-        framebufferStateName[m->avail[2].state]);
     return 0;
 }
 
@@ -534,7 +663,7 @@
 static int fb_lockBuffer(struct framebuffer_device_t* dev, int index)
 {
     private_module_t* m = reinterpret_cast<private_module_t*>(
-            dev->common.module);
+        dev->common.module);
 
     // Return immediately if the buffer is available
     if ((m->avail[index].state == AVL) || (m->swapInterval == 0))
@@ -543,15 +672,13 @@
     pthread_mutex_lock(&(m->avail[index].lock));
     while (m->avail[index].state != AVL) {
         pthread_cond_wait(&(m->avail[index].cond),
-                         &(m->avail[index].lock));
+                          &(m->avail[index].lock));
     }
     pthread_mutex_unlock(&(m->avail[index].lock));
 
     return 0;
 }
 
-/*****************************************************************************/
-
 int mapFrameBufferLocked(struct private_module_t* module)
 {
     // already initialized...
@@ -559,9 +686,9 @@
         return 0;
     }
     char const * const device_template[] = {
-            "/dev/graphics/fb%u",
-            "/dev/fb%u",
-            0 };
+        "/dev/graphics/fb%u",
+        "/dev/fb%u",
+        0 };
 
     int fd = -1;
     int i=0;
@@ -592,11 +719,11 @@
     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.
-    */
+     * 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) {
         /*
@@ -617,7 +744,8 @@
          * 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))
+        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;
@@ -641,7 +769,7 @@
     int  size = roundUpToPageSize(info.yres * info.xres * (info.bits_per_pixel/8));
 
     /*
-     * Request NUM_BUFFERS screens (at lest 2 for page flipping)
+     * 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);
@@ -673,7 +801,7 @@
         info.yres_virtual = size / line_length;
         flags &= ~PAGE_FLIP;
         ALOGW("page flipping not supported (yres_virtual=%d, requested=%d)",
-                info.yres_virtual, info.yres*2);
+              info.yres_virtual, info.yres*2);
     }
 
     if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
@@ -691,35 +819,35 @@
     //The reserved[4] field is used to store FPS by the driver.
     float fps  = info.reserved[4];
 
-    ALOGI(   "using (fd=%d)\n"
-            "id           = %s\n"
-            "xres         = %d px\n"
-            "yres         = %d px\n"
-            "xres_virtual = %d px\n"
-            "yres_virtual = %d px\n"
-            "bpp          = %d\n"
-            "r            = %2u:%u\n"
-            "g            = %2u:%u\n"
-            "b            = %2u:%u\n",
-            fd,
-            finfo.id,
-            info.xres,
-            info.yres,
-            info.xres_virtual,
-            info.yres_virtual,
-            info.bits_per_pixel,
-            info.red.offset, info.red.length,
-            info.green.offset, info.green.length,
-            info.blue.offset, info.blue.length
-    );
+    ALOGI("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
-    );
+    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)
@@ -739,12 +867,12 @@
     char pval[PROPERTY_VALUE_MAX];
     property_get("debug.gr.swapinterval", pval, "1");
     module->swapInterval = atoi(pval);
-    if (module->swapInterval < private_module_t::PRIV_MIN_SWAP_INTERVAL ||
-        module->swapInterval > private_module_t::PRIV_MAX_SWAP_INTERVAL) {
+    if (module->swapInterval < PRIV_MIN_SWAP_INTERVAL ||
+        module->swapInterval > PRIV_MAX_SWAP_INTERVAL) {
         module->swapInterval = 1;
         ALOGW("Out of range (%d to %d) value for debug.gr.swapinterval, using 1",
-             private_module_t::PRIV_MIN_SWAP_INTERVAL,
-             private_module_t::PRIV_MAX_SWAP_INTERVAL);
+              PRIV_MIN_SWAP_INTERVAL,
+              PRIV_MAX_SWAP_INTERVAL);
     }
 
 #else
@@ -765,9 +893,9 @@
     }
 
     /* create display update thread */
-    pthread_t thread1;
-    if (pthread_create(&thread1, NULL, &disp_loop, (void *) module)) {
-         return -errno;
+    pthread_t disp_thread;
+    if (pthread_create(&disp_thread, NULL, &disp_loop, (void *) module)) {
+        return -errno;
     }
 
     /*
@@ -778,10 +906,12 @@
     module->numBuffers = info.yres_virtual / info.yres;
     module->bufferMask = 0;
     //adreno needs page aligned offsets. Align the fbsize to pagesize.
-    size_t fbSize = roundUpToPageSize(finfo.line_length * info.yres) * module->numBuffers;
+    size_t fbSize = roundUpToPageSize(finfo.line_length * info.yres)*
+                    module->numBuffers;
     module->framebuffer = new private_handle_t(fd, fbSize,
-                            private_handle_t::PRIV_FLAGS_USES_PMEM, BUFFER_TYPE_UI,
-                            module->fbFormat, info.xres, info.yres);
+                                               private_handle_t::PRIV_FLAGS_USES_PMEM,
+                                               BUFFER_TYPE_UI,
+                                               module->fbFormat, info.xres, info.yres);
     void* vaddr = mmap(0, fbSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
     if (vaddr == MAP_FAILED) {
         ALOGE("Error mapping the framebuffer (%s)", strerror(errno));
@@ -794,7 +924,6 @@
     /* Overlay for HDMI*/
     pthread_mutex_init(&(module->overlayLock), NULL);
     pthread_cond_init(&(module->overlayPost), NULL);
-    module->pobjOverlay = new Overlay();
     module->currentOffset = 0;
     module->exitHDMIUILoop = false;
     module->hdmiStateChanged = false;
@@ -822,7 +951,7 @@
     fb_context_t* ctx = (fb_context_t*)dev;
 #if defined(HDMI_DUAL_DISPLAY)
     private_module_t* m = reinterpret_cast<private_module_t*>(
-            ctx->device.common.module);
+        ctx->device.common.module);
     pthread_mutex_lock(&m->overlayLock);
     m->exitHDMIUILoop = true;
     pthread_cond_signal(&(m->overlayPost));
@@ -835,7 +964,7 @@
 }
 
 int fb_device_open(hw_module_t const* module, const char* name,
-        hw_device_t** device)
+                   hw_device_t** device)
 {
     int status = -EINVAL;
     if (!strcmp(name, GRALLOC_HARDWARE_FB0)) {
@@ -849,22 +978,14 @@
         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.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.setUpdateRect   = 0;
         dev->device.compositionComplete = fb_compositionComplete;
-        //dev->device.lockBuffer = fb_lockBuffer;
-#if defined(HDMI_DUAL_DISPLAY)
-        dev->device.orientationChanged = fb_orientationChanged;
-        dev->device.videoOverlayStarted = fb_videoOverlayStarted;
-        dev->device.enableHDMIOutput = fb_enableHDMIOutput;
-        dev->device.setActionSafeWidthRatio = fb_setActionSafeWidthRatio;
-        dev->device.setActionSafeHeightRatio = fb_setActionSafeHeightRatio;
-#endif
 
         private_module_t* m = (private_module_t*)module;
         status = mapFrameBuffer(m);
@@ -878,11 +999,10 @@
             const_cast<float&>(dev->device.xdpi) = m->xdpi;
             const_cast<float&>(dev->device.ydpi) = m->ydpi;
             const_cast<float&>(dev->device.fps) = m->fps;
-            const_cast<int&>(dev->device.minSwapInterval) = private_module_t::PRIV_MIN_SWAP_INTERVAL;
-            const_cast<int&>(dev->device.maxSwapInterval) = private_module_t::PRIV_MAX_SWAP_INTERVAL;
-            //const_cast<int&>(dev->device.numFramebuffers) = m->numBuffers;
+            const_cast<int&>(dev->device.minSwapInterval) = PRIV_MIN_SWAP_INTERVAL;
+            const_cast<int&>(dev->device.maxSwapInterval) = PRIV_MAX_SWAP_INTERVAL;
             if (m->finfo.reserved[0] == 0x5444 &&
-                    m->finfo.reserved[1] == 0x5055) {
+                m->finfo.reserved[1] == 0x5055) {
                 dev->device.setUpdateRect = fb_setUpdateRect;
                 ALOGD("UPDATE_ON_DEMAND supported");
             }
@@ -895,43 +1015,3 @@
     }
     return status;
 }
-
-/* Copy a pmem buffer to the framebuffer */
-
-static void
-msm_copy_buffer(buffer_handle_t handle, int fd,
-                int width, int height, int format,
-                int x, int y, int w, int h)
-{
-    struct {
-        unsigned int count;
-        mdp_blit_req req;
-    } blit;
-    private_handle_t *priv = (private_handle_t*) handle;
-
-    memset(&blit, 0, sizeof(blit));
-    blit.count = 1;
-
-    blit.req.flags = 0;
-    blit.req.alpha = 0xff;
-    blit.req.transp_mask = 0xffffffff;
-
-    blit.req.src.width = width;
-    blit.req.src.height = height;
-    blit.req.src.offset = 0;
-    blit.req.src.memory_id = priv->fd;
-
-    blit.req.dst.width = width;
-    blit.req.dst.height = height;
-    blit.req.dst.offset = 0;
-    blit.req.dst.memory_id = fd;
-    blit.req.dst.format = format;
-
-    blit.req.src_rect.x = blit.req.dst_rect.x = x;
-    blit.req.src_rect.y = blit.req.dst_rect.y = y;
-    blit.req.src_rect.w = blit.req.dst_rect.w = w;
-    blit.req.src_rect.h = blit.req.dst_rect.h = h;
-
-    if (ioctl(fd, MSMFB_BLIT, &blit))
-        ALOGE("MSMFB_BLIT failed = %d", -errno);
-}
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
old mode 100755
new mode 100644
index 77ad174..0ec8d73
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -32,34 +32,12 @@
 using android::sp;
 
 gpu_context_t::gpu_context_t(const private_module_t* module,
-        sp<IAllocController> alloc_ctrl ) :
+                             sp<IAllocController> alloc_ctrl ) :
     mAllocCtrl(alloc_ctrl)
 {
     // Zero out the alloc_device_t
     memset(static_cast<alloc_device_t*>(this), 0, sizeof(alloc_device_t));
 
-    char property[PROPERTY_VALUE_MAX];
-    if (property_get("debug.sf.hw", property, NULL) > 0) {
-        if(atoi(property) == 0) {
-            //debug.sf.hw = 0
-            compositionType = CPU_COMPOSITION;
-        } else { //debug.sf.hw = 1
-            // Get the composition type
-            property_get("debug.composition.type", property, NULL);
-            if (property == NULL) {
-                compositionType = GPU_COMPOSITION;
-            } else if ((strncmp(property, "mdp", 3)) == 0) {
-                compositionType = MDP_COMPOSITION;
-            } else if ((strncmp(property, "c2d", 3)) == 0) {
-                compositionType = C2D_COMPOSITION;
-            } else {
-                compositionType = GPU_COMPOSITION;
-            }
-        }
-    } else { //debug.sf.hw is not set. Use cpu composition
-        compositionType = CPU_COMPOSITION;
-    }
-
     // Initialize the procs
     common.tag     = HARDWARE_DEVICE_TAG;
     common.version = 0;
@@ -74,7 +52,7 @@
 }
 
 int gpu_context_t::gralloc_alloc_framebuffer_locked(size_t size, int usage,
-        buffer_handle_t* pHandle)
+                                                    buffer_handle_t* pHandle)
 {
     private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
 
@@ -136,7 +114,7 @@
 
 
 int gpu_context_t::gralloc_alloc_framebuffer(size_t size, int usage,
-        buffer_handle_t* pHandle)
+                                             buffer_handle_t* pHandle)
 {
     private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
     pthread_mutex_lock(&m->lock);
@@ -162,7 +140,7 @@
     else
         data.align = getpagesize();
     data.pHandle = (unsigned int) pHandle;
-    err = mAllocCtrl->allocate(data, usage, compositionType);
+    err = mAllocCtrl->allocate(data, usage, 0);
 
     if (usage & GRALLOC_USAGE_PRIVATE_UNSYNCHRONIZED) {
         flags |= private_handle_t::PRIV_FLAGS_UNSYNCHRONIZED;
@@ -179,7 +157,8 @@
     if (err == 0) {
         flags |= data.allocType;
         private_handle_t* hnd = new private_handle_t(data.fd, size, flags,
-                bufferType, format, width, height);
+                                                     bufferType, format, width,
+                                                     height);
 
         hnd->offset = data.offset;
         hnd->base = int(data.base) + data.offset;
@@ -217,7 +196,8 @@
 }
 
 int gpu_context_t::alloc_impl(int w, int h, int format, int usage,
-        buffer_handle_t* pHandle, int* pStride, size_t bufferSize) {
+                              buffer_handle_t* pHandle, int* pStride,
+                              size_t bufferSize) {
     if (!pHandle || !pStride)
         return -EINVAL;
 
@@ -234,8 +214,9 @@
     // All buffers marked as protected or for external
     // display need to go to overlay
     if ((usage & GRALLOC_USAGE_EXTERNAL_DISP) ||
-        (usage & GRALLOC_USAGE_PROTECTED)) {
-            bufferType = BUFFER_TYPE_VIDEO;
+        (usage & GRALLOC_USAGE_PROTECTED) ||
+        (usage & GRALLOC_USAGE_PRIVATE_CP_BUFFER)) {
+        bufferType = BUFFER_TYPE_VIDEO;
     }
     int err;
     if (usage & GRALLOC_USAGE_HW_FB) {
@@ -268,12 +249,12 @@
         int index = (hnd->base - m->framebuffer->base) / bufferSize;
         m->bufferMask &= ~(1<<index);
     } else {
+        terminateBuffer(&m->base, const_cast<private_handle_t*>(hnd));
         sp<IMemAlloc> memalloc = mAllocCtrl->getAllocator(hnd->flags);
         int err = memalloc->free_buffer((void*)hnd->base, (size_t) hnd->size,
-                hnd->offset, hnd->fd);
+                                        hnd->offset, hnd->fd);
         if(err)
             return err;
-        terminateBuffer(&m->base, const_cast<private_handle_t*>(hnd));
     }
 
     // Release the genlock
@@ -287,7 +268,8 @@
 }
 
 int gpu_context_t::gralloc_alloc(alloc_device_t* dev, int w, int h, int format,
-        int usage, buffer_handle_t* pHandle, int* pStride)
+                                 int usage, buffer_handle_t* pHandle,
+                                 int* pStride)
 {
     if (!dev) {
         return -EINVAL;
@@ -295,8 +277,10 @@
     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)
+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;
@@ -307,7 +291,7 @@
 
 
 int gpu_context_t::gralloc_free(alloc_device_t* dev,
-        buffer_handle_t handle)
+                                buffer_handle_t handle)
 {
     if (private_handle_t::validate(handle) < 0)
         return -EINVAL;
diff --git a/libgralloc/gpu.h b/libgralloc/gpu.h
index 301c411..487f4d1 100644
--- a/libgralloc/gpu.h
+++ b/libgralloc/gpu.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -28,54 +28,51 @@
 #include <utils/RefBase.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,
-                          android::sp<IAllocController>alloc_ctrl);
+class IAllocController;
+class gpu_context_t : public alloc_device_t {
+    public:
+    gpu_context_t(const private_module_t* module,
+                  android::sp<IAllocController>alloc_ctrl);
 
-            int gralloc_alloc_framebuffer_locked(size_t size, int usage,
-                                                 buffer_handle_t* pHandle);
+    int gralloc_alloc_framebuffer_locked(size_t size, int usage,
+                                         buffer_handle_t* pHandle);
 
-            int gralloc_alloc_framebuffer(size_t size, int usage,
-                                          buffer_handle_t* pHandle);
+    int gralloc_alloc_framebuffer(size_t size, int usage,
+                                  buffer_handle_t* pHandle);
 
-            int gralloc_alloc_buffer(size_t size, int usage,
-                                     buffer_handle_t* pHandle,
-                                     int bufferType, int format,
-                                     int width, int height);
+    int gralloc_alloc_buffer(size_t size, int usage,
+                             buffer_handle_t* pHandle,
+                             int bufferType, int format,
+                             int width, int height);
 
-            int free_impl(private_handle_t const* hnd);
+    int free_impl(private_handle_t const* hnd);
 
-            int alloc_impl(int w, int h, int format, int usage,
-                           buffer_handle_t* pHandle, int* pStride,
-                           size_t bufferSize = 0);
+    int alloc_impl(int w, int h, int format, int usage,
+                   buffer_handle_t* pHandle, int* pStride,
+                   size_t bufferSize = 0);
 
-            static int gralloc_alloc(alloc_device_t* dev, int w, int h,
-                                     int format, int usage,
-                                     buffer_handle_t* pHandle,
-                                     int* pStride);
+    static int gralloc_alloc(alloc_device_t* dev, int w, int h,
+                             int format, int usage,
+                             buffer_handle_t* pHandle,
+                             int* pStride);
 
-            static int gralloc_free(alloc_device_t* dev, buffer_handle_t handle);
+    static int gralloc_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_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);
+    static int gralloc_close(struct hw_device_t *dev);
 
-            int get_composition_type() const { return compositionType; }
-
-
-        private:
-            android::sp<IAllocController> mAllocCtrl;
-            int compositionType;
-            void getGrallocInformationFromFormat(int inputFormat,
-                                                 int *colorFormat,
-                                                 int *bufferType);
-    };
+    private:
+    android::sp<IAllocController> mAllocCtrl;
+    void getGrallocInformationFromFormat(int inputFormat,
+                                         int *colorFormat,
+                                         int *bufferType);
+};
 }
 #endif  // GRALLOC_GPU_H
diff --git a/libgralloc/gr.h b/libgralloc/gr.h
index cc36d9a..b330da9 100644
--- a/libgralloc/gr.h
+++ b/libgralloc/gr.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -51,11 +51,11 @@
 int mapFrameBufferLocked(struct private_module_t* module);
 int terminateBuffer(gralloc_module_t const* module, private_handle_t* hnd);
 size_t getBufferSizeAndDimensions(int width, int height, int format,
-                        int& alignedw, int &alignedh);
+                                  int& alignedw, int &alignedh);
 
 int decideBufferHandlingMechanism(int format, const char *compositionUsed,
-                                   int hasBlitEngine, int *needConversion,
-                                   int *useBufferDirectly);
+                                  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
@@ -66,10 +66,10 @@
 
 class Locker {
     pthread_mutex_t mutex;
-public:
+    public:
     class Autolock {
         Locker& locker;
-    public:
+        public:
         inline Autolock(Locker& locker) : locker(locker) {  locker.lock(); }
         inline ~Autolock() { locker.unlock(); }
     };
diff --git a/libgralloc/gralloc.cpp b/libgralloc/gralloc.cpp
index a98baf8..cf57fee 100644
--- a/libgralloc/gralloc.cpp
+++ b/libgralloc/gralloc.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008, The Android Open Source Project
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -36,71 +36,71 @@
 using android::sp;
 
 int fb_device_open(const hw_module_t* module, const char* name,
-        hw_device_t** device);
+                   hw_device_t** device);
 
 static int gralloc_device_open(const hw_module_t* module, const char* name,
-        hw_device_t** device);
+                               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);
+                        buffer_handle_t handle, int usage,
+                        int l, int t, int w, int h,
+                        void** vaddr);
 
 extern int gralloc_unlock(gralloc_module_t const* module,
-        buffer_handle_t handle);
+                          buffer_handle_t handle);
 
 extern int gralloc_register_buffer(gralloc_module_t const* module,
-        buffer_handle_t handle);
+                                   buffer_handle_t handle);
 
 extern int gralloc_unregister_buffer(gralloc_module_t const* module,
-        buffer_handle_t handle);
+                                     buffer_handle_t handle);
 
 extern int gralloc_perform(struct gralloc_module_t const* module,
-        int operation, ... );
+                           int operation, ... );
 
 // HAL module methods
 static struct hw_module_methods_t gralloc_module_methods = {
-    open: gralloc_device_open
+open: gralloc_device_open
 };
 
 // HAL module initialize
 struct private_module_t HAL_MODULE_INFO_SYM = {
-    base: {
-        common: {
-            tag: HARDWARE_MODULE_TAG,
-            version_major: 1,
-            version_minor: 0,
-            id: GRALLOC_HARDWARE_MODULE_ID,
-            name: "Graphics Memory Allocator Module",
-            author: "The Android Open Source Project",
-            methods: &gralloc_module_methods,
-            dso: 0,
-            reserved: {0},
-        },
-        registerBuffer: gralloc_register_buffer,
-        unregisterBuffer: gralloc_unregister_buffer,
-        lock: gralloc_lock,
-        unlock: gralloc_unlock,
-        perform: gralloc_perform,
-        reserved_proc: {0},
-    },
-    framebuffer: 0,
-    fbFormat: 0,
-    flags: 0,
-    numBuffers: 0,
-    bufferMask: 0,
-    lock: PTHREAD_MUTEX_INITIALIZER,
-    currentBuffer: 0,
+base: {
+    common: {
+        tag: HARDWARE_MODULE_TAG,
+             version_major: 1,
+             version_minor: 0,
+             id: GRALLOC_HARDWARE_MODULE_ID,
+             name: "Graphics Memory Allocator Module",
+             author: "The Android Open Source Project",
+             methods: &gralloc_module_methods,
+             dso: 0,
+             reserved: {0},
+            },
+    registerBuffer: gralloc_register_buffer,
+    unregisterBuffer: gralloc_unregister_buffer,
+    lock: gralloc_lock,
+    unlock: gralloc_unlock,
+    perform: gralloc_perform,
+    reserved_proc: {0},
+      },
+framebuffer: 0,
+fbFormat: 0,
+flags: 0,
+numBuffers: 0,
+bufferMask: 0,
+lock: PTHREAD_MUTEX_INITIALIZER,
+currentBuffer: 0,
 };
 
 // Open Gralloc device
 int gralloc_device_open(const hw_module_t* module, const char* name,
-        hw_device_t** device)
+                        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);
+            module);
         gpu_context_t *dev;
         sp<IAllocController> alloc_ctrl = IAllocController::getInstance(true);
         dev = new gpu_context_t(m, alloc_ctrl);
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index 0679621..846a611 100644
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -28,13 +28,6 @@
 
 #include <cutils/native_handle.h>
 
-#include <linux/fb.h>
-
-#if defined(__cplusplus) && defined(HDMI_DUAL_DISPLAY)
-#include "overlayLib.h"
-using namespace overlay;
-#endif
-
 #include <cutils/log.h>
 
 enum {
@@ -87,6 +80,14 @@
      * other EXTERNAL_ONLY buffers are available. Used during suspend.
      */
     GRALLOC_USAGE_EXTERNAL_BLOCK          =       0x00020000,
+
+    /* Use this flag to request content protected buffers. Please note
+     * that this flag is different from the GRALLOC_USAGE_PROTECTED flag
+     * which can be used for buffers that are not secured for DRM
+     * but still need to be protected from screen captures
+     * 0x00040000 is reserved and these values are subject to change.
+     */
+    GRALLOC_USAGE_PRIVATE_CP_BUFFER       =       0x00080000,
 };
 
 enum {
@@ -96,107 +97,12 @@
 };
 
 
-enum {
-    GPU_COMPOSITION,
-    C2D_COMPOSITION,
-    MDP_COMPOSITION,
-    CPU_COMPOSITION,
-};
-
-/* numbers of max buffers for page flipping */
-#define NUM_FRAMEBUFFERS_MIN 2
-#define NUM_FRAMEBUFFERS_MAX 3
-
-/* number of default bufers for page flipping */
-#define NUM_DEF_FRAME_BUFFERS 2
-#define NO_SURFACEFLINGER_SWAPINTERVAL
 #define INTERLACE_MASK 0x80
 #define S3D_FORMAT_MASK 0xFF000
-#define COLOR_FORMAT(x) (x & 0xFFF) // Max range for colorFormats is 0 - FFF
 #define DEVICE_PMEM "/dev/pmem"
 #define DEVICE_PMEM_ADSP "/dev/pmem_adsp"
 #define DEVICE_PMEM_SMIPOOL "/dev/pmem_smipool"
 /*****************************************************************************/
-#ifdef __cplusplus
-
-//XXX: Remove framebuffer specific classes and defines to a different header
-template <class T>
-struct Node
-{
-    T data;
-    Node<T> *next;
-};
-
-template <class T>
-class Queue
-{
-public:
-    Queue(): front(NULL), back(NULL), len(0) {dummy = new T;}
-    ~Queue()
-    {
-        clear();
-        delete dummy;
-    }
-    void push(const T& item)   //add an item to the back of the queue
-    {
-        if(len != 0) {         //if the queue is not empty
-            back->next = new Node<T>; //create a new node
-            back = back->next; //set the new node as the back node
-            back->data = item;
-            back->next = NULL;
-        } else {
-            back = new Node<T>;
-            back->data = item;
-            back->next = NULL;
-            front = back;
-       }
-       len++;
-    }
-    void pop()                 //remove the first item from the queue
-    {
-        if (isEmpty())
-            return;            //if the queue is empty, no node to dequeue
-        T item = front->data;
-        Node<T> *tmp = front;
-        front = front->next;
-        delete tmp;
-        if(front == NULL)      //if the queue is empty, update the back pointer
-            back = NULL;
-        len--;
-        return;
-    }
-    T& getHeadValue() const    //return the value of the first item in the queue
-    {                          //without modification to the structure
-        if (isEmpty()) {
-            ALOGE("Error can't get head of empty queue");
-            return *dummy;
-        }
-        return front->data;
-    }
-
-    bool isEmpty() const       //returns true if no elements are in the queue
-    {
-        return (front == NULL);
-    }
-
-    size_t size() const        //returns the amount of elements in the queue
-    {
-        return len;
-    }
-
-private:
-    Node<T> *front;
-    Node<T> *back;
-    size_t len;
-    void clear()
-    {
-        while (!isEmpty())
-            pop();
-    }
-    T *dummy;
-};
-#endif
-
 enum {
     /* OEM specific HAL formats */
     HAL_PIXEL_FORMAT_NV12_ENCODEABLE  = 0x102,
@@ -206,6 +112,8 @@
     HAL_PIXEL_FORMAT_YCrCb_422_SP           = 0x10B,
     HAL_PIXEL_FORMAT_R_8                    = 0x10D,
     HAL_PIXEL_FORMAT_RG_88                  = 0x10E,
+    HAL_PIXEL_FORMAT_YCbCr_444_SP           = 0x10F,
+    HAL_PIXEL_FORMAT_YCrCb_444_SP           = 0x110,
     HAL_PIXEL_FORMAT_INTERLACE              = 0x180,
 
 };
@@ -224,89 +132,8 @@
 };
 
 enum {
-	BUFFER_TYPE_UI = 0,
-	BUFFER_TYPE_VIDEO
-};
-
-#if defined(HDMI_DUAL_DISPLAY)
-enum hdmi_mirroring_state {
-    HDMI_NO_MIRRORING,
-    HDMI_UI_MIRRORING,
-    HDMI_ORIGINAL_RESOLUTION_MIRRORING
-};
-#endif
-/*****************************************************************************/
-
-struct private_module_t;
-struct private_handle_t;
-struct PmemAllocator;
-
-struct qbuf_t {
-    buffer_handle_t buf;
-    int  idx;
-};
-
-enum buf_state {
-    SUB,
-    REF,
-    AVL
-};
-
-struct avail_t {
-    pthread_mutex_t lock;
-    pthread_cond_t cond;
-#ifdef __cplusplus
-    bool is_avail;
-    buf_state state;
-#endif
-};
-
-struct private_module_t {
-    gralloc_module_t base;
-
-    struct private_handle_t* framebuffer;
-    uint32_t fbFormat;
-    uint32_t flags;
-    uint32_t numBuffers;
-    uint32_t bufferMask;
-    pthread_mutex_t lock;
-    buffer_handle_t currentBuffer;
-
-    struct fb_var_screeninfo info;
-    struct fb_fix_screeninfo finfo;
-    float xdpi;
-    float ydpi;
-    float fps;
-    int swapInterval;
-#ifdef __cplusplus
-    Queue<struct qbuf_t> disp; // non-empty when buffer is ready for display
-#endif
-    int currentIdx;
-    struct avail_t avail[NUM_FRAMEBUFFERS_MAX];
-    pthread_mutex_t qlock;
-    pthread_cond_t qpost;
-
-    enum {
-        // flag to indicate we'll post this buffer
-        PRIV_USAGE_LOCKED_FOR_POST = 0x80000000,
-        PRIV_MIN_SWAP_INTERVAL = 0,
-        PRIV_MAX_SWAP_INTERVAL = 1,
-    };
-#if defined(__cplusplus) && defined(HDMI_DUAL_DISPLAY)
-    Overlay* pobjOverlay;
-    int orientation;
-    bool videoOverlay;
-    uint32_t currentOffset;
-    int enableHDMIOutput; // holds the type of external display
-    bool trueMirrorSupport;
-    bool exitHDMIUILoop;
-    float actionsafeWidthRatio;
-    float actionsafeHeightRatio;
-    bool hdmiStateChanged;
-    hdmi_mirroring_state hdmiMirroringState;
-    pthread_mutex_t overlayLock;
-    pthread_cond_t overlayPost;
-#endif
+    BUFFER_TYPE_UI = 0,
+    BUFFER_TYPE_VIDEO
 };
 
 /*****************************************************************************/
@@ -314,87 +141,114 @@
 #ifdef __cplusplus
 struct private_handle_t : public native_handle {
 #else
-struct private_handle_t {
-    native_handle_t nativeHandle;
+    struct private_handle_t {
+        native_handle_t nativeHandle;
 #endif
-    enum {
-        PRIV_FLAGS_FRAMEBUFFER    = 0x00000001,
-        PRIV_FLAGS_USES_PMEM      = 0x00000002,
-        PRIV_FLAGS_USES_PMEM_ADSP = 0x00000004,
-        PRIV_FLAGS_USES_ION       = 0x00000008,
-        PRIV_FLAGS_USES_ASHMEM    = 0x00000010,
-        PRIV_FLAGS_NEEDS_FLUSH    = 0x00000020,
-        PRIV_FLAGS_DO_NOT_FLUSH   = 0x00000040,
-        PRIV_FLAGS_SW_LOCK        = 0x00000080,
-        PRIV_FLAGS_NONCONTIGUOUS_MEM = 0x00000100,
-        PRIV_FLAGS_HWC_LOCK       = 0x00000200, // Set by HWC when storing the handle
-        PRIV_FLAGS_SECURE_BUFFER  = 0x00000400,
-        PRIV_FLAGS_UNSYNCHRONIZED = 0x00000800, // For explicit synchronization
-        PRIV_FLAGS_NOT_MAPPED     = 0x00001000, // Not mapped in userspace
-        PRIV_FLAGS_EXTERNAL_ONLY  = 0x00002000, // Display on external only
-        PRIV_FLAGS_EXTERNAL_BLOCK = 0x00004000, // Display only this buffer on external
-    };
+        enum {
+            PRIV_FLAGS_FRAMEBUFFER        = 0x00000001,
+            PRIV_FLAGS_USES_PMEM          = 0x00000002,
+            PRIV_FLAGS_USES_PMEM_ADSP     = 0x00000004,
+            PRIV_FLAGS_USES_ION           = 0x00000008,
+            PRIV_FLAGS_USES_ASHMEM        = 0x00000010,
+            PRIV_FLAGS_NEEDS_FLUSH        = 0x00000020,
+            PRIV_FLAGS_DO_NOT_FLUSH       = 0x00000040,
+            PRIV_FLAGS_SW_LOCK            = 0x00000080,
+            PRIV_FLAGS_NONCONTIGUOUS_MEM  = 0x00000100,
+            // Set by HWC when storing the handle
+            PRIV_FLAGS_HWC_LOCK           = 0x00000200,
+            PRIV_FLAGS_SECURE_BUFFER      = 0x00000400,
+            // For explicit synchronization
+            PRIV_FLAGS_UNSYNCHRONIZED     = 0x00000800,
+            // Not mapped in userspace
+            PRIV_FLAGS_NOT_MAPPED         = 0x00001000,
+            // Display on external only
+            PRIV_FLAGS_EXTERNAL_ONLY      = 0x00002000,
+            // Display only this buffer on external
+            PRIV_FLAGS_EXTERNAL_BLOCK     = 0x00004000,
+        };
 
-    // file-descriptors
-    int     fd;
-    int     genlockHandle; // genlock handle to be dup'd by the binder
-    // ints
-    int     magic;
-    int     flags;
-    int     size;
-    int     offset;
-    int     bufferType;
-
-    // FIXME: the attributes below should be out-of-line
-    int     base;
-    int     gpuaddr; // The gpu address mapped into the mmu. If using ashmem, set to 0 They don't care
-    int     pid;
-    int     format;
-    int     width;
-    int     height;
-    int     genlockPrivFd; // local fd of the genlock device.
+        // file-descriptors
+        int     fd;
+        // genlock handle to be dup'd by the binder
+        int     genlockHandle;
+        // ints
+        int     magic;
+        int     flags;
+        int     size;
+        int     offset;
+        int     bufferType;
+        int     base;
+        // The gpu address mapped into the mmu.
+        // If using ashmem, set to 0, they don't care
+        int     gpuaddr;
+        int     pid;
+        int     format;
+        int     width;
+        int     height;
+        // local fd of the genlock device.
+        int     genlockPrivFd;
 
 #ifdef __cplusplus
-    static const int sNumInts = 12;
-    static const int sNumFds = 2;
-    static const int sMagic = 'gmsm';
+        static const int sNumInts = 12;
+        static const int sNumFds = 2;
+        static const int sMagic = 'gmsm';
 
-    private_handle_t(int fd, int size, int flags, int bufferType, int format, int width, int height) :
-        fd(fd), genlockHandle(-1), magic(sMagic), flags(flags), size(size), offset(0),
-        bufferType(bufferType), base(0), gpuaddr(0), pid(getpid()), format(format),
-        width(width), height(height), genlockPrivFd(-1)
-    {
-        version = sizeof(native_handle);
-        numInts = sNumInts;
-        numFds = sNumFds;
-    }
-    ~private_handle_t() {
-        magic = 0;
-    }
+        private_handle_t(int fd, int size, int flags, int bufferType,
+                         int format,int width, int height) :
+            fd(fd), genlockHandle(-1), magic(sMagic),
+            flags(flags), size(size), offset(0),
+            bufferType(bufferType), base(0), gpuaddr(0),
+            pid(getpid()), format(format),
+            width(width), height(height), genlockPrivFd(-1)
+        {
+            version = sizeof(native_handle);
+            numInts = sNumInts;
+            numFds = sNumFds;
+        }
+        ~private_handle_t() {
+            magic = 0;
+        }
 
-    bool usesPhysicallyContiguousMemory() {
-        return (flags & PRIV_FLAGS_USES_PMEM) != 0;
-    }
+        bool usesPhysicallyContiguousMemory() {
+            return (flags & PRIV_FLAGS_USES_PMEM) != 0;
+        }
 
-    static int validate(const native_handle* h) {
-        const private_handle_t* hnd = (const private_handle_t*)h;
-        if (!h || h->version != sizeof(native_handle) ||
+        static int validate(const native_handle* h) {
+            const private_handle_t* hnd = (const private_handle_t*)h;
+            if (!h || h->version != sizeof(native_handle) ||
                 h->numInts != sNumInts || h->numFds != sNumFds ||
                 hnd->magic != sMagic)
-        {
-            ALOGE("invalid gralloc handle (at %p)", h);
-            return -EINVAL;
+            {
+                ALOGD("Invalid gralloc handle (at %p): "
+                      "ver(%d/%d) 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;
         }
-        return 0;
-    }
 
-    static private_handle_t* dynamicCast(const native_handle* in) {
-        if (validate(in) == 0) {
-            return (private_handle_t*) in;
+        static private_handle_t* dynamicCast(const native_handle* in) {
+            if (validate(in) == 0) {
+                return (private_handle_t*) in;
+            }
+            return NULL;
         }
-        return NULL;
-    }
 #endif
-};
+    };
 
 #endif /* GRALLOC_PRIV_H_ */
diff --git a/libgralloc/ionalloc.cpp b/libgralloc/ionalloc.cpp
index 9ff0a5e..7c8fbf4 100644
--- a/libgralloc/ionalloc.cpp
+++ b/libgralloc/ionalloc.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -48,7 +48,7 @@
 
     if(mIonFd < 0 ) {
         ALOGE("%s: Failed to open ion device - %s",
-                __FUNCTION__, strerror(errno));
+              __FUNCTION__, strerror(errno));
         mIonFd = FD_INIT;
         return -errno;
     }
@@ -64,6 +64,7 @@
 
 int IonAlloc::alloc_buffer(alloc_data& data)
 {
+    Locker::Autolock _l(mLock);
     int err = 0;
     int ionSyncFd = FD_INIT;
     int iFd = FD_INIT;
@@ -84,12 +85,11 @@
     if(data.uncached) {
         // Use the sync FD to alloc and map
         // when we need uncached memory
-        // FIX: О–DSYNC defined to open uncached - add that in kernel
-	//ionSyncFd = open(ION_DEVICE, O_RDONLY|O_DSYNC);
-        ionSyncFd = open(ION_DEVICE, O_RDONLY);
+        // XXX: Change O_SYNC to O_DSYNC when available in bionic
+        ionSyncFd = open(ION_DEVICE, O_RDONLY|O_SYNC);
         if(ionSyncFd < 0) {
             ALOGE("%s: Failed to open ion device - %s",
-                    __FUNCTION__, strerror(errno));
+                  __FUNCTION__, strerror(errno));
             return -errno;
         }
         iFd = ionSyncFd;
@@ -111,7 +111,7 @@
     if(ioctl(iFd, ION_IOC_MAP, &fd_data)) {
         err = -errno;
         ALOGE("%s: ION_IOC_MAP failed with error - %s",
-                __FUNCTION__, strerror(errno));
+              __FUNCTION__, strerror(errno));
         ioctl(mIonFd, ION_IOC_FREE, &handle_data);
         if(ionSyncFd >= 0)
             close(ionSyncFd);
@@ -119,15 +119,15 @@
         return err;
     }
 
-    //if(!(data.flags & ION_SECURE) &&
-    if(!(data.allocType & private_handle_t::PRIV_FLAGS_NOT_MAPPED)) {
+    if(!(data.flags & ION_SECURE) &&
+       !(data.allocType & private_handle_t::PRIV_FLAGS_NOT_MAPPED)) {
 
         base = mmap(0, ionAllocData.len, PROT_READ|PROT_WRITE,
-                                MAP_SHARED, fd_data.fd, 0);
+                    MAP_SHARED, fd_data.fd, 0);
         if(base == MAP_FAILED) {
             err = -errno;
             ALOGE("%s: Failed to map the allocated memory: %s",
-                                    __FUNCTION__, strerror(errno));
+                  __FUNCTION__, strerror(errno));
             ioctl(mIonFd, ION_IOC_FREE, &handle_data);
             ionSyncFd = FD_INIT;
             return err;
@@ -146,15 +146,16 @@
     data.fd = fd_data.fd;
     ioctl(mIonFd, ION_IOC_FREE, &handle_data);
     ALOGD("ion: Allocated buffer base:%p size:%d fd:%d",
-                            data.base, ionAllocData.len, data.fd);
+          data.base, ionAllocData.len, data.fd);
     return 0;
 }
 
 
 int IonAlloc::free_buffer(void* base, size_t size, int offset, int fd)
 {
+    Locker::Autolock _l(mLock);
     ALOGD("ion: Freeing buffer base:%p size:%d fd:%d",
-            base, size, fd);
+          base, size, fd);
     int err = 0;
     err = open_device();
     if (err)
@@ -177,15 +178,15 @@
         return err;
 
     base = mmap(0, size, PROT_READ| PROT_WRITE,
-            MAP_SHARED, fd, 0);
+                MAP_SHARED, fd, 0);
     *pBase = base;
     if(base == MAP_FAILED) {
         err = -errno;
         ALOGD("ion: Failed to map memory in the client: %s",
-                                strerror(errno));
+              strerror(errno));
     } else {
         ALOGD("ion: Mapped buffer base:%p size:%d offset:%d fd:%d",
-                                base, size, offset, fd);
+              base, size, offset, fd);
     }
     return err;
 }
@@ -197,7 +198,7 @@
     if(munmap(base, size)) {
         err = -errno;
         ALOGE("ion: Failed to unmap memory at %p : %s",
-                 base, strerror(errno));
+              base, strerror(errno));
     }
     return err;
 
@@ -218,7 +219,7 @@
     if (ioctl(mIonFd, ION_IOC_IMPORT, &fd_data)) {
         err = -errno;
         ALOGE("%s: ION_IOC_IMPORT failed with error - %s",
-                __FUNCTION__, strerror(errno));
+              __FUNCTION__, strerror(errno));
         return err;
     }
 
@@ -230,7 +231,7 @@
     if(ioctl(mIonFd, ION_IOC_CLEAN_INV_CACHES, &flush_data)) {
         err = -errno;
         ALOGE("%s: ION_IOC_CLEAN_INV_CACHES failed with error - %s",
-                __FUNCTION__, strerror(errno));
+              __FUNCTION__, strerror(errno));
         ioctl(mIonFd, ION_IOC_FREE, &handle_data);
         return err;
     }
diff --git a/libgralloc/ionalloc.h b/libgralloc/ionalloc.h
index be26cd7..083f106 100644
--- a/libgralloc/ionalloc.h
+++ b/libgralloc/ionalloc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -31,39 +31,44 @@
 #define GRALLOC_IONALLOC_H
 
 #include "memalloc.h"
+#include "gr.h"
+//#include <linux/ion.h>
+//XXX: Move to bionic
 #include "ion_msm.h"
 
 namespace gralloc {
 
-    class IonAlloc : public IMemAlloc  {
+class IonAlloc : public IMemAlloc  {
 
-        public:
-            virtual int alloc_buffer(alloc_data& data);
+    public:
+    virtual int alloc_buffer(alloc_data& data);
 
-            virtual int free_buffer(void *base, size_t size,
-                    int offset, int fd);
+    virtual int free_buffer(void *base, size_t size,
+                            int offset, int fd);
 
-            virtual int map_buffer(void **pBase, size_t size,
-                    int offset, int fd);
+    virtual int map_buffer(void **pBase, size_t size,
+                           int offset, int fd);
 
-            virtual int unmap_buffer(void *base, size_t size,
-                    int offset);
+    virtual int unmap_buffer(void *base, size_t size,
+                             int offset);
 
-            virtual int clean_buffer(void*base, size_t size,
-                    int offset, int fd);
+    virtual int clean_buffer(void*base, size_t size,
+                             int offset, int fd);
 
-            IonAlloc() { mIonFd = FD_INIT; }
+    IonAlloc() { mIonFd = FD_INIT; }
 
-            ~IonAlloc() { close_device(); }
+    ~IonAlloc() { close_device(); }
 
-        private:
-            int mIonFd;
+    private:
+    int mIonFd;
 
-            int open_device();
+    int open_device();
 
-            void close_device();
+    void close_device();
 
-    };
+    mutable Locker mLock;
+
+};
 
 }
 
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
old mode 100755
new mode 100644
index c7ee7d4..4249f3f
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -58,8 +58,8 @@
 }
 
 static int gralloc_map(gralloc_module_t const* module,
-        buffer_handle_t handle,
-        void** vaddr)
+                       buffer_handle_t handle,
+                       void** vaddr)
 {
     private_handle_t* hnd = (private_handle_t*)handle;
     void *mappedAddress;
@@ -68,22 +68,22 @@
         size_t size = hnd->size;
         sp<IMemAlloc> memalloc = getAllocator(hnd->flags) ;
         int err = memalloc->map_buffer(&mappedAddress, size,
-                hnd->offset, hnd->fd);
+                                       hnd->offset, hnd->fd);
         if(err) {
             ALOGE("Could not mmap handle %p, fd=%d (%s)",
-                    handle, hnd->fd, strerror(errno));
+                  handle, hnd->fd, strerror(errno));
             hnd->base = 0;
             return -errno;
         }
 
         if (mappedAddress == MAP_FAILED) {
             ALOGE("Could not mmap handle %p, fd=%d (%s)",
-                    handle, hnd->fd, strerror(errno));
+                  handle, hnd->fd, strerror(errno));
             hnd->base = 0;
             return -errno;
         }
         hnd->base = intptr_t(mappedAddress) + hnd->offset;
-        //ALOGD("gralloc_map() succeeded fd=%d, off=%d, size=%d, vaddr=%p",
+        //LOGD("gralloc_map() succeeded fd=%d, off=%d, size=%d, vaddr=%p",
         //        hnd->fd, hnd->offset, hnd->size, mappedAddress);
     }
     *vaddr = (void*)hnd->base;
@@ -91,7 +91,7 @@
 }
 
 static int gralloc_unmap(gralloc_module_t const* module,
-        buffer_handle_t handle)
+                         buffer_handle_t handle)
 {
     private_handle_t* hnd = (private_handle_t*)handle;
     if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
@@ -116,7 +116,7 @@
 /*****************************************************************************/
 
 int gralloc_register_buffer(gralloc_module_t const* module,
-        buffer_handle_t handle)
+                            buffer_handle_t handle)
 {
     if (private_handle_t::validate(handle) < 0)
         return -EINVAL;
@@ -164,7 +164,7 @@
 }
 
 int gralloc_unregister_buffer(gralloc_module_t const* module,
-        buffer_handle_t handle)
+                              buffer_handle_t handle)
 {
     if (private_handle_t::validate(handle) < 0)
         return -EINVAL;
@@ -195,7 +195,7 @@
 }
 
 int terminateBuffer(gralloc_module_t const* module,
-        private_handle_t* hnd)
+                    private_handle_t* hnd)
 {
     /*
      * If the buffer has been mapped during a lock operation, it's time
@@ -215,7 +215,8 @@
                 gralloc_unmap(module, hnd);
             }
         } else {
-            ALOGE("terminateBuffer: unmapping a non pmem/ashmem buffer flags = 0x%x", hnd->flags);
+            ALOGE("terminateBuffer: unmapping a non pmem/ashmem buffer flags = 0x%x",
+                  hnd->flags);
             gralloc_unmap(module, hnd);
         }
     }
@@ -224,9 +225,9 @@
 }
 
 int gralloc_lock(gralloc_module_t const* module,
-        buffer_handle_t handle, int usage,
-        int l, int t, int w, int h,
-        void** vaddr)
+                 buffer_handle_t handle, int usage,
+                 int l, int t, int w, int h,
+                 void** vaddr)
 {
     if (private_handle_t::validate(handle) < 0)
         return -EINVAL;
@@ -254,10 +255,10 @@
 
         int timeout = GENLOCK_MAX_TIMEOUT;
         if (GENLOCK_NO_ERROR != genlock_lock_buffer((native_handle_t *)handle,
-                                                   (genlock_lock_type)lockType,
-                                                   timeout)) {
+                                                    (genlock_lock_type)lockType,
+                                                    timeout)) {
             ALOGE("%s: genlock_lock_buffer (lockType=0x%x) failed", __FUNCTION__,
-                lockType);
+                  lockType);
             return -EINVAL;
         } else {
             // Mark this buffer as locked for SW read/write operation.
@@ -274,7 +275,7 @@
 }
 
 int gralloc_unlock(gralloc_module_t const* module,
-        buffer_handle_t handle)
+                   buffer_handle_t handle)
 {
     if (private_handle_t::validate(handle) < 0)
         return -EINVAL;
@@ -285,9 +286,9 @@
         int err;
         sp<IMemAlloc> memalloc = getAllocator(hnd->flags) ;
         err = memalloc->clean_buffer((void*)hnd->base,
-                hnd->size, hnd->offset, hnd->fd);
+                                     hnd->size, hnd->offset, hnd->fd);
         ALOGE_IF(err < 0, "cannot flush handle %p (offs=%x len=%x, flags = 0x%x) err=%s\n",
-                hnd, hnd->offset, hnd->size, hnd->flags, strerror(errno));
+                 hnd, hnd->offset, hnd->size, hnd->flags, strerror(errno));
         hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
     }
 
@@ -305,7 +306,7 @@
 /*****************************************************************************/
 
 int gralloc_perform(struct gralloc_module_t const* module,
-        int operation, ... )
+                    int operation, ... )
 {
     int res = -EINVAL;
     va_list args;
@@ -324,12 +325,12 @@
                 native_handle_t** handle = va_arg(args, native_handle_t**);
                 int memoryFlags = va_arg(args, int);
                 private_handle_t* hnd = (private_handle_t*)native_handle_create(
-                        private_handle_t::sNumFds, private_handle_t::sNumInts);
+                    private_handle_t::sNumFds, private_handle_t::sNumInts);
                 hnd->magic = private_handle_t::sMagic;
                 hnd->fd = fd;
                 unsigned int contigFlags = GRALLOC_USAGE_PRIVATE_ADSP_HEAP |
-                                  GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP |
-                                  GRALLOC_USAGE_PRIVATE_SMI_HEAP;
+                    GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP |
+                    GRALLOC_USAGE_PRIVATE_SMI_HEAP;
 
                 if (memoryFlags & contigFlags) {
                     // check if the buffer is a pmem buffer
@@ -338,7 +339,7 @@
                         hnd->flags =  private_handle_t::PRIV_FLAGS_USES_ION;
                     else
                         hnd->flags =  private_handle_t::PRIV_FLAGS_USES_PMEM |
-                                      private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH;
+                            private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH;
                 } else {
                     if (memoryFlags & GRALLOC_USAGE_PRIVATE_ION)
                         hnd->flags =  private_handle_t::PRIV_FLAGS_USES_ION;
diff --git a/libgralloc/memalloc.h b/libgralloc/memalloc.h
index 13a54e7..349078d 100644
--- a/libgralloc/memalloc.h
+++ b/libgralloc/memalloc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -35,50 +35,50 @@
 
 namespace gralloc {
 
-    struct alloc_data {
-        void           *base;
-        int            fd;
-        int            offset;
-        size_t         size;
-        size_t         align;
-        unsigned int   pHandle;
-        bool           uncached;
-        unsigned int   flags;
-        int            allocType;
+struct alloc_data {
+    void           *base;
+    int            fd;
+    int            offset;
+    size_t         size;
+    size_t         align;
+    unsigned int   pHandle;
+    bool           uncached;
+    unsigned int   flags;
+    int            allocType;
+};
+
+class IMemAlloc : public android::RefBase {
+
+    public:
+    // Allocate buffer - fill in the alloc_data
+    // structure and pass it in. Mapped address
+    // and fd are returned in the alloc_data struct
+    virtual int alloc_buffer(alloc_data& data) = 0;
+
+    // Free buffer
+    virtual int free_buffer(void *base, size_t size,
+                            int offset, int fd) = 0;
+
+    // Map buffer
+    virtual int map_buffer(void **pBase, size_t size,
+                           int offset, int fd) = 0;
+
+    // Unmap buffer
+    virtual int unmap_buffer(void *base, size_t size,
+                             int offset) = 0;
+
+    // Clean and invalidate
+    virtual int clean_buffer(void *base, size_t size,
+                             int offset, int fd) = 0;
+
+    // Destructor
+    virtual ~IMemAlloc() {};
+
+    enum {
+        FD_INIT = -1,
     };
 
-    class IMemAlloc : public android::RefBase {
-
-        public:
-            // Allocate buffer - fill in the alloc_data
-            // structure and pass it in. Mapped address
-            // and fd are returned in the alloc_data struct
-            virtual int alloc_buffer(alloc_data& data) = 0;
-
-            // Free buffer
-            virtual int free_buffer(void *base, size_t size,
-                    int offset, int fd) = 0;
-
-            // Map buffer
-            virtual int map_buffer(void **pBase, size_t size,
-                    int offset, int fd) = 0;
-
-            // Unmap buffer
-            virtual int unmap_buffer(void *base, size_t size,
-                    int offset) = 0;
-
-            // Clean and invalidate
-            virtual int clean_buffer(void *base, size_t size,
-                    int offset, int fd) = 0;
-
-            // Destructor
-            virtual ~IMemAlloc() {};
-
-            enum {
-                FD_INIT = -1,
-            };
-
-    };
+};
 
 } // end gralloc namespace
 #endif // GRALLOC_MEMALLOC_H
diff --git a/libgralloc/pmem_bestfit_alloc.cpp b/libgralloc/pmem_bestfit_alloc.cpp
index e3875e9..3b91dec 100644
--- a/libgralloc/pmem_bestfit_alloc.cpp
+++ b/libgralloc/pmem_bestfit_alloc.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2009 The Android Open Source Project
- * Copyright (c) 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -24,12 +24,12 @@
 const int SimpleBestFitAllocator::kMemoryAlign = 32;
 
 SimpleBestFitAllocator::SimpleBestFitAllocator()
-    : mHeapSize(0)
+: mHeapSize(0)
 {
 }
 
 SimpleBestFitAllocator::SimpleBestFitAllocator(size_t size)
-    : mHeapSize(0)
+: mHeapSize(0)
 {
     setSize(size);
 }
@@ -113,13 +113,13 @@
                 mList.insertBefore(free_chunk, split);
             }
 
-            LOGE_IF(((free_chunk->start*kMemoryAlign)&(pagesize-1)),
-                    "page is not aligned!!!");
+            ALOGE_IF(((free_chunk->start*kMemoryAlign)&(pagesize-1)),
+                     "page is not aligned!!!");
 
             const ssize_t tail_free = free_size - (size+extra);
             if (tail_free > 0) {
                 chunk_t* split = new chunk_t(
-                        free_chunk->start + free_chunk->size, tail_free);
+                    free_chunk->start + free_chunk->size, tail_free);
                 mList.insertAfter(free_chunk, split);
             }
         }
@@ -128,33 +128,33 @@
     // we are out of PMEM. Print pmem stats
     // check if there is any leak or fragmentation
 
-    LOGD (" Out of PMEM. Dumping PMEM stats for debugging");
-    LOGD (" ------------- PRINT PMEM STATS --------------");
+    ALOGD (" Out of PMEM. Dumping PMEM stats for debugging");
+    ALOGD (" ------------- PRINT PMEM STATS --------------");
 
     cur = mList.head();
     static uint32_t node_count;
     static uint64_t allocated, free_space;
 
     while (cur) {
-      LOGD (" Node %d -> Start Address : %u Size %u Free info %d",\
-              node_count++, cur->start, cur->size, cur->free);
+        ALOGD (" Node %d -> Start Address : %u Size %u Free info %d",\
+               node_count++, cur->start, cur->size, cur->free);
 
-      // if cur-> free is 1 , the node is free
-      // calculate the total allocated and total free stats also
+        // if cur-> free is 1 , the node is free
+        // calculate the total allocated and total free stats also
 
-      if (cur->free)
-         free_space += cur->size;
-      else
-         allocated += cur->size;
-      // read next node
-      cur = cur->next;
+        if (cur->free)
+            free_space += cur->size;
+        else
+            allocated += cur->size;
+        // read next node
+        cur = cur->next;
     }
-    LOGD (" Total Allocated: %l Total Free: %l", allocated, free_space );
+    ALOGD (" Total Allocated: %l Total Free: %l", allocated, free_space );
 
     node_count = 0;
     allocated = 0;
     free_space = 0;
-    LOGD ("----------------------------------------------");
+    ALOGD ("----------------------------------------------");
     return -ENOMEM;
 }
 
@@ -164,9 +164,9 @@
     chunk_t* cur = mList.head();
     while (cur) {
         if (cur->start == start) {
-            LOG_FATAL_IF(cur->free,
-                "block at offset 0x%08lX of size 0x%08lX already freed",
-                cur->start*kMemoryAlign, cur->size*kMemoryAlign);
+            ALOG_FATAL_IF(cur->free,
+                          "block at offset 0x%08lX of size 0x%08lX already freed",
+                          cur->start*kMemoryAlign, cur->size*kMemoryAlign);
 
             // merge freed blocks together
             chunk_t* freed = cur;
@@ -183,9 +183,9 @@
                 cur = n;
             } while (cur && cur->free);
 
-            LOG_FATAL_IF(!freed->free,
-                "freed block at offset 0x%08lX of size 0x%08lX is not free!",
-                freed->start * kMemoryAlign, freed->size * kMemoryAlign);
+            ALOG_FATAL_IF(!freed->free,
+                          "freed block at offset 0x%08lX of size 0x%08lX is not free!",
+                          freed->start * kMemoryAlign, freed->size * kMemoryAlign);
 
             return freed;
         }
diff --git a/libgralloc/pmem_bestfit_alloc.h b/libgralloc/pmem_bestfit_alloc.h
index 2ea8452..4346ec3 100644
--- a/libgralloc/pmem_bestfit_alloc.h
+++ b/libgralloc/pmem_bestfit_alloc.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2009 The Android Open Source Project
- * Copyright (c) 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -36,8 +36,8 @@
     NODE*  mFirst;
     NODE*  mLast;
 
-public:
-                LinkedList() : mFirst(0), mLast(0) { }
+ public:
+    LinkedList() : mFirst(0), mLast(0) { }
     bool        isEmpty() const { return mFirst == 0; }
     NODE const* head() const { return mFirst; }
     NODE*       head() { return mFirst; }
@@ -53,11 +53,11 @@
     }
 
     void insertBefore(NODE* node, NODE* newNode) {
-         newNode->prev = node->prev;
-         newNode->next = node;
-         if (node->prev == 0)   mFirst = newNode;
-         else                   node->prev->next = newNode;
-         node->prev = newNode;
+        newNode->prev = node->prev;
+        newNode->next = node;
+        if (node->prev == 0)   mFirst = newNode;
+        else                   node->prev->next = newNode;
+        node->prev = newNode;
     }
 
     void insertHead(NODE* newNode) {
@@ -94,36 +94,36 @@
 
 class SimpleBestFitAllocator : public gralloc::PmemUserspaceAlloc::Allocator
 {
-public:
+ public:
 
-    SimpleBestFitAllocator();
-    SimpleBestFitAllocator(size_t size);
-    virtual ~SimpleBestFitAllocator();
+  SimpleBestFitAllocator();
+  SimpleBestFitAllocator(size_t size);
+  virtual ~SimpleBestFitAllocator();
 
-    virtual ssize_t setSize(size_t size);
+  virtual ssize_t setSize(size_t size);
 
-    virtual ssize_t allocate(size_t size, uint32_t flags = 0);
-    virtual ssize_t deallocate(size_t offset);
-    virtual size_t  size() const;
+  virtual ssize_t allocate(size_t size, uint32_t flags = 0);
+  virtual ssize_t deallocate(size_t offset);
+  virtual size_t  size() const;
 
-private:
-    struct chunk_t {
-        chunk_t(size_t start, size_t size)
-            : start(start), size(size), free(1), prev(0), next(0) {
-        }
-        size_t              start;
-        size_t              size : 28;
-        int                 free : 4;
-        mutable chunk_t*    prev;
-        mutable chunk_t*    next;
-    };
+ private:
+  struct chunk_t {
+      chunk_t(size_t start, size_t size)
+          : start(start), size(size), free(1), prev(0), next(0) {
+          }
+      size_t              start;
+      size_t              size : 28;
+      int                 free : 4;
+      mutable chunk_t*    prev;
+      mutable chunk_t*    next;
+  };
 
-    ssize_t  alloc(size_t size, uint32_t flags);
-    chunk_t* dealloc(size_t start);
+  ssize_t  alloc(size_t size, uint32_t flags);
+  chunk_t* dealloc(size_t start);
 
-    static const int    kMemoryAlign;
-    mutable Locker      mLock;
-    LinkedList<chunk_t> mList;
-    size_t              mHeapSize;
+  static const int    kMemoryAlign;
+  mutable Locker      mLock;
+  LinkedList<chunk_t> mList;
+  size_t              mHeapSize;
 };
 #endif /* GRALLOC_ALLOCATOR_H_ */
diff --git a/libgralloc/pmemalloc.cpp b/libgralloc/pmemalloc.cpp
index ccbf127..2286fb0 100644
--- a/libgralloc/pmemalloc.cpp
+++ b/libgralloc/pmemalloc.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -126,17 +126,17 @@
         ALOGD("%s: Total pmem size: %d", __FUNCTION__, size);
         if (err < 0) {
             ALOGE("%s: PMEM_GET_TOTAL_SIZE failed (%d), limp mode", mPmemDev,
-                    err);
+                  err);
             size = 8<<20;   // 8 MiB
         }
         mAllocator->setSize(size);
 
         void* base = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd,
-                0);
+                          0);
         if (base == MAP_FAILED) {
             err = -errno;
             ALOGE("%s: Failed to map pmem master fd: %s", mPmemDev,
-                    strerror(errno));
+                  strerror(errno));
             base = 0;
             close(fd);
             fd = -1;
@@ -147,7 +147,7 @@
     } else {
         err = -errno;
         ALOGE("%s: Failed to open pmem device: %s", mPmemDev,
-                strerror(errno));
+              strerror(errno));
     }
     return err;
 }
@@ -203,13 +203,13 @@
 
             if (err < 0) {
                 ALOGE("%s: Failed to initialize pmem sub-heap: %d", mPmemDev,
-                        err);
+                      err);
                 close(fd);
                 mAllocator->deallocate(offset);
                 fd = -1;
             } else {
                 ALOGD("%s: Allocated buffer base:%p size:%d offset:%d fd:%d",
-                        mPmemDev, base, size, offset, fd);
+                      mPmemDev, base, size, offset, fd);
                 memset((char*)base + offset, 0, size);
                 //Clean cache before flushing to ensure pmem is properly flushed
                 err = clean_buffer((void*)((intptr_t) base + offset), size, offset, fd);
@@ -230,12 +230,12 @@
 int PmemUserspaceAlloc::free_buffer(void* base, size_t size, int offset, int fd)
 {
     ALOGD("%s: Freeing buffer base:%p size:%d offset:%d fd:%d",
-            mPmemDev, base, size, offset, fd);
+          mPmemDev, base, size, offset, fd);
     int err = 0;
     if (fd >= 0) {
         int err = unmapSubRegion(fd, offset, size);
         ALOGE_IF(err<0, "PMEM_UNMAP failed (%s), fd=%d, sub.offset=%u, "
-                "sub.size=%u", strerror(errno), fd, offset, size);
+                 "sub.size=%u", strerror(errno), fd, offset, size);
         if (err == 0) {
             // we can't deallocate the memory in case of UNMAP failure
             // because it would give that process access to someone else's
@@ -252,15 +252,15 @@
     int err = 0;
     size += offset;
     void *base = mmap(0, size, PROT_READ| PROT_WRITE,
-            MAP_SHARED, fd, 0);
+                      MAP_SHARED, fd, 0);
     *pBase = base;
     if(base == MAP_FAILED) {
         err = -errno;
         ALOGE("%s: Failed to map buffer size:%d offset:%d fd:%d Error: %s",
-                mPmemDev, size, offset, fd, strerror(errno));
+              mPmemDev, size, offset, fd, strerror(errno));
     } else {
         ALOGD("%s: Mapped buffer base:%p size:%d offset:%d fd:%d",
-                mPmemDev, base, size, offset, fd);
+              mPmemDev, base, size, offset, fd);
     }
     return err;
 
@@ -273,16 +273,15 @@
     base = (void*)(intptr_t(base) - offset);
     size += offset;
     ALOGD("%s: Unmapping buffer base:%p size:%d offset:%d",
-            mPmemDev , base, size, offset);
+          mPmemDev , base, size, offset);
     if (munmap(base, size) < 0) {
-
         err = -errno;
         ALOGE("%s: Failed to unmap memory at %p :%s",
-                   mPmemDev, base, strerror(errno));
+              mPmemDev, base, strerror(errno));
 
     }
 
-   return err;
+    return err;
 }
 
 int PmemUserspaceAlloc::clean_buffer(void *base, size_t size, int offset, int fd)
@@ -327,7 +326,7 @@
     if (base == MAP_FAILED) {
         err = -errno;
         ALOGE("%s: failed to map pmem fd: %s", mPmemDev,
-                strerror(errno));
+              strerror(errno));
         close(fd);
         return err;
     }
@@ -337,7 +336,7 @@
     data.offset = 0;
     data.fd = fd;
     ALOGD("%s: Allocated buffer base:%p size:%d fd:%d",
-                            mPmemDev, base, size, fd);
+          mPmemDev, base, size, fd);
     return 0;
 
 }
@@ -345,7 +344,7 @@
 int PmemKernelAlloc::free_buffer(void* base, size_t size, int offset, int fd)
 {
     ALOGD("%s: Freeing buffer base:%p size:%d fd:%d",
-            mPmemDev, base, size, fd);
+          mPmemDev, base, size, fd);
 
     int err =  unmap_buffer(base, size, offset);
     close(fd);
@@ -356,15 +355,15 @@
 {
     int err = 0;
     void *base = mmap(0, size, PROT_READ| PROT_WRITE,
-            MAP_SHARED, fd, 0);
+                      MAP_SHARED, fd, 0);
     *pBase = base;
     if(base == MAP_FAILED) {
         err = -errno;
         ALOGE("%s: Failed to map memory in the client: %s",
-                mPmemDev, strerror(errno));
+              mPmemDev, strerror(errno));
     } else {
         ALOGD("%s: Mapped buffer base:%p size:%d, fd:%d",
-                                mPmemDev, base, size, fd);
+              mPmemDev, base, size, fd);
     }
     return err;
 
@@ -376,7 +375,7 @@
     if (munmap(base, size)) {
         err = -errno;
         ALOGW("%s: Error unmapping memory at %p: %s",
-                                mPmemDev, base, strerror(err));
+              mPmemDev, base, strerror(err));
     }
     return err;
 
diff --git a/libgralloc/pmemalloc.h b/libgralloc/pmemalloc.h
index 4aed0b1..82794ec 100644
--- a/libgralloc/pmemalloc.h
+++ b/libgralloc/pmemalloc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -35,72 +35,72 @@
 #include "memalloc.h"
 
 namespace gralloc {
-    class PmemUserspaceAlloc : public IMemAlloc  {
+class PmemUserspaceAlloc : public IMemAlloc  {
 
+    public:
+    class Allocator: public android::RefBase {
         public:
-            class Allocator: public android::RefBase {
-                public:
-                    virtual ~Allocator() {};
-                    virtual ssize_t setSize(size_t size) = 0;
-                    virtual size_t  size() const = 0;
-                    virtual ssize_t allocate(size_t size, uint32_t flags = 0) = 0;
-                    virtual ssize_t deallocate(size_t offset) = 0;
-            };
-
-            virtual int alloc_buffer(alloc_data& data);
-
-            virtual int free_buffer(void *base, size_t size,
-                    int offset, int fd);
-
-            virtual int map_buffer(void **pBase, size_t size,
-                    int offset, int fd);
-
-            virtual int unmap_buffer(void *base, size_t size,
-                    int offset);
-
-            virtual int clean_buffer(void*base, size_t size,
-                    int offset, int fd);
-
-            PmemUserspaceAlloc();
-
-            ~PmemUserspaceAlloc();
-
-        private:
-            int mMasterFd;
-            void* mMasterBase;
-            const char* mPmemDev;
-            android::sp<Allocator> mAllocator;
-            pthread_mutex_t mLock;
-            int init_pmem_area();
-            int init_pmem_area_locked();
-
+        virtual ~Allocator() {};
+        virtual ssize_t setSize(size_t size) = 0;
+        virtual size_t  size() const = 0;
+        virtual ssize_t allocate(size_t size, uint32_t flags = 0) = 0;
+        virtual ssize_t deallocate(size_t offset) = 0;
     };
 
-    class PmemKernelAlloc : public IMemAlloc  {
+    virtual int alloc_buffer(alloc_data& data);
 
-        public:
-            virtual int alloc_buffer(alloc_data& data);
+    virtual int free_buffer(void *base, size_t size,
+                            int offset, int fd);
 
-            virtual int free_buffer(void *base, size_t size,
-                    int offset, int fd);
+    virtual int map_buffer(void **pBase, size_t size,
+                           int offset, int fd);
 
-            virtual int map_buffer(void **pBase, size_t size,
-                    int offset, int fd);
+    virtual int unmap_buffer(void *base, size_t size,
+                             int offset);
 
-            virtual int unmap_buffer(void *base, size_t size,
-                    int offset);
+    virtual int clean_buffer(void*base, size_t size,
+                             int offset, int fd);
 
-            virtual int clean_buffer(void*base, size_t size,
-                    int offset, int fd);
+    PmemUserspaceAlloc();
 
-            PmemKernelAlloc(const char* device);
+    ~PmemUserspaceAlloc();
 
-            ~PmemKernelAlloc();
-        private:
-            const char* mPmemDev;
+    private:
+    int mMasterFd;
+    void* mMasterBase;
+    const char* mPmemDev;
+    android::sp<Allocator> mAllocator;
+    pthread_mutex_t mLock;
+    int init_pmem_area();
+    int init_pmem_area_locked();
+
+};
+
+class PmemKernelAlloc : public IMemAlloc  {
+
+    public:
+    virtual int alloc_buffer(alloc_data& data);
+
+    virtual int free_buffer(void *base, size_t size,
+                            int offset, int fd);
+
+    virtual int map_buffer(void **pBase, size_t size,
+                           int offset, int fd);
+
+    virtual int unmap_buffer(void *base, size_t size,
+                             int offset);
+
+    virtual int clean_buffer(void*base, size_t size,
+                             int offset, int fd);
+
+    PmemKernelAlloc(const char* device);
+
+    ~PmemKernelAlloc();
+    private:
+    const char* mPmemDev;
 
 
-    };
+};
 
 }
 #endif /* GRALLOC_PMEMALLOC_H */
diff --git a/libhwcomposer/Android.mk b/libhwcomposer/Android.mk
index a600f97..7cb5c6f 100644
--- a/libhwcomposer/Android.mk
+++ b/libhwcomposer/Android.mk
@@ -1,39 +1,18 @@
 LOCAL_PATH := $(call my-dir)
-
-# HAL module implemenation, not prelinked and stored in
-# hw/<OVERLAY_HARDWARE_MODULE_ID>.<ro.product.board>.so
 include $(CLEAR_VARS)
 LOCAL_PRELINK_MODULE := false
 LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
-LOCAL_SHARED_LIBRARIES := liblog libcutils libEGL libhardware libutils liboverlay
-LOCAL_SHARED_LIBRARIES += libgenlock libQcomUI libmemalloc
-
-LOCAL_SRC_FILES := 	\
-    hwcomposer.cpp \
-    external_display_only.h
-
+LOCAL_SHARED_LIBRARIES := liblog libcutils libhardware libutils
+LOCAL_SHARED_LIBRARIES += libEGL liboverlay libgenlock
+LOCAL_SRC_FILES :=  hwc.cpp          \
+                    hwc_overlay.cpp  \
+                    hwc_utils.cpp
 LOCAL_MODULE := hwcomposer.$(TARGET_BOARD_PLATFORM)
-LOCAL_CFLAGS:= -DLOG_TAG=\"$(TARGET_BOARD_PLATFORM).hwcomposer\" -DDEBUG_CALC_FPS
-
-LOCAL_C_INCLUDES += hardware/qcom/display/libgralloc
-LOCAL_C_INCLUDES += hardware/qcom/display/liboverlay
-LOCAL_C_INCLUDES += hardware/qcom/display/libcopybit
+LOCAL_C_INCLUDES := hardware/qcom/display/libgralloc
 LOCAL_C_INCLUDES += hardware/qcom/display/libgenlock
+LOCAL_C_INCLUDES += hardware/qcom/display/liboverlay
 LOCAL_C_INCLUDES += hardware/qcom/display/libqcomui
-LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+LOCAL_CFLAGS:= -DLOG_TAG=\"$(TARGET_BOARD_PLATFORM).hwcomposer\"
 
-LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
-ifeq ($(TARGET_HAVE_HDMI_OUT),true)
-LOCAL_CFLAGS += -DHDMI_DUAL_DISPLAY
-endif
-ifeq ($(TARGET_USES_OVERLAY),true)
-LOCAL_CFLAGS += -DUSE_OVERLAY
-endif
-ifeq ($(TARGET_HAVE_BYPASS),true)
-LOCAL_CFLAGS += -DCOMPOSITION_BYPASS
-endif
-ifeq ($(TARGET_USE_HDMI_AS_PRIMARY),true)
-LOCAL_CFLAGS += -DHDMI_AS_PRIMARY
-endif
-LOCAL_MODULE_TAGS := optional eng
+LOCAL_MODULE_TAGS := optional
 include $(BUILD_SHARED_LIBRARY)
diff --git a/libhwcomposer/external_display_only.h b/libhwcomposer/external_display_only.h
deleted file mode 100644
index fa24642..0000000
--- a/libhwcomposer/external_display_only.h
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   * Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the following
- *     disclaimer in the documentation and/or other materials provided
- *     with the distribution.
- *   * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *     contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#define EXTDEBUG 0
-class ExtDispOnly {
-
-    enum ExternalOnlyMode {
-        EXT_ONLY_MODE_OFF = 0,
-        EXT_ONLY_MODE_ON = 1,
-    };
-
-    enum {
-        MAX_EXT_ONLY_LAYERS = 2,
-    };
-
-public:
-    /* Initialize, allocate data members */
-    static void init();
-
-    /* Deallocate data members */
-    static void destroy();
-
-    /* Closes all the overlay channels */
-    static void close();
-
-    /* Prepare overlay and configures mdp pipes */
-    static int prepare(hwc_context_t *ctx, hwc_layer_t *layer, int index,
-            bool waitForVsync);
-
-    /* Returns status of external-only mode */
-    static bool isModeOn();
-
-    /* Updates stats and pipe config related to external_only and external_block layers
-     * If we are staring or stopping this mode, update default mirroring.
-     */
-    static int update(hwc_context_t* ctx, hwc_layer_list_t* list);
-
-    /* Stores the locked handle for the buffer that was successfully queued */
-    static void storeLockedHandles(hwc_layer_list_t* list);
-
-    /* Queue buffers to mdp for display */
-    static int draw(hwc_context_t *ctx, hwc_layer_list_t *list);
-
-private:
-    /* Locks a buffer and marks it as locked */
-    static void lockBuffer(native_handle_t *hnd);
-
-    /* Unlocks a buffer and clears the locked flag */
-    static void unlockBuffer(native_handle_t *hnd);
-
-    /* Unlocks buffers queued in previous round (and displayed by now)
-     * Clears the handle cache.
-     */
-    static void unlockPreviousBuffers();
-
-    /* Closes the  a range of overlay channels */
-    static void closeRange(int start);
-
-    /* Start default external mirroring */
-    static void startDefaultMirror(hwc_context_t* ctx);
-
-    /* Stop default external mirroring */
-    static void stopDefaultMirror(hwc_context_t* ctx);
-
-    /* Checks if external-only mode is starting */
-    static bool isExtModeStarting(hwc_context_t* ctx, const int&
-        numExtLayers);
-
-    /* Checks if external-only mode is stopping */
-    static bool isExtModeStopping(hwc_context_t* ctx, const int&
-        numExtLayers);
-
-    //Data members
-#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
-    static overlay::OverlayUI* sOvExtUI[MAX_EXT_ONLY_LAYERS];
-    static native_handle_t* sPreviousExtHandle[MAX_EXT_ONLY_LAYERS];
-    static ExternalOnlyMode sExtOnlyMode;
-    static int sNumExtOnlyLayers;
-    static bool sSkipLayerPresent;
-    static bool sBlockLayerPresent;
-    static int sBlockLayerIndex;
-#endif
-}; //class ExtDispOnly
-
-void ExtDispOnly::lockBuffer(native_handle_t *hnd) {
-#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
-    private_handle_t* phnd = (private_handle_t*)hnd;
-
-    //Genlock is reference counted and recursive.
-    //Do not accidently lock a locked buffer.
-    if(phnd && (phnd->flags & private_handle_t::PRIV_FLAGS_HWC_LOCK)) {
-        LOGE_IF(EXTDEBUG, "%s: handle %p already locked", __func__, phnd);
-        return;
-    }
-    if (GENLOCK_FAILURE == genlock_lock_buffer(hnd, GENLOCK_READ_LOCK,
-            GENLOCK_MAX_TIMEOUT)) {
-        LOGE("%s: genlock_lock_buffer(READ) failed", __func__);
-        return;
-    }
-    phnd->flags |= private_handle_t::PRIV_FLAGS_HWC_LOCK;
-    LOGE_IF(EXTDEBUG, "%s: locked handle = %p", __func__, hnd);
-#endif
-}
-
-void ExtDispOnly::unlockBuffer(native_handle_t *hnd) {
-#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
-    //Check if buffer is still around
-    if(private_handle_t::validate(hnd) != 0) {
-        LOGE("%s Handle already deallocated", __func__);
-        return;
-    }
-
-    private_handle_t* phnd = (private_handle_t*)hnd;
-
-    //Check if buffer was locked in the first place
-    if((phnd->flags & private_handle_t::PRIV_FLAGS_HWC_LOCK) == 0) {
-        LOGE("%s Handle not locked, cannot unlock", __func__);
-        return;
-    }
-
-    //Actually try to unlock
-    if (GENLOCK_FAILURE == genlock_unlock_buffer(hnd)) {
-        LOGE("%s: genlock_unlock_buffer failed", __func__);
-        return;
-    }
-
-    //Clear the locked flag
-    phnd->flags &= ~private_handle_t::PRIV_FLAGS_HWC_LOCK;
-    LOGE_IF(EXTDEBUG, "%s: unlocked handle = %p", __func__, hnd);
-#endif
-}
-
-void ExtDispOnly::unlockPreviousBuffers() {
-#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
-    for(int i = 0; (i < MAX_EXT_ONLY_LAYERS) && sPreviousExtHandle[i]; i++) {
-        LOGE_IF(EXTDEBUG, "%s", __func__);
-        ExtDispOnly::unlockBuffer(sPreviousExtHandle[i]);
-        sPreviousExtHandle[i] = NULL;
-    }
-#endif
-}
-
-void ExtDispOnly::init() {
-#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
-    for(int i = 0; i < MAX_EXT_ONLY_LAYERS; i++) {
-        sOvExtUI[i] = new overlay::OverlayUI();
-        sPreviousExtHandle[i] = NULL;
-    }
-    sExtOnlyMode = EXT_ONLY_MODE_OFF;
-    sNumExtOnlyLayers = 0;
-    sSkipLayerPresent = false;
-    sBlockLayerPresent = false;
-    sBlockLayerIndex = -1;
-    LOGE_IF(EXTDEBUG, "%s", __func__);
-#endif
-}
-
-void ExtDispOnly::destroy() {
-#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
-    for(int i = 0; i < MAX_EXT_ONLY_LAYERS; i++) {
-        delete sOvExtUI[i];
-    }
-#endif
-}
-
-void ExtDispOnly::closeRange(int start) {
-#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
-    for (int index = start; index < MAX_EXT_ONLY_LAYERS; index++) {
-        if(sPreviousExtHandle[index]) {
-            LOGE_IF(EXTDEBUG, "%s", __func__);
-            ExtDispOnly::unlockBuffer(sPreviousExtHandle[index]);
-            sPreviousExtHandle[index] = NULL;
-        }
-        sOvExtUI[index]->closeChannel();
-    }
-#endif
-}
-
-void inline ExtDispOnly::close() {
-#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
-    closeRange(0);
-#endif
-}
-
-int ExtDispOnly::prepare(hwc_context_t *ctx, hwc_layer_t *layer, int index,
-        bool waitForVsync) {
-#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
-    if(ctx->mHDMIEnabled == EXT_DISPLAY_OFF ||
-        ctx->pendingHDMI == true)
-        return -1;
-
-    if (ctx && sOvExtUI[index]) {
-        private_hwc_module_t* hwcModule = reinterpret_cast<
-                private_hwc_module_t*>(ctx->device.common.module);
-        if (!hwcModule) {
-            LOGE("%s null module", __func__);
-            return -1;
-        }
-        private_handle_t *hnd = (private_handle_t *)layer->handle;
-        if(!hnd) {
-            LOGE("%s handle null", __func__);
-            return -1;
-        }
-        overlay::OverlayUI *ovUI = sOvExtUI[index];
-        int ret = 0;
-        //int orientation = layer->transform;
-        //Assuming layers will always be source landscape
-        const int orientation = 0;
-        overlay_buffer_info info;
-        hwc_rect_t sourceCrop = layer->sourceCrop;
-        info.width = sourceCrop.right - sourceCrop.left;
-        info.height = sourceCrop.bottom - sourceCrop.top;
-        info.format = hnd->format;
-        info.size = hnd->size;
-
-
-        const int fbnum = ctx->mHDMIEnabled; //HDMI or WFD
-        const bool isFg = false;
-        //Just to differentiate zorders for different layers
-        const int zorder = index;
-        const bool isVGPipe = true;
-        ovUI->setSource(info, orientation);
-        ovUI->setDisplayParams(fbnum, waitForVsync, isFg, zorder, isVGPipe);
-        const int fbWidth = ovUI->getFBWidth();
-        const int fbHeight = ovUI->getFBHeight();
-        ovUI->setPosition(0, 0, fbWidth, fbHeight);
-        if(ovUI->commit() != overlay::NO_ERROR) {
-            LOGE("%s: Overlay Commit failed", __func__);
-            return -1;
-        }
-    }
-    LOGE_IF(EXTDEBUG, "%s", __func__);
-#endif
-    return overlay::NO_ERROR;
-}
-
-inline void ExtDispOnly::startDefaultMirror(hwc_context_t* ctx) {
-#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
-    hwc_composer_device_t* dev = (hwc_composer_device_t*) ctx;
-    private_hwc_module_t* hwcModule =
-        reinterpret_cast<private_hwc_module_t*>(dev->common.module);
-    framebuffer_device_t *fbDev = hwcModule->fbDevice;
-    if (fbDev) {
-        //mHDMIEnabled could be HDMI/WFD/NO EXTERNAL
-        fbDev->enableHDMIOutput(fbDev, ctx->mHDMIEnabled);
-    }
-#endif
-}
-
-inline void ExtDispOnly::stopDefaultMirror(hwc_context_t* ctx) {
-#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
-    hwc_composer_device_t* dev = (hwc_composer_device_t*) ctx;
-    private_hwc_module_t* hwcModule =
-        reinterpret_cast<private_hwc_module_t*>(dev->common.module);
-    framebuffer_device_t *fbDev = hwcModule->fbDevice;
-    if (fbDev) {
-        fbDev->enableHDMIOutput(fbDev, EXT_DISPLAY_OFF);
-    }
-#endif
-}
-
-inline bool ExtDispOnly::isExtModeStarting(hwc_context_t* ctx, const int&
-        numExtLayers) {
-#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
-    return ((sExtOnlyMode == EXT_ONLY_MODE_OFF) && numExtLayers);
-#endif
-    return false;
-}
-
-inline bool ExtDispOnly::isExtModeStopping(hwc_context_t* ctx, const int&
-        numExtLayers) {
-#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
-    return ((sExtOnlyMode == EXT_ONLY_MODE_ON) && (numExtLayers == 0));
-#endif
-    return false;
-}
-
-inline bool ExtDispOnly::isModeOn() {
-#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
-    return (sExtOnlyMode == EXT_ONLY_MODE_ON);
-#endif
-    return false;
-}
-
-int ExtDispOnly::update(hwc_context_t* ctx, hwc_layer_list_t* list) {
-#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
-    int aNumExtLayers = 0;
-    bool aSkipLayerPresent = false;
-    bool aBlockLayerPresent = false;
-    int aBlockLayerIndex = -1;
-
-    //Book-keeping done each cycle
-    for (size_t i = 0; i < list->numHwLayers; i++) {
-        private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
-        // Dont draw in this round
-        if(list->hwLayers[i].flags & HWC_SKIP_LAYER) {
-            aSkipLayerPresent = true;
-        }
-        if(hnd && (hnd->flags & private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY)) {
-            aNumExtLayers++;
-            // No way we can let this be drawn by GPU to fb0
-            if(list->hwLayers[i].flags & HWC_SKIP_LAYER) {
-                list->hwLayers[i].flags &= ~ HWC_SKIP_LAYER;
-            }
-            list->hwLayers[i].flags |= HWC_USE_EXT_ONLY;
-            list->hwLayers[i].compositionType = HWC_USE_OVERLAY;
-            list->hwLayers[i].hints &= ~HWC_HINT_CLEAR_FB;
-            //EXTERNAL_BLOCK is always an add-on
-            if(hnd && (hnd->flags &
-                    private_handle_t::PRIV_FLAGS_EXTERNAL_BLOCK)) {
-                aBlockLayerPresent = true;
-                aBlockLayerIndex = i;
-                list->hwLayers[i].flags |= HWC_USE_EXT_BLOCK;
-            }
-        }
-    }
-
-    //Update Default mirroring state
-    if (isExtModeStarting(ctx, aNumExtLayers)) {
-        stopDefaultMirror(ctx);
-    } else if (isExtModeStopping(ctx, aNumExtLayers)) {
-        startDefaultMirror(ctx);
-    }
-
-    //Cache our stats
-    sExtOnlyMode = aNumExtLayers ? EXT_ONLY_MODE_ON : EXT_ONLY_MODE_OFF;
-    sNumExtOnlyLayers = aNumExtLayers;
-    sSkipLayerPresent = aSkipLayerPresent;
-    sBlockLayerPresent = aBlockLayerPresent;
-    sBlockLayerIndex = aBlockLayerIndex;
-
-    LOGE_IF(EXTDEBUG, "%s: numExtLayers = %d skipLayerPresent = %d", __func__,
-            aNumExtLayers, aSkipLayerPresent);
-    //If skip layer present return. Buffers to be unlocked in draw phase.
-    if(aSkipLayerPresent) {
-        return overlay::NO_ERROR;
-    }
-
-    //If External is not connected, dont setup pipes, just return
-    if(ctx->mHDMIEnabled == EXT_DISPLAY_OFF ||
-        ctx->pendingHDMI == true) {
-        ExtDispOnly::close();
-        return -1;
-    }
-
-
-    //Update pipes
-    bool waitForVsync = true;
-    bool index = 0;
-
-    if (aBlockLayerPresent) {
-        ExtDispOnly::closeRange(1);
-        ExtDispOnly::prepare(ctx, &(list->hwLayers[aBlockLayerIndex]),
-            index, waitForVsync);
-    } else if (aNumExtLayers) {
-        ExtDispOnly::closeRange(aNumExtLayers);
-        for (size_t i = 0; i < list->numHwLayers; i++) {
-            private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
-            if(hnd && hnd->flags & private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY) {
-                waitForVsync = (index == (aNumExtLayers - 1));
-                ExtDispOnly::prepare(ctx, &(list->hwLayers[i]),
-                    index, waitForVsync);
-                index++;
-            }
-        }
-    } else {
-        ExtDispOnly::close();
-    }
-#endif
-    return overlay::NO_ERROR;
-}
-
-void ExtDispOnly::storeLockedHandles(hwc_layer_list_t* list) {
-#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
-    int index = 0;
-    if(sBlockLayerPresent) {
-        private_handle_t *hnd = (private_handle_t *)
-            list->hwLayers[sBlockLayerIndex].handle;
-        if(list->hwLayers[sBlockLayerIndex].flags & HWC_USE_EXT_ONLY) {
-            if(!(hnd->flags & private_handle_t::PRIV_FLAGS_HWC_LOCK)) {
-                ExtDispOnly::lockBuffer(hnd);
-            }
-            sPreviousExtHandle[index] = hnd;
-            LOGE_IF(EXTDEBUG, "%s BLOCK: handle = %p", __func__, hnd);
-            return;
-        }
-    }
-    for(int i = 0; i < list->numHwLayers; i++) {
-        private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
-        if(list->hwLayers[i].flags & HWC_USE_EXT_ONLY) {
-            if(!(hnd->flags & private_handle_t::PRIV_FLAGS_HWC_LOCK)) {
-                ExtDispOnly::lockBuffer(hnd);
-            }
-            sPreviousExtHandle[index] = hnd;
-            index++;
-            LOGE_IF(EXTDEBUG, "%s: handle = %p", __func__, hnd);
-        }
-    }
-#endif
-}
-
-int ExtDispOnly::draw(hwc_context_t *ctx, hwc_layer_list_t *list) {
-#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
-    LOGE_IF(EXTDEBUG, "%s", __func__);
-    if(ctx->mHDMIEnabled == EXT_DISPLAY_OFF ||
-        ctx->pendingHDMI == true) {
-        ExtDispOnly::close();
-        return -1;
-    }
-
-    int ret = overlay::NO_ERROR;
-    int index = 0;
-
-    //If skip layer present or list invalid unlock and return.
-    if(sSkipLayerPresent || list == NULL) {
-        ExtDispOnly::unlockPreviousBuffers();
-        return overlay::NO_ERROR;
-    }
-
-    if(sBlockLayerPresent) {
-        private_handle_t *hnd = (private_handle_t*)
-            list->hwLayers[sBlockLayerIndex].handle;
-        ExtDispOnly::lockBuffer(hnd);
-        ret =  sOvExtUI[index]->queueBuffer(hnd);
-        if (ret) {
-            LOGE("%s queueBuffer failed", __func__);
-            // Unlock the locked buffer
-            ExtDispOnly::unlockBuffer(hnd);
-            ExtDispOnly::close();
-            return -1;
-        }
-        ExtDispOnly::unlockPreviousBuffers();
-        ExtDispOnly::storeLockedHandles(list);
-        return overlay::NO_ERROR;
-    }
-
-    for(int i = 0; i < list->numHwLayers; i++) {
-        private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
-        if(hnd && list->hwLayers[i].flags & HWC_USE_EXT_ONLY) {
-            overlay::OverlayUI *ovUI = sOvExtUI[index];
-            ExtDispOnly::lockBuffer(hnd);
-            ret = ovUI->queueBuffer(hnd);
-            if (ret) {
-                LOGE("%s queueBuffer failed", __func__);
-                // Unlock the all the currently locked buffers
-                for (int j = 0; j <= i; j++) {
-                    private_handle_t *tmphnd =
-                        (private_handle_t *)list->hwLayers[j].handle;
-                    if(hnd && list->hwLayers[j].flags & HWC_USE_EXT_ONLY)
-                        ExtDispOnly::unlockBuffer(tmphnd);
-                }
-                ExtDispOnly::close();
-                return -1;
-            }
-            index++;
-        }
-    }
-    ExtDispOnly::unlockPreviousBuffers();
-    ExtDispOnly::storeLockedHandles(list);
-#endif
-    return overlay::NO_ERROR;
-}
-
-#if defined (HDMI_DUAL_DISPLAY) && defined (USE_OVERLAY)
-overlay::OverlayUI* ExtDispOnly::sOvExtUI[MAX_EXT_ONLY_LAYERS];
-native_handle_t* ExtDispOnly::sPreviousExtHandle[MAX_EXT_ONLY_LAYERS];
-ExtDispOnly::ExternalOnlyMode ExtDispOnly::sExtOnlyMode;
-int ExtDispOnly::sNumExtOnlyLayers;
-bool ExtDispOnly::sSkipLayerPresent;
-bool ExtDispOnly::sBlockLayerPresent;
-int ExtDispOnly::sBlockLayerIndex;
-#endif
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
new file mode 100644
index 0000000..afd2aa9
--- /dev/null
+++ b/libhwcomposer/hwc.cpp
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fcntl.h>
+#include <errno.h>
+
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+#include <EGL/egl.h>
+
+#include "hwc_utils.h"
+
+using namespace qhwc;
+
+static int hwc_device_open(const struct hw_module_t* module,
+                           const char* name,
+                           struct hw_device_t** device);
+
+static struct hw_module_methods_t hwc_module_methods = {
+    open: hwc_device_open
+};
+
+hwc_module_t HAL_MODULE_INFO_SYM = {
+    common: {
+        tag: HARDWARE_MODULE_TAG,
+        version_major: 2,
+        version_minor: 0,
+        id: HWC_HARDWARE_MODULE_ID,
+        name: "Qualcomm Hardware Composer Module",
+        author: "CodeAurora Forum",
+        methods: &hwc_module_methods,
+        dso: 0,
+        reserved: {0},
+    }
+};
+
+/*
+ * Save callback functions registered to HWC
+ */
+static void hwc_registerProcs(struct hwc_composer_device* dev,
+                              hwc_procs_t const* procs)
+{
+    hwc_context_t* ctx = (hwc_context_t*)(dev);
+    if(!ctx) {
+        ALOGE("%s: Invalid context", __FUNCTION__);
+        return;
+    }
+    ctx->device.reserved_proc[0] = (void*)procs;
+}
+
+static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list)
+{
+    hwc_context_t* ctx = (hwc_context_t*)(dev);
+    if (LIKELY(list)) {
+        getLayerStats(ctx, list);
+        cleanOverlays(ctx);
+        for (int i=list->numHwLayers-1; i >= 0 ; i--) {
+            private_handle_t *hnd =
+                (private_handle_t *)list->hwLayers[i].handle;
+            if (isSkipLayer(&list->hwLayers[i])) {
+                break;
+            } else if(isYuvBuffer(hnd)) {
+                handleYUV(ctx,&list->hwLayers[i]);
+            } else {
+                list->hwLayers[i].compositionType = HWC_FRAMEBUFFER;
+            }
+        }
+    }
+    return 0;
+}
+
+static int hwc_set(hwc_composer_device_t *dev,
+                   hwc_display_t dpy,
+                   hwc_surface_t sur,
+                   hwc_layer_list_t* list)
+{
+    int ret = 0;
+    hwc_context_t* ctx = (hwc_context_t*)(dev);
+    if (LIKELY(list)) {
+        for (size_t i=0; i<list->numHwLayers; i++) {
+            if (list->hwLayers[i].flags & HWC_SKIP_LAYER) {
+                continue;
+            } else if (list->hwLayers[i].compositionType == HWC_USE_OVERLAY) {
+                drawLayerUsingOverlay(ctx, &(list->hwLayers[i]));
+            }
+        }
+        //XXX: Handle vsync with FBIO_WAITFORVSYNC ioctl
+        //All other operations (including pan display) should be NOWAIT
+        EGLBoolean sucess = eglSwapBuffers((EGLDisplay)dpy, (EGLSurface)sur);
+    } else {
+        //XXX: put in a wrapper for non overlay targets
+        setOverlayState(ctx, ovutils::OV_CLOSED);
+    }
+    ctx->qbuf->unlockAllPrevious();
+    return ret;
+}
+
+static int hwc_device_close(struct hw_device_t *dev)
+{
+    if(!dev) {
+        ALOGE("hwc_device_close null device pointer");
+        return -1;
+    }
+    closeContext((hwc_context_t*)dev);
+    free(dev);
+
+    return 0;
+}
+
+static int hwc_device_open(const struct hw_module_t* module, const char* name,
+                           struct hw_device_t** device)
+{
+    int status = -EINVAL;
+
+    if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
+        struct hwc_context_t *dev;
+        dev = (hwc_context_t*)malloc(sizeof(*dev));
+        memset(dev, 0, sizeof(*dev));
+        initContext(dev);
+        dev->device.common.tag     = HARDWARE_DEVICE_TAG;
+        dev->device.common.version = 0;
+        dev->device.common.module  = const_cast<hw_module_t*>(module);
+        dev->device.common.close   = hwc_device_close;
+        dev->device.prepare        = hwc_prepare;
+        dev->device.set            = hwc_set;
+        dev->device.registerProcs  = hwc_registerProcs;
+        *device                    = &dev->device.common;
+        status = 0;
+    }
+    return status;
+}
diff --git a/libhwcomposer/hwc_overlay.cpp b/libhwcomposer/hwc_overlay.cpp
new file mode 100644
index 0000000..00f53e9
--- /dev/null
+++ b/libhwcomposer/hwc_overlay.cpp
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "hwc_utils.h"
+
+namespace qhwc {
+// Determine overlay state based on decoded video info
+static ovutils::eOverlayState determineOverlayState(hwc_context_t* ctx,
+                                                    uint32_t bypassLayer,
+                                                    uint32_t format)
+{
+    ovutils::eOverlayState state = ovutils::OV_CLOSED;
+
+    // Sanity check
+    if (!ctx) {
+        ALOGE("%s: NULL ctx", __FUNCTION__);
+        return state;
+    }
+
+    overlay::Overlay& ov = *(ctx->mOverlay);
+    state = ov.getState();
+
+    // If there are any bypassLayers, state is based on number of layers
+    if ((bypassLayer > 0) && (ctx->hdmiEnabled == EXT_TYPE_NONE)) {
+        if (bypassLayer == 1) {
+            state = ovutils::OV_BYPASS_1_LAYER;
+        } else if (bypassLayer == 2) {
+            state = ovutils::OV_BYPASS_2_LAYER;
+        } else if (bypassLayer == 3) {
+            state = ovutils::OV_BYPASS_3_LAYER;
+        }
+        return state;
+    }
+
+    // RGB is ambiguous for determining overlay state
+    if (ovutils::isRgb(ovutils::getMdpFormat(format))) {
+        return state;
+    }
+
+    // Content type is either 2D or 3D
+    uint32_t fmt3D = 0;//XXX: 3D - ovutils::getS3DFormat(format);
+
+    // Determine state based on the external display, content type, and hw type
+    if (ctx->hdmiEnabled == EXT_TYPE_HDMI) {
+        // External display is HDMI
+        if (fmt3D) {
+            // Content type is 3D
+            if (ovutils::is3DTV()) {
+                // TV panel type is 3D
+                state = ovutils::OV_3D_VIDEO_ON_3D_TV;
+            } else {
+                // TV panel type is 2D
+                state = ovutils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV;
+            }
+        } else {
+            // Content type is 2D
+            if (ovutils::FrameBufferInfo::getInstance()->supportTrueMirroring()) {
+                // True UI mirroring is supported
+                state = ovutils::OV_2D_TRUE_UI_MIRROR;
+            } else {
+                // True UI mirroring is not supported
+                state = ovutils::OV_2D_VIDEO_ON_PANEL_TV;
+            }
+        }
+    } else if (ctx->hdmiEnabled == EXT_TYPE_WIFI) {
+        // External display is Wifi (currently unsupported)
+        ALOGE("%s: WIFI external display is unsupported", __FUNCTION__);
+        return state;
+    } else {
+        // No external display (primary panel only)
+        if (fmt3D) {
+            // Content type is 3D
+            if (ovutils::usePanel3D()) {
+                // Primary panel type is 3D
+                state = ovutils::OV_3D_VIDEO_ON_3D_PANEL;
+            } else {
+                // Primary panel type is 2D
+                state = ovutils::OV_3D_VIDEO_ON_2D_PANEL;
+            }
+        } else {
+            // Content type is 2D
+            state = ovutils::OV_2D_VIDEO_ON_PANEL;
+        }
+    }
+
+    return state;
+}
+
+void setOverlayState(hwc_context_t *ctx, ovutils::eOverlayState state)
+{
+    if (!ctx) {
+        ALOGE("%s: NULL ctx", __FUNCTION__);
+        return;
+    }
+
+    overlay::Overlay *ov = ctx->mOverlay;
+    if (!ov) {
+        ALOGE("%s: NULL OV object", __FUNCTION__);
+        return;
+    }
+    ov->setState(state);
+}
+
+bool prepareOverlay(hwc_context_t *ctx, hwc_layer_t *layer)
+{
+    bool ret = false;
+    if (LIKELY(ctx->mOverlay)) {
+        private_handle_t *hnd = (private_handle_t *)layer->handle;
+        overlay::Overlay& ov = *(ctx->mOverlay);
+        ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
+
+        // Set overlay state
+        ovutils::eOverlayState state = determineOverlayState(ctx, 0, info.format);
+        setOverlayState(ctx, state);
+
+        ovutils::eDest dest = ovutils::OV_PIPE_ALL;
+
+        // In the true UI mirroring case, video needs to go to OV_PIPE0 (for
+        // primary) and OV_PIPE1 (for external)
+        if (state == ovutils::OV_2D_TRUE_UI_MIRROR) {
+            dest = static_cast<ovutils::eDest>(
+                ovutils::OV_PIPE0 | ovutils::OV_PIPE1);
+        }
+
+        // Order order order
+        // setSource - just setting source
+        // setParameter - changes src w/h/f accordingly
+        // setCrop - ROI - that is src_rect
+        // setPosition - need to do scaling
+        // commit - commit changes to mdp driver
+        // queueBuffer - not here, happens when draw is called
+
+        ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
+        if (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
+            ovutils::setMdpFlags(mdpFlags,
+                                 ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
+        }
+
+        // FIXME: Use source orientation for TV when source is portrait
+        int transform = layer->transform & FINAL_TRANSFORM_MASK;
+        ovutils::eTransform orient =
+            static_cast<ovutils::eTransform>(transform);
+
+        ovutils::eWait waitFlag = ovutils::NO_WAIT;
+        if (ctx->skipComposition == true) {
+            waitFlag = ovutils::WAIT;
+        }
+
+        ovutils::eIsFg isFgFlag = ovutils::IS_FG_OFF;
+        if (ctx->numHwLayers == 1) {
+            isFgFlag = ovutils::IS_FG_SET;
+        }
+
+        ovutils::PipeArgs parg(mdpFlags,
+                               orient,
+                               info,
+                               waitFlag,
+                               ovutils::ZORDER_0,
+                               isFgFlag,
+                               ovutils::ROT_FLAG_DISABLED);
+        ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg };
+        ret = ov.setSource(pargs, dest);
+        if (!ret) {
+            ALOGE("%s: setSource failed", __FUNCTION__);
+            return ret;
+        }
+
+        const ovutils::Params prms (ovutils::OVERLAY_TRANSFORM, orient);
+        ret = ov.setParameter(prms, dest);
+        if (!ret) {
+            ALOGE("%s: setParameter failed transform %x", __FUNCTION__, orient);
+            return ret;
+        }
+
+        hwc_rect_t sourceCrop = layer->sourceCrop;
+        // x,y,w,h
+        ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top, // x, y
+                           sourceCrop.right - sourceCrop.left, // w
+                           sourceCrop.bottom - sourceCrop.top);// h
+        ret = ov.setCrop(dcrop, dest);
+        if (!ret) {
+            ALOGE("%s: setCrop failed", __FUNCTION__);
+            return ret;
+        }
+
+        int orientation = 0;
+        ovutils::Dim dim;
+        hwc_rect_t displayFrame = layer->displayFrame;
+        dim.x = displayFrame.left;
+        dim.y = displayFrame.top;
+        dim.w = (displayFrame.right - displayFrame.left);
+        dim.h = (displayFrame.bottom - displayFrame.top);
+        dim.o = orientation;
+
+        ret = ov.setPosition(dim, dest);
+        if (!ret) {
+            ALOGE("%s: setPosition failed", __FUNCTION__);
+            return ret;
+        }
+        if (!ov.commit(dest)) {
+            ALOGE("%s: commit fails", __FUNCTION__);
+            return false;
+        }
+    }
+    return true;
+}
+
+bool drawLayerUsingOverlay(hwc_context_t *ctx, hwc_layer_t *layer)
+{
+    private_handle_t *hnd = (private_handle_t *)layer->handle;
+
+    // Lock this buffer for read.
+    ctx->qbuf->lockAndAdd(hnd);
+    bool ret = true;
+    overlay::Overlay& ov = *(ctx->mOverlay);
+    ovutils::eOverlayState state = ov.getState();
+
+    // Differentiate between states that need to wait for vsync
+    switch (state) {
+        case ovutils::OV_2D_VIDEO_ON_PANEL_TV:
+        case ovutils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
+        case ovutils::OV_2D_TRUE_UI_MIRROR:
+            // If displaying on both primary and external, must play each
+            // pipe individually since wait for vsync needs to be done at
+            // the end. Do the following:
+            //     - Play external
+            //     - Play primary
+            //     - Wait for external vsync to be done
+            // NOTE: In these states
+            //           - primary VG = OV_PIPE0
+            //           - external VG = OV_PIPE1
+            //           - external RGB = OV_PIPE2
+            //             - Only in true UI mirroring case, played by fb
+
+            // Same FD for both primary and external VG pipes
+            ov.setMemoryId(hnd->fd, static_cast<ovutils::eDest>(
+                    ovutils::OV_PIPE0 | ovutils::OV_PIPE1));
+
+            // Play external
+            if (!ov.queueBuffer(hnd->offset, ovutils::OV_PIPE1)) {
+                ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
+                ret = false;
+            }
+
+            // Play primary
+            if (!ov.queueBuffer(hnd->offset, ovutils::OV_PIPE0)) {
+                ALOGE("%s: queueBuffer failed for primary", __FUNCTION__);
+                ret = false;
+            }
+
+            // Wait for external vsync to be done
+            if (!ov.waitForVsync(ovutils::OV_PIPE1)) {
+                ALOGE("%s: waitForVsync failed for external", __FUNCTION__);
+                ret = false;
+            }
+            break;
+        default:
+            // In most cases, displaying only to one (primary or external)
+            // so use OV_PIPE_ALL since overlay will ignore NullPipes
+            ov.setMemoryId(hnd->fd, ovutils::OV_PIPE_ALL);
+            if (!ov.queueBuffer(hnd->offset, ovutils::OV_PIPE_ALL)) {
+                ALOGE("%s: queueBuffer failed", __FUNCTION__);
+                ret = false;
+            }
+            break;
+    }
+
+    if (!ret) {
+        ALOGE("%s: failed", __FUNCTION__);
+    }
+    return ret;
+}
+
+void cleanOverlays(hwc_context_t *ctx )
+{
+    //XXX: handle for HDMI
+    if(0 == ctx->yuvBufferCount)
+        setOverlayState(ctx, ovutils::OV_CLOSED);
+}
+}; //namespace qhwc
diff --git a/libhwcomposer/hwc_qbuf.h b/libhwcomposer/hwc_qbuf.h
new file mode 100644
index 0000000..a0ade8c
--- /dev/null
+++ b/libhwcomposer/hwc_qbuf.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// -----------------------------------------------------------------------------
+// QueuedBufferStore
+//This class holds currently and previously queued buffers.
+//Provides utilities to store, lock, remove, unlock.
+
+namespace qhwc{
+static const int MAX_QUEUED_BUFS = 4;
+class QueuedBufferStore {
+    public:
+    QueuedBufferStore() {
+        clearCurrent();
+        clearPrevious();
+    }
+    ~QueuedBufferStore() {}
+    void lockAndAdd(private_handle_t*);
+    void unlockAllPrevious();
+
+    private:
+    QueuedBufferStore& operator=(const QueuedBufferStore&);
+    QueuedBufferStore(const QueuedBufferStore&);
+    bool lockBuffer(private_handle_t *hnd);
+    void unlockBuffer(private_handle_t *hnd);
+    void clearCurrent();
+    void clearPrevious();
+    void mvCurrToPrev();
+
+    //members
+    private_handle_t *current[MAX_QUEUED_BUFS]; //holds buf being queued
+    private_handle_t *previous[MAX_QUEUED_BUFS]; //holds bufs queued in prev round
+    int curCount;
+    int prevCount;
+};
+
+//Store and lock current drawing round buffers
+inline void QueuedBufferStore::lockAndAdd(private_handle_t *hnd) {
+    if(lockBuffer(hnd))
+        current[curCount++] = hnd;
+}
+
+//Unlock all previous drawing round buffers
+inline void QueuedBufferStore::unlockAllPrevious() {
+    //Unlock
+    for(int i = 0; i < prevCount; i++) {
+        unlockBuffer(previous[i]);
+        previous[i] = NULL;
+    }
+    //Move current hnd to previous
+    mvCurrToPrev();
+    //Clear current
+    clearCurrent();
+}
+
+//Clear currentbuf store
+inline void QueuedBufferStore::clearCurrent() {
+    for(int i = 0; i < MAX_QUEUED_BUFS; i++)
+        current[i] = NULL;
+    curCount = 0;
+}
+
+//Clear previousbuf store
+inline void QueuedBufferStore::clearPrevious() {
+    for(int i = 0; i < MAX_QUEUED_BUFS; i++)
+        previous[i] = NULL;
+    prevCount = 0;
+}
+
+//Copy from current to previous
+inline void QueuedBufferStore::mvCurrToPrev() {
+    for(int i = 0; i < curCount; i++)
+        previous[i] = current[i];
+    prevCount = curCount;
+}
+
+inline bool QueuedBufferStore::lockBuffer(private_handle_t *hnd) {
+    if (GENLOCK_FAILURE == genlock_lock_buffer(hnd, GENLOCK_READ_LOCK,
+                                               GENLOCK_MAX_TIMEOUT)) {
+        ALOGE("%s: genlock_lock_buffer(READ) failed", __func__);
+        return false;
+    }
+    return true;
+}
+
+inline void QueuedBufferStore::unlockBuffer(private_handle_t *hnd) {
+    //Check if buffer is still around
+    if(private_handle_t::validate(hnd) != 0) {
+        ALOGE("%s Invalid Handle", __func__);
+        return;
+    }
+    //Actually try to unlock
+    if (GENLOCK_FAILURE == genlock_unlock_buffer(hnd)) {
+        ALOGE("%s: genlock_unlock_buffer failed", __func__);
+        return;
+    }
+}
+// -----------------------------------------------------------------------------
+};//namespace
+
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
new file mode 100644
index 0000000..13873f8
--- /dev/null
+++ b/libhwcomposer/hwc_utils.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "hwc_utils.h"
+
+namespace qhwc {
+void initContext(hwc_context_t *ctx)
+{
+    //XXX: target specific initializations here
+    openFramebufferDevice(ctx);
+    ctx->mOverlay = overlay::Overlay::getInstance();
+    ctx->qbuf = new QueuedBufferStore();
+
+}
+
+void closeContext(hwc_context_t *ctx)
+{
+    if(ctx->mOverlay) {
+        delete ctx->mOverlay;
+        ctx->mOverlay = NULL;
+    }
+    if(ctx->fbDev) {
+        framebuffer_close(ctx->fbDev);
+        ctx->fbDev = NULL;
+    }
+
+    if(ctx->qbuf) {
+        delete ctx->qbuf;
+        ctx->qbuf = NULL;
+    }
+}
+
+// Opens Framebuffer device
+void openFramebufferDevice(hwc_context_t *ctx) {
+    hw_module_t const *module;
+    if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
+        framebuffer_open(module, &(ctx->fbDev));
+    }
+}
+
+void dumpLayer(hwc_layer_t const* l)
+{
+    ALOGD("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, {%d,%d,%d,%d}"
+          ", {%d,%d,%d,%d}",
+          l->compositionType, l->flags, l->handle, l->transform, l->blending,
+          l->sourceCrop.left,
+          l->sourceCrop.top,
+          l->sourceCrop.right,
+          l->sourceCrop.bottom,
+          l->displayFrame.left,
+          l->displayFrame.top,
+          l->displayFrame.right,
+          l->displayFrame.bottom);
+}
+
+void getLayerStats(hwc_context_t *ctx, const hwc_layer_list_t *list)
+{
+    int yuvBufCount = 0;
+    int layersNotUpdatingCount = 0;
+    for (size_t i=0 ; i<list->numHwLayers; i++) {
+        private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
+        if (isYuvBuffer(hnd)) {
+            yuvBufCount++;
+        }
+    }
+    // Number of video/camera layers drawable with overlay
+    ctx->yuvBufferCount = yuvBufCount;
+    ctx->numHwLayers = list->numHwLayers;
+    return;
+}
+
+void handleYUV(hwc_context_t *ctx, hwc_layer_t *layer)
+{
+    private_handle_t *hnd =
+                   (private_handle_t *)layer->handle;
+    //XXX: Handle targets not using overlay
+    if(prepareOverlay(ctx, layer)) {
+        layer->compositionType = HWC_USE_OVERLAY;
+        layer->hints |= HWC_HINT_CLEAR_FB;
+    }
+}
+};//namespace
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
new file mode 100644
index 0000000..b1c7871
--- /dev/null
+++ b/libhwcomposer/hwc_utils.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HWC_UTILS_H
+#define HWC_UTILS_H
+#include <cutils/log.h>
+#include <gralloc_priv.h>
+#include <hardware/hwcomposer.h>
+#include <hardware/hardware.h>
+#include <hardware/gralloc.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fb_priv.h>
+#include <overlay.h>
+#include <qcom_ui.h>
+#include <genlock.h>
+#include "hwc_qbuf.h"
+
+#define ALIGN(x, align)     (((x) + ((align)-1)) & ~((align)-1))
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+struct hwc_context_t;
+namespace qhwc {
+
+// -----------------------------------------------------------------------------
+// Utility functions - implemented in hwc_utils.cpp
+void dumpLayer(hwc_layer_t const* l);
+void getLayerStats(hwc_context_t *ctx, const hwc_layer_list_t *list);
+void handleYUV(hwc_context_t *ctx, hwc_layer_t *layer);
+void initContext(hwc_context_t *ctx);
+void closeContext(hwc_context_t *ctx);
+void openFramebufferDevice(hwc_context_t *ctx);
+
+// Inline utility functions
+static inline bool isSkipLayer(const hwc_layer_t* l) {
+    return (UNLIKELY(l && (l->flags & HWC_SKIP_LAYER)));
+}
+
+// Returns true if the buffer is yuv
+static inline bool isYuvBuffer(const private_handle_t* hnd) {
+    return (hnd && (hnd->bufferType == BUFFER_TYPE_VIDEO));
+}
+
+//Return true if buffer is marked locked
+static inline bool isBufferLocked(const private_handle_t* hnd) {
+    return (hnd && (private_handle_t::PRIV_FLAGS_HWC_LOCK & hnd->flags));
+}
+
+// -----------------------------------------------------------------------------
+// Overlay specific functions - inline or implemented in hwc_overlay.cpp
+bool prepareOverlay(hwc_context_t *ctx, hwc_layer_t *layer);
+//XXX: Refine draw functions
+bool drawLayerUsingOverlay(hwc_context_t *ctx, hwc_layer_t *layer);
+//XXX: Refine
+void cleanOverlays(hwc_context_t *ctx );
+void setOverlayState(hwc_context_t* ctx, ovutils::eOverlayState state);
+
+// -----------------------------------------------------------------------------
+// Copybit specific functions - inline or implemented in hwc_copybit.cpp
+
+
+
+// -----------------------------------------------------------------------------
+// HDMI specific functions - inline or implemented in hwc_hdmi.cpp
+
+
+
+} //qhwc namespace
+
+
+
+// -----------------------------------------------------------------------------
+// HWC context
+// This structure contains overall state
+struct hwc_context_t {
+    hwc_composer_device_t device;
+    // Layer variables
+    int yuvBufferCount;
+    int hdmiEnabled;
+    int numHwLayers;
+    bool skipComposition;
+
+    //Framebuffer device
+    framebuffer_device_t *fbDev;
+
+    //Overlay object - NULL for non overlay devices
+    overlay::Overlay *mOverlay;
+
+    //QueuedBufferStore to hold buffers for overlay
+    qhwc::QueuedBufferStore *qbuf;
+};
+
+
+
+
+#endif //HWC_UTILS_H
diff --git a/libhwcomposer/hwcomposer.cpp b/libhwcomposer/hwcomposer.cpp
deleted file mode 100755
index c43fa04..0000000
--- a/libhwcomposer/hwcomposer.cpp
+++ /dev/null
@@ -1,1734 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <hardware/hardware.h>
-
-#include <fcntl.h>
-#include <errno.h>
-
-#include <cutils/log.h>
-#include <cutils/atomic.h>
-#include <cutils/properties.h>
-
-#include <hardware/hwcomposer.h>
-#include <overlayLib.h>
-#include <overlayLibUI.h>
-#include <copybit.h>
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <ui/android_native_buffer.h>
-#include <gralloc_priv.h>
-#include <genlock.h>
-#include <qcom_ui.h>
-#include <gr.h>
-
-/*****************************************************************************/
-#define ALIGN(x, align) (((x) + ((align)-1)) & ~((align)-1))
-#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
-#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
-
-#ifdef COMPOSITION_BYPASS
-#define MAX_BYPASS_LAYERS 3
-#define BYPASS_DEBUG 0
-#define BYPASS_INDEX_OFFSET 4
-
-enum BypassState {
-    BYPASS_ON,
-    BYPASS_OFF,
-    BYPASS_OFF_PENDING,
-};
-
-enum BypassBufferLockState {
-    BYPASS_BUFFER_UNLOCKED,
-    BYPASS_BUFFER_LOCKED,
-};
-#endif
-
-enum HWCLayerType{
-    HWC_SINGLE_VIDEO           = 0x1,
-    HWC_ORIG_RESOLUTION        = 0x2,
-    HWC_S3D_LAYER              = 0x4,
-    HWC_STOP_UI_MIRRORING_MASK = 0xF
-};
-
-enum eHWCOverlayStatus {
-    HWC_OVERLAY_OPEN,
-    HWC_OVERLAY_PREPARE_TO_CLOSE,
-    HWC_OVERLAY_CLOSED
-};
-
-struct hwc_context_t {
-    hwc_composer_device_t device;
-    /* our private state goes below here */
-    overlay::Overlay* mOverlayLibObject;
-    native_handle_t *previousOverlayHandle;
-#ifdef COMPOSITION_BYPASS
-    overlay::OverlayUI* mOvUI[MAX_BYPASS_LAYERS];
-    native_handle_t* previousBypassHandle[MAX_BYPASS_LAYERS];
-    BypassBufferLockState bypassBufferLockState[MAX_BYPASS_LAYERS];
-    int layerindex[MAX_BYPASS_LAYERS];
-    int nPipesUsed;
-    BypassState bypassState;
-#endif
-#if defined HDMI_DUAL_DISPLAY
-    external_display mHDMIEnabled; // Type of external display
-    bool pendingHDMI;
-#endif
-    int previousLayerCount;
-    eHWCOverlayStatus hwcOverlayStatus;
-};
-
-static int hwc_device_open(const struct hw_module_t* module, const char* name,
-        struct hw_device_t** device);
-
-static struct hw_module_methods_t hwc_module_methods = {
-    open: hwc_device_open
-};
-
-
-struct private_hwc_module_t {
-    hwc_module_t base;
-    copybit_device_t *copybitEngine;
-    framebuffer_device_t *fbDevice;
-    int compositionType;
-    bool isBypassEnabled; //from build.prop ro.sf.compbypass.enable
-};
-
-struct private_hwc_module_t HAL_MODULE_INFO_SYM = {
-    base: {
-        common: {
-            tag: HARDWARE_MODULE_TAG,
-            version_major: 1,
-            version_minor: 0,
-            id: HWC_HARDWARE_MODULE_ID,
-            name: "Hardware Composer Module",
-            author: "The Android Open Source Project",
-            methods: &hwc_module_methods,
-        }
-   },
-   copybitEngine: NULL,
-   fbDevice: NULL,
-   compositionType: 0,
-   isBypassEnabled: false,
-};
-
-//Only at this point would the compiler know all storage class sizes.
-//The header has hooks which need to know those beforehand.
-#include "external_display_only.h"
-
-/*****************************************************************************/
-
-static void dump_layer(hwc_layer_t const* l) {
-    LOGD("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, {%d,%d,%d,%d}, {%d,%d,%d,%d}",
-            l->compositionType, l->flags, l->handle, l->transform, l->blending,
-            l->sourceCrop.left,
-            l->sourceCrop.top,
-            l->sourceCrop.right,
-            l->sourceCrop.bottom,
-            l->displayFrame.left,
-            l->displayFrame.top,
-            l->displayFrame.right,
-            l->displayFrame.bottom);
-}
-
-static inline int min(const int& a, const int& b) {
-    return (a < b) ? a : b;
-}
-
-static inline int max(const int& a, const int& b) {
-    return (a > b) ? a : b;
-}
-#ifdef COMPOSITION_BYPASS
-void setLayerbypassIndex(hwc_layer_t* layer, const int bypass_index)
-{
-    layer->flags &= ~HWC_BYPASS_INDEX_MASK;
-    layer->flags |= bypass_index << BYPASS_INDEX_OFFSET;
-}
-
-int  getLayerbypassIndex(hwc_layer_t* layer)
-{
-    int byp_index = -1;
-
-    if(layer->flags & HWC_COMP_BYPASS) {
-        byp_index = ((layer->flags & HWC_BYPASS_INDEX_MASK) >> BYPASS_INDEX_OFFSET);
-        byp_index = (byp_index < MAX_BYPASS_LAYERS ? byp_index : -1 );
-    }
-    return byp_index;
-}
-
-void unlockPreviousBypassBuffers(hwc_context_t* ctx) {
-    // Unlock the previous bypass buffers. We can blindly unlock the buffers here,
-    // because buffers will be in this list only if the lock was successfully acquired.
-    for(int i = 0; i < MAX_BYPASS_LAYERS && ctx->previousBypassHandle[i]; i++) {
-       private_handle_t *hnd = (private_handle_t*) ctx->previousBypassHandle[i];
-
-       // Validate the handle to make sure it hasn't been deallocated.
-       if (private_handle_t::validate(ctx->previousBypassHandle[i])) {
-            continue;
-       }
-       // Check if the handle was locked previously
-       if (private_handle_t::PRIV_FLAGS_HWC_LOCK & hnd->flags) {
-          if (GENLOCK_FAILURE == genlock_unlock_buffer(ctx->previousBypassHandle[i])) {
-              LOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
-          } else {
-              ctx->previousBypassHandle[i] = NULL;
-              // Reset the lock flag
-              hnd->flags &= ~private_handle_t::PRIV_FLAGS_HWC_LOCK;
-          }
-       }
-    }
-}
-
-void print_info(hwc_layer_t* layer)
-{
-     hwc_rect_t sourceCrop = layer->sourceCrop;
-     hwc_rect_t displayFrame = layer->displayFrame;
-
-     int s_l = sourceCrop.left;
-     int s_t = sourceCrop.top;
-     int s_r = sourceCrop.right;
-     int s_b = sourceCrop.bottom;
-
-     int d_l = displayFrame.left;
-     int d_t = displayFrame.top;
-     int d_r = displayFrame.right;
-     int d_b = displayFrame.bottom;
-
-     LOGE_IF(BYPASS_DEBUG, "src:[%d,%d,%d,%d] (%d x %d) dst:[%d,%d,%d,%d] (%d x %d)",
-                             s_l, s_t, s_r, s_b, (s_r - s_l), (s_b - s_t),
-                             d_l, d_t, d_r, d_b, (d_r - d_l), (d_b - d_t));
-}
-
-//Crops source buffer against destination and FB boundaries
-void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst, int hw_w, int hw_h) {
-
-    int& crop_x = crop.left;
-    int& crop_y = crop.top;
-    int& crop_r = crop.right;
-    int& crop_b = crop.bottom;
-    int crop_w = crop.right - crop.left;
-    int crop_h = crop.bottom - crop.top;
-
-    int& dst_x = dst.left;
-    int& dst_y = dst.top;
-    int& dst_r = dst.right;
-    int& dst_b = dst.bottom;
-    int dst_w = dst.right - dst.left;
-    int dst_h = dst.bottom - dst.top;
-
-    if(dst_x < 0) {
-        float scale_x =  crop_w * 1.0f / dst_w;
-        float diff_factor = (scale_x * abs(dst_x));
-        crop_x = crop_x + (int)diff_factor;
-        crop_w = crop_r - crop_x;
-
-        dst_x = 0;
-        dst_w = dst_r - dst_x;;
-    }
-    if(dst_r > hw_w) {
-        float scale_x = crop_w * 1.0f / dst_w;
-        float diff_factor = scale_x * (dst_r - hw_w);
-        crop_r = crop_r - diff_factor;
-        crop_w = crop_r - crop_x;
-
-        dst_r = hw_w;
-        dst_w = dst_r - dst_x;
-    }
-    if(dst_y < 0) {
-        float scale_y = crop_h * 1.0f / dst_h;
-        float diff_factor = scale_y * abs(dst_y);
-        crop_y = crop_y + diff_factor;
-        crop_h = crop_b - crop_y;
-
-        dst_y = 0;
-        dst_h = dst_b - dst_y;
-    }
-    if(dst_b > hw_h) {
-        float scale_y = crop_h * 1.0f / dst_h;
-        float diff_factor = scale_y * (dst_b - hw_h);
-        crop_b = crop_b - diff_factor;
-        crop_h = crop_b - crop_y;
-
-        dst_b = hw_h;
-        dst_h = dst_b - dst_y;
-    }
-
-    LOGE_IF(BYPASS_DEBUG,"crop: [%d,%d,%d,%d] dst:[%d,%d,%d,%d]",
-                     crop_x, crop_y, crop_w, crop_h,dst_x, dst_y, dst_w, dst_h);
-}
-
-/*
- * Configures pipe(s) for composition bypass
- */
-static int prepareBypass(hwc_context_t *ctx, hwc_layer_t *layer,
-                        int nPipeIndex, int vsync_wait, int isFG) {
-
-    if (ctx && ctx->mOvUI[nPipeIndex]) {
-        overlay::OverlayUI *ovUI = ctx->mOvUI[nPipeIndex];
-
-        private_hwc_module_t* hwcModule = reinterpret_cast<
-                private_hwc_module_t*>(ctx->device.common.module);
-        if (!hwcModule) {
-            LOGE("%s: NULL Module", __FUNCTION__);
-            return -1;
-        }
-
-        private_handle_t *hnd = (private_handle_t *)layer->handle;
-        if(!hnd) {
-            LOGE("%s: layer handle is NULL", __FUNCTION__);
-            return -1;
-        }
-
-        int hw_w = hwcModule->fbDevice->width;
-        int hw_h = hwcModule->fbDevice->height;
-
-        hwc_rect_t sourceCrop = layer->sourceCrop;
-        hwc_rect_t displayFrame = layer->displayFrame;
-
-        const int src_w = sourceCrop.right - sourceCrop.left;
-        const int src_h = sourceCrop.bottom - sourceCrop.top;
-
-        hwc_rect_t crop = sourceCrop;
-        int crop_w = crop.right - crop.left;
-        int crop_h = crop.bottom - crop.top;
-
-        hwc_rect_t dst = displayFrame;
-        int dst_w = dst.right - dst.left;
-        int dst_h = dst.bottom - dst.top;
-
-        if(hnd != NULL && (hnd->flags & private_handle_t::PRIV_FLAGS_NONCONTIGUOUS_MEM )) {
-            LOGE("%s: Unable to setup bypass due to non-pmem memory",__FUNCTION__);
-            return -1;
-        }
-
-        if(dst.left < 0 || dst.top < 0 || dst.right > hw_w || dst.bottom > hw_h) {
-            LOGE_IF(BYPASS_DEBUG,"%s: Destination has negative coordinates", __FUNCTION__);
-
-            calculate_crop_rects(crop, dst, hw_w, hw_h);
-
-            //Update calulated width and height
-            crop_w = crop.right - crop.left;
-            crop_h = crop.bottom - crop.top;
-
-            dst_w = dst.right - dst.left;
-            dst_h = dst.bottom - dst.top;
-        }
-
-        if( (dst_w > hw_w)|| (dst_h > hw_h)) {
-            LOGE_IF(BYPASS_DEBUG,"%s: Destination rectangle exceeds FB resolution", __FUNCTION__);
-            print_info(layer);
-            dst_w = hw_w;
-            dst_h = hw_h;
-        }
-
-        overlay_buffer_info info;
-        info.width = src_w;
-        info.height = src_h;
-        info.format = hnd->format;
-        info.size = hnd->size;
-
-        int fbnum = 0;
-        int orientation = layer->transform;
-        const bool useVGPipe =  (nPipeIndex != (MAX_BYPASS_LAYERS-1));
-        //only last layer should wait for vsync
-        const bool waitForVsync = vsync_wait;
-        const bool isFg = isFG;
-        //Just to differentiate zorders for different layers
-        const int zorder = nPipeIndex;
-
-        ovUI->setSource(info, orientation);
-        ovUI->setCrop(crop.left, crop.top, crop_w, crop_h);
-        ovUI->setDisplayParams(fbnum, waitForVsync, isFg, zorder, useVGPipe);
-        ovUI->setPosition(dst.left, dst.top, dst_w, dst_h);
-
-        LOGE_IF(BYPASS_DEBUG,"%s: Bypass set: crop[%d,%d,%d,%d] dst[%d,%d,%d,%d] waitforVsync: %d \
-                                isFg: %d zorder: %d VG = %d nPipe: %d",__FUNCTION__,
-                                crop.left, crop.top, crop_w, crop_h,
-                                dst.left, dst.top, dst_w, dst_h,
-                                waitForVsync, isFg, zorder, useVGPipe, nPipeIndex );
-
-        if(ovUI->commit() != overlay::NO_ERROR) {
-            LOGE("%s: Overlay Commit failed", __FUNCTION__);
-            return -1;
-        }
-    }
-    return 0;
-}
-
-/*
- * Checks if doing comp. bypass is possible.
- * It is possible if
- * 1. No MDP pipe is used
- * 2. Rotation is not needed
- * 3. We have atmost MAX_BYPASS_LAYERS
- */
-inline static bool isBypassDoable(hwc_composer_device_t *dev, const int yuvCount,
-        const hwc_layer_list_t* list) {
-    hwc_context_t* ctx = (hwc_context_t*)(dev);
-    private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(
-                                                           dev->common.module);
-    //Check if enabled in build.prop
-    if(hwcModule->isBypassEnabled == false) {
-        return false;
-    }
-
-    if(list->numHwLayers < 1) {
-        return false;
-    }
-
-#if defined HDMI_DUAL_DISPLAY
-    //Disable bypass when HDMI is enabled
-    if(ctx->mHDMIEnabled || ctx->pendingHDMI) {
-        return false;
-    }
-#endif
-
-    if(ExtDispOnly::isModeOn()) {
-        return false;
-    }
-
-    //Bypass is not efficient if rotation or asynchronous mode is needed.
-    for(int i = 0; i < list->numHwLayers; ++i) {
-        if(list->hwLayers[i].transform) {
-            return false;
-        }
-        if(list->hwLayers[i].flags & HWC_LAYER_ASYNCHRONOUS) {
-            return false;
-        }
-    }
-
-    return (yuvCount == 0) && (ctx->hwcOverlayStatus == HWC_OVERLAY_CLOSED)
-                                   && (list->numHwLayers <= MAX_BYPASS_LAYERS);
-}
-
-void setBypassLayerFlags(hwc_context_t* ctx, hwc_layer_list_t* list)
-{
-    for(int index = 0 ; index < MAX_BYPASS_LAYERS; index++ )
-    {
-        int layer_index = ctx->layerindex[index];
-        if(layer_index >= 0) {
-            hwc_layer_t* layer = &(list->hwLayers[layer_index]);
-
-            layer->flags |= HWC_COMP_BYPASS;
-            layer->compositionType = HWC_USE_OVERLAY;
-            layer->hints |= HWC_HINT_CLEAR_FB;
-        }
-    }
-
-    if( list->numHwLayers > ctx->nPipesUsed ) {
-         list->flags &= ~HWC_SKIP_COMPOSITION; //Compose to FB
-    } else {
-         list->flags |= HWC_SKIP_COMPOSITION; // Dont
-    }
-}
-
-bool setupBypass(hwc_context_t* ctx, hwc_layer_list_t* list) {
-    int nPipeIndex, vsync_wait, isFG;
-    int numHwLayers = list->numHwLayers;
-    int nPipeAvailable = MAX_BYPASS_LAYERS;
-
-    for (int index = 0 ; (index < numHwLayers) && nPipeAvailable; index++) {
-
-        hwc_layer_t* layer = &(list->hwLayers[index]);
-
-        nPipeIndex =  MAX_BYPASS_LAYERS - nPipeAvailable;
-        //Set VSYNC wait is needed only for the last pipe queued
-        vsync_wait = (nPipeIndex == (numHwLayers-1));
-        //Set isFG to true for layer with z-order zero
-        isFG = !index;
-
-        //Clear Bypass flags for the layer
-        layer->flags &= ~HWC_COMP_BYPASS;
-        layer->flags |= HWC_BYPASS_INDEX_MASK;
-
-        if( prepareBypass(ctx, &(list->hwLayers[index]), nPipeIndex, vsync_wait, isFG) != 0 ) {
-           LOGE_IF(BYPASS_DEBUG, "%s: layer %d failed to configure bypass for pipe index: %d",
-                                                               __FUNCTION__, index, nPipeIndex);
-           return false;
-         } else {
-           ctx->layerindex[nPipeIndex] = index;
-           setLayerbypassIndex(layer, nPipeIndex);
-           nPipeAvailable--;
-         }
-    }
-    ctx->nPipesUsed =  MAX_BYPASS_LAYERS - nPipeAvailable;
-    return true;
-}
-
-void unsetBypassLayerFlags(hwc_layer_list_t* list) {
-    if (!list)
-        return;
-
-    for (int index = 0 ; index < list->numHwLayers; index++) {
-        if(list->hwLayers[index].flags & HWC_COMP_BYPASS) {
-            list->hwLayers[index].flags &= ~HWC_COMP_BYPASS;
-        }
-    }
-}
-
-void unsetBypassBufferLockState(hwc_context_t* ctx) {
-    for (int i= 0; i< MAX_BYPASS_LAYERS; i++) {
-        ctx->bypassBufferLockState[i] = BYPASS_BUFFER_UNLOCKED;
-    }
-}
-
-void storeLockedBypassHandle(hwc_layer_list_t* list, hwc_context_t* ctx) {
-   if (!list)
-        return;
-
-   for(int index = 0; index < MAX_BYPASS_LAYERS; index++ ) {
-       hwc_layer_t layer = list->hwLayers[ctx->layerindex[index]];
-
-       if (layer.flags & HWC_COMP_BYPASS) {
-            private_handle_t *hnd = (private_handle_t*)layer.handle;
-
-            if (ctx->bypassBufferLockState[index] == BYPASS_BUFFER_LOCKED) {
-               ctx->previousBypassHandle[index] = (native_handle_t*)layer.handle;
-               hnd->flags |= private_handle_t::PRIV_FLAGS_HWC_LOCK;
-           } else {
-              ctx->previousBypassHandle[index] = NULL;
-           }
-       }
-   }
-}
-
-void closeExtraPipes(hwc_context_t* ctx) {
-
-    int pipes_used = ctx->nPipesUsed;
-
-    //Unused pipes must be of higher z-order
-    for (int i =  pipes_used ; i < MAX_BYPASS_LAYERS; i++) {
-        if (ctx->previousBypassHandle[i]) {
-            private_handle_t *hnd = (private_handle_t*) ctx->previousBypassHandle[i];
-
-            if (!private_handle_t::validate(ctx->previousBypassHandle[i])) {
-                if (GENLOCK_FAILURE == genlock_unlock_buffer(ctx->previousBypassHandle[i])) {
-                    LOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
-                } else {
-                    ctx->previousBypassHandle[i] = NULL;
-                    ctx->bypassBufferLockState[i] = BYPASS_BUFFER_UNLOCKED;
-                    hnd->flags &= ~private_handle_t::PRIV_FLAGS_HWC_LOCK;
-                }
-            }
-        }
-        ctx->mOvUI[i]->closeChannel();
-        ctx->layerindex[i] = -1;
-    }
-}
-#endif  //COMPOSITION_BYPASS
-
-static int setVideoOverlayStatusInGralloc(hwc_context_t* ctx, const bool enable) {
-#if defined HDMI_DUAL_DISPLAY
-    private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(
-                                                           ctx->device.common.module);
-    if(!hwcModule) {
-        LOGE("%s: invalid params", __FUNCTION__);
-        return -1;
-    }
-
-    framebuffer_device_t *fbDev = hwcModule->fbDevice;
-    if (!fbDev) {
-        LOGE("%s: fbDev is NULL", __FUNCTION__);
-        return -1;
-    }
-
-    // Inform the gralloc to stop or start UI mirroring
-    fbDev->videoOverlayStarted(fbDev, enable);
-#endif
-    return 0;
-}
-
-static void setHWCOverlayStatus(hwc_context_t *ctx, bool isVideoPresent) {
-
-    switch (ctx->hwcOverlayStatus) {
-        case HWC_OVERLAY_OPEN:
-            ctx->hwcOverlayStatus =
-                isVideoPresent ? HWC_OVERLAY_OPEN : HWC_OVERLAY_PREPARE_TO_CLOSE;
-        break;
-        case HWC_OVERLAY_PREPARE_TO_CLOSE:
-            ctx->hwcOverlayStatus =
-                isVideoPresent ? HWC_OVERLAY_OPEN : HWC_OVERLAY_CLOSED;
-        break;
-        case HWC_OVERLAY_CLOSED:
-            ctx->hwcOverlayStatus =
-                isVideoPresent ? HWC_OVERLAY_OPEN : HWC_OVERLAY_CLOSED;
-        break;
-        default:
-          LOGE("%s: Invalid hwcOverlayStatus (status =%d)", __FUNCTION__,
-                ctx->hwcOverlayStatus);
-        break;
-    }
-}
-
-static int hwc_closeOverlayChannels(hwc_context_t* ctx) {
-#ifdef USE_OVERLAY
-    overlay::Overlay *ovLibObject = ctx->mOverlayLibObject;
-    if(!ovLibObject) {
-        LOGE("%s: invalid params", __FUNCTION__);
-        return -1;
-    }
-
-    if (HWC_OVERLAY_PREPARE_TO_CLOSE == ctx->hwcOverlayStatus) {
-        // Video mirroring is going on, and we do not have any layers to
-        // mirror directly. Close the current video channel and inform the
-        // gralloc to start UI mirroring
-        ovLibObject->closeChannel();
-        // Inform the gralloc that video overlay has stopped.
-        setVideoOverlayStatusInGralloc(ctx, false);
-    }
-#endif
-    return 0;
-}
-
-/*
- * Configures mdp pipes
- */
-static int prepareOverlay(hwc_context_t *ctx, hwc_layer_t *layer, const int flags) {
-     int ret = 0;
-
-#ifdef COMPOSITION_BYPASS
-     if(ctx && (ctx->bypassState != BYPASS_OFF)) {
-        ctx->nPipesUsed = 0;
-        closeExtraPipes(ctx);
-        ctx->bypassState = BYPASS_OFF;
-     }
-#endif
-
-     if (LIKELY(ctx && ctx->mOverlayLibObject)) {
-        private_hwc_module_t* hwcModule =
-            reinterpret_cast<private_hwc_module_t*>(ctx->device.common.module);
-        if (UNLIKELY(!hwcModule)) {
-            LOGE("prepareOverlay null module ");
-            return -1;
-        }
-
-        private_handle_t *hnd = (private_handle_t *)layer->handle;
-        overlay::Overlay *ovLibObject = ctx->mOverlayLibObject;
-        overlay_buffer_info info;
-        info.width = hnd->width;
-        info.height = hnd->height;
-        info.format = hnd->format;
-        info.size = hnd->size;
-
-        int hdmiConnected = 0;
-
-#if defined HDMI_DUAL_DISPLAY
-        if(!ctx->pendingHDMI) //makes sure the UI channel is opened first
-            hdmiConnected = (int)ctx->mHDMIEnabled;
-#endif
-        ret = ovLibObject->setSource(info, layer->transform,
-                            hdmiConnected, flags);
-        if (!ret) {
-            LOGE("prepareOverlay setSource failed");
-            return -1;
-        }
-
-        ret = ovLibObject->setTransform(layer->transform);
-        if (!ret) {
-            LOGE("prepareOverlay setTransform failed transform %x",
-                    layer->transform);
-            return -1;
-        }
-
-        hwc_rect_t sourceCrop = layer->sourceCrop;
-        ret = ovLibObject->setCrop(sourceCrop.left, sourceCrop.top,
-                                  (sourceCrop.right - sourceCrop.left),
-                                  (sourceCrop.bottom - sourceCrop.top));
-        if (!ret) {
-            LOGE("prepareOverlay setCrop failed");
-            return -1;
-        }
-#if defined HDMI_DUAL_DISPLAY
-        // Send the device orientation to  overlayLib
-        if(hwcModule) {
-            framebuffer_device_t *fbDev = reinterpret_cast<framebuffer_device_t*>
-                                                            (hwcModule->fbDevice);
-            if(fbDev) {
-                private_module_t* m = reinterpret_cast<private_module_t*>(
-                                                         fbDev->common.module);
-                if(m)
-                    ovLibObject->setDeviceOrientation(m->orientation);
-            }
-        }
-#endif
-        if (layer->flags & HWC_USE_ORIGINAL_RESOLUTION) {
-            framebuffer_device_t* fbDev = hwcModule->fbDevice;
-            ret = ovLibObject->setPosition(0, 0,
-                                           fbDev->width, fbDev->height);
-        } else {
-            hwc_rect_t displayFrame = layer->displayFrame;
-            ret = ovLibObject->setPosition(displayFrame.left, displayFrame.top,
-                                    (displayFrame.right - displayFrame.left),
-                                    (displayFrame.bottom - displayFrame.top));
-        }
-        if (!ret) {
-            LOGE("prepareOverlay setPosition failed");
-            return -1;
-        }
-     }
-     return 0;
-}
-
-void unlockPreviousOverlayBuffer(hwc_context_t* ctx)
-{
-    if (ctx->previousOverlayHandle) {
-        // Validate the handle before attempting to use it.
-        if (!private_handle_t::validate(ctx->previousOverlayHandle)) {
-            private_handle_t *hnd = (private_handle_t*)ctx->previousOverlayHandle;
-            // Unlock any previously locked buffers
-            if (private_handle_t::PRIV_FLAGS_HWC_LOCK & hnd->flags) {
-                if (GENLOCK_NO_ERROR == genlock_unlock_buffer(ctx->previousOverlayHandle)) {
-                    ctx->previousOverlayHandle = NULL;
-                    hnd->flags &= ~private_handle_t::PRIV_FLAGS_HWC_LOCK;
-                } else {
-                    LOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
-                }
-            }
-        }
-    }
-}
-
-bool canSkipComposition(hwc_context_t* ctx, int yuvBufferCount, int currentLayerCount,
-                        int numLayersNotUpdating)
-{
-    if (!ctx) {
-        LOGE("%s: invalid context",__FUNCTION__);
-        return false;
-    }
-
-    hwc_composer_device_t* dev = (hwc_composer_device_t *)(ctx);
-    private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(
-                                                           dev->common.module);
-    if (hwcModule->compositionType == COMPOSITION_TYPE_CPU)
-        return false;
-
-    //Video / Camera case
-    if (yuvBufferCount == 1) {
-        //If the previousLayerCount is anything other than the current count, it
-        //means something changed and we need to compose atleast once to FB.
-        if (currentLayerCount != ctx->previousLayerCount) {
-            ctx->previousLayerCount = currentLayerCount;
-            return false;
-        }
-        // We either have only one overlay layer or we have
-        // all non-updating UI layers.
-        // We can skip the composition of the UI layers.
-        if ((currentLayerCount == 1) ||
-            ((currentLayerCount - 1) == numLayersNotUpdating)) {
-            return true;
-        }
-    } else {
-        ctx->previousLayerCount = -1;
-    }
-    return false;
-}
-
-inline void getLayerResolution(const hwc_layer_t* layer, int& width, int& height)
-{
-   hwc_rect_t displayFrame  = layer->displayFrame;
-
-   width = displayFrame.right - displayFrame.left;
-   height = displayFrame.bottom - displayFrame.top;
-}
-
-static bool canUseCopybit(const framebuffer_device_t* fbDev, const hwc_layer_list_t* list) {
-
-    if(!fbDev) {
-       LOGE("ERROR: %s : fb device is invalid",__func__);
-       return false;
-    }
-
-    if (!list)
-        return false;
-
-    int fb_w = fbDev->width;
-    int fb_h = fbDev->height;
-
-    /*
-     * Use copybit only when we need to blit
-     * max 2 full screen sized regions
-     */
-
-    unsigned int renderArea = 0;
-
-    for(int i = 0; i < list->numHwLayers; i++ ) {
-        int w, h;
-        getLayerResolution(&list->hwLayers[i], w, h);
-        renderArea += w*h;
-    }
-
-    return (renderArea <= (2 * fb_w * fb_h));
-}
-
-static void handleHDMIStateChange(hwc_composer_device_t *dev, int externaltype) {
-#if defined HDMI_DUAL_DISPLAY
-    hwc_context_t* ctx = (hwc_context_t*)(dev);
-    private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(
-                                                           dev->common.module);
-    //Route the event to fbdev only if we are in default mirror mode
-    if(ExtDispOnly::isModeOn() == false) {
-        framebuffer_device_t *fbDev = hwcModule->fbDevice;
-        if (fbDev) {
-            fbDev->enableHDMIOutput(fbDev, externaltype);
-        }
-
-        if(ctx && ctx->mOverlayLibObject) {
-            overlay::Overlay *ovLibObject = ctx->mOverlayLibObject;
-            if (!externaltype) {
-                // Close the external overlay channels if HDMI is disconnected
-                ovLibObject->closeExternalChannel();
-            }
-        }
-    }
-#endif
-}
-
-/*
- * function to set the status of external display in hwc
- * Just mark flags and do stuff after eglSwapBuffers
- * externaltype - can be HDMI, WIFI or OFF
- */
-static void hwc_enableHDMIOutput(hwc_composer_device_t *dev, int externaltype) {
-#if defined HDMI_DUAL_DISPLAY
-    hwc_context_t* ctx = (hwc_context_t*)(dev);
-    private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(
-                                                           dev->common.module);
-    framebuffer_device_t *fbDev = hwcModule->fbDevice;
-    overlay::Overlay *ovLibObject = ctx->mOverlayLibObject;
-    if(externaltype && ctx->mHDMIEnabled &&
-            (externaltype != ctx->mHDMIEnabled)) {
-        // Close the current external display - as the SF will
-        // prioritize and send the correct external display HDMI/WFD
-        handleHDMIStateChange(dev, 0);
-    }
-    // Store the external display
-    ctx->mHDMIEnabled = (external_display)externaltype;
-    if(ctx->mHDMIEnabled) { //On connect, allow bypass to draw once to FB
-        ctx->pendingHDMI = true;
-    } else { //On disconnect, close immediately (there will be no bypass)
-        handleHDMIStateChange(dev, ctx->mHDMIEnabled);
-    }
-#endif
-}
-
-static bool isValidDestination(const framebuffer_device_t* fbDev, const hwc_rect_t& rect)
-{
-    if (!fbDev) {
-        LOGE("%s: fbDev is null", __FUNCTION__);
-        return false;
-    }
-
-    int dest_width = (rect.right - rect.left);
-    int dest_height = (rect.bottom - rect.top);
-
-    if (rect.left < 0 || rect.right < 0 || rect.top < 0 || rect.bottom < 0
-        || dest_width <= 0 || dest_height <= 0) {
-        LOGE("%s: destination: left=%d right=%d top=%d bottom=%d width=%d"
-             "height=%d", __FUNCTION__, rect.left, rect.right, rect.top,
-             rect.bottom, dest_width, dest_height);
-        return false;
-    }
-
-    if ((rect.left+dest_width) > fbDev->width || (rect.top+dest_height) > fbDev->height) {
-        LOGE("%s: destination out of bound params", __FUNCTION__);
-        return false;
-    }
-
-    return true;
-}
-
-static int getYUVBufferCount (const hwc_layer_list_t* list) {
-    int yuvBufferCount = 0;
-    if (list) {
-        for (size_t i=0 ; i<list->numHwLayers; i++) {
-            private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
-            if (hnd && (hnd->bufferType == BUFFER_TYPE_VIDEO) &&
-               !(list->hwLayers[i].flags & HWC_DO_NOT_USE_OVERLAY)) {
-                yuvBufferCount++;
-                if (yuvBufferCount > 1) {
-                    break;
-                }
-            }
-        }
-    }
-    return yuvBufferCount;
-}
-
-static int getS3DVideoFormat (const hwc_layer_list_t* list) {
-    int s3dFormat = 0;
-    if (list) {
-        for (size_t i=0; i<list->numHwLayers; i++) {
-            private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
-            if (hnd && (hnd->bufferType == BUFFER_TYPE_VIDEO))
-                s3dFormat = FORMAT_3D_INPUT(hnd->format);
-            if (s3dFormat)
-                break;
-        }
-    }
-    return s3dFormat;
-}
-
-static int getS3DFormat (const hwc_layer_list_t* list) {
-    int s3dFormat = 0;
-    if (list) {
-        for (size_t i=0; i<list->numHwLayers; i++) {
-            private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
-            if (hnd)
-                s3dFormat = FORMAT_3D_INPUT(hnd->format);
-            if (s3dFormat)
-                break;
-        }
-    }
-    return s3dFormat;
-}
-
-
-static int getLayerS3DFormat (hwc_layer_t &layer) {
-    int s3dFormat = 0;
-    private_handle_t *hnd = (private_handle_t *)layer.handle;
-    if (hnd)
-        s3dFormat = FORMAT_3D_INPUT(hnd->format);
-    return s3dFormat;
-}
-static bool isS3DCompositionRequired() {
-#ifdef HDMI_AS_PRIMARY
-    return overlay::is3DTV();
-#endif
-    return false;
-}
-
-static void markUILayerForS3DComposition (hwc_layer_t &layer, int s3dVideoFormat) {
-#ifdef HDMI_AS_PRIMARY
-    layer.compositionType = HWC_FRAMEBUFFER;
-    switch(s3dVideoFormat) {
-        case HAL_3D_IN_SIDE_BY_SIDE_L_R:
-        case HAL_3D_IN_SIDE_BY_SIDE_R_L:
-            layer.hints |= HWC_HINT_DRAW_S3D_SIDE_BY_SIDE;
-            break;
-        case HAL_3D_IN_TOP_BOTTOM:
-            layer.hints |= HWC_HINT_DRAW_S3D_TOP_BOTTOM;
-            break;
-        default:
-            LOGE("%s: Unknown S3D input format 0x%x", __FUNCTION__, s3dVideoFormat);
-            break;
-    }
-#endif
-    return;
-}
-
-static int getLayersNotUpdatingCount(const hwc_layer_list_t* list) {
-    int numLayersNotUpdating = 0;
-    if (list) {
-        for (size_t i=0 ; i<list->numHwLayers; i++) {
-            private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
-            if (hnd && (hnd->bufferType != BUFFER_TYPE_VIDEO) &&
-               list->hwLayers[i].flags & HWC_LAYER_NOT_UPDATING)
-               numLayersNotUpdating++;
-        }
-    }
-    return numLayersNotUpdating;
-}
-
-static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list) {
-
-    hwc_context_t* ctx = (hwc_context_t*)(dev);
-
-    if(!ctx) {
-        LOGE("hwc_prepare invalid context");
-        return -1;
-    }
-
-    private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(
-                                                           dev->common.module);
-    if (!hwcModule) {
-        LOGE("hwc_prepare invalid module");
-#ifdef COMPOSITION_BYPASS
-        unlockPreviousBypassBuffers(ctx);
-        unsetBypassBufferLockState(ctx);
-#endif
-        unlockPreviousOverlayBuffer(ctx);
-        ExtDispOnly::close();
-        return -1;
-    }
-
-    int yuvBufferCount = 0;
-    int layerType = 0;
-    bool isS3DCompositionNeeded = false;
-    int s3dVideoFormat = 0;
-    int numLayersNotUpdating = 0;
-    bool useCopybit = false;
-    bool isSkipLayerPresent = false;
-    bool skipComposition = false;
-
-    if (list) {
-        useCopybit = canUseCopybit(hwcModule->fbDevice, list);
-        yuvBufferCount = getYUVBufferCount(list);
-        numLayersNotUpdating = getLayersNotUpdatingCount(list);
-        skipComposition = canSkipComposition(ctx, yuvBufferCount,
-                                list->numHwLayers, numLayersNotUpdating);
-
-        if (yuvBufferCount == 1) {
-            s3dVideoFormat = getS3DVideoFormat(list);
-            if (s3dVideoFormat)
-                isS3DCompositionNeeded = isS3DCompositionRequired();
-        } else if((s3dVideoFormat = getS3DFormat(list))){
-            if (s3dVideoFormat)
-                isS3DCompositionNeeded = isS3DCompositionRequired();
-        } else {
-            unlockPreviousOverlayBuffer(ctx);
-        }
-
-        if (list->flags & HWC_GEOMETRY_CHANGED) {
-            if (yuvBufferCount == 1) {
-                // Inform the gralloc of the current video overlay status
-                setVideoOverlayStatusInGralloc(ctx, true);
-            }
-        }
-
-        for (size_t i=0 ; i<list->numHwLayers ; i++) {
-            private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
-
-            // If there is a single Fullscreen layer, we can bypass it - TBD
-            // If there is only one video/camera buffer, we can bypass itn
-            if (list->hwLayers[i].flags & HWC_SKIP_LAYER) {
-                // During the animaton UI layers are marked as SKIP
-                // need to still mark the layer for S3D composition
-                isSkipLayerPresent = true;
-                skipComposition = false;
-                //Reset count, so that we end up composing once after animation
-                //is over, in case of overlay.
-                ctx->previousLayerCount = -1;
-
-                if (isS3DCompositionNeeded)
-                    markUILayerForS3DComposition(list->hwLayers[i], s3dVideoFormat);
-
-// LGE_CHANGE_E, [G1_Player][bokyung.kim@lge.com], 20120201, Apply SR 00744210 to fix screen flicker {
-                ssize_t layer_countdown = ((ssize_t)i) - 1;
-                // Mark every layer below the SKIP layer to be composed by the GPU
-                while (layer_countdown >= 0)
-                {
-                    private_handle_t *countdown_handle =
-                               (private_handle_t *)list->hwLayers[layer_countdown].handle;
-                    if (countdown_handle && (countdown_handle->bufferType == BUFFER_TYPE_VIDEO)
-                        && (yuvBufferCount == 1)) {
-                        unlockPreviousOverlayBuffer(ctx);
-                    }
-                    list->hwLayers[layer_countdown].compositionType = HWC_FRAMEBUFFER;
-                    list->hwLayers[layer_countdown].hints &= ~HWC_HINT_CLEAR_FB;
-                    layer_countdown--;
-                }
-// LGE_CHANGE_E, [G1_Player][bokyung.kim@lge.com], 20120201, Apply SR 00744210 to fix screen flicker }
-                continue;
-            }
-            if (hnd && (hnd->bufferType == BUFFER_TYPE_VIDEO) && (yuvBufferCount == 1)) {
-                int flags = WAIT_FOR_VSYNC;
-                flags |= (hnd->flags &
-                       private_handle_t::PRIV_FLAGS_SECURE_BUFFER)?
-                       SECURE_OVERLAY_SESSION : 0;
-                flags |= (1 == list->numHwLayers) ? DISABLE_FRAMEBUFFER_FETCH : 0;
-                if (!isValidDestination(hwcModule->fbDevice, list->hwLayers[i].displayFrame)) {
-                    list->hwLayers[i].compositionType = HWC_FRAMEBUFFER;
-                    //Even though there are no skip layers, animation is still
-                    //ON and in its final stages.
-                    //Reset count, so that we end up composing once after animation
-                    //is done, if overlay is used.
-                    ctx->previousLayerCount = -1;
-                    skipComposition = false;
-#ifdef USE_OVERLAY
-                } else if(prepareOverlay(ctx, &(list->hwLayers[i]), flags) == 0) {
-                    list->hwLayers[i].compositionType = HWC_USE_OVERLAY;
-                    list->hwLayers[i].hints |= HWC_HINT_CLEAR_FB;
-                    // We've opened the channel. Set the state to open.
-                    ctx->hwcOverlayStatus = HWC_OVERLAY_OPEN;
-#endif
-                } else if (hwcModule->compositionType & (COMPOSITION_TYPE_C2D|
-                            COMPOSITION_TYPE_MDP)) {
-                    //Fail safe path: If drawing with overlay fails,
-
-                    //Use C2D if available.
-                    list->hwLayers[i].compositionType = HWC_USE_COPYBIT;
-                } else {
-                    //If C2D is not enabled fall back to GPU.
-                    list->hwLayers[i].compositionType = HWC_FRAMEBUFFER;
-                }
-                if (HWC_USE_OVERLAY != list->hwLayers[i].compositionType) {
-                    unlockPreviousOverlayBuffer(ctx);
-                    skipComposition = false;
-                }
-            } else if (getLayerS3DFormat(list->hwLayers[i])) {
-                int flags = WAIT_FOR_VSYNC;
-                flags |= (1 == list->numHwLayers) ? DISABLE_FRAMEBUFFER_FETCH : 0;
-                flags |= (hnd->flags &
-                       private_handle_t::PRIV_FLAGS_SECURE_BUFFER)?
-                       SECURE_OVERLAY_SESSION : 0;
-#ifdef USE_OVERLAY
-                if(prepareOverlay(ctx, &(list->hwLayers[i]), flags) == 0) {
-                    list->hwLayers[i].compositionType = HWC_USE_OVERLAY;
-                    list->hwLayers[i].hints |= HWC_HINT_CLEAR_FB;
-                    // We've opened the channel. Set the state to open.
-                    ctx->hwcOverlayStatus = HWC_OVERLAY_OPEN;
-                }
-#endif
-            } else if (isS3DCompositionNeeded) {
-                markUILayerForS3DComposition(list->hwLayers[i], s3dVideoFormat);
-            } else if (list->hwLayers[i].flags & HWC_USE_ORIGINAL_RESOLUTION) {
-                list->hwLayers[i].compositionType = HWC_USE_OVERLAY;
-                list->hwLayers[i].hints |= HWC_HINT_CLEAR_FB;
-                layerType |= HWC_ORIG_RESOLUTION;
-            } else if (hnd && hnd->flags & private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY) {
-                //handle later after other layers are handled
-            } else if (hnd && (hwcModule->compositionType &
-                    (COMPOSITION_TYPE_C2D|COMPOSITION_TYPE_MDP))) {
-                list->hwLayers[i].compositionType = HWC_USE_COPYBIT;
-            } else if ((hwcModule->compositionType == COMPOSITION_TYPE_DYN)
-                    && useCopybit) {
-                list->hwLayers[i].compositionType = HWC_USE_COPYBIT;
-            }
-            else {
-                list->hwLayers[i].compositionType = HWC_FRAMEBUFFER;
-            }
-        }
-
-        //Update the stats and pipe config for external-only layers
-        ExtDispOnly::update(ctx, list);
-
-        if (skipComposition) {
-            list->flags |= HWC_SKIP_COMPOSITION;
-        } else {
-            list->flags &= ~HWC_SKIP_COMPOSITION;
-        }
-
-#ifdef COMPOSITION_BYPASS
-        bool isBypassUsed = true;
-        bool isDoable = isBypassDoable(dev, yuvBufferCount, list);
-        //Check if bypass is feasible
-        if(isDoable && !isSkipLayerPresent) {
-            if(setupBypass(ctx, list)) {
-                setBypassLayerFlags(ctx, list);
-                ctx->bypassState = BYPASS_ON;
-            } else {
-                LOGE_IF(BYPASS_DEBUG,"%s: Bypass setup Failed",__FUNCTION__);
-                isBypassUsed = false;
-            }
-        } else {
-            LOGE_IF(BYPASS_DEBUG,"%s: Bypass not possible[%d,%d]",__FUNCTION__,
-                       isDoable, !isSkipLayerPresent );
-            isBypassUsed = false;
-        }
-
-        //Reset bypass states
-        if(!isBypassUsed) {
-            ctx->nPipesUsed = 0;
-            unsetBypassLayerFlags(list);
-            if(ctx->bypassState == BYPASS_ON) {
-                ctx->bypassState = BYPASS_OFF_PENDING;
-            }
-        }
-#endif
-    } else {
-#ifdef COMPOSITION_BYPASS
-        unlockPreviousBypassBuffers(ctx);
-        unsetBypassBufferLockState(ctx);
-#endif
-        unlockPreviousOverlayBuffer(ctx);
-    }
-    return 0;
-}
-// ---------------------------------------------------------------------------
-struct range {
-    int current;
-    int end;
-};
-struct region_iterator : public copybit_region_t {
-    
-    region_iterator(hwc_region_t region) {
-        mRegion = region;
-        r.end = region.numRects;
-        r.current = 0;
-        this->next = iterate;
-    }
-
-private:
-    static int iterate(copybit_region_t const * self, copybit_rect_t* rect) {
-        if (!self || !rect) {
-            LOGE("iterate invalid parameters");
-            return 0;
-        }
-
-        region_iterator const* me = static_cast<region_iterator const*>(self);
-        if (me->r.current != me->r.end) {
-            rect->l = me->mRegion.rects[me->r.current].left;
-            rect->t = me->mRegion.rects[me->r.current].top;
-            rect->r = me->mRegion.rects[me->r.current].right;
-            rect->b = me->mRegion.rects[me->r.current].bottom;
-            me->r.current++;
-            return 1;
-        }
-        return 0;
-    }
-    
-    hwc_region_t mRegion;
-    mutable range r; 
-};
-
-static int drawLayerUsingCopybit(hwc_composer_device_t *dev, hwc_layer_t *layer, EGLDisplay dpy,
-                                 EGLSurface surface)
-{
-    hwc_context_t* ctx = (hwc_context_t*)(dev);
-    if(!ctx) {
-         LOGE("drawLayerUsingCopybit null context ");
-         return -1;
-    }
-
-    private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(dev->common.module);
-    if(!hwcModule) {
-        LOGE("drawLayerUsingCopybit null module ");
-        return -1;
-    }
-
-    private_handle_t *hnd = (private_handle_t *)layer->handle;
-    if(!hnd) {
-        LOGE("drawLayerUsingCopybit invalid handle");
-        return -1;
-    }
-
-    // Lock this buffer for read.
-    genlock_lock_type lockType = GENLOCK_READ_LOCK;
-    int err = genlock_lock_buffer(hnd, lockType, GENLOCK_MAX_TIMEOUT);
-    if (GENLOCK_FAILURE == err) {
-        LOGE("%s: genlock_lock_buffer(READ) failed", __FUNCTION__);
-        return -1;
-    }
-    //render buffer
-    android_native_buffer_t *renderBuffer = (android_native_buffer_t *)eglGetRenderBufferANDROID(dpy, surface);
-    if (!renderBuffer) {
-        LOGE("eglGetRenderBufferANDROID returned NULL buffer");
-        genlock_unlock_buffer(hnd);
-        return -1;
-    }
-    private_handle_t *fbHandle = (private_handle_t *)renderBuffer->handle;
-    if(!fbHandle) {
-        LOGE("Framebuffer handle is NULL");
-        genlock_unlock_buffer(hnd);
-        return -1;
-    }
-    int alignment = 32;
-    if( HAL_PIXEL_FORMAT_RGB_565 == fbHandle->format )
-        alignment = 16;
-     // Set the copybit source:
-    copybit_image_t src;
-    src.w = ALIGN(hnd->width, alignment);
-    src.h = hnd->height;
-    src.format = hnd->format;
-    src.base = (void *)hnd->base;
-    src.handle = (native_handle_t *)layer->handle;
-    src.horiz_padding = src.w - hnd->width;
-    // Initialize vertical padding to zero for now,
-    // this needs to change to accomodate vertical stride
-    // if needed in the future
-    src.vert_padding = 0;
-
-    // Copybit source rect
-    hwc_rect_t sourceCrop = layer->sourceCrop;
-    copybit_rect_t srcRect = {sourceCrop.left, sourceCrop.top,
-                              sourceCrop.right,
-                              sourceCrop.bottom};
-
-    // Copybit destination rect
-    hwc_rect_t displayFrame = layer->displayFrame;
-    copybit_rect_t dstRect = {displayFrame.left, displayFrame.top,
-                              displayFrame.right,
-                              displayFrame.bottom};
-
-    // Copybit dst
-    copybit_image_t dst;
-    dst.w = ALIGN(fbHandle->width,alignment);
-    dst.h = fbHandle->height;
-    dst.format = fbHandle->format;
-    dst.base = (void *)fbHandle->base;
-    dst.handle = (native_handle_t *)renderBuffer->handle;
-
-    copybit_device_t *copybit = hwcModule->copybitEngine;
-
-    int32_t screen_w        = displayFrame.right - displayFrame.left;
-    int32_t screen_h        = displayFrame.bottom - displayFrame.top;
-    int32_t src_crop_width  = sourceCrop.right - sourceCrop.left;
-    int32_t src_crop_height = sourceCrop.bottom -sourceCrop.top;
-
-    float copybitsMaxScale = (float)copybit->get(copybit,COPYBIT_MAGNIFICATION_LIMIT);
-    float copybitsMinScale = (float)copybit->get(copybit,COPYBIT_MINIFICATION_LIMIT);
-
-    if((layer->transform == HWC_TRANSFORM_ROT_90) ||
-                           (layer->transform == HWC_TRANSFORM_ROT_270)) {
-        //swap screen width and height
-        int tmp = screen_w;
-        screen_w  = screen_h;
-        screen_h = tmp;
-    }
-    private_handle_t *tmpHnd = NULL;
-
-    if(screen_w <=0 || screen_h<=0 ||src_crop_width<=0 || src_crop_height<=0 ) {
-        LOGE("%s: wrong params for display screen_w=%d src_crop_width=%d screen_w=%d \
-                                src_crop_width=%d", __FUNCTION__, screen_w,
-                                src_crop_width,screen_w,src_crop_width);
-        genlock_unlock_buffer(hnd);
-        return -1;
-    }
-
-    float dsdx = (float)screen_w/src_crop_width;
-    float dtdy = (float)screen_h/src_crop_height;
-
-    float scaleLimitMax = copybitsMaxScale * copybitsMaxScale;
-    float scaleLimitMin = copybitsMinScale * copybitsMinScale;
-    if(dsdx > scaleLimitMax || dtdy > scaleLimitMax || dsdx < 1/scaleLimitMin || dtdy < 1/scaleLimitMin) {
-        LOGE("%s: greater than max supported size dsdx=%f dtdy=%f scaleLimitMax=%f scaleLimitMin=%f", __FUNCTION__,dsdx,dtdy,scaleLimitMax,1/scaleLimitMin);
-        genlock_unlock_buffer(hnd);
-        return -1;
-    }
-    if(dsdx > copybitsMaxScale || dtdy > copybitsMaxScale || dsdx < 1/copybitsMinScale || dtdy < 1/copybitsMinScale){
-        // The requested scale is out of the range the hardware
-        // can support.
-       LOGD("%s:%d::Need to scale twice dsdx=%f, dtdy=%f,copybitsMaxScale=%f,copybitsMinScale=%f,screen_w=%d,screen_h=%d \
-                  src_crop_width=%d src_crop_height=%d",__FUNCTION__,__LINE__,
-                  dsdx,dtdy,copybitsMaxScale,1/copybitsMinScale,screen_w,screen_h,src_crop_width,src_crop_height);
-
-       //Driver makes width and height as even
-       //that may cause wrong calculation of the ratio
-       //in display and crop.Hence we make
-       //crop width and height as even.
-       src_crop_width  = (src_crop_width/2)*2;
-       src_crop_height = (src_crop_height/2)*2;
-
-       int tmp_w =  src_crop_width;
-       int tmp_h =  src_crop_height;
-
-       if (dsdx > copybitsMaxScale || dtdy > copybitsMaxScale ){
-         tmp_w = src_crop_width*copybitsMaxScale;
-         tmp_h = src_crop_height*copybitsMaxScale;
-       }else if (dsdx < 1/copybitsMinScale ||dtdy < 1/copybitsMinScale ){
-         tmp_w = src_crop_width/copybitsMinScale;
-         tmp_h = src_crop_height/copybitsMinScale;
-         tmp_w  = (tmp_w/2)*2;
-         tmp_h = (tmp_h/2)*2;
-       }
-       LOGD("%s:%d::tmp_w = %d,tmp_h = %d",__FUNCTION__,__LINE__,tmp_w,tmp_h);
-
-       int usage = GRALLOC_USAGE_PRIVATE_ADSP_HEAP |
-                   GRALLOC_USAGE_PRIVATE_MM_HEAP;
-
-       if (0 == alloc_buffer(&tmpHnd, tmp_w, tmp_h, fbHandle->format, usage)){
-            copybit_image_t tmp_dst;
-            copybit_rect_t tmp_rect;
-            tmp_dst.w = tmp_w;
-            tmp_dst.h = tmp_h;
-            tmp_dst.format = tmpHnd->format;
-            tmp_dst.handle = tmpHnd;
-            tmp_dst.horiz_padding = src.horiz_padding;
-            tmp_dst.vert_padding = src.vert_padding;
-            tmp_rect.l = 0;
-            tmp_rect.t = 0;
-            tmp_rect.r = tmp_dst.w;
-            tmp_rect.b = tmp_dst.h;
-            //create one clip region
-            hwc_rect tmp_hwc_rect = {0,0,tmp_rect.r,tmp_rect.b};
-            hwc_region_t tmp_hwc_reg = {1,(hwc_rect_t const*)&tmp_hwc_rect};
-            region_iterator tmp_it(tmp_hwc_reg);
-            copybit->set_parameter(copybit,COPYBIT_TRANSFORM,0);
-            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA,
-                        (layer->blending == HWC_BLENDING_NONE) ? -1 : layer->alpha);
-            err = copybit->stretch(copybit,&tmp_dst, &src, &tmp_rect, &srcRect, &tmp_it);
-            if(err < 0){
-                LOGE("%s:%d::tmp copybit stretch failed",__FUNCTION__,__LINE__);
-                if(tmpHnd)
-                    free_buffer(tmpHnd);
-                genlock_unlock_buffer(hnd);
-                return err;
-            }
-            // copy new src and src rect crop
-            src = tmp_dst;
-            srcRect = tmp_rect;
-      }
-    }
-    // Copybit region
-    hwc_region_t region = layer->visibleRegionScreen;
-    region_iterator copybitRegion(region);
-
-    copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_WIDTH, renderBuffer->width);
-    copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_HEIGHT, renderBuffer->height);
-    copybit->set_parameter(copybit, COPYBIT_TRANSFORM, layer->transform);
-    copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA,
-                           (layer->blending == HWC_BLENDING_NONE) ? -1 : layer->alpha);
-    copybit->set_parameter(copybit, COPYBIT_PREMULTIPLIED_ALPHA,
-                           (layer->blending == HWC_BLENDING_PREMULT)? COPYBIT_ENABLE : COPYBIT_DISABLE);
-    copybit->set_parameter(copybit, COPYBIT_DITHER,
-                            (dst.format == HAL_PIXEL_FORMAT_RGB_565)? COPYBIT_ENABLE : COPYBIT_DISABLE);
-    err = copybit->stretch(copybit, &dst, &src, &dstRect, &srcRect, &copybitRegion);
-
-    if(tmpHnd)
-        free_buffer(tmpHnd);
-
-    if(err < 0)
-        LOGE("%s: copybit stretch failed",__FUNCTION__);
-
-    // Unlock this buffer since copybit is done with it.
-    err = genlock_unlock_buffer(hnd);
-    if (GENLOCK_FAILURE == err) {
-        LOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
-    }
-
-    return err;
-}
-
-static int drawLayerUsingOverlay(hwc_context_t *ctx, hwc_layer_t *layer)
-{
-    if (ctx && ctx->mOverlayLibObject) {
-        private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(ctx->device.common.module);
-        if (!hwcModule) {
-            LOGE("drawLayerUsingLayer null module ");
-            return -1;
-        }
-        private_handle_t *hnd = (private_handle_t *)layer->handle;
-        overlay::Overlay *ovLibObject = ctx->mOverlayLibObject;
-        int ret = 0;
-
-        // Lock this buffer for read.
-        if (GENLOCK_NO_ERROR != genlock_lock_buffer(hnd, GENLOCK_READ_LOCK,
-                                                    GENLOCK_MAX_TIMEOUT)) {
-            LOGE("%s: genlock_lock_buffer(READ) failed", __FUNCTION__);
-            return -1;
-        }
-
-        ret = ovLibObject->queueBuffer(hnd);
-
-        // Unlock the previously locked buffer, since the overlay has completed reading the buffer
-        unlockPreviousOverlayBuffer(ctx);
-
-        if (!ret) {
-            LOGE("drawLayerUsingOverlay queueBuffer failed");
-            // Unlock the buffer handle
-            genlock_unlock_buffer(hnd);
-            ctx->previousOverlayHandle = NULL;
-        } else {
-            // Store the current buffer handle as the one that is to be unlocked after
-            // the next overlay play call.
-            ctx->previousOverlayHandle = hnd;
-            hnd->flags |= private_handle_t::PRIV_FLAGS_HWC_LOCK;
-        }
-
-        return ret;
-    }
-    return -1;
-}
-
-#ifdef COMPOSITION_BYPASS
-static int drawLayerUsingBypass(hwc_context_t *ctx, hwc_layer_t *layer, int layer_index) {
-
-    int index = getLayerbypassIndex(layer);
-
-    if(index < 0) {
-        LOGE("%s: Invalid bypass index (%d)", __FUNCTION__, index);
-        return -1;
-    }
-
-    if (ctx && ctx->mOvUI[index]) {
-        overlay::OverlayUI *ovUI = ctx->mOvUI[index];
-        int ret = 0;
-
-        private_handle_t *hnd = (private_handle_t *)layer->handle;
-        if(!hnd) {
-            LOGE("%s handle null", __FUNCTION__);
-            return -1;
-        }
-
-        ctx->bypassBufferLockState[index] = BYPASS_BUFFER_UNLOCKED;
-
-        if (GENLOCK_FAILURE == genlock_lock_buffer(hnd, GENLOCK_READ_LOCK,
-                                                   GENLOCK_MAX_TIMEOUT)) {
-            LOGE("%s: genlock_lock_buffer(READ) failed", __FUNCTION__);
-            return -1;
-        }
-
-        ctx->bypassBufferLockState[index] = BYPASS_BUFFER_LOCKED;
-
-        LOGE_IF(BYPASS_DEBUG,"%s: Bypassing layer: %p using pipe: %d",__FUNCTION__, layer, index );
-
-        ret = ovUI->queueBuffer(hnd);
-
-        if (ret) {
-            // Unlock the locked buffer
-            if (GENLOCK_FAILURE == genlock_unlock_buffer(hnd)) {
-                LOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
-            }
-            ctx->bypassBufferLockState[index] = BYPASS_BUFFER_UNLOCKED;
-            return -1;
-        }
-    }
-    return 0;
-}
-#endif
-
-static int hwc_set(hwc_composer_device_t *dev,
-        hwc_display_t dpy,
-        hwc_surface_t sur,
-        hwc_layer_list_t* list)
-{
-    hwc_context_t* ctx = (hwc_context_t*)(dev);
-    if(!ctx) {
-        LOGE("hwc_set invalid context");
-        ExtDispOnly::close();
-        return -1;
-    }
-
-    private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(
-                                                           dev->common.module);
-    if (!hwcModule) {
-        LOGE("hwc_set invalid module");
-#ifdef COMPOSITION_BYPASS
-        unlockPreviousBypassBuffers(ctx);
-        unsetBypassBufferLockState(ctx);
-#endif
-        ExtDispOnly::close();
-        unlockPreviousOverlayBuffer(ctx);
-        return -1;
-    }
-
-    int ret = 0;
-    if (list) {
-        bool bDumpLayers = needToDumpLayers(); // Check need for debugging dumps
-        for (size_t i=0; i<list->numHwLayers; i++) {
-            if (bDumpLayers)
-                dumpLayer(hwcModule->compositionType, list->flags, i, list->hwLayers);
-            if (list->hwLayers[i].flags & HWC_SKIP_LAYER) {
-                continue;
-            } else if(list->hwLayers[i].flags & HWC_USE_EXT_ONLY) {
-                continue;
-            //Draw after layers for primary are drawn
-#ifdef COMPOSITION_BYPASS
-            } else if (list->hwLayers[i].flags & HWC_COMP_BYPASS) {
-                drawLayerUsingBypass(ctx, &(list->hwLayers[i]), i);
-#endif
-            } else if (list->hwLayers[i].compositionType == HWC_USE_OVERLAY) {
-                drawLayerUsingOverlay(ctx, &(list->hwLayers[i]));
-            } else if (list->flags & HWC_SKIP_COMPOSITION) {
-// LGE_CHANGE_S, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents { 
-            //break;
-                continue;
-// LGE_CHANGE_E, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents }
-            } else if (list->hwLayers[i].compositionType == HWC_USE_COPYBIT) {
-            drawLayerUsingCopybit(dev, &(list->hwLayers[i]), (EGLDisplay)dpy, (EGLSurface)sur);
-            }
-        } 
-    } else {
-        //Device in suspended state. Close all the MDP pipes
-#ifdef COMPOSITION_BYPASS
-        ctx->nPipesUsed = 0;
-#endif
-        ctx->hwcOverlayStatus =  HWC_OVERLAY_PREPARE_TO_CLOSE;
-    }
-
-    bool canSkipComposition = list && list->flags & HWC_SKIP_COMPOSITION;
-    //Draw External-only layers
-    if(ExtDispOnly::draw(ctx, list) != overlay::NO_ERROR) {
-        ExtDispOnly::close();
-    }
-
-#ifdef COMPOSITION_BYPASS
-    unlockPreviousBypassBuffers(ctx);
-    storeLockedBypassHandle(list, ctx);
-    // We have stored the handles, unset the current lock states in the context.
-    unsetBypassBufferLockState(ctx);
-    closeExtraPipes(ctx);
-#if BYPASS_DEBUG
-    if(canSkipComposition)
-        LOGE("%s: skipping eglSwapBuffer call", __FUNCTION__);
-#endif
-#endif
-    // Do not call eglSwapBuffers if we the skip composition flag is set on the list.
-    if (dpy && sur && !canSkipComposition) {
-        EGLBoolean sucess = eglSwapBuffers((EGLDisplay)dpy, (EGLSurface)sur);
-        if (!sucess) {
-            ret = HWC_EGL_ERROR;
-        } else {
-            CALC_FPS();
-        }
-    }
-#if defined HDMI_DUAL_DISPLAY
-    if(ctx->pendingHDMI) {
-        handleHDMIStateChange(dev, ctx->mHDMIEnabled);
-        ctx->pendingHDMI = false;
-    }
-#endif
-
-    hwc_closeOverlayChannels(ctx);
-    int yuvBufferCount = getYUVBufferCount(list);
-    setHWCOverlayStatus(ctx, yuvBufferCount);
-
-    return ret;
-}
-
-static int hwc_device_close(struct hw_device_t *dev)
-{
-    if(!dev) {
-        LOGE("hwc_device_close null device pointer");
-        return -1;
-    }
-
-    struct hwc_context_t* ctx = (struct hwc_context_t*)dev;
-
-    private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(
-            ctx->device.common.module);
-    // Close the overlay and copybit modules
-    if(hwcModule->copybitEngine) {
-        copybit_close(hwcModule->copybitEngine);
-        hwcModule->copybitEngine = NULL;
-    }
-    if(hwcModule->fbDevice) {
-        framebuffer_close(hwcModule->fbDevice);
-        hwcModule->fbDevice = NULL;
-    }
-
-    unlockPreviousOverlayBuffer(ctx);
-
-    if (ctx) {
-         delete ctx->mOverlayLibObject;
-         ctx->mOverlayLibObject = NULL;
-#ifdef COMPOSITION_BYPASS
-            for(int i = 0; i < MAX_BYPASS_LAYERS; i++) {
-                delete ctx->mOvUI[i];
-            }
-            unlockPreviousBypassBuffers(ctx);
-            unsetBypassBufferLockState(ctx);
-#endif
-        ExtDispOnly::close();
-        ExtDispOnly::destroy();
-
-        free(ctx);
-    }
-    return 0;
-}
-
-/*****************************************************************************/
-static int hwc_module_initialize(struct private_hwc_module_t* hwcModule)
-{
-
-    // Open the overlay and copybit modules
-    hw_module_t const *module;
-    if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
-        copybit_open(module, &(hwcModule->copybitEngine));
-    }
-    if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
-        framebuffer_open(module, &(hwcModule->fbDevice));
-    }
-
-    // get the current composition type
-    char property[PROPERTY_VALUE_MAX];
-    if (property_get("debug.sf.hw", property, NULL) > 0) {
-        if(atoi(property) == 0) {
-            //debug.sf.hw = 0
-            hwcModule->compositionType = COMPOSITION_TYPE_CPU;
-        } else { //debug.sf.hw = 1
-            // Get the composition type
-            property_get("debug.composition.type", property, NULL);
-            if (property == NULL) {
-                hwcModule->compositionType = COMPOSITION_TYPE_GPU;
-            } else if ((strncmp(property, "mdp", 3)) == 0) {
-                hwcModule->compositionType = COMPOSITION_TYPE_MDP;
-            } else if ((strncmp(property, "c2d", 3)) == 0) {
-                hwcModule->compositionType = COMPOSITION_TYPE_C2D;
-            } else if ((strncmp(property, "dyn", 3)) == 0) {
-                hwcModule->compositionType = COMPOSITION_TYPE_DYN;
-            } else {
-                hwcModule->compositionType = COMPOSITION_TYPE_GPU;
-            }
-
-            if(!hwcModule->copybitEngine)
-                hwcModule->compositionType = COMPOSITION_TYPE_GPU;
-        }
-    } else { //debug.sf.hw is not set. Use cpu composition
-        hwcModule->compositionType = COMPOSITION_TYPE_CPU;
-    }
-
-    //Check if composition bypass is enabled
-    if(property_get("ro.sf.compbypass.enable", property, NULL) > 0) {
-        if(atoi(property) == 1) {
-            hwcModule->isBypassEnabled = true;
-        }
-    }
-
-    CALC_INIT();
-
-    return 0;
-}
-
-
-static int hwc_device_open(const struct hw_module_t* module, const char* name,
-        struct hw_device_t** device)
-{
-    int status = -EINVAL;
-
-    if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
-        private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>
-                                        (const_cast<hw_module_t*>(module));
-        hwc_module_initialize(hwcModule);
-        struct hwc_context_t *dev;
-        dev = (hwc_context_t*)malloc(sizeof(*dev));
-
-        /* initialize our state here */
-        memset(dev, 0, sizeof(*dev));
-#ifdef USE_OVERLAY
-        dev->mOverlayLibObject = new overlay::Overlay();
-        if(overlay::initOverlay() == -1)
-            LOGE("overlay::initOverlay() ERROR!!");
-#else
-        dev->mOverlayLibObject = NULL;
-#endif
-#ifdef COMPOSITION_BYPASS
-        for(int i = 0; i < MAX_BYPASS_LAYERS; i++) {
-            dev->mOvUI[i] = new overlay::OverlayUI();
-            dev->previousBypassHandle[i] = NULL;
-        }
-        unsetBypassBufferLockState(dev);
-        dev->bypassState = BYPASS_OFF;
-#endif
-        ExtDispOnly::init();
-#if defined HDMI_DUAL_DISPLAY
-        dev->mHDMIEnabled = EXT_DISPLAY_OFF;
-        dev->pendingHDMI = false;
-#endif
-        dev->previousOverlayHandle = NULL;
-        dev->hwcOverlayStatus = HWC_OVERLAY_CLOSED;
-        dev->previousLayerCount = -1;
-        /* initialize the procs */
-        dev->device.common.tag = HARDWARE_DEVICE_TAG;
-        dev->device.common.version = 0;
-        dev->device.common.module = const_cast<hw_module_t*>(module);
-        dev->device.common.close = hwc_device_close;
-
-        dev->device.prepare = hwc_prepare;
-        dev->device.set = hwc_set;
-        dev->device.enableHDMIOutput = hwc_enableHDMIOutput;
-        *device = &dev->device.common;
-
-        status = 0;
-    }
-    return status;
-}
diff --git a/liboverlay/Android.mk b/liboverlay/Android.mk
old mode 100755
new mode 100644
index 79e4256..63d7780
--- a/liboverlay/Android.mk
+++ b/liboverlay/Android.mk
@@ -1,43 +1,20 @@
-# Copyright (C) 2008 The Android Open Source Project
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License
-#
-
 LOCAL_PATH := $(call my-dir)
-
 include $(CLEAR_VARS)
-LOCAL_PRELINK_MODULE := false
 LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)
-LOCAL_SHARED_LIBRARIES := liblog libcutils libutils libmemalloc
-LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
-LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
-LOCAL_C_INCLUDES += hardware/qcom/display/libgralloc
+LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_SHARED_LIBRARIES += libcutils
+LOCAL_SHARED_LIBRARIES += libutils
+LOCAL_SHARED_LIBRARIES += libmemalloc
+LOCAL_C_INCLUDES := hardware/qcom/display/libgralloc
 LOCAL_SRC_FILES := \
-    overlayLib.cpp \
-    overlayLibUI.cpp \
-LOCAL_CFLAGS:= -DLOG_TAG=\"OverlayLib\"
+      overlay.cpp \
+      overlayCtrl.cpp \
+      overlayUtils.cpp \
+      overlayMdp.cpp \
+      overlayRotator.cpp \
+      overlayTransitions.cpp
 
-ifeq ($(TARGET_USE_HDMI_AS_PRIMARY),true)
-LOCAL_CFLAGS += -DHDMI_AS_PRIMARY
-endif
-ifeq ($(TARGET_USES_POST_PROCESSING),true)
-LOCAL_CFLAGS += -DUSES_POST_PROCESSING
-LOCAL_SHARED_LIBRARIES += libmm-abl
-LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/pp/inc
-LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/lib/
-endif
+LOCAL_CFLAGS:= -DLOG_TAG=\"overlay2\"
 LOCAL_MODULE := liboverlay
-
-#LGE_CHANGE, for userdebug mode
 LOCAL_MODULE_TAGS := optional
 include $(BUILD_SHARED_LIBRARY)
diff --git a/liboverlay/mdpWrapper.h b/liboverlay/mdpWrapper.h
new file mode 100644
index 0000000..4cfd3e0
--- /dev/null
+++ b/liboverlay/mdpWrapper.h
@@ -0,0 +1,270 @@
+/*
+* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef MDP_WRAPPER_H
+#define MDP_WRAPPER_H
+
+/*
+* In order to make overlay::mdp_wrapper shorter, please do something like:
+* namespace mdpwrap = overlay::mdp_wrapper;
+* */
+
+#include <linux/msm_mdp.h>
+#include <linux/msm_rotator.h>
+#include <sys/ioctl.h>
+#include <utils/Log.h>
+#include <errno.h>
+#include "overlayUtils.h"
+
+namespace overlay{
+
+namespace mdp_wrapper{
+/* FBIOGET_FSCREENINFO */
+bool getFScreenInfo(int fd, fb_fix_screeninfo& finfo);
+
+/* FBIOGET_VSCREENINFO */
+bool getVScreenInfo(int fd, fb_var_screeninfo& vinfo);
+
+/* FBIOPUT_VSCREENINFO */
+bool setVScreenInfo(int fd, fb_var_screeninfo& vinfo);
+
+/* MSM_ROTATOR_IOCTL_START */
+bool startRotator(int fd, msm_rotator_img_info& rot);
+
+/* MSM_ROTATOR_IOCTL_ROTATE */
+bool rotate(int fd, msm_rotator_data_info& rot);
+
+/* MSMFB_OVERLAY_SET */
+bool setOverlay(int fd, mdp_overlay& ov);
+
+/* MSM_ROTATOR_IOCTL_FINISH */
+bool endRotator(int fd, int sessionId);
+
+/* MSMFB_OVERLAY_UNSET */
+bool unsetOverlay(int fd, int ovId);
+
+/* MSMFB_OVERLAY_GET */
+bool getOverlay(int fd, mdp_overlay& ov);
+
+/* MSMFB_OVERLAY_PLAY */
+bool play(int fd, msmfb_overlay_data& od);
+
+/* MSMFB_OVERLAY_PLAY_WAIT */
+bool playWait(int fd, msmfb_overlay_data& od);
+
+/* MSMFB_OVERLAY_3D */
+bool set3D(int fd, msmfb_overlay_3d& ov);
+
+/* the following are helper functions for dumping
+ * msm_mdp and friends*/
+void dump(const char* const s, const msmfb_overlay_data& ov);
+void dump(const char* const s, const msmfb_data& ov);
+void dump(const char* const s, const mdp_overlay& ov);
+void dump(const char* const s, const msmfb_overlay_3d& ov);
+void dump(const char* const s, const uint32_t u[], uint32_t cnt);
+void dump(const char* const s, const msmfb_img& ov);
+void dump(const char* const s, const mdp_rect& ov);
+
+/* and rotator */
+void dump(const char* const s, const msm_rotator_img_info& rot);
+void dump(const char* const s, const msm_rotator_data_info& rot);
+
+/* info */
+void dump(const char* const s, const fb_fix_screeninfo& finfo);
+void dump(const char* const s, const fb_var_screeninfo& vinfo);
+
+//---------------Inlines -------------------------------------
+
+inline bool getFScreenInfo(int fd, fb_fix_screeninfo& finfo) {
+    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) {
+        ALOGE("Failed to call ioctl FBIOGET_FSCREENINFO err=%d", errno);
+        return false;
+    }
+    return true;
+}
+
+inline bool getVScreenInfo(int fd, fb_var_screeninfo& vinfo) {
+    if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) == -1) {
+        ALOGE("Failed to call ioctl FBIOGET_VSCREENINFO err=%d", errno);
+        return false;
+    }
+    return true;
+}
+
+inline bool setVScreenInfo(int fd, fb_var_screeninfo& vinfo) {
+    if (ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo) == -1) {
+        ALOGE("Failed to call ioctl FBIOPUT_VSCREENINFO err=%d", errno);
+        return false;
+    }
+    return true;
+}
+
+inline bool startRotator(int fd, msm_rotator_img_info& rot) {
+    if (ioctl(fd, MSM_ROTATOR_IOCTL_START, &rot) == -1){
+        ALOGE("Failed to call ioctl MSM_ROTATOR_IOCTL_START err=%d", errno);
+        return false;
+    }
+    return true;
+}
+
+inline bool rotate(int fd, msm_rotator_data_info& rot) {
+    if (ioctl(fd, MSM_ROTATOR_IOCTL_ROTATE, &rot) == -1) {
+        ALOGE("Failed to call ioctl MSM_ROTATOR_IOCTL_ROTATE err=%d", errno);
+        return false;
+    }
+    return true;
+}
+
+inline bool setOverlay(int fd, mdp_overlay& ov) {
+    if (ioctl(fd, MSMFB_OVERLAY_SET, &ov) == -1) {
+        ALOGE("Failed to call ioctl MSMFB_OVERLAY_SET err=%d", errno);
+        return false;
+    }
+    return true;
+}
+
+inline bool endRotator(int fd, int sessionId) {
+    if (ioctl(fd, MSM_ROTATOR_IOCTL_FINISH, &sessionId) == -1) {
+        ALOGE("Failed to call ioctl MSM_ROTATOR_IOCTL_FINISH err=%d", errno);
+        return false;
+    }
+    return true;
+}
+
+inline bool unsetOverlay(int fd, int ovId) {
+    if (ioctl(fd, MSMFB_OVERLAY_UNSET, &ovId) == -1) {
+        ALOGE("Failed to call ioctl MSMFB_OVERLAY_UNSET err=%d", errno);
+        return false;
+    }
+    return true;
+}
+
+inline bool getOverlay(int fd, mdp_overlay& ov) {
+    if (ioctl(fd, MSMFB_OVERLAY_GET, &ov) == -1) {
+        ALOGE("Failed to call ioctl MSMFB_OVERLAY_GET err=%d", errno);
+        return false;
+    }
+    return true;
+}
+
+inline bool play(int fd, msmfb_overlay_data& od) {
+    if (ioctl(fd, MSMFB_OVERLAY_PLAY, &od) == -1) {
+        ALOGE("Failed to call ioctl MSMFB_OVERLAY_PLAY err=%d", errno);
+        return false;
+    }
+    return true;
+}
+
+inline bool playWait(int fd, msmfb_overlay_data& od) {
+    if (ioctl(fd, MSMFB_OVERLAY_PLAY_WAIT, &od) == -1) {
+        ALOGE("Failed to call ioctl MSMFB_OVERLAY_PLAY_WAIT err=%d", errno);
+        return false;
+    }
+    return true;
+}
+
+inline bool set3D(int fd, msmfb_overlay_3d& ov) {
+    if (ioctl(fd, MSMFB_OVERLAY_3D, &ov) == -1) {
+        ALOGE("Failed to call ioctl MSMFB_OVERLAY_3D err=%d", errno);
+        return false;
+    }
+    return true;
+}
+
+/* dump funcs */
+inline void dump(const char* const s, const msmfb_overlay_data& ov) {
+    ALOGE("%s msmfb_overlay_data id=%d",
+            s, ov.id);
+    dump("data", ov.data);
+}
+inline void dump(const char* const s, const msmfb_data& ov) {
+    ALOGE("%s msmfb_data offset=%d memid=%d id=%d flags=0x%x priv=%d",
+            s, ov.offset, ov.memory_id, ov.id, ov.flags, ov.priv);
+}
+inline void dump(const char* const s, const mdp_overlay& ov) {
+    ALOGE("%s mdp_overlay z=%d fg=%d alpha=%d mask=%d flags=0x%x id=%d",
+            s, ov.z_order, ov.is_fg, ov.alpha,
+            ov.transp_mask, ov.flags, ov.id);
+    dump("src", ov.src);
+    dump("src_rect", ov.src_rect);
+    dump("dst_rect", ov.dst_rect);
+    dump("user_data", ov.user_data,
+            sizeof(ov.user_data)/sizeof(ov.user_data[0]));
+}
+inline void dump(const char* const s, const msmfb_img& ov) {
+    ALOGE("%s msmfb_img w=%d h=%d format=%d %s",
+            s, ov.width, ov.height, ov.format,
+            overlay::utils::getFormatString(ov.format));
+}
+inline void dump(const char* const s, const mdp_rect& ov) {
+    ALOGE("%s mdp_rect x=%d y=%d w=%d h=%d",
+            s, ov.x, ov.y, ov.w, ov.h);
+}
+
+inline void dump(const char* const s, const msmfb_overlay_3d& ov) {
+    ALOGE("%s msmfb_overlay_3d 3d=%d w=%d h=%d",
+            s, ov.is_3d, ov.width, ov.height);
+
+}
+inline void dump(const char* const s, const uint32_t u[], uint32_t cnt) {
+    ALOGE("%s user_data cnt=%d", s, cnt);
+    for(uint32_t i=0; i < cnt; ++i) {
+        ALOGE("i=%d val=%d", i, u[i]);
+    }
+}
+inline void dump(const char* const s, const msm_rotator_img_info& rot) {
+    ALOGE("%s msm_rotator_img_info sessid=%d dstx=%d dsty=%d rot=%d, ena=%d",
+            s, rot.session_id, rot.dst_x, rot.dst_y,
+            rot.rotations, rot.enable);
+    dump("src", rot.src);
+    dump("dst", rot.dst);
+    dump("src_rect", rot.src_rect);
+}
+inline void dump(const char* const s, const msm_rotator_data_info& rot) {
+    ALOGE("%s msm_rotator_data_info sessid=%d verkey=%d",
+            s, rot.session_id, rot.version_key);
+    dump("src", rot.src);
+    dump("dst", rot.dst);
+    dump("src_chroma", rot.src_chroma);
+    dump("dst_chroma", rot.dst_chroma);
+}
+inline void dump(const char* const s, const fb_fix_screeninfo& finfo) {
+    ALOGE("%s fb_fix_screeninfo type=%d", s, finfo.type);
+}
+inline void dump(const char* const s, const fb_var_screeninfo& vinfo) {
+    ALOGE("%s fb_var_screeninfo xres=%d yres=%d",
+            s, vinfo.xres, vinfo.yres);
+}
+
+
+} // mdp_wrapper
+
+} // overlay
+
+#endif // MDP_WRAPPER_H
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
new file mode 100644
index 0000000..ed968c1
--- /dev/null
+++ b/liboverlay/overlay.cpp
@@ -0,0 +1,455 @@
+/*
+* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "overlayUtils.h"
+#include "overlayImpl.h"
+#include "overlay.h"
+
+// MDP related FIXME move to state
+#include "overlayMdp.h"
+#include "overlayCtrlData.h"
+#include "overlayRotator.h"
+
+namespace overlay {
+
+Overlay::Overlay(): mOv(0) {
+}
+
+Overlay::~Overlay() {
+    if(mState.state() == utils::OV_CLOSED) return;
+    close();
+    delete mOv;
+    mOv = 0;
+}
+
+bool Overlay::open() {
+    // We need an empty open to just open the bare minimum for business
+    return true;
+}
+
+void Overlay::reset(){
+    if(mOv && !mOv->close()) {
+        ALOGE("%s Overlay failed", __FUNCTION__);
+    }
+
+    delete mOv;
+    mOv = 0;
+}
+
+bool Overlay::close()
+{
+    OVASSERT(mOv,
+            "%s Overlay and Rotator should be init at this point",
+            __FUNCTION__);
+    // FIXME that one needs to move to the state machine class
+    utils::eOverlayState st = mState.state();
+    switch (st) {
+        case utils::OV_CLOSED:
+            // try to close any partially opened items
+            break;
+        case utils::OV_2D_VIDEO_ON_PANEL:
+        case utils::OV_2D_VIDEO_ON_PANEL_TV:
+        case utils::OV_3D_VIDEO_ON_2D_PANEL:
+        case utils::OV_3D_VIDEO_ON_3D_PANEL:
+        case utils::OV_3D_VIDEO_ON_3D_TV:
+        case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
+        case utils::OV_UI_MIRROR:
+        case utils::OV_2D_TRUE_UI_MIRROR:
+        case utils::OV_BYPASS_1_LAYER:
+        case utils::OV_BYPASS_2_LAYER:
+        case utils::OV_BYPASS_3_LAYER:
+            mOv = mState.handleEvent(utils::OV_CLOSED, mOv);
+            this->reset();
+            break;
+        default:
+            OVASSERT(false, "close Unknown state %d", st);
+            return false;
+    }
+    return true;
+}
+
+bool Overlay::commit(utils::eDest dest)
+{
+    OVASSERT(mOv,
+            "%s Overlay and Rotator should be init at this point",
+            __FUNCTION__);
+    // FIXME that one needs to move to the state machine class
+    utils::eOverlayState st = mState.state();
+    switch (st) {
+        case utils::OV_2D_VIDEO_ON_PANEL:
+        case utils::OV_2D_VIDEO_ON_PANEL_TV:
+        case utils::OV_3D_VIDEO_ON_2D_PANEL:
+        case utils::OV_3D_VIDEO_ON_3D_PANEL:
+        case utils::OV_3D_VIDEO_ON_3D_TV:
+        case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
+        case utils::OV_UI_MIRROR:
+        case utils::OV_2D_TRUE_UI_MIRROR:
+        case utils::OV_BYPASS_1_LAYER:
+        case utils::OV_BYPASS_2_LAYER:
+        case utils::OV_BYPASS_3_LAYER:
+            if(!mOv->commit(dest)) {
+                ALOGE("Overlay %s failed", __FUNCTION__);
+                return false;
+            }
+            break;
+        default:
+            OVASSERT(false, "%s Unknown state %d", __FUNCTION__, st);
+            return false;
+    }
+    return true;
+}
+
+bool Overlay::queueBuffer(uint32_t offset,
+        utils::eDest dest)
+{
+    OVASSERT(mOv,
+            "%s Overlay and Rotator should be init at this point",
+            __FUNCTION__);
+    // FIXME that one needs to move to the state machine class
+    utils::eOverlayState st = mState.state();
+    switch (st) {
+        case utils::OV_2D_VIDEO_ON_PANEL:
+        case utils::OV_2D_VIDEO_ON_PANEL_TV:
+        case utils::OV_3D_VIDEO_ON_2D_PANEL:
+        case utils::OV_3D_VIDEO_ON_3D_PANEL:
+        case utils::OV_3D_VIDEO_ON_3D_TV:
+        case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
+        case utils::OV_UI_MIRROR:
+        case utils::OV_2D_TRUE_UI_MIRROR:
+        case utils::OV_BYPASS_1_LAYER:
+        case utils::OV_BYPASS_2_LAYER:
+        case utils::OV_BYPASS_3_LAYER:
+            if(!mOv->queueBuffer(offset, dest)) {
+                ALOGE("Overlay %s failed", __FUNCTION__);
+                return false;
+            }
+            break;
+        default:
+            OVASSERT(false, "%s Unknown state %d", __FUNCTION__, st);
+            return false;
+    }
+    return true;
+}
+
+bool Overlay::dequeueBuffer(void*& buf,
+        utils::eDest dest)
+{
+    OVASSERT(mOv,
+            "%s Overlay and Rotator should be init at this point",
+            __FUNCTION__);
+    // FIXME that one needs to move to the state machine class
+    utils::eOverlayState st = mState.state();
+    switch (st) {
+        case utils::OV_2D_VIDEO_ON_PANEL:
+        case utils::OV_2D_VIDEO_ON_PANEL_TV:
+        case utils::OV_3D_VIDEO_ON_2D_PANEL:
+        case utils::OV_3D_VIDEO_ON_3D_PANEL:
+        case utils::OV_3D_VIDEO_ON_3D_TV:
+        case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
+        case utils::OV_UI_MIRROR:
+        case utils::OV_2D_TRUE_UI_MIRROR:
+        case utils::OV_BYPASS_1_LAYER:
+        case utils::OV_BYPASS_2_LAYER:
+        case utils::OV_BYPASS_3_LAYER:
+            if(!mOv->dequeueBuffer(buf, dest)) {
+                ALOGE("Overlay %s failed", __FUNCTION__);
+                return false;
+            }
+            break;
+        default:
+            OVASSERT(false, "%s Unknown state %d", __FUNCTION__, st);
+            return false;
+    }
+    return true;
+}
+
+bool Overlay::waitForVsync(utils::eDest dest)
+{
+    OVASSERT(mOv,
+            "%s Overlay and Rotator should be init at this point",
+            __FUNCTION__);
+    // FIXME that one needs to move to the state machine class
+    utils::eOverlayState st = mState.state();
+    switch (st) {
+        case utils::OV_2D_VIDEO_ON_PANEL:
+        case utils::OV_2D_VIDEO_ON_PANEL_TV:
+        case utils::OV_3D_VIDEO_ON_2D_PANEL:
+        case utils::OV_3D_VIDEO_ON_3D_PANEL:
+        case utils::OV_3D_VIDEO_ON_3D_TV:
+        case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
+        case utils::OV_UI_MIRROR:
+        case utils::OV_2D_TRUE_UI_MIRROR:
+        case utils::OV_BYPASS_1_LAYER:
+        case utils::OV_BYPASS_2_LAYER:
+        case utils::OV_BYPASS_3_LAYER:
+            if(!mOv->waitForVsync(dest)) {
+                ALOGE("Overlay %s failed", __FUNCTION__);
+                return false;
+            }
+            break;
+        default:
+            OVASSERT(false, "%s Unknown state %d", __FUNCTION__, st);
+            return false;
+    }
+    return true;
+}
+
+bool Overlay::setCrop(const utils::Dim& d,
+        utils::eDest dest)
+{
+    OVASSERT(mOv,
+            "%s Overlay and Rotator should be init at this point",
+            __FUNCTION__);
+    // FIXME that one needs to move to the state machine class
+    utils::eOverlayState st = mState.state();
+    switch (st) {
+        case utils::OV_2D_VIDEO_ON_PANEL:
+        case utils::OV_2D_VIDEO_ON_PANEL_TV:
+        case utils::OV_3D_VIDEO_ON_2D_PANEL:
+        case utils::OV_3D_VIDEO_ON_3D_PANEL:
+        case utils::OV_3D_VIDEO_ON_3D_TV:
+        case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
+        case utils::OV_UI_MIRROR:
+        case utils::OV_2D_TRUE_UI_MIRROR:
+        case utils::OV_BYPASS_1_LAYER:
+        case utils::OV_BYPASS_2_LAYER:
+        case utils::OV_BYPASS_3_LAYER:
+            if(!mOv->setCrop(d, dest)) {
+                ALOGE("Overlay %s failed", __FUNCTION__);
+                return false;
+            }
+            break;
+        default:
+            OVASSERT(false, "%s Unknown state %d", __FUNCTION__, st);
+            return false;
+    }
+    return true;
+}
+bool Overlay::setPosition(const utils::Dim& d,
+        utils::eDest dest)
+{
+    OVASSERT(mOv,
+            "%s Overlay and Rotator should be init at this point",
+            __FUNCTION__);
+    // FIXME that one needs to move to the state machine class
+    utils::eOverlayState st = mState.state();
+    switch (st) {
+        case utils::OV_2D_VIDEO_ON_PANEL:
+        case utils::OV_2D_VIDEO_ON_PANEL_TV:
+        case utils::OV_3D_VIDEO_ON_2D_PANEL:
+        case utils::OV_3D_VIDEO_ON_3D_PANEL:
+        case utils::OV_3D_VIDEO_ON_3D_TV:
+        case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
+        case utils::OV_UI_MIRROR:
+        case utils::OV_2D_TRUE_UI_MIRROR:
+        case utils::OV_BYPASS_1_LAYER:
+        case utils::OV_BYPASS_2_LAYER:
+        case utils::OV_BYPASS_3_LAYER:
+            if(!mOv->setPosition(d, dest)) {
+                ALOGE("Overlay %s failed", __FUNCTION__);
+                return false;
+            }
+            break;
+        default:
+            OVASSERT(false, "setPos Unknown state %d", st);
+            return false;
+    }
+    return true;
+}
+bool Overlay::setParameter(const utils::Params& param,
+        utils::eDest dest)
+{
+    OVASSERT(mOv,
+            "%s Overlay and Rotator should be init at this point",
+            __FUNCTION__);
+    // FIXME that one needs to move to the state machine class
+    utils::eOverlayState st = mState.state();
+    switch (st) {
+        case utils::OV_2D_VIDEO_ON_PANEL:
+        case utils::OV_2D_VIDEO_ON_PANEL_TV:
+        case utils::OV_3D_VIDEO_ON_2D_PANEL:
+        case utils::OV_3D_VIDEO_ON_3D_PANEL:
+        case utils::OV_3D_VIDEO_ON_3D_TV:
+        case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
+        case utils::OV_UI_MIRROR:
+        case utils::OV_2D_TRUE_UI_MIRROR:
+        case utils::OV_BYPASS_1_LAYER:
+        case utils::OV_BYPASS_2_LAYER:
+        case utils::OV_BYPASS_3_LAYER:
+            if(!mOv->setParameter(param, dest)) {
+                ALOGE("Overlay %s failed", __FUNCTION__);
+                return false;
+            }
+            break;
+        default:
+            OVASSERT(false, "%s Unknown state %d", __FUNCTION__ , st);
+            return false;
+    }
+    return true;
+}
+bool Overlay::setSource(const utils::PipeArgs args[utils::MAX_PIPES],
+        utils::eDest dest)
+{
+    // FIXME that one needs to move to the state machine class
+    utils::PipeArgs margs[utils::MAX_PIPES] = {
+        args[0], args[1], args[2] };
+    utils::eOverlayState st = mState.state();
+
+    switch (st) {
+        case utils::OV_CLOSED:
+            // if we get setSource when we are closed, then
+            // we will assume tranistion to OV_2D_VIDEO_ON_PANEL
+            // returns overlay
+            mOv = mState.handle_closed(utils::OV_2D_VIDEO_ON_PANEL);
+            if (!mOv) {
+                ALOGE("Overlay %s failed", __FUNCTION__);
+                this->reset(); // cleanup
+                return false;
+            }
+            break;
+        case utils::OV_2D_VIDEO_ON_PANEL:
+        case utils::OV_3D_VIDEO_ON_2D_PANEL:
+        case utils::OV_UI_MIRROR:
+        case utils::OV_BYPASS_1_LAYER:
+        case utils::OV_BYPASS_2_LAYER:
+        case utils::OV_BYPASS_3_LAYER:
+            // no tweaking
+            break;
+        case utils::OV_3D_VIDEO_ON_3D_PANEL:
+        case utils::OV_3D_VIDEO_ON_3D_TV:
+            margs[utils::CHANNEL_1].zorder = utils::ZORDER_1;
+            break;
+        case utils::OV_2D_VIDEO_ON_PANEL_TV:
+        case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
+            // If displaying on both, external VG pipe set to be no wait
+            margs[utils::CHANNEL_1].wait = utils::NO_WAIT;
+            break;
+        case utils::OV_2D_TRUE_UI_MIRROR:
+            // Set zorder -- external VG pipe (video) gets 0, RGB pipe (UI) gets 1
+            margs[utils::CHANNEL_1].zorder = utils::ZORDER_0;
+            margs[utils::CHANNEL_2].zorder = utils::ZORDER_1;
+            // External VG (video) and RGB (UI) pipe set to be no wait
+            margs[utils::CHANNEL_0].wait = utils::WAIT;
+            margs[utils::CHANNEL_1].wait = utils::NO_WAIT;
+            margs[utils::CHANNEL_2].wait = utils::NO_WAIT;
+            break;
+        default:
+            OVASSERT(false, "%s Unknown state %d", __FUNCTION__, st);
+            return false;
+    }
+
+    if (!mOv->setSource(margs, dest)) {
+        ALOGE("Overlay %s failed", __FUNCTION__);
+        return false;
+    }
+
+    return true;
+}
+void Overlay::setMemoryId(int id, utils::eDest dest)
+{
+    OVASSERT(mOv,
+            "%s Overlay and Rotator should be init at this point",
+            __FUNCTION__);
+    // FIXME that one needs to move to the state machine class
+    utils::eOverlayState st = mState.state();
+    switch (st) {
+        case utils::OV_2D_VIDEO_ON_PANEL:
+        case utils::OV_2D_VIDEO_ON_PANEL_TV:
+        case utils::OV_3D_VIDEO_ON_2D_PANEL:
+        case utils::OV_3D_VIDEO_ON_3D_PANEL:
+        case utils::OV_3D_VIDEO_ON_3D_TV:
+        case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
+        case utils::OV_UI_MIRROR:
+        case utils::OV_2D_TRUE_UI_MIRROR:
+        case utils::OV_BYPASS_1_LAYER:
+        case utils::OV_BYPASS_2_LAYER:
+        case utils::OV_BYPASS_3_LAYER:
+            mOv->setMemoryId(id, dest);
+            break;
+        default:
+            OVASSERT(false, "setMemId Unknown state %d", st);
+    }
+}
+
+
+void Overlay::dump() const
+{
+    OVASSERT(mOv,
+            "%s Overlay and Rotator should be init at this point",
+            __FUNCTION__);
+    // FIXME dump tate object, factory
+    ALOGE("== Dump Overlay start ==");
+    mState.dump();
+    mOv->dump();
+    ALOGE("== Dump Overlay end ==");
+}
+
+void Overlay::setState(utils::eOverlayState s) {
+    mOv = mState.handleEvent(s, mOv);
+}
+
+utils::eOverlayState Overlay::getState() const {
+    return mState.state();
+}
+
+Overlay *Overlay::sInstance = 0;
+
+Overlay* Overlay::getInstance() {
+    if(sInstance == NULL)
+        sInstance = new Overlay();
+    return sInstance;
+}
+
+/****  NullPipe  ****/
+
+bool NullPipe::open(RotatorBase*) {
+    ALOGE_IF(DEBUG_OVERLAY, "NullPipe open");
+    return true;
+}
+bool NullPipe::close() { return true; }
+bool NullPipe::commit() { return true; }
+bool NullPipe::start(const utils::PipeArgs&) { return true; }
+bool NullPipe::setCrop(const utils::Dim&) { return true; }
+bool NullPipe::setPosition(const utils::Dim&) { return true; }
+bool NullPipe::setParameter(const utils::Params&) { return true; }
+bool NullPipe::setSource(const utils::PipeArgs&) { return true; }
+bool NullPipe::queueBuffer(uint32_t offset) { return true; }
+bool NullPipe::dequeueBuffer(void*&) { return true; }
+bool NullPipe::waitForVsync() { return true; }
+void NullPipe::setMemoryId(int) {}
+// NullPipe will return by val here as opposed to other Pipes.
+utils::PipeArgs NullPipe::getArgs() const { return utils::PipeArgs(); }
+utils::eOverlayPipeType NullPipe::getOvPipeType() const {
+    return utils::OV_PIPE_TYPE_NULL;
+}
+void NullPipe::dump() const {
+    ALOGE("== NullPipe (null) start/end ==");
+}
+
+} // overlay
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
new file mode 100644
index 0000000..e2ee6cd
--- /dev/null
+++ b/liboverlay/overlay.h
@@ -0,0 +1,103 @@
+/*
+* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef OVERLAY_H
+#define OVERLAY_H
+
+#include "overlayUtils.h"
+#include "overlayState.h"
+#include "overlayImpl.h"
+
+namespace overlay {
+/**/
+class Overlay : utils::NoCopy {
+public:
+    /* dtor close */
+    ~Overlay();
+
+    /* Overlay related func */
+
+    /* We need an empty open to just open the bare minimum for
+     * business. */
+    bool open();
+
+    /* close rotator, state, overlayimpl*/
+    bool close();
+
+    /* Following is the same as the pure virt interface in ov impl  */
+
+    bool commit(utils::eDest dest = utils::OV_PIPE_ALL);
+
+    bool queueBuffer(uint32_t offset,
+            utils::eDest dest = utils::OV_PIPE_ALL);
+    bool dequeueBuffer(void*& buf,
+            utils::eDest dest = utils::OV_PIPE_ALL);
+    bool waitForVsync(utils::eDest dest = utils::OV_PIPE1);
+    bool setCrop(const utils::Dim& d,
+            utils::eDest dest = utils::OV_PIPE_ALL);
+    bool setPosition(const utils::Dim& dim,
+            utils::eDest dest = utils::OV_PIPE_ALL);
+    bool setParameter(const utils::Params& param,
+            utils::eDest dest = utils::OV_PIPE_ALL);
+    bool setSource(const utils::PipeArgs args[utils::MAX_PIPES],
+            utils::eDest dest = utils::OV_PIPE_ALL);
+    void setMemoryId(int id, utils::eDest dest = utils::OV_PIPE_ALL);
+    void dump() const;
+
+    /* state related functions */
+    void setState(utils::eOverlayState s);
+
+    /* expose state */
+    utils::eOverlayState getState() const;
+
+    /* Returns the singleton instance of overlay */
+    static Overlay* getInstance();
+
+private:
+    /* Ctor setup */
+    Overlay();
+
+    /* reset all pointers */
+    void reset();
+
+    /* Holds the state, state transition logic
+     * In the meantime, using simple enum rather than
+     * a class */
+    OverlayState mState;
+
+    /* Holds the actual overlay impl, set when changing state*/
+    OverlayImplBase *mOv;
+
+    /* Singleton Instance*/
+    static Overlay *sInstance;
+};
+
+} // overlay
+
+#endif // OVERLAY_H
diff --git a/liboverlay/overlayCtrl.cpp b/liboverlay/overlayCtrl.cpp
new file mode 100644
index 0000000..6f84d07
--- /dev/null
+++ b/liboverlay/overlayCtrl.cpp
@@ -0,0 +1,349 @@
+/*
+* Copyright (C) 2008 The Android Open Source Project
+* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <cutils/properties.h>
+#include "overlayCtrlData.h"
+#include "fb_priv.h"
+
+namespace overlay{
+
+bool Ctrl::open(uint32_t fbnum,
+        RotatorBase* rot) {
+    // MDP/FD open
+    if(!mMdp.open(fbnum)) {
+        ALOGE("Ctrl failed to open fbnum=%d", fbnum);
+        return false;
+    }
+
+    if(!getScreenInfo(mInfo)) {
+        ALOGE("Ctrl failed to getScreenInfo");
+        return false;
+    }
+
+    OVASSERT(rot, "rot is null");
+    mRot = rot;
+    // rot should be already opened
+
+    return true;
+}
+
+bool Ctrl::start(const utils::PipeArgs& args)
+{
+    int colorFormat = utils::getColorFormat(args.whf.format);
+    utils::eMdpFlags flags = args.mdpFlags;
+
+    //XXX: Support for interlaced content
+    if (0) {
+
+        setMdpFlags(flags, utils::OV_MDP_DEINTERLACE);
+
+        // Get the actual format
+        colorFormat = args.whf.format ^ HAL_PIXEL_FORMAT_INTERLACE;
+    }
+    utils::Whf hwwhf(args.whf);
+    int fmt = utils::getMdpFormat(colorFormat);
+    // FIXME format should probably be int and not uint
+    if (fmt < 0) {
+        ALOGE("Ctrl failed getMdpFormat unsopported "
+                "colorFormat=%d format=%d flags=%d",
+                colorFormat, fmt, flags);
+        return false;
+    }
+    hwwhf.format = fmt;
+
+    // devices should be already opened
+    // (by calling open earlier in the flow)
+
+    const utils::PipeArgs newargs(flags, // mdp flags
+            args.orientation, // trans
+            hwwhf,
+            args.wait,
+            args.zorder,
+            args.isFg,
+            args.rotFlags);
+    if (!setInfo(newargs)) {
+        ALOGE("Ctrl failed to setInfo mdpflags=%d wait=%d zorder=%d",
+                newargs.mdpFlags, newargs.wait, newargs.zorder);
+        hwwhf.dump();
+        return false;
+    }
+
+    // FIXME, can we remove that and have it in
+    // setSource only when source changed?
+    if(!mRot->start(newargs)) {
+        ALOGE("Ctrl failed to start Rotation session");
+        return false;
+    }
+
+    // if geom is different, we need to prepare a new rot buffers.
+    // remap on demand when the current orientation is 90,180, etc.
+    // and the prev orientation was 0. It means we go from orient
+    if(!mRot->remap(utils::ROT_NUM_BUFS, newargs)) {
+        ALOGE("%s Error in remapping", __FUNCTION__);
+    }
+
+    if(!mMdp.set()) {
+        ALOGE("Ctrl start failed set overlay");
+        return false;
+    }
+
+    // cache the src to be the current mCrop vals
+    mCrop.w = hwwhf.w;
+    mCrop.h = hwwhf.h;
+
+    return true;
+}
+
+inline void Ctrl::updateSource(RotatorBase* r,
+        const utils::PipeArgs& args,
+        utils::ScreenInfo& info)
+{
+    mMdp.updateSource(r, args, info);
+}
+
+bool Ctrl::setSource(const utils::PipeArgs& args)
+{
+    mMdp.setWait(args.wait);
+
+    utils::PipeArgs newargs(args);
+    utils::Whf whf(args.whf);
+    // check geom change
+    if(mOvBufInfo != whf) {
+        // whf.format is given as HAL, that is why it is
+        // needed to be MDP fmt.
+        whf.format = utils::getColorFormat(whf.format);
+        int fmt = utils::getMdpFormat(whf.format);
+        OVASSERT(-1 != fmt, "Ctrl setSource format is -1");
+        whf.format = fmt;
+        newargs.whf = whf;
+        updateSource(mRot, newargs, mInfo);
+        mMdp.setUserData(0);
+        if(!mRot->start(newargs)) {
+            ALOGE("%s failed start rot", __FUNCTION__);
+            return false;
+        }
+
+        // if geom is different, we need to prepare a new rot buffers.
+        // remap on demand when the current orientation is 90,180, etc.
+        // and the prev orientation was 0. It means we go from orient
+        if(!mRot->remap(utils::ROT_NUM_BUFS, newargs)) {
+            ALOGE("%s Error in remapping", __FUNCTION__);
+        }
+    }
+
+    // needed for setSource
+    mOrient = args.orientation;
+
+    // cache last whf from gralloc hnd
+    mOvBufInfo = args.whf;
+
+    // orign impl is returning false here
+    // because they will close the overlay and reopen it.
+    // New design would not do that.
+    return true;
+}
+
+bool Ctrl::setPosition(const utils::Dim& dim)
+{
+    if(!dim.check(mInfo.mFBWidth, mInfo.mFBHeight)) {
+        ALOGE("Ctrl setPosition error in dim");
+        dim.dump();
+        return false;
+    }
+
+    if(!mMdp.setPosition(dim, mInfo.mFBWidth, mInfo.mFBHeight)) {
+        ALOGE("Ctrl failed MDP setPosition");
+        return false;
+    }
+    return true;
+}
+
+bool Ctrl::setParameter(const utils::Params& p)
+{
+    if (utils::OVERLAY_TRANSFORM == p.param &&
+            p.value == mMdp.getUserData()) {
+        // nothing to do here
+        return true;
+    }
+
+    utils::eTransform trns = static_cast<utils::eTransform>(p.value);
+    switch (p.param) {
+        case utils::OVERLAY_DITHER:
+            // nothing here today
+            ALOGE("Ctrl setParameter OVERLAY_DITHER not impl");
+            return true;
+        case utils::OVERLAY_TRANSFORM:
+            if(!mRot->overlayTransform(mMdp, trns)) {
+                ALOGE("Ctrl setParameter failed Rot overlayTransform");
+                return false;
+            }
+            break;
+        default:
+            ALOGE("Ctrl setParameter unknown param %d", p.param);
+            return false;
+    }
+    return true;
+}
+
+bool Ctrl::setCrop(const utils::Dim& d)
+{
+    // FIXME check channel validity
+    if(!mMdp.setCrop(d)) {
+        ALOGE("Data setCrop failed in MDP setCrop");
+        return false;
+    }
+    mCrop = d;
+    return true;
+}
+
+utils::Dim Ctrl::getAspectRatio(const utils::Whf& whf) const
+{
+    utils::Whf inWhf(whf.w, whf.h, mMdp.getSrcWhf().format);
+    utils::Whf tmpwhf(inWhf);
+    uint32_t fbWidth  = mInfo.mFBWidth;
+    uint32_t fbHeight = mInfo.mFBHeight;
+
+    /* Calculate the width and height if it is YUV TILE format*/
+    if (inWhf.format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
+        tmpwhf.w = whf.w - (utils::alignup(whf.w, 64) - whf.w);
+        tmpwhf.h = whf.h - (utils::alignup(whf.h, 32) - whf.h);
+    }
+    if (inWhf.w * fbHeight > fbWidth * inWhf.h) {
+        inWhf.h = fbWidth * inWhf.h / inWhf.w;
+        utils::even_out(inWhf.h);
+        inWhf.w = fbWidth;
+    } else if (inWhf.w * fbHeight < fbWidth * inWhf.h) {
+        inWhf.w = fbHeight * inWhf.w / inWhf.h;
+        utils::even_out(inWhf.w);
+        inWhf.h = fbHeight;
+    } else {
+        inWhf.w = fbWidth;
+        inWhf.h = fbHeight;
+    }
+    /* Scaling of upto a max of 8 times supported */
+    if (inWhf.w > (tmpwhf.w * utils::HW_OV_MAGNIFICATION_LIMIT)){
+        inWhf.w = utils::HW_OV_MAGNIFICATION_LIMIT * tmpwhf.w;
+    }
+    if(inWhf.h > (tmpwhf.h * utils::HW_OV_MAGNIFICATION_LIMIT)) {
+        inWhf.h = utils::HW_OV_MAGNIFICATION_LIMIT * tmpwhf.h;
+    }
+    if (inWhf.w > fbWidth) inWhf.w = fbWidth;
+    if (inWhf.h > fbHeight) inWhf.h = fbHeight;
+
+    char value[PROPERTY_VALUE_MAX];
+    property_get("hw.actionsafe.width", value, "0");
+    float asWidth = atof(value);
+    property_get("hw.actionsafe.height", value, "0");
+    float asHeight = atof(value);
+    inWhf.w = inWhf.w * (1.0f - asWidth / 100.0f);
+    inWhf.h = inWhf.h * (1.0f - asHeight / 100.0f);
+
+    uint32_t x = (fbWidth - inWhf.w) / 2.0;
+    uint32_t y = (fbHeight - inWhf.h) / 2.0;
+    return utils::Dim(x, y, inWhf.w, inWhf.h);
+}
+
+utils::FrameBufferInfo* utils::FrameBufferInfo::sFBInfoInstance = 0;
+
+// This function gets the destination position for external display
+// based on the position and aspect ratio of the primary
+utils::Dim Ctrl::getAspectRatio(const utils::Dim& dim) const {
+    float priWidth  = utils::FrameBufferInfo::getInstance()->getWidth();
+    float priHeight = utils::FrameBufferInfo::getInstance()->getHeight();
+    float fbWidth = mInfo.mFBWidth;
+    float fbHeight = mInfo.mFBHeight;
+    float wRatio = 1.0;
+    float hRatio = 1.0;
+    float xRatio = 1.0;
+    float yRatio = 1.0;
+    utils::Dim inDim(dim);
+
+    int xPos = 0;
+    int yPos = 0;
+    int tmp = 0;
+    utils::Dim tmpDim;
+    switch(inDim.o) {
+        case MDP_ROT_NOP:
+        case MDP_ROT_180:
+            {
+                utils::Whf whf((uint32_t) priWidth, (uint32_t) priHeight, 0);
+                tmpDim = getAspectRatio(whf);
+                xPos = tmpDim.x;
+                yPos = tmpDim.y;
+                fbWidth = tmpDim.w;
+                fbHeight = tmpDim.h;
+
+                if (inDim.o == MDP_ROT_180) {
+                    inDim.x = priWidth - (inDim.x + inDim.w);
+                    inDim.y = priHeight - (inDim.y + inDim.h);
+                }
+                break;
+            }
+        case MDP_ROT_90:
+        case MDP_ROT_270:
+            {
+                if(inDim.o == MDP_ROT_90) {
+                    tmp = inDim.y;
+                    inDim.y = priWidth - (inDim.x + inDim.w);
+                    inDim.x = tmp;
+                }
+                else if (inDim.o == MDP_ROT_270) {
+                    tmp = inDim.x;
+                    inDim.x = priHeight - (inDim.y + inDim.h);
+                    inDim.y = tmp;
+                }
+
+                // Swap the destination width/height
+                utils::swapWidthHeight(inDim.w, inDim.h);
+                // Swap width/height for primary
+                utils::swapWidthHeight(priWidth, priHeight);
+                utils::Whf whf((uint32_t) priWidth, (uint32_t) priHeight, 0);
+                tmpDim = getAspectRatio(whf);
+                xPos = tmpDim.x;
+                yPos = tmpDim.y;
+                fbWidth = tmpDim.w;
+                fbHeight = tmpDim.h;
+                break;
+            }
+        default:
+            ALOGE("%s: Unknown Orientation", __FUNCTION__);
+            break;
+    }
+
+    // Calculate the position
+    xRatio = inDim.x/priWidth;
+    yRatio = inDim.y/priHeight;
+    wRatio = inDim.w/priWidth;
+    hRatio = inDim.h/priHeight;
+
+    return utils::Dim((xRatio * fbWidth) + xPos,   // x
+            (yRatio * fbHeight) + yPos,  // y
+            (wRatio * fbWidth),          // width
+            (hRatio * fbHeight),         // height
+            inDim.o);                    // orientation
+}
+
+void Ctrl::dump() const {
+    ALOGE("== Dump Ctrl start ==");
+    ALOGE("orient=%d", mOrient);
+    mInfo.dump("mInfo");
+    mMdp.dump();
+    mRot->dump();
+    ALOGE("== Dump Ctrl end ==");
+}
+
+} // overlay
diff --git a/liboverlay/overlayCtrlData.h b/liboverlay/overlayCtrlData.h
new file mode 100644
index 0000000..fbd701a
--- /dev/null
+++ b/liboverlay/overlayCtrlData.h
@@ -0,0 +1,365 @@
+/*
+* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef OVERLAY_CTRLDATA_H
+#define OVERLAY_CTRLDATA_H
+
+#include "overlayUtils.h"
+#include "overlayMdp.h"
+#include "gralloc_priv.h" // INTERLACE_MASK
+
+namespace ovutils = overlay::utils;
+
+namespace overlay {
+
+// FIXME make int to be uint32 whenever possible
+
+class RotatorBase;
+
+/*
+* FIXME do we want rot to be template parameter?
+* It's already using inheritance...
+*
+* Sequence to use:
+* open
+* start
+* setXXX
+* close
+*
+* Can call setRot anytime to replace rotator on-the-fly
+* */
+class Ctrl : utils::NoCopy {
+public:
+
+    /* ctor */
+    explicit Ctrl();
+
+    /* dtor close */
+    ~Ctrl();
+
+    /* should open devices? or start()? */
+    bool open(uint32_t fbnum, RotatorBase* rot);
+
+    /* close underlying mdp */
+    bool close();
+
+    /* Invoke methods for opening underlying devices
+     * flags - PIPE SHARED
+     * wait - WAIT, NO_WAIT */
+    bool start(const utils::PipeArgs& args);
+
+    /* Dynamically set rotator*/
+    void setRot(RotatorBase* rot);
+
+    /* set mdp posision using dim */
+    bool setPosition(const utils::Dim& dim);
+
+    /* set param using Params (param,value pair)  */
+    bool setParameter(const utils::Params& p);
+
+    /* set source using whf, orient and wait flag */
+    bool setSource(const utils::PipeArgs& args);
+
+    /* set crop info and pass it down to mdp */
+    bool setCrop(const utils::Dim& d);
+
+    /* mdp set overlay/commit changes */
+    bool commit();
+
+    /* ctrl id */
+    int  getId() const;
+    /* ctrl fd */
+    int  getFd() const;
+    bool getRotSessId(int& id) const;
+    utils::Dim getAspectRatio(const utils::Whf& whf) const;
+    utils::Dim getAspectRatio(const utils::Dim& dim) const;
+
+    /* access for screen info */
+    utils::ScreenInfo getScreenInfo() const;
+
+    /* retrieve cached crop data */
+    utils::Dim getCrop() const;
+
+    /* dump the state of the object */
+    void dump() const;
+
+private:
+    /* Retrieve screen info from underlying mdp */
+    bool getScreenInfo(utils::ScreenInfo& info);
+
+    /* calls underlying mdp set info */
+    bool setInfo(const utils::PipeArgs& args);
+
+    /* given whf, update src */
+    void updateSource(RotatorBase* r,
+            const utils::PipeArgs& args,
+            utils::ScreenInfo& info);
+
+    // mdp ctrl struct(info e.g.)
+    MdpCtrl mMdp;
+
+    // Rotator
+    RotatorBase* mRot;
+
+    /* Cache cropped value */
+    utils::Dim mCrop;
+
+    /* Screen info */
+    utils::ScreenInfo mInfo;
+
+    /* orientation cache FIXME */
+    utils::eTransform mOrient;
+
+    /* Cache last known whfz.
+     * That would help us compare to a previous
+     * source that was submitted */
+    utils::Whf mOvBufInfo;
+};
+
+
+/*
+* MDP = DataMdp, ROT = CtrlMdp usually since Rotator<>
+* is instansiated with Ctrl data structure.
+* */
+class Data : utils::NoCopy {
+public:
+    /* init, reset */
+    explicit Data();
+
+    /* calls close */
+    ~Data();
+
+    /* should open devices? or start()? */
+    bool open(uint32_t fbnum, RotatorBase* rot);
+
+    /* calls underlying mdp close */
+    bool close();
+
+    /* set the rotator */
+    void setRot(RotatorBase* rot);
+
+    /* set memory id in the mdp struct */
+    void setMemoryId(int id);
+
+    /* set overlay id in the mdp struct */
+    void setId(int id);
+
+    /* get overlay id in the mdp struct */
+    int getId() const;
+
+    /* queue buffer to the overlay */
+    bool queueBuffer(uint32_t offset);
+
+    /* wait for vsync to be done */
+    bool waitForVsync();
+
+    /* sump the state of the obj */
+    void dump() const;
+private:
+    /* play wrapper */
+    bool play();
+
+    /* playWait wrapper */
+    bool playWait();
+
+    // mdp data struct
+    MdpData mMdp;
+
+    // Rotator
+    RotatorBase* mRot;
+};
+
+/* This class just creates a Ctrl Data pair to be used by a pipe.
+ * Although this was legacy design, this separation still makes sense, since we
+ * need to use the Ctrl channel in hwc_prepare (i.e config stage) and Data
+ * channel in hwc_set (i.e draw stage)
+ */
+struct CtrlData {
+    Ctrl ctrl;
+    Data data;
+};
+
+//-------------Inlines-------------------------------
+
+inline Ctrl::Ctrl() : mRot(0), mOrient(utils::OVERLAY_TRANSFORM_0) {
+    mMdp.reset();
+}
+
+inline Ctrl::~Ctrl() {
+    close();
+}
+
+inline bool Ctrl::close() {
+    // do not close the rotator
+    if(!mMdp.close())
+        return false;
+    return true;
+}
+
+inline bool Ctrl::commit() {
+    if(!mMdp.set()) {
+        ALOGE("Ctrl commit failed set overlay");
+        return false;
+    }
+    return true;
+}
+
+inline bool Ctrl::getScreenInfo(utils::ScreenInfo& info) {
+    if(!mMdp.getScreenInfo(info)){
+        ALOGE("Ctrl failed to get screen info");
+        return false;
+    }
+    return true;
+}
+
+inline bool Ctrl::setInfo(const utils::PipeArgs& args)
+{
+    // FIXME set flags, zorder and wait separtly
+    if(!mMdp.setInfo(mRot, args, mInfo)){
+        ALOGE("Ctrl failed to setInfo wait=%d mdpflags=%d "
+                "zorder=%d", args.wait, args.mdpFlags, args.zorder);
+        return false;
+    }
+    return true;
+}
+
+inline int Ctrl::getId() const {
+    // FIXME check channel up?
+    return mMdp.getId();
+}
+
+inline int Ctrl::getFd() const {
+    // FIXME check channel up?
+    return mMdp.getFd();
+}
+
+inline bool Ctrl::getRotSessId(int& id) const {
+    // FIXME check channel up?
+    // should be -1 in case of no rot session active
+    id = mRot->getSessId();
+    return true;
+}
+
+inline utils::ScreenInfo Ctrl::getScreenInfo() const {
+    return mInfo;
+}
+
+inline utils::Dim Ctrl::getCrop() const {
+    return mCrop;
+}
+
+
+
+inline Data::Data() : mRot(0) {
+    mMdp.reset();
+}
+
+inline Data::~Data() { close(); }
+
+inline void Data::setRot(RotatorBase* rot) { mRot = rot; }
+
+inline void Data::setMemoryId(int id) { mMdp.setMemoryId(id); }
+
+// really a reqid
+inline void Data::setId(int id) { mMdp.setId(id); }
+
+inline int Data::getId() const { return mMdp.getId(); }
+
+inline bool Data::open(uint32_t fbnum,
+        RotatorBase* rot) {
+    if(!mMdp.open(fbnum)) {
+        ALOGE("Data cannot open mdp");
+        return false;
+    }
+
+    OVASSERT(rot, "rot is null");
+    mRot = rot;
+
+    // rotator should be already opened here
+    return true;
+}
+
+inline bool Data::close() {
+    if(!mMdp.close()) {
+        ALOGE("Data close failed");
+        return false;
+    }
+    return true;
+}
+
+inline bool Data::queueBuffer(uint32_t offset) {
+    // FIXME asserts on state validity
+
+    mMdp.setOffset(offset);
+    mRot->setRotDataSrcMemId(mMdp.getMemoryId());
+    // will play if succeeded
+    if(!mRot->prepareQueueBuf(offset)) {
+        ALOGE("Data failed to prepareQueueBuf");
+        return false;
+    }
+    // Play can go either from mdp or rot
+    if(!this->play()){
+        ALOGE("Data error in MDP/ROT play");
+        return false;
+    }
+
+    return true;
+}
+
+inline bool Data::waitForVsync() {
+
+    // Call mdp playWait
+    if(!this->playWait()){
+        ALOGE("Error in MDP playWait");
+        return false;
+    }
+
+    return true;
+}
+
+inline bool Data::play() {
+    int fd = mMdp.getFd();
+    return mRot->enabled() ? mRot->play(fd) : mMdp.play();
+}
+
+inline bool Data::playWait() {
+    return mMdp.playWait();
+}
+
+inline void Data::dump() const {
+    ALOGE("== Dump Data MDP start ==");
+    mMdp.dump();
+    mRot->dump();
+    ALOGE("== Dump Data MDP end ==");
+}
+
+
+} // overlay
+
+#endif
diff --git a/liboverlay/overlayImpl.h b/liboverlay/overlayImpl.h
new file mode 100644
index 0000000..5f999f2
--- /dev/null
+++ b/liboverlay/overlayImpl.h
@@ -0,0 +1,742 @@
+/*
+* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef OVERLAY_IMPL_H
+#define OVERLAY_IMPL_H
+
+#include "overlayUtils.h"
+#include "overlayRotator.h"
+
+// FIXME make int to be uint32 whenever possible
+
+namespace overlay {
+
+// Interface only. No member, no definiton (except ~ which can
+// also be =0 with impl in cpp)
+class OverlayImplBase {
+public:
+    /* empty dtor. can be =0 with cpp impl*/
+    virtual ~OverlayImplBase() {}
+
+    /* Open pipe/rot for one dest */
+    virtual bool openPipe(RotatorBase* rot, utils::eDest dest) = 0;
+
+    /* Close pipe/rot for all specified dest */
+    virtual bool closePipe(utils::eDest dest) = 0;
+
+    /* Copy specified pipe/rot from ov passed in (used by state machine only) */
+    virtual bool copyOvPipe(OverlayImplBase* ov, utils::eDest dest) = 0;
+
+    /* TODO open func customized for RGBx pipes */
+
+    /* Open all pipes
+     * To open just one pipe, use openPipe()
+     * */
+    virtual bool open(RotatorBase* rot0,
+            RotatorBase* rot1,
+            RotatorBase* rot2) = 0;
+
+    /* Close all pipes
+     * To close just one pipe, use closePipe()
+     * */
+    virtual bool close() = 0;
+
+    /*
+     * Commit changes to the overlay
+     * */
+    virtual bool commit(utils::eDest dest = utils::OV_PIPE_ALL) = 0;
+
+    /* Queue buffer with offset*/
+    virtual bool queueBuffer(uint32_t offset,
+            utils::eDest dest = utils::OV_PIPE_ALL) = 0;
+
+    /* For RGBx pipes, dequeue buffer (that is fb chunk)*/
+    virtual bool dequeueBuffer(void*& buf,
+            utils::eDest dest = utils::OV_PIPE_ALL) = 0;
+
+    /* Wait for vsync to be done on dest */
+    virtual bool waitForVsync(utils::eDest dest = utils::OV_PIPE1) = 0;
+
+    /* Crop existing destination using Dim coordinates */
+    virtual bool setCrop(const utils::Dim& d,
+            utils::eDest dest = utils::OV_PIPE_ALL) = 0;
+
+    /* Set new position using Dim */
+    virtual bool setPosition(const utils::Dim& dim,
+            utils::eDest dest = utils::OV_PIPE_ALL) = 0;
+
+    /* Set parameters - usually needed for Rotator, but would
+     * be passed down the stack as well */
+    virtual bool setParameter(const utils::Params& param,
+            utils::eDest dest = utils::OV_PIPE_ALL) = 0;
+
+    /* Set new source including orientation */
+    virtual bool setSource(const utils::PipeArgs[utils::MAX_PIPES],
+            utils::eDest dest = utils::OV_PIPE_ALL) = 0;
+
+    /* set memory id to the underlying pipes */
+    virtual void setMemoryId(int id, utils::eDest dest = utils::OV_PIPE_ALL) = 0;
+
+    /* Get the overlay pipe type */
+    virtual utils::eOverlayPipeType getOvPipeType(utils::eDest dest) const = 0;
+
+    /* Dump underlying state */
+    virtual void dump() const = 0;
+};
+
+class NullPipe {
+public:
+    /* TODO open func customized for RGBx pipes */
+    bool open(RotatorBase* rot);
+    bool close();
+    bool start(const utils::PipeArgs& args);
+    bool commit();
+    bool setCrop(const utils::Dim& d);
+    bool setPosition(const utils::Dim& dim);
+    bool setParameter(const utils::Params& param);
+    bool setSource(const utils::PipeArgs& args);
+    bool queueBuffer(uint32_t offset);
+    bool dequeueBuffer(void*& buf);
+    bool waitForVsync();
+    void setMemoryId(int id);
+    utils::PipeArgs getArgs() const;
+    utils::eOverlayPipeType getOvPipeType() const;
+    void dump() const;
+};
+
+/*
+* Each pipe is not specific to a display (primary/external). The order in the
+* template params, will setup the priorities of the pipes.
+* */
+template <class P0, class P1=NullPipe, class P2=NullPipe>
+class OverlayImpl : public OverlayImplBase {
+public:
+    typedef P0 pipe0;
+    typedef P1 pipe1;
+    typedef P2 pipe2;
+
+    /* ctor */
+    OverlayImpl();
+    OverlayImpl(P0* p0, P1* p1, P2* p2);
+
+    /*
+     * Comments of the below functions are the same as the one
+     * in OverlayImplBase.
+     * */
+    virtual ~OverlayImpl();
+
+    virtual bool openPipe(RotatorBase* rot, utils::eDest dest);
+    virtual bool closePipe(utils::eDest dest);
+    virtual bool copyOvPipe(OverlayImplBase* ov, utils::eDest dest);
+
+    /* TODO open func customized for RGBx pipes */
+    virtual bool open(RotatorBase* rot0,
+            RotatorBase* rot1,
+            RotatorBase* rot2);
+    virtual bool close();
+    virtual bool commit(utils::eDest dest = utils::OV_PIPE_ALL);
+    virtual bool setCrop(const utils::Dim& d,
+            utils::eDest dest = utils::OV_PIPE_ALL);
+    virtual bool setPosition(const utils::Dim& dim,
+            utils::eDest dest = utils::OV_PIPE_ALL);
+    virtual bool setParameter(const utils::Params& param,
+            utils::eDest dest = utils::OV_PIPE_ALL);
+    virtual bool setSource(const utils::PipeArgs[utils::MAX_PIPES],
+            utils::eDest dest = utils::OV_PIPE_ALL);
+    virtual bool queueBuffer(uint32_t offset,
+            utils::eDest dest = utils::OV_PIPE_ALL);
+    virtual bool dequeueBuffer(void*& buf,
+            utils::eDest dest = utils::OV_PIPE_ALL);
+    virtual bool waitForVsync(utils::eDest dest = utils::OV_PIPE1);
+    virtual void setMemoryId(int id, utils::eDest dest = utils::OV_PIPE_ALL);
+    virtual utils::eOverlayPipeType getOvPipeType(utils::eDest dest) const;
+    virtual void dump() const;
+
+private:
+    P0* mPipe0;
+    P1* mPipe1;
+    P2* mPipe2;
+    // More Px here in the future as needed
+
+    /*  */
+
+    /* Each Px has it's own Rotator here.
+     * will pass rotator to the lower layer in stack
+     * but only overlay is allowed to control the lifetime
+     * of the rotator instace */
+    RotatorBase* mRotP0;
+    RotatorBase* mRotP1;
+    RotatorBase* mRotP2;
+};
+
+
+
+
+
+//-----------Inlines and Template defn---------------------------------
+
+template <class P0, class P1, class P2>
+OverlayImpl<P0, P1, P2>::OverlayImpl() :
+    mPipe0(new P0), mPipe1(new P1), mPipe2(new P2),
+    mRotP0(0), mRotP1(0), mRotP2(0)
+{}
+
+template <class P0, class P1, class P2>
+OverlayImpl<P0, P1, P2>::OverlayImpl(P0* p0, P1* p1, P2* p2) :
+    mPipe0(p0), mPipe1(p1), mPipe2(p2),
+    mRotP0(0), mRotP1(0), mRotP2(0)
+{}
+
+template <class P0, class P1, class P2>
+OverlayImpl<P0, P1, P2>::~OverlayImpl()
+{
+    // no op in the meantime. needed to be clean
+    // since state machine will do delete. so we
+    // do not want to close/delete pipes here
+}
+
+/* Open only one pipe/rot pair per call */
+template <class P0, class P1, class P2>
+bool OverlayImpl<P0, P1, P2>::openPipe(RotatorBase* rot, utils::eDest dest)
+{
+    OVASSERT(rot, "%s: OverlayImpl rot is null", __FUNCTION__);
+    OVASSERT(utils::isValidDest(dest), "%s: OverlayImpl invalid dest=%d",
+            __FUNCTION__, dest);
+
+    // Need to down case rotator to mdp one.
+    // we assume p0/p1/p2/px all use the _same_ underlying mdp structure.
+    // FIXME STATIC_ASSERT here
+
+    bool ret = true;
+
+    if (utils::OV_PIPE0 & dest) {
+        OVASSERT(mPipe0, "%s: OverlayImpl pipe0 is null", __FUNCTION__);
+        ALOGE_IF(DEBUG_OVERLAY, "Open pipe0");
+        ret = mPipe0->open(rot);
+        mRotP0 = rot;
+        if(!ret) {
+            ALOGE("%s: OverlayImpl pipe0 failed to open", __FUNCTION__);
+        }
+        return ret;
+    }
+
+    if (utils::OV_PIPE1 & dest) {
+        OVASSERT(mPipe1, "%s: OverlayImpl pipe1 is null", __FUNCTION__);
+        ALOGE_IF(DEBUG_OVERLAY, "Open pipe1");
+        ret = mPipe1->open(rot);
+        mRotP1 = rot;
+        if(!ret) {
+            ALOGE("%s: OverlayImpl pipe1 failed to open", __FUNCTION__);
+        }
+        return ret;
+    }
+
+    if (utils::OV_PIPE2 & dest) {
+        OVASSERT(mPipe2, "%s: OverlayImpl pipe2 is null", __FUNCTION__);
+        ALOGE_IF(DEBUG_OVERLAY, "Open pipe2");
+        ret = mPipe2->open(rot);
+        mRotP2 = rot;
+        if(!ret) {
+            ALOGE("%s: OverlayImpl pipe2 failed to open", __FUNCTION__);
+        }
+        return ret;
+    }
+
+    // Should have returned by here
+    return false;
+}
+
+/* Close pipe/rot for all specified dest */
+template <class P0, class P1, class P2>
+bool OverlayImpl<P0, P1, P2>::closePipe(utils::eDest dest)
+{
+    OVASSERT(utils::isValidDest(dest), "%s: OverlayImpl invalid dest=%d",
+            __FUNCTION__, dest);
+
+    if (utils::OV_PIPE0 & dest) {
+        // Close pipe0
+        OVASSERT(mPipe0, "%s: OverlayImpl pipe0 is null", __FUNCTION__);
+        ALOGE_IF(DEBUG_OVERLAY, "Close pipe0");
+        if (!mPipe0->close()) {
+            ALOGE("%s: OverlayImpl failed to close pipe0", __FUNCTION__);
+            return false;
+        }
+        delete mPipe0;
+        mPipe0 = 0;
+
+        // Close the rotator for pipe0
+        OVASSERT(mRotP0, "%s: OverlayImpl rot0 is null", __FUNCTION__);
+        if (!mRotP0->close()) {
+            ALOGE("%s: OverlayImpl failed to close rot for pipe0", __FUNCTION__);
+        }
+        delete mRotP0;
+        mRotP0 = 0;
+    }
+
+    if (utils::OV_PIPE1 & dest) {
+        // Close pipe1
+        OVASSERT(mPipe1, "%s: OverlayImpl pipe1 is null", __FUNCTION__);
+        ALOGE_IF(DEBUG_OVERLAY, "Close pipe1");
+        if (!mPipe1->close()) {
+            ALOGE("%s: OverlayImpl failed to close pipe1", __FUNCTION__);
+            return false;
+        }
+        delete mPipe1;
+        mPipe1 = 0;
+
+        // Close the rotator for pipe1
+        OVASSERT(mRotP1, "%s: OverlayImpl rot1 is null", __FUNCTION__);
+        if (!mRotP1->close()) {
+            ALOGE("%s: OverlayImpl failed to close rot for pipe1", __FUNCTION__);
+        }
+        delete mRotP1;
+        mRotP1 = 0;
+    }
+
+    if (utils::OV_PIPE2 & dest) {
+        // Close pipe2
+        OVASSERT(mPipe2, "%s: OverlayImpl pipe2 is null", __FUNCTION__);
+        ALOGE_IF(DEBUG_OVERLAY, "Close pipe2");
+        if (!mPipe2->close()) {
+            ALOGE("%s: OverlayImpl failed to close pipe2", __FUNCTION__);
+            return false;
+        }
+        delete mPipe2;
+        mPipe2 = 0;
+
+        // Close the rotator for pipe2
+        OVASSERT(mRotP2, "%s: OverlayImpl rot2 is null", __FUNCTION__);
+        if (!mRotP2->close()) {
+            ALOGE("%s: OverlayImpl failed to close rot for pipe2", __FUNCTION__);
+        }
+        delete mRotP2;
+        mRotP2 = 0;
+    }
+
+    return true;
+}
+
+/* Copy pipe/rot from ov for all specified dest */
+template <class P0, class P1, class P2>
+bool OverlayImpl<P0, P1, P2>::copyOvPipe(OverlayImplBase* ov,
+        utils::eDest dest)
+{
+    OVASSERT(ov, "%s: OverlayImpl ov is null", __FUNCTION__);
+    OVASSERT(utils::isValidDest(dest), "%s: OverlayImpl invalid dest=%d",
+            __FUNCTION__, dest);
+
+    OverlayImpl<P0, P1, P2>* ovimpl = static_cast<OverlayImpl<P0, P1, P2>*>(ov);
+
+    if (utils::OV_PIPE0 & dest) {
+        mPipe0 = ovimpl->mPipe0;
+        mRotP0 = ovimpl->mRotP0;
+    }
+
+    if (utils::OV_PIPE1 & dest) {
+        mPipe1 = ovimpl->mPipe1;
+        mRotP1 = ovimpl->mRotP1;
+    }
+
+    if (utils::OV_PIPE2 & dest) {
+        mPipe2 = ovimpl->mPipe2;
+        mRotP2 = ovimpl->mRotP2;
+    }
+
+    return true;
+}
+
+/* TODO open func customized for RGBx pipes */
+
+/* Open all pipes/rot */
+template <class P0, class P1, class P2>
+bool OverlayImpl<P0, P1, P2>::open(RotatorBase* rot0,
+        RotatorBase* rot1,
+        RotatorBase* rot2)
+{
+    if (!this->openPipe(rot0, utils::OV_PIPE0)) {
+        if (!this->close()) {
+            ALOGE("%s: failed to close at least one pipe", __FUNCTION__);
+        }
+        return false;
+    }
+
+    if (!this->openPipe(rot1, utils::OV_PIPE1)) {
+        if (!this->close()) {
+            ALOGE("%s: failed to close at least one pipe", __FUNCTION__);
+        }
+        return false;
+    }
+
+    if (!this->openPipe(rot2, utils::OV_PIPE2)) {
+        if (!this->close()) {
+            ALOGE("%s: failed to close at least one pipe", __FUNCTION__);
+        }
+        return false;
+    }
+
+    return true;
+}
+
+/* Close all pipes/rot */
+template <class P0, class P1, class P2>
+bool OverlayImpl<P0, P1, P2>::close()
+{
+    if (!this->closePipe(utils::OV_PIPE_ALL)) {
+        return false;
+    }
+
+    return true;
+}
+
+template <class P0, class P1, class P2>
+bool OverlayImpl<P0, P1, P2>::commit(utils::eDest dest)
+{
+    OVASSERT(mPipe0 && mPipe1 && mPipe2,
+            "%s: Pipes are null p0=%p p1=%p p2=%p",
+            __FUNCTION__, mPipe0, mPipe1, mPipe2);
+
+    if (utils::OV_PIPE0 & dest) {
+        if(!mPipe0->commit()) {
+            ALOGE("OverlayImpl p0 failed to commit");
+            return false;
+        }
+    }
+
+    if (utils::OV_PIPE1 & dest) {
+        if(!mPipe1->commit()) {
+            ALOGE("OverlayImpl p1 failed to commit");
+            return false;
+        }
+    }
+
+    if (utils::OV_PIPE2 & dest) {
+        if(!mPipe2->commit()) {
+            ALOGE("OverlayImpl p2 failed to commit");
+            return false;
+        }
+    }
+
+    return true;
+}
+
+template <class P0, class P1, class P2>
+bool OverlayImpl<P0, P1, P2>::setCrop(const utils::Dim& d, utils::eDest dest)
+{
+    OVASSERT(mPipe0 && mPipe1 && mPipe2,
+            "%s: Pipes are null p0=%p p1=%p p2=%p",
+            __FUNCTION__, mPipe0, mPipe1, mPipe2);
+
+    if (utils::OV_PIPE0 & dest) {
+        if(!mPipe0->setCrop(d)) {
+            ALOGE("OverlayImpl p0 failed to crop");
+            return false;
+        }
+    }
+
+    if (utils::OV_PIPE1 & dest) {
+        if(!mPipe1->setCrop(d)) {
+            ALOGE("OverlayImpl p1 failed to crop");
+            return false;
+        }
+    }
+
+    if (utils::OV_PIPE2 & dest) {
+        if(!mPipe2->setCrop(d)) {
+            ALOGE("OverlayImpl p2 failed to crop");
+            return false;
+        }
+    }
+
+    return true;
+}
+
+template <class P0, class P1, class P2>
+bool OverlayImpl<P0, P1, P2>::setPosition(const utils::Dim& d,
+        utils::eDest dest)
+{
+    OVASSERT(mPipe0 && mPipe1 && mPipe2,
+            "%s: Pipes are null p0=%p p1=%p p2=%p",
+            __FUNCTION__, mPipe0, mPipe1, mPipe2);
+
+    if (utils::OV_PIPE0 & dest) {
+        if(!mPipe0->setPosition(d)) {
+            ALOGE("OverlayImpl p0 failed to setpos");
+            return false;
+        }
+    }
+
+    if (utils::OV_PIPE1 & dest) {
+        if(!mPipe1->setPosition(d)) {
+            ALOGE("OverlayImpl p1 failed to setpos");
+            return false;
+        }
+    }
+
+    if (utils::OV_PIPE2 & dest) {
+        if(!mPipe2->setPosition(d)) {
+            ALOGE("OverlayImpl p2 failed to setpos");
+            return false;
+        }
+    }
+
+    return true;
+}
+
+template <class P0, class P1, class P2>
+bool OverlayImpl<P0, P1, P2>::setParameter(const utils::Params& param,
+        utils::eDest dest)
+{
+    OVASSERT(mPipe0 && mPipe1 && mPipe2,
+            "%s: Pipes are null p0=%p p1=%p p2=%p",
+            __FUNCTION__, mPipe0, mPipe1, mPipe2);
+
+    if (utils::OV_PIPE0 & dest) {
+        if(!mPipe0->setParameter(param)) {
+            ALOGE("OverlayImpl p0 failed to setparam");
+            return false;
+        }
+    }
+
+    if (utils::OV_PIPE1 & dest) {
+        if(!mPipe1->setParameter(param)) {
+            ALOGE("OverlayImpl p1 failed to setparam");
+            return false;
+        }
+    }
+
+    if (utils::OV_PIPE2 & dest) {
+        if(!mPipe2->setParameter(param)) {
+            ALOGE("OverlayImpl p2 failed to setparam");
+            return false;
+        }
+    }
+
+    return true;
+}
+
+template <class P0, class P1, class P2>
+bool OverlayImpl<P0, P1, P2>::setSource(const utils::PipeArgs args[utils::MAX_PIPES],
+        utils::eDest dest)
+{
+    OVASSERT(mPipe0 && mPipe1 && mPipe2,
+            "%s: Pipes are null p0=%p p1=%p p2=%p",
+            __FUNCTION__, mPipe0, mPipe1, mPipe2);
+
+    if (utils::OV_PIPE0 & dest) {
+        if(!mPipe0->setSource(args[0])) {
+            ALOGE("OverlayImpl p0 failed to setsrc");
+            return false;
+        }
+    }
+
+    if (utils::OV_PIPE1 & dest) {
+        if(!mPipe1->setSource(args[1])) {
+            ALOGE("OverlayImpl p1 failed to setsrc");
+            return false;
+        }
+    }
+
+    if (utils::OV_PIPE2 & dest) {
+        if(!mPipe2->setSource(args[2])) {
+            ALOGE("OverlayImpl p2 failed to setsrc");
+            return false;
+        }
+    }
+
+    return true;
+}
+
+template <class P0, class P1, class P2>
+bool OverlayImpl<P0, P1, P2>::queueBuffer(uint32_t offset, utils::eDest dest)
+{
+    OVASSERT(mPipe0 && mPipe1 && mPipe2,
+            "%s: Pipes are null p0=%p p1=%p p2=%p",
+            __FUNCTION__, mPipe0, mPipe1, mPipe2);
+
+    if (utils::OV_PIPE0 & dest) {
+        if(!mPipe0->queueBuffer(offset)) {
+            ALOGE("OverlayImpl p0 failed to queueBuffer");
+            return false;
+        }
+    }
+
+    if (utils::OV_PIPE1 & dest) {
+        if(!mPipe1->queueBuffer(offset)) {
+            ALOGE("OverlayImpl p1 failed to queueBuffer");
+            return false;
+        }
+    }
+
+    if (utils::OV_PIPE2 & dest) {
+        if(!mPipe2->queueBuffer(offset)) {
+            ALOGE("OverlayImpl p2 failed to queueBuffer");
+            return false;
+        }
+    }
+
+    return true;
+}
+
+template <class P0, class P1, class P2>
+bool OverlayImpl<P0, P1, P2>::dequeueBuffer(void*& buf, utils::eDest dest)
+{
+    OVASSERT(mPipe0 && mPipe1 && mPipe2,
+            "%s: Pipes are null p0=%p p1=%p p2=%p",
+            __FUNCTION__, mPipe0, mPipe1, mPipe2);
+
+    if (utils::OV_PIPE0 & dest) {
+        if(!mPipe0->dequeueBuffer(buf)) {
+            ALOGE("OverlayImpl p0 failed to dequeueBuffer");
+            return false;
+        }
+    }
+
+    if (utils::OV_PIPE1 & dest) {
+        if(!mPipe1->dequeueBuffer(buf)) {
+            ALOGE("OverlayImpl p1 failed to dequeueBuffer");
+            return false;
+        }
+    }
+
+    if (utils::OV_PIPE2 & dest) {
+        if(!mPipe2->dequeueBuffer(buf)) {
+            ALOGE("OverlayImpl p2 failed to dequeueBuffer");
+            return false;
+        }
+    }
+
+    return true;
+}
+
+template <class P0, class P1, class P2>
+bool OverlayImpl<P0, P1, P2>::waitForVsync(utils::eDest dest)
+{
+    OVASSERT(mPipe0 && mPipe1 && mPipe2,
+            "%s: Pipes are null p0=%p p1=%p p2=%p",
+            __FUNCTION__, mPipe0, mPipe1, mPipe2);
+
+    if (utils::OV_PIPE0 & dest) {
+        if(!mPipe0->waitForVsync()) {
+            ALOGE("OverlayImpl p0 failed to waitForVsync");
+            return false;
+        }
+    }
+
+    if (utils::OV_PIPE1 & dest) {
+        if(!mPipe1->waitForVsync()) {
+            ALOGE("OverlayImpl p1 failed to waitForVsync");
+            return false;
+        }
+    }
+
+    if (utils::OV_PIPE2 & dest) {
+        if(!mPipe2->waitForVsync()) {
+            ALOGE("OverlayImpl p2 failed to waitForVsync");
+            return false;
+        }
+    }
+
+    return true;
+}
+
+template <class P0, class P1, class P2>
+void OverlayImpl<P0, P1, P2>::setMemoryId(int id, utils::eDest dest)
+{
+    OVASSERT(mPipe0 && mPipe1 && mPipe2,
+            "%s: Pipes are null p0=%p p1=%p p2=%p",
+            __FUNCTION__, mPipe0, mPipe1, mPipe2);
+
+    if (utils::OV_PIPE0 & dest) {
+        mPipe0->setMemoryId(id);
+    }
+
+    if (utils::OV_PIPE1 & dest) {
+        mPipe1->setMemoryId(id);
+    }
+
+    if (utils::OV_PIPE2 & dest) {
+        mPipe2->setMemoryId(id);
+    }
+}
+
+template <class P0, class P1, class P2>
+utils::eOverlayPipeType OverlayImpl<P0, P1, P2>::getOvPipeType(utils::eDest dest) const
+{
+    OVASSERT(utils::isValidDest(dest), "%s: OverlayImpl invalid dest=%d",
+            __FUNCTION__, dest);
+
+    if (utils::OV_PIPE0 & dest) {
+        OVASSERT(mPipe0, "%s: OverlayImpl pipe0 is null", __FUNCTION__);
+        return mPipe0->getOvPipeType();
+    }
+
+    if (utils::OV_PIPE1 & dest) {
+        OVASSERT(mPipe1, "%s: OverlayImpl pipe1 is null", __FUNCTION__);
+        return mPipe1->getOvPipeType();
+    }
+
+    if (utils::OV_PIPE2 & dest) {
+        OVASSERT(mPipe2, "%s: OverlayImpl pipe2 is null", __FUNCTION__);
+        return mPipe2->getOvPipeType();
+    }
+
+    // Should never get here
+    return utils::OV_PIPE_TYPE_NULL;
+}
+
+template <class P0, class P1, class P2>
+void OverlayImpl<P0, P1, P2>::dump() const
+{
+    OVASSERT(mPipe0 && mPipe1 && mPipe2,
+            "%s: Pipes are null p0=%p p1=%p p2=%p",
+            __FUNCTION__, mPipe0, mPipe1, mPipe2);
+    ALOGE("== Dump OverlayImpl dump start ROT p0 ==");
+    mRotP0->dump();
+    ALOGE("== Dump OverlayImpl dump end ROT p0 ==");
+    ALOGE("== Dump OverlayImpl dump start ROT p1 ==");
+    mRotP1->dump();
+    ALOGE("== Dump OverlayImpl dump end ROT p1 ==");
+    ALOGE("== Dump OverlayImpl dump start ROT p2 ==");
+    mRotP2->dump();
+    ALOGE("== Dump OverlayImpl dump end ROT p2 ==");
+    ALOGE("== Dump OverlayImpl dump start p0 ==");
+    mPipe0->dump();
+    ALOGE("== Dump OverlayImpl dump end p0 ==");
+    ALOGE("== Dump OverlayImpl dump start p1 ==");
+    mPipe1->dump();
+    ALOGE("== Dump OverlayImpl dump end p1 ==");
+    ALOGE("== Dump OverlayImpl dump start p2 ==");
+    mPipe2->dump();
+    ALOGE("== Dump OverlayImpl dump end p2 ==");
+}
+
+
+} // overlay
+
+#endif // OVERLAY_IMPL_H
diff --git a/liboverlay/overlayLib.cpp b/liboverlay/overlayLib.cpp
deleted file mode 100755
index fe5c3d3..0000000
--- a/liboverlay/overlayLib.cpp
+++ /dev/null
@@ -1,2352 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "overlayLib.h"
-#include "gralloc_priv.h"
-
-#define INTERLACE_MASK 0x80
-#define DEBUG_OVERLAY true
-/* Helper functions */
-static inline size_t ALIGN(size_t x, size_t align) {
-    return (x + align-1) & ~(align-1);
-}
-
-using namespace overlay;
-using android::sp;
-using gralloc::IMemAlloc;
-using gralloc::IonController;
-using gralloc::alloc_data;
-
-#ifdef HDMI_AS_PRIMARY
-bool Overlay::sHDMIAsPrimary = true;
-#else
-bool Overlay::sHDMIAsPrimary = false;
-#endif
-
-template <class Type>
-void swapWidthHeight(Type& width, Type& height) {
-    Type tmp = width;
-    width = height;
-    height = tmp;
-}
-
-int overlay::get_mdp_format(int format) {
-    switch (format) {
-    case HAL_PIXEL_FORMAT_RGBA_8888 :
-        return MDP_RGBA_8888;
-    case HAL_PIXEL_FORMAT_BGRA_8888:
-        return MDP_BGRA_8888;
-    case HAL_PIXEL_FORMAT_RGB_565:
-        return MDP_RGB_565;
-    case HAL_PIXEL_FORMAT_RGBX_8888:
-        return MDP_RGBX_8888;
-    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
-        return MDP_Y_CBCR_H2V1;
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
-        return MDP_Y_CRCB_H2V2;
-    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-        return MDP_Y_CBCR_H2V2;
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
-        return MDP_Y_CRCB_H2V2_TILE;
-    case HAL_PIXEL_FORMAT_YV12:
-        return MDP_Y_CR_CB_GH2V2;
-    default:
-        LOGE("%s: unknown color format [0x%x]", __FUNCTION__, format);
-        return -1;
-    }
-    return -1;
-}
-
-int overlay::get_mdp_orientation(int value) {
-    switch(value) {
-        case 0: return 0;
-        case HAL_TRANSFORM_FLIP_V:  return MDP_FLIP_UD;
-        case HAL_TRANSFORM_FLIP_H:  return MDP_FLIP_LR;
-        case HAL_TRANSFORM_ROT_90:  return MDP_ROT_90;
-        case HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_V:
-                                    return MDP_ROT_90|MDP_FLIP_LR;
-        case HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_H:
-                                    return MDP_ROT_90|MDP_FLIP_UD;
-        case HAL_TRANSFORM_ROT_180: return MDP_ROT_180;
-        case HAL_TRANSFORM_ROT_270: return MDP_ROT_270;
-        default:
-            LOGE("%s: invalid rotation value (value = 0x%x",
-                  __FUNCTION__, value);
-            return -1;
-    }
-    return -1;
-}
-
-// Rotator - input to output mapping
-int overlay::get_rot_output_format(int format) {
-    switch (format) {
-    case MDP_Y_CRCB_H2V2_TILE:
-        return MDP_Y_CRCB_H2V2;
-    case MDP_Y_CB_CR_H2V2:
-        return MDP_Y_CBCR_H2V2;
-    case MDP_Y_CR_CB_GH2V2:
-        return MDP_Y_CRCB_H2V2;
-    default:
-        return format;
-    }
-    return -1;
-}
-
-// This function normalizes the crop values to be all even
-void overlay::normalize_crop(uint32_t& xy, uint32_t& wh) {
-
-    if (xy & 0x0001) {
-        // x or y is odd, increment it's value
-        xy += 1;
-        // Since we've incremented x(y), we need to decrement
-        // w(h) accordingly
-        if (wh & 0x0001) {
-            // w or h is odd, decrement it by 1, to make it even
-            EVEN_OUT(wh);
-        } else {
-            // w(h) is already even, hence we decrement by 2
-            wh -=2;
-        }
-    } else {
-        EVEN_OUT(wh);
-    }
-}
-
-#define LOG_TAG "OverlayLIB"
-static void reportError(const char* message) {
-    LOGE( "%s", message);
-}
-
-void overlay::dump(mdp_overlay& mOVInfo) {
-    if (!DEBUG_OVERLAY)
-        return;
-    LOGE("mOVInfo:");
-    LOGE("src: width %d height %d format %s user_data[0] %d", mOVInfo.src.width,
-        mOVInfo.src.height, getFormatString(mOVInfo.src.format),
-        mOVInfo.user_data[0]);
-    LOGE("src_rect: x %d y %d w %d h %d", mOVInfo.src_rect.x,
-        mOVInfo.src_rect.y, mOVInfo.src_rect.w, mOVInfo.src_rect.h);
-    LOGE("dst_rect: x %d y %d w %d h %d", mOVInfo.dst_rect.x,
-        mOVInfo.dst_rect.y, mOVInfo.dst_rect.w, mOVInfo.dst_rect.h);
-    LOGE("z_order %d is_fg %d alpha %d transp_mask %d flags %x id %d",
-        mOVInfo.z_order, mOVInfo.is_fg, mOVInfo.alpha, mOVInfo.transp_mask,
-        mOVInfo.flags, mOVInfo.id);
-}
-
-void overlay::dump(msm_rotator_img_info& mRotInfo) {
-    if (!DEBUG_OVERLAY)
-        return;
-    LOGE("mRotInfo:");
-    LOGE("session_id %d dst_x %d dst_y %d rotations %d enable %d",
-        mRotInfo.session_id, mRotInfo.dst_x, mRotInfo.dst_y,
-        mRotInfo.rotations, mRotInfo.enable);
-    LOGE("src: width %d height %d format %s", mRotInfo.src.width,
-        mRotInfo.src.height, getFormatString(mRotInfo.src.format));
-    LOGE("dst: width %d height %d format %s", mRotInfo.dst.width,
-        mRotInfo.dst.height, getFormatString(mRotInfo.src.format));
-    LOGE("src_rect: x %d y %d w %d h %d", mRotInfo.src_rect.x,
-        mRotInfo.src_rect.y, mRotInfo.src_rect.w, mRotInfo.src_rect.h);
-}
-
-const char* overlay::getFormatString(int format){
-    static const char* formats[] = {
-             "MDP_RGB_565",
-             "MDP_XRGB_8888",
-             "MDP_Y_CBCR_H2V2",
-             "MDP_ARGB_8888",
-             "MDP_RGB_888",
-             "MDP_Y_CRCB_H2V2",
-             "MDP_YCRYCB_H2V1",
-             "MDP_Y_CRCB_H2V1",
-             "MDP_Y_CBCR_H2V1",
-             "MDP_RGBA_8888",
-             "MDP_BGRA_8888",
-             "MDP_RGBX_8888",
-             "MDP_Y_CRCB_H2V2_TILE",
-             "MDP_Y_CBCR_H2V2_TILE",
-             "MDP_Y_CR_CB_H2V2",
-             "MDP_Y_CR_CB_GH2V2",
-             "MDP_Y_CB_CR_H2V2",
-             "MDP_Y_CRCB_H1V1",
-             "MDP_Y_CBCR_H1V1",
-             "MDP_IMGTYPE_LIMIT",
-             "MDP_BGR_565",
-             "MDP_FB_FORMAT",
-             "MDP_IMGTYPE_LIMIT2"
-        };
-    return formats[format];
-}
-ZOrderManager* ZOrderManager::sInstance = 0;
-FrameBufferInfo* FrameBufferInfo::sFBInfoInstance = 0;
-
-int ZOrderManager::getZ(int fbnum){
-    int zorder = NO_PIPE;;
-    Mutex::Autolock objLock(mObjMutex);
-    if(mPipesInuse == mMaxPipes) {
-        LOGE("No free pipes available.. inUse = %d ", mPipesInuse);
-        return NO_PIPE;
-    }
-    switch(fbnum) {
-        case FRAMEBUFFER_0:
-            for (int i = 0;i < NUM_CHANNELS; i++) {
-                if(mFB0Pipes[i] == false) {
-                    mFB0Pipes[i]= true;
-                    zorder = i;
-                    break;
-                }
-            }
-            break;
-        case FRAMEBUFFER_1:
-        case FRAMEBUFFER_2:
-            for (int i = 0;i < mMaxPipes; i++) {
-                if(mFB1Pipes[i] == false) {
-                    mFB1Pipes[i]= true;
-                    zorder = i;
-                    break;
-                 }
-             }
-             break;
-         default:
-             LOGE("getZ: Invalid framebuffer..");
-             break;
-    }
-    mPipesInuse++;
-    LOGE("getZ: return zorder = %d for fbdev = %d, pipesinUse = %d",
-            zorder, fbnum, mPipesInuse);
-    return zorder;
-}
-
-void ZOrderManager::decZ(int fbnum, int zorder){
-   Mutex::Autolock objLock(mObjMutex);
-   switch(fbnum) {
-       case FRAMEBUFFER_0:
-           LOG_ASSERT(!mFB0Pipes[zorder],"channel with ZOrder does not exist");
-           LOGE("decZ: freeing the pipe with zorder = %d for fbdev = %d", zorder, fbnum);
-           mFB0Pipes[zorder] = false;
-           break;
-       case FRAMEBUFFER_1:
-       case FRAMEBUFFER_2:
-           LOG_ASSERT(!mFB1Pipes[zorder],"channel with ZOrder does not exist");
-           LOGE("decZ: freeing the pipe with zorder = %d for fbdev = %d", zorder, fbnum);
-           mFB1Pipes[zorder] = false;
-           break;
-       default:
-           LOGE("decZ: Invalid framebuffer ");
-           break;
-    }
-    if(mPipesInuse > 0)
-        mPipesInuse--;
-    LOGE("decZ: Pipes in use  = %d", mPipesInuse);
-}
-
-bool overlay::isHDMIConnected () {
-    char value[PROPERTY_VALUE_MAX];
-    property_get("hw.hdmiON", value, "0");
-    int isHDMI = atoi(value);
-    return isHDMI ? true : false;
-}
-
-bool overlay::is3DTV() {
-    char is3DTV = '0';
-    FILE *fp = fopen(EDID_3D_INFO_FILE, "r");
-    if (fp) {
-        fread(&is3DTV, 1, 1, fp);
-        fclose(fp);
-    }
-    LOGI("3DTV EDID flag: %c", is3DTV);
-    return (is3DTV == '0') ? false : true;
-}
-
-bool overlay::isPanel3D() {
-    int fd = open("/dev/graphics/fb0", O_RDWR, 0);
-    if (fd < 0) {
-        reportError("Can't open framebuffer 0");
-        return false;
-    }
-    fb_fix_screeninfo finfo;
-    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) {
-        reportError("FBIOGET_FSCREENINFO on fb0 failed");
-        close(fd);
-        fd = -1;
-        return false;
-    }
-    close(fd);
-    return (FB_TYPE_3D_PANEL == finfo.type) ? true : false;
-}
-
-bool overlay::usePanel3D() {
-    if (Overlay::sHDMIAsPrimary)
-        return is3DTV();
-
-    if(!isPanel3D())
-        return false;
-    char value[PROPERTY_VALUE_MAX];
-    property_get("persist.user.panel3D", value, "0");
-    int usePanel3D = atoi(value);
-    return usePanel3D ? true : false;
-}
-
-bool overlay::send3DInfoPacket (unsigned int format3D) {
-    FILE *fp = fopen(FORMAT_3D_FILE, "wb");
-    if (fp) {
-        fprintf(fp, "%d", format3D);
-        fclose(fp);
-        fp = NULL;
-        return true;
-    }
-    LOGE("%s:no sysfs entry for setting 3d mode!", __FUNCTION__);
-    return false;
-}
-
-bool overlay::enableBarrier (unsigned int orientation) {
-    FILE *fp = fopen(BARRIER_FILE, "wb");
-    if (fp) {
-        fprintf(fp, "%d", orientation);
-        fclose(fp);
-        fp = NULL;
-        return true;
-    }
-    LOGE("%s:no sysfs entry for enabling barriers on 3D panel!", __FUNCTION__);
-    return false;
-}
-
-int overlay::getColorFormat(int format)
-{
-    if (format == HAL_PIXEL_FORMAT_YV12)
-        return format;
-    else if (format & INTERLACE_MASK)
-        return format ^ HAL_PIXEL_FORMAT_INTERLACE;
-    else
-        return COLOR_FORMAT(format);
-}
-
-bool overlay::isInterlacedContent(int format)
-{
-    if ((format != HAL_PIXEL_FORMAT_YV12) &&
-        (format & INTERLACE_MASK))
-        return true;
-
-    return false;
-}
-
-unsigned int overlay::getOverlayConfig (unsigned int format3D, bool poll,
-        bool isHDMI) {
-    bool isTV3D = false;
-    unsigned int curState = 0;
-    if (poll)
-        isHDMI = isHDMIConnected();
-    if (isHDMI) {
-        LOGD("%s: HDMI connected... checking the TV type", __FUNCTION__);
-        if (format3D) {
-            if (is3DTV())
-                curState = OV_3D_VIDEO_3D_TV;
-            else
-                curState = OV_3D_VIDEO_2D_TV;
-        } else
-            curState = OV_2D_VIDEO_ON_TV;
-    } else {
-        LOGD("%s: HDMI not connected...", __FUNCTION__);
-        if(format3D) {
-            if (usePanel3D())
-                curState = OV_3D_VIDEO_3D_PANEL;
-            else
-                curState = OV_3D_VIDEO_2D_PANEL;
-        }
-        else
-            curState = OV_2D_VIDEO_ON_PANEL;
-    }
-    return curState;
-}
-
-/* clears any VG pipes allocated to the fb devices */
-int overlay::initOverlay() {
-    msmfb_mixer_info_req  req;
-    mdp_mixer_info *minfo = NULL;
-    char name[64];
-    int fd = -1;
-    for(int i = 0; i < NUM_FB_DEVICES; i++) {
-        snprintf(name, 64, FB_DEVICE_TEMPLATE, i);
-        LOGD("initoverlay:: opening the device:: %s", name);
-        fd = open(name, O_RDWR, 0);
-        if(fd < 0) {
-            LOGE("cannot open framebuffer(%d)", i);
-            return -1;
-        }
-        //Get the mixer configuration */
-        req.mixer_num = i;
-        if (ioctl(fd, MSMFB_MIXER_INFO, &req) == -1) {
-            LOGE("ERROR: MSMFB_MIXER_INFO ioctl failed");
-            close(fd);
-            return -1;
-        }
-        minfo = req.info;
-        for (int j = 0; j < req.cnt; j++) {
-            LOGD("ndx=%d num=%d z_order=%d", minfo->pndx, minfo->pnum,
-                    minfo->z_order);
-            // except the RGB base layer with z_order of -1, clear any
-            // other pipes connected to mixer.
-            if((minfo->z_order) != -1) {
-                int index = minfo->pndx;
-                LOGD("Unset overlay with index: %d at mixer %d", index, i);
-                if(ioctl(fd, MSMFB_OVERLAY_UNSET, &index) == -1) {
-                    LOGE("ERROR: MSMFB_OVERLAY_UNSET failed");
-                    close(fd);
-                    return -1;
-                }
-            }
-            minfo++;
-        }
-        close(fd);
-        fd = -1;
-    }
-    return 0;
-}
-
-Overlay::Overlay() : mChannelUP(false), mExternalDisplay(false),
-                     mS3DFormat(0), mCroppedSrcWidth(0),
-                     mCroppedSrcHeight(0), mState(-1) {
-    mOVBufferInfo.width = mOVBufferInfo.height = 0;
-    mOVBufferInfo.format = mOVBufferInfo.size = 0;
-}
-
-Overlay::~Overlay() {
-    closeChannel();
-}
-
-int Overlay::getFBWidth(int channel) const {
-    return objOvCtrlChannel[channel].getFBWidth();
-}
-
-int Overlay::getFBHeight(int channel) const {
-    return objOvCtrlChannel[channel].getFBHeight();
-}
-
-bool Overlay::startChannel(const overlay_buffer_info& info, int fbnum,
-                              bool norot, bool uichannel,
-                              unsigned int format3D, int channel,
-                              int flags, int num_buffers) {
-    int zorder = 0;
-    mCroppedSrcWidth = info.width;
-    mCroppedSrcHeight = info.height;
-    if (format3D)
-        zorder = channel;
-    if (mState == -1)
-        mState = OV_UI_MIRROR_TV;
-
-    mChannelUP = objOvCtrlChannel[channel].startControlChannel(info, fbnum,
-                                                       norot, uichannel,
-                                                       format3D, zorder, flags);
-    if (!mChannelUP) {
-        LOGE("startChannel for fb%d failed", fbnum);
-        return mChannelUP;
-    }
-    bool secure = flags & SECURE_OVERLAY_SESSION;
-    objOvCtrlChannel[channel].setSize(info.size);
-    return objOvDataChannel[channel].startDataChannel(objOvCtrlChannel[channel], fbnum,
-                                            norot, secure, uichannel, num_buffers);
-}
-
-bool Overlay::closeChannel() {
-
-    if (!mChannelUP)
-        return true;
-
-    if(mS3DFormat) {
-        if (mExternalDisplay)
-            overlay::send3DInfoPacket(0);
-        else if (mState == OV_3D_VIDEO_3D_PANEL) {
-            if (sHDMIAsPrimary)
-                overlay::send3DInfoPacket(0);
-            else
-                enableBarrier(0);
-        }
-    }
-    for (int i = 0; i < NUM_CHANNELS; i++) {
-        objOvCtrlChannel[i].closeControlChannel();
-        objOvDataChannel[i].closeDataChannel();
-    }
-    mChannelUP = false;
-    mS3DFormat = 0;
-    mOVBufferInfo.width = 0;
-    mOVBufferInfo.height = 0;
-    mOVBufferInfo.format = 0;
-    mOVBufferInfo.size = 0;
-    mState = -1;
-    return true;
-}
-
-void Overlay::closeExternalChannel() {
-    if (objOvCtrlChannel[VG1_PIPE].isChannelUP()) {
-        objOvCtrlChannel[VG1_PIPE].closeControlChannel();
-        objOvDataChannel[VG1_PIPE].closeDataChannel();
-    }
-}
-
-bool Overlay::getPosition(int& x, int& y, uint32_t& w, uint32_t& h, int channel) {
-    return objOvCtrlChannel[channel].getPosition(x, y, w, h);
-}
-
-bool Overlay::getOrientation(int& orientation, int channel) const {
-    return objOvCtrlChannel[channel].getOrientation(orientation);
-}
-
-bool Overlay::setDeviceOrientation(int orientation) {
-    // Use this to calculate the position on HDMI
-    mDevOrientation = orientation;
-    return true;
-}
-
-bool Overlay::setPosition(int x, int y, uint32_t w, uint32_t h) {
-    bool ret = false;
-    overlay_rect secDest;
-    overlay_rect priDest;
-    int currX, currY;
-    uint32_t currW, currH;
-    // Set even destination co-ordinates
-    EVEN_OUT(x); EVEN_OUT(y);
-    EVEN_OUT(w); EVEN_OUT(h);
-    objOvCtrlChannel[VG0_PIPE].getPosition(currX, currY, currW, currH);
-    priDest.x = x, priDest.y = y;
-    priDest.w = w, priDest.h = h;
-    if(x != currX || y != currY || w != currW || h != currH) {
-        switch (mState) {
-            case OV_UI_MIRROR_TV:
-            case OV_2D_VIDEO_ON_PANEL:
-            case OV_3D_VIDEO_2D_PANEL:
-                return setChannelPosition(x, y, w, h, VG0_PIPE);
-                break;
-            case OV_2D_VIDEO_ON_TV:
-                if (FrameBufferInfo::getInstance()->canSupportTrueMirroring()) {
-                    objOvCtrlChannel[VG1_PIPE].getAspectRatioPosition(
-                            mCroppedSrcWidth, mCroppedSrcHeight, mDevOrientation,
-                            &priDest, &secDest);
-                } else {
-                    objOvCtrlChannel[VG1_PIPE].getAspectRatioPosition(
-                            mCroppedSrcWidth, mCroppedSrcHeight, &secDest);
-                }
-                setChannelPosition(secDest.x, secDest.y, secDest.w, secDest.h,
-                            VG1_PIPE);
-                return setChannelPosition(x, y, w, h, VG0_PIPE);
-                break;
-            case OV_3D_VIDEO_3D_PANEL:
-                for (int i = 0; i < NUM_CHANNELS; i++) {
-                    if (sHDMIAsPrimary)
-                        objOvCtrlChannel[i].getPositionS3D(i, mS3DFormat, &secDest);
-                    else {
-                        if (!objOvCtrlChannel[i].useVirtualFB()) {
-                            LOGE("%s: failed virtual fb for channel %d", __FUNCTION__, i);
-                            return false;
-                        }
-                        objOvCtrlChannel[i].getPositionS3D(i, 0x1, &secDest);
-                    }
-                    if(!setChannelPosition(secDest.x, secDest.y, secDest.w,
-                                                               secDest.h, i)) {
-                        LOGE("%s: failed for channel %d", __FUNCTION__, i);
-                        return false;
-                    }
-                }
-                break;
-            case OV_3D_VIDEO_2D_TV:
-            case OV_3D_VIDEO_3D_TV:
-                for (int i = 0; i < NUM_CHANNELS; i++) {
-                    ret = objOvCtrlChannel[i].getPositionS3D(i, mS3DFormat,
-                                                                     &secDest);
-                    if (!ret)
-                        ret = setChannelPosition(x, y, w, h, i);
-                    else
-                        ret = setChannelPosition(secDest.x, secDest.y, secDest.w,
-                                                                  secDest.h, i);
-                    if (!ret) {
-                        LOGE("%s: failed for channel %d", __FUNCTION__, i);
-                        return ret;
-                    }
-                }
-                break;
-            default:
-                LOGE("%s:Unknown state %d", __FUNCTION__, mState);
-                break;
-        }
-    }
-    return true;
-}
-
-bool Overlay::setChannelPosition(int x, int y, uint32_t w, uint32_t h, int channel) {
-    return objOvCtrlChannel[channel].setPosition(x, y, w, h);
-}
-
-bool Overlay::updateOverlaySource(const overlay_buffer_info& info, int orientation,
-                                  int flags) {
-    bool ret = false;
-    int currentFlags = 0;
-
-    bool needUpdateFlags = false;
-    if (objOvCtrlChannel[0].isChannelUP()) {
-        needUpdateFlags = objOvCtrlChannel[0].doFlagsNeedUpdate(flags);
-    }
-
-    bool geometryChanged = true;
-    if (info.width == mOVBufferInfo.width &&
-        info.height == mOVBufferInfo.height &&
-        info.format == mOVBufferInfo.format) {
-        geometryChanged = false;
-    }
-
-    if (sHDMIAsPrimary)
-        needUpdateFlags = false;
-
-    if ((false == needUpdateFlags) && (false == geometryChanged)) {
-        return true;
-    }
-
-    // Disable rotation for the HDMI channels
-    int orientHdmi = 0;
-    int orientPrimary = sHDMIAsPrimary ? 0 : orientation;
-    int orient[2] = {orientPrimary, orientHdmi};
-    // disable waitForVsync on HDMI, since we call the wait ioctl
-    int ovFlagsExternal = 0;
-    int ovFlagsPrimary = sHDMIAsPrimary ? (flags |= WAIT_FOR_VSYNC): flags;
-    int ovFlags[2] = {flags, ovFlagsExternal};
-    switch(mState) {
-        case OV_3D_VIDEO_3D_PANEL:
-            orient[1] = sHDMIAsPrimary ? 0 : orientation;
-            break;
-        case OV_3D_VIDEO_3D_TV:
-            orient[0] = 0;
-            break;
-        default:
-            break;
-    }
-
-    int numChannelsToUpdate = NUM_CHANNELS;
-    if (!geometryChanged) {
-        // Only update the primary channel - we only need to update the
-        // wait/no-wait flags
-        if (objOvCtrlChannel[0].isChannelUP()) {
-            return objOvCtrlChannel[0].updateOverlayFlags(flags);
-        }
-    }
-
-    // Set the overlay source info
-    for (int i = 0; i < NUM_CHANNELS; i++) {
-        if (objOvCtrlChannel[i].isChannelUP()) {
-            ret = objOvCtrlChannel[i].updateOverlaySource(info, orient[i], ovFlags[i]);
-            if (!ret) {
-                LOGE("objOvCtrlChannel[%d].updateOverlaySource failed", i);
-                return false;
-            }
-            objOvCtrlChannel[i].setSize(info.size);
-            ret = objOvDataChannel[i].updateDataChannel(info.size);
-        }
-    }
-    if (ret) {
-        mOVBufferInfo = info;
-    } else
-        LOGE("update failed");
-    return ret;
-}
-
-bool Overlay::getAspectRatioPosition(int w, int h, overlay_rect *rect, int channel) {
-    return objOvCtrlChannel[channel].getAspectRatioPosition(w, h, rect);
-}
-
-int Overlay::getS3DFormat(int format) {
-    // The S3D is part of the HAL_PIXEL_FORMAT_YV12 value. Add
-    // an explicit check for the format
-    if (format == HAL_PIXEL_FORMAT_YV12) {
-        return 0;
-    }
-    int format3D = FORMAT_3D(format);
-    int fIn3D = FORMAT_3D_INPUT(format3D); // MSB 2 bytes are input format
-    int fOut3D = FORMAT_3D_OUTPUT(format3D); // LSB 2 bytes are output format
-    format3D = fIn3D | fOut3D;
-    if (!fIn3D) {
-        format3D |= fOut3D << SHIFT_3D; //Set the input format
-    }
-    if (!fOut3D) {
-        format3D |= fIn3D >> SHIFT_3D; //Set the output format
-    }
-    return format3D;
-}
-
-bool Overlay::setSource(const overlay_buffer_info& info, int orientation,
-                        int hdmiConnected, int flags, int num_buffers) {
-    // Separate the color format from the 3D format.
-    // If there is 3D content; the effective format passed by the client is:
-    // effectiveFormat = 3D_IN | 3D_OUT | ColorFormat
-    int newState = mState;
-    bool stateChange = false, ret = true;
-    bool isHDMIStateChange = (mExternalDisplay != hdmiConnected) && (mState != -1);
-    unsigned int format3D = getS3DFormat(info.format);
-    int colorFormat = getColorFormat(info.format);
-    if (isHDMIStateChange || -1 == mState) {
-        // we were mirroring UI. Also HDMI state stored was stale
-        newState = getOverlayConfig (format3D, false, hdmiConnected);
-        stateChange = (mState == newState) ? false : true;
-    }
-
-    if (stateChange) {
-        mExternalDisplay = hdmiConnected;
-        mState = newState;
-        mS3DFormat = format3D;
-        if (mState == OV_3D_VIDEO_2D_PANEL || mState == OV_3D_VIDEO_2D_TV) {
-            LOGI("3D content on 2D display: set the output format as monoscopic");
-            mS3DFormat = FORMAT_3D_INPUT(format3D) | HAL_3D_OUT_MONOSCOPIC_MASK;
-        }
-        // We always enable the rotator for the primary.
-        bool noRot = false;
-        bool uiChannel = false;
-        int fbnum = 0;
-        switch(mState) {
-            case OV_2D_VIDEO_ON_PANEL:
-                if(isHDMIStateChange) {
-                    //close HDMI Only
-                    closeExternalChannel();
-                    break;
-                }
-            case OV_3D_VIDEO_2D_PANEL:
-                closeChannel();
-                return startChannel(info, FRAMEBUFFER_0, noRot, false,
-                        mS3DFormat, VG0_PIPE, flags, num_buffers);
-                break;
-            case OV_3D_VIDEO_3D_PANEL:
-                closeChannel();
-                if (sHDMIAsPrimary) {
-                    noRot = true;
-                    flags |= WAIT_FOR_VSYNC;
-                    send3DInfoPacket(mS3DFormat & OUTPUT_MASK_3D);
-                }
-                for (int i=0; i<NUM_CHANNELS; i++) {
-                    if(!startChannel(info, FRAMEBUFFER_0, noRot, uiChannel,
-                                mS3DFormat, i, flags, num_buffers)) {
-                        LOGE("%s:failed to open channel %d", __FUNCTION__, i);
-                        return false;
-                    }
-                }
-                break;
-            case OV_2D_VIDEO_ON_TV:
-                if(isHDMIStateChange) {
-                   //start only HDMI channel
-                   noRot = true;
-                   bool waitForVsync = true;
-                   // External display connected, start corresponding channel
-                   // mExternalDisplay will hold the fbnum
-                   if(!startChannel(info, mExternalDisplay, noRot, false, mS3DFormat,
-                               VG1_PIPE, waitForVsync, num_buffers)) {
-                       LOGE("%s:failed to open channel %d", __func__, VG1_PIPE);
-                       return false;
-                   }
-                   int currX, currY;
-                   uint32_t currW, currH;
-                   overlay_rect priDest;
-                   overlay_rect secDest;
-                   objOvCtrlChannel[VG0_PIPE].getPosition(currX, currY, currW, currH);
-                   priDest.x = currX, priDest.y = currY;
-                   priDest.w = currW, priDest.h = currH;
-                   if (FrameBufferInfo::getInstance()->canSupportTrueMirroring()) {
-                       objOvCtrlChannel[VG1_PIPE].getAspectRatioPosition(
-                               mCroppedSrcWidth, mCroppedSrcHeight, mDevOrientation,
-                               &priDest, &secDest);
-                   } else {
-                       objOvCtrlChannel[VG1_PIPE].getAspectRatioPosition(
-                               mCroppedSrcWidth, mCroppedSrcHeight, &secDest);
-                   }
-                   return setChannelPosition(secDest.x, secDest.y, secDest.w, secDest.h, VG1_PIPE);
-                }
-            case OV_3D_VIDEO_2D_TV:
-                closeChannel();
-                for (int i=0; i<NUM_CHANNELS; i++) {
-                    fbnum = i;
-                    //start two channels for one for primary and external.
-                    if (fbnum) {
-                        // Disable rotation for external
-                        noRot = true;
-                        //set fbnum to hdmiConnected, which holds the ext display
-                        fbnum = hdmiConnected;
-                        flags &= ~WAIT_FOR_VSYNC;
-                    }
-                    if(!startChannel(info, fbnum, noRot, false, mS3DFormat,
-                                i, flags, num_buffers)) {
-                        LOGE("%s:failed to open channel %d", __FUNCTION__, i);
-                        return false;
-                    }
-                }
-                return true;
-                break;
-            case OV_3D_VIDEO_3D_TV:
-                closeChannel();
-                for (int i=0; i<NUM_CHANNELS; i++) {
-                    if(!startChannel(info, FRAMEBUFFER_1, true, false,
-                                mS3DFormat, i, flags, num_buffers)) {
-                        LOGE("%s:failed to open channel %d", __FUNCTION__, i);
-                        return false;
-                    }
-                    send3DInfoPacket(mS3DFormat & OUTPUT_MASK_3D);
-                }
-                break;
-            default:
-                LOGE("%s:Unknown state %d", __FUNCTION__, mState);
-                break;
-        }
-    } else {
-        ret = updateOverlaySource(info, orientation, flags);
-// LGE_CHANGE_S, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents {
-        return ret;
-// LGE_CHANGE_E, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents }
-    }
-    return true;
-}
-
-bool Overlay::setCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h) {
-    if (!mChannelUP) {
-        LOGE("%s: channel not set", __FUNCTION__);
-        return false;
-    }
-    overlay_rect rect, inRect;
-    inRect.x = x; inRect.y = y; inRect.w = w; inRect.h = h;
-    mCroppedSrcWidth = w;
-    mCroppedSrcHeight = h;
-    switch (mState) {
-        case OV_UI_MIRROR_TV:
-        case OV_2D_VIDEO_ON_PANEL:
-            return setChannelCrop(x, y, w, h, VG0_PIPE);
-            break;
-        case OV_3D_VIDEO_2D_PANEL:
-            objOvDataChannel[VG0_PIPE].getCropS3D(&inRect, VG0_PIPE, mS3DFormat, &rect);
-            return setChannelCrop(rect.x, rect.y, rect.w, rect.h, VG0_PIPE);
-            break;
-        case OV_2D_VIDEO_ON_TV:
-            for (int i=0; i<NUM_CHANNELS; i++) {
-                if(!setChannelCrop(x, y, w, h, i)) {
-                    LOGE("%s: failed for pipe %d", __FUNCTION__, i);
-                    return false;
-                }
-            }
-            break;
-        case OV_3D_VIDEO_3D_PANEL:
-        case OV_3D_VIDEO_2D_TV:
-        case OV_3D_VIDEO_3D_TV:
-            for (int i=0; i<NUM_CHANNELS; i++) {
-                objOvDataChannel[i].getCropS3D(&inRect, i, mS3DFormat, &rect);
-                if(!setChannelCrop(rect.x, rect.y, rect.w, rect.h, i)) {
-                    LOGE("%s: failed for pipe %d", __FUNCTION__, i);
-                    return false;
-                }
-            }
-            break;
-        default:
-            LOGE("%s:Unknown state %d", __FUNCTION__, mState);
-            break;
-    }
-    return true;
-}
-
-bool Overlay::setChannelCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h, int channel) {
-    return objOvDataChannel[channel].setCrop(x, y, w, h);
-}
-
-bool Overlay::updateOverlayFlags(int flags) {
-        return objOvCtrlChannel[VG0_PIPE].updateOverlayFlags(flags);
-}
-
-bool Overlay::setTransform(int value) {
-    int barrier = 0;
-    switch (mState) {
-        case OV_UI_MIRROR_TV:
-        case OV_2D_VIDEO_ON_PANEL:
-        case OV_3D_VIDEO_2D_PANEL:
-            return objOvCtrlChannel[VG0_PIPE].setTransform(value);
-            break;
-        case OV_2D_VIDEO_ON_TV:
-        case OV_3D_VIDEO_2D_TV:
-        case OV_3D_VIDEO_3D_TV:
-            for (int i=0; i<NUM_CHANNELS; i++) {
-                if(!objOvCtrlChannel[i].setTransform(value)) {
-                    LOGE("%s:failed for channel %d", __FUNCTION__, i);
-                    return false;
-                }
-            }
-            break;
-        case OV_3D_VIDEO_3D_PANEL:
-            switch (value) {
-                case HAL_TRANSFORM_ROT_90:
-                case HAL_TRANSFORM_ROT_270:
-                    barrier = BARRIER_LANDSCAPE;
-                    break;
-                default:
-                    barrier = BARRIER_PORTRAIT;
-                    break;
-                    if(!enableBarrier(barrier))
-                        LOGE("%s:failed to enable barriers for 3D video", __FUNCTION__);
-            }
-            for (int i=0; i<NUM_CHANNELS; i++) {
-                if(!objOvCtrlChannel[i].setTransform(value)) {
-                    LOGE("%s:failed for channel %d", __FUNCTION__, i);
-                    return false;
-               }
-            }
-            break;
-        default:
-            LOGE("%s:Unknown state %d", __FUNCTION__, mState);
-            break;
-    }
-    return true;
-}
-
-bool Overlay::setFd(int fd, int channel) {
-    return objOvDataChannel[channel].setFd(fd);
-}
-
-bool Overlay::queueBuffer(uint32_t offset, int channel) {
-    return objOvDataChannel[channel].queueBuffer(offset);
-}
-
-bool Overlay::waitForHdmiVsync(int channel) {
-    return objOvDataChannel[channel].waitForHdmiVsync();
-}
-
-bool Overlay::queueBuffer(buffer_handle_t buffer) {
-    private_handle_t const* hnd = reinterpret_cast
-                                   <private_handle_t const*>(buffer);
-    if (!hnd) {
-        LOGE("Overlay::queueBuffer invalid handle");
-        return false;
-    }
-    const size_t offset = hnd->offset;
-    const int fd = hnd->fd;
-    switch (mState) {
-        case OV_UI_MIRROR_TV:
-        case OV_2D_VIDEO_ON_PANEL:
-        case OV_3D_VIDEO_2D_PANEL:
-            if(!queueBuffer(fd, offset, VG0_PIPE)) {
-                LOGE("%s:failed for channel 0", __FUNCTION__);
-                return false;
-            }
-            break;
-        case OV_2D_VIDEO_ON_TV:
-        case OV_3D_VIDEO_3D_PANEL:
-        case OV_3D_VIDEO_2D_TV:
-        case OV_3D_VIDEO_3D_TV:
-            for (int i=NUM_CHANNELS-1; i>=0; i--) {
-                if(!queueBuffer(fd, offset, i)) {
-                    LOGE("%s:failed for channel %d", __FUNCTION__, i);
-                    return false;
-                }
-            }
-            //Wait for HDMI done..
-            if(!waitForHdmiVsync(VG1_PIPE)) {
-                LOGE("%s: waitforHdmiVsync failed", __FUNCTION__);
-                return false;
-            }
-            break;
-        default:
-            LOGE("%s:Unknown state %d", __FUNCTION__, mState);
-            break;
-    }
-    return true;
-}
-
-bool Overlay::queueBuffer(int fd, uint32_t offset, int channel) {
-    bool ret = false;
-    ret = setFd(fd, channel);
-    if(!ret) {
-        LOGE("Overlay::queueBuffer channel %d setFd failed", channel);
-        return false;
-    }
-    ret = queueBuffer(offset, channel);
-    if(!ret) {
-        LOGE("Overlay::queueBuffer channel %d queueBuffer failed", channel);
-        return false;
-    }
-    return ret;
-}
-
-OverlayControlChannel::OverlayControlChannel() : mNoRot(false), mFD(-1), mRotFD(-1),
-                                                 mFormat3D(0), mIsChannelUpdated(true) {
-    memset(&mOVInfo, 0, sizeof(mOVInfo));
-    memset(&m3DOVInfo, 0, sizeof(m3DOVInfo));
-    memset(&mRotInfo, 0, sizeof(mRotInfo));
-}
-
-
-OverlayControlChannel::~OverlayControlChannel() {
-    closeControlChannel();
-}
-
-bool OverlayControlChannel::getAspectRatioPosition(int w, int h, overlay_rect *rect)
-{
-    int width = w, height = h, x, y;
-    int fbWidth  = getFBWidth();
-    int fbHeight = getFBHeight();
-    // width and height for YUV TILE format
-    int tempWidth = w, tempHeight = h;
-    /* Calculate the width and height if it is YUV TILE format*/
-    if(getFormat() == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
-        tempWidth = w - ( (((w-1)/64 +1)*64) - w);
-        tempHeight = h - ((((h-1)/32 +1)*32) - h);
-    }
-    if (width * fbHeight > fbWidth * height) {
-        height = fbWidth * height / width;
-        EVEN_OUT(height);
-        width = fbWidth;
-    } else if (width * fbHeight < fbWidth * height) {
-        width = fbHeight * width / height;
-        EVEN_OUT(width);
-        height = fbHeight;
-    } else {
-        width = fbWidth;
-        height = fbHeight;
-    }
-    /* Scaling of upto a max of 8 times supported */
-    if(width >(tempWidth * HW_OVERLAY_MAGNIFICATION_LIMIT)){
-        width = HW_OVERLAY_MAGNIFICATION_LIMIT * tempWidth;
-    }
-    if(height >(tempHeight*HW_OVERLAY_MAGNIFICATION_LIMIT)) {
-        height = HW_OVERLAY_MAGNIFICATION_LIMIT * tempHeight;
-    }
-    if (width > fbWidth) width = fbWidth;
-    if (height > fbHeight) height = fbHeight;
-
-    char value[PROPERTY_VALUE_MAX];
-    property_get("hw.actionsafe.width", value, "0");
-    float asWidth = atof(value);
-    property_get("hw.actionsafe.height", value, "0");
-    float asHeight = atof(value);
-    width = width * (1.0f -  asWidth / 100.0f);
-    height = height * (1.0f -  asHeight / 100.0f);
-
-    x = (fbWidth - width) / 2;
-    y = (fbHeight - height) / 2;
-    rect->x = x;
-    rect->y = y;
-    rect->w = width;
-    rect->h = height;
-    return true;
-}
-
-
-// This function gets the destination position for Seconday display
-// based on the position and aspect ratio of the primary
-bool OverlayControlChannel::getAspectRatioPosition(int w, int h, int orientation,
-                                 overlay_rect *inRect, overlay_rect *outRect) {
-    float priWidth  = FrameBufferInfo::getInstance()->getWidth();
-    float priHeight = FrameBufferInfo::getInstance()->getHeight();
-    float fbWidth = getFBWidth();
-    float fbHeight = getFBHeight();
-    float wRatio = 1.0;
-    float hRatio = 1.0;
-    float xRatio = 1.0;
-    float yRatio = 1.0;
-
-    int xPos = 0;
-    int yPos = 0;
-    int tmp = 0;
-    overlay_rect rect;
-    switch(orientation) {
-        case MDP_ROT_NOP:
-        case MDP_ROT_180:
-            getAspectRatioPosition((int)priWidth, (int)priHeight, &rect);
-            xPos = rect.x;
-            yPos = rect.y;
-            fbWidth = rect.w;
-            fbHeight = rect.h;
-
-            if(orientation == MDP_ROT_180) {
-                inRect->x = priWidth - (inRect->x + inRect->w);
-                inRect->y = priHeight - (inRect->y + inRect->h);
-            }
-            break;
-        case MDP_ROT_90:
-        case MDP_ROT_270:
-            if(orientation == MDP_ROT_90) {
-                tmp = inRect->y;
-                inRect->y = priWidth - (inRect->x + inRect->w);
-                inRect->x = tmp;
-            }
-            else if(orientation == MDP_ROT_270) {
-                tmp = inRect->x;
-                inRect->x = priHeight - (inRect->y + inRect->h);
-                inRect->y = tmp;
-            }
-            //Swap the destination width/height
-            swapWidthHeight(inRect->w, inRect->h);
-            // Swap width/height for primary
-            swapWidthHeight(priWidth, priHeight);
-            getAspectRatioPosition((int)priWidth, (int)priHeight, &rect);
-            xPos = rect.x;
-            yPos = rect.y;
-            fbWidth = rect.w;
-            fbHeight = rect.h;
-            break;
-        default:
-            LOGE("In  %s: Unknown Orientation", __FUNCTION__);
-            break;
-    }
-    //Calculate the position...
-    xRatio = inRect->x/priWidth;
-    yRatio = inRect->y/priHeight;
-
-    wRatio = inRect->w/priWidth;
-    hRatio = inRect->h/priHeight;
-    outRect->x = (xRatio * fbWidth) + xPos;
-    outRect->y = (yRatio * fbHeight) + yPos;
-
-    outRect->w = (wRatio * fbWidth);
-    outRect->h = hRatio * fbHeight;
-    LOGD("Calculated AS Position for HDMI:  X= %d, y = %d w = %d h = %d",
-                                  outRect->x, outRect->y,outRect->w, outRect->h);
-    return true;
-}
-
-
-bool OverlayControlChannel::getPositionS3D(int channel, int format, overlay_rect *rect) {
-    int wDisp = getFBWidth();
-    int hDisp = getFBHeight();
-    switch (format & OUTPUT_MASK_3D) {
-    case HAL_3D_OUT_SIDE_BY_SIDE_MASK:
-        if (channel == VG0_PIPE) {
-            rect->x = 0;
-            rect->y = 0;
-            rect->w = wDisp/2;
-            rect->h = hDisp;
-        } else {
-            rect->x = wDisp/2;
-            rect->y = 0;
-            rect->w = wDisp/2;
-            rect->h = hDisp;
-        }
-        break;
-    case HAL_3D_OUT_TOP_BOTTOM_MASK:
-        if (channel == VG0_PIPE) {
-            rect->x = 0;
-            rect->y = 0;
-            rect->w = wDisp;
-            rect->h = hDisp/2;
-        } else {
-            rect->x = 0;
-            rect->y = hDisp/2;
-            rect->w = wDisp;
-            rect->h = hDisp/2;
-        }
-        break;
-    case HAL_3D_OUT_MONOSCOPIC_MASK:
-        if (channel == VG1_PIPE) {
-            rect->x = 0;
-            rect->y = 0;
-            rect->w = wDisp;
-            rect->h = hDisp;
-        }
-        else
-            return false;
-        break;
-    case HAL_3D_OUT_INTERLEAVE_MASK:
-        break;
-    default:
-        reportError("Unsupported 3D output format");
-        break;
-    }
-    return true;
-}
-
-bool OverlayControlChannel::openDevices(int fbnum) {
-    if (fbnum < 0)
-        return false;
-
-    char dev_name[64];
-    snprintf(dev_name, 64, FB_DEVICE_TEMPLATE, fbnum);
-    mFD = open(dev_name, O_RDWR, 0);
-    if (mFD < 0) {
-        reportError("Cant open framebuffer ");
-        return false;
-    }
-
-    fb_fix_screeninfo finfo;
-    if (ioctl(mFD, FBIOGET_FSCREENINFO, &finfo) == -1) {
-        reportError("FBIOGET_FSCREENINFO on fb1 failed");
-        close(mFD);
-        mFD = -1;
-        return false;
-    }
-
-    fb_var_screeninfo vinfo;
-    if (ioctl(mFD, FBIOGET_VSCREENINFO, &vinfo) == -1) {
-        reportError("FBIOGET_VSCREENINFO on fb1 failed");
-        close(mFD);
-        mFD = -1;
-        return false;
-    }
-    mFBWidth = vinfo.xres;
-    mFBHeight = vinfo.yres;
-    mFBbpp = vinfo.bits_per_pixel;
-    mFBystride = finfo.line_length;
-
-    if (!mNoRot) {
-        mRotFD = open("/dev/msm_rotator", O_RDWR, 0);
-        if (mRotFD < 0) {
-            reportError("Cant open rotator device");
-            close(mFD);
-            mFD = -1;
-            return false;
-        }
-    }
-
-    return true;
-}
-
-bool OverlayControlChannel::setOverlayInformation(const overlay_buffer_info& info,
-                                  int zorder, int flags, int requestType) {
-    int w = info.width;
-    int h = info.height;
-    int format = info.format;
-
-    mOVInfo.src.width  = w;
-    mOVInfo.src.height = h;
-    mOVInfo.src_rect.x = 0;
-    mOVInfo.src_rect.y = 0;
-    mOVInfo.dst_rect.x = 0;
-    mOVInfo.dst_rect.y = 0;
-    mOVInfo.dst_rect.w = w;
-    mOVInfo.dst_rect.h = h;
-    if(format == MDP_Y_CRCB_H2V2_TILE) {
-        if (mNoRot) {
-           mOVInfo.src_rect.w = w - ((((w-1)/64 +1)*64) - w);
-           mOVInfo.src_rect.h = h - ((((h-1)/32 +1)*32) - h);
-        } else {
-           mOVInfo.src_rect.w = w;
-           mOVInfo.src_rect.h = h;
-           mOVInfo.src.width  = (((w-1)/64 +1)*64);
-           mOVInfo.src.height = (((h-1)/32 +1)*32);
-           mOVInfo.src_rect.x = mOVInfo.src.width - w;
-           mOVInfo.src_rect.y = mOVInfo.src.height - h;
-        }
-    } else {
-        mOVInfo.src_rect.w = w;
-        mOVInfo.src_rect.h = h;
-    }
-
-    mOVInfo.src.format = format;
-    int dst_w = w;
-    int dst_h = h;
-
-    if (dst_w > mFBWidth) {
-        dst_w = mFBWidth;
-        dst_h = dst_h * mFBWidth / w;
-    }
-    if (dst_h > mFBHeight) {
-        dst_h = mFBHeight;
-        dst_w = dst_w * mFBHeight / h;
-    }
-    mOVInfo.dst_rect.w = dst_w;
-    mOVInfo.dst_rect.h = dst_h;
-    mOVInfo.user_data[0] = 0;
-    if (requestType == NEW_REQUEST) {
-        mOVInfo.id = MSMFB_NEW_REQUEST;
-        mOVInfo.z_order = zorder;
-        mOVInfo.alpha = 0xff;
-        mOVInfo.transp_mask = 0xffffffff;
-    }
-    mOVInfo.flags = 0;
-    setInformationFromFlags(flags, mOVInfo);
-    mOVInfo.dpp.sharp_strength = 0;
-    return true;
-}
-
-void OverlayControlChannel::setInformationFromFlags(int flags, mdp_overlay& ov)
-{
-    if (flags & INTERLACED_CONTENT) {
-        mOVInfo.flags |= MDP_DEINTERLACE;
-    } else {
-        mOVInfo.flags &= ~MDP_DEINTERLACE;
-    }
-
-    if ((flags & WAIT_FOR_VSYNC) == 0)
-        mOVInfo.flags |= MDP_OV_PLAY_NOWAIT;
-    else
-        mOVInfo.flags &= ~MDP_OV_PLAY_NOWAIT;
-
-    if(flags & SECURE_OVERLAY_SESSION)
-         mOVInfo.flags |= MDP_SECURE_OVERLAY_SESSION;
-    else
-         mOVInfo.flags &= ~MDP_SECURE_OVERLAY_SESSION;
-
-    //set the default sharpening settings
-    mOVInfo.flags |= MDP_SHARPENING;
-
-    if (flags & DISABLE_FRAMEBUFFER_FETCH)
-        mOVInfo.is_fg = 1;
-    else
-        mOVInfo.is_fg = 0;
-
-    if (flags & OVERLAY_PIPE_SHARE) {
-        mOVInfo.flags |= MDP_OV_PIPE_SHARE;
-    } else {
-        mOVInfo.flags &= ~MDP_OV_PIPE_SHARE;
-    }
-    mOVInfo.dpp.sharp_strength = 0;
-	
-}
-
-bool OverlayControlChannel::doFlagsNeedUpdate(int flags) {
-    bool needUpdate = false;
-
-    if ((flags & WAIT_FOR_VSYNC) == 0) {
-        if (!(mOVInfo.flags & MDP_OV_PLAY_NOWAIT)) {
-            needUpdate = true;
-        }
-    }
-    if (flags & WAIT_FOR_VSYNC) {
-        if (mOVInfo.flags & MDP_OV_PLAY_NOWAIT) {
-            needUpdate = true;
-        }
-    }
-
-    if ((flags & DISABLE_FRAMEBUFFER_FETCH) == 0) {
-        if (mOVInfo.is_fg == 1) {
-           needUpdate = true;
-        }
-    }
-    if (flags & DISABLE_FRAMEBUFFER_FETCH) {
-        if (mOVInfo.is_fg == 0) {
-            needUpdate = true;
-        }
-    }
-    return needUpdate;
-}
-
-bool OverlayControlChannel::startOVRotatorSessions(
-                           const overlay_buffer_info& info,
-                           int requestType) {
-    bool ret = true;
-    int w = info.width;
-    int h = info.height;
-    int format = info.format;
-
-    if (!mNoRot) {
-        mRotInfo.src.format = format;
-        mRotInfo.src.width = w;
-        mRotInfo.src.height = h;
-        mRotInfo.src_rect.w = w;
-        mRotInfo.src_rect.h = h;
-        mRotInfo.dst.width = w;
-        mRotInfo.dst.height = h;
-        if(format == MDP_Y_CRCB_H2V2_TILE) {
-            mRotInfo.src.width =  (((w-1)/64 +1)*64);
-            mRotInfo.src.height = (((h-1)/32 +1)*32);
-            mRotInfo.src_rect.w = (((w-1)/64 +1)*64);
-            mRotInfo.src_rect.h = (((h-1)/32 +1)*32);
-            mRotInfo.dst.width = (((w-1)/64 +1)*64);
-            mRotInfo.dst.height = (((h-1)/32 +1)*32);
-            mRotInfo.dst.format = MDP_Y_CRCB_H2V2;
-        }
-        mRotInfo.dst.format = get_rot_output_format(format);
-        mRotInfo.dst_x = 0;
-        mRotInfo.dst_y = 0;
-        mRotInfo.src_rect.x = 0;
-        mRotInfo.src_rect.y = 0;
-        mRotInfo.rotations = 0;
-
-        if (requestType == NEW_REQUEST) {
-            mRotInfo.enable = 0;
-            if(mUIChannel)
-                mRotInfo.enable = 1;
-            mRotInfo.session_id = 0;
-        } else
-            mRotInfo.enable = 1;
-
-        int result = ioctl(mRotFD, MSM_ROTATOR_IOCTL_START, &mRotInfo);
-        if (result) {
-            reportError("Rotator session failed");
-            dump(mRotInfo);
-            ret = false;
-        }
-    }
-
-    if (ret && ioctl(mFD, MSMFB_OVERLAY_SET, &mOVInfo)) {
-        reportError("startOVRotatorSessions, Overlay set failed");
-        dump(mOVInfo);
-        ret = false;
-    }
-
-    if (!ret)
-        closeControlChannel();
-    else
-        mIsChannelUpdated = true;
-    return ret;
-}
-
-bool OverlayControlChannel::updateOverlaySource(const overlay_buffer_info& info,
-                                                int orientation, int flags)
-{
-    int colorFormat = getColorFormat(info.format);
-    int hw_format = get_mdp_format(colorFormat);
-    overlay_buffer_info ovBufInfo;
-    ovBufInfo.width = info.width;
-    ovBufInfo.height = info.height;
-    ovBufInfo.format = hw_format;
-
-    if (isInterlacedContent(info.format)) {
-        flags |= INTERLACED_CONTENT;
-    }
-    if (!setOverlayInformation(ovBufInfo, 0, flags,
-                               UPDATE_REQUEST))
-        return false;
-
-    return startOVRotatorSessions(ovBufInfo, UPDATE_REQUEST);
-}
-
-bool OverlayControlChannel::startControlChannel(const overlay_buffer_info& info,
-                                           int fbnum, bool norot,
-                                           bool uichannel,
-                                           unsigned int format3D, int zorder,
-                                           int flags) {
-    int colorFormat = getColorFormat(info.format);
-    mNoRot = norot;
-    mFormat = colorFormat;
-    mUIChannel = uichannel;
-    mFBNum = fbnum;
-    fb_fix_screeninfo finfo;
-    fb_var_screeninfo vinfo;
-    int hw_format;
-
-    // The interlace mask is part of the HAL_PIXEL_FORMAT_YV12 value. Add
-    // an explicit check for the format
-    if (isInterlacedContent(colorFormat)) {
-        flags |= MDP_DEINTERLACE;
-
-        // Get the actual format
-        colorFormat = colorFormat ^ HAL_PIXEL_FORMAT_INTERLACE;
-    }
-    hw_format = get_mdp_format(colorFormat);
-    if (hw_format < 0) {
-        reportError("Unsupported format");
-        return false;
-    }
-
-    mFormat3D = format3D;
-    if ( !mFormat3D || (mFormat3D & HAL_3D_OUT_MONOSCOPIC_MASK) ) {
-        // Set the share bit for sharing the VG pipe
-        flags |= OVERLAY_PIPE_SHARE;
-    }
-    //do not set the PIPE SHARE bit for true mirroring
-    if(uichannel && FrameBufferInfo::getInstance()->canSupportTrueMirroring())
-        flags &= ~OVERLAY_PIPE_SHARE;
-    if (!openDevices(fbnum))
-        return false;
-
-   //get Z order
-    zorder = ZOrderManager::getInstance()->getZ(fbnum);
-    if (zorder == NO_PIPE)
-        return false;
-
-    overlay_buffer_info ovBufInfo;
-    ovBufInfo.width = info.width;
-    ovBufInfo.height = info.height;
-    ovBufInfo.format = hw_format;
-    if (!setOverlayInformation(ovBufInfo, zorder, flags, NEW_REQUEST))
-        return false;
-
-    return startOVRotatorSessions(ovBufInfo, NEW_REQUEST);
-}
-
-bool OverlayControlChannel::closeControlChannel() {
-    if (!isChannelUP())
-        return true;
-
-    if (!mNoRot && mRotFD > 0) {
-        ioctl(mRotFD, MSM_ROTATOR_IOCTL_FINISH, &(mRotInfo.session_id));
-        close(mRotFD);
-        mRotFD = -1;
-    }
-
-    int ovid = mOVInfo.id;
-    ioctl(mFD, MSMFB_OVERLAY_UNSET, &ovid);
-    if (m3DOVInfo.is_3d) {
-        m3DOVInfo.is_3d = 0;
-        ioctl(mFD, MSMFB_OVERLAY_3D, &m3DOVInfo);
-    }
-
-    close(mFD);
-
-    if(NO_PIPE != mOVInfo.z_order){
-        ZOrderManager::getInstance()->decZ(mFBNum, mOVInfo.z_order);
-    }
-    memset(&mOVInfo, 0, sizeof(mOVInfo));
-    memset(&mRotInfo, 0, sizeof(mRotInfo));
-    memset(&m3DOVInfo, 0, sizeof(m3DOVInfo));
-
-    mOVInfo.z_order = NO_PIPE;
-    mFD = -1;
-
-    return true;
-}
-
-bool OverlayControlChannel::updateOverlayFlags(int flags) {
-    if ((flags & WAIT_FOR_VSYNC) == 0)
-        mOVInfo.flags |= MDP_OV_PLAY_NOWAIT;
-    else
-        mOVInfo.flags &= ~MDP_OV_PLAY_NOWAIT;
-
-    if (flags & DISABLE_FRAMEBUFFER_FETCH)
-        mOVInfo.is_fg = 1;
-    else
-        mOVInfo.is_fg = 0;
-
-    if (ioctl(mFD, MSMFB_OVERLAY_SET, &mOVInfo)) {
-        LOGE("%s: OVERLAY_SET failed", __FUNCTION__);
-        dump(mOVInfo);
-        return false;
-    }
-    return true;
-}
-
-bool OverlayControlChannel::setPosition(int x, int y, uint32_t w, uint32_t h) {
-
-    if (!isChannelUP() ||
-           (x < 0) || (y < 0) || ((x + w) > mFBWidth) ||
-           ((y + h) > mFBHeight)) {
-        reportError("setPosition failed");
-        LOGW("x %d y %d (x+w) %d (y+h) %d FBWidth %d FBHeight %d", x, y, x+w, y+h,
-                                                        mFBWidth,mFBHeight);
-        return false;
-    }
-    if( x != mOVInfo.dst_rect.x || y != mOVInfo.dst_rect.y ||
-        w != mOVInfo.dst_rect.w || h !=  mOVInfo.dst_rect.h ) {
-        mdp_overlay ov;
-        ov.id = mOVInfo.id;
-        if (ioctl(mFD, MSMFB_OVERLAY_GET, &ov)) {
-            reportError("setPosition, overlay GET failed");
-            return false;
-        }
-		
-// LGE_CHANGE_S, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents {
-    // can not scale-up 8 times over original source
-    // return false to compose with GPU
-#if 1
-        if(w > (ov.src_rect.w * HW_OVERLAY_MAGNIFICATION_LIMIT)){
-            LOGE("[TJ] setPosition : too big width, back to GPU comp %d => %d", ov.src_rect.w, w);
-            return false;
-        }
-        if(h > (ov.src_rect.h * HW_OVERLAY_MAGNIFICATION_LIMIT)) {
-            LOGE("[TJ] setPosition : too big height, back to GPU comp %d => %d", ov.src_rect.h, h);
-            return false;
-        }
-#else
-// LGE_CHANGE_E, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents }
-
-        /* Scaling of upto a max of 8 times supported */
-        if(w >(ov.src_rect.w * HW_OVERLAY_MAGNIFICATION_LIMIT)){
-            w = HW_OVERLAY_MAGNIFICATION_LIMIT * ov.src_rect.w;
-            x = (mFBWidth - w) / 2;
-        }
-        if(h >(ov.src_rect.h * HW_OVERLAY_MAGNIFICATION_LIMIT)) {
-            h = HW_OVERLAY_MAGNIFICATION_LIMIT * ov.src_rect.h;
-            y = (mFBHeight - h) / 2;
-        }
-// LGE_CHANGE_S, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents {
-#endif
-// LGE_CHANGE_E, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents }
-
-        ov.dst_rect.x = x;
-        ov.dst_rect.y = y;
-        ov.dst_rect.w = w;
-        ov.dst_rect.h = h;
-        if (ioctl(mFD, MSMFB_OVERLAY_SET, &ov)) {
-            reportError("setPosition, Overlay SET failed");
-            dump(ov);
-            return false;
-        }
-        mOVInfo = ov;
-// LGE_CHANGE_S, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents {
-        LOGE("setPosition");
-        dump(ov);
-// LGE_CHANGE_E, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents }
-    }
-    return true;
-}
-
-void OverlayControlChannel::swapOVRotWidthHeight() {
-    int tmp = mOVInfo.src.width;
-    mOVInfo.src.width = mOVInfo.src.height;
-    mOVInfo.src.height = tmp;
-
-    tmp = mOVInfo.src_rect.h;
-    mOVInfo.src_rect.h = mOVInfo.src_rect.w;
-    mOVInfo.src_rect.w = tmp;
-
-    tmp = mRotInfo.dst.width;
-    mRotInfo.dst.width = mRotInfo.dst.height;
-    mRotInfo.dst.height = tmp;
-}
-
-bool OverlayControlChannel::useVirtualFB() {
-    if(!m3DOVInfo.is_3d) {
-        m3DOVInfo.is_3d = 1;
-        mFBWidth *= 2;
-        mFBHeight /= 2;
-        m3DOVInfo.width = mFBWidth;
-        m3DOVInfo.height = mFBHeight;
-        return ioctl(mFD, MSMFB_OVERLAY_3D, &m3DOVInfo) ? false : true;
-    }
-    return true;
-}
-
-bool OverlayControlChannel::setTransform(int value, bool fetch) {
-    if (!isChannelUP()) {
-        LOGE("%s: channel is not up", __FUNCTION__);
-        return false;
-    }
-
-    mdp_overlay ov = mOVInfo;
-    if (fetch && ioctl(mFD, MSMFB_OVERLAY_GET, &ov)) {
-        reportError("setParameter, overlay GET failed");
-        return false;
-    }
-    mOVInfo = ov;
-    if (!mIsChannelUpdated) {
-        int orientation = get_mdp_orientation(value);
-        if (orientation == mOVInfo.user_data[0]) {
-            return true;
-        }
-    }
-    mIsChannelUpdated = false;
-
-    int val = mOVInfo.user_data[0];
-    if (mNoRot)
-        return true;
-
-    int rot = value;
-
-    switch(rot) {
-        case 0:
-        case HAL_TRANSFORM_FLIP_H:
-        case HAL_TRANSFORM_FLIP_V:
-        {
-            if (val == MDP_ROT_90) {
-                    int tmp = mOVInfo.src_rect.y;
-                    mOVInfo.src_rect.y = mOVInfo.src.width -
-                            (mOVInfo.src_rect.x + mOVInfo.src_rect.w);
-                    mOVInfo.src_rect.x = tmp;
-                    swapOVRotWidthHeight();
-            }
-            else if (val == MDP_ROT_270) {
-                    int tmp = mOVInfo.src_rect.x;
-                    mOVInfo.src_rect.x = mOVInfo.src.height - (
-                            mOVInfo.src_rect.y + mOVInfo.src_rect.h);
-                    mOVInfo.src_rect.y = tmp;
-                    swapOVRotWidthHeight();
-            }
-            break;
-        }
-        case HAL_TRANSFORM_ROT_90:
-        case (HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_H):
-        case (HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_V):
-        {
-            if (val == MDP_ROT_270) {
-                    mOVInfo.src_rect.x = mOVInfo.src.width - (
-                            mOVInfo.src_rect.x + mOVInfo.src_rect.w);
-                    mOVInfo.src_rect.y = mOVInfo.src.height - (
-                    mOVInfo.src_rect.y + mOVInfo.src_rect.h);
-            }
-            else if (val == MDP_ROT_NOP || val == MDP_ROT_180) {
-                    int tmp = mOVInfo.src_rect.x;
-                    mOVInfo.src_rect.x = mOVInfo.src.height -
-                               (mOVInfo.src_rect.y + mOVInfo.src_rect.h);
-                    mOVInfo.src_rect.y = tmp;
-                    swapOVRotWidthHeight();
-            }
-            break;
-        }
-        case HAL_TRANSFORM_ROT_180:
-        {
-            if (val == MDP_ROT_270) {
-                    int tmp = mOVInfo.src_rect.y;
-                    mOVInfo.src_rect.y = mOVInfo.src.width -
-                               (mOVInfo.src_rect.x + mOVInfo.src_rect.w);
-                    mOVInfo.src_rect.x = tmp;
-                    swapOVRotWidthHeight();
-            }
-            else if (val == MDP_ROT_90) {
-                    int tmp = mOVInfo.src_rect.x;
-                    mOVInfo.src_rect.x = mOVInfo.src.height - (
-                             mOVInfo.src_rect.y + mOVInfo.src_rect.h);
-                    mOVInfo.src_rect.y = tmp;
-                    swapOVRotWidthHeight();
-            }
-            break;
-        }
-        case HAL_TRANSFORM_ROT_270:
-        {
-            if (val == MDP_ROT_90) {
-                    mOVInfo.src_rect.y = mOVInfo.src.height -
-                               (mOVInfo.src_rect.y + mOVInfo.src_rect.h);
-                    mOVInfo.src_rect.x = mOVInfo.src.width -
-                               (mOVInfo.src_rect.x + mOVInfo.src_rect.w);
-            }
-            else if (val == MDP_ROT_NOP || val == MDP_ROT_180) {
-                    int tmp = mOVInfo.src_rect.y;
-                    mOVInfo.src_rect.y = mOVInfo.src.width - (
-                        mOVInfo.src_rect.x + mOVInfo.src_rect.w);
-                    mOVInfo.src_rect.x = tmp;
-                    swapOVRotWidthHeight();
-            }
-            break;
-        }
-        default: return false;
-    }
-
-    int mdp_rotation = get_mdp_orientation(rot);
-    if (mdp_rotation == -1)
-        return false;
-
-    mOVInfo.user_data[0] = mdp_rotation;
-    mRotInfo.rotations = mOVInfo.user_data[0];
-
-    /* Rotator always outputs non-tiled formats.
-    If rotator is used, set Overlay input to non-tiled
-    Else, overlay input remains tiled */
-    if (mOVInfo.user_data[0]) {
-        mOVInfo.src.format = get_rot_output_format(mRotInfo.src.format);
-        mRotInfo.enable = 1;
-    }
-    else {
-        //We can switch between rotator ON and OFF. Reset overlay
-        //i/p format whenever this happens
-        if(mRotInfo.dst.format == mOVInfo.src.format)
-            mOVInfo.src.format = mRotInfo.src.format;
-        mRotInfo.enable = 0;
-        //Always enable rotation for UI mirror usecase
-        if(mUIChannel)
-            mRotInfo.enable = 1;
-    }
-
-// LGE_CHANGE_S, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents {
-    // can not scale-up 8 times over original source
-    // return false to compose with GPU
-#if 1
-    if(mOVInfo.dst_rect.w > (mOVInfo.src_rect.w * HW_OVERLAY_MAGNIFICATION_LIMIT)){
-        LOGE("[TJ] setTransform : too big width, back to GPU comp %d => %d", mOVInfo.src_rect.w, mOVInfo.dst_rect.w);
-        return false;
-    }
-    if(mOVInfo.dst_rect.h > (mOVInfo.src_rect.h * HW_OVERLAY_MAGNIFICATION_LIMIT)) {
-        LOGE("[TJ] setTransform : too big height, back to GPU comp %d => %d", mOVInfo.src_rect.h, mOVInfo.dst_rect.h);
-        return false;
-    }
-#endif
-// LGE_CHANGE_E, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents }
-
-    //dump(mRotInfo); // TJ
-    if (ioctl(mRotFD, MSM_ROTATOR_IOCTL_START, &mRotInfo)) {
-        reportError("setTransform, rotator start failed");
-        dump(mRotInfo);
-        return false;
-    }
-
-    if ((mOVInfo.user_data[0] == MDP_ROT_90) ||
-        (mOVInfo.user_data[0] == MDP_ROT_270))
-        mOVInfo.flags |= MDP_SOURCE_ROTATED_90;
-    else
-        mOVInfo.flags &= ~MDP_SOURCE_ROTATED_90;
-
-// LGE_CHANGE_S, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents {
-    LOGE("setTransform"); // TJ
-	dump(mOVInfo); // TJ
-// LGE_CHANGE_E, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents }
-
-    if (ioctl(mFD, MSMFB_OVERLAY_SET, &mOVInfo)) {
-        reportError("setTransform, overlay set failed");
-        dump(mOVInfo);
-        return false;
-    }
-
-    return true;
-}
-
-bool OverlayControlChannel::getPosition(int& x, int& y,
-                                  uint32_t& w, uint32_t& h) {
-    if (!isChannelUP())
-        return false;
-    //mOVInfo has the current Overlay Position
-    x = mOVInfo.dst_rect.x;
-    y = mOVInfo.dst_rect.y;
-    w = mOVInfo.dst_rect.w;
-    h = mOVInfo.dst_rect.h;
-
-    return true;
-}
-
-bool OverlayControlChannel::getOrientation(int& orientation) const {
-    if (!isChannelUP())
-        return false;
-    // mOVInfo has the current orientation
-    orientation = mOVInfo.user_data[0];
-    return true;
-}
-bool OverlayControlChannel::getOvSessionID(int& sessionID) const {
-    if (!isChannelUP())
-        return false;
-    sessionID = mOVInfo.id;
-    return true;
-}
-
-bool OverlayControlChannel::getRotSessionID(int& sessionID) const {
-    if (!isChannelUP())
-        return false;
-    sessionID = mRotInfo.session_id;
-    return true;
-}
-
-bool OverlayControlChannel::getSize(int& size) const {
-    if (!isChannelUP())
-        return false;
-    size = mSize;
-    return true;
-}
-
-OverlayDataChannel::OverlayDataChannel() : mNoRot(false), mFD(-1), mRotFD(-1),
-                                  mPmemFD(-1), mPmemAddr(0), mUpdateDataChannel(false)
-{
-    //XXX: getInstance(false) implies that it should only
-    // use the kernel allocator. Change it to something
-    // more descriptive later.
-    mAlloc = gralloc::IAllocController::getInstance(false);
-}
-
-OverlayDataChannel::~OverlayDataChannel() {
-    closeDataChannel();
-}
-
-bool OverlayDataChannel::startDataChannel(
-               const OverlayControlChannel& objOvCtrlChannel,
-               int fbnum, bool norot, bool secure, bool uichannel,
-               int num_buffers) {
-    int ovid, rotid, size;
-    mNoRot = norot;
-    mSecure = secure;
-    memset(&mOvData, 0, sizeof(mOvData));
-    memset(&mOvDataRot, 0, sizeof(mOvDataRot));
-    memset(&mRotData, 0, sizeof(mRotData));
-    if (objOvCtrlChannel.getOvSessionID(ovid) &&
-            objOvCtrlChannel.getRotSessionID(rotid) &&
-            objOvCtrlChannel.getSize(size)) {
-        return startDataChannel(ovid, rotid, size, fbnum,
-                      norot, uichannel, num_buffers);
-    }
-    else
-        return false;
-}
-
-bool OverlayDataChannel::openDevices(int fbnum, bool uichannel, int num_buffers) {
-    if (fbnum < 0)
-        return false;
-    char dev_name[64];
-    snprintf(dev_name, 64, FB_DEVICE_TEMPLATE, fbnum);
-
-    mFD = open(dev_name, O_RDWR, 0);
-    if (mFD < 0) {
-        reportError("Cant open framebuffer ");
-        return false;
-    }
-    if (!mNoRot) {
-        mRotFD = open("/dev/msm_rotator", O_RDWR, 0);
-        if (mRotFD < 0) {
-            reportError("Cant open rotator device");
-            close(mFD);
-            mFD = -1;
-            return false;
-        }
-
-        return mapRotatorMemory(num_buffers, uichannel, NEW_REQUEST);
-    }
-    return true;
-}
-
-bool OverlayDataChannel::mapRotatorMemory(int num_buffers, bool uiChannel, int requestType)
-{
-    mPmemAddr = MAP_FAILED;
-
-    alloc_data data;
-    data.base = 0;
-    data.fd = -1;
-    data.offset = 0;
-    data.size = mPmemOffset * num_buffers;
-    data.align = getpagesize();
-    data.uncached = true;
-
-    int allocFlags = GRALLOC_USAGE_PRIVATE_MM_HEAP       |
-                     GRALLOC_USAGE_PRIVATE_WRITEBACK_HEAP|
-                     GRALLOC_USAGE_PRIVATE_DO_NOT_MAP;
-
-    if(mSecure) {
-        allocFlags |= GRALLOC_USAGE_PROTECTED;
-    } else {
-        allocFlags |= GRALLOC_USAGE_PRIVATE_ADSP_HEAP        |
-                      GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
-        if((requestType == NEW_REQUEST) && !uiChannel)
-            allocFlags |= GRALLOC_USAGE_PRIVATE_SMI_HEAP;
-    }
-
-    int err = mAlloc->allocate(data, allocFlags, 0);
-    if(err) {
-        reportError("Cant allocate rotatory memory");
-        close(mFD);
-        mFD = -1;
-        close(mRotFD);
-        mRotFD = -1;
-        return false;
-    }
-    mPmemFD = data.fd;
-    mPmemAddr = data.base;
-    mBufferType = data.allocType;
-
-    // Set this flag if source memory is fb
-    if(uiChannel)
-        mRotData.src.flags |= MDP_MEMORY_ID_TYPE_FB;
-
-    mOvDataRot.data.memory_id = mPmemFD;
-    mRotData.dst.memory_id = mPmemFD;
-    mRotData.dst.offset = 0;
-    mNumBuffers = num_buffers;
-    mCurrentItem = 0;
-    for (int i = 0; i < num_buffers; i++)
-        mRotOffset[i] = i * mPmemOffset;
-
-    return true;
-}
-
-bool OverlayDataChannel::updateDataChannel(int size) {
-    mUpdateDataChannel = true;
-    mNewPmemOffset = size;
-    return true;
-}
-
-bool OverlayDataChannel::startDataChannel(int ovid, int rotid, int size,
-                                   int fbnum, bool norot,
-                                   bool uichannel, int num_buffers) {
-    memset(&mOvData, 0, sizeof(mOvData));
-    memset(&mOvDataRot, 0, sizeof(mOvDataRot));
-    memset(&mRotData, 0, sizeof(mRotData));
-    mNoRot = norot;
-    mOvData.data.memory_id = -1;
-    mOvData.id = ovid;
-    mOvDataRot = mOvData;
-    mPmemOffset = size;
-    mRotData.session_id = rotid;
-    mNumBuffers = 0;
-    mCurrentItem = 0;
-
-    return openDevices(fbnum, uichannel, num_buffers);
-}
-
-bool OverlayDataChannel::closeDataChannel() {
-    if (!isChannelUP())
-        return true;
-
-    if (!mNoRot && mRotFD > 0) {
-        sp<IMemAlloc> memalloc = mAlloc->getAllocator(mBufferType);
-        memalloc->free_buffer(mPmemAddr, mPmemOffset * mNumBuffers, 0, mPmemFD);
-        close(mPmemFD);
-        mPmemFD = -1;
-        close(mRotFD);
-        mRotFD = -1;
-    }
-    close(mFD);
-    mFD = -1;
-    memset(&mOvData, 0, sizeof(mOvData));
-    memset(&mOvDataRot, 0, sizeof(mOvDataRot));
-    memset(&mRotData, 0, sizeof(mRotData));
-
-    mNumBuffers = 0;
-    mCurrentItem = 0;
-
-    return true;
-}
-
-bool OverlayDataChannel::setFd(int fd) {
-    mOvData.data.memory_id = fd;
-    return true;
-}
-
-bool OverlayDataChannel::queueBuffer(uint32_t offset) {
-    if ((!isChannelUP()) || mOvData.data.memory_id < 0) {
-        reportError("QueueBuffer failed, either channel is not set or no file descriptor to read from");
-        return false;
-    }
-
-    int oldPmemFD = -1;
-    void* oldPmemAddr = MAP_FAILED;
-    uint32_t oldPmemOffset = -1;
-    bool result;
-    if (!mNoRot) {
-        if (mUpdateDataChannel) {
-            oldPmemFD = mPmemFD;
-            oldPmemAddr = mPmemAddr;
-            oldPmemOffset = mPmemOffset;
-            mPmemOffset = mNewPmemOffset;
-            mNewPmemOffset = -1;
-            // Map the new PMEM memory
-            result = mapRotatorMemory(mNumBuffers, 0, UPDATE_REQUEST);
-            if (!result) {
-                LOGE("queueBuffer: mapRotatorMemory failed");
-                return false;
-            }
-            mUpdateDataChannel = false;
-       }
-    }
-
-    result = queue(offset);
-
-    // Unmap the old PMEM memory after the queueBuffer has returned
-    if (oldPmemFD != -1 && oldPmemAddr != MAP_FAILED) {
-        sp<IMemAlloc> memalloc = mAlloc->getAllocator(mBufferType);
-        memalloc->free_buffer(oldPmemAddr, oldPmemOffset * mNumBuffers, 0, oldPmemFD);
-        oldPmemFD = -1;
-    }
-    return result;
-}
-
-bool OverlayDataChannel::queue(uint32_t offset) {
-    msmfb_overlay_data *odPtr;
-    mOvData.data.offset = offset;
-    odPtr = &mOvData;
-    if (!mNoRot) {
-        mRotData.src.memory_id = mOvData.data.memory_id;
-        mRotData.src.offset = offset;
-        mRotData.dst.offset = (mRotData.dst.offset) ? 0 : mPmemOffset;
-        mRotData.dst.offset = mRotOffset[mCurrentItem];
-        mCurrentItem = (mCurrentItem + 1) % mNumBuffers;
-
-        int result = ioctl(mRotFD,
-                       MSM_ROTATOR_IOCTL_ROTATE, &mRotData);
-
-        if (!result) {
-            mOvDataRot.data.offset = (uint32_t) mRotData.dst.offset;
-            odPtr = &mOvDataRot;
-        }
-    }
-
-    if (ioctl(mFD, MSMFB_OVERLAY_PLAY, odPtr)) {
-        reportError("overlay play failed.");
-        return false;
-    }
-
-    return true;
-}
-
-bool OverlayDataChannel::waitForHdmiVsync() {
-    if (!isChannelUP()) {
-        LOGE("%s: channel not up", __FUNCTION__);
-        return false;
-    }
-    if (ioctl(mFD, MSMFB_OVERLAY_PLAY_WAIT, &mOvData)) {
-        LOGE("%s: MSMFB_OVERLAY_PLAY_WAIT failed", __FUNCTION__);
-        return false;
-    }
-    return true;
-}
-
-bool OverlayDataChannel::getCropS3D(overlay_rect *inRect, int channel, int format,
-                                    overlay_rect *rect) {
-    // for the 3D usecase extract channels from a frame
-    switch (format & INPUT_MASK_3D) {
-    case HAL_3D_IN_SIDE_BY_SIDE_L_R:
-        if(channel == 0) {
-            rect->x = 0;
-            rect->y = 0;
-            rect->w = inRect->w/2;
-            rect->h = inRect->h;
-        } else {
-            rect->x = inRect->w/2;
-            rect->y = 0;
-            rect->w = inRect->w/2;
-            rect->h = inRect->h;
-        }
-        break;
-    case HAL_3D_IN_SIDE_BY_SIDE_R_L:
-         if(channel == 1) {
-            rect->x = 0;
-            rect->y = 0;
-            rect->w = inRect->w/2;
-            rect->h = inRect->h;
-        } else {
-            rect->x = inRect->w/2;
-            rect->y = 0;
-            rect->w = inRect->w/2;
-            rect->h = inRect->h;
-        }
-         break;
-    case HAL_3D_IN_TOP_BOTTOM:
-        if(channel == 0) {
-            rect->x = 0;
-            rect->y = 0;
-            rect->w = inRect->w;
-            rect->h = inRect->h/2;
-        } else {
-            rect->x = 0;
-            rect->y = inRect->h/2;
-            rect->w = inRect->w;
-            rect->h = inRect->h/2;
-        }
-        break;
-    case HAL_3D_IN_INTERLEAVE:
-      break;
-    default:
-        reportError("Unsupported 3D format...");
-        break;
-   }
-   return true;
-}
-
-bool OverlayDataChannel::setCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h) {
-    if (!isChannelUP()) {
-        reportError("Channel not set");
-        return false;
-    }
-
-    mdp_overlay ov;
-    ov.id = mOvData.id;
-    if (ioctl(mFD, MSMFB_OVERLAY_GET, &ov)) {
-        reportError("setCrop, overlay GET failed");
-        return false;
-    }
-
-    if ((ov.user_data[0] == MDP_ROT_90) ||
-        (ov.user_data[0] == (MDP_ROT_90 | MDP_FLIP_UD)) ||
-        (ov.user_data[0] == (MDP_ROT_90 | MDP_FLIP_LR))){
-        if (ov.src.width < (y + h))
-            return false;
-
-        uint32_t tmp = x;
-        x = ov.src.width - (y + h);
-        y = tmp;
-
-        tmp = w;
-        w = h;
-        h = tmp;
-    }
-    else if (ov.user_data[0] == MDP_ROT_270) {
-        if (ov.src.height < (x + w))
-            return false;
-
-        uint32_t tmp = y;
-        y = ov.src.height - (x + w);
-        x = tmp;
-
-        tmp = w;
-        w = h;
-        h = tmp;
-    }
-    else if(ov.user_data[0] == MDP_ROT_180) {
-        if ((ov.src.height < (y + h)) || (ov.src.width < ( x + w)))
-            return false;
-
-        x = ov.src.width - (x + w);
-        y = ov.src.height - (y + h);
-    }
-
-
-    normalize_crop(x, w);
-    normalize_crop(y, h);
-
-    if ((ov.src_rect.x == x) &&
-           (ov.src_rect.y == y) &&
-           (ov.src_rect.w == w) &&
-           (ov.src_rect.h == h))
-        return true;
-
-    ov.src_rect.x = x;
-    ov.src_rect.y = y;
-    ov.src_rect.w = w;
-    ov.src_rect.h = h;
-
-// LGE_CHANGE_S, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents {
-    // can not scale-up 8 times over original source
-    // return false to compose with GPU
-#if 1
-    if(ov.dst_rect.w > (ov.src_rect.w * HW_OVERLAY_MAGNIFICATION_LIMIT)){
-        LOGE("[TJ] setCrop : too big width, back to GPU comp %d => %d", ov.src_rect.w, ov.dst_rect.w);
-        return false;
-    }
-    if(ov.dst_rect.h > (ov.src_rect.h * HW_OVERLAY_MAGNIFICATION_LIMIT)) {
-        LOGE("[TJ] setCrop : too big height, back to GPU comp %d => %d", ov.src_rect.h, ov.dst_rect.h);
-        return false;
-    }
-#else
-// LGE_CHANGE_E, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents }
-
-    /* Scaling of upto a max of 8 times supported */
-    if(ov.dst_rect.w >(ov.src_rect.w * HW_OVERLAY_MAGNIFICATION_LIMIT)){
-        ov.dst_rect.w = HW_OVERLAY_MAGNIFICATION_LIMIT * ov.src_rect.w;
-    }
-    if(ov.dst_rect.h >(ov.src_rect.h * HW_OVERLAY_MAGNIFICATION_LIMIT)) {
-        ov.dst_rect.h = HW_OVERLAY_MAGNIFICATION_LIMIT * ov.src_rect.h;
-    }
-// LGE_CHANGE_S, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents {
-#endif
-
-    LOGE("setCrop");
-    dump(ov);
-// LGE_CHANGE_E, [G1_Player][mukyung.jung@lge.com], 20120206, Apply SR 00718706 to fix noise of QCIF contents }
-	
-    if (ioctl(mFD, MSMFB_OVERLAY_SET, &ov)) {
-        reportError("setCrop, overlay set error");
-        dump(ov);
-        return false;
-    }
-
-    return true;
-}
-
-/* setVisualParam can be called to set the configuration value of a post
- * processing feature (HUE,SATURATION,BRIGHTNESS,CONTRAST,SMOOTHING/SHARPENING)
- * for the first 4, the setting will stay set until the parameter is changed
- * by another call to setVisualParam with that same paramType */
-void Overlay::setVisualParam(int8_t paramType, float paramValue) {
-    switch (mState) {
-    case OV_UI_MIRROR_TV:
-    case OV_2D_VIDEO_ON_PANEL:
-    case OV_3D_VIDEO_2D_PANEL:
-        // set the parameter value for the given parameter type.
-        if(!objOvCtrlChannel[VG0_PIPE].setVisualParam(paramType, paramValue)) {
-            LOGE("Failed to set param %d for value %f", paramType, paramValue);
-        }
-        break;
-    case OV_2D_VIDEO_ON_TV:
-    case OV_3D_VIDEO_3D_PANEL:
-    case OV_3D_VIDEO_2D_TV:
-    case OV_3D_VIDEO_3D_TV:
-        for (int i=0; i<NUM_CHANNELS; i++) {
-            //setting the value for the given parameter on each pipe (i.e. for
-            //both video pipes)
-            if(!objOvCtrlChannel[i].setVisualParam(paramType, paramValue)) {
-                LOGE("Failed to set param %d for value %f", paramType, paramValue);
-            }
-        }
-        break;
-     default:
-        break;
-     }
-}
-
-/* Finalizes the parameter value in the hsic_cfg structure*/
-int OverlayControlChannel::commitVisualParam(int8_t paramType, float paramValue) {
-#ifdef USES_POST_PROCESSING
-    switch(paramType) {
-    case SET_HUE:
-        //API expects param within range -180 - 180
-        CAP_RANGE(paramValue, HUE_RANGE, -HUE_RANGE);
-        hsic_cfg.hue = (int32_t) paramValue;
-        break;
-    case SET_BRIGHTNESS:
-        //API expects param within range -255 - 255
-        CAP_RANGE(paramValue, BRIGHTNESS_RANGE, -BRIGHTNESS_RANGE);
-        hsic_cfg.intensity = (int32_t) paramValue;
-        break;
-    case SET_SATURATION:
-        //API expects param within range -1 - 1
-        CAP_RANGE(paramValue, CON_SAT_RANGE, -CON_SAT_RANGE);
-        hsic_cfg.sat = paramValue;
-        break;
-    case SET_CONTRAST:
-        //API expects param within range -1 - 1
-        CAP_RANGE(paramValue, CON_SAT_RANGE, -CON_SAT_RANGE);
-        hsic_cfg.contrast = paramValue;
-        break;
-    default:
-        return -1;
-    }
-    return 0;
-#endif
-    return -1;
-}
-
-/* Converts paramValue to the expected range for each paramType, */
-bool OverlayControlChannel::setVisualParam(int8_t paramType, float paramValue)
-{
-    if (!isChannelUP()) {
-        LOGE("%s: Channel not set", __FUNCTION__);
-        return false;
-    }
-
-    bool setFlag = false;
-
-    //Sharpness values range from -128 to 127
-    //Integer values must be converted accordingly
-
-    int8_t value;
-    if (paramType == SET_SHARPNESS) {
-        //binding paramValue to the limits of its range.
-        CAP_RANGE(paramValue, SHARPNESS_RANGE, -SHARPNESS_RANGE);
-        value = paramValue * NUM_SHARPNESS_VALS - (NUM_SHARPNESS_VALS / 2);
-    }
-
-    uint32_t block = MDP_BLOCK_MAX;
-
-    //tranlate mOVInfo.id into block type for pp_conv
-    switch(mOVInfo.id) {
-        case 3:
-            // 3 is the pipe_ndx given when OVERLAY_PIPE_VG1 is used
-            block = MDP_BLOCK_VG_1;
-            break;
-        case 4:
-            // 4 is the pipe_ndx given when OVERLAY_PIPE_VG2 is used
-            block = MDP_BLOCK_VG_2;
-            break;
-        default:
-            LOGE("%s: Invalid HSIC overlay id",__FUNCTION__);
-    }
-
-    //save the paramValue to hsic_cfg
-    commitVisualParam(paramType, paramValue);
-#ifdef USES_POST_PROCESSING
-    //calling our user space library to configure the post processing color
-    //conversion (does Hue, Saturation, Brightness, and Contrast adjustment)
-    display_pp_conv_set_cfg(block, &hsic_cfg);
-#endif
-    mdp_overlay overlay;
-
-    switch(paramType) {
-    case SET_NONE:
-        return true;
-    case SET_SHARPNESS:
-        if (ioctl(mFD, MSMFB_OVERLAY_GET, &overlay)) {
-            reportError("setVisualParam, overlay GET failed");
-            return false;
-        }
-        if (overlay.dpp.sharp_strength != value) {
-            mOVInfo.flags |= MDP_SHARPENING;
-            mOVInfo.dpp.sharp_strength = value;
-            setFlag = true;
-        }
-        break;
-    case RESET_ALL:
-        //set all visual params to a default value
-        //passed in from the app
-        mOVInfo.flags |= MDP_SHARPENING;
-        mOVInfo.dpp.sharp_strength = value;
-        setFlag = true;
-        break;
-    default:
-        return false;
-    }
-    if (setFlag) {
-        if (ioctl(mFD, MSMFB_OVERLAY_SET, &mOVInfo)) {
-            reportError("setVisualParam, overlay set failed");
-            dump(mOVInfo);
-            return false;
-        }
-    }
-    return true;
-}
diff --git a/liboverlay/overlayLib.h b/liboverlay/overlayLib.h
deleted file mode 100755
index 65b134c..0000000
--- a/liboverlay/overlayLib.h
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef INCLUDE_OVERLAY_LIB
-#define INCLUDE_OVERLAY_LIB
-
-#include <cutils/log.h>
-#include <cutils/properties.h>
-#include <cutils/atomic.h>
-
-#include <hardware/hardware.h>
-#include <hardware/gralloc.h>
-
-#include <dlfcn.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <pthread.h>
-
-#include <linux/fb.h>
-#include <linux/msm_mdp.h>
-#include <linux/msm_rotator.h>
-#include <linux/android_pmem.h>
-
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <utils/threads.h>
-#include <utils/RefBase.h>
-#include <alloc_controller.h>
-#include <memalloc.h>
-
-#ifdef USES_POST_PROCESSING
-#include "lib-postproc.h"
-#endif
-
-#define HW_OVERLAY_MAGNIFICATION_LIMIT 8
-#define HW_OVERLAY_MINIFICATION_LIMIT HW_OVERLAY_MAGNIFICATION_LIMIT
-
-#define EVEN_OUT(x) if (x & 0x0001) {x--;}
-#define NO_PIPE -1
-#define VG0_PIPE 0
-#define VG1_PIPE 1
-#define NUM_CHANNELS 2
-#define NUM_FB_DEVICES 3
-#define FRAMEBUFFER_0 0
-#define FRAMEBUFFER_1 1
-#define FRAMEBUFFER_2 2
-#define NUM_SHARPNESS_VALS 256
-#define SHARPNESS_RANGE 1.0f
-#define HUE_RANGE 180
-#define BRIGHTNESS_RANGE 255
-#define CON_SAT_RANGE 1.0f
-#define CAP_RANGE(value,max,min) do { if (value - min < -0.0001)\
-                                          {value = min;}\
-                                      else if(value - max > 0.0001)\
-                                          {value = max;}\
-                                    } while(0);
-
-enum {
-    HDMI_OFF,
-    HDMI_ON
-};
-
-enum {
-    OVERLAY_CHANNEL_DOWN,
-    OVERLAY_CHANNEL_UP
-};
-
-enum {
-    NEW_REQUEST,
-    UPDATE_REQUEST
-};
-
-enum {
-    WAIT_FOR_VSYNC             = 1<<0,
-    DISABLE_FRAMEBUFFER_FETCH  = 1<<1,
-    INTERLACED_CONTENT         = 1<<2,
-    OVERLAY_PIPE_SHARE         = 1<<3,
-    SECURE_OVERLAY_SESSION     = 1<<4,
-};
-
-/* ------------------------------- 3D defines ---------------------------------------*/
-// The compound format passed to the overlay is
-// ABCCC where A is the input 3D format,
-// B is the output 3D format
-// CCC is the color format e.g YCbCr420SP YCrCb420SP etc.
-#define FORMAT_3D(x) (x & 0xFF000)
-#define COLOR_FORMAT(x) (x & 0xFFF)
-// in the final 3D format, the MSB 2Bytes are the input format and the
-// LSB 2bytes are the output format. Shift the output byte 12 bits.
-#define SHIFT_OUTPUT_3D 12
-#define FORMAT_3D_OUTPUT(x) ((x & 0xF000) >> SHIFT_OUTPUT_3D)
-#define FORMAT_3D_INPUT(x)  (x & 0xF0000)
-#define INPUT_MASK_3D  0xFFFF0000
-#define OUTPUT_MASK_3D 0x0000FFFF
-#define SHIFT_3D       16
-// The output format is the 2MSB bytes. Shift the format by 12 to reflect this
-#define HAL_3D_OUT_SIDE_BY_SIDE_MASK (HAL_3D_OUT_SIDE_BY_SIDE >> SHIFT_OUTPUT_3D)
-#define HAL_3D_OUT_TOP_BOTTOM_MASK   (HAL_3D_OUT_TOP_BOTTOM   >> SHIFT_OUTPUT_3D)
-#define HAL_3D_OUT_INTERLEAVE_MASK   (HAL_3D_OUT_INTERLEAVE   >> SHIFT_OUTPUT_3D)
-#define HAL_3D_OUT_MONOSCOPIC_MASK   (HAL_3D_OUT_MONOSCOPIC   >> SHIFT_OUTPUT_3D)
-
-// 3D panel barrier orientation
-#define BARRIER_LANDSCAPE 1
-#define BARRIER_PORTRAIT  2
-
-#ifdef HDMI_AS_PRIMARY
-#define FORMAT_3D_FILE        "/sys/class/graphics/fb0/format_3d"
-#define EDID_3D_INFO_FILE     "/sys/class/graphics/fb0/3d_present"
-#else
-#define FORMAT_3D_FILE        "/sys/class/graphics/fb1/format_3d"
-#define EDID_3D_INFO_FILE     "/sys/class/graphics/fb1/3d_present"
-#endif
-#define BARRIER_FILE          "/sys/devices/platform/mipi_novatek.0/enable_3d_barrier"
-/* -------------------------- end 3D defines ----------------------------------------*/
-
-// Struct to hold the buffer info: geometry and size
-struct overlay_buffer_info {
-    int width;
-    int height;
-    int format;
-    int size;
-};
-
-using android::Mutex;
-namespace overlay {
-
-#define FB_DEVICE_TEMPLATE "/dev/graphics/fb%u"
-
-    //Utility Class to query the framebuffer info
-    class FrameBufferInfo {
-        int mFBWidth;
-        int mFBHeight;
-        bool mBorderFillSupported;
-        static FrameBufferInfo *sFBInfoInstance;
-
-        FrameBufferInfo():mFBWidth(0),mFBHeight(0), mBorderFillSupported(false) {
-            char const * const device_name =
-                       "/dev/graphics/fb0";
-            int fd = open(device_name, O_RDWR, 0);
-            mdp_overlay ov;
-            memset(&ov, 0, sizeof(ov));
-            if (fd < 0) {
-               LOGE("FrameBufferInfo: Cant open framebuffer ");
-               return;
-            }
-            fb_var_screeninfo vinfo;
-            if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) == -1) {
-                  LOGE("FrameBufferInfo: FBIOGET_VSCREENINFO on fb0 failed");
-                  close(fd);
-                  fd = -1;
-                  return;
-            }
-            ov.id = 1;
-            if(ioctl(fd, MSMFB_OVERLAY_GET, &ov)) {
-                  LOGE("FrameBufferInfo: MSMFB_OVERLAY_GET on fb0 failed");
-                  close(fd);
-                  fd = -1;
-                  return;
-            }
-            close(fd);
-            fd = -1;
-            mFBWidth = vinfo.xres;
-            mFBHeight = vinfo.yres;
-            mBorderFillSupported = (ov.flags & MDP_BORDERFILL_SUPPORTED) ?
-                                                              true : false;
-        }
-        public:
-        static FrameBufferInfo* getInstance(){
-            if (!sFBInfoInstance){
-                sFBInfoInstance = new FrameBufferInfo;
-            }
-            return sFBInfoInstance;
-        }
-        int getWidth() const { return mFBWidth; }
-        int getHeight() const { return mFBHeight; }
-        bool canSupportTrueMirroring() const {
-            return mBorderFillSupported; }
-    };
-
-enum {
-    OV_UI_MIRROR_TV = 0,
-    OV_2D_VIDEO_ON_PANEL,
-    OV_2D_VIDEO_ON_TV,
-    OV_3D_VIDEO_2D_PANEL,
-    OV_3D_VIDEO_2D_TV,
-    OV_3D_VIDEO_3D_PANEL,
-    OV_3D_VIDEO_3D_TV
-};
-bool isHDMIConnected();
-bool is3DTV();
-bool isPanel3D();
-bool usePanel3D();
-bool send3DInfoPacket(unsigned int format3D);
-bool enableBarrier(unsigned int orientation);
-unsigned int  getOverlayConfig (unsigned int format3D, bool poll = true,
-                                bool isHDMI = false);
-int getColorFormat(int format);
-bool isInterlacedContent(int format);
-int get_mdp_format(int format);
-int get_size(int format, int w, int h);
-int get_rot_output_format(int format);
-int get_mdp_orientation(int value);
-void normalize_crop(uint32_t& xy, uint32_t& wh);
-//Initializes the overlay - cleans up any existing overlay pipes
-int initOverlay();
-
-/* Print values being sent to driver in case of ioctl failures
-   These logs are enabled only if DEBUG_OVERLAY is true       */
-void dump(msm_rotator_img_info& mRotInfo);
-void dump(mdp_overlay& mOvInfo);
-const char* getFormatString(int format);
-
-    //singleton class to decide the z order of new overlay surfaces
-    class ZOrderManager {
-        bool mFB0Pipes[NUM_CHANNELS];
-        bool mFB1Pipes[NUM_CHANNELS+1]; //FB1 can have 3 pipes
-        int  mPipesInuse; // Holds the number of pipes in use
-        int  mMaxPipes;   // Max number of pipes
-        static ZOrderManager *sInstance;
-        Mutex *mObjMutex;
-        ZOrderManager(){
-            mPipesInuse = 0;
-            // for true mirroring support there can be 3 pipes on secondary
-            mMaxPipes = FrameBufferInfo::getInstance()->canSupportTrueMirroring()?
-                                                  NUM_CHANNELS+1 : NUM_CHANNELS;
-            for (int i = 0; i < NUM_CHANNELS; i++)
-                mFB0Pipes[i] = false;
-            for (int j = 0; j < mMaxPipes; j++)
-                mFB1Pipes[j] = false;
-            mObjMutex = new Mutex();
-        }
-        ~ZOrderManager() {
-            delete sInstance;
-            delete mObjMutex;
-        }
-        public:
-        static ZOrderManager* getInstance(){
-            if (!sInstance){
-                sInstance = new ZOrderManager;
-            }
-            return sInstance;
-        }
-        int getZ(int fbnum);
-        void decZ(int fbnum, int zorder);
-    };
-const int max_num_buffers = 3;
-typedef struct mdp_rect overlay_rect;
-
-class OverlayControlChannel {
-
-enum {
-    SET_NONE = 0,
-    SET_SHARPNESS,
-#ifdef USES_POST_PROCESSING
-    SET_HUE,
-    SET_BRIGHTNESS,
-    SET_SATURATION,
-    SET_CONTRAST,
-#endif
-    RESET_ALL,
-};
-    bool mNoRot;
-    int mFBNum;
-    int mFBWidth;
-    int mFBHeight;
-    int mFBbpp;
-    int mFBystride;
-    int mFormat;
-    int mFD;
-    int mRotFD;
-    int mSize;
-    int mOrientation;
-    unsigned int mFormat3D;
-    bool mUIChannel;
-#ifdef USES_POST_PROCESSING
-    struct display_pp_conv_cfg hsic_cfg;
-#endif
-    mdp_overlay mOVInfo;
-    msm_rotator_img_info mRotInfo;
-    msmfb_overlay_3d m3DOVInfo;
-    bool mIsChannelUpdated;
-    bool openDevices(int fbnum = -1);
-    bool setOverlayInformation(const overlay_buffer_info& info,
-                               int zorder = 0, int flags = 0,
-                               int requestType = NEW_REQUEST);
-    bool startOVRotatorSessions(const overlay_buffer_info& info, int requestType);
-    void swapOVRotWidthHeight();
-    int commitVisualParam(int8_t paramType, float paramValue);
-    void setInformationFromFlags(int flags, mdp_overlay& ov);
-
-public:
-    OverlayControlChannel();
-    ~OverlayControlChannel();
-    bool startControlChannel(const overlay_buffer_info& info,
-                               int fbnum, bool norot = false,
-                               bool uichannel = false,
-                               unsigned int format3D = 0, int zorder = 0,
-                               int flags = 0);
-    bool closeControlChannel();
-    bool setPosition(int x, int y, uint32_t w, uint32_t h);
-    bool setTransform(int value, bool fetch = true);
-    void setSize (int size) { mSize = size; }
-    bool getPosition(int& x, int& y, uint32_t& w, uint32_t& h);
-    bool getOvSessionID(int& sessionID) const;
-    bool getRotSessionID(int& sessionID) const;
-    bool getSize(int& size) const;
-    bool isChannelUP() const { return (mFD > 0); }
-    int getFBWidth() const { return mFBWidth; }
-    int getFBHeight() const { return mFBHeight; }
-    int getFormat3D() const { return mFormat3D; }
-    bool getOrientation(int& orientation) const;
-    bool updateOverlayFlags(int flags);
-    bool getAspectRatioPosition(int w, int h, overlay_rect *rect);
-    // Calculates the aspect ratio for video on HDMI based on primary
-    //  aspect ratio used in case of true mirroring
-    bool getAspectRatioPosition(int w, int h, int orientation,
-                                overlay_rect *inRect, overlay_rect *outRect);
-    bool getPositionS3D(int channel, int format, overlay_rect *rect);
-    bool updateOverlaySource(const overlay_buffer_info& info, int orientation, int flags);
-    bool getFormat() const { return mFormat; }
-    bool setVisualParam(int8_t paramType, float paramValue);
-    bool useVirtualFB ();
-    bool doFlagsNeedUpdate(int flags);
-};
-
-class OverlayDataChannel {
-
-    bool mNoRot;
-    bool mSecure;
-    int mFD;
-    int mRotFD;
-    int mPmemFD;
-    void* mPmemAddr;
-    uint32_t mPmemOffset;
-    uint32_t mNewPmemOffset;
-    msmfb_overlay_data mOvData;
-    msmfb_overlay_data mOvDataRot;
-    msm_rotator_data_info mRotData;
-    int mRotOffset[max_num_buffers];
-    int mCurrentItem;
-    int mNumBuffers;
-    bool mUpdateDataChannel;
-    android::sp<gralloc::IAllocController> mAlloc;
-    int mBufferType;
-
-    bool openDevices(int fbnum = -1, bool uichannel = false, int num_buffers = 2);
-    bool mapRotatorMemory(int num_buffers, bool uiChannel, int requestType);
-    bool queue(uint32_t offset);
-
-public:
-    OverlayDataChannel();
-    ~OverlayDataChannel();
-    bool startDataChannel(const OverlayControlChannel& objOvCtrlChannel,
-                                int fbnum, bool norot = false, bool secure = false,
-                                bool uichannel = false, int num_buffers = 2);
-    bool startDataChannel(int ovid, int rotid, int size,
-                       int fbnum, bool norot = false, bool uichannel = false,
-                       int num_buffers = 2);
-    bool closeDataChannel();
-    bool setFd(int fd);
-    bool queueBuffer(uint32_t offset);
-    bool waitForHdmiVsync();
-    bool setCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h);
-    bool getCropS3D(overlay_rect *inRect, int channel, int format, overlay_rect *rect);
-    bool isChannelUP() const { return (mFD > 0); }
-    bool updateDataChannel(int size);
-};
-
-/*
- * Overlay class for single thread application
- * A multiple thread/process application need to use Overlay HAL
- */
-class Overlay {
-
-    bool mChannelUP;
-    //stores the connected external display Ex: HDMI(1) WFD(2)
-    int mExternalDisplay;
-    unsigned int mS3DFormat;
-    //Actual cropped source width and height of overlay
-    int mCroppedSrcWidth;
-    int mCroppedSrcHeight;
-    overlay_buffer_info mOVBufferInfo;
-    int mState;
-    // Stores the current device orientation
-    int mDevOrientation;
-    OverlayControlChannel objOvCtrlChannel[2];
-    OverlayDataChannel    objOvDataChannel[2];
-
-public:
-    Overlay();
-    ~Overlay();
-
-    static bool sHDMIAsPrimary;
-    bool startChannel(const overlay_buffer_info& info, int fbnum, bool norot = false,
-                          bool uichannel = false, unsigned int format3D = 0,
-                          int channel = 0, int flags = 0,
-                          int num_buffers = 2);
-    bool closeChannel();
-    bool setDeviceOrientation(int orientation);
-    bool setPosition(int x, int y, uint32_t w, uint32_t h);
-    bool setTransform(int value);
-    bool setOrientation(int value, int channel = 0);
-    bool setFd(int fd, int channel = 0);
-    bool queueBuffer(uint32_t offset, int channel = 0);
-    bool getPosition(int& x, int& y, uint32_t& w, uint32_t& h, int channel = 0);
-    bool isChannelUP() const { return mChannelUP; }
-    int getFBWidth(int channel = 0) const;
-    int getFBHeight(int channel = 0) const;
-    bool getOrientation(int& orientation, int channel = 0) const;
-    bool queueBuffer(buffer_handle_t buffer);
-    bool setSource(const overlay_buffer_info& info, int orientation, int hdmiConnected,
-                    int flags, int numBuffers = 2);
-    bool getAspectRatioPosition(int w, int h, overlay_rect *rect, int channel = 0);
-    bool setCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h);
-    bool updateOverlayFlags(int flags);
-    void setVisualParam(int8_t paramType, float paramValue);
-    bool waitForHdmiVsync(int channel);
-    int  getChannelStatus() const { return (mChannelUP ? OVERLAY_CHANNEL_UP: OVERLAY_CHANNEL_DOWN); }
-    void closeExternalChannel();
-private:
-    bool setChannelPosition(int x, int y, uint32_t w, uint32_t h, int channel = 0);
-    bool setChannelCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h, int channel);
-    bool queueBuffer(int fd, uint32_t offset, int channel);
-    bool updateOverlaySource(const overlay_buffer_info& info, int orientation, int flags);
-    int getS3DFormat(int format);
-};
-
-struct overlay_shared_data {
-    volatile bool isControlSetup;
-    unsigned int state;
-    int rotid[2];
-    int ovid[2];
-};
-};
-#endif
diff --git a/liboverlay/overlayLibUI.cpp b/liboverlay/overlayLibUI.cpp
deleted file mode 100755
index d3fd80a..0000000
--- a/liboverlay/overlayLibUI.cpp
+++ /dev/null
@@ -1,482 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "overlayLibUI.h"
-#include "gralloc_priv.h"
-#define LOG_TAG "OverlayUI"
-
-using android::sp;
-using gralloc::IMemAlloc;
-using gralloc::alloc_data;
-
-namespace {
-/* helper functions */
-void swapOVRotWidthHeight(msm_rotator_img_info& rotInfo,
-                                 mdp_overlay& ovInfo) {
-    int srcWidth = ovInfo.src.width;
-    ovInfo.src.width = ovInfo.src.height;
-    ovInfo.src.height = srcWidth;
-
-    int srcRectWidth = ovInfo.src_rect.w;
-    ovInfo.src_rect.w = ovInfo.src_rect.h;
-    ovInfo.src_rect.h = srcRectWidth;
-
-    int dstWidth = rotInfo.dst.width;
-    rotInfo.dst.width = rotInfo.dst.height;
-    rotInfo.dst.height = dstWidth;
-}
-
-bool isRGBType(int format) {
-    bool ret = false;
-    switch(format) {
-        case MDP_RGBA_8888:
-        case MDP_BGRA_8888:
-        case MDP_RGBX_8888:
-        case MDP_RGB_565:
-            ret = true;
-            break;
-        default:
-            ret = false;
-            break;
-    }
-    return ret;
-}
-
-int getRGBBpp(int format) {
-    int ret = -1;
-    switch(format) {
-        case MDP_RGBA_8888:
-        case MDP_BGRA_8888:
-        case MDP_RGBX_8888:
-            ret = 4;
-            break;
-        case MDP_RGB_565:
-            ret = 2;
-            break;
-        default:
-            ret = -1;
-            break;
-    }
-
-    return ret;
-}
-
-bool turnOFFVSync() {
-    static int swapIntervalPropVal = -1;
-    if (swapIntervalPropVal == -1) {
-        char pval[PROPERTY_VALUE_MAX];
-        property_get("debug.gr.swapinterval", pval, "1");
-        swapIntervalPropVal = atoi(pval);
-    }
-    return (swapIntervalPropVal == 0);
-}
-
-};
-
-namespace overlay {
-
-status_t Display::openDisplay(int fbnum) {
-    if (mFD != NO_INIT)
-        return NO_ERROR;
-
-    status_t ret = NO_INIT;
-    char dev_name[64];
-    snprintf(dev_name, 64, FB_DEVICE_TEMPLATE, fbnum);
-
-    mFD = open(dev_name, O_RDWR, 0);
-    if (mFD < 0) {
-        LOGE("Failed to open FB %d", fbnum);
-        return ret;
-    }
-
-    fb_var_screeninfo vinfo;
-    if (ioctl(mFD, FBIOGET_VSCREENINFO, &vinfo)) {
-        LOGE("FBIOGET_VSCREENINFO on failed on FB %d", fbnum);
-        close(mFD);
-        mFD = NO_INIT;
-        return ret;
-    }
-
-    mFBWidth = vinfo.xres;
-    mFBHeight = vinfo.yres;
-    mFBBpp = vinfo.bits_per_pixel;
-    ret = NO_ERROR;
-
-    return ret;
-}
-
-void Display::closeDisplay() {
-    close(mFD);
-    mFD = NO_INIT;
-}
-
-Rotator::Rotator() : mFD(NO_INIT), mSessionID(NO_INIT), mPmemFD(NO_INIT)
-{
-    mAlloc = gralloc::IAllocController::getInstance(false);
-}
-
-Rotator::~Rotator()
-{
-    closeRotSession();
-}
-
-status_t Rotator::startRotSession(msm_rotator_img_info& rotInfo,
-                                   int size, int numBuffers) {
-    status_t ret = NO_ERROR;
-    if (mSessionID == NO_INIT && mFD == NO_INIT) {
-        mNumBuffers = numBuffers;
-        mFD = open("/dev/msm_rotator", O_RDWR, 0);
-        if (mFD < 0) {
-            LOGE("Couldnt open rotator device");
-            return NO_INIT;
-        }
-
-        if (ioctl(mFD, MSM_ROTATOR_IOCTL_START, &rotInfo)) {
-            close(mFD);
-            mFD = NO_INIT;
-            return NO_INIT;
-        }
-
-        mSessionID = rotInfo.session_id;
-        alloc_data data;
-        data.base = 0;
-        data.fd = -1;
-        data.offset = 0;
-        data.size = mSize * mNumBuffers;
-        data.align = getpagesize();
-        data.uncached = true;
-
-        int allocFlags = GRALLOC_USAGE_PRIVATE_MM_HEAP          |
-                         GRALLOC_USAGE_PRIVATE_WRITEBACK_HEAP   |
-                         GRALLOC_USAGE_PRIVATE_ADSP_HEAP        |
-                         GRALLOC_USAGE_PRIVATE_IOMMU_HEAP       |
-                         GRALLOC_USAGE_PRIVATE_SMI_HEAP         |
-                         GRALLOC_USAGE_PRIVATE_DO_NOT_MAP;
-
-        int err = mAlloc->allocate(data, allocFlags, 0);
-
-        if(err) {
-            LOGE("%s: Can't allocate rotator memory", __func__);
-            closeRotSession();
-            return NO_INIT;
-        }
-        mPmemFD = data.fd;
-        mPmemAddr = data.base;
-        mBufferType = data.allocType;
-
-        mCurrentItem = 0;
-        for (int i = 0; i < mNumBuffers; i++)
-            mRotOffset[i] = i * mSize;
-        ret = NO_ERROR;
-    }
-    return ret;
-}
-
-status_t Rotator::closeRotSession() {
-    if (mSessionID != NO_INIT && mFD != NO_INIT) {
-        ioctl(mFD, MSM_ROTATOR_IOCTL_FINISH, &mSessionID);
-        close(mFD);
-        if (NO_INIT != mPmemFD) {
-            sp<IMemAlloc> memalloc = mAlloc->getAllocator(mBufferType);
-            memalloc->free_buffer(mPmemAddr, mSize * mNumBuffers, 0, mPmemFD);
-            close(mPmemFD);
-        }
-    }
-
-    mFD = NO_INIT;
-    mSessionID = NO_INIT;
-    mPmemFD = NO_INIT;
-    mPmemAddr = MAP_FAILED;
-
-    return NO_ERROR;
-}
-
-status_t Rotator::rotateBuffer(msm_rotator_data_info& rotData) {
-    status_t ret = NO_INIT;
-    if (mSessionID != NO_INIT) {
-        rotData.dst.memory_id = mPmemFD;
-        rotData.dst.offset = mRotOffset[mCurrentItem];
-        rotData.session_id = mSessionID;
-        mCurrentItem = (mCurrentItem + 1) % mNumBuffers;
-        if (ioctl(mFD, MSM_ROTATOR_IOCTL_ROTATE, &rotData)) {
-            LOGE("Rotator failed to rotate");
-            return BAD_VALUE;
-        }
-        return NO_ERROR;
-    }
-
-    return ret;
-}
-
-//===================== OverlayUI =================//
-
-OverlayUI::OverlayUI() : mChannelState(CLOSED), mOrientation(NO_INIT),
-        mFBNum(NO_INIT), mZorder(NO_INIT), mWaitForVsync(false), mIsFg(false),
-        mSessionID(NO_INIT), mParamsChanged(false) {
-        memset(&mOvInfo, 0, sizeof(mOvInfo));
-        memset(&mRotInfo, 0, sizeof(mRotInfo));
-}
-
-OverlayUI::~OverlayUI() {
-    closeChannel();
-}
-
-void OverlayUI::setSource(const overlay_buffer_info& info, int orientation) {
-    status_t ret = NO_INIT;
-    int format3D = FORMAT_3D(info.format);
-    int colorFormat = COLOR_FORMAT(info.format);
-    int format = get_mdp_format(colorFormat);
-
-    if (format3D || !isRGBType(format)) {
-        LOGE("%s: Unsupported format", __func__);
-        return;
-    }
-
-    mParamsChanged |= (mSource.width ^ info.width) ||
-                      (mSource.height ^ info.height) ||
-                      (mSource.format ^ format) ||
-                      (mSource.size ^ info.size) ||
-                      (mOrientation ^ orientation);
-
-    mSource.width = info.width;
-    mSource.height = info.height;
-    mSource.format = format;
-    mSource.size = info.size;
-    mOrientation = orientation;
-    setupOvRotInfo();
-}
-
-void OverlayUI::setDisplayParams(int fbNum, bool waitForVsync, bool isFg, int
-        zorder, bool isVGPipe) {
-    int flags = 0;
-
-    if(false == waitForVsync)
-        flags |= MDP_OV_PLAY_NOWAIT;
-    else
-        flags &= ~MDP_OV_PLAY_NOWAIT;
-
-    if(isVGPipe)
-        flags |= MDP_OV_PIPE_SHARE;
-    else
-        flags &= ~MDP_OV_PIPE_SHARE;
-
-    if (turnOFFVSync())
-        flags |= MDP_OV_PLAY_NOWAIT;
-
-    mParamsChanged |= (mFBNum ^ fbNum) ||
-                      (mOvInfo.is_fg ^ isFg) ||
-                      (mOvInfo.flags ^ flags) ||
-                      (mOvInfo.z_order ^ zorder);
-
-    mFBNum = fbNum;
-    mOvInfo.is_fg = isFg;
-    mOvInfo.flags = flags;
-    mOvInfo.z_order = zorder;
-
-    mobjDisplay.openDisplay(mFBNum);
-}
-
-void OverlayUI::setPosition(int x, int y, int w, int h) {
-    mParamsChanged |= (mOvInfo.dst_rect.x ^ x) ||
-                      (mOvInfo.dst_rect.y ^ y) ||
-                      (mOvInfo.dst_rect.w ^ w) ||
-                      (mOvInfo.dst_rect.h ^ h);
-
-    mOvInfo.dst_rect.x = x;
-    mOvInfo.dst_rect.y = y;
-    mOvInfo.dst_rect.w = w;
-    mOvInfo.dst_rect.h = h;
-}
-
-void OverlayUI::setCrop(int x, int y, int w, int h) {
-    mParamsChanged |= (mOvInfo.src_rect.x ^ x) ||
-                      (mOvInfo.src_rect.y ^ y) ||
-                      (mOvInfo.src_rect.w ^ w) ||
-                      (mOvInfo.src_rect.h ^ h);
-
-    mOvInfo.src_rect.x = x;
-    mOvInfo.src_rect.y = y;
-    mOvInfo.src_rect.w = w;
-    mOvInfo.src_rect.h = h;
-}
-
-void OverlayUI::setupOvRotInfo() {
-    int w = mSource.width;
-    int h = mSource.height;
-    int format = mSource.format;
-    int srcw = (w + 31) & ~31;
-    int srch = (h + 31) & ~31;
-    mOvInfo.src.width = srcw;
-    mOvInfo.src.height = srch;
-    mOvInfo.src.format = format;
-    mOvInfo.src_rect.w = w;
-    mOvInfo.src_rect.h = h;
-    mOvInfo.alpha = 0xff;
-    mOvInfo.transp_mask = 0xffffffff;
-    mRotInfo.src.format = format;
-    mRotInfo.dst.format = format;
-    mRotInfo.src.width = srcw;
-    mRotInfo.src.height = srch;
-    mRotInfo.src_rect.w = srcw;
-    mRotInfo.src_rect.h = srch;
-    mRotInfo.dst.width = srcw;
-    mRotInfo.dst.height = srch;
-
-    int rot = mOrientation;
-    switch(rot) {
-        case 0:
-        case HAL_TRANSFORM_FLIP_H:
-        case HAL_TRANSFORM_FLIP_V:
-            rot = 0;
-            break;
-        case HAL_TRANSFORM_ROT_90:
-        case (HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_H):
-        case (HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_V): {
-            int tmp = mOvInfo.src_rect.x;
-            mOvInfo.src_rect.x = mOvInfo.src.height -
-                (mOvInfo.src_rect.y + mOvInfo.src_rect.h);
-            mOvInfo.src_rect.y = tmp;
-            swapOVRotWidthHeight(mRotInfo, mOvInfo);
-            rot = HAL_TRANSFORM_ROT_90;
-            break;
-        }
-        case HAL_TRANSFORM_ROT_180:
-            break;
-        case HAL_TRANSFORM_ROT_270: {
-            int tmp = mOvInfo.src_rect.y;
-            mOvInfo.src_rect.y = mOvInfo.src.width -
-                (mOvInfo.src_rect.x + mOvInfo.src_rect.w);
-            mOvInfo.src_rect.x = tmp;
-            swapOVRotWidthHeight(mRotInfo, mOvInfo);
-            break;
-        }
-        default:
-            break;
-    }
-    int mdp_rotation = overlay::get_mdp_orientation(rot);
-    if (mdp_rotation < 0)
-        mdp_rotation = 0;
-    mOvInfo.user_data[0] = mdp_rotation;
-    mRotInfo.rotations = mOvInfo.user_data[0];
-    if (mdp_rotation)
-        mRotInfo.enable = 1;
-}
-
-status_t OverlayUI::commit() {
-    status_t ret = BAD_VALUE;
-    if(mChannelState != UP)
-        mOvInfo.id = MSMFB_NEW_REQUEST;
-    ret = startOVSession();
-    if (ret == NO_ERROR && mOrientation) {
-        ret = mobjRotator.startRotSession(mRotInfo, mSource.size);
-    }
-    if (ret == NO_ERROR) {
-        mChannelState = UP;
-    } else {
-        LOGE("start channel failed.");
-    }
-    return ret;
-}
-
-status_t OverlayUI::closeChannel() {
-    if( mChannelState != UP ) {
-        return NO_ERROR;
-    }
-    if(NO_ERROR != closeOVSession()) {
-        LOGE("%s: closeOVSession() failed.", __FUNCTION__);
-        return BAD_VALUE;
-    }
-    if(NO_ERROR != mobjRotator.closeRotSession()) {
-        LOGE("%s: closeRotSession() failed.", __FUNCTION__);
-        return BAD_VALUE;
-    }
-    mChannelState = CLOSED;
-    mParamsChanged = false;
-    memset(&mOvInfo, 0, sizeof(mOvInfo));
-    memset(&mRotInfo, 0, sizeof(mRotInfo));
-    return NO_ERROR;
-}
-
-status_t OverlayUI::startOVSession() {
-    status_t ret = NO_INIT;
-    ret = mobjDisplay.openDisplay(mFBNum);
-
-    if (ret != NO_ERROR)
-        return ret;
-
-    if(mParamsChanged) {
-        mParamsChanged = false;
-        mdp_overlay ovInfo = mOvInfo;
-        if (ioctl(mobjDisplay.getFD(), MSMFB_OVERLAY_SET, &ovInfo)) {
-            LOGE("Overlay set failed..");
-            ret = BAD_VALUE;
-        } else {
-            mSessionID = ovInfo.id;
-            mOvInfo = ovInfo;
-            ret = NO_ERROR;
-        }
-    }
-    return ret;
-}
-
-status_t OverlayUI::closeOVSession() {
-    status_t ret = NO_ERROR;
-    int err = 0;
-    if(err = ioctl(mobjDisplay.getFD(), MSMFB_OVERLAY_UNSET, &mSessionID)) {
-        LOGE("%s: MSMFB_OVERLAY_UNSET failed. (%d)", __FUNCTION__, err);
-        ret = BAD_VALUE;
-    } else {
-        mobjDisplay.closeDisplay();
-        mSessionID = NO_INIT;
-    }
-    return ret;
-}
-
-status_t OverlayUI::queueBuffer(buffer_handle_t buffer) {
-    status_t ret = NO_INIT;
-
-    if (mChannelState != UP)
-        return ret;
-
-    msmfb_overlay_data ovData;
-    memset(&ovData, 0, sizeof(ovData));
-
-    private_handle_t const* hnd = reinterpret_cast
-                                        <private_handle_t const*>(buffer);
-    ovData.data.memory_id = hnd->fd;
-    ovData.data.offset = hnd->offset;
-    if (mOrientation) {
-        msm_rotator_data_info rotData;
-        memset(&rotData, 0, sizeof(rotData));
-        rotData.src.memory_id = hnd->fd;
-        rotData.src.offset = hnd->offset;
-        if (mobjRotator.rotateBuffer(rotData) != NO_ERROR) {
-            LOGE("Rotator failed.. ");
-            return BAD_VALUE;
-        }
-        ovData.data.memory_id = rotData.dst.memory_id;
-        ovData.data.offset = rotData.dst.offset;
-    }
-    ovData.id = mSessionID;
-    if (ioctl(mobjDisplay.getFD(), MSMFB_OVERLAY_PLAY, &ovData)) {
-        LOGE("Queuebuffer failed ");
-        return BAD_VALUE;
-    }
-    return NO_ERROR;
-}
-
-};
diff --git a/liboverlay/overlayLibUI.h b/liboverlay/overlayLibUI.h
deleted file mode 100644
index d16a968..0000000
--- a/liboverlay/overlayLibUI.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef INCLUDE_OVERLAY_LIB_UI
-#define INCLUDE_OVERLAY_LIB_UI
-
-#include <errno.h>
-
-#include "overlayLib.h"
-
-namespace overlay {
-
-enum channel_state_t { UP, CLOSED, PENDING_CLOSE };
-enum status_t {
-                  NO_ERROR,
-                  INVALID_OPERATION = -ENOSYS,
-                  BAD_VALUE = -EINVAL,
-                  NO_INIT = -ENODEV,
-                  ALREADY_EXISTS = -EEXIST
-              };
-
-/*
- * Display class provides following services
- * Open FB
- * FB information (Width, Height and Bpp)
- */
-
-class Display {
-    int mFD;
-    int mFBWidth;
-    int mFBHeight;
-    int mFBBpp;
-    Display(const Display& objDisplay);
-    Display& operator=(const Display& objDisplay);
-
-public:
-    explicit Display() : mFD(NO_INIT) { };
-    ~Display() { close(mFD); };
-    int getFD() const { return mFD; };
-    int getFBWidth() const { return mFBWidth; };
-    int getFBHeight() const { return mFBHeight; };
-    int getFBBpp() const { return mFBBpp; };
-    status_t openDisplay(int fbnum);
-    void closeDisplay();
-};
-
-/*
- * Rotator class, manages rotation of the buffers
- * It communicates with Rotator driver, provides following services
- * Start rotator session
- * Rotate buffer
- */
-
-class Rotator {
-    int mFD;
-    int mSessionID;
-    int mPmemFD;
-    void* mPmemAddr;
-    int mRotOffset[max_num_buffers];
-    int mCurrentItem;
-    int mNumBuffers;
-    int mSize;
-    android::sp<gralloc::IAllocController> mAlloc;
-    int mBufferType;
-    Rotator(const Rotator& objROtator);
-    Rotator& operator=(const Rotator& objRotator);
-
-public:
-    explicit Rotator();
-    ~Rotator();
-    status_t startRotSession(msm_rotator_img_info& rotInfo, int size,
-                             int numBuffers = max_num_buffers);
-    status_t closeRotSession();
-    status_t rotateBuffer(msm_rotator_data_info& rotData);
-};
-
-/*
- * Overlay class for Comp. Bypass
- * We merge control and data channel classes.
- */
-
-class OverlayUI {
-    channel_state_t mChannelState;
-    overlay_buffer_info mSource;
-    int mZorder;
-    int mOrientation;
-    int mFBNum;
-    bool mWaitForVsync;
-    bool mIsFg;
-    int mSessionID;
-    Display mobjDisplay;
-    Rotator mobjRotator;
-
-    mdp_overlay mOvInfo;
-    msm_rotator_img_info mRotInfo;
-
-    bool mParamsChanged;
-
-    OverlayUI(const OverlayUI& objOverlay);
-    OverlayUI& operator=(const OverlayUI& objOverlay);
-
-    status_t startOVSession();
-    status_t closeOVSession();
-    void setupOvRotInfo();
-
-public:
-
-    enum fbnum_t { FB0, FB1 };
-
-    OverlayUI();
-    ~OverlayUI();
-    void setSource(const overlay_buffer_info& info, int orientation);
-    void setPosition(int x, int y, int w, int h);
-    void setCrop(int x, int y, int w, int h);
-    void setDisplayParams(int fbNum, bool waitForVsync, bool isFg, int zorder,
-            bool isVGPipe);
-    status_t commit();
-    status_t closeChannel();
-    channel_state_t isChannelUP() const { return mChannelState; };
-    int getFBWidth() const { return mobjDisplay.getFBWidth(); };
-    int getFBHeight() const { return mobjDisplay.getFBHeight(); };
-    status_t queueBuffer(buffer_handle_t buffer);
-};
-
-};
-#endif
diff --git a/liboverlay/overlayMdp.cpp b/liboverlay/overlayMdp.cpp
new file mode 100644
index 0000000..09499c0
--- /dev/null
+++ b/liboverlay/overlayMdp.cpp
@@ -0,0 +1,289 @@
+/*
+* Copyright (C) 2008 The Android Open Source Project
+* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "overlayUtils.h"
+#include "overlayMdp.h"
+
+#undef ALOG_TAG
+#define ALOG_TAG "overlay"
+
+namespace ovutils = overlay::utils;
+namespace overlay {
+bool MdpCtrl::open(uint32_t fbnum) {
+    // FD open
+    if(!utils::openDev(mFd, fbnum,
+                Res::devTemplate, O_RDWR)){
+        ALOGE("Ctrl failed to open fbnum=%d", fbnum);
+        return false;
+    }
+    return true;
+}
+
+void MdpCtrl::reset() {
+    utils::memset0(mOVInfo);
+    utils::memset0(mLkgo);
+    mOVInfo.id = -1;
+    mLkgo.id = -1;
+}
+
+bool MdpCtrl::close() {
+    if(-1 == static_cast<int>(mOVInfo.id)) return true;
+    if(!mdp_wrapper::unsetOverlay(mFd.getFD(), mOVInfo.id)) {
+        ALOGE("MdpCtrl close error in unset");
+        return false;
+    }
+    reset();
+    if(!mFd.close()) {
+        return false;
+    }
+    return true;
+}
+
+bool MdpCtrl::getScreenInfo(overlay::utils::ScreenInfo& info) {
+    fb_fix_screeninfo finfo;
+    if (!mdp_wrapper::getFScreenInfo(mFd.getFD(), finfo)) {
+        return false;
+    }
+
+    fb_var_screeninfo vinfo;
+    if (!mdp_wrapper::getVScreenInfo(mFd.getFD(), vinfo)) {
+        return false;
+    }
+    info.mFBWidth   = vinfo.xres;
+    info.mFBHeight  = vinfo.yres;
+    info.mFBbpp     = vinfo.bits_per_pixel;
+    info.mFBystride = finfo.line_length;
+    return true;
+}
+
+bool MdpCtrl::get() {
+    mdp_overlay ov;
+    ov.id = mOVInfo.id;
+    if (!mdp_wrapper::getOverlay(mFd.getFD(), ov)) {
+        ALOGE("MdpCtrl get failed");
+        return false;
+    }
+    mOVInfo = ov;
+    return true;
+}
+
+// that is the second part of original setParameter function
+void MdpCtrl::setSrcFormat(const utils::Whf& whf) {
+
+    //By default mdp src format is the same as buffer's
+    mOVInfo.src.format = whf.format;
+
+    //If rotation is used and input formats are tiled then output of rotator is
+    //non-tiled.
+    // FIXME mRotInfo.enable = 1; for enable
+    if (getUserData()) { // if rotations enabled in MdpCtrl
+        if (whf.format == MDP_Y_CRCB_H2V2_TILE)
+            mOVInfo.src.format = MDP_Y_CRCB_H2V2;
+        else if (whf.format == MDP_Y_CBCR_H2V2_TILE)
+            mOVInfo.src.format = MDP_Y_CBCR_H2V2;
+        return;
+    }
+
+}
+
+bool MdpCtrl::set() {
+    if(!this->ovChanged()) {
+        return true; // nothing todo here.
+    }
+
+    if(!mdp_wrapper::setOverlay(mFd.getFD(), mOVInfo)) {
+        ALOGE("MdpCtrl failed to setOverlay, restoring last known "
+                "good ov info");
+        mdp_wrapper::dump("== Bad OVInfo is: ", mOVInfo);
+        mdp_wrapper::dump("== Last good known OVInfo is: ", mLkgo);
+        this->restore();
+        // FIXME, do we need to set the old one?
+        return false;
+    }
+    this->save();
+    return true;
+}
+
+bool MdpCtrl::setPosition(const overlay::utils::Dim& d,
+        int fbw, int fbh)
+{
+    // Validatee against FB size
+    if(!d.check(fbw, fbh)) {
+        ALOGE("MdpCtrl setPosition failed dest dim violate screen limits");
+        return false;
+    }
+
+    ovutils::Dim dim(d);
+    ovutils::Dim ovsrcdim = getSrcRectDim();
+    // Scaling of upto a max of 8 times supported
+    if(dim.w >(ovsrcdim.w * ovutils::HW_OV_MAGNIFICATION_LIMIT)){
+        dim.w = ovutils::HW_OV_MAGNIFICATION_LIMIT * ovsrcdim.w;
+        dim.x = (fbw - dim.w) / 2;
+    }
+    if(dim.h >(ovsrcdim.h * ovutils::HW_OV_MAGNIFICATION_LIMIT)) {
+        dim.h = ovutils::HW_OV_MAGNIFICATION_LIMIT * ovsrcdim.h;
+        dim.y = (fbh - dim.h) / 2;
+    }
+
+    //dim.even_out();
+    setDstRectDim(dim);
+    return true;
+}
+
+void MdpCtrl::updateSource(RotatorBase* r,
+        const utils::PipeArgs& args,
+        const utils::ScreenInfo& info) {
+    utils::Whf whf(args.whf);
+    mOVInfo.src.width  = whf.w;
+    mOVInfo.src.height = whf.h;
+    mOVInfo.src_rect.x = 0;
+    mOVInfo.src_rect.y = 0;
+    mOVInfo.dst_rect.x = 0;
+    mOVInfo.dst_rect.y = 0;
+    mOVInfo.dst_rect.w = whf.w;
+    mOVInfo.dst_rect.h = whf.h;
+    mOVInfo.src.format = whf.format;
+
+    if(whf.format == MDP_Y_CRCB_H2V2_TILE ||
+        (whf.format == MDP_Y_CBCR_H2V2_TILE)) {
+        // passing by value, setInfo fills it and return by val
+        mOVInfo = r->setInfo(args, mOVInfo);
+    } else {
+        mOVInfo.src_rect.w = whf.w;
+        mOVInfo.src_rect.h = whf.h;
+    }
+
+    if (whf.w > info.mFBWidth)
+        mOVInfo.dst_rect.w = info.mFBWidth;
+    if (whf.h > info.mFBHeight)
+        mOVInfo.dst_rect.h = info.mFBHeight;
+    mSize = whf.size;
+}
+
+
+bool MdpCtrl::setInfo(RotatorBase* r,
+        const utils::PipeArgs& args,
+        const utils::ScreenInfo& info)
+{
+    // new request
+    utils::Whf whf(args.whf);
+    mOVInfo.id = MSMFB_NEW_REQUEST;
+
+    updateSource(r, args, info);
+
+    setUserData(0);
+    mOVInfo.alpha = 0xff;
+    mOVInfo.transp_mask = 0xffffffff;
+    setZ(args.zorder);
+    setFlags(args.mdpFlags);
+    setWait(args.wait);
+    setIsFg(args.isFg);
+    mSize = whf.size;
+    return true;
+}
+
+bool MdpCtrl::setCrop(const utils::Dim& cdim) {
+    utils::Dim d(cdim);
+    const utils::Whf ovwhf = getSrcWhf();
+    int udata = getUserData();
+    switch(udata) {
+        case MDP_ROT_NOP:
+            break; // nothing to do here
+        case MDP_ROT_90:
+        case MDP_ROT_90 | MDP_FLIP_UD:
+        case MDP_ROT_90 | MDP_FLIP_LR:
+            {
+                if (ovwhf.w < (d.y + d.h)) {
+                    ALOGE("MdpCtrl setCrop failed ROT 90 udata=%d",
+                            udata);
+                    d.dump();
+                    this->dump();
+                    return false;
+                }
+                uint32_t tmp = d.x;
+                d.x = ovwhf.w - (d.y + d.h);
+                d.y = tmp;
+                utils::swap(d.w, d.h);
+            }break;
+        case MDP_ROT_270:
+            {
+                if (ovwhf.h < (d.x + d.w)) {
+                    ALOGE("MdpCtrl setCrop failed ROT 270 udata=%d",
+                            udata);
+                    d.dump();
+                    this->dump();
+                    return false;
+                }
+                uint32_t tmp = d.y;
+                d.y = ovwhf.h - (d.x + d.w);
+                d.x = tmp;
+                utils::swap(d.w, d.h);
+            }break;
+        case MDP_ROT_180:
+            {
+                if ((ovwhf.h < (d.y + d.h)) ||
+                        (ovwhf.w < ( d.x + d.w))) {
+                    ALOGE("MdpCtrl setCrop failed ROT 180 udata=%d",
+                            udata);
+                    d.dump();
+                    this->dump();
+                    return false;
+                }
+                d.x = ovwhf.w - (d.x + d.w);
+                d.y = ovwhf.h - (d.y + d.h);
+            }break;
+        default:
+            if(!(udata & (MDP_FLIP_UD | MDP_FLIP_LR))) {
+                ALOGE("MdpCtrl setCrop unknown rot %d", udata);
+                return false;
+            }
+    }
+
+    if(getSrcRectDim() == d) {
+        return true; // Nothing to do here
+    }
+
+    utils::normalizeCrop(d.x, d.w);
+    utils::normalizeCrop(d.y, d.h);
+
+    setSrcRectDim(d);
+
+    return true;
+}
+
+void MdpCtrl::dump() const {
+    ALOGE("== Dump MdpCtrl start ==");
+    ALOGE("size=%d", mSize);
+    mFd.dump();
+    mdp_wrapper::dump("mOVInfo", mOVInfo);
+    ALOGE("== Dump MdpCtrl end ==");
+}
+
+void MdpData::dump() const {
+    ALOGE("== Dump MdpData start ==");
+    mFd.dump();
+    mdp_wrapper::dump("mOvData", mOvData);
+    ALOGE("== Dump MdpData end ==");
+}
+
+void MdpCtrl3D::dump() const {
+    ALOGE("== Dump MdpCtrl start ==");
+    mFd.dump();
+    ALOGE("== Dump MdpCtrl end ==");
+}
+
+} // overlay
diff --git a/liboverlay/overlayMdp.h b/liboverlay/overlayMdp.h
new file mode 100644
index 0000000..29f8fd5
--- /dev/null
+++ b/liboverlay/overlayMdp.h
@@ -0,0 +1,489 @@
+/*
+* Copyright (C) 2008 The Android Open Source Project
+* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef OVERLAY_MDP_H
+#define OVERLAY_MDP_H
+
+#include <linux/msm_mdp.h>
+
+#include "overlayUtils.h"
+#include "mdpWrapper.h"
+#include "overlayRotator.h"
+
+namespace overlay{
+
+class RotatorBase;
+
+/*
+* Mdp Ctrl holds corresponding fd and MDP related struct.
+* It is simple wrapper to MDP services
+* */
+class MdpCtrl {
+public:
+    /* ctor reset */
+    explicit MdpCtrl();
+
+    /* dtor close */
+    ~MdpCtrl();
+
+    /* Open underlying device using fbnum */
+    bool open(uint32_t fbnum);
+
+    /* unset overlay, reset and close fd */
+    bool close();
+
+    /* reset and set ov id to -1*/
+    void reset();
+
+    /* get orient / user_data[0] */
+    int getOrient() const;
+
+    /* returns session id */
+    int getId() const;
+
+    /* returns the fd associated to ctrl*/
+    int getFd() const;
+
+    /* Get screen info. out: info*/
+    bool getScreenInfo(utils::ScreenInfo& info);
+
+    /* overlay get */
+    bool get();
+
+    /* returns flags from mdp structure.
+     * Flags are WAIT/NOWAIT/PIPE SHARED*/
+    int getFlags() const;
+
+    /* set flags to mdp structure */
+    void setFlags(int f);
+
+    /* code taken from OverlayControlChannel::setOverlayInformation  */
+    bool setInfo(RotatorBase* r,
+            const utils::PipeArgs& args,
+            const utils::ScreenInfo& info);
+
+    /* given whf, update src */
+    void updateSource(RotatorBase* r,
+            const utils::PipeArgs& args,
+            const utils::ScreenInfo& info);
+
+    /* set z order */
+    void setZ(utils::eZorder z);
+
+    /* set Wait/nowait */
+    void setWait(utils::eWait wait);
+
+    /* set isFg flag */
+    void setIsFg(utils::eIsFg isFg);
+
+    /* calls overlay set
+     * Set would always consult last good known ov instance.
+     * Only if it is different, set would actually exectue ioctl.
+     * On a sucess ioctl. last good known ov instance is updated */
+    bool set();
+
+    /* return a copy of src whf*/
+    utils::Whf getSrcWhf() const;
+
+    /* set src whf */
+    void setSrcWhf(const utils::Whf& whf);
+
+    /* set source format based on rot info */
+    void setSrcFormat(const utils::Whf& whf);
+
+    /* swap src w/h*/
+    void swapSrcWH();
+
+    /* swap src rect w/h */
+    void swapSrcRectWH();
+
+    /* returns a copy to src rect dim */
+    utils::Dim getSrcRectDim() const;
+
+    /* set src/dst rect dim */
+    void setSrcRectDim(const utils::Dim d);
+    void setDstRectDim(const utils::Dim d);
+
+    /* returns a copy ro dst rect dim */
+    utils::Dim getDstRectDim() const;
+
+    /* returns user_data[0]*/
+    int getUserData() const;
+
+    /* sets user_data[0] */
+    void setUserData(int v);
+
+    /* return true if current overlay is different
+     * than lask known good overlay */
+    bool ovChanged() const;
+
+    /* save mOVInfo to be last known good ov*/
+    void save();
+
+    /* restore last known good ov to be the current */
+    void restore();
+
+    /*
+     * Sets ROI, the unpadded region, for source buffer.
+     * Should be called before a setPosition, for small clips.
+     * Dim - ROI dimensions.
+     */
+    bool setCrop(const utils::Dim& d);
+
+    /* given a dim and w/h, set overlay dim */
+    bool setPosition(const utils::Dim& dim, int w, int h);
+
+    /* using user_data, sets/unsets roationvalue in mdp flags */
+    void setRotationFlags();
+
+    /* dump state of the object */
+    void dump() const;
+private:
+
+    /* last good known ov info */
+    mdp_overlay   mLkgo;
+
+    /* Actual overlay mdp structure */
+    mdp_overlay   mOVInfo;
+
+    /* FD for the mdp fbnum */
+    OvFD          mFd;
+
+    /* cached size FIXME do we need it? */
+    uint32_t mSize;
+};
+
+
+/* MDP 3D related ctrl */
+class MdpCtrl3D {
+public:
+    /* ctor reset data */
+    MdpCtrl3D();
+    /* calls MSMFB_OVERLAY_3D */
+    bool close();
+    /* set w/h. format is ignored*/
+    void setWh(const utils::Whf& whf);
+    /* set is_3d calls MSMFB_OVERLAY_3D */
+    bool useVirtualFB();
+    /* set fd to be used in ioctl */
+    void setFd(int fd);
+    /* dump */
+    void dump() const;
+private:
+    /* reset */
+    void reset();
+    /* actual MSM 3D info */
+    msmfb_overlay_3d m3DOVInfo;
+    /* FD for the mdp 3D */
+    OvFD mFd;
+};
+
+/* MDP data */
+class MdpData {
+public:
+    /* ctor reset data */
+    explicit MdpData();
+
+    /* dtor close*/
+    ~MdpData();
+
+    /* open FD */
+    bool open(uint32_t fbnum);
+
+    /* memset0 the underlying mdp object */
+    void reset();
+
+    /* close fd, and reset */
+    bool close();
+
+    /* Set FD / memid */
+    void setMemoryId(int id);
+
+    /* set id of mdp data */
+    void setId(int id);
+
+    /* return ses id of data */
+    int getId() const;
+
+    /* get underlying fd*/
+    int getFd() const;
+
+    /* get memory_id */
+    int getMemoryId() const;
+
+    /* set offset in underlying mdp obj */
+    void setOffset(uint32_t o);
+
+    /* calls wrapper play */
+    bool play();
+
+    /* calls wrapper playWait */
+    bool playWait();
+
+    /* dump state of the object */
+    void dump() const;
+private:
+
+    /* actual overlay mdp data */
+    msmfb_overlay_data mOvData;
+
+    /* fd to mdp fbnum */
+    OvFD mFd;
+};
+
+//--------------Inlines---------------------------------
+namespace utils {
+    inline bool openDev(OvFD& fd, int fb,
+            const char* const s,
+            int flags) {
+        return overlay::open(fd, fb, Res::devTemplate, O_RDWR);
+    }
+}
+
+template <class T>
+        inline void init(T& t) {
+            memset(&t, 0, sizeof(T));
+        }
+
+/////   MdpCtrl  //////
+
+inline MdpCtrl::MdpCtrl() : mSize(0) {
+    reset();
+}
+
+inline MdpCtrl::~MdpCtrl() {
+    close();
+}
+
+inline int MdpCtrl::getOrient() const {
+    return getUserData();
+}
+
+inline int MdpCtrl::getId() const {
+    return mOVInfo.id;
+}
+
+inline int MdpCtrl::getFd() const {
+    return mFd.getFD();
+}
+
+inline int MdpCtrl::getFlags() const {
+    return mOVInfo.flags;
+}
+
+inline void MdpCtrl::setFlags(int f) {
+    mOVInfo.flags = f;
+}
+
+inline void MdpCtrl::setZ(overlay::utils::eZorder z) {
+    mOVInfo.z_order = z;
+}
+
+inline void MdpCtrl::setWait(overlay::utils::eWait wait) {
+    mOVInfo.flags = utils::setWait(wait, mOVInfo.flags);
+}
+
+inline void MdpCtrl::setIsFg(overlay::utils::eIsFg isFg) {
+    mOVInfo.is_fg = isFg;
+}
+
+inline bool MdpCtrl::ovChanged() const {
+    // 0 means same
+    if(0 == ::memcmp(&mOVInfo, &mLkgo, sizeof (mdp_overlay))) {
+        return false;
+    }
+    return true;
+}
+
+inline void MdpCtrl::save() {
+    if(static_cast<ssize_t>(mOVInfo.id) == -1) {
+        ALOGE("MdpCtrl current ov has id -1, will not save");
+        // FIXME dump both?
+        return;
+    }
+    mLkgo = mOVInfo;
+}
+
+inline void MdpCtrl::restore() {
+    if(static_cast<ssize_t>(mLkgo.id) == -1) {
+        ALOGE("MdpCtrl Lkgo ov has id -1, will not restore");
+        // FIXME dump both?
+        return;
+    }
+    mOVInfo = mLkgo;
+}
+
+inline overlay::utils::Whf MdpCtrl::getSrcWhf() const {
+    return utils::Whf(mOVInfo.src.width,
+            mOVInfo.src.height,
+            mOVInfo.src.format);
+}
+
+inline void MdpCtrl::setSrcWhf(const overlay::utils::Whf& whf) {
+    mOVInfo.src.width  = whf.w;
+    mOVInfo.src.height = whf.h;
+    mOVInfo.src.format = whf.format;
+}
+
+inline overlay::utils::Dim MdpCtrl::getSrcRectDim() const {
+    return utils::Dim(mOVInfo.src_rect.x,
+            mOVInfo.src_rect.y,
+            mOVInfo.src_rect.w,
+            mOVInfo.src_rect.h);
+}
+
+inline void MdpCtrl::setSrcRectDim(const overlay::utils::Dim d) {
+    mOVInfo.src_rect.x = d.x;
+    mOVInfo.src_rect.y = d.y;
+    mOVInfo.src_rect.w = d.w;
+    mOVInfo.src_rect.h = d.h;
+}
+
+inline overlay::utils::Dim MdpCtrl::getDstRectDim() const {
+    return utils::Dim(mOVInfo.dst_rect.x,
+            mOVInfo.dst_rect.y,
+            mOVInfo.dst_rect.w,
+            mOVInfo.dst_rect.h);
+}
+
+inline void MdpCtrl::setDstRectDim(const overlay::utils::Dim d) {
+    mOVInfo.dst_rect.x = d.x;
+    mOVInfo.dst_rect.y = d.y;
+    mOVInfo.dst_rect.w = d.w;
+    mOVInfo.dst_rect.h = d.h;
+}
+
+inline int MdpCtrl::getUserData() const { return mOVInfo.user_data[0]; }
+
+inline void MdpCtrl::setUserData(int v) { mOVInfo.user_data[0] = v; }
+
+inline void MdpCtrl::setRotationFlags() {
+    const int u = getUserData();
+    if (u == MDP_ROT_90 || u == MDP_ROT_270)
+        mOVInfo.flags |= MDP_SOURCE_ROTATED_90;
+    else
+        mOVInfo.flags &= ~MDP_SOURCE_ROTATED_90;
+}
+
+
+inline void MdpCtrl::swapSrcWH() {
+    utils::swap(mOVInfo.src.width,
+            mOVInfo.src.height); }
+
+inline void MdpCtrl::swapSrcRectWH() {
+    utils::swap(mOVInfo.src_rect.h,
+            mOVInfo.src_rect.w); }
+
+///////    MdpCtrl3D //////
+
+inline MdpCtrl3D::MdpCtrl3D() { reset(); }
+inline bool MdpCtrl3D::close() {
+    if (m3DOVInfo.is_3d) {
+        m3DOVInfo.is_3d = 0;
+        if(!mdp_wrapper::set3D(mFd.getFD(), m3DOVInfo)) {
+            ALOGE("MdpCtrl3D close failed set3D with 0");
+            return false;
+        }
+    }
+    reset();
+    return true;
+}
+inline void MdpCtrl3D::reset() {
+    utils::memset0(m3DOVInfo);
+}
+
+inline void MdpCtrl3D::setFd(int fd) {
+    mFd.copy(fd);
+    OVASSERT(mFd.valid(), "MdpCtrl3D setFd, FD should be valid");
+}
+
+inline void MdpCtrl3D::setWh(const utils::Whf& whf) {
+    // ignore fmt. Needed for useVirtualFB callflow
+    m3DOVInfo.width = whf.w;
+    m3DOVInfo.height = whf.h;
+}
+
+inline bool MdpCtrl3D::useVirtualFB() {
+    if(!m3DOVInfo.is_3d) {
+        m3DOVInfo.is_3d = 1;
+        if(!mdp_wrapper::set3D(mFd.getFD(), m3DOVInfo)) {
+            ALOGE("MdpCtrl3D close failed set3D with 0");
+            return false;
+        }
+    }
+    return true;
+}
+
+///////    MdpData   //////
+
+inline MdpData::MdpData() { reset(); }
+
+inline MdpData::~MdpData() { close(); }
+
+inline bool MdpData::open(uint32_t fbnum) {
+    // FD open
+    if(!utils::openDev(mFd, fbnum, Res::devTemplate, O_RDWR)){
+        ALOGE("Ctrl failed to open fbnum=%d", fbnum);
+        return false;
+    }
+    return true;
+}
+
+inline void MdpData::reset() {
+    overlay::utils::memset0(mOvData);
+    mOvData.data.memory_id = -1;
+}
+
+inline bool MdpData::close() {
+    if(-1 == mOvData.data.memory_id) return true;
+    reset();
+    if(!mFd.close()) {
+        return false;
+    }
+    return true;
+}
+
+inline void MdpData::setMemoryId(int id) { mOvData.data.memory_id = id; }
+inline int MdpData::getMemoryId() const { return mOvData.data.memory_id; }
+
+inline void MdpData::setId(int id) { mOvData.id = id; }
+
+inline int MdpData::getId() const { return mOvData.id; }
+
+inline int MdpData::getFd() const { return mFd.getFD(); }
+
+inline void MdpData::setOffset(uint32_t o) { mOvData.data.offset = o; }
+
+inline bool MdpData::play() {
+    if(!mdp_wrapper::play(mFd.getFD(), mOvData)){
+        ALOGE("MdpData failed to play");
+        return false;
+    }
+    return true;
+}
+
+inline bool MdpData::playWait() {
+    if(!mdp_wrapper::playWait(mFd.getFD(), mOvData)){
+        ALOGE("MdpData failed to playWait");
+        return false;
+    }
+    return true;
+}
+
+} // overlay
+
+#endif // OVERLAY_MDP_H
diff --git a/liboverlay/overlayMem.h b/liboverlay/overlayMem.h
new file mode 100644
index 0000000..7c04890
--- /dev/null
+++ b/liboverlay/overlayMem.h
@@ -0,0 +1,205 @@
+/*
+* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#ifndef OVERLAY_MEM_H
+#define OVERLAY_MEM_H
+
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <alloc_controller.h>
+#include <memalloc.h>
+
+#include "gralloc_priv.h"
+#include "overlayUtils.h"
+
+namespace overlay {
+
+/*
+* Holds base address, offset and the fd
+* */
+class OvMem {
+public:
+    /* ctor init*/
+    explicit OvMem();
+
+    /* dtor DO NOT call close so it can be copied */
+    ~OvMem();
+
+    /* Use libgralloc to retrieve fd, base addr, alloc type */
+    bool open(uint32_t numbufs,
+            uint32_t bufSz, int flags = O_RDWR);
+
+    /* close fd. assign base address to invalid*/
+    bool close();
+
+    /* return underlying fd */
+    int getFD() const;
+
+    /* return true if fd is valid and base address is valid */
+    bool valid() const;
+
+    /* dump the state of the object */
+    void dump() const;
+
+    /* return underlying address */
+    void* addr() const;
+
+    /* return underlying offset */
+    uint32_t bufSz() const;
+
+    /* return number of bufs */
+    uint32_t numBufs() const ;
+
+private:
+    /* actual os fd */
+    int mFd;
+
+    /* points to base addr (mmap)*/
+    void* mBaseAddr;
+
+    /* allocated buffer type determined by gralloc (ashmem, ion, etc) */
+    int mAllocType;
+
+    /* holds buf size */
+    uint32_t mBufSz;
+
+    /* num of bufs */
+    uint32_t mNumBuffers;
+
+    /* gralloc alloc controller */
+    android::sp<gralloc::IAllocController> mAlloc;
+};
+
+//-------------------Inlines-----------------------------------
+
+using android::sp;
+using gralloc::IMemAlloc;
+using gralloc::alloc_data;
+
+inline OvMem::OvMem() {
+    mFd = -1;
+    mBaseAddr = MAP_FAILED;
+    mAllocType = 0;
+    mBufSz = 0;
+    mNumBuffers = 0;
+    mAlloc = gralloc::IAllocController::getInstance(false);
+}
+
+inline OvMem::~OvMem() { }
+
+inline bool OvMem::open(uint32_t numbufs,
+        uint32_t bufSz, int flags)
+{
+    alloc_data data;
+    //XXX: secure buffers and IOMMU heap
+    int allocFlags = GRALLOC_USAGE_PRIVATE_MM_HEAP |
+                     GRALLOC_USAGE_PRIVATE_DO_NOT_MAP;
+    int err = 0;
+
+    OVASSERT(numbufs && bufSz, "numbufs=%d bufSz=%d", numbufs, bufSz);
+
+    mBufSz = bufSz;
+    mNumBuffers = numbufs;
+
+    data.base = 0;
+    data.fd = -1;
+    data.offset = 0;
+    data.size = mBufSz * mNumBuffers;
+    data.align = getpagesize();
+    data.uncached = true;
+
+    err = mAlloc->allocate(data, allocFlags, 0);
+    if (err != 0) {
+        ALOGE("OvMem: error allocating memory");
+    }
+
+    mFd = data.fd;
+    mBaseAddr = data.base;
+    mAllocType = data.allocType;
+
+    return true;
+}
+
+inline bool OvMem::close()
+{
+    int ret = 0;
+
+    if(!valid()) {
+        return true;
+    }
+
+    sp<IMemAlloc> memalloc = mAlloc->getAllocator(mAllocType);
+    ret = memalloc->free_buffer(mBaseAddr, mBufSz * mNumBuffers, 0, mFd);
+    if (ret != 0) {
+        ALOGE("OvMem: error freeing buffer");
+    }
+
+    mFd = -1;
+    mBaseAddr = MAP_FAILED;
+    mAllocType = 0;
+    mBufSz = 0;
+    mNumBuffers = 0;
+    return ret;
+}
+
+inline bool OvMem::valid() const
+{
+    return (mFd != -1) && (mBaseAddr != MAP_FAILED);
+}
+
+inline int OvMem::getFD() const
+{
+    return mFd;
+}
+
+inline void* OvMem::addr() const
+{
+    return mBaseAddr;
+}
+
+inline uint32_t OvMem::bufSz() const
+{
+    return mBufSz;
+}
+
+inline uint32_t OvMem::numBufs() const
+{
+    return mNumBuffers;
+}
+
+inline void OvMem::dump() const
+{
+    ALOGE("%s: fd=%d addr=%p type=%d bufsz=%u",
+          __FUNCTION__, mFd, mBaseAddr, mAllocType, mBufSz);
+}
+
+} // overlay
+
+#endif // OVERLAY_MEM_H
diff --git a/liboverlay/overlayRotator.cpp b/liboverlay/overlayRotator.cpp
new file mode 100644
index 0000000..30c5ea5
--- /dev/null
+++ b/liboverlay/overlayRotator.cpp
@@ -0,0 +1,430 @@
+/*
+* Copyright (C) 2008 The Android Open Source Project
+* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "overlayRotator.h"
+#include "overlayUtils.h"
+#include "overlayMdp.h"
+
+namespace ovutils = overlay::utils;
+
+namespace overlay {
+
+namespace utils {
+inline mdp_overlay setInfoNullRot(const utils::PipeArgs& args,
+        const mdp_overlay& o)
+{
+    mdp_overlay ov = o;
+    utils::Whf whf(args.whf);
+    utils::Dim d(utils::getSrcRectDim(ov));
+
+    d.w = whf.w - (utils::alignup(whf.w, 64) - whf.w);
+    d.h = whf.h - (utils::alignup(whf.h, 32) - whf.h);
+    utils::setSrcRectDim(ov, d);
+    return ov;
+}
+
+inline mdp_overlay setInfoRot(const utils::PipeArgs& args,
+        const mdp_overlay& o)
+{
+    /* If there are no orientation, then we use setInfoRot
+     * That is even if we are a real rotator object (not null)
+     * Note, that if args.rotFlags are ENABLED
+     * it means we would still like to have rot
+     * even though it is ROT_0 */
+    if(OVERLAY_TRANSFORM_0 == args.orientation &&
+            utils::ROT_FLAG_ENABLED != args.rotFlags) {
+        return setInfoNullRot(args, o);
+    }
+
+    mdp_overlay ov = o;
+    utils::Whf whf(args.whf);
+    utils::Dim d(utils::getSrcRectDim(ov));
+    d.w = whf.w;
+    d.h = whf.h;
+    utils::Whf localwhf (utils::getSrcWhf(ov));
+    localwhf.w = utils::alignup(whf.w, 64);
+    localwhf.h = utils::alignup(whf.h, 32);
+    d.x = localwhf.w - whf.w;
+    d.y = localwhf.h - whf.h;
+    utils::setSrcRectDim(ov, d);
+    utils::setSrcWhf(ov, localwhf);
+    return ov;
+}
+
+} // utils
+
+bool MdpRot::open()
+{
+    if(!mFd.open(Res::rotPath, O_RDWR)){
+        ALOGE("MdpRot failed to open %s", Res::rotPath);
+        return false;
+    }
+    return true;
+}
+
+bool MdpRot::open_i(uint32_t numbufs, uint32_t bufsz)
+{
+    OvMem mem;
+
+    OVASSERT(MAP_FAILED == mem.addr(), "MAP failed in open_i");
+
+    if(!mem.open(numbufs, bufsz)){
+        ALOGE("%s: Failed to open", __func__);
+        mem.close();
+        return false;
+    }
+
+    OVASSERT(MAP_FAILED != mem.addr(), "MAP failed");
+    OVASSERT(mem.getFD() != -1, "getFd is -1");
+
+    mData.data.memory_id = mem.getFD();
+    mRotDataInfo.dst.memory_id = mem.getFD();
+    mRotDataInfo.dst.offset = 0;
+    mMem.curr().m = mem;
+    return true;
+}
+
+bool MdpRot::RotMem::close() {
+    bool ret = true;
+    for(uint32_t i=0; i < RotMem::MAX_ROT_MEM; ++i) {
+        // skip current, and if valid, close
+        if(m[i].valid() && (m[i].close() != 0)) {
+            ALOGE("%s error in closing prev rot mem %d", __FUNCTION__, i);
+            ret = false;
+        }
+    }
+    return ret;
+}
+
+bool MdpRot::close() {
+    bool success = true;
+    if(mFd.valid() && (getSessId() > 0)) {
+        if(!mdp_wrapper::endRotator(mFd.getFD(), getSessId())) {
+            ALOGE("Mdp Rot error endRotator, fd=%d sessId=%d",
+                    mFd.getFD(), getSessId());
+            success = false;
+        }
+    }
+    if (!mFd.close()) {
+        ALOGE("Mdp Rot error closing fd");
+        success = false;
+    }
+    if (!mMem.close()) {
+        ALOGE("Mdp Rot error closing mem");
+        success = false;
+    }
+    reset();
+    return success;
+}
+
+bool MdpRot::unmapNonCurrent() {
+    bool ret = true;
+    for(uint32_t i=0; i < RotMem::MAX_ROT_MEM; ++i) {
+        // skip current, and if valid, close
+        if(i != mMem._curr % RotMem::MAX_ROT_MEM &&
+                mMem.m[i].valid() &&
+                !mMem.m[i].close()) {
+            ALOGE("%s error in closing prev rot mem %d", __FUNCTION__, i);
+            ret = false;
+        }
+    }
+    return ret;
+}
+
+bool MdpRot::remap(uint32_t numbufs,
+        const utils::PipeArgs& args) {
+    // if current size changed, remap
+    if(args.whf.size == mMem.curr().size()) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: same size %d", __FUNCTION__, args.whf.size);
+        return true;
+    }
+
+    // remap only if we have orientation.
+    // If rotFlags are ENABLED, it means we need rotation bufs
+    // even when orientation is 0
+    if(utils::OVERLAY_TRANSFORM_0 == args.orientation &&
+            utils::ROT_FLAG_ENABLED != args.rotFlags) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: orientation=%d, rotFlags=%d",
+                __FUNCTION__, args.orientation, args.rotFlags);
+        return true;
+    }
+
+    ALOGE_IF(DEBUG_OVERLAY, "%s: size changed - remapping", __FUNCTION__);
+    OVASSERT(!mMem.prev().valid(), "Prev should not be valid");
+
+    // remap and have the current to be the new one.
+    // ++mMem will make curr to be prev, and prev will be curr
+    ++mMem;
+    if(!open_i(numbufs, args.whf.size)) {
+        ALOGE("%s Error could not open", __FUNCTION__);
+        return false;
+    }
+    OVASSERT(numbufs <= ROT_MAX_BUF_OFFSET,
+            "Numbufs %d > ROT_MAX_BUF_OFFSET", numbufs);
+    for (uint32_t i = 0; i < numbufs; ++i) {
+        mMem.curr().mRotOffset[i] = i * args.whf.size;
+    }
+    return true;
+}
+
+bool MdpRot::start() {
+    if(!overlay::mdp_wrapper::startRotator(mFd.getFD(), mRotImgInfo)) {
+        ALOGE("MdpRot start failed");
+        this->dump();
+        return false;
+    }
+    mRotDataInfo.session_id = mRotImgInfo.session_id;
+    return true;
+}
+
+void MdpRot::reset() {
+    ovutils::memset0(mRotImgInfo);
+    ovutils::memset0(mRotDataInfo);
+    ovutils::memset0(mData);
+    ovutils::memset0(mMem.curr().mRotOffset);
+    ovutils::memset0(mMem.prev().mRotOffset);
+    mMem.curr().mCurrOffset = 0;
+    mMem.prev().mCurrOffset = 0;
+    isSrcFB = false;
+}
+
+bool MdpRot::prepareQueueBuf(uint32_t offset) {
+    // FIXME if it fails, what happens to the above current item?
+    if(enabled()) {
+        OVASSERT(mMem.curr().m.numBufs(),
+                "prepareQueueBuf numbufs is 0");
+
+        // If the rotator source is FB
+        if(isSrcFB) {
+            mRotDataInfo.src.flags |= MDP_MEMORY_ID_TYPE_FB;
+        }
+
+        mRotDataInfo.src.offset = offset;
+        mRotDataInfo.dst.offset =
+                mMem.curr().mRotOffset[mMem.curr().mCurrOffset];
+        mMem.curr().mCurrOffset =
+                (mMem.curr().mCurrOffset + 1) % mMem.curr().m.numBufs();
+        if(!overlay::mdp_wrapper::rotate(mFd.getFD(), mRotDataInfo)) {
+            ALOGE("MdpRot failed rotate");
+            return false;
+        }
+        mData.data.offset =  mRotDataInfo.dst.offset;
+    }
+    return true;
+}
+
+
+bool MdpRot::play(int fd) {
+    if(!overlay::mdp_wrapper::play(fd, mData)) {
+        ALOGE("MdpRot failed to play with fd=%d", fd);
+        return false;
+    }
+
+    // if the prev mem is valid, we need to close
+    if(mMem.prev().valid()) {
+        // FIXME FIXME FIXME if no wait for vsync the above
+        // play will return immediatly and might cause
+        // tearing when prev.close is called.
+        if(!mMem.prev().close()) {
+            ALOGE("%s error in closing prev rot mem", __FUNCTION__);
+        }
+    }
+    return true;
+}
+
+///// Null Rot ////
+
+mdp_overlay NullRotator::setInfo(
+        const utils::PipeArgs& args,
+        const mdp_overlay& o) {
+    return utils::setInfoNullRot(args, o);
+}
+
+///// Rotator ////
+
+mdp_overlay Rotator::setInfo(
+        const utils::PipeArgs& args,
+        const mdp_overlay& o)
+{
+    return utils::setInfoRot(args, o);
+}
+
+bool Rotator::overlayTransform(MdpCtrl& mdp,
+        utils::eTransform& rot)
+{
+    ALOGE_IF(DEBUG_OVERLAY, "%s: rot=%d", __FUNCTION__, rot);
+    switch(int(rot)) {
+        case 0:
+        case HAL_TRANSFORM_FLIP_H:
+        case HAL_TRANSFORM_FLIP_V:
+            overlayTransFlipHV(mdp, rot);
+            break;
+        case HAL_TRANSFORM_ROT_90:
+        case (HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_H):
+        case (HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_V):
+            overlayTransFlipRot90(mdp, rot);
+            break;
+        case HAL_TRANSFORM_ROT_180:
+            overlayTransFlipRot180(mdp);
+            break;
+        case HAL_TRANSFORM_ROT_270:
+            overlayTransFlipRot270(mdp);
+            break;
+        default:
+            ALOGE("%s: Error due to unknown rot value %d", __FUNCTION__, rot);
+            return false;
+    }
+
+    /* everything below is rotation related */
+    int r = utils::getMdpOrient(rot);
+    ALOGE_IF(DEBUG_OVERLAY, "%s: r=%d", __FUNCTION__, r);
+    if (r == -1) {
+        ALOGE("Ctrl setParameter rot it -1");
+        return false;
+    }
+
+    // Need to have both in sync
+    mdp.setUserData(r);
+    this->setRotations(r);
+    this->setDisable();
+    if(r) {
+        this->setEnable();
+    }
+
+    /* set src format using rotation info
+     * e.g. (12-->5 in case of rotation) */
+    mdp.setSrcFormat(this->getSrcWhf());
+
+    // based on 90/270 set flags
+    mdp.setRotationFlags();
+    return true;
+}
+
+void Rotator::overlayTransFlipHV(MdpCtrl& mdp,
+        utils::eTransform& rot)
+{
+    int val = mdp.getUserData();
+    ALOGE_IF(DEBUG_OVERLAY, "%s: prev=%d", __FUNCTION__, val);
+    utils::Dim d   = mdp.getSrcRectDim();
+    utils::Whf whf = mdp.getSrcWhf();
+    if (val == MDP_ROT_90) {
+        int tmp = d.y;
+        d.y = compute(whf.w,
+                d.x,
+                d.w);
+        d.x = tmp;
+        mdp.setSrcRectDim(d);
+        utils::swapOVRotWidthHeight(mRot, mdp);
+    }
+    else if (val == MDP_ROT_270) {
+        int tmp = d.x;
+        d.x = compute(whf.h,
+                d.y,
+                d.h);
+        d.y = tmp;
+        mdp.setSrcRectDim(d);
+        utils::swapOVRotWidthHeight(mRot, mdp);
+    }
+}
+
+void Rotator::overlayTransFlipRot90(MdpCtrl& mdp,
+        utils::eTransform& rot)
+{
+    int val = mdp.getUserData();
+    ALOGE_IF(DEBUG_OVERLAY, "%s: prev=%d", __FUNCTION__, val);
+    utils::Dim d   = mdp.getSrcRectDim();
+    utils::Whf whf = mdp.getSrcWhf();
+    if (val == MDP_ROT_270) {
+        d.x = compute(whf.w,
+                d.x,
+                d.w);
+        d.y = compute(whf.h,
+                d.y,
+                d.h);
+    }
+    else if (val == MDP_ROT_NOP || val == MDP_ROT_180) {
+        int tmp = d.x;
+        d.x = compute(whf.h,
+                d.y,
+                d.h);
+        d.y = tmp;
+        mdp.setSrcRectDim(d);
+        utils::swapOVRotWidthHeight(mRot, mdp);
+    }
+}
+
+void Rotator::overlayTransFlipRot180(MdpCtrl& mdp)
+{
+    int val = mdp.getUserData();
+    ALOGE_IF(DEBUG_OVERLAY, "%s: prev=%d", __FUNCTION__, val);
+    utils::Dim d   = mdp.getSrcRectDim();
+    utils::Whf whf = mdp.getSrcWhf();
+    if (val == MDP_ROT_270) {
+        int tmp = d.y;
+        d.y = compute(whf.w,
+                d.x,
+                d.w);
+        d.x = tmp;
+        mdp.setSrcRectDim(d);
+        utils::swapOVRotWidthHeight(mRot, mdp);
+    }
+    else if (val == MDP_ROT_90) {
+        int tmp = d.x;
+        d.x = compute(whf.h,
+                d.y,
+                d.h);
+        d.y = tmp;
+        mdp.setSrcRectDim(d);
+        utils::swapOVRotWidthHeight(mRot, mdp);
+    }
+}
+
+void Rotator::overlayTransFlipRot270(MdpCtrl& mdp)
+{
+    int val = mdp.getUserData();
+    ALOGE_IF(DEBUG_OVERLAY, "%s: prev=%d", __FUNCTION__, val);
+    utils::Dim d   = mdp.getSrcRectDim();
+    utils::Whf whf = mdp.getSrcWhf();
+    if (val == MDP_ROT_90) {
+        d.y = compute(whf.h,
+                d.y,
+                d.h);
+        d.x = compute(whf.w,
+                d.x,
+                d.w);
+    }
+    else if (val == MDP_ROT_NOP || val == MDP_ROT_180) {
+        int tmp = d.y;
+        d.y = compute(whf.w,
+                d.x,
+                d.w);
+        d.x = tmp;
+        mdp.setSrcRectDim(d);
+        utils::swapOVRotWidthHeight(mRot, mdp);
+    }
+}
+
+void MdpRot::dump() const {
+    ALOGE("== Dump MdpRot start ==");
+    mFd.dump();
+    mMem.curr().m.dump();
+    mdp_wrapper::dump("mRotImgInfo", mRotImgInfo);
+    mdp_wrapper::dump("mRotDataInfo", mRotDataInfo);
+    mdp_wrapper::dump("mData", mData);
+    ALOGE("== Dump MdpRot end ==");
+}
+}
diff --git a/liboverlay/overlayRotator.h b/liboverlay/overlayRotator.h
new file mode 100644
index 0000000..39c4f0c
--- /dev/null
+++ b/liboverlay/overlayRotator.h
@@ -0,0 +1,554 @@
+/*
+* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef OVERLAY_ROTATOR_H
+#define OVERLAY_ROTATOR_H
+
+#include <stdlib.h>
+
+#include "mdpWrapper.h"
+#include "overlayUtils.h"
+#include "overlayMem.h"
+
+namespace overlay {
+    class MdpCtrl;
+/*
+* MDP rot holds MDP's rotation related structures.
+*
+* */
+class MdpRot {
+public:
+    /* ctor */
+    explicit MdpRot();
+
+    /* open fd for rotator. map bufs is defered */
+    bool open();
+
+    /* remap rot buffers */
+    bool remap(uint32_t numbufs, const utils::PipeArgs& args);
+
+    /* Unmap everything that is not current */
+    bool unmapNonCurrent();
+
+    /* close fd, mem */
+    bool close();
+
+    /* reset underlying data, basically memset 0 */
+    void reset();
+
+    /* calls underlying wrappers to start rotator */
+    bool start();
+
+    /* start underlying but use given whf and flags */
+    bool start(const utils::PipeArgs& args);
+
+    /* start underlying but use given whf and flags.
+     * Has the ability to parameterize the dst fmt */
+    template <int ROT_OUT_FMT>
+            bool start(const utils::PipeArgs& args);
+
+    /* assign memory id to mdp structure */
+    void setDataMemId(int fd);
+    void setRotDataSrcMemId(int fd);
+
+    /* Mark src as FB (non-ION) */
+    void setSrcFB(bool);
+
+    /* get dst (for offset and memory id) non-virt */
+    int getDstMemId() const;
+    uint32_t getDstOffset() const;
+
+    /* set enable/disable flag */
+    void setEnable();
+    void setDisable();
+    bool enabled() const;
+
+    /* set rotator flag*/
+    void setRotations(uint32_t r);
+
+    /* set the req data id in mData */
+    void setDataReqId(int id);
+
+    /* swap rot info dst w/h */
+    void swapDstWH();
+
+    /* returns a copy of src whf */
+    utils::Whf getSrcWhf() const;
+
+    /* setup rotator data before queue buf calls
+     * call play if rotate call succeed. return false if failed */
+    bool prepareQueueBuf(uint32_t offset);
+
+    /* call play on mdp*/
+    bool play(int fd);
+
+    /* set src whf */
+    void setSrcWhf(const utils::Whf& whf);
+
+    /* returns rotator session id */
+    int getSessId() const;
+
+    /* dump the state of the object */
+    void dump() const;
+
+private:
+    bool open_i(uint32_t numbufs, uint32_t bufsz);
+
+    /* max buf no for offset */
+    enum { ROT_MAX_BUF_OFFSET = 2 };
+    /* rot info*/
+    msm_rotator_img_info mRotImgInfo;
+    /* rot data */
+    msm_rotator_data_info mRotDataInfo;
+    /* data needed for rotator */
+    msmfb_overlay_data mData;
+    /* rotator fd */
+    OvFD mFd;
+    /* Array of memory map for rotator
+     * The array enable us to change rot buffers/mapping
+     * on the fly*/
+    struct RotMem {
+        enum {MAX_ROT_MEM = 2};
+        struct Mem {
+            Mem() : mCurrOffset(0) {utils::memset0(mRotOffset); }
+            bool valid() { return m.valid(); }
+            bool close() { return m.close(); }
+            uint32_t size() const { return m.bufSz(); }
+            /* rotator data info dst offset */
+            uint32_t mRotOffset[ROT_MAX_BUF_OFFSET];
+            /* current offset slot from mRotOffset */
+            uint32_t mCurrOffset;
+            OvMem m;
+        };
+        RotMem() : _curr(0) {}
+        Mem& curr() { return m[_curr % MAX_ROT_MEM]; }
+        const Mem& curr() const { return m[_curr % MAX_ROT_MEM]; }
+        Mem& prev() { return m[(_curr+1) % MAX_ROT_MEM]; }
+        RotMem& operator++() { ++_curr; return *this; }
+        bool close();
+        uint32_t _curr;
+        Mem m[MAX_ROT_MEM];
+    } mMem;
+    bool isSrcFB;
+};
+
+/*
+* RotatorBase. No memebers, just interface.
+* ~ can also be =0 with empty impl in cpp.
+* */
+class RotatorBase {
+public:
+    /* Most of the below are No op funcs for RotatorBase */
+    virtual ~RotatorBase() {}
+    virtual bool open() = 0;
+    virtual bool remap(uint32_t numbufs, const utils::PipeArgs& args) = 0;
+    virtual bool close() = 0;
+    virtual bool start(const utils::PipeArgs& args) = 0;
+    virtual bool start() = 0;
+    virtual mdp_overlay setInfo(const utils::PipeArgs& args,
+            const mdp_overlay& o) = 0;
+    virtual bool overlayTransform(MdpCtrl& mdp,
+            utils::eTransform& rot) = 0;
+    virtual void setSrcWhf(const utils::Whf& wfh) = 0;
+    virtual utils::Whf getSrcWhf() const = 0;
+    virtual void setRotations(uint32_t r) = 0;
+    virtual void setDataReqId(int id) = 0;
+    virtual bool prepareQueueBuf(uint32_t offset) = 0;
+    virtual bool play(int fd) = 0;
+    virtual void setEnable() = 0;
+    virtual void setDisable() = 0;
+    virtual bool enabled() const = 0;
+    virtual void setDataMemId(int fd) = 0;
+    virtual void setRotDataSrcMemId(int fd) = 0;
+    virtual void setSrcFB(bool) = 0;
+    virtual int getSessId() const = 0;
+    virtual void dump() const = 0;
+};
+
+/*
+* Null/Empty impl of RotatorBase
+* */
+class NullRotator : public RotatorBase {
+public:
+    /* Most of the below are No op funcs for RotatorBase */
+    virtual ~NullRotator();
+    virtual bool open();
+    virtual bool remap(uint32_t numbufs, const utils::PipeArgs& args);
+    virtual bool close();
+    virtual bool start(const utils::PipeArgs& args);
+    virtual bool start();
+    /* null rotator behavior should set info in a specific way */
+    virtual mdp_overlay setInfo(const utils::PipeArgs& args,
+            const mdp_overlay& o);
+    virtual bool overlayTransform(MdpCtrl& o,
+            utils::eTransform& rot);
+    virtual void setSrcWhf(const utils::Whf& wfh);
+    virtual utils::Whf getSrcWhf() const;
+    virtual void setRotations(uint32_t r);
+    virtual void setDataReqId(int id);
+    virtual bool prepareQueueBuf(uint32_t offset);
+    virtual bool play(int fd);
+    virtual void setEnable();
+    virtual void setDisable();
+    virtual bool enabled () const;
+    virtual void setDataMemId(int fd);
+    virtual void setRotDataSrcMemId(int fd);
+    virtual void setSrcFB(bool);
+    virtual int getSessId() const;
+    virtual void dump() const;
+};
+
+
+/*
+* Rotator impl.
+* */
+class Rotator : public RotatorBase
+{
+public:
+    /* construct underlying object */
+    explicit Rotator();
+
+    /* close underlying rot */
+    virtual ~Rotator();
+
+    /* calls underlying open */
+    virtual bool open();
+
+    /* remap rot buffers */
+    virtual bool remap(uint32_t numbufs, const utils::PipeArgs& args);
+
+    /* calls underlying close */
+    virtual bool close();
+
+    /* calls underlying  start */
+    virtual bool start();
+
+    /* calls underlying start with whf and flags */
+    virtual bool start(const utils::PipeArgs& args);
+
+    /* non virtual - calls underlying start with whf and flags.
+     * Has the ability to parameterize the dst */
+    template <int ROT_OUT_FMT>
+            bool start(const utils::PipeArgs& args);
+
+    /* Unmap everything that is not current */
+    bool unmapNonCurrent();
+
+    /* set info using whf and given mdp */
+    virtual mdp_overlay setInfo(const utils::PipeArgs& args,
+            const mdp_overlay& o);
+
+    /* transform function for the MDP  */
+    virtual bool overlayTransform(MdpCtrl& mdp,
+            utils::eTransform& rot);
+
+    /* set src whf */
+    virtual void setSrcWhf(const utils::Whf& wfh);
+
+    /* set Rotations */
+    virtual void setRotations(uint32_t r);
+
+    /* set the req data id in mData */
+    virtual void setDataReqId(int id);
+
+    /* set memory_id */
+    virtual void setDataMemId(int fd);
+    virtual void setRotDataSrcMemId(int fd);
+
+    /* Mark the src for rotator as FB. usually set by UI mirroing cases */
+    virtual void setSrcFB(bool);
+
+    /* get dst (for offset and memory id) non-virt */
+    int getDstMemId() const;
+    uint32_t getDstOffset() const;
+
+    /* set enable/disable flag */
+    virtual void setEnable();
+    virtual void setDisable();
+    virtual bool enabled () const;
+
+    /* return rotator sess id */
+    virtual int getSessId() const;
+
+    /* return a copy of src whf*/
+    virtual utils::Whf getSrcWhf() const;
+
+    /* prepare rot for queue buf*/
+    virtual bool prepareQueueBuf(uint32_t offset);
+
+    /* call play on mdp*/
+    virtual bool play(int fd);
+
+    /* dump the state of the object */
+    virtual void dump() const;
+private:
+    /* helper functions for overlayTransform */
+    void overlayTransFlipHV(MdpCtrl& mdp,
+            utils::eTransform& rot);
+    void overlayTransFlipRot90(MdpCtrl& mdp,
+            utils::eTransform& rot);
+    void overlayTransFlipRot180(MdpCtrl& mdp);
+    void overlayTransFlipRot270(MdpCtrl& mdp);
+
+    /* underlying rotator MDP object */
+    MdpRot mRot;
+};
+
+
+//--------------inlines------------------------------------
+//// MdpRot ////
+inline MdpRot::MdpRot() { reset(); }
+inline bool MdpRot::start(const utils::PipeArgs& args) {
+    return this->start<utils::ROT_OUT_FMT_DEFAULT>(args);
+}
+
+inline void MdpRot::setDataMemId(int fd) { mData.data.memory_id = fd; }
+inline void MdpRot::setRotDataSrcMemId(int fd) {
+    mRotDataInfo.src.memory_id = fd; }
+
+inline void MdpRot::setEnable() { mRotImgInfo.enable = 1; }
+inline void MdpRot::setDisable() { mRotImgInfo.enable = 0; }
+inline bool MdpRot::enabled() const { return mRotImgInfo.enable; }
+
+inline void MdpRot::setRotations(uint32_t r) { mRotImgInfo.rotations = r; }
+inline void MdpRot::setDataReqId(int id) { mData.id = id; }
+inline void MdpRot::swapDstWH() {
+    overlay::utils::swap(mRotImgInfo.dst.width,
+            mRotImgInfo.dst.height); }
+
+inline overlay::utils::Whf MdpRot::getSrcWhf() const {
+    return overlay::utils::Whf(mRotImgInfo.src.width,
+            mRotImgInfo.src.height,
+            mRotImgInfo.src.format);
+}
+
+inline int MdpRot::getDstMemId() const {
+    return mRotDataInfo.dst.memory_id;
+}
+inline uint32_t MdpRot::getDstOffset() const {
+    return mRotDataInfo.dst.offset;
+}
+
+inline void MdpRot::setSrcWhf(const overlay::utils::Whf& whf) {
+    mRotImgInfo.src.width = whf.w;
+    mRotImgInfo.src.height = whf.h;
+    mRotImgInfo.src.format = whf.format;
+}
+
+inline int MdpRot::getSessId() const { return mRotImgInfo.session_id; }
+
+inline void MdpRot::setSrcFB(bool mark) { isSrcFB = mark; }
+
+///// Null Rotator /////
+inline NullRotator::~NullRotator() {}
+inline bool NullRotator::open() {
+    return true; }
+inline bool NullRotator::remap(uint32_t numbufs,
+        const utils::PipeArgs& args){
+    return true; }
+inline bool NullRotator::close() { return true; }
+inline bool NullRotator::start(const utils::PipeArgs& args)
+{ return true; }
+
+inline bool NullRotator::start() { return true; }
+inline bool NullRotator::overlayTransform(MdpCtrl& o,
+        utils::eTransform& rot)
+{ return true; }
+inline void NullRotator::setSrcWhf(const overlay::utils::Whf& wfh) {}
+inline void NullRotator::setRotations(uint32_t) {}
+inline void NullRotator::setDataReqId(int id) {}
+inline void NullRotator::setEnable() {}
+inline void NullRotator::setDisable() {}
+inline bool NullRotator::enabled() const { return false; }
+inline int NullRotator::getSessId() const { return -1; }
+inline overlay::utils::Whf NullRotator::getSrcWhf() const {
+    return overlay::utils::Whf(); }
+inline bool NullRotator::prepareQueueBuf(uint32_t offset)
+{ return true; }
+inline bool NullRotator::play(int fd)
+{ return true; }
+inline void NullRotator::setDataMemId(int fd) {}
+inline void NullRotator::setRotDataSrcMemId(int fd) {}
+inline void NullRotator::setSrcFB(bool) {}
+inline void NullRotator::dump() const {
+    ALOGE("== Dump NullRotator dump (null) start/end ==");
+}
+
+///// Rotator /////
+inline Rotator::Rotator() { }
+
+inline Rotator::~Rotator() {
+    mRot.close(); // also will do reset
+}
+
+inline bool Rotator::open() {
+    if(!mRot.open()) {
+        ALOGE("Rotator::open failed");
+        return false;
+    }
+    return true;
+}
+
+template <int ROT_OUT_FMT>
+inline bool Rotator::start(const utils::PipeArgs& args) {
+    return mRot.start<ROT_OUT_FMT>(args);
+}
+
+inline bool Rotator::remap(uint32_t numbufs,
+        const utils::PipeArgs& args){
+    if(!mRot.remap(numbufs, args)) {
+        ALOGE("%s failed", __FUNCTION__);
+        return false;
+    }
+    return true;
+}
+
+inline bool Rotator::close() {
+    return mRot.close();
+}
+
+inline bool Rotator::start() {
+    return mRot.start();
+}
+
+inline bool Rotator::start(const utils::PipeArgs& args) {
+    return mRot.start(args);
+}
+
+inline bool Rotator::unmapNonCurrent() {
+    return mRot.unmapNonCurrent();
+}
+
+inline void Rotator::setEnable(){ mRot.setEnable(); }
+inline void Rotator::setDisable(){ mRot.setDisable(); }
+inline bool Rotator::enabled() const { return mRot.enabled(); }
+inline void Rotator::setDataMemId(int fd) {
+    mRot.setDataMemId(fd); }
+
+inline void Rotator::setRotDataSrcMemId(int fd) {
+    mRot.setRotDataSrcMemId(fd);
+}
+
+inline void Rotator::setSrcFB(bool mark) { mRot.setSrcFB(mark); }
+
+inline int Rotator::getDstMemId() const {
+    return mRot.getDstMemId();
+}
+inline uint32_t Rotator::getDstOffset() const {
+    return mRot.getDstOffset();
+}
+
+inline void Rotator::setDataReqId(int id) {
+    mRot.setDataReqId(id);
+}
+
+inline void Rotator::setSrcWhf(
+        const overlay::utils::Whf& whf) {
+    mRot.setSrcWhf(whf);
+}
+
+inline void Rotator::setRotations(uint32_t rot) {
+    mRot.setRotations (rot);
+}
+
+inline int Rotator::getSessId() const {
+    return mRot.getSessId(); }
+
+inline void Rotator::dump() const {
+    ALOGE("== Dump Rotator start ==");
+    mRot.dump();
+    ALOGE("== Dump Rotator end ==");
+}
+
+inline overlay::utils::Whf Rotator::getSrcWhf() const {
+    return mRot.getSrcWhf(); }
+
+inline bool Rotator::prepareQueueBuf(uint32_t offset)
+{
+    return mRot.prepareQueueBuf(offset);
+}
+
+inline bool Rotator::play(int fd)
+{
+    return mRot.play(fd);
+}
+
+template <int ROT_OUT_FMT>
+bool MdpRot::start(const utils::PipeArgs& args) {
+    // Do nothing when no orientation
+    if(utils::OVERLAY_TRANSFORM_0 == args.orientation &&
+            utils::ROT_FLAG_ENABLED != args.rotFlags) {
+        return true;
+    }
+    utils::Whf whf(args.whf);
+    mRotImgInfo.src.format = whf.format;
+    mRotImgInfo.src.width = whf.w;
+    mRotImgInfo.src.height = whf.h;
+    mRotImgInfo.src_rect.w = whf.w;
+    mRotImgInfo.src_rect.h = whf.h;
+    mRotImgInfo.dst.width = whf.w;
+    mRotImgInfo.dst.height = whf.h;
+    if(whf.format == MDP_Y_CRCB_H2V2_TILE ||
+        whf.format == MDP_Y_CBCR_H2V2_TILE) {
+        mRotImgInfo.src.width =  utils::alignup(whf.w, 64);
+        mRotImgInfo.src.height = utils::alignup(whf.h, 32);
+        mRotImgInfo.src_rect.w = utils::alignup(whf.w, 64);
+        mRotImgInfo.src_rect.h = utils::alignup(whf.h, 32);
+        mRotImgInfo.dst.width  = utils::alignup(whf.w, 64);
+        mRotImgInfo.dst.height = utils::alignup(whf.h, 32);
+        mRotImgInfo.dst.format = MDP_Y_CRCB_H2V2;
+    }
+    // either utils::getRotOutFmt(whf.format); or supplied fmt
+    // utils::RotOutFmt<ROT_OUT_FMT_DEFAULT>::fmt;
+    mRotImgInfo.dst.format = utils::RotOutFmt<ROT_OUT_FMT>::fmt(whf.format);
+    mRotImgInfo.dst_x = 0;
+    mRotImgInfo.dst_y = 0;
+    mRotImgInfo.src_rect.x = 0;
+    mRotImgInfo.src_rect.y = 0;
+    mRotImgInfo.rotations = 0;
+    // ROT_FLAG_DISABLED / ENABLED
+    // Refer to overlayUtils.h eRotFlags
+    // for more info
+    mRotImgInfo.enable = args.rotFlags;
+    mRotImgInfo.session_id = mRotImgInfo.session_id ?
+            mRotImgInfo.session_id : 0;
+
+    return start();
+}
+
+} // overlay
+
+namespace {
+// just a helper func for Rotator common operations x-(y+z)
+int compute(uint32_t x, uint32_t y, uint32_t z) {
+    return x-(y+z);
+}
+}
+
+#endif // OVERLAY_ROTATOR_H
diff --git a/liboverlay/overlayState.h b/liboverlay/overlayState.h
new file mode 100644
index 0000000..1d13a2e
--- /dev/null
+++ b/liboverlay/overlayState.h
@@ -0,0 +1,907 @@
+/*
+* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef OVERLAY_STATE_H
+#define OVERLAY_STATE_H
+
+#include "overlayUtils.h"
+#include "overlayImpl.h"
+#include "overlayRotator.h"
+#include "pipes/overlayGenPipe.h"
+#include "pipes/overlayBypassPipe.h"
+#include "pipes/overlayHdmiPipe.h"
+#include "pipes/overlayUIMirrorPipe.h"
+#include "pipes/overlay3DPipe.h"
+
+// FIXME make int to be uint32 whenever possible
+
+namespace overlay {
+
+/*
+* Used by Overlay class. Invokes each event
+* */
+
+/* TODO case of RGBx will call mOv open with diff
+* params customized for RGBx pipes */
+
+class OverlayState : utils::NoCopy {
+public:
+    /**/
+    explicit OverlayState();
+
+    /**/
+    ~OverlayState();
+
+    /* return current state */
+    utils::eOverlayState state() const;
+
+    /* Overlay Event */
+
+    /* Hard reset to a new state. If the state is the same
+     * as the current one, it would be a no-op */
+    OverlayImplBase* reset(utils::eOverlayState s);
+
+    /* Caller pass the state to the handleEvent function.
+     * The input is the current OverlayImplBase*, and output is
+     * a pointer to (possibly new) instance of OverlayImplBase
+     * The eFormat can be 2D/3D etc. */
+    OverlayImplBase* handleEvent(utils::eOverlayState s,
+            OverlayImplBase* ov);
+
+    /* Transitions from XXX to XXX */
+    OverlayImplBase* handle_closed(utils::eOverlayState s);
+    OverlayImplBase* handle_2D_2DPanel(utils::eOverlayState s,
+            OverlayImplBase* ov);
+    OverlayImplBase* handle_2D_2DTV(utils::eOverlayState s,
+            OverlayImplBase* ov);
+    OverlayImplBase* handle_3D_2DPanel(utils::eOverlayState s,
+            OverlayImplBase* ov);
+    OverlayImplBase* handle_3D_3DPanel(utils::eOverlayState s,
+            OverlayImplBase* ov);
+    OverlayImplBase* handle_3D_3DTV(utils::eOverlayState s,
+            OverlayImplBase* ov);
+    OverlayImplBase* handle_3D_2DTV(utils::eOverlayState s,
+            OverlayImplBase* ov);
+    OverlayImplBase* handle_UI_Mirror(utils::eOverlayState s,
+            OverlayImplBase* ov);
+    OverlayImplBase* handle_2D_trueUI_Mirror(utils::eOverlayState s,
+            OverlayImplBase* ov);
+    OverlayImplBase* handle_bypass(utils::eOverlayState s,
+            OverlayImplBase* ov);
+
+    /* Transition from any state to 2D video on 2D panel */
+    OverlayImplBase* handle_xxx_to_2D_2DPanel(OverlayImplBase* ov);
+
+    /* Transition from any state to 2D video on 2D panel and 2D TV */
+    OverlayImplBase* handle_xxx_to_2D_2DTV(OverlayImplBase* ov);
+
+    /* Transition from any state to 3D video on 2D panel */
+    OverlayImplBase* handle_xxx_to_3D_2DPanel(OverlayImplBase* ov);
+
+    /* Transition from any state to 3D video on 2D panel and 2D TV */
+    OverlayImplBase* handle_xxx_to_3D_2DTV(OverlayImplBase* ov);
+
+    /* Transition from any state to 2D video true UI mirroring (2D video + UI) */
+    OverlayImplBase* handle_xxx_to_2D_trueUI_Mirror(OverlayImplBase* ov);
+
+    /* Transitions from any state to 1 layer composition bypass */
+    OverlayImplBase* handle_xxx_to_bypass1(OverlayImplBase* ov);
+
+    /* Transitions from any state to 2 layers composition bypass */
+    OverlayImplBase* handle_xxx_to_bypass2(OverlayImplBase* ov);
+
+    /* Transitions from any state to 3 layers composition bypass */
+    OverlayImplBase* handle_xxx_to_bypass3(OverlayImplBase* ov);
+
+    /* Dump */
+    void dump() const;
+private:
+    /* States here */
+    utils::eOverlayState mState;
+};
+
+//------------------------State Traits --------------------------
+
+// primary has nothing
+template <int STATE> struct StateTraits {};
+
+/*
+ * For 3D_xxx we need channel ID besides the FBx since
+ * get crop/position 3D need that to determine pos/crop
+ * info.
+ * */
+
+template <> struct StateTraits<utils::OV_2D_VIDEO_ON_PANEL>
+{
+    typedef overlay::GenericPipe<utils::PRIMARY> pipe0;
+    typedef overlay::NullPipe pipe1;   // place holder
+    typedef overlay::NullPipe pipe2;   // place holder
+
+    typedef Rotator rot0;
+    typedef NullRotator rot1;
+    typedef NullRotator rot2;
+
+    typedef overlay::OverlayImpl<pipe0> ovimpl;
+};
+
+template <> struct StateTraits<utils::OV_2D_VIDEO_ON_PANEL_TV>
+{
+    typedef overlay::GenericPipe<utils::PRIMARY> pipe0;
+    typedef overlay::HdmiPipe pipe1;
+    typedef overlay::NullPipe pipe2;   // place holder
+
+    typedef Rotator rot0;
+    typedef NullRotator rot1;
+    typedef NullRotator rot2;
+
+    typedef overlay::OverlayImpl<pipe0, pipe1> ovimpl;
+};
+
+template <> struct StateTraits<utils::OV_3D_VIDEO_ON_2D_PANEL>
+{
+    typedef overlay::M3DPrimaryPipe<utils::OV_PIPE0> pipe0;
+    typedef overlay::NullPipe pipe1;   // place holder
+    typedef overlay::NullPipe pipe2;   // place holder
+
+    typedef Rotator rot0;
+    typedef NullRotator rot1;
+    typedef NullRotator rot2;
+
+    typedef overlay::OverlayImpl<pipe0> ovimpl;
+};
+
+template <> struct StateTraits<utils::OV_3D_VIDEO_ON_3D_PANEL>
+{
+    typedef overlay::S3DPrimaryPipe<utils::OV_PIPE0> pipe0;
+    typedef overlay::S3DPrimaryPipe<utils::OV_PIPE1> pipe1;
+    typedef overlay::NullPipe pipe2;   // place holder
+
+    typedef Rotator rot0;
+    typedef Rotator rot1;
+    typedef NullRotator rot2;
+
+    typedef overlay::OverlayImpl<pipe0, pipe1> ovimpl;
+};
+
+template <> struct StateTraits<utils::OV_3D_VIDEO_ON_3D_TV>
+{
+    typedef overlay::S3DExtPipe<utils::OV_PIPE0> pipe0;
+    typedef overlay::S3DExtPipe<utils::OV_PIPE1> pipe1;
+    typedef overlay::NullPipe pipe2;   // place holder
+
+    typedef NullRotator rot0;
+    typedef NullRotator rot1;
+    typedef NullRotator rot2;
+
+    typedef overlay::OverlayImpl<pipe0, pipe1> ovimpl;
+};
+
+template <> struct StateTraits<utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV>
+{
+    typedef overlay::M3DPrimaryPipe<utils::OV_PIPE0> pipe0;
+    typedef overlay::M3DExtPipe<utils::OV_PIPE1> pipe1;
+    typedef overlay::NullPipe pipe2;   // place holder
+
+    typedef Rotator rot0;
+    typedef NullRotator rot1;
+    typedef NullRotator rot2;
+
+    typedef overlay::OverlayImpl<pipe0, pipe1> ovimpl;
+};
+
+template <> struct StateTraits<utils::OV_UI_MIRROR>
+{
+    typedef overlay::UIMirrorPipe pipe0;
+    typedef overlay::NullPipe pipe1;   // place holder
+    typedef overlay::NullPipe pipe2;   // place holder
+
+    typedef Rotator rot0;
+    typedef NullRotator rot1;
+    typedef NullRotator rot2;
+
+    typedef overlay::OverlayImpl<pipe0> ovimpl;
+};
+
+template <> struct StateTraits<utils::OV_2D_TRUE_UI_MIRROR>
+{
+    typedef overlay::GenericPipe<utils::PRIMARY> pipe0;
+    typedef overlay::HdmiPipe pipe1;
+    typedef overlay::UIMirrorPipe pipe2;
+
+    typedef Rotator rot0;
+    typedef NullRotator rot1;
+    typedef Rotator rot2;
+
+    typedef overlay::OverlayImpl<pipe0, pipe1, pipe2> ovimpl;
+};
+
+template <> struct StateTraits<utils::OV_BYPASS_1_LAYER>
+{
+    typedef overlay::BypassPipe<utils::OV_MDP_PIPE_VG, utils::IS_FG_SET, utils::WAIT, utils::ZORDER_0> pipe0;
+    typedef overlay::NullPipe pipe1;   // place holder
+    typedef overlay::NullPipe pipe2;   // place holder
+
+    typedef NullRotator rot0;
+    typedef NullRotator rot1;
+    typedef NullRotator rot2;
+
+    typedef overlay::OverlayImpl<pipe0> ovimpl;
+};
+
+template <> struct StateTraits<utils::OV_BYPASS_2_LAYER>
+{
+    typedef overlay::BypassPipe<utils::OV_MDP_PIPE_VG, utils::IS_FG_SET, utils::NO_WAIT, utils::ZORDER_0> pipe0;
+    typedef overlay::BypassPipe<utils::OV_MDP_PIPE_VG, utils::IS_FG_OFF, utils::WAIT, utils::ZORDER_1> pipe1;
+    typedef overlay::NullPipe pipe2;   // place holder
+
+    typedef NullRotator rot0;
+    typedef NullRotator rot1;
+    typedef NullRotator rot2;
+
+    typedef overlay::OverlayImpl<pipe0, pipe1> ovimpl;
+};
+
+template <> struct StateTraits<utils::OV_BYPASS_3_LAYER>
+{
+    typedef overlay::BypassPipe<utils::OV_MDP_PIPE_VG, utils::IS_FG_SET, utils::NO_WAIT, utils::ZORDER_0> pipe0;
+    typedef overlay::BypassPipe<utils::OV_MDP_PIPE_VG, utils::IS_FG_OFF, utils::NO_WAIT, utils::ZORDER_1> pipe1;
+    typedef overlay::BypassPipe<utils::OV_MDP_PIPE_RGB, utils::IS_FG_OFF, utils::WAIT, utils::ZORDER_2> pipe2;
+
+    typedef NullRotator rot0;
+    typedef NullRotator rot1;
+    typedef NullRotator rot2;
+
+    typedef overlay::OverlayImpl<pipe0, pipe1, pipe2> ovimpl;
+};
+
+
+//------------------------Inlines --------------------------------
+
+inline OverlayState::OverlayState() : mState(utils::OV_CLOSED)
+{}
+
+inline OverlayState::~OverlayState() {}
+
+inline utils::eOverlayState OverlayState::state() const
+{
+    return mState;
+}
+
+inline OverlayImplBase* OverlayState::reset(utils::eOverlayState s)
+{
+    return handleEvent(s, 0);
+}
+
+inline void OverlayState::dump() const
+{
+    ALOGE("== Dump state %d start/end ==", mState);
+}
+
+template <int STATE>
+inline OverlayImplBase* handle_closed_to_xxx()
+{
+    OverlayImplBase* ov = new typename StateTraits<STATE>::ovimpl;
+    RotatorBase* rot0 = new typename StateTraits<STATE>::rot0;
+    RotatorBase* rot1 = new typename StateTraits<STATE>::rot1;
+    RotatorBase* rot2 = new typename StateTraits<STATE>::rot2;
+    if(!ov->open(rot0, rot1, rot2)) {
+        ALOGE("Overlay failed to open in state %d", STATE);
+        return 0;
+    }
+    return ov;
+}
+
+inline OverlayImplBase* handle_xxx_to_closed(OverlayImplBase* ov)
+{
+    OVASSERT(ov, "%s: ov is null", __FUNCTION__);
+
+    if(!ov->close()) {
+        ALOGE("%s: Failed to ov close", __FUNCTION__);
+    }
+    delete ov;
+    ov = 0;
+    return 0;
+}
+
+/* Hard transitions from any state to any state will close and then open */
+template <int STATE>
+inline OverlayImplBase* handle_xxx_to_xxx(OverlayImplBase* ov)
+{
+    OVASSERT(ov, "%s: ov is null", __FUNCTION__);
+
+    handle_xxx_to_closed(ov);
+    return handle_closed_to_xxx<STATE>();
+}
+
+inline OverlayImplBase* OverlayState::handleEvent(utils::eOverlayState newState,
+        OverlayImplBase* ov)
+{
+    OverlayImplBase* newov = ov; // at least, we return the same
+    if (mState != newState) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: state changed %s-->%s",
+                __FUNCTION__, getStateString(mState), getStateString(newState));
+    } else {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: no state change, state=%s",
+                __FUNCTION__, getStateString(newState));
+        return newov;
+    }
+
+    switch(mState)
+    {
+        case utils::OV_CLOSED:
+            newov = handle_closed(newState);
+            break;
+        case utils::OV_2D_VIDEO_ON_PANEL:
+            newov = handle_2D_2DPanel(newState, ov);
+            break;
+        case utils::OV_2D_VIDEO_ON_PANEL_TV:
+            newov = handle_2D_2DTV(newState, ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_2D_PANEL:
+            newov = handle_3D_2DPanel(newState, ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_3D_PANEL:
+            newov = handle_3D_3DPanel(newState, ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_3D_TV:
+            newov = handle_3D_3DTV(newState, ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
+            newov = handle_3D_2DTV(newState, ov);
+            break;
+        case utils::OV_UI_MIRROR:
+            newov = handle_UI_Mirror(newState, ov);
+            break;
+        case utils::OV_2D_TRUE_UI_MIRROR:
+            newov = handle_2D_trueUI_Mirror(newState, ov);
+            break;
+        case utils::OV_BYPASS_1_LAYER:
+        case utils::OV_BYPASS_2_LAYER:
+        case utils::OV_BYPASS_3_LAYER:
+            newov = handle_bypass(newState, ov);
+            break;
+        default:
+            ALOGE("%s: unknown state=%d", __FUNCTION__, mState);
+    }
+
+    // FIXME, how to communicate bad transition?
+    // Should we have bool returned from transition func?
+
+    return newov;
+}
+
+// Transitions from closed to XXX
+inline OverlayImplBase* OverlayState::handle_closed(utils::eOverlayState s)
+{
+    OverlayImplBase* ov = 0;
+    switch(s)
+    {
+        case utils::OV_CLOSED:
+            // no state change
+            break;
+        case utils::OV_2D_VIDEO_ON_PANEL:
+            ov = handle_closed_to_xxx<utils::OV_2D_VIDEO_ON_PANEL>();
+            break;
+        case utils::OV_2D_VIDEO_ON_PANEL_TV:
+            ov = handle_closed_to_xxx<utils::OV_2D_VIDEO_ON_PANEL_TV>();
+            break;
+        case utils::OV_3D_VIDEO_ON_2D_PANEL:
+            ov = handle_closed_to_xxx<utils::OV_3D_VIDEO_ON_2D_PANEL>();
+            break;
+        case utils::OV_3D_VIDEO_ON_3D_PANEL:
+            ov = handle_closed_to_xxx<utils::OV_3D_VIDEO_ON_3D_PANEL>();
+            break;
+        case utils::OV_3D_VIDEO_ON_3D_TV:
+            ov = handle_closed_to_xxx<utils::OV_3D_VIDEO_ON_3D_TV>();
+            break;
+        case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
+            ov = handle_closed_to_xxx<utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV>();
+            break;
+        case utils::OV_UI_MIRROR:
+            ov = handle_closed_to_xxx<utils::OV_UI_MIRROR>();
+            break;
+        case utils::OV_2D_TRUE_UI_MIRROR:
+            ov = handle_closed_to_xxx<utils::OV_2D_TRUE_UI_MIRROR>();
+            break;
+        case utils::OV_BYPASS_1_LAYER:
+            ov = handle_closed_to_xxx<utils::OV_BYPASS_1_LAYER>();
+            break;
+        case utils::OV_BYPASS_2_LAYER:
+            ov = handle_closed_to_xxx<utils::OV_BYPASS_2_LAYER>();
+            break;
+        case utils::OV_BYPASS_3_LAYER:
+            ov = handle_closed_to_xxx<utils::OV_BYPASS_3_LAYER>();
+            break;
+        default:
+            ALOGE("%s: unknown state=%d", __FUNCTION__, s);
+    }
+    mState = s;
+    return ov;
+}
+
+// Transitions from 2D video on 2D panel to XXX
+inline OverlayImplBase* OverlayState::handle_2D_2DPanel(
+        utils::eOverlayState s,
+        OverlayImplBase* ov)
+{
+    OverlayImplBase* newov = ov;
+    switch(s)
+    {
+        case utils::OV_CLOSED:
+            newov = handle_xxx_to_closed(ov);
+            break;
+        case utils::OV_2D_VIDEO_ON_PANEL:
+            // no state change
+            break;
+        case utils::OV_2D_VIDEO_ON_PANEL_TV:
+            newov = handle_xxx_to_2D_2DTV(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_2D_PANEL:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_2D_PANEL>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_3D_PANEL:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_3D_PANEL>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_3D_TV:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_3D_TV>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV>(ov);
+            break;
+        case utils::OV_UI_MIRROR:
+            newov = handle_xxx_to_xxx<utils::OV_UI_MIRROR>(ov);
+            break;
+        case utils::OV_2D_TRUE_UI_MIRROR:
+            newov = handle_xxx_to_2D_trueUI_Mirror(ov);
+            break;
+        case utils::OV_BYPASS_1_LAYER:
+            newov = handle_xxx_to_xxx<utils::OV_BYPASS_1_LAYER>(ov);
+            break;
+        case utils::OV_BYPASS_2_LAYER:
+            newov = handle_xxx_to_xxx<utils::OV_BYPASS_2_LAYER>(ov);
+            break;
+        case utils::OV_BYPASS_3_LAYER:
+            newov = handle_xxx_to_xxx<utils::OV_BYPASS_3_LAYER>(ov);
+            break;
+        default:
+            ALOGE("%s: unknown state=%d", __FUNCTION__, s);
+    }
+    mState = s;
+    return newov;
+}
+
+// Transitions from 2D video on 2D panel and 2D TV to XXX
+inline OverlayImplBase* OverlayState::handle_2D_2DTV(
+        utils::eOverlayState s,
+        OverlayImplBase* ov)
+{
+    OverlayImplBase* newov = ov;
+    switch(s)
+    {
+        case utils::OV_CLOSED:
+            newov = handle_xxx_to_closed(ov);
+            break;
+        case utils::OV_2D_VIDEO_ON_PANEL:
+            newov = handle_xxx_to_2D_2DPanel(ov);
+            break;
+        case utils::OV_2D_VIDEO_ON_PANEL_TV:
+            // no state change
+            break;
+        case utils::OV_3D_VIDEO_ON_2D_PANEL:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_2D_PANEL>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_3D_PANEL:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_3D_PANEL>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_3D_TV:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_3D_TV>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV>(ov);
+            break;
+        case utils::OV_UI_MIRROR:
+            newov = handle_xxx_to_xxx<utils::OV_UI_MIRROR>(ov);
+            break;
+        case utils::OV_2D_TRUE_UI_MIRROR:
+            newov = handle_xxx_to_2D_trueUI_Mirror(ov);
+            break;
+        case utils::OV_BYPASS_1_LAYER:
+            newov = handle_xxx_to_xxx<utils::OV_BYPASS_1_LAYER>(ov);
+            break;
+        case utils::OV_BYPASS_2_LAYER:
+            newov = handle_xxx_to_xxx<utils::OV_BYPASS_2_LAYER>(ov);
+            break;
+        case utils::OV_BYPASS_3_LAYER:
+            newov = handle_xxx_to_xxx<utils::OV_BYPASS_3_LAYER>(ov);
+            break;
+        default:
+            ALOGE("%s: unknown state=%d", __FUNCTION__, s);
+    }
+    mState = s;
+    return newov;
+}
+
+// Transitions from 3D video on 2D panel to XXX
+inline OverlayImplBase* OverlayState::handle_3D_2DPanel(
+        utils::eOverlayState s,
+        OverlayImplBase* ov)
+{
+    OverlayImplBase* newov = ov;
+    switch(s)
+    {
+        case utils::OV_CLOSED:
+            newov = handle_xxx_to_closed(ov);
+            break;
+        case utils::OV_2D_VIDEO_ON_PANEL:
+            newov = handle_xxx_to_xxx<utils::OV_2D_VIDEO_ON_PANEL>(ov);
+            break;
+        case utils::OV_2D_VIDEO_ON_PANEL_TV:
+            newov = handle_xxx_to_xxx<utils::OV_2D_VIDEO_ON_PANEL_TV>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_2D_PANEL:
+            // no state change
+            break;
+        case utils::OV_3D_VIDEO_ON_3D_PANEL:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_3D_PANEL>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_3D_TV:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_3D_TV>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
+            newov = handle_xxx_to_3D_2DTV(ov);
+            break;
+        case utils::OV_UI_MIRROR:
+            newov = handle_xxx_to_xxx<utils::OV_UI_MIRROR>(ov);
+            break;
+        case utils::OV_2D_TRUE_UI_MIRROR:
+            newov = handle_xxx_to_xxx<utils::OV_2D_TRUE_UI_MIRROR>(ov);
+            break;
+        case utils::OV_BYPASS_1_LAYER:
+            newov = handle_xxx_to_xxx<utils::OV_BYPASS_1_LAYER>(ov);
+            break;
+        case utils::OV_BYPASS_2_LAYER:
+            newov = handle_xxx_to_xxx<utils::OV_BYPASS_2_LAYER>(ov);
+            break;
+        case utils::OV_BYPASS_3_LAYER:
+            newov = handle_xxx_to_xxx<utils::OV_BYPASS_3_LAYER>(ov);
+            break;
+        default:
+            ALOGE("%s: unknown state=%d", __FUNCTION__, s);
+    }
+    mState = s;
+    return newov;
+}
+
+// Transitions from 3D video on 3D panel to XXX
+inline OverlayImplBase* OverlayState::handle_3D_3DPanel(
+        utils::eOverlayState s,
+        OverlayImplBase* ov)
+{
+    OverlayImplBase* newov = ov;
+    switch(s)
+    {
+        case utils::OV_CLOSED:
+            newov = handle_xxx_to_closed(ov);
+            break;
+        case utils::OV_2D_VIDEO_ON_PANEL:
+            newov = handle_xxx_to_xxx<utils::OV_2D_VIDEO_ON_PANEL>(ov);
+            break;
+        case utils::OV_2D_VIDEO_ON_PANEL_TV:
+            newov = handle_xxx_to_xxx<utils::OV_2D_VIDEO_ON_PANEL_TV>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_2D_PANEL:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_2D_PANEL>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_3D_PANEL:
+            // no state change
+            break;
+        case utils::OV_3D_VIDEO_ON_3D_TV:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_3D_TV>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV>(ov);
+            break;
+        case utils::OV_UI_MIRROR:
+            newov = handle_xxx_to_xxx<utils::OV_UI_MIRROR>(ov);
+            break;
+        case utils::OV_2D_TRUE_UI_MIRROR:
+            newov = handle_xxx_to_xxx<utils::OV_2D_TRUE_UI_MIRROR>(ov);
+            break;
+        case utils::OV_BYPASS_1_LAYER:
+            newov = handle_xxx_to_xxx<utils::OV_BYPASS_1_LAYER>(ov);
+            break;
+        case utils::OV_BYPASS_2_LAYER:
+            newov = handle_xxx_to_xxx<utils::OV_BYPASS_2_LAYER>(ov);
+            break;
+        case utils::OV_BYPASS_3_LAYER:
+            newov = handle_xxx_to_xxx<utils::OV_BYPASS_3_LAYER>(ov);
+            break;
+        default:
+            ALOGE("%s: unknown state=%d", __FUNCTION__, s);
+    }
+    mState = s;
+    return newov;
+}
+
+// Transitions from 3D video on 3D TV to XXX
+inline OverlayImplBase* OverlayState::handle_3D_3DTV(
+        utils::eOverlayState s,
+        OverlayImplBase* ov)
+{
+    OverlayImplBase* newov = ov;
+    switch(s)
+    {
+        case utils::OV_CLOSED:
+            newov = handle_xxx_to_closed(ov);
+            break;
+        case utils::OV_2D_VIDEO_ON_PANEL:
+            newov = handle_xxx_to_xxx<utils::OV_2D_VIDEO_ON_PANEL>(ov);
+            break;
+        case utils::OV_2D_VIDEO_ON_PANEL_TV:
+            newov = handle_xxx_to_xxx<utils::OV_2D_VIDEO_ON_PANEL_TV>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_2D_PANEL:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_2D_PANEL>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_3D_PANEL:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_3D_PANEL>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_3D_TV:
+            // no state change
+            break;
+        case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV>(ov);
+            break;
+        case utils::OV_UI_MIRROR:
+            newov = handle_xxx_to_xxx<utils::OV_UI_MIRROR>(ov);
+            break;
+        case utils::OV_2D_TRUE_UI_MIRROR:
+            newov = handle_xxx_to_xxx<utils::OV_2D_TRUE_UI_MIRROR>(ov);
+            break;
+        case utils::OV_BYPASS_1_LAYER:
+            newov = handle_xxx_to_xxx<utils::OV_BYPASS_1_LAYER>(ov);
+            break;
+        case utils::OV_BYPASS_2_LAYER:
+            newov = handle_xxx_to_xxx<utils::OV_BYPASS_2_LAYER>(ov);
+            break;
+        case utils::OV_BYPASS_3_LAYER:
+            newov = handle_xxx_to_xxx<utils::OV_BYPASS_3_LAYER>(ov);
+            break;
+        default:
+            ALOGE("%s: unknown state=%d", __FUNCTION__, s);
+    }
+    mState = s;
+    return newov;
+}
+
+// Transitions from 3D video on 2D panel and 2D TV to XXX
+inline OverlayImplBase* OverlayState::handle_3D_2DTV(
+        utils::eOverlayState s,
+        OverlayImplBase* ov)
+{
+    OverlayImplBase* newov = ov;
+    switch(s)
+    {
+        case utils::OV_CLOSED:
+            newov = handle_xxx_to_closed(ov);
+            break;
+        case utils::OV_2D_VIDEO_ON_PANEL:
+            newov = handle_xxx_to_xxx<utils::OV_2D_VIDEO_ON_PANEL>(ov);
+            break;
+        case utils::OV_2D_VIDEO_ON_PANEL_TV:
+            newov = handle_xxx_to_xxx<utils::OV_2D_VIDEO_ON_PANEL_TV>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_2D_PANEL:
+            newov = handle_xxx_to_3D_2DPanel(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_3D_PANEL:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_3D_PANEL>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_3D_TV:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_3D_TV>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
+            // no state change
+            break;
+        case utils::OV_UI_MIRROR:
+            newov = handle_xxx_to_xxx<utils::OV_UI_MIRROR>(ov);
+            break;
+        case utils::OV_2D_TRUE_UI_MIRROR:
+            newov = handle_xxx_to_xxx<utils::OV_2D_TRUE_UI_MIRROR>(ov);
+            break;
+        case utils::OV_BYPASS_1_LAYER:
+            newov = handle_xxx_to_xxx<utils::OV_BYPASS_1_LAYER>(ov);
+            break;
+        case utils::OV_BYPASS_2_LAYER:
+            newov = handle_xxx_to_xxx<utils::OV_BYPASS_2_LAYER>(ov);
+            break;
+        case utils::OV_BYPASS_3_LAYER:
+            newov = handle_xxx_to_xxx<utils::OV_BYPASS_3_LAYER>(ov);
+            break;
+        default:
+            ALOGE("%s: unknown state=%d", __FUNCTION__, s);
+    }
+    mState = s;
+    return newov;
+}
+
+// Transitions from UI mirroring to XXX
+inline OverlayImplBase* OverlayState::handle_UI_Mirror(utils::eOverlayState s,
+        OverlayImplBase* ov)
+{
+    OverlayImplBase* newov = ov;
+    switch(s)
+    {
+        case utils::OV_CLOSED:
+            newov = handle_xxx_to_closed(ov);
+            break;
+        case utils::OV_2D_VIDEO_ON_PANEL:
+            newov = handle_xxx_to_xxx<utils::OV_2D_VIDEO_ON_PANEL>(ov);
+            break;
+        case utils::OV_2D_VIDEO_ON_PANEL_TV:
+            newov = handle_xxx_to_xxx<utils::OV_2D_VIDEO_ON_PANEL_TV>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_2D_PANEL:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_2D_PANEL>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_3D_PANEL:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_3D_PANEL>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_3D_TV:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_3D_TV>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV>(ov);
+            break;
+        case utils::OV_UI_MIRROR:
+            // no state change
+            break;
+        case utils::OV_2D_TRUE_UI_MIRROR:
+            newov = handle_xxx_to_xxx<utils::OV_2D_TRUE_UI_MIRROR>(ov);
+            break;
+        case utils::OV_BYPASS_1_LAYER:
+            newov = handle_xxx_to_xxx<utils::OV_BYPASS_1_LAYER>(ov);
+            break;
+        case utils::OV_BYPASS_2_LAYER:
+            newov = handle_xxx_to_xxx<utils::OV_BYPASS_2_LAYER>(ov);
+            break;
+        case utils::OV_BYPASS_3_LAYER:
+            newov = handle_xxx_to_xxx<utils::OV_BYPASS_3_LAYER>(ov);
+            break;
+        default:
+            ALOGE("%s: unknown state=%d", __FUNCTION__, s);
+    }
+    mState = s;
+    return newov;
+}
+
+// Transitions from 2D video true UI mirroring (2D video + UI) to XXX
+inline OverlayImplBase* OverlayState::handle_2D_trueUI_Mirror(utils::eOverlayState s,
+        OverlayImplBase* ov)
+{
+    OverlayImplBase* newov = ov;
+    switch(s)
+    {
+        case utils::OV_CLOSED:
+            newov = handle_xxx_to_closed(ov);
+            break;
+        case utils::OV_2D_VIDEO_ON_PANEL:
+            newov = handle_xxx_to_2D_2DPanel(ov);
+            break;
+        case utils::OV_2D_VIDEO_ON_PANEL_TV:
+            newov = handle_xxx_to_2D_2DTV(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_2D_PANEL:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_2D_PANEL>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_3D_PANEL:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_3D_PANEL>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_3D_TV:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_3D_TV>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV>(ov);
+            break;
+        case utils::OV_UI_MIRROR:
+            newov = handle_xxx_to_xxx<utils::OV_UI_MIRROR>(ov);
+            break;
+        case utils::OV_2D_TRUE_UI_MIRROR:
+            // no state change
+            break;
+        case utils::OV_BYPASS_1_LAYER:
+            newov = handle_xxx_to_xxx<utils::OV_BYPASS_1_LAYER>(ov);
+            break;
+        case utils::OV_BYPASS_2_LAYER:
+            newov = handle_xxx_to_xxx<utils::OV_BYPASS_2_LAYER>(ov);
+            break;
+        case utils::OV_BYPASS_3_LAYER:
+            newov = handle_xxx_to_xxx<utils::OV_BYPASS_3_LAYER>(ov);
+            break;
+        default:
+            ALOGE("%s: unknown state=%d", __FUNCTION__, s);
+    }
+    mState = s;
+    return newov;
+}
+
+// Transitions from composition bypass to XXX
+inline OverlayImplBase* OverlayState::handle_bypass(utils::eOverlayState s,
+        OverlayImplBase* ov)
+{
+    OverlayImplBase* newov = ov;
+    switch(s)
+    {
+        case utils::OV_CLOSED:
+            newov = handle_xxx_to_closed(ov);
+            break;
+        case utils::OV_2D_VIDEO_ON_PANEL:
+            newov = handle_xxx_to_xxx<utils::OV_2D_VIDEO_ON_PANEL>(ov);
+            break;
+        case utils::OV_2D_VIDEO_ON_PANEL_TV:
+            newov = handle_xxx_to_xxx<utils::OV_2D_VIDEO_ON_PANEL_TV>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_2D_PANEL:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_2D_PANEL>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_3D_PANEL:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_3D_PANEL>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_3D_TV:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_3D_TV>(ov);
+            break;
+        case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
+            newov = handle_xxx_to_xxx<utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV>(ov);
+            break;
+        case utils::OV_UI_MIRROR:
+            newov = handle_xxx_to_xxx<utils::OV_UI_MIRROR>(ov);
+            break;
+        case utils::OV_2D_TRUE_UI_MIRROR:
+            newov = handle_xxx_to_xxx<utils::OV_2D_TRUE_UI_MIRROR>(ov);
+            break;
+        case utils::OV_BYPASS_1_LAYER:
+            newov = handle_xxx_to_bypass1(ov);
+            break;
+        case utils::OV_BYPASS_2_LAYER:
+            newov = handle_xxx_to_bypass2(ov);
+            break;
+        case utils::OV_BYPASS_3_LAYER:
+            newov = handle_xxx_to_bypass3(ov);
+            break;
+        default:
+            ALOGE("%s: unknown state=%d", __FUNCTION__, s);
+    }
+    mState = s;
+    return newov;
+}
+
+
+} // overlay
+
+#endif // OVERLAY_STATE_H
diff --git a/liboverlay/overlayTransitions.cpp b/liboverlay/overlayTransitions.cpp
new file mode 100644
index 0000000..45d3720
--- /dev/null
+++ b/liboverlay/overlayTransitions.cpp
@@ -0,0 +1,503 @@
+/*
+* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "overlayState.h"
+
+namespace overlay {
+
+/*
+ * Transition from any state to 2D video on 2D panel
+ */
+OverlayImplBase* OverlayState::handle_xxx_to_2D_2DPanel(
+        OverlayImplBase* ov)
+{
+    OVASSERT(ov, "%s: ov is null", __FUNCTION__);
+    ALOGE("%s", __FUNCTION__);
+
+    // Create new ovimpl based on new state
+    typedef StateTraits<utils::OV_2D_VIDEO_ON_PANEL> NewState;
+    OverlayImplBase* newov = new NewState::ovimpl;
+
+    //===========================================================
+    // For each pipe:
+    //    - If pipe matches, copy from previous into new ovimpl
+    //    - Otherwise open for new and delete from previous ovimpl
+    //===========================================================
+
+    // pipe0/rot0 (GenericPipe)
+    if (ov->getOvPipeType(utils::OV_PIPE0) == utils::OV_PIPE_TYPE_GENERIC) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (GenericPipe)", __FUNCTION__);
+        newov->copyOvPipe(ov, utils::OV_PIPE0);
+    } else {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe0 (GenericPipe)", __FUNCTION__);
+        RotatorBase* rot0 = new NewState::rot0;
+        ov->closePipe(utils::OV_PIPE0);
+        newov->openPipe(rot0, utils::OV_PIPE0);
+    }
+
+    // pipe1/rot1 (NullPipe)
+    if (ov->getOvPipeType(utils::OV_PIPE1) == utils::OV_PIPE_TYPE_NULL) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (NullPipe)", __FUNCTION__);
+        newov->copyOvPipe(ov, utils::OV_PIPE1);
+    } else {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe1 (NullPipe)", __FUNCTION__);
+        RotatorBase* rot1 = new NewState::rot1;
+        ov->closePipe(utils::OV_PIPE1);
+        newov->openPipe(rot1, utils::OV_PIPE1);
+    }
+
+    // pipe2/rot2 (NullPipe)
+    if (ov->getOvPipeType(utils::OV_PIPE2) == utils::OV_PIPE_TYPE_NULL) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (NullPipe)", __FUNCTION__);
+        newov->copyOvPipe(ov, utils::OV_PIPE2);
+    } else {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe2 (NullPipe)", __FUNCTION__);
+        RotatorBase* rot2 = new NewState::rot2;
+        ov->closePipe(utils::OV_PIPE2);
+        newov->openPipe(rot2, utils::OV_PIPE2);
+    }
+
+    // All pipes are copied or deleted so no more need for previous ovimpl
+    delete ov;
+    ov = 0;
+
+    return newov;
+}
+
+/*
+ * Transition from any state to 2D video on 2D panel and 2D TV
+ */
+OverlayImplBase* OverlayState::handle_xxx_to_2D_2DTV(
+        OverlayImplBase* ov)
+{
+    OVASSERT(ov, "%s: ov is null", __FUNCTION__);
+    ALOGE("%s", __FUNCTION__);
+
+    // Create new ovimpl based on new state
+    typedef StateTraits<utils::OV_2D_VIDEO_ON_PANEL_TV> NewState;
+    OverlayImplBase* newov = new NewState::ovimpl;
+
+    //===========================================================
+    // For each pipe:
+    //    - If pipe matches, copy from previous into new ovimpl
+    //    - Otherwise open for new and delete from previous ovimpl
+    //===========================================================
+
+    // pipe0/rot0 (GenericPipe)
+    if (ov->getOvPipeType(utils::OV_PIPE0) == utils::OV_PIPE_TYPE_GENERIC) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (GenericPipe)", __FUNCTION__);
+        newov->copyOvPipe(ov, utils::OV_PIPE0);
+    } else {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe0 (GenericPipe)", __FUNCTION__);
+        RotatorBase* rot0 = new NewState::rot0;
+        ov->closePipe(utils::OV_PIPE0);
+        newov->openPipe(rot0, utils::OV_PIPE0);
+    }
+
+    // pipe1/rot1 (HdmiPipe)
+    if (ov->getOvPipeType(utils::OV_PIPE1) == utils::OV_PIPE_TYPE_HDMI) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (HdmiPipe)", __FUNCTION__);
+        newov->copyOvPipe(ov, utils::OV_PIPE1);
+    } else {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe1 (HdmiPipe)", __FUNCTION__);
+        RotatorBase* rot1 = new NewState::rot1;
+        ov->closePipe(utils::OV_PIPE1);
+        newov->openPipe(rot1, utils::OV_PIPE1);
+    }
+
+    // pipe2/rot2 (NullPipe)
+    if (ov->getOvPipeType(utils::OV_PIPE2) == utils::OV_PIPE_TYPE_NULL) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (NullPipe)", __FUNCTION__);
+        newov->copyOvPipe(ov, utils::OV_PIPE2);
+    } else {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe2 (NullPipe)", __FUNCTION__);
+        RotatorBase* rot2 = new NewState::rot2;
+        ov->closePipe(utils::OV_PIPE2);
+        newov->openPipe(rot2, utils::OV_PIPE2);
+    }
+
+    // All pipes are copied or deleted so no more need for previous ovimpl
+    delete ov;
+    ov = 0;
+
+    return newov;
+}
+
+/*
+ * Transition from any state to 3D video on 2D panel
+ */
+OverlayImplBase* OverlayState::handle_xxx_to_3D_2DPanel(
+        OverlayImplBase* ov)
+{
+    OVASSERT(ov, "%s: ov is null", __FUNCTION__);
+    ALOGE("%s", __FUNCTION__);
+
+    // Create new ovimpl based on new state
+    typedef StateTraits<utils::OV_3D_VIDEO_ON_2D_PANEL> NewState;
+    OverlayImplBase* newov = new NewState::ovimpl;
+
+    //===========================================================
+    // For each pipe:
+    //    - If pipe matches, copy from previous into new ovimpl
+    //    - Otherwise open for new and delete from previous ovimpl
+    //===========================================================
+
+    // pipe0/rot0 (M3DPrimaryPipe)
+    if (ov->getOvPipeType(utils::OV_PIPE0) == utils::OV_PIPE_TYPE_M3D_PRIMARY) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (M3DPrimaryPipe)", __FUNCTION__);
+        newov->copyOvPipe(ov, utils::OV_PIPE0);
+    } else {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe0 (M3DPrimaryPipe)", __FUNCTION__);
+        RotatorBase* rot0 = new NewState::rot0;
+        ov->closePipe(utils::OV_PIPE0);
+        newov->openPipe(rot0, utils::OV_PIPE0);
+    }
+
+    // pipe1/rot1 (NullPipe)
+    if (ov->getOvPipeType(utils::OV_PIPE1) == utils::OV_PIPE_TYPE_NULL) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (NullPipe)", __FUNCTION__);
+        newov->copyOvPipe(ov, utils::OV_PIPE1);
+    } else {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe1 (NullPipe)", __FUNCTION__);
+        RotatorBase* rot1 = new NewState::rot1;
+        ov->closePipe(utils::OV_PIPE1);
+        newov->openPipe(rot1, utils::OV_PIPE1);
+    }
+
+    // pipe2/rot2 (NullPipe)
+    if (ov->getOvPipeType(utils::OV_PIPE2) == utils::OV_PIPE_TYPE_NULL) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (NullPipe)", __FUNCTION__);
+        newov->copyOvPipe(ov, utils::OV_PIPE2);
+    } else {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe2 (NullPipe)", __FUNCTION__);
+        RotatorBase* rot2 = new NewState::rot2;
+        ov->closePipe(utils::OV_PIPE2);
+        newov->openPipe(rot2, utils::OV_PIPE2);
+    }
+
+    // All pipes are copied or deleted so no more need for previous ovimpl
+    delete ov;
+    ov = 0;
+
+    return newov;
+}
+
+/*
+ * Transition from any state to 3D video on 2D panel and 2D TV
+ */
+OverlayImplBase* OverlayState::handle_xxx_to_3D_2DTV(
+        OverlayImplBase* ov)
+{
+    OVASSERT(ov, "%s: ov is null", __FUNCTION__);
+    ALOGE("%s", __FUNCTION__);
+
+    // Create new ovimpl based on new state
+    typedef StateTraits<utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV> NewState;
+    OverlayImplBase* newov = new NewState::ovimpl;
+
+    //===========================================================
+    // For each pipe:
+    //    - If pipe matches, copy from previous into new ovimpl
+    //    - Otherwise open for new and delete from previous ovimpl
+    //===========================================================
+
+    // pipe0/rot0 (M3DPrimaryPipe)
+    if (ov->getOvPipeType(utils::OV_PIPE0) == utils::OV_PIPE_TYPE_M3D_PRIMARY) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (M3DPrimaryPipe)", __FUNCTION__);
+        newov->copyOvPipe(ov, utils::OV_PIPE0);
+    } else {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe0 (M3DPrimaryPipe)", __FUNCTION__);
+        RotatorBase* rot0 = new NewState::rot0;
+        ov->closePipe(utils::OV_PIPE0);
+        newov->openPipe(rot0, utils::OV_PIPE0);
+    }
+
+    // pipe1/rot1 (M3DExtPipe)
+    if (ov->getOvPipeType(utils::OV_PIPE1) == utils::OV_PIPE_TYPE_M3D_EXTERNAL) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (M3DExtPipe)", __FUNCTION__);
+        newov->copyOvPipe(ov, utils::OV_PIPE1);
+    } else {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe1 (M3DExtPipe)", __FUNCTION__);
+        RotatorBase* rot1 = new NewState::rot1;
+        ov->closePipe(utils::OV_PIPE1);
+        newov->openPipe(rot1, utils::OV_PIPE1);
+    }
+
+    // pipe2/rot2 (NullPipe)
+    if (ov->getOvPipeType(utils::OV_PIPE2) == utils::OV_PIPE_TYPE_NULL) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (NullPipe)", __FUNCTION__);
+        newov->copyOvPipe(ov, utils::OV_PIPE2);
+    } else {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe2 (NullPipe)", __FUNCTION__);
+        RotatorBase* rot2 = new NewState::rot2;
+        ov->closePipe(utils::OV_PIPE2);
+        newov->openPipe(rot2, utils::OV_PIPE2);
+    }
+
+    // All pipes are copied or deleted so no more need for previous ovimpl
+    delete ov;
+    ov = 0;
+
+    return newov;
+}
+
+/*
+ * Transition from any state to 2D true UI mirroring (2D video + UI)
+ */
+OverlayImplBase* OverlayState::handle_xxx_to_2D_trueUI_Mirror(
+        OverlayImplBase* ov)
+{
+    OVASSERT(ov, "%s: ov is null", __FUNCTION__);
+    ALOGE("%s", __FUNCTION__);
+
+    // Create new ovimpl based on new state
+    typedef StateTraits<utils::OV_2D_TRUE_UI_MIRROR> NewState;
+    OverlayImplBase* newov = new NewState::ovimpl;
+
+    //===========================================================
+    // For each pipe:
+    //    - If pipe matches, copy from previous into new ovimpl
+    //    - Otherwise open for new and delete from previous ovimpl
+    //===========================================================
+
+    // pipe0/rot0 (GenericPipe)
+    if (ov->getOvPipeType(utils::OV_PIPE0) == utils::OV_PIPE_TYPE_GENERIC) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (GenericPipe)", __FUNCTION__);
+        newov->copyOvPipe(ov, utils::OV_PIPE0);
+    } else {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe0 (GenericPipe)", __FUNCTION__);
+        RotatorBase* rot0 = new NewState::rot0;
+        ov->closePipe(utils::OV_PIPE0);
+        newov->openPipe(rot0, utils::OV_PIPE0);
+    }
+
+    // pipe1/rot1 (HdmiPipe)
+    if (ov->getOvPipeType(utils::OV_PIPE1) == utils::OV_PIPE_TYPE_HDMI) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (HdmiPipe)", __FUNCTION__);
+        newov->copyOvPipe(ov, utils::OV_PIPE1);
+    } else {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe1 (HdmiPipe)", __FUNCTION__);
+        RotatorBase* rot1 = new NewState::rot1;
+        ov->closePipe(utils::OV_PIPE1);
+        newov->openPipe(rot1, utils::OV_PIPE1);
+    }
+
+    // pipe2/rot2 (UIMirrorPipe)
+    if (ov->getOvPipeType(utils::OV_PIPE2) == utils::OV_PIPE_TYPE_UI_MIRROR) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (UIMirrorPipe)", __FUNCTION__);
+        newov->copyOvPipe(ov, utils::OV_PIPE2);
+    } else {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe2 (UIMirrorPipe)", __FUNCTION__);
+        RotatorBase* rot2 = new NewState::rot2;
+        ov->closePipe(utils::OV_PIPE2);
+        newov->openPipe(rot2, utils::OV_PIPE2);
+    }
+
+    // All pipes are copied or deleted so no more need for previous ovimpl
+    delete ov;
+    ov = 0;
+
+    return newov;
+}
+
+/*
+ * Transitions from any state to 1 layer composition bypass
+ */
+OverlayImplBase* OverlayState::handle_xxx_to_bypass1(OverlayImplBase* ov)
+{
+    OVASSERT(ov, "%s: ov is null", __FUNCTION__);
+    ALOGE("%s", __FUNCTION__);
+
+    // Create new ovimpl based on new state
+    typedef StateTraits<utils::OV_BYPASS_1_LAYER> NewState;
+    OverlayImplBase* newov = new NewState::ovimpl;
+
+    //===========================================================
+    // For each pipe:
+    //    - If pipe matches, copy from previous into new ovimpl
+    //    - Otherwise open for new and delete from previous ovimpl
+    //===========================================================
+
+    // pipe0/rot0 (BypassPipe)
+    if (ov->getOvPipeType(utils::OV_PIPE0) == utils::OV_PIPE_TYPE_BYPASS) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (BypassPipe)", __FUNCTION__);
+        newov->copyOvPipe(ov, utils::OV_PIPE0);
+    } else {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe0 (BypassPipe)", __FUNCTION__);
+        RotatorBase* rot0 = new NewState::rot0;
+        ov->closePipe(utils::OV_PIPE0);
+        newov->openPipe(rot0, utils::OV_PIPE0);
+    }
+
+    // pipe1/rot1 (NullPipe)
+    if (ov->getOvPipeType(utils::OV_PIPE1) == utils::OV_PIPE_TYPE_NULL) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (NullPipe)", __FUNCTION__);
+        newov->copyOvPipe(ov, utils::OV_PIPE1);
+    } else {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe1 (NullPipe)", __FUNCTION__);
+        RotatorBase* rot1 = new NewState::rot1;
+        ov->closePipe(utils::OV_PIPE1);
+        newov->openPipe(rot1, utils::OV_PIPE1);
+    }
+
+    // pipe2/rot2 (NullPipe)
+    if (ov->getOvPipeType(utils::OV_PIPE2) == utils::OV_PIPE_TYPE_NULL) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (NullPipe)", __FUNCTION__);
+        newov->copyOvPipe(ov, utils::OV_PIPE2);
+    } else {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe2 (NullPipe)", __FUNCTION__);
+        RotatorBase* rot2 = new NewState::rot2;
+        ov->closePipe(utils::OV_PIPE2);
+        newov->openPipe(rot2, utils::OV_PIPE2);
+    }
+
+    // All pipes are copied or deleted so no more need for previous ovimpl
+    delete ov;
+    ov = 0;
+
+    return newov;
+}
+
+/*
+ * Transitions from any state to 2 layers composition bypass
+ */
+OverlayImplBase* OverlayState::handle_xxx_to_bypass2(OverlayImplBase* ov)
+{
+    OVASSERT(ov, "%s: ov is null", __FUNCTION__);
+    ALOGE("%s", __FUNCTION__);
+
+    // Create new ovimpl based on new state
+    typedef StateTraits<utils::OV_BYPASS_2_LAYER> NewState;
+    OverlayImplBase* newov = new NewState::ovimpl;
+
+    //===========================================================
+    // For each pipe:
+    //    - If pipe matches, copy from previous into new ovimpl
+    //    - Otherwise open for new and delete from previous ovimpl
+    //===========================================================
+
+    // pipe0/rot0 (BypassPipe)
+    if (ov->getOvPipeType(utils::OV_PIPE0) == utils::OV_PIPE_TYPE_BYPASS) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (BypassPipe)", __FUNCTION__);
+        newov->copyOvPipe(ov, utils::OV_PIPE0);
+    } else {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe0 (BypassPipe)", __FUNCTION__);
+        RotatorBase* rot0 = new NewState::rot0;
+        ov->closePipe(utils::OV_PIPE0);
+        newov->openPipe(rot0, utils::OV_PIPE0);
+    }
+
+    // pipe1/rot1 (BypassPipe)
+    if (ov->getOvPipeType(utils::OV_PIPE1) == utils::OV_PIPE_TYPE_BYPASS) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (BypassPipe)", __FUNCTION__);
+        newov->copyOvPipe(ov, utils::OV_PIPE1);
+    } else {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe1 (BypassPipe)", __FUNCTION__);
+        RotatorBase* rot1 = new NewState::rot1;
+        ov->closePipe(utils::OV_PIPE1);
+        newov->openPipe(rot1, utils::OV_PIPE1);
+    }
+
+    // pipe2/rot2 (NullPipe)
+    if (ov->getOvPipeType(utils::OV_PIPE2) == utils::OV_PIPE_TYPE_NULL) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (NullPipe)", __FUNCTION__);
+        newov->copyOvPipe(ov, utils::OV_PIPE2);
+    } else {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe2 (NullPipe)", __FUNCTION__);
+        RotatorBase* rot2 = new NewState::rot2;
+        ov->closePipe(utils::OV_PIPE2);
+        newov->openPipe(rot2, utils::OV_PIPE2);
+    }
+
+    // All pipes are copied or deleted so no more need for previous ovimpl
+    delete ov;
+    ov = 0;
+
+    return newov;
+}
+
+/*
+ * Transitions from any state to 3 layers composition bypass
+ */
+OverlayImplBase* OverlayState::handle_xxx_to_bypass3(OverlayImplBase* ov)
+{
+    OVASSERT(ov, "%s: ov is null", __FUNCTION__);
+    ALOGE("%s", __FUNCTION__);
+
+    // Create new ovimpl based on new state
+    typedef StateTraits<utils::OV_BYPASS_3_LAYER> NewState;
+    OverlayImplBase* newov = new NewState::ovimpl;
+
+    //===========================================================
+    // For each pipe:
+    //    - If pipe matches, copy from previous into new ovimpl
+    //    - Otherwise open for new and delete from previous ovimpl
+    //===========================================================
+
+    // pipe0/rot0 (BypassPipe)
+    if (ov->getOvPipeType(utils::OV_PIPE0) == utils::OV_PIPE_TYPE_BYPASS) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (BypassPipe)", __FUNCTION__);
+        newov->copyOvPipe(ov, utils::OV_PIPE0);
+    } else {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe0 (BypassPipe)", __FUNCTION__);
+        RotatorBase* rot0 = new NewState::rot0;
+        ov->closePipe(utils::OV_PIPE0);
+        newov->openPipe(rot0, utils::OV_PIPE0);
+    }
+
+    // pipe1/rot1 (BypassPipe)
+    if (ov->getOvPipeType(utils::OV_PIPE1) == utils::OV_PIPE_TYPE_BYPASS) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (BypassPipe)", __FUNCTION__);
+        newov->copyOvPipe(ov, utils::OV_PIPE1);
+    } else {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe1 (BypassPipe)", __FUNCTION__);
+        RotatorBase* rot1 = new NewState::rot1;
+        ov->closePipe(utils::OV_PIPE1);
+        newov->openPipe(rot1, utils::OV_PIPE1);
+    }
+
+    // pipe2/rot2 (BypassPipe)
+    if (ov->getOvPipeType(utils::OV_PIPE2) == utils::OV_PIPE_TYPE_BYPASS) {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (BypassPipe)", __FUNCTION__);
+        newov->copyOvPipe(ov, utils::OV_PIPE2);
+    } else {
+        ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe2 (BypassPipe)", __FUNCTION__);
+        RotatorBase* rot2 = new NewState::rot2;
+        ov->closePipe(utils::OV_PIPE2);
+        newov->openPipe(rot2, utils::OV_PIPE2);
+    }
+
+    // All pipes are copied or deleted so no more need for previous ovimpl
+    delete ov;
+    ov = 0;
+
+    return newov;
+}
+
+} // overlay
diff --git a/liboverlay/overlayUtils.cpp b/liboverlay/overlayUtils.cpp
new file mode 100644
index 0000000..38e3ab2
--- /dev/null
+++ b/liboverlay/overlayUtils.cpp
@@ -0,0 +1,337 @@
+/*
+* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdlib.h>
+#include <utils/Log.h>
+#include <linux/msm_mdp.h>
+#include <cutils/properties.h>
+#include "gralloc_priv.h"
+#include "fb_priv.h"
+#include "overlayUtils.h"
+#include "mdpWrapper.h"
+
+// just a helper static thingy
+namespace {
+struct IOFile {
+    IOFile(const char* s, const char* mode) : fp(0) {
+        fp = ::fopen(s, mode);
+        if(!fp) {
+            ALOGE("Failed open %s", s);
+        }
+    }
+    template <class T>
+            size_t read(T& r, size_t elem) {
+                if(fp) {
+                    return ::fread(&r, sizeof(T), elem, fp);
+                }
+                return 0;
+            }
+    size_t write(const char* s, uint32_t val) {
+        if(fp) {
+            return ::fprintf(fp, s, val);
+        }
+        return 0;
+    }
+    bool valid() const { return fp != 0; }
+    ~IOFile() {
+        if(fp) ::fclose(fp);
+        fp=0;
+    }
+    FILE* fp;
+};
+}
+
+namespace overlay {
+
+//----------From class Res ------------------------------
+const char* const Res::devTemplate = "/dev/graphics/fb%u";
+const char* const Res::rotPath = "/dev/msm_rotator";
+const char* const Res::format3DFile =
+        "/sys/class/graphics/fb1/format_3d";
+const char* const Res::edid3dInfoFile =
+        "/sys/class/graphics/fb1/3d_present";
+const char* const Res::barrierFile =
+        "/sys/devices/platform/mipi_novatek.0/enable_3d_barrier";
+//--------------------------------------------------------
+
+
+
+namespace utils {
+//--------------------------------------------------------
+FrameBufferInfo::FrameBufferInfo() {
+    mFBWidth = 0;
+    mFBHeight = 0;
+    mBorderFillSupported = false;
+
+    OvFD mFd;
+
+    // Use open defined in overlayFD file to open fd for fb0
+    if(!overlay::open(mFd, 0, Res::devTemplate)) {
+        ALOGE("FrameBufferInfo: failed to open fd");
+        return;
+    }
+
+    if (!mFd.valid()) {
+        ALOGE("FrameBufferInfo: FD not valid");
+        return;
+    }
+
+    fb_var_screeninfo vinfo;
+    if (!mdp_wrapper::getVScreenInfo(mFd.getFD(), vinfo)) {
+        ALOGE("FrameBufferInfo: failed getVScreenInfo on fb0");
+        mFd.close();
+        return;
+    }
+
+    mdp_overlay ov;
+    memset(&ov, 0, sizeof(ov));
+    ov.id = 1;
+    if (!mdp_wrapper::getOverlay(mFd.getFD(), ov)) {
+        ALOGE("FrameBufferInfo: failed getOverlay on fb0");
+        mFd.close();
+        return;
+    }
+
+    mFd.close();
+
+    mFBWidth = vinfo.xres;
+    mFBHeight = vinfo.yres;
+    mBorderFillSupported = (ov.flags & MDP_BORDERFILL_SUPPORTED) ?
+            true : false;
+}
+
+FrameBufferInfo* FrameBufferInfo::getInstance() {
+    if (!sFBInfoInstance) {
+        sFBInfoInstance = new FrameBufferInfo;
+    }
+    return sFBInfoInstance;
+}
+
+int FrameBufferInfo::getWidth() const {
+    return mFBWidth;
+}
+
+int FrameBufferInfo::getHeight() const {
+    return mFBHeight;
+}
+
+bool FrameBufferInfo::supportTrueMirroring() const {
+    return mBorderFillSupported;
+}
+
+//--------------------------------------------------------
+uint32_t getSize(const Whf& whf) {
+    int aligned_height=0, pitch=0;
+
+    uint32_t size = whf.w * whf.h;
+    switch (whf.format) {
+        case MDP_RGBA_8888:
+        case MDP_BGRA_8888:
+        case MDP_RGBX_8888:
+            size *= 4;
+            break;
+        case MDP_RGB_565:
+        case MDP_Y_CBCR_H2V1:
+            size *= 2;
+            break;
+        case MDP_Y_CBCR_H2V2:
+        case MDP_Y_CRCB_H2V2:
+            size = (size * 3) / 2;
+            break;
+        case MDP_Y_CRCB_H2V2_TILE:
+        case MDP_Y_CBCR_H2V2_TILE:
+            aligned_height = align(whf.h , 32);
+            pitch = align(whf.w, 128);
+            size = pitch * aligned_height;
+            size = align(size, 8192);
+
+            aligned_height = align(whf.h >> 1, 32);
+            size += pitch * aligned_height;
+            size = align(size, 8192);
+            break;
+        default:
+            ALOGE("getSize unknown format %d", whf.format);
+            return 0;
+    }
+    return size;
+}
+
+int getMdpFormat(int format) {
+    switch (format) {
+        case HAL_PIXEL_FORMAT_RGBA_8888 :
+            return MDP_RGBA_8888;
+        case HAL_PIXEL_FORMAT_BGRA_8888:
+            return MDP_BGRA_8888;
+        case HAL_PIXEL_FORMAT_RGB_565:
+            return MDP_RGB_565;
+        case HAL_PIXEL_FORMAT_RGBX_8888:
+            return MDP_RGBX_8888;
+        case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+            return MDP_Y_CBCR_H2V1;
+        case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+            return MDP_Y_CRCB_H2V1;
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+            return MDP_Y_CBCR_H2V2;
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+            return MDP_Y_CRCB_H2V2;
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
+            return MDP_Y_CBCR_H2V2_TILE;
+        case HAL_PIXEL_FORMAT_YV12:
+            return MDP_Y_CR_CB_H2V2;
+        default:
+            ALOGE("Error getMdpFormat format=%d", format);
+            return -1;
+    }
+    // not reached
+    return -1;
+}
+
+bool isHDMIConnected () {
+    char value[PROPERTY_VALUE_MAX] = {0};
+    property_get("hw.hdmiON", value, "0");
+    int isHDMI = atoi(value);
+    return isHDMI ? true : false;
+}
+
+bool is3DTV() {
+    char is3DTV = '0';
+    IOFile fp(Res::edid3dInfoFile, "r");
+    (void)fp.read(is3DTV, 1);
+    ALOGI("3DTV EDID flag: %d", is3DTV);
+    return (is3DTV == '0') ? false : true;
+}
+
+bool isPanel3D() {
+    OvFD fd;
+    if(!overlay::open(fd, 0 /*fb*/, Res::devTemplate)){
+        ALOGE("isPanel3D Can't open framebuffer 0");
+        return false;
+    }
+    fb_fix_screeninfo finfo;
+    if(!mdp_wrapper::getFScreenInfo(fd.getFD(), finfo)) {
+        ALOGE("isPanel3D read fb0 failed");
+    }
+    fd.close();
+    return (FB_TYPE_3D_PANEL == finfo.type) ? true : false;
+}
+
+bool usePanel3D() {
+    if(!isPanel3D())
+        return false;
+    char value[PROPERTY_VALUE_MAX];
+    property_get("persist.user.panel3D", value, "0");
+    int usePanel3D = atoi(value);
+    return usePanel3D ? true : false;
+}
+
+bool send3DInfoPacket (uint32_t format3D) {
+    IOFile fp(Res::format3DFile, "wb");
+    (void)fp.write("%d", format3D);
+    if(!fp.valid()) {
+        ALOGE("send3DInfoPacket: no sysfs entry for setting 3d mode");
+        return false;
+    }
+    return true;
+}
+
+bool enableBarrier (uint32_t orientation) {
+    IOFile fp(Res::barrierFile, "wb");
+    (void)fp.write("%d", orientation);
+    if(!fp.valid()) {
+        ALOGE("enableBarrier no sysfs entry for "
+                "enabling barriers on 3D panel");
+        return false;
+    }
+    return true;
+}
+
+uint32_t getS3DFormat(uint32_t fmt) {
+    // The S3D is part of the HAL_PIXEL_FORMAT_YV12 value. Add
+    // an explicit check for the format
+    if (fmt == HAL_PIXEL_FORMAT_YV12) {
+        return 0;
+    }
+    uint32_t fmt3D = format3D(fmt);
+    uint32_t fIn3D = format3DInput(fmt3D); // MSB 2 bytes - inp
+    uint32_t fOut3D = format3DOutput(fmt3D); // LSB 2 bytes - out
+    fmt3D = fIn3D | fOut3D;
+    if (!fIn3D) {
+        fmt3D |= fOut3D << SHIFT_TOT_3D; //Set the input format
+    }
+    if (!fOut3D) {
+        switch (fIn3D) {
+            case HAL_3D_IN_SIDE_BY_SIDE_L_R:
+            case HAL_3D_IN_SIDE_BY_SIDE_R_L:
+                // For all side by side formats, set the output
+                // format as Side-by-Side i.e 0x1
+                fmt3D |= HAL_3D_IN_SIDE_BY_SIDE_L_R >> SHIFT_TOT_3D;
+                break;
+            default:
+                fmt3D |= fIn3D >> SHIFT_TOT_3D; //Set the output format
+        }
+    }
+    return fmt3D;
+}
+
+void normalizeCrop(uint32_t& xy, uint32_t& wh) {
+    if (xy & 0x0001) {
+        // x or y is odd, increment it's value
+        xy += 1;
+        // Since we've incremented x(y), we need to decrement
+        // w(h) accordingly
+        if (wh & 0x0001) {
+            // w or h is odd, decrement it by 1, to make it even
+            even_out(wh);
+        } else {
+            // w(h) is already even, hence we decrement by 2
+            wh -=2;
+        }
+    } else {
+        even_out(wh);
+    }
+}
+
+void scale(mdp_overlay& ov)
+{
+    /* Scaling of upto a max of 8 times supported */
+    overlay::utils::Dim dst(overlay::utils::getDstRectDim(ov));
+    overlay::utils::Dim src(overlay::utils::getSrcRectDim(ov));
+    if(dst.w >(src.w * overlay::utils::HW_OV_MAGNIFICATION_LIMIT)) {
+        dst.w = overlay::utils::HW_OV_MAGNIFICATION_LIMIT * src.w;
+    }
+    if(dst.h >(src.h * overlay::utils::HW_OV_MAGNIFICATION_LIMIT)) {
+        dst.h = overlay::utils::HW_OV_MAGNIFICATION_LIMIT * src.h;
+    }
+
+    setDstRectDim(dst, ov);
+}
+
+} // utils
+
+} // overlay
diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h
new file mode 100644
index 0000000..089d3fb
--- /dev/null
+++ b/liboverlay/overlayUtils.h
@@ -0,0 +1,1112 @@
+/*
+* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef OVERLAY_UTILS_H
+#define OVERLAY_UTILS_H
+
+#include <cutils/log.h> // ALOGE, etc
+#include <errno.h>
+#include <fcntl.h> // open, O_RDWR, etc
+#include <hardware/hardware.h>
+#include <hardware/gralloc.h> // buffer_handle_t
+#include <linux/msm_mdp.h> // MDP_OV_PLAY_NOWAIT etc ...
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <utils/Log.h>
+
+/*
+*
+* Collection of utilities functions/structs/enums etc...
+*
+* */
+
+// comment that out if you want to remove asserts
+// or put it as -D in Android.mk. your choice.
+#define OVERLAY_HAS_ASSERT
+
+#ifdef OVERLAY_HAS_ASSERT
+# define OVASSERT(x, ...) if(!(x)) { ALOGE(__VA_ARGS__); abort(); }
+#else
+# define OVASSERT(x, ...) ALOGE_IF(!(x), __VA_ARGS__)
+#endif // OVERLAY_HAS_ASSERT
+
+#define DEBUG_OVERLAY 0
+#define PROFILE_OVERLAY 0
+
+namespace overlay {
+
+// fwd
+class Overlay;
+
+namespace utils {
+struct Whf;
+struct Dim;
+template <class T>
+        inline void even_out(T& x) { if (x & 0x0001) --x; }
+
+inline uint32_t getBit(uint32_t x, uint32_t mask) {
+    return (x & mask);
+}
+
+inline uint32_t setBit(uint32_t x, uint32_t mask) {
+    return (x | mask);
+}
+
+inline uint32_t clrBit(uint32_t x, uint32_t mask) {
+    return (x & ~mask);
+}
+
+/* Utility class to help avoid copying instances by making the copy ctor
+* and assignment operator private
+*
+* Usage:
+* *    class SomeClass : utils::NoCopy {...};
+*/
+class NoCopy {
+protected:
+    NoCopy(){}
+    ~NoCopy() {}
+private:
+    NoCopy(const NoCopy&);
+    const NoCopy& operator=(const NoCopy&);
+};
+
+/*
+* Utility class to query the framebuffer info for primary display
+*
+* Usage:
+*    Outside of functions:
+*       utils::FrameBufferInfo* utils::FrameBufferInfo::sFBInfoInstance = 0;
+*    Inside functions:
+*       utils::FrameBufferInfo::getInstance()->supportTrueMirroring()
+*/
+class FrameBufferInfo {
+
+public:
+    /* ctor init */
+    explicit FrameBufferInfo();
+
+    /* Gets an instance if one does not already exist */
+    static FrameBufferInfo* getInstance();
+
+    /* Gets width of primary framebuffer */
+    int getWidth() const;
+
+    /* Gets height of primary framebuffer */
+    int getHeight() const;
+
+    /* Indicates whether true mirroring is supported */
+    bool supportTrueMirroring() const;
+
+private:
+    int mFBWidth;
+    int mFBHeight;
+    bool mBorderFillSupported;
+    static FrameBufferInfo *sFBInfoInstance;
+};
+
+/* 3D related utils, defines etc...
+ * The compound format passed to the overlay is
+ * ABCCC where A is the input 3D format
+ * B is the output 3D format
+ * CCC is the color format e.g YCbCr420SP YCrCb420SP etc */
+enum { SHIFT_OUT_3D = 12,
+    SHIFT_TOT_3D = 16 };
+enum { INPUT_3D_MASK = 0xFFFF0000,
+    OUTPUT_3D_MASK = 0x0000FFFF };
+enum { BARRIER_LAND = 1,
+    BARRIER_PORT = 2 };
+
+inline uint32_t format3D(uint32_t x) { return x & 0xFF000; }
+inline uint32_t colorFormat(uint32_t x) { return x & 0xFFF; }
+inline uint32_t format3DOutput(uint32_t x) {
+    return (x & 0xF000) >> SHIFT_OUT_3D; }
+inline uint32_t format3DInput(uint32_t x) { return x & 0xF0000; }
+uint32_t getColorFormat(uint32_t format);
+
+bool isHDMIConnected ();
+bool is3DTV();
+bool isPanel3D();
+bool usePanel3D();
+bool send3DInfoPacket (uint32_t fmt);
+bool enableBarrier (uint32_t orientation);
+uint32_t getS3DFormat(uint32_t fmt);
+template <int CHAN>
+        bool getPositionS3D(const Whf& whf, Dim& out);
+template <int CHAN>
+        bool getCropS3D(const Dim& in, Dim& out, uint32_t fmt);
+template <class Type>
+        void swapWidthHeight(Type& width, Type& height);
+
+struct Dim {
+    Dim () : x(0), y(0),
+    w(0), h(0),
+    o(0) {}
+    Dim(uint32_t _x, uint32_t _y, uint32_t _w, uint32_t _h) :
+        x(_x), y(_y),
+        w(_w), h(_h) {}
+    Dim(uint32_t _x, uint32_t _y, uint32_t _w, uint32_t _h, uint32_t _o) :
+        x(_x), y(_y),
+        w(_w), h(_h),
+        o(_o) {}
+    bool check(uint32_t _w, uint32_t _h) const {
+        return (x+w <= _w && y+h <= _h);
+
+    }
+
+    bool operator==(const Dim& d) const {
+        return d.x == x && d.y == y &&
+                d.w == w && d.h == h &&
+                d.o == o;
+    }
+
+    bool operator!=(const Dim& d) const {
+        return !operator==(d);
+    }
+
+    void even_out() {
+        utils::even_out(x);
+        utils::even_out(y);
+        utils::even_out(w);
+        utils::even_out(h);
+    }
+
+    void dump() const;
+    uint32_t x;
+    uint32_t y;
+    uint32_t w;
+    uint32_t h;
+    uint32_t o;
+};
+
+// TODO have Whfz
+
+struct Whf {
+    Whf() : w(0), h(0), format(0), size(0) {}
+    Whf(uint32_t wi, uint32_t he, uint32_t f) :
+        w(wi), h(he), format(f), size(0) {}
+    Whf(uint32_t wi, uint32_t he, uint32_t f, uint32_t s) :
+        w(wi), h(he), format(f), size(s) {}
+    // FIXME not comparing size at the moment
+    bool operator==(const Whf& whf) const {
+        return whf.w == w && whf.h == h &&
+                whf.format == format;
+    }
+    bool operator!=(const Whf& whf) const {
+        return !operator==(whf);
+    }
+    void dump() const;
+    uint32_t w;
+    uint32_t h;
+    // FIXME need to be int32_t ?
+    uint32_t format;
+    uint32_t size;
+};
+
+enum { MAX_PATH_LEN = 256 };
+
+enum eParams {
+    OVERLAY_DITHER,
+    OVERLAY_TRANSFORM,
+    OVERLAY_TRANSFORM_UI
+};
+
+struct Params{
+    Params(eParams p, int v) : param(p), value(v) {}
+    eParams param;
+    int value;
+};
+
+
+/**
+ * Rotator flags: not to be confused with orientation flags.
+ * Ususally, you want to open the rotator to make sure it is
+ * ready for business.
+ * ROT_FLAG_DISABLED: Rotator would not kick in. (ioctl will emit errors).
+ * ROT_FLAG_ENABLED: and when rotation is needed.
+ *                   (prim video playback)
+ *                   (UI mirroring on HDMI w/ 0 degree rotator. - just memcpy)
+ * In HDMI UI mirroring, rotator is always used.
+ * Even when w/o orienation change on primary,
+ * we do 0 rotation on HDMI and using rotator buffers.
+ * That is because we might see tearing otherwise. so
+ * we use another buffer (rotator).
+ * When a simple video playback on HDMI, no rotator is being used.(null r).
+ * */
+enum eRotFlags {
+    ROT_FLAG_DISABLED = 0,
+    ROT_FLAG_ENABLED = 1 // needed in rot
+};
+
+/* Used for rotator open.
+ * FIXME that is default, might be configs */
+enum { ROT_NUM_BUFS = 2 };
+
+/* Wait/No wait for waiting for vsync
+ * WAIT - wait for vsync, ignore fb (no need to compose w/ fb)
+ * NO_WAIT - do not wait for vsync and return immediatly since
+ * we need to run composition code */
+enum eWait {
+    WAIT,
+    NO_WAIT
+};
+
+/* The values for is_fg flag for control alpha and transp
+ * IS_FG_OFF means is_fg = 0
+ * IS_FG_SET means is_fg = 1
+ */
+enum eIsFg {
+    IS_FG_OFF = 0,
+    IS_FG_SET = 1
+};
+
+/*
+ * Various mdp flags like PIPE SHARE, DEINTERLACE etc...
+ * kernel/common/linux/msm_mdp.h
+ * INTERLACE_MASK: hardware/qcom/display/libgralloc/badger/fb_priv.h
+ * */
+enum eMdpFlags {
+    OV_MDP_FLAGS_NONE = 0,
+    OV_MDP_PIPE_SHARE =  MDP_OV_PIPE_SHARE,
+    OV_MDP_DEINTERLACE = MDP_DEINTERLACE,
+    OV_MDP_PLAY_NOWAIT = MDP_OV_PLAY_NOWAIT,
+    OV_MDP_SECURE_OVERLAY_SESSION = MDP_SECURE_OVERLAY_SESSION
+};
+
+enum eOverlayPipeType {
+    OV_PIPE_TYPE_NULL,
+    OV_PIPE_TYPE_BYPASS,
+    OV_PIPE_TYPE_GENERIC,
+    OV_PIPE_TYPE_HDMI,
+    OV_PIPE_TYPE_M3D_EXTERNAL,
+    OV_PIPE_TYPE_M3D_PRIMARY,
+    OV_PIPE_TYPE_RGB,
+    OV_PIPE_TYPE_S3D_EXTERNAL,
+    OV_PIPE_TYPE_S3D_PRIMARY,
+    OV_PIPE_TYPE_UI_MIRROR
+};
+
+enum eZorder {
+    ZORDER_0,
+    ZORDER_1,
+    ZORDER_2,
+    Z_SYSTEM_ALLOC = 0xFFFF
+};
+
+enum eMdpPipeType {
+    OV_MDP_PIPE_RGB,
+    OV_MDP_PIPE_VG
+};
+
+/* Corresponds to pipes in eDest */
+enum eChannel {
+    CHANNEL_0,
+    CHANNEL_1,
+    CHANNEL_2
+};
+
+// Max pipes via overlay (VG0, VG1, RGB1)
+enum { MAX_PIPES = 3 };
+
+/* Used to identify destination channels and
+ * also 3D channels e.g. when in 3D mode with 2
+ * pipes opened and it is used in get crop/pos 3D
+ *
+ * PLEASE NOTE : DO NOT USE eDest FOR ARRAYS
+ * i.e. args[OV_PIPE1] since it is a BIT MASK
+ * use CHANNELS enum instead. Each OV_PIPEX is
+ * not specific to a display (primary/external).
+ * */
+enum eDest {
+    OV_PIPE0 = 1 << 0,
+    OV_PIPE1 = 1 << 1,
+    OV_PIPE2 = 1 << 2,
+    OV_PIPE_ALL  = (OV_PIPE0 | OV_PIPE1 | OV_PIPE2)
+};
+
+/* values for copybit_set_parameter(OVERLAY_TRANSFORM) */
+enum eTransform {
+    /* No rot */
+    OVERLAY_TRANSFORM_0         = 0x0,
+    /* flip source image horizontally */
+    OVERLAY_TRANSFORM_FLIP_H    = HAL_TRANSFORM_FLIP_H,
+    /* flip source image vertically */
+    OVERLAY_TRANSFORM_FLIP_V    = HAL_TRANSFORM_FLIP_V,
+    /* rotate source image 90 degrees */
+    OVERLAY_TRANSFORM_ROT_90    = HAL_TRANSFORM_ROT_90,
+    /* rotate source image 180 degrees
+     * It is basically bit-or-ed  H | V == 0x3 */
+    OVERLAY_TRANSFORM_ROT_180   = HAL_TRANSFORM_ROT_180,
+    /* rotate source image 270 degrees
+     * Basically 180 | 90 == 0x7 */
+    OVERLAY_TRANSFORM_ROT_270   = HAL_TRANSFORM_ROT_270,
+    /* rotate invalid like in Transform.h */
+    OVERLAY_TRANSFORM_INV       = 0x80
+};
+
+/* offset and fd are play info */
+struct PlayInfo {
+    PlayInfo() : fd(-1), offset(0) {}
+    PlayInfo(int _fd, uint32_t _offset) :
+        fd(_fd), offset(_offset) {}
+    bool operator==(const PlayInfo& p) {
+        return (fd == p.fd && offset == p.offset);
+    }
+    int fd;
+    uint32_t offset;
+};
+
+// Used to consolidate pipe params
+struct PipeArgs {
+    PipeArgs() : mdpFlags(OV_MDP_FLAGS_NONE),
+        orientation(OVERLAY_TRANSFORM_0),
+        wait(NO_WAIT),
+        zorder(Z_SYSTEM_ALLOC),
+        isFg(IS_FG_OFF),
+        rotFlags(ROT_FLAG_DISABLED){
+    }
+
+    PipeArgs(eMdpFlags f, eTransform o,
+            Whf _whf, eWait w,
+            eZorder z, eIsFg fg, eRotFlags r) :
+        mdpFlags(f),
+        orientation(o),
+        whf(_whf),
+        wait(w),
+        zorder(z),
+        isFg(fg),
+        rotFlags(r) {
+    }
+
+    eMdpFlags mdpFlags; // for mdp_overlay flags PIPE_SHARE, NO_WAIT, etc
+    eTransform orientation; // FIXME docs
+    Whf whf;
+    eWait wait; // flags WAIT/NO_WAIT
+    eZorder zorder; // stage number
+    eIsFg isFg; // control alpha & transp
+    eRotFlags rotFlags;
+    PlayInfo play;
+};
+
+enum eOverlayState{
+    /* No pipes from overlay open */
+    OV_CLOSED = 0,
+
+    /* 2D Video */
+    OV_2D_VIDEO_ON_PANEL,
+    OV_2D_VIDEO_ON_PANEL_TV,
+
+    /* 3D Video on one display (panel or TV) */
+    OV_3D_VIDEO_ON_2D_PANEL,
+    OV_3D_VIDEO_ON_3D_PANEL,
+    OV_3D_VIDEO_ON_3D_TV,
+
+    /* 3D Video on two displays (panel and TV) */
+    OV_3D_VIDEO_ON_2D_PANEL_2D_TV,
+
+    /* UI Mirroring */
+    OV_UI_MIRROR,
+    OV_2D_TRUE_UI_MIRROR,
+    OV_M3D_TRUE_UI_MIRROR,  // Not yet supported
+
+    /* Composition Bypass */
+    OV_BYPASS_1_LAYER,
+    OV_BYPASS_2_LAYER,
+    OV_BYPASS_3_LAYER,
+};
+
+inline void setMdpFlags(eMdpFlags& f, eMdpFlags v) {
+    f = static_cast<eMdpFlags>(setBit(f, v));
+}
+
+inline void clearMdpFlags(eMdpFlags& f, eMdpFlags v) {
+    f = static_cast<eMdpFlags>(clrBit(f, v));
+}
+
+// fb 0/1/2
+enum { FB0, FB1, FB2 };
+
+//Panels could be categorized as primary and external
+enum { PRIMARY, EXTERNAL };
+
+//External Panels could use HDMI or WFD
+enum {
+    HDMI = 1,
+    WFD = 2
+};
+
+static int sExtType = HDMI; //HDMI or WFD
+
+//Set by client as HDMI/WFD
+static inline void setExtType(const int& type) {
+    if(type != HDMI || type != WFD) {
+        ALOGE("%s: Unrecognized type %d", __func__, type);
+        return;
+    }
+    sExtType = type;
+}
+
+//Return External panel type set by client.
+static inline int getExtType() {
+    return sExtType;
+}
+
+//Gets the FB number for the external type.
+//As of now, HDMI always has fb1, WFD could use fb1 or fb2
+//Assumes Ext type set by setExtType() from client.
+static int getFBForPanel(int panel) { // PRIMARY OR EXTERNAL
+    switch(panel) {
+        case PRIMARY: return FB0;
+            break;
+        case EXTERNAL:
+            switch(getExtType()) {
+                case HDMI: return FB1;
+                    break;
+                case WFD: return FB2;//Hardcoding fb2 for wfd. Will change.
+                    break;
+            }
+            break;
+        default:
+            ALOGE("%s: Unrecognized PANEL category %d", __func__, panel);
+            break;
+    }
+    return -1;
+}
+
+// number of rgb pipes bufs (max)
+// 2 for rgb0/1 double bufs
+enum { RGB_PIPE_NUM_BUFS = 2 };
+
+struct ScreenInfo {
+    ScreenInfo() : mFBWidth(0),
+    mFBHeight(0),
+    mFBbpp(0),
+    mFBystride(0) {}
+    void dump(const char* const s) const;
+    uint32_t mFBWidth;
+    uint32_t mFBHeight;
+    uint32_t mFBbpp;
+    uint32_t mFBystride;
+};
+
+int getMdpFormat(int format);
+int getRotOutFmt(uint32_t format);
+/* flip is upside down and such. V, H flip
+ * rotation is 90, 180 etc
+ * It returns MDP related enum/define that match rot+flip*/
+int getMdpOrient(eTransform rotation);
+uint32_t getSize(const Whf& whf);
+uint32_t getSizeByMdp(const Whf& whf);
+const char* getFormatString(uint32_t format);
+const char* getStateString(eOverlayState state);
+
+inline int setWait(eWait wait, int flags) {
+    return (wait == WAIT) ?
+            flags &= ~MDP_OV_PLAY_NOWAIT :
+            flags |= MDP_OV_PLAY_NOWAIT;
+}
+/* possible overlay formats libhardware/include/hardware/hardware.h */
+enum eFormat {
+    OVERLAY_FORMAT_RGBA_8888    = HAL_PIXEL_FORMAT_RGBA_8888,
+    OVERLAY_FORMAT_RGB_565      = HAL_PIXEL_FORMAT_RGB_565,
+    OVERLAY_FORMAT_BGRA_8888    = HAL_PIXEL_FORMAT_BGRA_8888,
+    OVERLAY_FORMAT_YCbYCr_422_I = 0x14,
+    OVERLAY_FORMAT_CbYCrY_422_I = 0x16,
+    OVERLAY_FORMAT_DEFAULT      = 99 // The actual color format is
+            // determined by the overlay
+};
+
+// Cannot use HW_OVERLAY_MAGNIFICATION_LIMIT, since at the time
+// of integration, HW_OVERLAY_MAGNIFICATION_LIMIT was a define
+enum { HW_OV_MAGNIFICATION_LIMIT = 20,
+    HW_OV_MINIFICATION_LIMIT  = 8
+};
+
+inline bool rotated(int orie) {
+    return (orie == OVERLAY_TRANSFORM_ROT_90 ||
+            orie == OVERLAY_TRANSFORM_ROT_270);
+}
+
+/* used by crop funcs in order to
+ * normalizes the crop values to be all even */
+void normalizeCrop(uint32_t& xy, uint32_t& wh);
+
+template <class T>
+        inline void memset0(T& t) { ::memset(&t, 0, sizeof(T)); }
+
+template <class ROT, class MDP>
+        inline void swapOVRotWidthHeight(ROT& rot, MDP& mdp)
+        {
+            mdp.swapSrcWH();
+            mdp.swapSrcRectWH();
+            rot.swapDstWH();
+        }
+
+template <class T> inline void swap ( T& a, T& b )
+{
+    T c(a); a=b; b=c;
+}
+
+inline int alignup(int value, int a) {
+    //if align = 0, return the value. Else, do alignment.
+    return a ? ((((value - 1) / a) + 1) * a) : value;
+}
+
+// FIXME that align should replace the upper one.
+inline int align(int value, int a) {
+    //if align = 0, return the value. Else, do alignment.
+    return a ? ((value + (a-1)) & ~(a-1)) : value;
+}
+
+
+template <class MDP>
+inline utils::Dim getSrcRectDim(const MDP& ov) {
+    return utils::Dim(ov.src_rect.x,
+            ov.src_rect.y,
+            ov.src_rect.w,
+            ov.src_rect.h);
+}
+
+template <class MDP>
+inline utils::Whf getSrcWhf(const MDP& ov) {
+    return utils::Whf(ov.src.width,
+            ov.src.height,
+            ov.src.format);
+}
+template <class MDP>
+inline void setSrcRectDim(MDP& ov, const utils::Dim& d) {
+    ov.src_rect.x = d.x;
+    ov.src_rect.y = d.y;
+    ov.src_rect.w = d.w;
+    ov.src_rect.h = d.h;
+}
+template <class MDP>
+inline void setSrcWhf(MDP& ov, const utils::Whf& whf) {
+    ov.src.width  = whf.w;
+    ov.src.height = whf.h;
+    ov.src.format = whf.format;
+}
+
+enum eRotOutFmt {
+    ROT_OUT_FMT_DEFAULT,
+    ROT_OUT_FMT_Y_CRCB_H2V2
+};
+
+template <int ROT_OUT_FMT> struct RotOutFmt;
+
+// FIXME, taken from gralloc_priv.h. Need to
+// put it back as soon as overlay takes place of the old one
+/* possible formats for 3D content*/
+enum {
+    HAL_NO_3D                         = 0x0000,
+    HAL_3D_IN_SIDE_BY_SIDE_L_R        = 0x10000,
+    HAL_3D_IN_TOP_BOTTOM              = 0x20000,
+    HAL_3D_IN_INTERLEAVE              = 0x40000,
+    HAL_3D_IN_SIDE_BY_SIDE_R_L        = 0x80000,
+    HAL_3D_OUT_SIDE_BY_SIDE           = 0x1000,
+    HAL_3D_OUT_TOP_BOTTOM             = 0x2000,
+    HAL_3D_OUT_INTERLEAVE             = 0x4000,
+    HAL_3D_OUT_MONOSCOPIC             = 0x8000
+};
+
+enum { HAL_3D_OUT_SBS_MASK =
+    HAL_3D_OUT_SIDE_BY_SIDE >> overlay::utils::SHIFT_OUT_3D,
+    HAL_3D_OUT_TOP_BOT_MASK =
+            HAL_3D_OUT_TOP_BOTTOM >> overlay::utils::SHIFT_OUT_3D,
+    HAL_3D_OUT_INTERL_MASK =
+            HAL_3D_OUT_INTERLEAVE >> overlay::utils::SHIFT_OUT_3D,
+    HAL_3D_OUT_MONOS_MASK =
+            HAL_3D_OUT_MONOSCOPIC >> overlay::utils::SHIFT_OUT_3D
+};
+
+
+inline bool isYuv(uint32_t format) {
+    switch(format){
+        case MDP_Y_CBCR_H2V1:
+        case MDP_Y_CBCR_H2V2:
+        case MDP_Y_CRCB_H2V2:
+        case MDP_Y_CRCB_H2V2_TILE:
+        case MDP_Y_CBCR_H2V2_TILE:
+            return true;
+        default:
+            return false;
+    }
+    return false;
+}
+
+inline bool isRgb(uint32_t format) {
+    switch(format) {
+        case MDP_RGBA_8888:
+        case MDP_BGRA_8888:
+        case MDP_RGBX_8888:
+        case MDP_RGB_565:
+            return true;
+        default:
+            return false;
+    }
+    return false;
+}
+
+inline bool isValidDest(eDest dest)
+{
+    if ((OV_PIPE0 & dest) ||
+            (OV_PIPE1 & dest) ||
+            (OV_PIPE2 & dest)) {
+        return true;
+    }
+    return false;
+}
+
+inline const char* getFormatString(uint32_t format){
+    static const char* const formats[] = {
+        "MDP_RGB_565",
+        "MDP_XRGB_8888",
+        "MDP_Y_CBCR_H2V2",
+        "MDP_ARGB_8888",
+        "MDP_RGB_888",
+        "MDP_Y_CRCB_H2V2",
+        "MDP_YCRYCB_H2V1",
+        "MDP_Y_CRCB_H2V1",
+        "MDP_Y_CBCR_H2V1",
+        "MDP_RGBA_8888",
+        "MDP_BGRA_8888",
+        "MDP_RGBX_8888",
+        "MDP_Y_CRCB_H2V2_TILE",
+        "MDP_Y_CBCR_H2V2_TILE",
+        "MDP_Y_CR_CB_H2V2",
+        "MDP_Y_CB_CR_H2V2",
+        "MDP_IMGTYPE_LIMIT",
+        "MDP_BGR_565",
+        "MDP_FB_FORMAT",
+        "MDP_IMGTYPE_LIMIT2"
+    };
+    OVASSERT(format < sizeof(formats) / sizeof(formats[0]),
+            "getFormatString wrong fmt %d", format);
+    return formats[format];
+}
+
+inline const char* getStateString(eOverlayState state){
+    switch (state) {
+        case OV_CLOSED:
+            return "OV_CLOSED";
+        case OV_2D_VIDEO_ON_PANEL:
+            return "OV_2D_VIDEO_ON_PANEL";
+        case OV_2D_VIDEO_ON_PANEL_TV:
+            return "OV_2D_VIDEO_ON_PANEL_TV";
+        case OV_3D_VIDEO_ON_2D_PANEL:
+            return "OV_3D_VIDEO_ON_2D_PANEL";
+        case OV_3D_VIDEO_ON_3D_PANEL:
+            return "OV_3D_VIDEO_ON_3D_PANEL";
+        case OV_3D_VIDEO_ON_3D_TV:
+            return "OV_3D_VIDEO_ON_3D_TV";
+        case OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
+            return "OV_3D_VIDEO_ON_2D_PANEL_2D_TV";
+        case OV_UI_MIRROR:
+            return "OV_UI_MIRROR";
+        case OV_2D_TRUE_UI_MIRROR:
+            return "OV_2D_TRUE_UI_MIRROR";
+        case OV_BYPASS_1_LAYER:
+            return "OV_BYPASS_1_LAYER";
+        case OV_BYPASS_2_LAYER:
+            return "OV_BYPASS_2_LAYER";
+        case OV_BYPASS_3_LAYER:
+            return "OV_BYPASS_3_LAYER";
+        default:
+            return "UNKNOWN_STATE";
+    }
+    return "BAD_STATE";
+}
+
+inline uint32_t getSizeByMdp(const Whf& whf) {
+    Whf _whf(whf);
+    int fmt = getMdpFormat(whf.format);
+    OVASSERT(-1 != fmt, "getSizeByMdp error in format %d",
+            whf.format);
+    _whf.format = fmt;
+    return getSize(_whf);
+}
+
+inline void Whf::dump() const {
+    ALOGE("== Dump WHF w=%d h=%d f=%d s=%d start/end ==",
+            w, h, format, size);
+}
+
+inline void Dim::dump() const {
+    ALOGE("== Dump Dim x=%d y=%d w=%d h=%d start/end ==", x, y, w, h);
+}
+
+inline int getMdpOrient(eTransform rotation) {
+    ALOGE_IF(DEBUG_OVERLAY, "%s: rot=%d", __FUNCTION__, rotation);
+    switch(int(rotation))
+    {
+        case OVERLAY_TRANSFORM_0 : return 0;
+        case HAL_TRANSFORM_FLIP_V:  return MDP_FLIP_UD;
+        case HAL_TRANSFORM_FLIP_H:  return MDP_FLIP_LR;
+        case HAL_TRANSFORM_ROT_90:  return MDP_ROT_90;
+        case HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_V:
+                                    return MDP_ROT_90|MDP_FLIP_LR;
+        case HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_H:
+                                    return MDP_ROT_90|MDP_FLIP_UD;
+        case HAL_TRANSFORM_ROT_180: return MDP_ROT_180;
+        case HAL_TRANSFORM_ROT_270: return MDP_ROT_270;
+        default:
+                                    ALOGE("%s: invalid rotation value (value = 0x%x",
+                                            __FUNCTION__, rotation);
+    }
+    return -1;
+}
+
+inline int getRotOutFmt(uint32_t format) {
+    switch (format) {
+        case MDP_Y_CRCB_H2V2_TILE:
+            return MDP_Y_CRCB_H2V2;
+        case MDP_Y_CBCR_H2V2_TILE:
+            return MDP_Y_CBCR_H2V2;
+        case MDP_Y_CB_CR_H2V2:
+            return MDP_Y_CBCR_H2V2;
+        default:
+            return format;
+    }
+    // not reached
+    OVASSERT(false, "%s not reached", __FUNCTION__);
+    return -1;
+}
+
+template<>
+struct RotOutFmt<ROT_OUT_FMT_DEFAULT>
+{
+    static inline int fmt(uint32_t format) {
+        return getRotOutFmt(format);
+    }
+};
+
+template<>
+struct RotOutFmt<ROT_OUT_FMT_Y_CRCB_H2V2>
+{
+    static inline int fmt(uint32_t) {
+        return MDP_Y_CRCB_H2V2;
+    }
+};
+
+inline uint32_t getColorFormat(uint32_t format)
+{
+    return (format == HAL_PIXEL_FORMAT_YV12) ?
+            format : colorFormat(format);
+}
+
+// FB0
+template <int CHAN>
+inline Dim getPositionS3DImpl(const Whf& whf)
+{
+    switch (whf.format & OUTPUT_3D_MASK)
+    {
+        case HAL_3D_OUT_SBS_MASK:
+            // x, y, w, h
+            return Dim(0, 0, whf.w/2, whf.h);
+        case HAL_3D_OUT_TOP_BOT_MASK:
+            return Dim(0, 0, whf.w, whf.h/2);
+        case HAL_3D_OUT_MONOS_MASK:
+            return Dim();
+        case HAL_3D_OUT_INTERL_MASK:
+            // FIXME error?
+            ALOGE("%s HAL_3D_OUT_INTERLEAVE_MASK", __FUNCTION__);
+            return Dim();
+        default:
+            ALOGE("%s Unsupported 3D output format %d", __FUNCTION__,
+                    whf.format);
+    }
+    return Dim();
+}
+
+template <>
+inline Dim getPositionS3DImpl<utils::OV_PIPE1>(const Whf& whf)
+{
+    switch (whf.format & OUTPUT_3D_MASK)
+    {
+        case HAL_3D_OUT_SBS_MASK:
+            return Dim(whf.w/2, 0, whf.w/2, whf.h);
+        case HAL_3D_OUT_TOP_BOT_MASK:
+            return Dim(0, whf.h/2, whf.w, whf.h/2);
+        case HAL_3D_OUT_MONOS_MASK:
+            return Dim(0, 0, whf.w, whf.h);
+        case HAL_3D_OUT_INTERL_MASK:
+            // FIXME error?
+            ALOGE("%s HAL_3D_OUT_INTERLEAVE_MASK", __FUNCTION__);
+            return Dim();
+        default:
+            ALOGE("%s Unsupported 3D output format %d", __FUNCTION__,
+                    whf.format);
+    }
+    return Dim();
+}
+
+template <int CHAN>
+inline bool getPositionS3D(const Whf& whf, Dim& out) {
+    out = getPositionS3DImpl<CHAN>(whf);
+    return (out != Dim());
+}
+
+template <int CHAN>
+inline Dim getCropS3DImpl(const Dim& in, uint32_t fmt) {
+    switch (fmt & INPUT_3D_MASK)
+    {
+        case HAL_3D_IN_SIDE_BY_SIDE_L_R:
+            return Dim(0, 0, in.w/2, in.h);
+        case HAL_3D_IN_SIDE_BY_SIDE_R_L:
+            return Dim(in.w/2, 0, in.w/2, in.h);
+        case HAL_3D_IN_TOP_BOTTOM:
+            return Dim(0, 0, in.w, in.h/2);
+        case HAL_3D_IN_INTERLEAVE:
+            ALOGE("%s HAL_3D_IN_INTERLEAVE", __FUNCTION__);
+            break;
+        default:
+            ALOGE("%s Unsupported 3D format %d", __FUNCTION__, fmt);
+            break;
+    }
+    return Dim();
+}
+
+template <>
+inline Dim getCropS3DImpl<utils::OV_PIPE1>(const Dim& in, uint32_t fmt) {
+    switch (fmt & INPUT_3D_MASK)
+    {
+        case HAL_3D_IN_SIDE_BY_SIDE_L_R:
+            return Dim(in.w/2, 0, in.w/2, in.h);
+        case HAL_3D_IN_SIDE_BY_SIDE_R_L:
+            return Dim(0, 0, in.w/2, in.h);
+        case HAL_3D_IN_TOP_BOTTOM:
+            return Dim(0, in.h/2, in.w, in.h/2);
+        case HAL_3D_IN_INTERLEAVE:
+            ALOGE("%s HAL_3D_IN_INTERLEAVE", __FUNCTION__);
+            break;
+        default:
+            ALOGE("%s Unsupported 3D format %d", __FUNCTION__, fmt);
+            break;
+    }
+    return Dim();
+}
+
+template <int CHAN>
+inline bool getCropS3D(const Dim& in, Dim& out, uint32_t fmt)
+{
+    out = getCropS3DImpl<CHAN>(in, fmt);
+    return (out != Dim());
+}
+
+template <class Type>
+void swapWidthHeight(Type& width, Type& height) {
+    Type tmp = width;
+    width = height;
+    height = tmp;
+}
+
+inline void ScreenInfo::dump(const char* const s) const {
+    ALOGE("== Dump %s ScreenInfo w=%d h=%d"
+            " bpp=%d stride=%d start/end ==",
+            s, mFBWidth, mFBHeight, mFBbpp, mFBystride);
+}
+
+inline void setSrcRectDim(const overlay::utils::Dim d,
+        mdp_overlay& ov) {
+    ov.src_rect.x = d.x;
+    ov.src_rect.y = d.y;
+    ov.src_rect.w = d.w;
+    ov.src_rect.h = d.h;
+}
+
+inline void setDstRectDim(const overlay::utils::Dim d,
+        mdp_overlay& ov) {
+    ov.dst_rect.x = d.x;
+    ov.dst_rect.y = d.y;
+    ov.dst_rect.w = d.w;
+    ov.dst_rect.h = d.h;
+}
+
+inline overlay::utils::Whf getSrcWhf(const mdp_overlay& ov) {
+    return overlay::utils::Whf(ov.src.width,
+            ov.src.height,
+            ov.src.format);
+}
+
+inline overlay::utils::Dim getSrcRectDim(const mdp_overlay& ov) {
+    return overlay::utils::Dim(ov.src_rect.x,
+            ov.src_rect.y,
+            ov.src_rect.w,
+            ov.src_rect.h);
+}
+
+inline overlay::utils::Dim getDstRectDim(const mdp_overlay& ov) {
+    return overlay::utils::Dim(ov.dst_rect.x,
+            ov.dst_rect.y,
+            ov.dst_rect.w,
+            ov.dst_rect.h);
+}
+
+
+} // namespace utils ends
+
+//--------------------Class Res stuff (namespace overlay only) -----------
+
+class Res {
+public:
+    // /dev/graphics/fb%u
+    static const char* const devTemplate;
+    // /dev/msm_rotator
+    static const char* const rotPath;
+    // /sys/class/graphics/fb1/format_3d
+    static const char* const format3DFile;
+    // /sys/class/graphics/fb1/3d_present
+    static const char* const edid3dInfoFile;
+    // /sys/devices/platform/mipi_novatek.0/enable_3d_barrier
+    static const char* const barrierFile;
+};
+
+
+//--------------------Class OvFD stuff (namespace overlay only) -----------
+
+class OvFD;
+
+/* helper function to open by using fbnum */
+bool open(OvFD& fd, uint32_t fbnum, const char* const dev,
+    int flags = O_RDWR);
+
+/*
+* Holds one FD
+* Dtor will NOT close the underlying FD.
+* That enables us to copy that object around
+* */
+class OvFD {
+public:
+    /* Ctor */
+    explicit OvFD();
+
+    /* dtor will NOT close the underlying FD */
+    ~OvFD();
+
+    /* Open fd using the path given by dev.
+     * return false in failure */
+    bool open(const char* const dev,
+            int flags = O_RDWR);
+
+    /* populate path */
+    void setPath(const char* const dev);
+
+    /* Close fd if we have a valid fd. */
+    bool close();
+
+    /* returns underlying fd.*/
+    int getFD() const;
+
+    /* returns true if fd is valid */
+    bool valid() const;
+
+    /* like operator= */
+    void copy(int fd);
+
+    /* dump the state of the instance */
+    void dump() const;
+private:
+    /* helper enum for determine valid/invalid fd */
+    enum { INVAL = -1 };
+
+    /* actual os fd */
+    int mFD;
+
+    /* path, for debugging */
+    char mPath[utils::MAX_PATH_LEN];
+};
+
+//-------------------Inlines--------------------------
+
+inline bool open(OvFD& fd, uint32_t fbnum, const char* const dev, int flags)
+{
+    char dev_name[64] = {0};
+    snprintf(dev_name, sizeof(dev_name), dev, fbnum);
+    return fd.open(dev_name, flags);
+}
+
+inline OvFD::OvFD() : mFD (INVAL) {
+    mPath[0] = 0;
+}
+
+inline OvFD::~OvFD() { /* no op in the meantime */ }
+
+inline bool OvFD::open(const char* const dev, int flags)
+{
+    mFD = ::open(dev, flags, 0);
+    if (mFD < 0) {
+        // FIXME errno, strerror in bionic?
+        ALOGE("Cant open device %s err=%d", dev, errno);
+        return false;
+    }
+    setPath(dev);
+    return true;
+}
+
+inline void OvFD::setPath(const char* const dev)
+{
+    ::strncpy(mPath, dev, utils::MAX_PATH_LEN);
+}
+
+inline bool OvFD::close()
+{
+    int ret = 0;
+    if(valid()) {
+        ret = ::close(mFD);
+        mFD = INVAL;
+    }
+    return (ret == 0);
+}
+
+inline bool OvFD::valid() const
+{
+    return (mFD != INVAL);
+}
+
+inline int OvFD::getFD() const { return mFD; }
+
+inline void OvFD::copy(int fd) {
+    mFD = fd;
+}
+
+inline void OvFD::dump() const
+{
+    ALOGE("== Dump OvFD fd=%d path=%s start/end ==",
+            mFD, mPath);
+}
+
+//--------------- class OvFD stuff ends ---------------------
+
+} // overlay
+
+
+#endif // OVERLAY_UTILS_H
diff --git a/liboverlay/pipes/overlay3DPipe.h b/liboverlay/pipes/overlay3DPipe.h
new file mode 100644
index 0000000..dce4bf4
--- /dev/null
+++ b/liboverlay/pipes/overlay3DPipe.h
@@ -0,0 +1,617 @@
+/*
+* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef OVERLAY_M3D_EXT_PIPE_H
+#define OVERLAY_M3D_EXT_PIPE_H
+
+#include "overlayGenPipe.h"
+#include "overlayUtils.h"
+
+namespace overlay {
+
+/////////////  M3DExt Pipe ////////////////////////////
+/**
+* A specific impl of GenericPipe for 3D.
+* Whenever needed to have a pass through - we do it.
+* If there is a special need for special/diff behavior
+* do it here
+* PANEL is always EXTERNAL for this pipe.
+* CHAN = 0,1 it's either Channel 1 or channel 2 needed for
+* 3D crop and position */
+template <int CHAN>
+class M3DExtPipe : utils::NoCopy {
+public:
+    /* Please look at overlayGenPipe.h for info */
+    explicit M3DExtPipe();
+    ~M3DExtPipe();
+    bool open(RotatorBase* rot);
+    bool close();
+    bool commit();
+    void setId(int id);
+    void setMemoryId(int id);
+    bool queueBuffer(uint32_t offset);
+    bool dequeueBuffer(void*& buf);
+    bool waitForVsync();
+    bool setCrop(const utils::Dim& d);
+    bool start(const utils::PipeArgs& args);
+    bool setPosition(const utils::Dim& dim);
+    bool setParameter(const utils::Params& param);
+    bool setSource(const utils::PipeArgs& args);
+    const utils::PipeArgs& getArgs() const;
+    utils::eOverlayPipeType getOvPipeType() const;
+    void dump() const;
+private:
+    overlay::GenericPipe<utils::EXTERNAL> mM3d;
+    // Cache the M3D format
+    uint32_t mM3Dfmt;
+};
+
+/////////////  M3DPrimary Pipe ////////////////////////////
+/**
+* A specific impl of GenericPipe for 3D.
+* Whenever needed to have a pass through - we do it.
+* If there is a special need for special/diff behavior
+* do it here
+* PANEL is always PRIMARY for this pipe.
+* CHAN = 0,1 it's either Channel 1 or channel 2 needed for
+* 3D crop and position */
+template <int CHAN>
+class M3DPrimaryPipe : utils::NoCopy {
+public:
+    /* Please look at overlayGenPipe.h for info */
+    explicit M3DPrimaryPipe();
+    ~M3DPrimaryPipe();
+    bool open(RotatorBase* rot);
+    bool close();
+    bool commit();
+    void setId(int id);
+    void setMemoryId(int id);
+    bool queueBuffer(uint32_t offset);
+    bool dequeueBuffer(void*& buf);
+    bool waitForVsync();
+    bool setCrop(const utils::Dim& d);
+    bool start(const utils::PipeArgs& args);
+    bool setPosition(const utils::Dim& dim);
+    bool setParameter(const utils::Params& param);
+    bool setSource(const utils::PipeArgs& args);
+    const utils::PipeArgs& getArgs() const;
+    utils::eOverlayPipeType getOvPipeType() const;
+    void dump() const;
+private:
+    overlay::GenericPipe<utils::PRIMARY> mM3d;
+    // Cache the M3D format
+    uint32_t mM3Dfmt;
+};
+
+/////////////  S3DExt Pipe ////////////////////////////////
+/**
+* A specific impl of GenericPipe for 3D.
+* Whenever needed to have a pass through - we do it.
+* If there is a special need for special/diff behavior
+* do it here.
+* PANEL is always EXTERNAL for this pipe.
+* CHAN = 0,1 it's either Channel 1 or channel 2 needed for
+* 3D crop and position */
+template <int CHAN>
+class S3DExtPipe : utils::NoCopy {
+public:
+    /* Please look at overlayGenPipe.h for info */
+    explicit S3DExtPipe();
+    ~S3DExtPipe();
+    bool open(RotatorBase* rot);
+    bool close();
+    bool commit();
+    void setId(int id);
+    void setMemoryId(int id);
+    bool queueBuffer(uint32_t offset);
+    bool dequeueBuffer(void*& buf);
+    bool waitForVsync();
+    bool setCrop(const utils::Dim& d);
+    bool start(const utils::PipeArgs& args);
+    bool setPosition(const utils::Dim& dim);
+    bool setParameter(const utils::Params& param);
+    bool setSource(const utils::PipeArgs& args);
+    const utils::PipeArgs& getArgs() const;
+    utils::eOverlayPipeType getOvPipeType() const;
+    void dump() const;
+private:
+    overlay::GenericPipe<utils::EXTERNAL> mS3d;
+    // Cache the 3D format
+    uint32_t mS3Dfmt;
+};
+
+/////////////  S3DPrimary Pipe ////////////////////////////
+/**
+* A specific impl of GenericPipe for 3D.
+* Whenever needed to have a pass through - we do it.
+* If there is a special need for special/diff behavior
+* do it here
+* PANEL is always PRIMARY for this pipe.
+* CHAN = 0,1 it's either Channel 1 or channel 2 needed for
+* 3D crop and position */
+template <int CHAN>
+class S3DPrimaryPipe : utils::NoCopy {
+public:
+    /* Please look at overlayGenPipe.h for info */
+    explicit S3DPrimaryPipe();
+    ~S3DPrimaryPipe();
+    bool open(RotatorBase* rot);
+    bool close();
+    bool commit();
+    void setId(int id);
+    void setMemoryId(int id);
+    bool queueBuffer(uint32_t offset);
+    bool dequeueBuffer(void*& buf);
+    bool waitForVsync();
+    bool setCrop(const utils::Dim& d);
+    bool start(const utils::PipeArgs& args);
+    bool setPosition(const utils::Dim& dim);
+    bool setParameter(const utils::Params& param);
+    bool setSource(const utils::PipeArgs& args);
+    const utils::PipeArgs& getArgs() const;
+    utils::eOverlayPipeType getOvPipeType() const;
+    void dump() const;
+private:
+    /* needed for 3D related IOCTL */
+    MdpCtrl3D mCtrl3D;
+    overlay::GenericPipe<utils::PRIMARY> mS3d;
+    // Cache the 3D format
+    uint32_t mS3Dfmt;
+};
+
+
+
+
+//------------------------Inlines and Templates--------------------------
+
+
+/////////////  M3DExt Pipe ////////////////////////////
+template <int CHAN>
+inline M3DExtPipe<CHAN>::M3DExtPipe() : mM3Dfmt(0) {}
+template <int CHAN>
+inline M3DExtPipe<CHAN>::~M3DExtPipe() { close(); }
+template <int CHAN>
+inline bool M3DExtPipe<CHAN>::open(RotatorBase* rot) {
+    ALOGE_IF(DEBUG_OVERLAY, "M3DExtPipe open");
+    if(!mM3d.open(rot)) {
+        ALOGE("3Dpipe failed to open");
+        return false;
+    }
+    return true;
+}
+template <int CHAN>
+inline bool M3DExtPipe<CHAN>::close() {
+    return mM3d.close();
+}
+template <int CHAN>
+inline bool M3DExtPipe<CHAN>::commit() { return mM3d.commit(); }
+template <int CHAN>
+inline void M3DExtPipe<CHAN>::setId(int id) { mM3d.setId(id); }
+template <int CHAN>
+inline void M3DExtPipe<CHAN>::setMemoryId(int id) { mM3d.setMemoryId(id); }
+template <int CHAN>
+inline bool M3DExtPipe<CHAN>::queueBuffer(uint32_t offset) {
+    return mM3d.queueBuffer(offset); }
+template <int CHAN>
+inline bool M3DExtPipe<CHAN>::dequeueBuffer(void*& buf) {
+    return mM3d.dequeueBuffer(buf); }
+template <int CHAN>
+inline bool M3DExtPipe<CHAN>::waitForVsync() {
+    return mM3d.waitForVsync(); }
+template <int CHAN>
+inline bool M3DExtPipe<CHAN>::setCrop(const utils::Dim& d) {
+    utils::Dim _dim;
+    if(!utils::getCropS3D<CHAN>(d, _dim, mM3Dfmt)){
+        ALOGE("M3DExtPipe setCrop failed to getCropS3D");
+        _dim = d;
+    }
+    return mM3d.setCrop(_dim);
+}
+template <int CHAN>
+inline bool M3DExtPipe<CHAN>::start(const utils::PipeArgs& args) {
+    if(!mM3d.start(args)) {
+        ALOGE("M3DExtPipe start failed");
+        return false;
+    }
+    return true;
+}
+template <int CHAN>
+inline bool M3DExtPipe<CHAN>::setPosition(const utils::Dim& d) {
+    utils::Dim _dim;
+    // original setPositionHandleState has getPositionS3D(...,true)
+    // which means format is HAL_3D_OUT_SBS_MASK
+    // HAL_3D_OUT_SBS_MASK is 0x1000 >> 12 == 0x1 as the orig
+    // code suggets
+    utils::Whf _whf(mM3d.getScreenInfo().mFBWidth,
+            mM3d.getScreenInfo().mFBHeight,
+            mM3Dfmt);
+    if(!utils::getPositionS3D<CHAN>(_whf, _dim)) {
+        ALOGE("S3DPrimaryPipe setPosition err in getPositionS3D");
+        _dim = d;
+    }
+    return mM3d.setPosition(_dim);
+}
+template <int CHAN>
+inline bool M3DExtPipe<CHAN>::setParameter(const utils::Params& param) {
+    return mM3d.setParameter(param);
+}
+template <int CHAN>
+inline bool M3DExtPipe<CHAN>::setSource(const utils::PipeArgs& args)
+{
+    // extract 3D fmt
+    mM3Dfmt = utils::format3DInput(utils::getS3DFormat(args.whf.format)) |
+            utils::HAL_3D_OUT_MONOS_MASK;
+    if(mM3d.isClosed()){
+        if(!this->start(args)) {
+            ALOGE("M3DExtPipe setSource failed to start");
+            return false;
+        }
+    }
+    return mM3d.setSource(args);
+}
+template <int CHAN>
+inline const utils::PipeArgs& M3DExtPipe<CHAN>::getArgs() const {
+    return mM3d.getArgs();
+}
+template <int CHAN>
+inline utils::eOverlayPipeType M3DExtPipe<CHAN>::getOvPipeType() const {
+    return utils::OV_PIPE_TYPE_M3D_EXTERNAL;
+}
+template <int CHAN>
+inline void M3DExtPipe<CHAN>::dump() const {
+    ALOGE("M3DExtPipe Pipe fmt=%d", mM3Dfmt);
+    mM3d.dump();
+}
+
+
+/////////////  M3DPrimary Pipe ////////////////////////////
+template <int CHAN>
+inline M3DPrimaryPipe<CHAN>::M3DPrimaryPipe() : mM3Dfmt(0) {}
+template <int CHAN>
+inline M3DPrimaryPipe<CHAN>::~M3DPrimaryPipe() { close(); }
+template <int CHAN>
+inline bool M3DPrimaryPipe<CHAN>::open(RotatorBase* rot) {
+    ALOGE_IF(DEBUG_OVERLAY, "M3DPrimaryPipe open");
+    if(!mM3d.open(rot)) {
+        ALOGE("3Dpipe failed to open");
+        return false;
+    }
+    return true;
+}
+template <int CHAN>
+inline bool M3DPrimaryPipe<CHAN>::close() {
+    return mM3d.close();
+}
+template <int CHAN>
+inline bool M3DPrimaryPipe<CHAN>::commit() { return mM3d.commit(); }
+template <int CHAN>
+inline void M3DPrimaryPipe<CHAN>::setId(int id) { mM3d.setId(id); }
+template <int CHAN>
+inline void M3DPrimaryPipe<CHAN>::setMemoryId(int id) { mM3d.setMemoryId(id); }
+template <int CHAN>
+inline bool M3DPrimaryPipe<CHAN>::queueBuffer(uint32_t offset) {
+    return mM3d.queueBuffer(offset); }
+template <int CHAN>
+inline bool M3DPrimaryPipe<CHAN>::dequeueBuffer(void*& buf) {
+    return mM3d.dequeueBuffer(buf); }
+template <int CHAN>
+inline bool M3DPrimaryPipe<CHAN>::waitForVsync() {
+    return mM3d.waitForVsync(); }
+template <int CHAN>
+inline bool M3DPrimaryPipe<CHAN>::setCrop(const utils::Dim& d) {
+    utils::Dim _dim;
+    if(!utils::getCropS3D<CHAN>(d, _dim, mM3Dfmt)){
+        ALOGE("M3DPrimaryPipe setCrop failed to getCropS3D");
+        _dim = d;
+    }
+    return mM3d.setCrop(_dim);
+}
+template <int CHAN>
+inline bool M3DPrimaryPipe<CHAN>::start(const utils::PipeArgs& args) {
+    if(!mM3d.start(args)) {
+        ALOGE("M3DPrimaryPipe start failed");
+        return false;
+    }
+    return true;
+}
+template <int CHAN>
+inline bool M3DPrimaryPipe<CHAN>::setPosition(const utils::Dim& d) {
+    return mM3d.setPosition(d);
+}
+template <int CHAN>
+inline bool M3DPrimaryPipe<CHAN>::setParameter(const utils::Params& param) {
+    return mM3d.setParameter(param);
+}
+template <int CHAN>
+inline bool M3DPrimaryPipe<CHAN>::setSource(const utils::PipeArgs& args)
+{
+    // extract 3D fmt
+    mM3Dfmt = utils::format3DInput(utils::getS3DFormat(args.whf.format)) |
+            utils::HAL_3D_OUT_MONOS_MASK;
+    if (mM3d.isClosed()) {
+        if (!this->start(args)) {
+            ALOGE("M3DPrimaryPipe setSource failed to start");
+            return false;
+        }
+    }
+    return mM3d.setSource(args);
+}
+template <int CHAN>
+inline const utils::PipeArgs& M3DPrimaryPipe<CHAN>::getArgs() const {
+    return mM3d.getArgs();
+}
+template <int CHAN>
+inline utils::eOverlayPipeType M3DPrimaryPipe<CHAN>::getOvPipeType() const {
+    return utils::OV_PIPE_TYPE_M3D_PRIMARY;
+}
+template <int CHAN>
+inline void M3DPrimaryPipe<CHAN>::dump() const {
+    ALOGE("M3DPrimaryPipe Pipe fmt=%d", mM3Dfmt);
+    mM3d.dump();
+}
+
+/////////////  S3DExt Pipe ////////////////////////////////
+template <int CHAN>
+inline S3DExtPipe<CHAN>::S3DExtPipe() : mS3Dfmt(0) {}
+template <int CHAN>
+inline S3DExtPipe<CHAN>::~S3DExtPipe() { close(); }
+template <int CHAN>
+inline bool S3DExtPipe<CHAN>::open(RotatorBase* rot) {
+    ALOGE_IF(DEBUG_OVERLAY, "S3DExtPipe open");
+    if(!mS3d.open(rot)) {
+        ALOGE("3Dpipe failed to open");
+        return false;
+    }
+    return true;
+}
+template <int CHAN>
+inline bool S3DExtPipe<CHAN>::close() {
+    if(!utils::send3DInfoPacket(0)) {
+        ALOGE("S3DExtPipe close failed send3D info packet");
+    }
+    return mS3d.close();
+}
+template <int CHAN>
+inline bool S3DExtPipe<CHAN>::commit() { return mS3d.commit(); }
+template <int CHAN>
+inline void S3DExtPipe<CHAN>::setId(int id) { mS3d.setId(id); }
+template <int CHAN>
+inline void S3DExtPipe<CHAN>::setMemoryId(int id) { mS3d.setMemoryId(id); }
+template <int CHAN>
+inline bool S3DExtPipe<CHAN>::queueBuffer(uint32_t offset) {
+    //this->dump();
+    return mS3d.queueBuffer(offset); }
+template <int CHAN>
+inline bool S3DExtPipe<CHAN>::dequeueBuffer(void*& buf) {
+    return mS3d.dequeueBuffer(buf); }
+template <int CHAN>
+inline bool S3DExtPipe<CHAN>::waitForVsync() {
+    return mS3d.waitForVsync(); }
+template <int CHAN>
+inline bool S3DExtPipe<CHAN>::setCrop(const utils::Dim& d) {
+    utils::Dim _dim;
+    if(!utils::getCropS3D<CHAN>(d, _dim, mS3Dfmt)){
+        ALOGE("S3DExtPipe setCrop failed to getCropS3D");
+        _dim = d;
+    }
+    return mS3d.setCrop(_dim);
+}
+template <int CHAN>
+inline bool S3DExtPipe<CHAN>::start(const utils::PipeArgs& args) {
+    OVASSERT(mS3Dfmt, "S3DExtPipe mS3Dfmt should not be 0 here");
+    if(!mS3d.start(args)) {
+        ALOGE("S3DExtPipe start failed");
+        return false;
+    }
+    uint32_t fmt = mS3Dfmt & utils::OUTPUT_3D_MASK;
+    if(!utils::send3DInfoPacket(fmt)){
+        ALOGE("Error S3DExtPipe start error send3DInfoPacket %d", fmt);
+        return false;
+    }
+    return true;
+}
+template <int CHAN>
+inline bool S3DExtPipe<CHAN>::setPosition(const utils::Dim& d)
+{
+    utils::Dim _dim;
+    utils::Whf _whf(mS3d.getScreenInfo().mFBWidth,
+            mS3d.getScreenInfo().mFBHeight,
+            mS3Dfmt);
+    if(!utils::getPositionS3D<CHAN>(_whf, _dim)) {
+        ALOGE("S3DExtPipe setPosition err in getPositionS3D");
+        _dim = d;
+    }
+    return mS3d.setPosition(_dim);
+}
+template <int CHAN>
+inline bool S3DExtPipe<CHAN>::setParameter(const utils::Params& param) {
+    return mS3d.setParameter(param);
+}
+template <int CHAN>
+inline bool S3DExtPipe<CHAN>::setSource(const utils::PipeArgs& args) {
+    mS3Dfmt = utils::getS3DFormat(args.whf.format);
+    if(mS3d.isClosed()){
+        if(!this->start(args)) {
+            ALOGE("S3DExtPipe setSource failed to start");
+            return false;
+        }
+    }
+    return mS3d.setSource(args);
+}
+template <int CHAN>
+inline const utils::PipeArgs& S3DExtPipe<CHAN>::getArgs() const {
+    return mS3d.getArgs();
+}
+template <int CHAN>
+inline utils::eOverlayPipeType S3DExtPipe<CHAN>::getOvPipeType() const {
+    return utils::OV_PIPE_TYPE_S3D_EXTERNAL;
+}
+template <int CHAN>
+inline void S3DExtPipe<CHAN>::dump() const {
+    ALOGE("S3DExtPipe Pipe fmt=%d", mS3Dfmt);
+    mS3d.dump();
+}
+
+/////////////  S3DPrimary Pipe ////////////////////////////
+template <int CHAN>
+inline S3DPrimaryPipe<CHAN>::S3DPrimaryPipe() : mS3Dfmt(0) {}
+template <int CHAN>
+inline S3DPrimaryPipe<CHAN>::~S3DPrimaryPipe() { close(); }
+template <int CHAN>
+inline bool S3DPrimaryPipe<CHAN>::open(RotatorBase* rot) {
+    ALOGE_IF(DEBUG_OVERLAY, "S3DPrimaryPipe open");
+    if(!mS3d.open(rot)) {
+        ALOGE("3Dpipe failed to open");
+        return false;
+    }
+    // set the ctrl fd
+    mCtrl3D.setFd(mS3d.getCtrlFd());
+    return true;
+}
+template <int CHAN>
+inline bool S3DPrimaryPipe<CHAN>::close() {
+    if(!utils::enableBarrier(0)) {
+        ALOGE("S3DExtPipe close failed enable barrier");
+    }
+    mCtrl3D.close();
+    return mS3d.close();
+}
+template <int CHAN>
+inline bool S3DPrimaryPipe<CHAN>::commit() { return mS3d.commit(); }
+template <int CHAN>
+inline void S3DPrimaryPipe<CHAN>::setId(int id) { mS3d.setId(id); }
+template <int CHAN>
+inline void S3DPrimaryPipe<CHAN>::setMemoryId(int id) { mS3d.setMemoryId(id); }
+template <int CHAN>
+inline bool S3DPrimaryPipe<CHAN>::queueBuffer(uint32_t offset) {
+    return mS3d.queueBuffer(offset); }
+template <int CHAN>
+inline bool S3DPrimaryPipe<CHAN>::dequeueBuffer(void*& buf) {
+    return mS3d.dequeueBuffer(buf); }
+template <int CHAN>
+inline bool S3DPrimaryPipe<CHAN>::waitForVsync() {
+    return mS3d.waitForVsync(); }
+template <int CHAN>
+inline bool S3DPrimaryPipe<CHAN>::setCrop(const utils::Dim& d) {
+    utils::Dim _dim;
+    if(!utils::getCropS3D<CHAN>(d, _dim, mS3Dfmt)){
+        ALOGE("S3DPrimaryPipe setCrop failed to getCropS3D");
+        _dim = d;
+    }
+    return mS3d.setCrop(_dim);
+}
+template <int CHAN>
+inline bool S3DPrimaryPipe<CHAN>::start(const utils::PipeArgs& args) {
+    if(!mS3d.start(args)) {
+        ALOGE("S3DPrimaryPipe start failed");
+        return false;
+    }
+    return true;
+}
+template <int CHAN>
+inline bool S3DPrimaryPipe<CHAN>::setPosition(const utils::Dim& d)
+{
+    utils::Whf fbwhf(mS3d.getScreenInfo().mFBWidth,
+            mS3d.getScreenInfo().mFBHeight,
+            0 /* fmt dont care*/);
+    mCtrl3D.setWh(fbwhf);
+    if(!mCtrl3D.useVirtualFB()) {
+        ALOGE("Failed to use VFB on %d (non fatal)", utils::FB0);
+        return false;
+    }
+    utils::Dim _dim;
+    // original setPositionHandleState has getPositionS3D(...,true)
+    // which means format is HAL_3D_OUT_SBS_MASK
+    // HAL_3D_OUT_SBS_MASK is 0x1000 >> 12 == 0x1 as the orig
+    // code suggets
+    utils::Whf _whf(d.w, d.h, utils::HAL_3D_OUT_SBS_MASK);
+    if(!utils::getPositionS3D<CHAN>(_whf, _dim)) {
+        ALOGE("S3DPrimaryPipe setPosition err in getPositionS3D");
+        _dim = d;
+    }
+    return mS3d.setPosition(_dim);
+}
+
+/* for S3DPrimaryPipe, we need to have barriers once
+* So the easiest way to achieve it, is to make sure FB0 is having it before
+* setParam is running */
+template <>
+inline bool S3DPrimaryPipe<utils::OV_PIPE0>::setParameter(
+        const utils::Params& param) {
+    if(utils::OVERLAY_TRANSFORM == param.param){
+        uint32_t barrier=0;
+        switch(param.value) {
+            case HAL_TRANSFORM_ROT_90:
+            case HAL_TRANSFORM_ROT_270:
+                barrier = utils::BARRIER_LAND;
+                break;
+            default:
+                barrier = utils::BARRIER_PORT;
+                break;
+        }
+        if(!utils::enableBarrier(barrier)) {
+            ALOGE("S3DPrimaryPipe setParameter failed to enable barrier");
+        }
+    }
+    return mS3d.setParameter(param);
+}
+
+template <int CHAN>
+inline bool S3DPrimaryPipe<CHAN>::setParameter(const utils::Params& param) {
+    return mS3d.setParameter(param);
+}
+template <int CHAN>
+inline bool S3DPrimaryPipe<CHAN>::setSource(const utils::PipeArgs& args)
+{
+    mS3Dfmt = utils::getS3DFormat(args.whf.format);
+    if(mS3d.isClosed()){
+        if(!this->start(args)) {
+            ALOGE("S3DPrimaryPipe setSource failed to start");
+            return false;
+        }
+    }
+    return mS3d.setSource(args);
+}
+template <int CHAN>
+inline const utils::PipeArgs& S3DPrimaryPipe<CHAN>::getArgs() const {
+    return mS3d.getArgs();
+}
+template <int CHAN>
+inline utils::eOverlayPipeType S3DPrimaryPipe<CHAN>::getOvPipeType() const {
+    return utils::OV_PIPE_TYPE_S3D_PRIMARY;
+}
+template <int CHAN>
+inline void S3DPrimaryPipe<CHAN>::dump() const {
+    ALOGE("S3DPrimaryPipe Pipe fmt=%d", mS3Dfmt);
+    mS3d.dump();
+}
+
+} // overlay
+
+#endif // OVERLAY_M3D_EXT_PIPE_H
diff --git a/liboverlay/pipes/overlayBypassPipe.h b/liboverlay/pipes/overlayBypassPipe.h
new file mode 100644
index 0000000..593a693
--- /dev/null
+++ b/liboverlay/pipes/overlayBypassPipe.h
@@ -0,0 +1,213 @@
+/*
+* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef OVERLAY_BYPASS_PIPE_H
+#define OVERLAY_BYPASS_PIPE_H
+
+#include "overlayGenPipe.h"
+#include "overlayUtils.h"
+#include "overlayCtrlData.h"
+#include "overlayMdp.h"
+#include "overlayRotator.h"
+
+namespace overlay {
+
+/* A specific impl of GenericPipe
+* Whenever needed to have a pass through - we do it.
+* If there is a special need for a different behavior - do it here
+* PipeType = 0 (RGB), 1 (VG) */
+template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
+    utils::eZorder Zorder>
+class BypassPipe : utils::NoCopy {
+public:
+    /* Please look at overlayGenPipe.h for info */
+    explicit BypassPipe();
+    ~BypassPipe();
+    bool open(RotatorBase* rot);
+    bool close();
+    bool commit();
+    void setId(int id);
+    void setMemoryId(int id);
+    bool queueBuffer(uint32_t offset);
+    bool dequeueBuffer(void*& buf);
+    bool waitForVsync();
+    bool setCrop(const utils::Dim& dim);
+    bool start(const utils::PipeArgs& args);
+    bool setPosition(const utils::Dim& dim);
+    bool setParameter(const utils::Params& param);
+    bool setSource(const utils::PipeArgs& args);
+    const utils::PipeArgs& getArgs() const;
+    utils::eOverlayPipeType getOvPipeType() const;
+    void dump() const;
+private:
+    overlay::GenericPipe<ovutils::PRIMARY> mBypass;
+};
+
+//------------------Inlines and Templates---------------------
+
+template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
+    utils::eZorder Zorder>
+inline BypassPipe<PipeType, IsFg, Wait, Zorder>::BypassPipe() {}
+
+template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
+    utils::eZorder Zorder>
+inline BypassPipe<PipeType, IsFg, Wait, Zorder>::~BypassPipe() {
+    close();
+}
+
+template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
+    utils::eZorder Zorder>
+inline bool BypassPipe<PipeType, IsFg, Wait, Zorder>::open(RotatorBase* rot) {
+    ALOGE_IF(DEBUG_OVERLAY, "BypassPipe open");
+    return mBypass.open(rot);
+}
+
+template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
+    utils::eZorder Zorder>
+inline bool BypassPipe<PipeType, IsFg, Wait, Zorder>::close() {
+    return mBypass.close();
+}
+
+template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
+    utils::eZorder Zorder>
+inline bool BypassPipe<PipeType, IsFg, Wait, Zorder>::commit() {
+    return mBypass.commit();
+}
+
+template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
+    utils::eZorder Zorder>
+inline void BypassPipe<PipeType, IsFg, Wait, Zorder>::setId(int id) {
+    mBypass.setId(id);
+}
+
+template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
+    utils::eZorder Zorder>
+inline void BypassPipe<PipeType, IsFg, Wait, Zorder>::setMemoryId(int id) {
+    mBypass.setMemoryId(id);
+}
+
+template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
+    utils::eZorder Zorder>
+inline bool BypassPipe<PipeType, IsFg, Wait, Zorder>::queueBuffer(
+        uint32_t offset) {
+    return mBypass.queueBuffer(offset);
+}
+
+template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
+    utils::eZorder Zorder>
+inline bool BypassPipe<PipeType, IsFg, Wait, Zorder>::dequeueBuffer(
+        void*& buf) {
+    return mBypass.dequeueBuffer(buf);
+}
+
+template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
+    utils::eZorder Zorder>
+inline bool BypassPipe<PipeType, IsFg, Wait, Zorder>::waitForVsync() {
+    return mBypass.waitForVsync();
+}
+
+template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
+    utils::eZorder Zorder>
+inline bool BypassPipe<PipeType, IsFg, Wait, Zorder>::setCrop(
+        const utils::Dim& dim) {
+    return mBypass.setCrop(dim);
+}
+
+template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
+    utils::eZorder Zorder>
+inline bool BypassPipe<PipeType, IsFg, Wait, Zorder>::start(
+        const utils::PipeArgs& args) {
+    return mBypass.start(args);
+}
+
+template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
+    utils::eZorder Zorder>
+inline bool BypassPipe<PipeType, IsFg, Wait, Zorder>::setPosition(
+        const utils::Dim& dim) {
+    return mBypass.setPosition(dim);
+}
+
+template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
+    utils::eZorder Zorder>
+inline bool BypassPipe<PipeType, IsFg, Wait, Zorder>::setParameter(
+        const utils::Params& param) {
+    return mBypass.setParameter(param);
+}
+
+template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
+    utils::eZorder Zorder>
+inline bool BypassPipe<PipeType, IsFg, Wait, Zorder>::setSource(
+        const utils::PipeArgs& args) {
+    utils::PipeArgs arg(args);
+
+    // Stride aligned to 32
+    arg.whf.w = utils::align(arg.whf.w, 32);
+    arg.whf.h = utils::align(arg.whf.h, 32);
+
+    // VG or RG pipe
+    if (PipeType == utils::OV_MDP_PIPE_VG) {
+        setMdpFlags(arg.mdpFlags, utils::OV_MDP_PIPE_SHARE);
+    }
+
+    // Set is_fg flag
+    arg.isFg = IsFg;
+
+    // Wait or no wait
+    arg.wait = Wait;
+
+    // Z-order
+    arg.zorder = Zorder;
+
+    return mBypass.setSource(arg);
+}
+
+template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
+    utils::eZorder Zorder>
+inline const utils::PipeArgs& BypassPipe<PipeType, IsFg, Wait,
+        Zorder>::getArgs() const {
+    return mBypass.getArgs();
+}
+
+template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
+    utils::eZorder Zorder>
+inline utils::eOverlayPipeType BypassPipe<PipeType, IsFg, Wait,
+        Zorder>::getOvPipeType() const {
+    return utils::OV_PIPE_TYPE_BYPASS;
+}
+
+template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
+    utils::eZorder Zorder>
+inline void BypassPipe<PipeType, IsFg, Wait, Zorder>::dump() const {
+    ALOGE("Bypass VG Pipe");
+    mBypass.dump();
+}
+
+} // overlay
+
+#endif // OVERLAY_BYPASS_PIPE_H
diff --git a/liboverlay/pipes/overlayGenPipe.h b/liboverlay/pipes/overlayGenPipe.h
new file mode 100644
index 0000000..1fd4a4f
--- /dev/null
+++ b/liboverlay/pipes/overlayGenPipe.h
@@ -0,0 +1,403 @@
+/*
+* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef OVERLAY_GENERIC_PIPE_H
+#define OVERLAY_GENERIC_PIPE_H
+
+#include "overlayUtils.h"
+#include "overlayRotator.h"
+#include "overlayCtrlData.h"
+
+// FIXME make int to be uint32 whenever possible
+
+namespace overlay {
+
+template <int PANEL>
+class GenericPipe : utils::NoCopy {
+public:
+    /* ctor init */
+    explicit GenericPipe();
+
+    /* dtor close */
+    ~GenericPipe();
+
+    /* CTRL/DATA/ROT open */
+    bool open(RotatorBase* rot);
+
+    /* CTRL/DATA close. Not owning rotator, will not close it */
+    bool close();
+
+    /* commit changes to the overlay "set"*/
+    bool commit();
+
+    /* "Data" related interface */
+
+    /* set ID directly to data channel */
+    void setId(int id);
+
+    /* Set FD / memid */
+    void setMemoryId(int id);
+
+    /* queue buffer to the overlay */
+    bool queueBuffer(uint32_t offset);
+
+    /* dequeue buffer to the overlay NOTSUPPORTED */
+    bool dequeueBuffer(void*& buf);
+
+    /* wait for vsync to be done */
+    bool waitForVsync();
+
+    /* set crop data FIXME setROI (Region Of Intrest) */
+    bool setCrop(const utils::Dim& d);
+
+    /* "Ctrl" related interface */
+
+    /*
+     * Start a session, opens the rotator
+     * FIXME, we might want to open the rotator separately
+     */
+    bool start(const utils::PipeArgs& args);
+
+    /* set mdp posision using dim */
+    bool setPosition(const utils::Dim& dim);
+
+    /* set param using Params (param,value pair) */
+    bool setParameter(const utils::Params& param);
+
+    /* set source using whf, orient and wait flag */
+    bool setSource(const utils::PipeArgs& args);
+
+    /* return cached startup args */
+    const utils::PipeArgs& getArgs() const;
+
+    /* retrieve screen info */
+    utils::ScreenInfo getScreenInfo() const;
+
+    /* retrieve cached crop data */
+    utils::Dim getCrop() const;
+
+    /* return aspect ratio from ctrl data */
+    utils::Dim getAspectRatio(const utils::Whf& whf) const;
+
+    /* return aspect ratio from ctrl data for true UI mirroring */
+    utils::Dim getAspectRatio(const utils::Dim& dim) const;
+
+    /* is closed */
+    bool isClosed() const;
+
+    /* is open */
+    bool isOpen() const;
+
+    /* return Ctrl fd. Used for S3D */
+    int getCtrlFd() const;
+
+    /* Get the overlay pipe type */
+    utils::eOverlayPipeType getOvPipeType() const;
+
+    /* dump the state of the object */
+    void dump() const;
+private:
+    /* set Closed channel */
+    bool setClosed();
+    // kick off rotator.
+    bool startRotator();
+
+    /* Ctrl/Data aggregator */
+    CtrlData mCtrlData;
+
+    /* caching startup params. useful when need
+     * to have the exact copy of that pipe.
+     * For example when HDMI is connected, and we would
+     * like to open/start the pipe with the args */
+    utils::PipeArgs mArgs;
+
+    /* rotator mdp base
+     * Can point to NullRotator or to Rotator*/
+    RotatorBase* mRot;
+
+    /* my flags */
+    enum { CLOSED = 1<<0 };
+    uint32_t mFlags;
+};
+
+//------------------------Inlines and Templates ----------------------
+
+template <int PANEL>
+GenericPipe<PANEL>::GenericPipe() : mRot(0), mFlags(CLOSED) {}
+
+template <int PANEL>
+GenericPipe<PANEL>::~GenericPipe() {
+    close();
+}
+
+template <int PANEL>
+bool GenericPipe<PANEL>::open(RotatorBase* rot)
+{
+    OVASSERT(rot, "rot is null");
+    // open ctrl and data
+    uint32_t fbnum = utils::getFBForPanel(PANEL);
+    ALOGE_IF(DEBUG_OVERLAY, "GenericPipe open");
+    if(!mCtrlData.ctrl.open(fbnum, rot)) {
+        ALOGE("GenericPipe failed to open ctrl");
+        return false;
+    }
+    if(!mCtrlData.data.open(fbnum, rot)) {
+        ALOGE("GenericPipe failed to open data");
+        return false;
+    }
+    mRot = rot;
+
+    // NOTE: we won't have the flags as non CLOSED since we
+    // consider the pipe opened for business only when we call
+    // start()
+
+    return true;
+}
+
+template <int PANEL>
+bool GenericPipe<PANEL>::close() {
+    if(isClosed()) return true;
+    bool ret = true;
+    if(!mCtrlData.ctrl.close()) {
+        ALOGE("GenericPipe failed to close ctrl");
+        ret = false;
+    }
+    if (!mCtrlData.data.close()) {
+        ALOGE("GenericPipe failed to close data");
+        ret = false;
+    }
+    setClosed();
+    return ret;
+}
+
+template <int PANEL>
+inline bool GenericPipe<PANEL>::commit(){
+    OVASSERT(isOpen(), "State is closed, cannot commit");
+    return mCtrlData.ctrl.commit();
+}
+
+template <int PANEL>
+inline void GenericPipe<PANEL>::setMemoryId(int id) {
+    OVASSERT(isOpen(), "State is closed, cannot setMemoryId");
+    mCtrlData.data.setMemoryId(id);
+}
+
+template <int PANEL>
+inline void GenericPipe<PANEL>::setId(int id) {
+    mCtrlData.data.setId(id); }
+
+template <int PANEL>
+inline int GenericPipe<PANEL>::getCtrlFd() const {
+    return mCtrlData.ctrl.getFd();
+}
+
+template <int PANEL>
+inline bool GenericPipe<PANEL>::setCrop(
+        const overlay::utils::Dim& d) {
+    OVASSERT(isOpen(), "State is closed, cannot setCrop");
+    return mCtrlData.ctrl.setCrop(d);
+}
+
+template <int PANEL>
+bool GenericPipe<PANEL>::start(const utils::PipeArgs& args)
+{
+    /* open before your start control rotator */
+    uint32_t sz = args.whf.size; //utils::getSizeByMdp(args.whf);
+    OVASSERT(sz, "GenericPipe sz=%d", sz);
+    if(!mRot->open()) {
+        ALOGE("GenericPipe start failed to open rot");
+        return false;
+    }
+
+    if(!mCtrlData.ctrl.start(args)){
+        ALOGE("GenericPipe failed to start");
+        return false;
+    }
+
+    int ctrlId = mCtrlData.ctrl.getId();
+    OVASSERT(-1 != ctrlId, "Ctrl ID should not be -1");
+    // set ID requeset to assoc ctrl to data
+    setId(ctrlId);
+    // set ID request to assoc MDP data to ROT MDP data
+    mRot->setDataReqId(mCtrlData.data.getId());
+
+    // cache the args for future reference.
+    mArgs = args;
+
+    // we got here so we are open+start and good to go
+    mFlags = 0; // clear flags from CLOSED
+    // TODO make it more robust when more flags
+    // are added
+
+    return true;
+}
+
+template <int PANEL>
+inline const utils::PipeArgs& GenericPipe<PANEL>::getArgs() const
+{
+    return mArgs;
+}
+
+template <int PANEL>
+bool GenericPipe<PANEL>::startRotator() {
+    // kick off rotator
+    if(!mRot->start()) {
+        ALOGE("GenericPipe failed to start rotator");
+        return false;
+    }
+    return true;
+}
+
+template <int PANEL>
+inline bool GenericPipe<PANEL>::queueBuffer(uint32_t offset) {
+    OVASSERT(isOpen(), "State is closed, cannot queueBuffer");
+    return mCtrlData.data.queueBuffer(offset);
+}
+
+template <int PANEL>
+inline bool GenericPipe<PANEL>::dequeueBuffer(void*&) {
+    OVASSERT(isOpen(), "State is closed, cannot dequeueBuffer");
+    // can also set error to NOTSUPPORTED in the future
+    return false;
+}
+
+template <int PANEL>
+inline bool GenericPipe<PANEL>::waitForVsync() {
+    OVASSERT(isOpen(), "State is closed, cannot waitForVsync");
+
+    return mCtrlData.data.waitForVsync();
+}
+
+template <int PANEL>
+inline bool GenericPipe<PANEL>::setPosition(const utils::Dim& dim)
+{
+    OVASSERT(isOpen(), "State is closed, cannot setPosition");
+    return mCtrlData.ctrl.setPosition(dim);
+}
+
+template <int PANEL>
+inline bool GenericPipe<PANEL>::setParameter(
+        const utils::Params& param)
+{
+    OVASSERT(isOpen(), "State is closed, cannot setParameter");
+    // Currently setParameter would start rotator
+    if(!mCtrlData.ctrl.setParameter(param)) {
+        ALOGE("GenericPipe failed to setparam");
+        return false;
+    }
+    // if rot flags are ENABLED it means we would always
+    // like to have rot. Even with 0 rot. (solves tearing)
+    if(utils::ROT_FLAG_ENABLED == mArgs.rotFlags) {
+        mRot->setEnable();
+    }
+    return startRotator();
+}
+
+template <int PANEL>
+inline bool GenericPipe<PANEL>::setSource(
+        const utils::PipeArgs& args)
+{
+    // cache the recent args.
+    mArgs = args;
+    // setSource is the 1st thing that is being called on a pipe.
+    // If pipe is closed, we should start everything.
+    // we assume it is being opened with the correct FDs.
+    if(isClosed()) {
+        if(!this->start(args)) {
+            ALOGE("GenericPipe setSource failed to start");
+            return false;
+        }
+        return true;
+    }
+
+    return mCtrlData.ctrl.setSource(args);
+}
+
+template <int PANEL>
+inline utils::Dim GenericPipe<PANEL>::getAspectRatio(
+        const utils::Whf& whf) const
+{
+    return mCtrlData.ctrl.getAspectRatio(whf);
+}
+
+template <int PANEL>
+inline utils::Dim GenericPipe<PANEL>::getAspectRatio(
+        const utils::Dim& dim) const
+{
+    return mCtrlData.ctrl.getAspectRatio(dim);
+}
+
+template <int PANEL>
+inline utils::ScreenInfo GenericPipe<PANEL>::getScreenInfo() const
+{
+    return mCtrlData.ctrl.getScreenInfo();
+}
+
+template <int PANEL>
+inline utils::Dim GenericPipe<PANEL>::getCrop() const
+{
+    return mCtrlData.ctrl.getCrop();
+}
+
+template <int PANEL>
+inline utils::eOverlayPipeType GenericPipe<PANEL>::getOvPipeType() const {
+    return utils::OV_PIPE_TYPE_GENERIC;
+}
+
+template <int PANEL>
+void GenericPipe<PANEL>::dump() const
+{
+    ALOGE("== Dump Generic pipe start ==");
+    ALOGE("flags=0x%x", mFlags);
+    OVASSERT(mRot, "GenericPipe should have a valid Rot");
+    mCtrlData.ctrl.dump();
+    mCtrlData.data.dump();
+    mRot->dump();
+    ALOGE("== Dump Generic pipe end ==");
+}
+
+template <int PANEL>
+inline bool GenericPipe<PANEL>::isClosed() const  {
+    return utils::getBit(mFlags, CLOSED);
+}
+
+template <int PANEL>
+inline bool GenericPipe<PANEL>::isOpen() const  {
+    return !isClosed();
+}
+
+template <int PANEL>
+inline bool GenericPipe<PANEL>::setClosed() {
+    return utils::setBit(mFlags, CLOSED);
+}
+
+
+} //namespace overlay
+
+#endif // OVERLAY_GENERIC_PIPE_H
diff --git a/liboverlay/pipes/overlayHdmiPipe.h b/liboverlay/pipes/overlayHdmiPipe.h
new file mode 100644
index 0000000..48c3817
--- /dev/null
+++ b/liboverlay/pipes/overlayHdmiPipe.h
@@ -0,0 +1,128 @@
+/*
+* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef OVERLAY_HDMI_PIPE_H
+#define OVERLAY_HDMI_PIPE_H
+
+#include "overlayGenPipe.h"
+#include "overlayUtils.h"
+#include "overlayCtrlData.h"
+#include "overlayMdp.h"
+#include "overlayRotator.h"
+
+namespace overlay {
+
+/* A specific impl of GenericPipe
+* Whenever needed to have a pass through - we do it.
+* If there is a special need for a different behavior - do it here */
+class HdmiPipe : utils::NoCopy {
+public:
+    /* Please look at overlayGenPipe.h for info */
+    explicit HdmiPipe();
+    ~HdmiPipe();
+    bool open(RotatorBase* rot);
+    bool close();
+    bool commit();
+    void setId(int id);
+    void setMemoryId(int id);
+    bool queueBuffer(uint32_t offset);
+    bool dequeueBuffer(void*& buf);
+    bool waitForVsync();
+    bool setCrop(const utils::Dim& dim);
+    bool start(const utils::PipeArgs& args);
+    bool setPosition(const utils::Dim& dim);
+    bool setParameter(const utils::Params& param);
+    bool setSource(const utils::PipeArgs& args);
+    const utils::PipeArgs& getArgs() const;
+    utils::eOverlayPipeType getOvPipeType() const;
+    void dump() const;
+private:
+    overlay::GenericPipe<ovutils::EXTERNAL> mHdmi;
+};
+
+//------------------Inlines -----------------------------
+
+inline HdmiPipe::HdmiPipe() {}
+inline HdmiPipe::~HdmiPipe() { close(); }
+inline bool HdmiPipe::open(RotatorBase* rot) {
+    ALOGE_IF(DEBUG_OVERLAY, "HdmiPipe open");
+    return mHdmi.open(rot);
+}
+inline bool HdmiPipe::close() { return mHdmi.close(); }
+inline bool HdmiPipe::commit() { return mHdmi.commit(); }
+inline void HdmiPipe::setId(int id) { mHdmi.setId(id); }
+inline void HdmiPipe::setMemoryId(int id) { mHdmi.setMemoryId(id); }
+inline bool HdmiPipe::queueBuffer(uint32_t offset) {
+    return mHdmi.queueBuffer(offset); }
+inline bool HdmiPipe::dequeueBuffer(void*& buf) {
+    return mHdmi.dequeueBuffer(buf); }
+inline bool HdmiPipe::waitForVsync() {
+    return mHdmi.waitForVsync(); }
+inline bool HdmiPipe::setCrop(const utils::Dim& dim) {
+    return mHdmi.setCrop(dim); }
+inline bool HdmiPipe::start(const utils::PipeArgs& args) {
+    return mHdmi.start(args); }
+inline bool HdmiPipe::setPosition(const utils::Dim& dim)
+{
+    utils::Dim d;
+    // Need to change dim to aspect ratio
+    if (utils::FrameBufferInfo::getInstance()->supportTrueMirroring()) {
+        // Use dim info to calculate aspect ratio for true UI mirroring
+        d = mHdmi.getAspectRatio(dim);
+    } else {
+        // Use cached crop data to get aspect ratio
+        utils::Dim crop = mHdmi.getCrop();
+        utils::Whf whf(crop.w, crop.h, 0);
+        d = mHdmi.getAspectRatio(whf);
+    }
+    ALOGE_IF(DEBUG_OVERLAY, "Calculated aspect ratio for HDMI: x=%d, y=%d, w=%d, h=%d, o=%d",
+            d.x, d.y, d.w, d.h, d.o);
+    return mHdmi.setPosition(d);
+}
+inline bool HdmiPipe::setParameter(const utils::Params& param) {
+    return mHdmi.setParameter(param); }
+inline bool HdmiPipe::setSource(const utils::PipeArgs& args) {
+    utils::PipeArgs arg(args);
+    return mHdmi.setSource(arg);
+}
+inline const utils::PipeArgs& HdmiPipe::getArgs() const {
+    return mHdmi.getArgs();
+}
+inline utils::eOverlayPipeType HdmiPipe::getOvPipeType() const {
+    return utils::OV_PIPE_TYPE_HDMI;
+}
+inline void HdmiPipe::dump() const {
+    ALOGE("HDMI Pipe");
+    mHdmi.dump();
+}
+
+
+} // overlay
+
+#endif // OVERLAY_HDMI_PIPE_H
diff --git a/liboverlay/pipes/overlayUIMirrorPipe.h b/liboverlay/pipes/overlayUIMirrorPipe.h
new file mode 100644
index 0000000..47fbc37
--- /dev/null
+++ b/liboverlay/pipes/overlayUIMirrorPipe.h
@@ -0,0 +1,192 @@
+/*
+* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*    * Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above
+*      copyright notice, this list of conditions and the following
+*      disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of Code Aurora Forum, Inc. nor the names of its
+*      contributors may be used to endorse or promote products derived
+*      from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef OVERLAY_UI_PIPE_H
+#define OVERLAY_UI_PIPE_H
+
+#include "overlayGenPipe.h"
+#include "overlayUtils.h"
+#include "overlayCtrlData.h"
+#include "overlayMdp.h"
+#include "overlayRotator.h"
+
+namespace overlay {
+
+/* A specific impl of GenericPipe
+* Whenever needed to have a pass through - we do it.
+* If there is a special need for a different behavior - do it here */
+class UIMirrorPipe : utils::NoCopy {
+public:
+    /* Please look at overlayGenPipe.h for info */
+    explicit UIMirrorPipe();
+    ~UIMirrorPipe();
+    bool open(RotatorBase* rot);
+    bool close();
+    bool commit();
+    void setId(int id);
+    void setMemoryId(int id);
+    bool queueBuffer(uint32_t offset);
+    bool dequeueBuffer(void*& buf);
+    bool waitForVsync();
+    bool setCrop(const utils::Dim& dim);
+    bool start(const utils::PipeArgs& args);
+    bool setPosition(const utils::Dim& dim);
+    bool setParameter(const utils::Params& param);
+    bool setSource(const utils::PipeArgs& args);
+    const utils::PipeArgs& getArgs() const;
+    utils::eOverlayPipeType getOvPipeType() const;
+    void dump() const;
+private:
+    overlay::GenericPipe<ovutils::EXTERNAL> mUI;
+};
+
+//----------------------------Inlines -----------------------------
+
+inline UIMirrorPipe::UIMirrorPipe() {}
+inline UIMirrorPipe::~UIMirrorPipe() { close(); }
+inline bool UIMirrorPipe::open(RotatorBase* rot) {
+    ALOGE_IF(DEBUG_OVERLAY, "UIMirrorPipe open");
+    bool ret = mUI.open(rot);
+    //If source to rotator is framebuffer, which is the case we UI Mirror pipe,
+    //we need to inform driver during playback. Since FB does not use ION.
+    rot->setSrcFB(true);
+    return ret;
+}
+inline bool UIMirrorPipe::close() { return mUI.close(); }
+inline bool UIMirrorPipe::commit() { return mUI.commit(); }
+inline void UIMirrorPipe::setId(int id) { mUI.setId(id); }
+inline void UIMirrorPipe::setMemoryId(int id) { mUI.setMemoryId(id); }
+inline bool UIMirrorPipe::queueBuffer(uint32_t offset) {
+    return mUI.queueBuffer(offset); }
+inline bool UIMirrorPipe::dequeueBuffer(void*& buf) {
+    return mUI.dequeueBuffer(buf); }
+inline bool UIMirrorPipe::waitForVsync() {
+    return mUI.waitForVsync(); }
+inline bool UIMirrorPipe::setCrop(const utils::Dim& dim) {
+    return mUI.setCrop(dim); }
+inline bool UIMirrorPipe::start(const utils::PipeArgs& args) {
+    if(!mUI.start(args)) {
+        ALOGE("%s failed to start", __FUNCTION__);
+        return false;
+    }
+    return true;
+}
+inline bool UIMirrorPipe::setPosition(const utils::Dim& dim) {
+
+    ovutils::Dim pdim;
+    switch (dim.o) {
+        case 0:
+        case HAL_TRANSFORM_ROT_180:
+            {
+                ovutils::Whf whf(dim.x, dim.y, 0);
+                pdim = mUI.getAspectRatio(whf);
+                break;
+            }
+        case HAL_TRANSFORM_ROT_90:
+        case HAL_TRANSFORM_ROT_270:
+            {
+                // Calculate the Aspectratio for the UI in the landscape mode
+                // Width and height will be swapped as there is rotation
+                ovutils::Whf whf(dim.y, dim.x, 0);
+                pdim = mUI.getAspectRatio(whf);
+                break;
+            }
+        default:
+            ALOGE("%s: Unknown orientation %d", __FUNCTION__, dim.o);
+            return false;
+    }
+
+    ovutils::even_out(pdim.x);
+    ovutils::even_out(pdim.y);
+    ovutils::even_out(pdim.w);
+    ovutils::even_out(pdim.h);
+    return mUI.setPosition(pdim);
+}
+inline bool UIMirrorPipe::setParameter(const utils::Params& param) {
+
+    OVASSERT(utils::OVERLAY_TRANSFORM_UI == param.param,
+            "%p Expecting OVERLAY_TRANSFORM_UI", __FUNCTION__);
+
+    int orientation = param.value;
+
+    // Figure out orientation to transform to
+    switch (param.value) {
+        case 0:
+            orientation = 0;
+            break;
+        case HAL_TRANSFORM_ROT_180:
+            orientation = HAL_TRANSFORM_ROT_180;
+            break;
+        case HAL_TRANSFORM_ROT_90:
+            orientation = HAL_TRANSFORM_ROT_270;
+            break;
+        case HAL_TRANSFORM_ROT_270:
+            orientation = HAL_TRANSFORM_ROT_90;
+            break;
+        default:
+            ALOGE("%s: Unknown orientation %d", __FUNCTION__, param.value);
+            return false;
+    }
+
+    ovutils::eTransform transform =
+            static_cast<ovutils::eTransform>(orientation);
+    const ovutils::Params prms (ovutils::OVERLAY_TRANSFORM, transform);
+    return mUI.setParameter(prms);
+}
+
+inline bool UIMirrorPipe::setSource(const utils::PipeArgs& args) {
+    utils::PipeArgs arg(args);
+
+    // Rotator flag enabled because buffer comes from fb
+    arg.rotFlags = utils::ROT_FLAG_ENABLED;
+
+    // For true UI mirroring, want the UI to go through available RGB pipe
+    // so do not set the PIPE SHARE flag which allocates VG pipe
+    if (utils::FrameBufferInfo::getInstance()->supportTrueMirroring()) {
+        arg.mdpFlags = static_cast<utils::eMdpFlags>(
+                arg.mdpFlags & ~utils::OV_MDP_PIPE_SHARE);
+    }
+
+    return mUI.setSource(arg);
+}
+inline const utils::PipeArgs& UIMirrorPipe::getArgs() const {
+    return mUI.getArgs();
+}
+inline utils::eOverlayPipeType UIMirrorPipe::getOvPipeType() const {
+    return utils::OV_PIPE_TYPE_UI_MIRROR;
+}
+inline void UIMirrorPipe::dump() const {
+    ALOGE("UI Mirror Pipe");
+    mUI.dump();
+}
+
+
+} // overlay
+
+#endif // OVERLAY_UI_PIPE_H
diff --git a/libqcomui/Android.mk b/libqcomui/Android.mk
index deb868c..d79929e 100644
--- a/libqcomui/Android.mk
+++ b/libqcomui/Android.mk
@@ -1,19 +1,19 @@
 LOCAL_PATH := $(call my-dir)
+
+#Headers to export
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES := \
-        qcom_ui.cpp
+LOCAL_SRC_FILES := qcomutils/profiler.cpp \
+                   qcomutils/IdleInvalidator.cpp
 
 LOCAL_SHARED_LIBRARIES := \
         libutils \
         libcutils \
         libui \
-        libEGL
+        libEGL \
 
-LOCAL_C_INCLUDES := $(TOP)/hardware/qcom/display/libgralloc \
-                    $(TOP)/frameworks/native/services/surfaceflinger \
-                    $(TOP)/external/skia/include/core \
-                    $(TOP)/external/skia/include/images
+LOCAL_C_INCLUDES := hardware/qcom/display/libgralloc \
+                    frameworks/base/services/surfaceflinger \
 
 LOCAL_CFLAGS := -DLOG_TAG=\"libQcomUI\"
 
@@ -23,6 +23,10 @@
     LOCAL_SHARED_LIBRARIES += libmemalloc
 endif
 
+ifeq ($(TARGET_USES_MDP3), true)
+    LOCAL_CFLAGS += -DUSE_MDP3
+endif
+
 LOCAL_CFLAGS += -DDEBUG_CALC_FPS
 
 LOCAL_MODULE := libQcomUI
diff --git a/libqcomui/qcom_ui.cpp b/libqcomui/qcom_ui.cpp
index 9fdd562..d060439 100644
--- a/libqcomui/qcom_ui.cpp
+++ b/libqcomui/qcom_ui.cpp
@@ -30,86 +30,78 @@
 #include <cutils/log.h>
 #include <cutils/memory.h>
 #include <qcom_ui.h>
+#include <utils/comptype.h>
 #include <gralloc_priv.h>
 #include <alloc_controller.h>
 #include <memalloc.h>
 #include <errno.h>
 #include <EGL/eglext.h>
 #include <sys/stat.h>
-#if 0
 #include <SkBitmap.h>
 #include <SkImageEncoder.h>
-#endif
 #include <Transform.h>
 
-#include <EGL/egl.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
 using gralloc::IMemAlloc;
 using gralloc::IonController;
 using gralloc::alloc_data;
 using android::sp;
-
-static int sCompositionType = -1;
-
 namespace {
 
-    static android::sp<gralloc::IAllocController> sAlloc = 0;
+static android::sp<gralloc::IAllocController> sAlloc = 0;
 
-    int reallocate_memory(native_handle_t *buffer_handle, int mReqSize, int usage)
-    {
-        int ret = 0;
+int reallocate_memory(native_handle_t *buffer_handle, int mReqSize, int usage)
+{
+    int ret = 0;
 
 #ifndef NON_QCOM_TARGET
-        if (sAlloc == 0) {
-            sAlloc = gralloc::IAllocController::getInstance(true);
-        }
-        if (sAlloc == 0) {
-            ALOGE("sAlloc is still NULL");
-            return -EINVAL;
-        }
-
-        // Dealloc the old memory
-        private_handle_t *hnd = (private_handle_t *)buffer_handle;
-        sp<IMemAlloc> memalloc = sAlloc->getAllocator(hnd->flags);
-        ret = memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);
-
-        if (ret) {
-            ALOGE("%s: free_buffer failed", __FUNCTION__);
-            return -1;
-        }
-
-        // Realloc new memory
-        alloc_data data;
-        data.base = 0;
-        data.fd = -1;
-        data.offset = 0;
-        data.size = mReqSize;
-        data.align = getpagesize();
-        data.uncached = true;
-        int allocFlags = usage;
-
-        switch (hnd->format) {
-            case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
-            case (HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED^HAL_PIXEL_FORMAT_INTERLACE): {
-                data.align = 8192;
-            } break;
-            default: break;
-        }
-        ret = sAlloc->allocate(data, allocFlags, 0);
-        if (ret == 0) {
-            hnd->fd = data.fd;
-            hnd->base = (int)data.base;
-            hnd->offset = data.offset;
-            hnd->size = data.size;
-        } else {
-            ALOGE("%s: allocate failed", __FUNCTION__);
-            return -EINVAL;
-        }
-#endif
-        return ret;
+    if (sAlloc == 0) {
+        sAlloc = gralloc::IAllocController::getInstance(true);
     }
+    if (sAlloc == 0) {
+        LOGE("sAlloc is still NULL");
+        return -EINVAL;
+    }
+
+    // Dealloc the old memory
+    private_handle_t *hnd = (private_handle_t *)buffer_handle;
+    sp<IMemAlloc> memalloc = sAlloc->getAllocator(hnd->flags);
+    ret = memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);
+
+    if (ret) {
+        LOGE("%s: free_buffer failed", __FUNCTION__);
+        return -1;
+    }
+
+    // Realloc new memory
+    alloc_data data;
+    data.base = 0;
+    data.fd = -1;
+    data.offset = 0;
+    data.size = mReqSize;
+    data.align = getpagesize();
+    data.uncached = true;
+    int allocFlags = usage;
+
+    switch (hnd->format) {
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
+        case (HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED^HAL_PIXEL_FORMAT_INTERLACE): {
+            data.align = 8192;
+        } break;
+        default: break;
+    }
+    ret = sAlloc->allocate(data, allocFlags, 0);
+    if (ret == 0) {
+        hnd->fd = data.fd;
+        hnd->base = (int)data.base;
+        hnd->offset = data.offset;
+        hnd->size = data.size;
+    } else {
+        LOGE("%s: allocate failed", __FUNCTION__);
+        return -EINVAL;
+    }
+#endif
+    return ret;
+}
 }; // ANONYNMOUS NAMESPACE
 
 /*
@@ -128,8 +120,11 @@
         case  NATIVE_WINDOW_UPDATE_BUFFERS_GEOMETRY:
             num_args = 3;
             break;
-        default: ALOGE("%s: invalid operation(0x%x)", __FUNCTION__, operation);
+        case NATIVE_WINDOW_SET_PIXEL_ASPECT_RATIO:
+            num_args = 2;
             break;
+        default: LOGE("%s: invalid operation(0x%x)", __FUNCTION__, operation);
+                 break;
     };
     return num_args;
 }
@@ -146,43 +141,20 @@
         // We check the YV12 formats, since some Qcom specific formats
         // could have the bits set.
         return true;
+    } else if ((format == HAL_PIXEL_FORMAT_RGB_888) ||
+               (format == HAL_PIXEL_FORMAT_YCrCb_422_SP) ||
+               (format == HAL_PIXEL_FORMAT_YCbCr_422_SP)){
+        return false;
     } else if (format & INTERLACE_MASK) {
         // Interlaced content
         return false;
     } else if (format & S3D_FORMAT_MASK) {
         // S3D Formats are not supported by the GPU
-       return false;
+        return false;
     }
     return true;
 }
 
-/* decide the texture target dynamically, based on the pixel format*/
-
-int decideTextureTarget(int pixel_format)
-{
-
-  // Default the return value to GL_TEXTURE_EXTERAL_OES
-  int retVal = GL_TEXTURE_EXTERNAL_OES;
-
-  // Change texture target to TEXTURE_2D for RGB formats
-  switch (pixel_format) {
-
-     case HAL_PIXEL_FORMAT_RGBA_8888:
-     case HAL_PIXEL_FORMAT_RGBX_8888:
-     case HAL_PIXEL_FORMAT_RGB_888:
-     case HAL_PIXEL_FORMAT_RGB_565:
-     case HAL_PIXEL_FORMAT_BGRA_8888:
-     case HAL_PIXEL_FORMAT_RGBA_5551:
-     case HAL_PIXEL_FORMAT_RGBA_4444:
-          retVal = GL_TEXTURE_2D;
-          break;
-     default:
-          retVal = GL_TEXTURE_EXTERNAL_OES;
-          break;
-  }
-  return retVal;
-}
-
 /*
  * Function to check if the allocated buffer is of the correct size.
  * Reallocate the buffer with the correct size, if the size doesn't
@@ -203,7 +175,7 @@
 
     // Validate the handle
     if (private_handle_t::validate(buffer_handle)) {
-        ALOGE("%s: handle is invalid", __FUNCTION__);
+        LOGE("%s: handle is invalid", __FUNCTION__);
         return -EINVAL;
     }
 
@@ -255,7 +227,7 @@
 int updateBufferGeometry(sp<GraphicBuffer> buffer, const qBufGeometry updatedGeometry)
 {
     if (buffer == 0) {
-        ALOGE("%s: graphic buffer is NULL", __FUNCTION__);
+        LOGE("%s: graphic buffer is NULL", __FUNCTION__);
         return -EINVAL;
     }
 
@@ -273,7 +245,7 @@
 
     // Validate the handle
     if (private_handle_t::validate(buffer->handle)) {
-        ALOGE("%s: handle is invalid", __FUNCTION__);
+        LOGE("%s: handle is invalid", __FUNCTION__);
         return -EINVAL;
     }
     buffer->width  = updatedGeometry.width;
@@ -285,7 +257,7 @@
         hnd->height = updatedGeometry.height;
         hnd->format = updatedGeometry.format;
     } else {
-        ALOGE("%s: hnd is NULL", __FUNCTION__);
+        LOGE("%s: hnd is NULL", __FUNCTION__);
         return -EINVAL;
     }
 
@@ -293,14 +265,14 @@
 }
 
 /* Update the S3D format of this buffer.
-*
-* @param: buffer whosei S3D format needs to be updated.
-* @param: Updated buffer S3D format
-*/
+ *
+ * @param: buffer whosei S3D format needs to be updated.
+ * @param: Updated buffer S3D format
+ */
 int updateBufferS3DFormat(sp<GraphicBuffer> buffer, const int s3dFormat)
 {
     if (buffer == 0) {
-        ALOGE("%s: graphic buffer is NULL", __FUNCTION__);
+        LOGE("%s: graphic buffer is NULL", __FUNCTION__);
         return -EINVAL;
     }
 
@@ -331,7 +303,7 @@
             else
                 currentFlags &= ~LAYER_ASYNCHRONOUS;
         } break;
-        default: ALOGE("%s: invalid attribute(0x%x)", __FUNCTION__, attribute);
+        default: LOGE("%s: invalid attribute(0x%x)", __FUNCTION__, attribute);
                  break;
     }
     return ret;
@@ -375,43 +347,12 @@
         case HWC_USE_COPYBIT:
             return true;
         default:
-            ALOGE("%s: invalid composition type(%d)", __FUNCTION__, compositionType);
+            LOGE("%s: invalid composition type(%d)", __FUNCTION__, compositionType);
             return false;
     };
 }
 
 /*
- * Get the current composition Type
- *
- * @return the compositon Type
- */
-int getCompositionType() {
-    char property[PROPERTY_VALUE_MAX];
-    int compositionType = 0;
-    if (property_get("debug.sf.hw", property, NULL) > 0) {
-        if(atoi(property) == 0) {
-            compositionType = COMPOSITION_TYPE_CPU;
-        } else { //debug.sf.hw = 1
-            property_get("debug.composition.type", property, NULL);
-            if (property == NULL) {
-                compositionType = COMPOSITION_TYPE_GPU;
-            } else if ((strncmp(property, "mdp", 3)) == 0) {
-                compositionType = COMPOSITION_TYPE_MDP;
-            } else if ((strncmp(property, "c2d", 3)) == 0) {
-                compositionType = COMPOSITION_TYPE_C2D;
-            } else if ((strncmp(property, "dyn", 3)) == 0) {
-                compositionType = COMPOSITION_TYPE_DYN;
-            } else {
-                compositionType = COMPOSITION_TYPE_GPU;
-            }
-        }
-    } else { //debug.sf.hw is not set. Use cpu composition
-        compositionType = COMPOSITION_TYPE_CPU;
-    }
-    return compositionType;
-}
-
-/*
  * Clear Region implementation for C2D/MDP versions.
  *
  * @param: region to be cleared
@@ -422,31 +363,27 @@
  */
 int qcomuiClearRegion(Region region, EGLDisplay dpy, EGLSurface sur)
 {
-#if 0 /* FIXME DIE */
     int ret = 0;
+    int compositionType = QCCompositionType::getInstance().getCompositionType();
 
-    if (-1 == sCompositionType) {
-        sCompositionType = getCompositionType();
-    }
-
-    if ((COMPOSITION_TYPE_MDP != sCompositionType) &&
-        (COMPOSITION_TYPE_C2D != sCompositionType) &&
-        (COMPOSITION_TYPE_CPU != sCompositionType)) {
-        // For non CPU/C2D/MDP composition, return an error, so that SF can use
+    if (compositionType & COMPOSITION_TYPE_GPU ||
+        (compositionType == COMPOSITION_TYPE_DYN|COMPOSITION_TYPE_C2D))
+    {
+        // For GPU or DYN comp. with C2D, return an error, so that SF can use
         // the GPU to draw the wormhole.
         return -1;
     }
 
     android_native_buffer_t *renderBuffer = (android_native_buffer_t *)
-                                        eglGetRenderBufferANDROID(dpy, sur);
+        eglGetRenderBufferANDROID(dpy, sur);
     if (!renderBuffer) {
-        ALOGE("%s: eglGetRenderBufferANDROID returned NULL buffer",
-            __FUNCTION__);
-            return -1;
+        LOGE("%s: eglGetRenderBufferANDROID returned NULL buffer",
+             __FUNCTION__);
+        return -1;
     }
     private_handle_t *fbHandle = (private_handle_t *)renderBuffer->handle;
     if(!fbHandle) {
-        ALOGE("%s: Framebuffer handle is NULL", __FUNCTION__);
+        LOGE("%s: Framebuffer handle is NULL", __FUNCTION__);
         return -1;
     }
 
@@ -461,7 +398,7 @@
     while (it != end) {
         const Rect& r = *it++;
         uint8_t* dst = (uint8_t*) fbHandle->base +
-                       (r.left + r.top*renderBuffer->stride)*bytesPerPixel;
+            (r.left + r.top*renderBuffer->stride)*bytesPerPixel;
         int w = r.width()*bytesPerPixel;
         int h = r.height();
         do {
@@ -472,42 +409,45 @@
             dst += stride;
         } while(--h);
     }
-#endif
     return 0;
 }
 
 /*
  * Handles the externalDisplay event
  * HDMI has highest priority compared to WifiDisplay
- * Based on the current and the new display event, decides the
+ * Based on the current and the new display type, decides the
  * external display to be enabled
  *
- * @param: newEvent - new external event
- * @param: currEvent - currently enabled external event
- * @return: external display to be enabled
+ * @param: disp - external display type(wfd/hdmi)
+ * @param: value - external event(0/1)
+ * @param: currdispType - Current enabled external display Type
+ * @return: external display type to be enabled
  *
  */
-external_display handleEventHDMI(external_display newState, external_display
-                                                                   currState)
+external_display_type handleEventHDMI(external_display_type disp, int value,
+                                      external_display_type currDispType)
 {
-    external_display retState = currState;
-    switch(newState) {
-        case EXT_DISPLAY_HDMI:
-            retState = EXT_DISPLAY_HDMI;
+    external_display_type retDispType = currDispType;
+    switch(disp) {
+        case EXT_TYPE_HDMI:
+            if(value)
+                retDispType = EXT_TYPE_HDMI;
+            else
+                retDispType = EXT_TYPE_NONE;
             break;
-        case EXT_DISPLAY_WIFI:
-            if(currState != EXT_DISPLAY_HDMI) {
-                retState = EXT_DISPLAY_WIFI;
+        case EXT_TYPE_WIFI:
+            if(currDispType != EXT_TYPE_HDMI) {
+                if(value)
+                    retDispType = EXT_TYPE_WIFI;
+                else
+                    retDispType = EXT_TYPE_NONE;
             }
             break;
-        case EXT_DISPLAY_OFF:
-            retState = EXT_DISPLAY_OFF;
-            break;
         default:
-            ALOGE("handleEventHDMI: unknown Event");
+            LOGE("%s: Unknown External Display Type!!");
             break;
     }
-    return retState;
+    return retDispType;
 }
 
 // Using global variables for layer dumping since "property_set("debug.sf.dump",
@@ -532,25 +472,25 @@
     localtime_r(&timenow, &sfdump_time);
 
     if ((property_get("debug.sf.dump.png", sfdump_propstr, NULL) > 0) &&
-            (strncmp(sfdump_propstr, sfdump_propstr_persist_png,
-                                                    PROPERTY_VALUE_MAX - 1))) {
+        (strncmp(sfdump_propstr, sfdump_propstr_persist_png,
+                 PROPERTY_VALUE_MAX - 1))) {
         // Strings exist & not equal implies it has changed, so trigger a dump
         strncpy(sfdump_propstr_persist_png, sfdump_propstr,
-                                                    PROPERTY_VALUE_MAX - 1);
+                PROPERTY_VALUE_MAX - 1);
         sfdump_countlimit_png = atoi(sfdump_propstr);
         sfdump_countlimit_png = (sfdump_countlimit_png < 0) ? 0:
-                        (sfdump_countlimit_png >= LONG_MAX) ? (LONG_MAX - 1):
-                                                        sfdump_countlimit_png;
+            (sfdump_countlimit_png >= LONG_MAX) ? (LONG_MAX - 1):
+            sfdump_countlimit_png;
         if (sfdump_countlimit_png) {
             sprintf(sfdumpdir_png,"/data/sfdump.png%04d%02d%02d.%02d%02d%02d",
-            sfdump_time.tm_year + 1900, sfdump_time.tm_mon + 1,
-            sfdump_time.tm_mday, sfdump_time.tm_hour,
-            sfdump_time.tm_min, sfdump_time.tm_sec);
+                    sfdump_time.tm_year + 1900, sfdump_time.tm_mon + 1,
+                    sfdump_time.tm_mday, sfdump_time.tm_hour,
+                    sfdump_time.tm_min, sfdump_time.tm_sec);
             if (0 == mkdir(sfdumpdir_png, 0777))
                 sfdump_counter_png = 0;
             else
-                ALOGE("sfdump: Error: %s. Failed to create sfdump directory"
-                ": %s", strerror(errno), sfdumpdir_png);
+                LOGE("sfdump: Error: %s. Failed to create sfdump directory"
+                     ": %s", strerror(errno), sfdumpdir_png);
         }
     }
 
@@ -558,25 +498,25 @@
         sfdump_counter_png++;
 
     if ((property_get("debug.sf.dump", sfdump_propstr, NULL) > 0) &&
-            (strncmp(sfdump_propstr, sfdump_propstr_persist_raw,
-                                                    PROPERTY_VALUE_MAX - 1))) {
+        (strncmp(sfdump_propstr, sfdump_propstr_persist_raw,
+                 PROPERTY_VALUE_MAX - 1))) {
         // Strings exist & not equal implies it has changed, so trigger a dump
         strncpy(sfdump_propstr_persist_raw, sfdump_propstr,
-                                                    PROPERTY_VALUE_MAX - 1);
+                PROPERTY_VALUE_MAX - 1);
         sfdump_countlimit_raw = atoi(sfdump_propstr);
         sfdump_countlimit_raw = (sfdump_countlimit_raw < 0) ? 0:
-                        (sfdump_countlimit_raw >= LONG_MAX) ? (LONG_MAX - 1):
-                                                        sfdump_countlimit_raw;
+            (sfdump_countlimit_raw >= LONG_MAX) ? (LONG_MAX - 1):
+            sfdump_countlimit_raw;
         if (sfdump_countlimit_raw) {
             sprintf(sfdumpdir_raw,"/data/sfdump.raw%04d%02d%02d.%02d%02d%02d",
-            sfdump_time.tm_year + 1900, sfdump_time.tm_mon + 1,
-            sfdump_time.tm_mday, sfdump_time.tm_hour,
-            sfdump_time.tm_min, sfdump_time.tm_sec);
+                    sfdump_time.tm_year + 1900, sfdump_time.tm_mon + 1,
+                    sfdump_time.tm_mday, sfdump_time.tm_hour,
+                    sfdump_time.tm_min, sfdump_time.tm_sec);
             if (0 == mkdir(sfdumpdir_raw, 0777))
                 sfdump_counter_raw = 0;
             else
-                ALOGE("sfdump: Error: %s. Failed to create sfdump directory"
-                ": %s", strerror(errno), sfdumpdir_raw);
+                LOGE("sfdump: Error: %s. Failed to create sfdump directory"
+                     ": %s", strerror(errno), sfdumpdir_raw);
         }
     }
 
@@ -593,85 +533,85 @@
         return;
 
     switch(format) {
-    case HAL_PIXEL_FORMAT_RGBA_8888:
-        strcpy(pixelformatstr, "RGBA_8888");
-        break;
-    case HAL_PIXEL_FORMAT_RGBX_8888:
-        strcpy(pixelformatstr, "RGBX_8888");
-        break;
-    case HAL_PIXEL_FORMAT_RGB_888:
-        strcpy(pixelformatstr, "RGB_888");
-        break;
-    case HAL_PIXEL_FORMAT_RGB_565:
-        strcpy(pixelformatstr, "RGB_565");
-        break;
-    case HAL_PIXEL_FORMAT_BGRA_8888:
-        strcpy(pixelformatstr, "BGRA_8888");
-        break;
-    case HAL_PIXEL_FORMAT_RGBA_5551:
-        strcpy(pixelformatstr, "RGBA_5551");
-        break;
-    case HAL_PIXEL_FORMAT_RGBA_4444:
-        strcpy(pixelformatstr, "RGBA_4444");
-        break;
-    case HAL_PIXEL_FORMAT_YV12:
-        strcpy(pixelformatstr, "YV12");
-        break;
-    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
-        strcpy(pixelformatstr, "YCbCr_422_SP_NV16");
-        break;
-    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-        strcpy(pixelformatstr, "YCrCb_420_SP_NV21");
-        break;
-    case HAL_PIXEL_FORMAT_YCbCr_422_I:
-        strcpy(pixelformatstr, "YCbCr_422_I_YUY2");
-        break;
-    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
-        strcpy(pixelformatstr, "NV12_ENCODEABLE");
-        break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
-        strcpy(pixelformatstr, "YCbCr_420_SP_TILED_TILE_4x2");
-        break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
-        strcpy(pixelformatstr, "YCbCr_420_SP");
-        break;
-    case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
-        strcpy(pixelformatstr, "YCrCb_420_SP_ADRENO");
-        break;
-    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
-        strcpy(pixelformatstr, "YCrCb_422_SP");
-        break;
-    case HAL_PIXEL_FORMAT_R_8:
-        strcpy(pixelformatstr, "R_8");
-        break;
-    case HAL_PIXEL_FORMAT_RG_88:
-        strcpy(pixelformatstr, "RG_88");
-        break;
-    case HAL_PIXEL_FORMAT_INTERLACE:
-        strcpy(pixelformatstr, "INTERLACE");
-        break;
-    default:
-        sprintf(pixelformatstr, "Unknown0x%X", format);
-        break;
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+            strcpy(pixelformatstr, "RGBA_8888");
+            break;
+        case HAL_PIXEL_FORMAT_RGBX_8888:
+            strcpy(pixelformatstr, "RGBX_8888");
+            break;
+        case HAL_PIXEL_FORMAT_RGB_888:
+            strcpy(pixelformatstr, "RGB_888");
+            break;
+        case HAL_PIXEL_FORMAT_RGB_565:
+            strcpy(pixelformatstr, "RGB_565");
+            break;
+        case HAL_PIXEL_FORMAT_BGRA_8888:
+            strcpy(pixelformatstr, "BGRA_8888");
+            break;
+        case HAL_PIXEL_FORMAT_RGBA_5551:
+            strcpy(pixelformatstr, "RGBA_5551");
+            break;
+        case HAL_PIXEL_FORMAT_RGBA_4444:
+            strcpy(pixelformatstr, "RGBA_4444");
+            break;
+        case HAL_PIXEL_FORMAT_YV12:
+            strcpy(pixelformatstr, "YV12");
+            break;
+        case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+            strcpy(pixelformatstr, "YCbCr_422_SP_NV16");
+            break;
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+            strcpy(pixelformatstr, "YCrCb_420_SP_NV21");
+            break;
+        case HAL_PIXEL_FORMAT_YCbCr_422_I:
+            strcpy(pixelformatstr, "YCbCr_422_I_YUY2");
+            break;
+        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+            strcpy(pixelformatstr, "NV12_ENCODEABLE");
+            break;
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
+            strcpy(pixelformatstr, "YCbCr_420_SP_TILED_TILE_4x2");
+            break;
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+            strcpy(pixelformatstr, "YCbCr_420_SP");
+            break;
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
+            strcpy(pixelformatstr, "YCrCb_420_SP_ADRENO");
+            break;
+        case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+            strcpy(pixelformatstr, "YCrCb_422_SP");
+            break;
+        case HAL_PIXEL_FORMAT_R_8:
+            strcpy(pixelformatstr, "R_8");
+            break;
+        case HAL_PIXEL_FORMAT_RG_88:
+            strcpy(pixelformatstr, "RG_88");
+            break;
+        case HAL_PIXEL_FORMAT_INTERLACE:
+            strcpy(pixelformatstr, "INTERLACE");
+            break;
+        default:
+            sprintf(pixelformatstr, "Unknown0x%X", format);
+            break;
     }
 }
 
 void dumpLayer(int moduleCompositionType, int listFlags, size_t layerIndex,
-                                                        hwc_layer_t hwLayers[])
+               hwc_layer_t hwLayers[])
 {
     char dumplogstr_png[128] = "";
     char dumplogstr_raw[128] = "";
     if (sfdump_counter_png <= sfdump_countlimit_png) {
         sprintf(dumplogstr_png, "[png-dump-frame: %03d of %03d] ",
-                                    sfdump_counter_png, sfdump_countlimit_png);
+                sfdump_counter_png, sfdump_countlimit_png);
     }
     if (sfdump_counter_raw <= sfdump_countlimit_raw) {
         sprintf(dumplogstr_raw, "[raw-dump-frame: %03d of %03d]",
-                                    sfdump_counter_raw, sfdump_countlimit_raw);
+                sfdump_counter_raw, sfdump_countlimit_raw);
     }
     if (NULL == hwLayers) {
-        ALOGE("sfdump: Error.%s%sLayer[%d] No hwLayers to dump.",
-                                dumplogstr_raw, dumplogstr_png, layerIndex);
+        LOGE("sfdump: Error.%s%sLayer[%d] No hwLayers to dump.",
+             dumplogstr_raw, dumplogstr_png, layerIndex);
         return;
     }
     hwc_layer *layer = &hwLayers[layerIndex];
@@ -679,263 +619,245 @@
     hwc_rect_t displayFrame = layer->displayFrame;
     private_handle_t *hnd = (private_handle_t *)layer->handle;
     char pixelformatstr[32] = "None";
+    uint32_t transform = layer->transform & FINAL_TRANSFORM_MASK;
 
     if (hnd)
         getHalPixelFormatStr(hnd->format, pixelformatstr);
-#if 0
-    ALOGE("sfdump: %s%s[%s]-Composition, Layer[%d] SrcBuff[%dx%d] "
-        "SrcCrop[%dl, %dt, %dr, %db] "
-        "DispFrame[%dl, %dt, %dr, %db] Composition-type = %s, Format = %s, "
-        "Orientation = %s, Flags = %s%s%s%s%s%s%s%s%s%s",
-        dumplogstr_raw, dumplogstr_png,
-        (moduleCompositionType == COMPOSITION_TYPE_GPU)? "GPU":
-        (moduleCompositionType == COMPOSITION_TYPE_MDP)? "MDP":
-        (moduleCompositionType == COMPOSITION_TYPE_C2D)? "C2D":
-        (moduleCompositionType == COMPOSITION_TYPE_CPU)? "CPU":
-        (moduleCompositionType == COMPOSITION_TYPE_DYN)? "DYN": "???",
-        layerIndex,
-        (hnd)? hnd->width : -1, (hnd)? hnd->height : -1,
-        sourceCrop.left, sourceCrop.top,
-        sourceCrop.right, sourceCrop.bottom,
-        displayFrame.left, displayFrame.top,
-        displayFrame.right, displayFrame.bottom,
-        (layer->compositionType == HWC_FRAMEBUFFER)? "Framebuffer (OpenGL ES)":
-        (layer->compositionType == HWC_OVERLAY)? "Overlay":
-        (layer->compositionType == HWC_USE_COPYBIT)? "Copybit": "???",
-        pixelformatstr,
-        (layer->transform == Transform::ROT_0)? "ROT_0":
-        (layer->transform == Transform::FLIP_H)? "FLIP_H":
-        (layer->transform == Transform::FLIP_V)? "FLIP_V":
-        (layer->transform == Transform::ROT_90)? "ROT_90":
-        (layer->transform == Transform::ROT_180)? "ROT_180":
-        (layer->transform == Transform::ROT_270)? "ROT_270":
-        (layer->transform == Transform::ROT_INVALID)? "ROT_INVALID":"???",
-        (layer->flags == 0)? "[None]":"",
-        (layer->flags & HWC_SKIP_LAYER)? "[Skip layer]":"",
-        (layer->flags & HWC_LAYER_NOT_UPDATING)? "[Layer not updating]":"",
-        (layer->flags & HWC_USE_ORIGINAL_RESOLUTION)? "[Original Resolution]":"",
-        (layer->flags & HWC_DO_NOT_USE_OVERLAY)? "[Do not use Overlay]":"",
-        (layer->flags & HWC_COMP_BYPASS)? "[Bypass]":"",
-        (layer->flags & HWC_BYPASS_RESERVE_0)? "[Bypass Reserve 0]":"",
-        (layer->flags & HWC_BYPASS_RESERVE_1)? "[Bypass Reserve 1]":"",
-        (listFlags & HWC_GEOMETRY_CHANGED)? "[List: Geometry Changed]":"",
-        (listFlags & HWC_SKIP_COMPOSITION)? "[List: Skip Composition]":"");
-#endif
-        if (NULL == hnd) {
-            ALOGE("sfdump: %s%sLayer[%d] private-handle is invalid.",
-                                dumplogstr_raw, dumplogstr_png, layerIndex);
-            return;
-        }
 
-        if ((sfdump_counter_png <= sfdump_countlimit_png) && hnd->base) {
-#if 0
-            bool bResult = false;
-            char sfdumpfile_name[256];
-            SkBitmap *tempSkBmp = new SkBitmap();
-            SkBitmap::Config tempSkBmpConfig = SkBitmap::kNo_Config;
-            sprintf(sfdumpfile_name, "%s/sfdump%03d_layer%d.png", sfdumpdir_png,
-                    sfdump_counter_png, layerIndex);
+    LOGE("sfdump: %s%s[%s]-Composition, Layer[%d] SrcBuff[%dx%d] "
+         "SrcCrop[%dl, %dt, %dr, %db] "
+         "DispFrame[%dl, %dt, %dr, %db] Composition-type = %s, Format = %s, "
+         "Orientation = %s, Flags = %s%s%s%s%s%s%s%s%s%s",
+         dumplogstr_raw, dumplogstr_png,
+         (moduleCompositionType == COMPOSITION_TYPE_GPU)? "GPU":
+         (moduleCompositionType == COMPOSITION_TYPE_MDP)? "MDP":
+         (moduleCompositionType == COMPOSITION_TYPE_C2D)? "C2D":
+         (moduleCompositionType == COMPOSITION_TYPE_CPU)? "CPU":
+         (moduleCompositionType == COMPOSITION_TYPE_DYN)? "DYN": "???",
+         layerIndex,
+         (hnd)? hnd->width : -1, (hnd)? hnd->height : -1,
+         sourceCrop.left, sourceCrop.top,
+         sourceCrop.right, sourceCrop.bottom,
+         displayFrame.left, displayFrame.top,
+         displayFrame.right, displayFrame.bottom,
+         (layer->compositionType == HWC_FRAMEBUFFER)? "Framebuffer (OpenGL ES)":
+         (layer->compositionType == HWC_OVERLAY)? "Overlay":
+         (layer->compositionType == HWC_USE_COPYBIT)? "Copybit": "???",
+         pixelformatstr,
+         (transform == Transform::ROT_0)? "ROT_0":
+             (transform == Transform::FLIP_H)? "FLIP_H":
+             (transform == Transform::FLIP_V)? "FLIP_V":
+             (transform == Transform::ROT_90)? "ROT_90":
+             (transform == Transform::ROT_180)? "ROT_180":
+             (transform == Transform::ROT_270)? "ROT_270":
+             (transform == Transform::ROT_INVALID)? "ROT_INVALID":"???",
+         (layer->flags == 0)? "[None]":"",
+         (layer->flags & HWC_SKIP_LAYER)? "[Skip layer]":"",
+         (layer->flags & HWC_LAYER_NOT_UPDATING)? "[Layer not updating]":"",
+         (layer->flags & HWC_COMP_BYPASS)? "[Bypass]":"",
+         (layer->flags & HWC_BYPASS_RESERVE_0)? "[Bypass Reserve 0]":"",
+         (layer->flags & HWC_BYPASS_RESERVE_1)? "[Bypass Reserve 1]":"",
+         (listFlags & HWC_GEOMETRY_CHANGED)? "[List: Geometry Changed]":"",
+         (listFlags & HWC_SKIP_COMPOSITION)? "[List: Skip Composition]":"");
 
-            switch (hnd->format) {
-                case HAL_PIXEL_FORMAT_RGBA_8888:
-                case HAL_PIXEL_FORMAT_RGBX_8888:
-                case HAL_PIXEL_FORMAT_BGRA_8888:
-                    tempSkBmpConfig = SkBitmap::kARGB_8888_Config;
-                    break;
-                case HAL_PIXEL_FORMAT_RGB_565:
-                case HAL_PIXEL_FORMAT_RGBA_5551:
-                case HAL_PIXEL_FORMAT_RGBA_4444:
-                    tempSkBmpConfig = SkBitmap::kRGB_565_Config;
-                    break;
-                case HAL_PIXEL_FORMAT_RGB_888:
-                default:
-                    tempSkBmpConfig = SkBitmap::kNo_Config;
-                    break;
-            }
-            if (SkBitmap::kNo_Config != tempSkBmpConfig) {
-                tempSkBmp->setConfig(tempSkBmpConfig, hnd->width, hnd->height);
-                tempSkBmp->setPixels((void*)hnd->base);
-                bResult = SkImageEncoder::EncodeFile(sfdumpfile_name,
-                                *tempSkBmp, SkImageEncoder::kPNG_Type, 100);
-                ALOGE("sfdump: %sDumped Layer[%d] to %s: %s", dumplogstr_png,
-                    layerIndex, sfdumpfile_name, bResult ? "Success" : "Fail");
-            }
-            else {
-                ALOGE("sfdump: %sSkipping Layer[%d] dump: Unsupported layer "
-                    "format %s for png encoder.", dumplogstr_png, layerIndex,
-                                            pixelformatstr);
-            }
-            delete tempSkBmp; // Calls SkBitmap::freePixels() internally.
-#endif
-        }
-
-        if ((sfdump_counter_raw <= sfdump_countlimit_raw) && hnd->base) {
-            char sfdumpfile_name[256];
-            bool bResult = false;
-            sprintf(sfdumpfile_name, "%s/sfdump%03d_layer%d_%dx%d_%s.raw",
-                sfdumpdir_raw,
-                sfdump_counter_raw, layerIndex, hnd->width, hnd->height,
-                pixelformatstr);
-            FILE* fp = fopen(sfdumpfile_name, "w+");
-            if (fp != NULL) {
-                bResult = (bool) fwrite((void*)hnd->base, hnd->size, 1, fp);
-                fclose(fp);
-            }
-            ALOGE("sfdump: %s Dumped Layer[%d] to %s: %s", dumplogstr_raw,
-                layerIndex, sfdumpfile_name, bResult ? "Success" : "Fail");
-        }
-}
-
-#ifdef DEBUG_CALC_FPS
-ANDROID_SINGLETON_STATIC_INSTANCE(CalcFps) ;
-
-CalcFps::CalcFps() {
-    debug_fps_level = 0;
-    Init();
-}
-
-CalcFps::~CalcFps() {
-}
-
-void CalcFps::Init() {
-    char prop[PROPERTY_VALUE_MAX];
-    property_get("debug.gr.calcfps", prop, "0");
-    debug_fps_level = atoi(prop);
-    if (debug_fps_level > MAX_DEBUG_FPS_LEVEL) {
-        ALOGW("out of range value for debug.gr.calcfps, using 0");
-        debug_fps_level = 0;
-    }
-
-    ALOGE("DEBUG_CALC_FPS: %d", debug_fps_level);
-    populate_debug_fps_metadata();
-}
-
-void CalcFps::Fps() {
-    if (debug_fps_level > 0)
-        calc_fps(ns2us(systemTime()));
-}
-
-void CalcFps::populate_debug_fps_metadata(void)
-{
-    char prop[PROPERTY_VALUE_MAX];
-
-    /*defaults calculation of fps to based on number of frames*/
-    property_get("debug.gr.calcfps.type", prop, "0");
-    debug_fps_metadata.type = (debug_fps_metadata_t::DfmType) atoi(prop);
-
-    /*defaults to 1000ms*/
-    property_get("debug.gr.calcfps.timeperiod", prop, "1000");
-    debug_fps_metadata.time_period = atoi(prop);
-
-    property_get("debug.gr.calcfps.period", prop, "10");
-    debug_fps_metadata.period = atoi(prop);
-
-    if (debug_fps_metadata.period > MAX_FPS_CALC_PERIOD_IN_FRAMES) {
-        debug_fps_metadata.period = MAX_FPS_CALC_PERIOD_IN_FRAMES;
-    }
-
-    /* default ignorethresh_us: 500 milli seconds */
-    property_get("debug.gr.calcfps.ignorethresh_us", prop, "500000");
-    debug_fps_metadata.ignorethresh_us = atoi(prop);
-
-    debug_fps_metadata.framearrival_steps =
-                       (debug_fps_metadata.ignorethresh_us / 16666);
-
-    if (debug_fps_metadata.framearrival_steps > MAX_FRAMEARRIVAL_STEPS) {
-        debug_fps_metadata.framearrival_steps = MAX_FRAMEARRIVAL_STEPS;
-        debug_fps_metadata.ignorethresh_us =
-                        debug_fps_metadata.framearrival_steps * 16666;
-    }
-
-    /* 2ms margin of error for the gettimeofday */
-    debug_fps_metadata.margin_us = 2000;
-
-    for (unsigned int i = 0; i < MAX_FRAMEARRIVAL_STEPS; i++)
-        debug_fps_metadata.accum_framearrivals[i] = 0;
-
-    ALOGE("period: %d", debug_fps_metadata.period);
-    ALOGE("ignorethresh_us: %lld", debug_fps_metadata.ignorethresh_us);
-}
-
-void CalcFps::print_fps(float fps)
-{
-    if (debug_fps_metadata_t::DFM_FRAMES == debug_fps_metadata.type)
-        ALOGE("FPS for last %d frames: %3.2f", debug_fps_metadata.period, fps);
-    else
-        ALOGE("FPS for last (%f ms, %d frames): %3.2f",
-             debug_fps_metadata.time_elapsed,
-             debug_fps_metadata.curr_frame, fps);
-
-    debug_fps_metadata.curr_frame = 0;
-    debug_fps_metadata.time_elapsed = 0.0;
-
-    if (debug_fps_level > 1) {
-        ALOGE("Frame Arrival Distribution:");
-        for (unsigned int i = 0;
-             i < ((debug_fps_metadata.framearrival_steps / 6) + 1);
-             i++) {
-            ALOGE("%lld %lld %lld %lld %lld %lld",
-                 debug_fps_metadata.accum_framearrivals[i*6],
-                 debug_fps_metadata.accum_framearrivals[i*6+1],
-                 debug_fps_metadata.accum_framearrivals[i*6+2],
-                 debug_fps_metadata.accum_framearrivals[i*6+3],
-                 debug_fps_metadata.accum_framearrivals[i*6+4],
-                 debug_fps_metadata.accum_framearrivals[i*6+5]);
-        }
-
-        /* We are done with displaying, now clear the stats */
-        for (unsigned int i = 0;
-             i < debug_fps_metadata.framearrival_steps;
-             i++)
-            debug_fps_metadata.accum_framearrivals[i] = 0;
-    }
-    return;
-}
-
-void CalcFps::calc_fps(nsecs_t currtime_us)
-{
-    static nsecs_t oldtime_us = 0;
-
-    nsecs_t diff = currtime_us - oldtime_us;
-
-    oldtime_us = currtime_us;
-
-    if (debug_fps_metadata_t::DFM_FRAMES == debug_fps_metadata.type &&
-        diff > debug_fps_metadata.ignorethresh_us) {
+    if (NULL == hnd) {
+        LOGE("sfdump: %s%sLayer[%d] private-handle is invalid.",
+             dumplogstr_raw, dumplogstr_png, layerIndex);
         return;
     }
 
-    if (debug_fps_metadata.curr_frame < MAX_FPS_CALC_PERIOD_IN_FRAMES) {
-        debug_fps_metadata.framearrivals[debug_fps_metadata.curr_frame] = diff;
-    }
+    if ((sfdump_counter_png <= sfdump_countlimit_png) && hnd->base) {
+        bool bResult = false;
+        char sfdumpfile_name[256];
+        SkBitmap *tempSkBmp = new SkBitmap();
+        SkBitmap::Config tempSkBmpConfig = SkBitmap::kNo_Config;
+        sprintf(sfdumpfile_name, "%s/sfdump%03d_layer%d.png", sfdumpdir_png,
+                sfdump_counter_png, layerIndex);
 
-    debug_fps_metadata.curr_frame++;
-
-    if (debug_fps_level > 1) {
-        unsigned int currstep = (diff + debug_fps_metadata.margin_us) / 16666;
-
-        if (currstep < debug_fps_metadata.framearrival_steps) {
-            debug_fps_metadata.accum_framearrivals[currstep-1]++;
+        switch (hnd->format) {
+            case HAL_PIXEL_FORMAT_RGBA_8888:
+            case HAL_PIXEL_FORMAT_RGBX_8888:
+            case HAL_PIXEL_FORMAT_BGRA_8888:
+                tempSkBmpConfig = SkBitmap::kARGB_8888_Config;
+                break;
+            case HAL_PIXEL_FORMAT_RGB_565:
+            case HAL_PIXEL_FORMAT_RGBA_5551:
+            case HAL_PIXEL_FORMAT_RGBA_4444:
+                tempSkBmpConfig = SkBitmap::kRGB_565_Config;
+                break;
+            case HAL_PIXEL_FORMAT_RGB_888:
+            default:
+                tempSkBmpConfig = SkBitmap::kNo_Config;
+                break;
         }
+        if (SkBitmap::kNo_Config != tempSkBmpConfig) {
+            tempSkBmp->setConfig(tempSkBmpConfig, hnd->width, hnd->height);
+            tempSkBmp->setPixels((void*)hnd->base);
+            bResult = SkImageEncoder::EncodeFile(sfdumpfile_name,
+                                                 *tempSkBmp, SkImageEncoder::kPNG_Type, 100);
+            LOGE("sfdump: %sDumped Layer[%d] to %s: %s", dumplogstr_png,
+                 layerIndex, sfdumpfile_name, bResult ? "Success" : "Fail");
+        }
+        else {
+            LOGE("sfdump: %sSkipping Layer[%d] dump: Unsupported layer "
+                 "format %s for png encoder.", dumplogstr_png, layerIndex,
+                 pixelformatstr);
+        }
+        delete tempSkBmp; // Calls SkBitmap::freePixels() internally.
     }
 
-    if (debug_fps_metadata_t::DFM_FRAMES == debug_fps_metadata.type) {
-        if (debug_fps_metadata.curr_frame == debug_fps_metadata.period) {
-            /* time to calculate and display FPS */
-            nsecs_t sum = 0;
-            for (unsigned int i = 0; i < debug_fps_metadata.period; i++)
-                sum += debug_fps_metadata.framearrivals[i];
-            print_fps((debug_fps_metadata.period * float(1000000))/float(sum));
+    if ((sfdump_counter_raw <= sfdump_countlimit_raw) && hnd->base) {
+        char sfdumpfile_name[256];
+        bool bResult = false;
+        sprintf(sfdumpfile_name, "%s/sfdump%03d_layer%d_%dx%d_%s.raw",
+                sfdumpdir_raw,
+                sfdump_counter_raw, layerIndex, hnd->width, hnd->height,
+                pixelformatstr);
+        FILE* fp = fopen(sfdumpfile_name, "w+");
+        if (fp != NULL) {
+            bResult = (bool) fwrite((void*)hnd->base, hnd->size, 1, fp);
+            fclose(fp);
         }
+        LOGE("sfdump: %s Dumped Layer[%d] to %s: %s", dumplogstr_raw,
+             layerIndex, sfdumpfile_name, bResult ? "Success" : "Fail");
     }
-    else if (debug_fps_metadata_t::DFM_TIME == debug_fps_metadata.type) {
-        debug_fps_metadata.time_elapsed += ((float)diff/1000.0);
-        if (debug_fps_metadata.time_elapsed >= debug_fps_metadata.time_period) {
-            float fps = (1000.0 * debug_fps_metadata.curr_frame)/
-                        (float)debug_fps_metadata.time_elapsed;
-            print_fps(fps);
-        }
-    }
-    return;
 }
-#endif
+
+bool needsAspectRatio (int wRatio, int hRatio) {
+    return ((wRatio != DEFAULT_WIDTH_RATIO) || (hRatio != DEFAULT_HEIGHT_RATIO));
+}
+
+void applyPixelAspectRatio (int wRatio, int hRatio, int orientation, int maxWidth,
+                            int maxHeight, Rect& visibleRect, GLfloat mVertices[][2]) {
+
+    if ((wRatio == 0) || (hRatio == 0))
+        return;
+
+    float wDelta = 0;
+    float hDelta = 0;
+    float aspectRatio;
+    float displayRatio;
+    float new_width, new_height;
+    float old_width = abs(visibleRect.right - visibleRect.left);
+    float old_height = abs(visibleRect.bottom - visibleRect.top);
+
+    if (orientation == Transform::ROT_INVALID) {
+        // During animation, no defined orientation, rely on mTransformedBounds
+        if (old_width >= old_height)
+            orientation = Transform::ROT_0;
+        else
+            orientation = Transform::ROT_90;
+    }
+
+    switch (orientation) {
+
+        case Transform::ROT_0:
+        case Transform::ROT_180:
+
+            // Calculated Aspect Ratio = Original Aspect Ratio x Pixel Aspect Ratio
+            aspectRatio = (old_width * wRatio) / (old_height * hRatio);
+            displayRatio = (float)maxWidth / (float)maxHeight;
+
+            if (aspectRatio >= displayRatio) {
+                new_height = old_width / aspectRatio;
+                if (new_height > maxHeight) {
+                    new_height = maxHeight;
+                    new_width = new_height * aspectRatio;
+                    wDelta = (new_width - old_width) / 2;
+                }
+                hDelta = (new_height - old_height) / 2;
+            } else {
+                new_width = old_height * aspectRatio;
+                if (new_width > maxWidth) {
+                    new_width = maxWidth;
+                    new_height = new_width / aspectRatio;
+                    hDelta = (new_height - old_height) / 2;
+                }
+                wDelta = (new_width - old_width) / 2;
+            }
+
+            if (hDelta != 0) {
+                visibleRect.top -= hDelta;
+                visibleRect.bottom += hDelta;
+
+                // Set mVertices for GPU fallback (During rotation)
+                if (orientation == Transform::ROT_0) {
+                    mVertices[1][1] = mVertices[2][1] = visibleRect.top;
+                    mVertices[0][1] = mVertices[3][1] = visibleRect.bottom;
+                } else {
+                    mVertices[0][1] = mVertices[3][1] = visibleRect.top;
+                    mVertices[1][1] = mVertices[2][1] = visibleRect.bottom;
+                }
+            }
+
+            if (wDelta != 0) {
+                visibleRect.left -= wDelta;
+                visibleRect.right += wDelta;
+
+                // Set mVertices for GPU fallback (During rotation)
+                mVertices[0][0] = mVertices[1][0] = visibleRect.left;
+                mVertices[2][0] = mVertices[3][0] = visibleRect.right;
+            }
+            break;
+
+        case Transform::ROT_90:
+        case Transform::ROT_270:
+
+            // Calculated Aspect Ratio = Original Aspect Ratio x Pixel Aspect Ratio
+            aspectRatio = (old_height * wRatio) / (old_width * hRatio);
+            displayRatio = (float)maxHeight / (float)maxWidth;
+
+            if (aspectRatio >= displayRatio) {
+                new_height = old_width * aspectRatio;
+                if (new_height > maxHeight) {
+                    new_height = maxHeight;
+                    new_width = new_height / aspectRatio;
+                    wDelta = (new_width - old_width) / 2;
+                }
+                hDelta = (new_height - old_height) / 2;
+            } else {
+                new_width = old_height / aspectRatio;
+                if (new_width > maxWidth) {
+                    new_width = maxWidth;
+                    new_height = new_width * aspectRatio;
+                    hDelta = (new_height - old_height) / 2;
+                }
+                wDelta = (new_width - old_width) / 2;
+            }
+
+            if (hDelta != 0) {
+                visibleRect.top -= hDelta;
+                visibleRect.bottom += hDelta;
+
+                // Set mVertices for GPU fallback (During rotation)
+                if (orientation == Transform::ROT_90) {
+                    mVertices[2][1] = mVertices[3][1] = visibleRect.top;
+                    mVertices[0][1] = mVertices[1][1] = visibleRect.bottom;
+                } else {
+                    mVertices[0][1] = mVertices[1][1] = visibleRect.top;
+                    mVertices[2][1] = mVertices[3][1] = visibleRect.bottom;
+                }
+            }
+
+            if (wDelta != 0) {
+                visibleRect.left -= wDelta;
+                visibleRect.right += wDelta;
+
+                // Set mVertices for GPU fallback (During rotation)
+                if (orientation == Transform::ROT_90) {
+                    mVertices[1][0] = mVertices[2][0] = visibleRect.left;
+                    mVertices[0][0] = mVertices[3][0] = visibleRect.right;
+                } else {
+                    mVertices[0][0] = mVertices[3][0] = visibleRect.left;
+                    mVertices[1][0] = mVertices[2][0] = visibleRect.right;
+                }
+            }
+            break;
+
+        default: // Handled above.
+            break;
+
+    }
+}
+
+
diff --git a/libqcomui/qcom_ui.h b/libqcomui/qcom_ui.h
index 88462cc..89974bd 100644
--- a/libqcomui/qcom_ui.h
+++ b/libqcomui/qcom_ui.h
@@ -33,18 +33,19 @@
 #include <cutils/native_handle.h>
 #include <ui/GraphicBuffer.h>
 #include <hardware/hwcomposer.h>
-#include <hardware/hwcomposer_defs.h>
 #include <ui/Region.h>
 #include <EGL/egl.h>
+#include <GLES/gl.h>
 #include <utils/Singleton.h>
 #include <cutils/properties.h>
-#include "../libgralloc/gralloc_priv.h"
 
 using namespace android;
 using android::sp;
 using android::GraphicBuffer;
 
 #define HWC_BYPASS_INDEX_MASK 0x00000030
+#define DEFAULT_WIDTH_RATIO  1
+#define DEFAULT_HEIGHT_RATIO 1
 
 /*
  * Qcom specific Native Window perform operations
@@ -53,15 +54,7 @@
     NATIVE_WINDOW_SET_BUFFERS_SIZE        = 0x10000000,
     NATIVE_WINDOW_UPDATE_BUFFERS_GEOMETRY = 0x20000000,
     NATIVE_WINDOW_SET_S3D_FORMAT          = 0x40000000,
-};
-
-// Enum containing the supported composition types
-enum {
-    COMPOSITION_TYPE_GPU = 0,
-    COMPOSITION_TYPE_MDP = 0x1,
-    COMPOSITION_TYPE_C2D = 0x2,
-    COMPOSITION_TYPE_CPU = 0x4,
-    COMPOSITION_TYPE_DYN = 0x8
+    NATIVE_WINDOW_SET_PIXEL_ASPECT_RATIO  = 0x80000000,
 };
 
 /*
@@ -81,16 +74,21 @@
 };
 
 /*
+ * Layer Transformation - refers to Layer::setGeometry()
+ */
+#define SHIFT_SRC_TRANSFORM  4
+#define SRC_TRANSFORM_MASK   0x00F0
+#define FINAL_TRANSFORM_MASK 0x000F
+
+/*
  * Flags set by the layer and sent to HWC
  */
 enum {
     HWC_LAYER_NOT_UPDATING      = 0x00000002,
     HWC_LAYER_ASYNCHRONOUS      = 0x00000004,
-    HWC_USE_ORIGINAL_RESOLUTION = 0x10000000,
-    HWC_DO_NOT_USE_OVERLAY      = 0x20000000,
-    HWC_COMP_BYPASS             = 0x40000000,
-    HWC_USE_EXT_ONLY            = 0x80000000, //Layer displayed on external only
-    HWC_USE_EXT_BLOCK           = 0x01000000, //Layer displayed on external only
+    HWC_COMP_BYPASS             = 0x10000000,
+    HWC_USE_EXT_ONLY            = 0x20000000, //Layer displayed on external only
+    HWC_USE_EXT_BLOCK           = 0x40000000, //Layer displayed on external only
     HWC_BYPASS_RESERVE_0        = 0x00000010,
     HWC_BYPASS_RESERVE_1        = 0x00000020,
 };
@@ -101,10 +99,41 @@
     HWC_USE_COPYBIT                // This layer is to be handled by copybit
 };
 
-enum external_display {
-    EXT_DISPLAY_OFF,
-    EXT_DISPLAY_HDMI,
-    EXT_DISPLAY_WIFI
+enum external_display_type {
+    EXT_TYPE_NONE,
+    EXT_TYPE_HDMI,
+    EXT_TYPE_WIFI
+};
+
+/* Events to the Display HAL perform function
+   As of now used for external display related such as
+   connect, disconnect, orientation, video started etc.,
+   */
+enum {
+    EVENT_EXTERNAL_DISPLAY,     // External display on/off Event
+    EVENT_VIDEO_OVERLAY,        // Video Overlay start/stop Event
+    EVENT_ORIENTATION_CHANGE,   // Orientation Change Event
+    EVENT_OVERLAY_STATE_CHANGE, // Overlay State Change Event
+    EVENT_OPEN_SECURE_START,    // Start of secure session setup config by stagefright
+    EVENT_OPEN_SECURE_END,      // End of secure session setup config by stagefright
+    EVENT_CLOSE_SECURE_START,   // Start of secure session teardown config
+    EVENT_CLOSE_SECURE_END,     // End of secure session teardown config
+    EVENT_RESET_POSTBUFFER,     // Reset post framebuffer mutex
+    EVENT_WAIT_POSTBUFFER,      // Wait until post framebuffer returns
+};
+
+// Video information sent to framebuffer HAl
+// used for handling UI mirroring.
+enum {
+    VIDEO_OVERLAY_ENDED = 0,
+    VIDEO_2D_OVERLAY_STARTED,
+    VIDEO_3D_OVERLAY_STARTED
+};
+
+// Information about overlay state change
+enum {
+    OVERLAY_STATE_CHANGE_START = 0,
+    OVERLAY_STATE_CHANGE_END
 };
 
 /*
@@ -115,86 +144,18 @@
     int height;
     int format;
     void set(int w, int h, int f) {
-       width = w;
-       height = h;
-       format = f;
+        width = w;
+        height = h;
+        format = f;
     }
 };
 
-#ifndef DEBUG_CALC_FPS
-#define CALC_FPS() ((void)0)
-#define CALC_INIT() ((void)0)
-#else
-#define CALC_FPS() CalcFps::getInstance().Fps()
-#define CALC_INIT() CalcFps::getInstance().Init()
-
-class CalcFps : public Singleton<CalcFps> {
-public:
-    CalcFps();
-    ~CalcFps();
-
-    void Init();
-    void Fps();
-
-private:
-    static const unsigned int MAX_FPS_CALC_PERIOD_IN_FRAMES = 128;
-    static const unsigned int MAX_FRAMEARRIVAL_STEPS = 50;
-    static const unsigned int MAX_DEBUG_FPS_LEVEL = 2;
-
-    struct debug_fps_metadata_t {
-        /*fps calculation based on time or number of frames*/
-        enum DfmType {
-          DFM_FRAMES = 0,
-          DFM_TIME   = 1,
-        };
-
-        DfmType type;
-
-        /* indicates how much time do we wait till we calculate FPS */
-        unsigned long time_period;
-
-        /*indicates how much time elapsed since we report fps*/
-        float time_elapsed;
-
-        /* indicates how many frames do we wait till we calculate FPS */
-        unsigned int period;
-        /* current frame, will go upto period, and then reset */
-        unsigned int curr_frame;
-        /* frame will arrive at a multiple of 16666 us at the display.
-           This indicates how many steps to consider for our calculations.
-           For example, if framearrival_steps = 10, then the frame that arrived
-           after 166660 us or more will be ignored.
-        */
-        unsigned int framearrival_steps;
-        /* ignorethresh_us = framearrival_steps * 16666 */
-        nsecs_t      ignorethresh_us;
-        /* used to calculate the actual frame arrival step, the times might not be
-           accurate
-        */
-        unsigned int margin_us;
-
-        /* actual data storage */
-        nsecs_t      framearrivals[MAX_FPS_CALC_PERIOD_IN_FRAMES];
-        nsecs_t      accum_framearrivals[MAX_FRAMEARRIVAL_STEPS];
-    };
-
-private:
-    void populate_debug_fps_metadata(void);
-    void print_fps(float fps);
-    void calc_fps(nsecs_t currtime_us);
-
-private:
-    debug_fps_metadata_t debug_fps_metadata;
-    unsigned int debug_fps_level;
-};
-#endif
-
 #if 0
 class QCBaseLayer
 {
-//    int mS3DFormat;
+    //    int mS3DFormat;
     int32_t mComposeS3DFormat;
-public:
+    public:
     QCBaseLayer()
     {
         mComposeS3DFormat = 0;
@@ -203,10 +164,10 @@
         eS3D_SIDE_BY_SIDE   = 0x10000,
         eS3D_TOP_BOTTOM     = 0x20000
     };
-/*
-    virtual status_t setStereoscopic3DFormat(int format) { mS3DFormat = format; return 0; }
-    virtual int getStereoscopic3DFormat() const { return mS3DFormat; }
- */
+    /*
+       virtual status_t setStereoscopic3DFormat(int format) { mS3DFormat = format; return 0; }
+       virtual int getStereoscopic3DFormat() const { return mS3DFormat; }
+       */
     void setS3DComposeFormat (int32_t hints)
     {
         if (hints & HWC_HINT_DRAW_S3D_SIDE_BY_SIDE)
@@ -242,21 +203,6 @@
  */
 bool isGPUSupportedFormat(int format);
 
-/*
- * Adreno is not optimized for GL_TEXTURE_EXTERNAL_OES
- * texure target. DO NOT choose TEXTURE_EXTERNAL_OES
- * target for RGB formats.
- *
- * Based on the pixel format, decide the texture target.
- *
- * @param : pixel format to check
- *
- * @return : GL_TEXTURE_2D for RGB formats, and
- *           GL_TEXTURE_EXTERNAL_OES for YUV formats.
- *
-*/
-
-int decideTextureTarget (const int pixel_format);
 
 /*
  * Gets the number of arguments required for this operation.
@@ -277,8 +223,8 @@
  * @return True if a memory reallocation is required.
  */
 bool needNewBuffer(const qBufGeometry currentGeometry,
-                            const qBufGeometry requiredGeometry,
-                            const qBufGeometry updatedGeometry);
+                   const qBufGeometry requiredGeometry,
+                   const qBufGeometry updatedGeometry);
 
 /*
  * Update the geometry of this buffer without reallocation.
@@ -327,13 +273,6 @@
 bool isUpdatingFB(HWCCompositionType compositionType);
 
 /*
- * Get the current composition Type
- *
- * @return the compositon Type
- */
-int getCompositionType();
-
-/*
  * Clear region implementation for C2D/MDP versions.
  *
  * @param: region to be cleared
@@ -355,9 +294,8 @@
  * @return: external display to be enabled
  *
  */
-external_display handleEventHDMI(external_display newEvent, external_display
-                                                                   currEvent);
-
+external_display_type handleEventHDMI(external_display_type disp, int value,
+                                      external_display_type currDispType);
 /*
  * Checks if layers need to be dumped based on system property "debug.sf.dump"
  * for raw dumps and "debug.sf.dump.png" for png dumps.
@@ -389,6 +327,10 @@
  *
  */
 void dumpLayer(int moduleCompositionType, int listFlags, size_t layerIndex,
-                                                    hwc_layer_t hwLayers[]);
+               hwc_layer_t hwLayers[]);
+
+bool needsAspectRatio (int wRatio, int hRatio);
+void applyPixelAspectRatio (int wRatio, int hRatio, int orientation, int fbWidth,
+                            int fbHeight, Rect& visibleRect, GLfloat vertices[][2]);
 
 #endif // INCLUDE_LIBQCOM_UI
diff --git a/libqcomui/qcomutils/IdleInvalidator.cpp b/libqcomui/qcomutils/IdleInvalidator.cpp
new file mode 100755
index 0000000..0b98e11
--- /dev/null
+++ b/libqcomui/qcomutils/IdleInvalidator.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "IdleInvalidator.h"
+#include <unistd.h>
+
+#define II_DEBUG 1
+
+static const char *threadName = "Invalidator";
+InvalidatorHandler IdleInvalidator::mHandler = NULL;
+android::sp<IdleInvalidator> IdleInvalidator::sInstance(0);
+
+IdleInvalidator::IdleInvalidator(): Thread(false), mHwcContext(0),
+    mSleepAgain(false), mSleepTime(0) {
+        ALOGE_IF(II_DEBUG, "shs %s", __func__);
+    }
+
+int IdleInvalidator::init(InvalidatorHandler reg_handler, void* user_data,
+                          unsigned int idleSleepTime) {
+    ALOGE_IF(II_DEBUG, "shs %s", __func__);
+
+    /* store registered handler */
+    mHandler = reg_handler;
+    mHwcContext = user_data;
+    mSleepTime = idleSleepTime; //Time in millis
+    return 0;
+}
+
+bool IdleInvalidator::threadLoop() {
+    ALOGE_IF(II_DEBUG, "shs %s", __func__);
+    usleep(mSleepTime * 1000);
+    if(mSleepAgain) {
+        //We need to sleep again!
+        mSleepAgain = false;
+        return true;
+    }
+
+    mHandler((void*)mHwcContext);
+    return false;
+}
+
+int IdleInvalidator::readyToRun() {
+    ALOGE_IF(II_DEBUG, "shs %s", __func__);
+    return 0; /*NO_ERROR*/
+}
+
+void IdleInvalidator::onFirstRef() {
+    ALOGE_IF(II_DEBUG, "shs %s", __func__);
+}
+
+void IdleInvalidator::markForSleep() {
+    mSleepAgain = true;
+    //Triggers the threadLoop to run, if not already running.
+    run(threadName, android::PRIORITY_AUDIO);
+}
+
+IdleInvalidator *IdleInvalidator::getInstance() {
+    ALOGE_IF(II_DEBUG, "shs %s", __func__);
+    if(sInstance.get() == NULL)
+        sInstance = new IdleInvalidator();
+    return sInstance.get();
+}
diff --git a/libqcomui/qcomutils/IdleInvalidator.h b/libqcomui/qcomutils/IdleInvalidator.h
new file mode 100755
index 0000000..930cd35
--- /dev/null
+++ b/libqcomui/qcomutils/IdleInvalidator.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef INCLUDE_IDLEINVALIDATOR
+#define INCLUDE_IDLEINVALIDATOR
+
+#include <cutils/log.h>
+#include <utils/threads.h>
+
+typedef void (*InvalidatorHandler)(void*);
+
+class IdleInvalidator : public android::Thread {
+    void *mHwcContext;
+    bool mSleepAgain;
+    unsigned int mSleepTime;
+    static InvalidatorHandler mHandler;
+    static android::sp<IdleInvalidator> sInstance;
+
+    public:
+    IdleInvalidator();
+    /* init timer obj */
+    int init(InvalidatorHandler reg_handler, void* user_data, unsigned int
+             idleSleepTime);
+    void markForSleep();
+    /*Overrides*/
+    virtual bool        threadLoop();
+    virtual int         readyToRun();
+    virtual void        onFirstRef();
+    static IdleInvalidator *getInstance();
+};
+
+#endif // INCLUDE_IDLEINVALIDATOR
diff --git a/libqcomui/qcomutils/comptype.h b/libqcomui/qcomutils/comptype.h
new file mode 100644
index 0000000..603e143
--- /dev/null
+++ b/libqcomui/qcomutils/comptype.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef INCLUDE_LIBQCOM_COMPTYPES
+#define INCLUDE_LIBQCOM_COMPTYPES
+
+#include <stdint.h>
+#include <utils/Singleton.h>
+#include <cutils/properties.h>
+
+using namespace android;
+
+// Enum containing the supported composition types
+enum {
+    COMPOSITION_TYPE_GPU = 0,
+    COMPOSITION_TYPE_MDP = 0x1,
+    COMPOSITION_TYPE_C2D = 0x2,
+    COMPOSITION_TYPE_CPU = 0x4,
+    COMPOSITION_TYPE_DYN = 0x8
+};
+
+/* This class caches the composition type
+ */
+class QCCompositionType : public Singleton <QCCompositionType>
+{
+    public:
+        QCCompositionType();
+        ~QCCompositionType() { }
+        int getCompositionType() {return mCompositionType;}
+    private:
+        int mCompositionType;
+
+};
+
+ANDROID_SINGLETON_STATIC_INSTANCE(QCCompositionType);
+inline QCCompositionType::QCCompositionType()
+{
+    char property[PROPERTY_VALUE_MAX];
+    mCompositionType = 0;
+    if (property_get("debug.sf.hw", property, NULL) > 0) {
+        if(atoi(property) == 0) {
+            mCompositionType = COMPOSITION_TYPE_CPU;
+        } else { //debug.sf.hw = 1
+            property_get("debug.composition.type", property, NULL);
+            if (property == NULL) {
+                mCompositionType = COMPOSITION_TYPE_GPU;
+            } else if ((strncmp(property, "mdp", 3)) == 0) {
+                mCompositionType = COMPOSITION_TYPE_MDP;
+            } else if ((strncmp(property, "c2d", 3)) == 0) {
+                mCompositionType = COMPOSITION_TYPE_C2D;
+            } else if ((strncmp(property, "dyn", 3)) == 0) {
+#ifdef USE_MDP3
+                mCompositionType = COMPOSITION_TYPE_DYN | COMPOSITION_TYPE_MDP;
+#else
+                mCompositionType = COMPOSITION_TYPE_DYN | COMPOSITION_TYPE_C2D;
+#endif
+            } else {
+                mCompositionType = COMPOSITION_TYPE_GPU;
+            }
+        }
+    } else { //debug.sf.hw is not set. Use cpu composition
+        mCompositionType = COMPOSITION_TYPE_CPU;
+    }
+
+}
+#endif //INCLUDE_LIBQCOM_COMPTYPES
diff --git a/libqcomui/qcomutils/profiler.cpp b/libqcomui/qcomutils/profiler.cpp
new file mode 100755
index 0000000..73854bc
--- /dev/null
+++ b/libqcomui/qcomutils/profiler.cpp
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "profiler.h"
+
+#ifdef DEBUG_CALC_FPS
+
+#define LOG_TAG "CALCFPS"
+#define LOG_NDDEBUG 0
+
+ANDROID_SINGLETON_STATIC_INSTANCE(CalcFps) ;
+
+CalcFps::CalcFps() {
+    debug_fps_level = 0;
+    Init();
+}
+
+CalcFps::~CalcFps() {
+}
+
+void CalcFps::Init() {
+    char prop[PROPERTY_VALUE_MAX];
+    property_get("debug.gr.calcfps", prop, "0");
+    debug_fps_level = atoi(prop);
+    if (debug_fps_level > MAX_DEBUG_FPS_LEVEL) {
+        ALOGW("out of range value for debug.gr.calcfps, using 0");
+        debug_fps_level = 0;
+    }
+
+    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) {
+        debug_fps_metadata.period = MAX_FPS_CALC_PERIOD_IN_FRAMES;
+    }
+
+    /* default ignorethresh_us: 500 milli seconds */
+    property_get("debug.gr.calcfps.ignorethresh_us", prop, "500000");
+    debug_fps_metadata.ignorethresh_us = atoi(prop);
+
+    debug_fps_metadata.framearrival_steps =
+        (debug_fps_metadata.ignorethresh_us / 16666);
+
+    if (debug_fps_metadata.framearrival_steps > MAX_FRAMEARRIVAL_STEPS) {
+        debug_fps_metadata.framearrival_steps = MAX_FRAMEARRIVAL_STEPS;
+        debug_fps_metadata.ignorethresh_us =
+            debug_fps_metadata.framearrival_steps * 16666;
+    }
+
+    /* 2ms margin of error for the gettimeofday */
+    debug_fps_metadata.margin_us = 2000;
+
+    for (unsigned int i = 0; i < MAX_FRAMEARRIVAL_STEPS; i++)
+        debug_fps_metadata.accum_framearrivals[i] = 0;
+
+    ALOGD("period: %d", debug_fps_metadata.period);
+    ALOGD("ignorethresh_us: %lld", debug_fps_metadata.ignorethresh_us);
+}
+
+void CalcFps::print_fps(float fps)
+{
+    if (debug_fps_metadata_t::DFM_FRAMES == debug_fps_metadata.type)
+        ALOGD("FPS for last %d frames: %3.2f", debug_fps_metadata.period, fps);
+    else
+        ALOGD("FPS for last (%f ms, %d frames): %3.2f",
+              debug_fps_metadata.time_elapsed,
+              debug_fps_metadata.curr_frame, fps);
+
+    debug_fps_metadata.curr_frame = 0;
+    debug_fps_metadata.time_elapsed = 0.0;
+
+    if (debug_fps_level > 1) {
+        ALOGD("Frame Arrival Distribution:");
+        for (unsigned int i = 0;
+             i < ((debug_fps_metadata.framearrival_steps / 6) + 1);
+             i++) {
+            ALOGD("%lld %lld %lld %lld %lld %lld",
+                  debug_fps_metadata.accum_framearrivals[i*6],
+                  debug_fps_metadata.accum_framearrivals[i*6+1],
+                  debug_fps_metadata.accum_framearrivals[i*6+2],
+                  debug_fps_metadata.accum_framearrivals[i*6+3],
+                  debug_fps_metadata.accum_framearrivals[i*6+4],
+                  debug_fps_metadata.accum_framearrivals[i*6+5]);
+        }
+
+        /* We are done with displaying, now clear the stats */
+        for (unsigned int i = 0;
+             i < debug_fps_metadata.framearrival_steps;
+             i++)
+            debug_fps_metadata.accum_framearrivals[i] = 0;
+    }
+    return;
+}
+
+void CalcFps::calc_fps(nsecs_t currtime_us)
+{
+    static nsecs_t oldtime_us = 0;
+
+    nsecs_t diff = currtime_us - oldtime_us;
+
+    oldtime_us = currtime_us;
+
+    if (debug_fps_metadata_t::DFM_FRAMES == debug_fps_metadata.type &&
+        diff > debug_fps_metadata.ignorethresh_us) {
+        return;
+    }
+
+    if (debug_fps_metadata.curr_frame < MAX_FPS_CALC_PERIOD_IN_FRAMES) {
+        debug_fps_metadata.framearrivals[debug_fps_metadata.curr_frame] = diff;
+    }
+
+    debug_fps_metadata.curr_frame++;
+
+    if (debug_fps_level > 1) {
+        unsigned int currstep = (diff + debug_fps_metadata.margin_us) / 16666;
+
+        if (currstep < debug_fps_metadata.framearrival_steps) {
+            debug_fps_metadata.accum_framearrivals[currstep-1]++;
+        }
+    }
+
+    if (debug_fps_metadata_t::DFM_FRAMES == debug_fps_metadata.type) {
+        if (debug_fps_metadata.curr_frame == debug_fps_metadata.period) {
+            /* time to calculate and display FPS */
+            nsecs_t sum = 0;
+            for (unsigned int i = 0; i < debug_fps_metadata.period; i++)
+                sum += debug_fps_metadata.framearrivals[i];
+            print_fps((debug_fps_metadata.period * float(1000000))/float(sum));
+        }
+    }
+    else if (debug_fps_metadata_t::DFM_TIME == debug_fps_metadata.type) {
+        debug_fps_metadata.time_elapsed += ((float)diff/1000.0);
+        if (debug_fps_metadata.time_elapsed >= debug_fps_metadata.time_period) {
+            float fps = (1000.0 * debug_fps_metadata.curr_frame)/
+                (float)debug_fps_metadata.time_elapsed;
+            print_fps(fps);
+        }
+    }
+    return;
+}
+#endif
diff --git a/libqcomui/qcomutils/profiler.h b/libqcomui/qcomutils/profiler.h
new file mode 100755
index 0000000..394f490
--- /dev/null
+++ b/libqcomui/qcomutils/profiler.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef INCLUDE_PROFILER
+#define INCLUDE_PROFILER
+
+#include <stdio.h>
+#include <utils/Singleton.h>
+#include <cutils/properties.h>
+#include <cutils/log.h>
+using namespace android;
+
+#ifndef DEBUG_CALC_FPS
+#define CALC_FPS() ((void)0)
+#define CALC_INIT() ((void)0)
+#else
+#define CALC_FPS() CalcFps::getInstance().Fps()
+#define CALC_INIT() CalcFps::getInstance().Init()
+
+class CalcFps : public Singleton<CalcFps> {
+    public:
+    CalcFps();
+    ~CalcFps();
+
+    void Init();
+    void Fps();
+
+    private:
+    static const unsigned int MAX_FPS_CALC_PERIOD_IN_FRAMES = 128;
+    static const unsigned int MAX_FRAMEARRIVAL_STEPS = 50;
+    static const unsigned int MAX_DEBUG_FPS_LEVEL = 2;
+
+    struct debug_fps_metadata_t {
+        /*fps calculation based on time or number of frames*/
+        enum DfmType {
+            DFM_FRAMES = 0,
+            DFM_TIME   = 1,
+        };
+
+        DfmType type;
+
+        /* indicates how much time do we wait till we calculate FPS */
+        unsigned long time_period;
+
+        /*indicates how much time elapsed since we report fps*/
+        float time_elapsed;
+
+        /* indicates how many frames do we wait till we calculate FPS */
+        unsigned int period;
+        /* current frame, will go upto period, and then reset */
+        unsigned int curr_frame;
+        /* frame will arrive at a multiple of 16666 us at the display.
+           This indicates how many steps to consider for our calculations.
+           For example, if framearrival_steps = 10, then the frame that arrived
+           after 166660 us or more will be ignored.
+           */
+        unsigned int framearrival_steps;
+        /* ignorethresh_us = framearrival_steps * 16666 */
+        nsecs_t      ignorethresh_us;
+        /* used to calculate the actual frame arrival step, the times might not be
+           accurate
+           */
+        unsigned int margin_us;
+
+        /* actual data storage */
+        nsecs_t      framearrivals[MAX_FPS_CALC_PERIOD_IN_FRAMES];
+        nsecs_t      accum_framearrivals[MAX_FRAMEARRIVAL_STEPS];
+    };
+
+    private:
+    void populate_debug_fps_metadata(void);
+    void print_fps(float fps);
+    void calc_fps(nsecs_t currtime_us);
+
+    private:
+    debug_fps_metadata_t debug_fps_metadata;
+    unsigned int debug_fps_level;
+};
+#endif
+
+#endif // INCLUDE_PROFILER
diff --git a/libtilerenderer/tilerenderer.cpp b/libtilerenderer/tilerenderer.cpp
index 6e8f847..4ed6895 100644
--- a/libtilerenderer/tilerenderer.cpp
+++ b/libtilerenderer/tilerenderer.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 The Android Open Source Project
- * Copyright (c) 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -52,7 +52,7 @@
 
     if (!left && !right && !top && !bottom) {
         //can't do tile rendering
-        LOGE("can't tile render; drity region, width, height not available");
+        ALOGE("can't tile render; drity region, width, height not available");
         return;
     }
 
diff --git a/libtilerenderer/tilerenderer.h b/libtilerenderer/tilerenderer.h
index bec225d..7f8d608 100644
--- a/libtilerenderer/tilerenderer.h
+++ b/libtilerenderer/tilerenderer.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 The Android Open Source Project
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -25,14 +25,14 @@
 class OpenGLRenderer;
 
 class TileRenderer: public Singleton<TileRenderer> {
-public:
+    public:
     TileRenderer();
     ~TileRenderer();
 
     void startTileRendering(OpenGLRenderer* renderer, int left, int top, int right, int bottom);
     void endTileRendering(OpenGLRenderer*);
 
-private:
+    private:
     bool mIsTiled;
 };
 
