qcom/display: Update HALs

- Update the display HAL from Code Aurora Forum
- Add updated overlay library
- Enable HWC with basic video going through overlay
- Cleanup some files

Change-Id: I65c687c51be458cee71213c79e03eeda962d9086
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;
 };