diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ad71dd6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+CMakeLists.txt
+.idea/
+.editorconfig
+.clang-complete
diff --git a/Android.mk b/Android.mk
index 58146e1..b5961ad 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,8 +1,13 @@
-display-hals := libgralloc libcopybit liblight libmemtrack libqservice libqdutils
-display-hals += hdmi_cec
+display-hals := libcopybit liblight libmemtrack libqservice libqdutils
+ifneq ($(TARGET_USES_GRALLOC1), true)
+    display-hals += libgralloc
+else
+    display-hals += libgralloc1
+endif
 
+display-hals += hdmi_cec
 sdm-libs := sdm/libs
-display-hals += $(sdm-libs)/utils $(sdm-libs)/core $(sdm-libs)/hwc
+display-hals += $(sdm-libs)/utils $(sdm-libs)/core $(sdm-libs)/hwc $(sdm-libs)/hwc2
 
 ifeq ($(call is-vendor-board-platform,QCOM),true)
     include $(call all-named-subdir-makefiles,$(display-hals))
diff --git a/common.mk b/common.mk
index 5b202eb..228f742 100644
--- a/common.mk
+++ b/common.mk
@@ -1,6 +1,8 @@
 #Common headers
 display_top := $(call my-dir)
 
+use_hwc2 := false
+
 common_includes := $(display_top)/libqdutils
 common_includes += $(display_top)/libqservice
 common_includes += $(display_top)/libcopybit
@@ -14,7 +16,11 @@
 #Common C flags
 common_flags := -DDEBUG_CALC_FPS -Wno-missing-field-initializers
 common_flags += -Wconversion -Wall -Werror
-common_flags += -isystem $(display_top)/libgralloc
+ifneq ($(TARGET_USES_GRALLOC1), true)
+    common_flags += -isystem $(display_top)/libgralloc
+else
+    common_flags += -isystem $(display_top)/libgralloc1
+endif
 
 ifeq ($(TARGET_USES_POST_PROCESSING),true)
     common_flags     += -DUSES_POST_PROCESSING
@@ -41,9 +47,7 @@
 # Enable QCOM Display features
 #    common_flags += -DQTI_BSP
 # endif
-ifneq ($(call is-platform-sdk-version-at-least,18),true)
-    common_flags += -DANDROID_JELLYBEAN_MR1=1
-endif
+
 ifeq ($(TARGET_COMPILE_WITH_MSM_KERNEL),true)
 # This check is to pick the kernel headers from the right location.
 # If the macro above is defined, we make the assumption that we have the kernel
diff --git a/libcopybit/software_converter.h b/libcopybit/software_converter.h
index 6e53e16..cc6ae34 100644
--- a/libcopybit/software_converter.h
+++ b/libcopybit/software_converter.h
@@ -31,11 +31,12 @@
 
 #include <copybit.h>
 #include "gralloc_priv.h"
-#include "gr.h"
 
 #define COPYBIT_SUCCESS 0
 #define COPYBIT_FAILURE -1
 
+#define ALIGN(x, y) (((x) + y - 1) & (~(y - 1)))
+
 int convertYV12toYCrCb420SP(const copybit_image_t *src,private_handle_t *yv12_handle);
 
 /*
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 581d112..e9cdc73 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -88,11 +88,10 @@
  * read or written in software. Any combination with a _RARELY_ flag will be
  * treated as uncached. */
 static bool useUncached(const int& usage) {
-    if((usage & GRALLOC_USAGE_PRIVATE_UNCACHED) or
-            ((usage & GRALLOC_USAGE_SW_WRITE_MASK) ==
-            GRALLOC_USAGE_SW_WRITE_RARELY) or
-            ((usage & GRALLOC_USAGE_SW_READ_MASK) ==
-            GRALLOC_USAGE_SW_READ_RARELY))
+    if ((usage & GRALLOC_USAGE_PROTECTED) or
+        (usage & GRALLOC_USAGE_PRIVATE_UNCACHED) or
+        ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY) or
+        ((usage & GRALLOC_USAGE_SW_READ_MASK) ==  GRALLOC_USAGE_SW_READ_RARELY))
         return true;
 
     return false;
@@ -267,6 +266,7 @@
                 aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV21, height);
                 break;
             case HAL_PIXEL_FORMAT_BLOB:
+            case HAL_PIXEL_FORMAT_RAW_OPAQUE:
                 break;
             case HAL_PIXEL_FORMAT_NV21_ZSL:
                 aligned_w = ALIGN(width, 64);
@@ -453,23 +453,16 @@
     data.allocType = 0;
 
     if(usage & GRALLOC_USAGE_PROTECTED) {
-        if (usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
-            if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
-                ionHeapId = ION_HEAP(SD_HEAP_ID);
-                /*
-                 * There is currently no flag in ION for Secure Display
-                 * VM. Please add it to the define once available.
-                */
-                ionFlags |= ION_SD_FLAGS;
-            } else {
-                ionHeapId = ION_HEAP(CP_HEAP_ID);
-                ionFlags |= ION_CP_FLAGS;
-            }
+        if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
+            ionHeapId = ION_HEAP(SD_HEAP_ID);
+            /*
+             * There is currently no flag in ION for Secure Display
+             * VM. Please add it to the define once available.
+             */
+            ionFlags |= ION_SD_FLAGS;
         } else {
-            // for targets/OEMs which do not need HW level protection
-            // do not set ion secure flag & MM heap. Fallback to system heap.
-            ionHeapId |= ION_HEAP(ION_SYSTEM_HEAP_ID);
-            data.allocType |= private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER;
+            ionHeapId = ION_HEAP(CP_HEAP_ID);
+            ionFlags |= ION_CP_FLAGS;
         }
     } else if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
         //MM Heap is exclusively a secure heap.
@@ -632,6 +625,7 @@
             size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height);
             break;
         case HAL_PIXEL_FORMAT_BLOB:
+        case HAL_PIXEL_FORMAT_RAW_OPAQUE:
             if(height != 1) {
                 ALOGE("%s: Buffers with format HAL_PIXEL_FORMAT_BLOB \
                       must have height==1 ", __FUNCTION__);
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index 2284633..c1d7788 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -63,8 +63,7 @@
     else
         data.align = getpagesize();
 
-    if ((usage & GRALLOC_USAGE_PROTECTED) &&
-        (usage & GRALLOC_USAGE_PRIVATE_MM_HEAP)) {
+    if (usage & GRALLOC_USAGE_PROTECTED) {
             if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
                 /* The alignment here reflects qsee mmu V7L/V8L requirement */
                 data.align = SZ_2M;
diff --git a/libgralloc1/Android.mk b/libgralloc1/Android.mk
new file mode 100644
index 0000000..b66a027
--- /dev/null
+++ b/libgralloc1/Android.mk
@@ -0,0 +1,25 @@
+# Gralloc module
+LOCAL_PATH := $(call my-dir)
+include $(LOCAL_PATH)/../common.mk
+include $(CLEAR_VARS)
+
+LOCAL_MODULE                  := gralloc.$(TARGET_BOARD_PLATFORM)
+LOCAL_MODULE_RELATIVE_PATH    := hw
+LOCAL_MODULE_TAGS             := optional
+LOCAL_C_INCLUDES              := $(common_includes) \
+                                 external/libcxx/include/
+
+LOCAL_SHARED_LIBRARIES        := $(common_libs) libqdMetaData libsync libqdutils
+LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wall -std=c++11 -Werror
+LOCAL_CFLAGS                  += -isystem  $(kernel_includes)
+LOCAL_CLANG                   := true
+LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
+LOCAL_SRC_FILES               := gr_utils.cpp \
+                                 gr_ion_alloc.cpp \
+                                 gr_adreno_info.cpp \
+                                 gr_allocator.cpp \
+                                 gr_buf_mgr.cpp \
+                                 gr_device_impl.cpp
+LOCAL_COPY_HEADERS_TO         := $(common_header_export_path)
+LOCAL_COPY_HEADERS            := gr_device_impl.h gralloc_priv.h gr_priv_handle.h
+include $(BUILD_SHARED_LIBRARY)
diff --git a/libgralloc1/gr_adreno_info.cpp b/libgralloc1/gr_adreno_info.cpp
new file mode 100644
index 0000000..adb59f0
--- /dev/null
+++ b/libgralloc1/gr_adreno_info.cpp
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include <dlfcn.h>
+
+#include "gralloc_priv.h"
+#include "gr_adreno_info.h"
+#include "gr_utils.h"
+
+namespace gralloc1 {
+
+AdrenoMemInfo::AdrenoMemInfo() {
+}
+
+bool AdrenoMemInfo::Init() {
+  libadreno_utils_ = ::dlopen("libadreno_utils.so", RTLD_NOW);
+  if (libadreno_utils_) {
+    *reinterpret_cast<void **>(&LINK_adreno_compute_aligned_width_and_height) =
+        ::dlsym(libadreno_utils_, "compute_aligned_width_and_height");
+    *reinterpret_cast<void **>(&LINK_adreno_compute_padding) =
+        ::dlsym(libadreno_utils_, "compute_surface_padding");
+    *reinterpret_cast<void **>(&LINK_adreno_isMacroTilingSupportedByGpu) =
+        ::dlsym(libadreno_utils_, "isMacroTilingSupportedByGpu");
+    *reinterpret_cast<void **>(&LINK_adreno_compute_compressedfmt_aligned_width_and_height) =
+        ::dlsym(libadreno_utils_, "compute_compressedfmt_aligned_width_and_height");
+    *reinterpret_cast<void **>(&LINK_adreno_isUBWCSupportedByGpu) =
+        ::dlsym(libadreno_utils_, "isUBWCSupportedByGpu");
+    *reinterpret_cast<void **>(&LINK_adreno_get_gpu_pixel_alignment) =
+        ::dlsym(libadreno_utils_, "get_gpu_pixel_alignment");
+  } else {
+    ALOGE(" Failed to load libadreno_utils.so");
+    return false;
+  }
+
+  // Check if the overriding property debug.gralloc.gfx_ubwc_disable_
+  // that disables UBWC allocations for the graphics stack is set
+  char property[PROPERTY_VALUE_MAX];
+  property_get("debug.gralloc.gfx_ubwc_disable_", property, "0");
+  if (!(strncmp(property, "1", PROPERTY_VALUE_MAX)) ||
+      !(strncmp(property, "true", PROPERTY_VALUE_MAX))) {
+    gfx_ubwc_disable_ = true;
+  }
+
+  if ((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
+      (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
+       (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
+    map_fb_ = true;
+  }
+
+  return true;
+}
+
+AdrenoMemInfo::~AdrenoMemInfo() {
+  if (libadreno_utils_) {
+    ::dlclose(libadreno_utils_);
+  }
+}
+
+bool AdrenoMemInfo::IsMacroTilingSupportedByGPU() {
+  if (LINK_adreno_isMacroTilingSupportedByGpu) {
+    return LINK_adreno_isMacroTilingSupportedByGpu();
+  }
+
+  return false;
+}
+
+void AdrenoMemInfo::AlignUnCompressedRGB(int width, int height, int format, int tile_enabled,
+                                         unsigned int *aligned_w, unsigned int *aligned_h) {
+  *aligned_w = (unsigned int)ALIGN(width, 32);
+  *aligned_h = (unsigned int)ALIGN(height, 32);
+
+  // Don't add any additional padding if debug.gralloc.map_fb_memory
+  // is enabled
+  if (map_fb_) {
+    return;
+  }
+
+  int bpp = 4;
+  switch (format) {
+    case HAL_PIXEL_FORMAT_RGB_888:
+      bpp = 3;
+      break;
+    case HAL_PIXEL_FORMAT_RGB_565:
+    case HAL_PIXEL_FORMAT_BGR_565:
+    case HAL_PIXEL_FORMAT_RGBA_5551:
+    case HAL_PIXEL_FORMAT_RGBA_4444:
+      bpp = 2;
+      break;
+    default:
+      break;
+  }
+
+  int raster_mode = 0;          // Adreno unknown raster mode.
+  int padding_threshold = 512;  // Threshold for padding surfaces.
+  // the function below computes aligned width and aligned height
+  // based on linear or macro tile mode selected.
+  if (LINK_adreno_compute_aligned_width_and_height) {
+    LINK_adreno_compute_aligned_width_and_height(
+        width, height, bpp, tile_enabled, raster_mode, padding_threshold,
+        reinterpret_cast<int *>(aligned_w), reinterpret_cast<int *>(aligned_h));
+  } else if (LINK_adreno_compute_padding) {
+    int surface_tile_height = 1;  // Linear surface
+    *aligned_w = UINT(LINK_adreno_compute_padding(width, bpp, surface_tile_height, raster_mode,
+                                                  padding_threshold));
+    ALOGW("%s: Warning!! Old GFX API is used to calculate stride", __FUNCTION__);
+  } else {
+    ALOGW(
+        "%s: Warning!! Symbols compute_surface_padding and "
+        "compute_aligned_width_and_height not found",
+        __FUNCTION__);
+  }
+}
+
+void AdrenoMemInfo::AlignCompressedRGB(int width, int height, int format, unsigned int *aligned_w,
+                                       unsigned int *aligned_h) {
+  if (LINK_adreno_compute_compressedfmt_aligned_width_and_height) {
+    int bytesPerPixel = 0;
+    int raster_mode = 0;          // Adreno unknown raster mode.
+    int padding_threshold = 512;  // Threshold for padding
+    // surfaces.
+
+    LINK_adreno_compute_compressedfmt_aligned_width_and_height(
+        width, height, format, 0, raster_mode, padding_threshold,
+        reinterpret_cast<int *>(aligned_w), reinterpret_cast<int *>(aligned_h), &bytesPerPixel);
+  } else {
+    ALOGW("%s: Warning!! compute_compressedfmt_aligned_width_and_height not found", __FUNCTION__);
+  }
+}
+
+bool AdrenoMemInfo::IsUBWCSupportedByGPU(int format) {
+  if (!gfx_ubwc_disable_ && LINK_adreno_isUBWCSupportedByGpu) {
+    ADRENOPIXELFORMAT gpu_format = GetGpuPixelFormat(format);
+    return LINK_adreno_isUBWCSupportedByGpu(gpu_format);
+  }
+
+  return false;
+}
+
+uint32_t AdrenoMemInfo::GetGpuPixelAlignment() {
+  if (LINK_adreno_get_gpu_pixel_alignment) {
+    return LINK_adreno_get_gpu_pixel_alignment();
+  }
+
+  return 1;
+}
+
+ADRENOPIXELFORMAT AdrenoMemInfo::GetGpuPixelFormat(int hal_format) {
+  switch (hal_format) {
+    case HAL_PIXEL_FORMAT_RGBA_8888:
+      return ADRENO_PIXELFORMAT_R8G8B8A8;
+    case HAL_PIXEL_FORMAT_RGBX_8888:
+      return ADRENO_PIXELFORMAT_R8G8B8X8;
+    case HAL_PIXEL_FORMAT_RGB_565:
+      return ADRENO_PIXELFORMAT_B5G6R5;
+    case HAL_PIXEL_FORMAT_BGR_565:
+      return ADRENO_PIXELFORMAT_R5G6B5;
+    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+      return ADRENO_PIXELFORMAT_NV12;
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+      return ADRENO_PIXELFORMAT_NV12_EXT;
+    default:
+      ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format);
+      break;
+  }
+
+  return ADRENO_PIXELFORMAT_UNKNOWN;
+}
+
+}  // namespace gralloc1
diff --git a/libgralloc1/gr_adreno_info.h b/libgralloc1/gr_adreno_info.h
new file mode 100644
index 0000000..7b053ad
--- /dev/null
+++ b/libgralloc1/gr_adreno_info.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __GR_ADRENO_INFO_H__
+#define __GR_ADRENO_INFO_H__
+
+#ifdef VENUS_COLOR_FORMAT
+#include <media/msm_media_info.h>
+#else
+#define VENUS_Y_STRIDE(args...) 0
+#define VENUS_Y_SCANLINES(args...) 0
+#define VENUS_BUFFER_SIZE(args...) 0
+#endif
+
+namespace gralloc1 {
+
+// Adreno Pixel Formats
+typedef enum {
+  ADRENO_PIXELFORMAT_UNKNOWN = 0,
+  ADRENO_PIXELFORMAT_R8G8B8A8 = 28,
+  ADRENO_PIXELFORMAT_R8G8B8A8_SRGB = 29,
+  ADRENO_PIXELFORMAT_B5G6R5 = 85,
+  ADRENO_PIXELFORMAT_B5G5R5A1 = 86,
+  ADRENO_PIXELFORMAT_B8G8R8A8 = 90,
+  ADRENO_PIXELFORMAT_B8G8R8A8_SRGB = 91,
+  ADRENO_PIXELFORMAT_B8G8R8X8_SRGB = 93,
+  ADRENO_PIXELFORMAT_NV12 = 103,
+  ADRENO_PIXELFORMAT_YUY2 = 107,
+  ADRENO_PIXELFORMAT_B4G4R4A4 = 115,
+  ADRENO_PIXELFORMAT_NV12_EXT = 506,       // NV12 with non-std alignment and offsets
+  ADRENO_PIXELFORMAT_R8G8B8X8 = 507,       //  GL_RGB8 (Internal)
+  ADRENO_PIXELFORMAT_R8G8B8 = 508,         //  GL_RGB8
+  ADRENO_PIXELFORMAT_A1B5G5R5 = 519,       //  GL_RGB5_A1
+  ADRENO_PIXELFORMAT_R8G8B8X8_SRGB = 520,  //  GL_SRGB8
+  ADRENO_PIXELFORMAT_R8G8B8_SRGB = 521,    //  GL_SRGB8
+  ADRENO_PIXELFORMAT_R5G6B5 = 610,         //  RGBA version of B5G6R5
+  ADRENO_PIXELFORMAT_R5G5B5A1 = 611,       //  RGBA version of B5G5R5A1
+  ADRENO_PIXELFORMAT_R4G4B4A4 = 612,       //  RGBA version of B4G4R4A4
+  ADRENO_PIXELFORMAT_UYVY = 614,           //  YUV 4:2:2 packed progressive (1 plane)
+  ADRENO_PIXELFORMAT_NV21 = 619,
+  ADRENO_PIXELFORMAT_Y8U8V8A8 = 620,  // YUV 4:4:4 packed (1 plane)
+  ADRENO_PIXELFORMAT_Y8 = 625,        //  Single 8-bit luma only channel YUV format
+} ADRENOPIXELFORMAT;
+
+class AdrenoMemInfo {
+ public:
+  AdrenoMemInfo();
+
+  ~AdrenoMemInfo();
+
+  bool Init();
+
+  /*
+   * Function to compute aligned width and aligned height based on
+   * width, height, format and usage flags.
+   *
+   * @return aligned width, aligned height
+   */
+  void GetAlignedWidthAndHeight(int width, int height, int format, int usage,
+                                unsigned int *aligned_w, unsigned int *aligned_h, bool ubwc_enabled,
+                                bool tile_enabled);
+
+  /*
+   * Function to compute the adreno aligned width and aligned height
+   * based on the width and format.
+   *
+   * @return aligned width, aligned height
+   */
+  void AlignUnCompressedRGB(int width, int height, int format, int tileEnabled,
+                            unsigned int *aligned_w, unsigned int *aligned_h);
+
+  /*
+   * Function to compute the adreno aligned width and aligned height
+   * based on the width and format.
+   *
+   * @return aligned width, aligned height
+   */
+  void AlignCompressedRGB(int width, int height, int format, unsigned int *aligned_w,
+                          unsigned int *aligned_h);
+
+  /*
+   * Function to compute the pixel alignment requirement.
+   *
+   * @return alignment
+   */
+  uint32_t GetGpuPixelAlignment();
+
+  /*
+   * Function to return whether GPU support MacroTile feature
+   *
+   * @return >0 : supported
+   *          0 : not supported
+   */
+  bool IsMacroTilingSupportedByGPU();
+
+  /*
+   * Function to query whether GPU supports UBWC for given HAL format
+   * @return > 0 : supported
+   *           0 : not supported
+   */
+  bool IsUBWCSupportedByGPU(int format);
+
+  /*
+   * Function to get the corresponding Adreno format for given HAL format
+   */
+  ADRENOPIXELFORMAT GetGpuPixelFormat(int hal_format);
+
+ private:
+  // link(s)to adreno surface padding library.
+  int (*LINK_adreno_compute_padding)(int width, int bpp, int surface_tile_height,
+                                     int screen_tile_height, int padding_threshold) = NULL;
+  void (*LINK_adreno_compute_aligned_width_and_height)(int width, int height, int bpp,
+                                                       int tile_mode, int raster_mode,
+                                                       int padding_threshold, int *aligned_w,
+                                                       int *aligned_h) = NULL;
+  int (*LINK_adreno_isMacroTilingSupportedByGpu)(void) = NULL;
+  void (*LINK_adreno_compute_compressedfmt_aligned_width_and_height)(
+      int width, int height, int format, int tile_mode, int raster_mode, int padding_threshold,
+      int *aligned_w, int *aligned_h, int *bpp) = NULL;
+  int (*LINK_adreno_isUBWCSupportedByGpu)(ADRENOPIXELFORMAT format) = NULL;
+  unsigned int (*LINK_adreno_get_gpu_pixel_alignment)() = NULL;
+
+  bool gfx_ubwc_disable_ = false;
+  bool map_fb_ = false;
+  void *libadreno_utils_ = NULL;
+};
+
+}  // namespace gralloc1
+
+#endif  // __GR_ADRENO_INFO_H__
diff --git a/libgralloc1/gr_allocator.cpp b/libgralloc1/gr_allocator.cpp
new file mode 100644
index 0000000..b45ba83
--- /dev/null
+++ b/libgralloc1/gr_allocator.cpp
@@ -0,0 +1,871 @@
+/*
+ * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <cutils/log.h>
+#include <algorithm>
+
+#include "gr_utils.h"
+#include "gr_allocator.h"
+#include "gr_adreno_info.h"
+#include "gralloc_priv.h"
+
+#include "qd_utils.h"
+#include "qdMetaData.h"
+
+#define ASTC_BLOCK_SIZE 16
+
+#ifndef ION_FLAG_CP_PIXEL
+#define ION_FLAG_CP_PIXEL 0
+#endif
+
+#ifndef ION_FLAG_ALLOW_NON_CONTIG
+#define ION_FLAG_ALLOW_NON_CONTIG 0
+#endif
+
+#ifdef MASTER_SIDE_CP
+#define CP_HEAP_ID ION_SECURE_HEAP_ID
+#define SD_HEAP_ID ION_SECURE_DISPLAY_HEAP_ID
+#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_CP_PIXEL)
+#define ION_SD_FLAGS (ION_SECURE | ION_FLAG_CP_SEC_DISPLAY)
+#else  // SLAVE_SIDE_CP
+#define CP_HEAP_ID ION_CP_MM_HEAP_ID
+#define SD_HEAP_ID CP_HEAP_ID
+#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_ALLOW_NON_CONTIG)
+#define ION_SD_FLAGS ION_SECURE
+#endif
+
+namespace gralloc1 {
+
+Allocator::Allocator() : ion_allocator_(NULL), adreno_helper_(NULL) {
+}
+
+bool Allocator::Init() {
+  ion_allocator_ = new IonAlloc();
+  if (!ion_allocator_->Init()) {
+    return false;
+  }
+
+  adreno_helper_ = new AdrenoMemInfo();
+  if (!adreno_helper_->Init()) {
+    return false;
+  }
+
+  gpu_support_macrotile = adreno_helper_->IsMacroTilingSupportedByGPU();
+  int supports_macrotile = 0;
+  qdutils::querySDEInfo(qdutils::HAS_MACRO_TILE, &supports_macrotile);
+  display_support_macrotile = !!supports_macrotile;
+
+  return true;
+}
+
+Allocator::~Allocator() {
+  if (ion_allocator_) {
+    delete ion_allocator_;
+  }
+
+  if (adreno_helper_) {
+    delete adreno_helper_;
+  }
+}
+
+int Allocator::AllocateMem(AllocData *alloc_data, gralloc1_producer_usage_t prod_usage,
+                           gralloc1_consumer_usage_t cons_usage) {
+  int ret;
+  alloc_data->uncached = UseUncached(prod_usage);
+
+  // After this point we should have the right heap set, there is no fallback
+  GetIonHeapInfo(prod_usage, cons_usage, &alloc_data->heap_id, &alloc_data->alloc_type,
+                 &alloc_data->flags);
+
+  ret = ion_allocator_->AllocBuffer(alloc_data);
+  if (ret >= 0) {
+    alloc_data->alloc_type |= private_handle_t::PRIV_FLAGS_USES_ION;
+  } else {
+    ALOGE("%s: Failed to allocate buffer - heap: 0x%x flags: 0x%x", __FUNCTION__,
+          alloc_data->heap_id, alloc_data->flags);
+  }
+
+  return ret;
+}
+
+// Allocates buffer from width, height and format into a
+// private_handle_t. It is the responsibility of the caller
+// to free the buffer using the FreeBuffer function
+int Allocator::AllocateBuffer(const BufferDescriptor &descriptor, private_handle_t **pHnd) {
+  AllocData data;
+  unsigned int aligned_w, aligned_h;
+  data.base = 0;
+  data.fd = -1;
+  data.offset = 0;
+  data.align = (unsigned int)getpagesize();
+  int format = descriptor.GetFormat();
+  gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
+  gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
+  GetBufferSizeAndDimensions(descriptor, &data.size, &aligned_w, &aligned_h);
+
+  int err = AllocateMem(&data, prod_usage, cons_usage);
+  if (0 != err) {
+    ALOGE("%s: allocate failed", __FUNCTION__);
+    return -ENOMEM;
+  }
+
+  if (IsUBwcEnabled(format, prod_usage, cons_usage)) {
+    data.alloc_type |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+  }
+
+  // Metadata is not allocated. would be empty
+  private_handle_t *hnd = new private_handle_t(
+      data.fd, data.size, INT(data.alloc_type), 0, INT(format), INT(aligned_w), INT(aligned_h), -1,
+      0, 0, descriptor.GetWidth(), descriptor.GetHeight(), prod_usage, cons_usage);
+  hnd->base = (uint64_t)data.base;
+  hnd->offset = data.offset;
+  hnd->gpuaddr = 0;
+  *pHnd = hnd;
+
+  return 0;
+}
+
+int Allocator::MapBuffer(void **base, unsigned int size, unsigned int offset, int fd) {
+  if (ion_allocator_) {
+    return ion_allocator_->MapBuffer(base, size, offset, fd);
+  }
+
+  return -EINVAL;
+}
+
+int Allocator::FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd) {
+  if (ion_allocator_) {
+    return ion_allocator_->FreeBuffer(base, size, offset, fd);
+  }
+
+  return -EINVAL;
+}
+
+int Allocator::CleanBuffer(void *base, unsigned int size, unsigned int offset, int fd, int op) {
+  if (ion_allocator_) {
+    return ion_allocator_->CleanBuffer(base, size, offset, fd, op);
+  }
+
+  return -EINVAL;
+}
+
+bool Allocator::CheckForBufferSharing(uint32_t num_descriptors, const BufferDescriptor *descriptors,
+                                      int *max_index) {
+  unsigned int cur_heap_id = 0, prev_heap_id = 0;
+  unsigned int cur_alloc_type = 0, prev_alloc_type = 0;
+  unsigned int cur_ion_flags = 0, prev_ion_flags = 0;
+  bool cur_uncached = false, prev_uncached = false;
+  unsigned int alignedw, alignedh;
+  unsigned int max_size = 0;
+
+  *max_index = -1;
+  for (uint32_t i = 0; i < num_descriptors; i++) {
+    // Check Cached vs non-cached and all the ION flags
+    cur_uncached = UseUncached(descriptors[i].GetProducerUsage());
+    GetIonHeapInfo(descriptors[i].GetProducerUsage(), descriptors[i].GetConsumerUsage(),
+                   &cur_heap_id, &cur_alloc_type, &cur_ion_flags);
+
+    if (i > 0 && (cur_heap_id != prev_heap_id || cur_alloc_type != prev_alloc_type ||
+                  cur_ion_flags != prev_ion_flags)) {
+      return false;
+    }
+
+    // For same format type, find the descriptor with bigger size
+    GetAlignedWidthAndHeight(descriptors[i], &alignedw, &alignedh);
+    unsigned int size = GetSize(descriptors[i], alignedw, alignedh);
+    if (max_size < size) {
+      *max_index = INT(i);
+      max_size = size;
+    }
+
+    prev_heap_id = cur_heap_id;
+    prev_uncached = cur_uncached;
+    prev_ion_flags = cur_ion_flags;
+    prev_alloc_type = cur_alloc_type;
+  }
+
+  return true;
+}
+
+bool Allocator::IsMacroTileEnabled(int format, gralloc1_producer_usage_t prod_usage,
+                                   gralloc1_consumer_usage_t cons_usage) {
+  bool tile_enabled = false;
+
+  // Check whether GPU & MDSS supports MacroTiling feature
+  if (!adreno_helper_->IsMacroTilingSupportedByGPU() || !display_support_macrotile) {
+    return tile_enabled;
+  }
+
+  // check the format
+  switch (format) {
+    case HAL_PIXEL_FORMAT_RGBA_8888:
+    case HAL_PIXEL_FORMAT_RGBX_8888:
+    case HAL_PIXEL_FORMAT_BGRA_8888:
+    case HAL_PIXEL_FORMAT_RGB_565:
+    case HAL_PIXEL_FORMAT_BGR_565:
+      if (!CpuCanAccess(prod_usage, cons_usage)) {
+        // not touched by CPU
+        tile_enabled = true;
+      }
+      break;
+    default:
+      break;
+  }
+
+  return tile_enabled;
+}
+
+// helper function
+unsigned int Allocator::GetSize(const BufferDescriptor &descriptor, unsigned int alignedw,
+                                unsigned int alignedh) {
+  unsigned int size = 0;
+  int format = descriptor.GetFormat();
+  int width = descriptor.GetWidth();
+  int height = descriptor.GetHeight();
+  gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
+  gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
+
+  if (IsUBwcEnabled(format, prod_usage, cons_usage)) {
+    return GetUBwcSize(width, height, format, alignedw, alignedh);
+  }
+
+  if (IsUncompressedRGBFormat(format)) {
+    uint32_t bpp = GetBppForUncompressedRGB(format);
+    size = alignedw * alignedh * bpp;
+    return size;
+  }
+
+  if (IsCompressedRGBFormat(format)) {
+    size = alignedw * alignedh * ASTC_BLOCK_SIZE;
+    return size;
+  }
+
+  // Below switch should be for only YUV/custom formats
+  switch (format) {
+    case HAL_PIXEL_FORMAT_RAW16:
+      size = alignedw * alignedh * 2;
+      break;
+    case HAL_PIXEL_FORMAT_RAW10:
+      size = ALIGN(alignedw * alignedh, SIZE_4K);
+      break;
+
+    // adreno formats
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:  // NV21
+      size = ALIGN(alignedw * alignedh, SIZE_4K);
+      size += (unsigned int)ALIGN(2 * ALIGN(width / 2, 32) * ALIGN(height / 2, 32), SIZE_4K);
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:  // NV12
+      // The chroma plane is subsampled,
+      // but the pitch in bytes is unchanged
+      // The GPU needs 4K alignment, but the video decoder needs 8K
+      size = ALIGN(alignedw * alignedh, SIZE_8K);
+      size += ALIGN(alignedw * (unsigned int)ALIGN(height / 2, 32), SIZE_8K);
+      break;
+    case HAL_PIXEL_FORMAT_YV12:
+      if ((format == HAL_PIXEL_FORMAT_YV12) && ((width & 1) || (height & 1))) {
+        ALOGE("w or h is odd for the YV12 format");
+        return 0;
+      }
+      size = alignedw * alignedh + (ALIGN(alignedw / 2, 16) * (alignedh / 2)) * 2;
+      size = ALIGN(size, (unsigned int)SIZE_4K);
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+      size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2 + 1, SIZE_4K);
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+    case HAL_PIXEL_FORMAT_YCbCr_422_I:
+    case HAL_PIXEL_FORMAT_YCrCb_422_I:
+      if (width & 1) {
+        ALOGE("width is odd for the YUV422_SP format");
+        return 0;
+      }
+      size = ALIGN(alignedw * alignedh * 2, SIZE_4K);
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+      size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
+      break;
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
+      size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height);
+      break;
+    case HAL_PIXEL_FORMAT_BLOB:
+    case HAL_PIXEL_FORMAT_RAW_OPAQUE:
+      if (height != 1) {
+        ALOGE("%s: Buffers with HAL_PIXEL_FORMAT_BLOB must have height 1 ", __FUNCTION__);
+        return 0;
+      }
+      size = (unsigned int)width;
+      break;
+    case HAL_PIXEL_FORMAT_NV21_ZSL:
+      size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2, SIZE_4K);
+      break;
+    default:
+      ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
+      return 0;
+  }
+
+  return size;
+}
+
+void Allocator::GetBufferSizeAndDimensions(int width, int height, int format, unsigned int *size,
+                                           unsigned int *alignedw, unsigned int *alignedh) {
+  BufferDescriptor descriptor = BufferDescriptor(width, height, format);
+  GetAlignedWidthAndHeight(descriptor, alignedw, alignedh);
+
+  *size = GetSize(descriptor, *alignedw, *alignedh);
+}
+
+void Allocator::GetBufferSizeAndDimensions(const BufferDescriptor &descriptor, unsigned int *size,
+                                           unsigned int *alignedw, unsigned int *alignedh) {
+  GetAlignedWidthAndHeight(descriptor, alignedw, alignedh);
+
+  *size = GetSize(descriptor, *alignedw, *alignedh);
+}
+
+void Allocator::GetBufferAttributes(const BufferDescriptor &descriptor, unsigned int *alignedw,
+                                    unsigned int *alignedh, int *tiled, unsigned int *size) {
+  int format = descriptor.GetFormat();
+  gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
+  gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
+
+  *tiled = false;
+  if (IsUBwcEnabled(format, prod_usage, cons_usage) ||
+      IsMacroTileEnabled(format, prod_usage, cons_usage)) {
+    *tiled = true;
+  }
+
+  GetAlignedWidthAndHeight(descriptor, alignedw, alignedh);
+  *size = GetSize(descriptor, *alignedw, *alignedh);
+}
+
+void Allocator::GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
+                                      int color_format, struct android_ycbcr *ycbcr) {
+  // UBWC buffer has these 4 planes in the following sequence:
+  // Y_Meta_Plane, Y_Plane, UV_Meta_Plane, UV_Plane
+  unsigned int y_meta_stride, y_meta_height, y_meta_size;
+  unsigned int y_stride, y_height, y_size;
+  unsigned int c_meta_stride, c_meta_height, c_meta_size;
+  unsigned int alignment = 4096;
+
+  y_meta_stride = VENUS_Y_META_STRIDE(color_format, INT(width));
+  y_meta_height = VENUS_Y_META_SCANLINES(color_format, INT(height));
+  y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);
+
+  y_stride = VENUS_Y_STRIDE(color_format, INT(width));
+  y_height = VENUS_Y_SCANLINES(color_format, INT(height));
+  y_size = ALIGN((y_stride * y_height), alignment);
+
+  c_meta_stride = VENUS_UV_META_STRIDE(color_format, INT(width));
+  c_meta_height = VENUS_UV_META_SCANLINES(color_format, INT(height));
+  c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
+
+  ycbcr->y = reinterpret_cast<void *>(base + y_meta_size);
+  ycbcr->cb = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size);
+  ycbcr->cr = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size + 1);
+  ycbcr->ystride = y_stride;
+  ycbcr->cstride = VENUS_UV_STRIDE(color_format, INT(width));
+}
+
+void Allocator::GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp,
+                                  struct android_ycbcr *ycbcr) {
+  unsigned int ystride, cstride;
+
+  ystride = cstride = UINT(width) * bpp;
+  ycbcr->y = reinterpret_cast<void *>(base);
+  ycbcr->cb = reinterpret_cast<void *>(base + ystride * UINT(height));
+  ycbcr->cr = reinterpret_cast<void *>(base + ystride * UINT(height) + 1);
+  ycbcr->ystride = ystride;
+  ycbcr->cstride = cstride;
+  ycbcr->chroma_step = 2 * bpp;
+}
+
+int Allocator::GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr *ycbcr) {
+  int err = 0;
+  uint32_t width = UINT(hnd->width);
+  uint32_t height = UINT(hnd->height);
+  int format = hnd->format;
+  gralloc1_producer_usage_t prod_usage = hnd->GetProducerUsage();
+  gralloc1_consumer_usage_t cons_usage = hnd->GetConsumerUsage();
+  unsigned int ystride, cstride;
+
+  memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
+  MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
+
+  // Check if UBWC buffer has been rendered in linear format.
+  if (metadata && (metadata->operation & LINEAR_FORMAT)) {
+    format = INT(metadata->linearFormat);
+  }
+
+  // Check metadata if the geometry has been updated.
+  if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
+    int usage = 0;
+
+    if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
+      usage = GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC;
+    }
+
+    BufferDescriptor descriptor =
+        BufferDescriptor(metadata->bufferDim.sliceWidth, metadata->bufferDim.sliceHeight, format,
+                         prod_usage, cons_usage);
+    GetAlignedWidthAndHeight(descriptor, &width, &height);
+  }
+
+  // Get the chroma offsets from the handle width/height. We take advantage
+  // of the fact the width _is_ the stride
+  switch (format) {
+    // Semiplanar
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+      // Same as YCbCr_420_SP_VENUS
+      GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
+      break;
+
+    case HAL_PIXEL_FORMAT_YCbCr_420_P010:
+      GetYuvSPPlaneInfo(hnd->base, width, height, 2, ycbcr);
+      break;
+
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+      GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr);
+      ycbcr->chroma_step = 2;
+      break;
+
+    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+      GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_BPP10_UBWC, ycbcr);
+      ycbcr->chroma_step = 3;
+      break;
+
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
+    case HAL_PIXEL_FORMAT_NV21_ZSL:
+    case HAL_PIXEL_FORMAT_RAW16:
+    case HAL_PIXEL_FORMAT_RAW10:
+      GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
+      std::swap(ycbcr->cb, ycbcr->cr);
+      break;
+
+    // Planar
+    case HAL_PIXEL_FORMAT_YV12:
+      ystride = width;
+      cstride = ALIGN(width / 2, 16);
+      ycbcr->y = reinterpret_cast<void *>(hnd->base);
+      ycbcr->cr = reinterpret_cast<void *>(hnd->base + ystride * height);
+      ycbcr->cb = reinterpret_cast<void *>(hnd->base + ystride * height + cstride * height / 2);
+      ycbcr->ystride = ystride;
+      ycbcr->cstride = cstride;
+      ycbcr->chroma_step = 1;
+      break;
+
+    // Unsupported formats
+    case HAL_PIXEL_FORMAT_YCbCr_422_I:
+    case HAL_PIXEL_FORMAT_YCrCb_422_I:
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
+    default:
+      ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
+      err = -EINVAL;
+  }
+
+  return err;
+}
+
+int Allocator::GetImplDefinedFormat(gralloc1_producer_usage_t prod_usage,
+                                    gralloc1_consumer_usage_t cons_usage, int format) {
+  int gr_format = format;
+
+  // If input format is HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED then based on
+  // the usage bits, gralloc assigns a format.
+  if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
+      format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+    if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC) {
+      gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
+    } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) {
+      gr_format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE;  // NV12
+    } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_ZSL) {
+      gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;  // NV21 ZSL
+    } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_CAMERA) {
+      gr_format = HAL_PIXEL_FORMAT_YCrCb_420_SP;  // NV21
+    } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
+      if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+        gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;  // NV21
+      } else {
+        gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS;  // NV12 preview
+      }
+    } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
+      // XXX: If we still haven't set a format, default to RGBA8888
+      gr_format = HAL_PIXEL_FORMAT_RGBA_8888;
+    } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+      // If no other usage flags are detected, default the
+      // flexible YUV format to NV21_ZSL
+      gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;
+    }
+  }
+
+  return gr_format;
+}
+
+// Explicitly defined UBWC formats
+bool Allocator::IsUBwcFormat(int format) {
+  switch (format) {
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+      return true;
+    default:
+      return false;
+  }
+}
+
+bool Allocator::IsUBwcSupported(int format) {
+  // Existing HAL formats with UBWC support
+  switch (format) {
+    case HAL_PIXEL_FORMAT_BGR_565:
+    case HAL_PIXEL_FORMAT_RGBA_8888:
+    case HAL_PIXEL_FORMAT_RGBX_8888:
+    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+      return true;
+    default:
+      break;
+  }
+
+  return false;
+}
+
+/* The default policy is to return cached buffers unless the client explicity
+ * sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely
+ * read or written in software. */
+// TODO(user) : As of now relying only on producer usage
+bool Allocator::UseUncached(gralloc1_producer_usage_t usage) {
+  if ((usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_UNCACHED) ||
+      (usage & GRALLOC1_PRODUCER_USAGE_PROTECTED)) {
+    return true;
+  }
+
+  // CPU read rarely
+  if ((usage & GRALLOC1_PRODUCER_USAGE_CPU_READ) &&
+      !(usage & GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN)) {
+    return true;
+  }
+
+  // CPU  write rarely
+  if ((usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE) &&
+      !(usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN)) {
+    return true;
+  }
+
+  return false;
+}
+
+void Allocator::GetIonHeapInfo(gralloc1_producer_usage_t prod_usage,
+                               gralloc1_consumer_usage_t cons_usage, unsigned int *ion_heap_id,
+                               unsigned int *alloc_type, unsigned int *ion_flags) {
+  unsigned int heap_id = 0;
+  unsigned int type = 0;
+  int flags = 0;
+  if (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) {
+    if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) {
+      heap_id = ION_HEAP(SD_HEAP_ID);
+      /*
+       * There is currently no flag in ION for Secure Display
+       * VM. Please add it to the define once available.
+       */
+      flags |= ION_SD_FLAGS;
+    } else {
+      heap_id = ION_HEAP(CP_HEAP_ID);
+      flags |= ION_CP_FLAGS;
+    }
+  } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_MM_HEAP) {
+    // MM Heap is exclusively a secure heap.
+    // If it is used for non secure cases, fallback to IOMMU heap
+    ALOGW("MM_HEAP cannot be used as an insecure heap. Using system heap instead!!");
+    heap_id |= ION_HEAP(ION_SYSTEM_HEAP_ID);
+  }
+
+  if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_HEAP) {
+    heap_id |= ION_HEAP(ION_CAMERA_HEAP_ID);
+  }
+
+  if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ADSP_HEAP) {
+    heap_id |= ION_HEAP(ION_ADSP_HEAP_ID);
+  }
+
+  if (flags & ION_SECURE) {
+    type |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
+  }
+
+  // if no ion heap flags are set, default to system heap
+  if (!heap_id) {
+    heap_id = ION_HEAP(ION_SYSTEM_HEAP_ID);
+  }
+
+  *alloc_type = type;
+  *ion_flags = (unsigned int)flags;
+  *ion_heap_id = heap_id;
+
+  return;
+}
+
+bool Allocator::IsUBwcEnabled(int format, gralloc1_producer_usage_t prod_usage,
+                              gralloc1_consumer_usage_t cons_usage) {
+  // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
+  if (IsUBwcFormat(format)) {
+    return true;
+  }
+
+  // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
+  // support the format. OR if a non-OpenGL client like Rotator, sets UBWC
+  // usage flag and MDP supports the format.
+  if ((prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC) && IsUBwcSupported(format)) {
+    bool enable = true;
+    // Query GPU for UBWC only if buffer is intended to be used by GPU.
+    if ((cons_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) ||
+        (prod_usage & GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET)) {
+      enable = adreno_helper_->IsUBWCSupportedByGPU(format);
+    }
+
+    // Allow UBWC, only if CPU usage flags are not set
+    if (enable && !(CpuCanAccess(prod_usage, cons_usage))) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+void Allocator::GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
+                                         unsigned int *aligned_h) {
+  switch (format) {
+    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+      *aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
+      *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
+      break;
+    default:
+      ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
+      *aligned_w = 0;
+      *aligned_h = 0;
+      break;
+  }
+}
+
+void Allocator::GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height) {
+  *block_width = 0;
+  *block_height = 0;
+
+  switch (bpp) {
+    case 2:
+    case 4:
+      *block_width = 16;
+      *block_height = 4;
+      break;
+    case 8:
+      *block_width = 8;
+      *block_height = 4;
+      break;
+    case 16:
+      *block_width = 4;
+      *block_height = 4;
+      break;
+    default:
+      ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
+      break;
+  }
+}
+
+unsigned int Allocator::GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp) {
+  unsigned int size = 0;
+  int meta_width, meta_height;
+  int block_width, block_height;
+
+  GetRgbUBwcBlockSize(bpp, &block_width, &block_height);
+  if (!block_width || !block_height) {
+    ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
+    return size;
+  }
+
+  // Align meta buffer height to 16 blocks
+  meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
+
+  // Align meta buffer width to 64 blocks
+  meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
+
+  // Align meta buffer size to 4K
+  size = (unsigned int)ALIGN((meta_width * meta_height), 4096);
+
+  return size;
+}
+
+unsigned int Allocator::GetUBwcSize(int width, int height, int format, unsigned int alignedw,
+                                    unsigned int alignedh) {
+  unsigned int size = 0;
+  uint32_t bpp = 0;
+  switch (format) {
+    case HAL_PIXEL_FORMAT_BGR_565:
+    case HAL_PIXEL_FORMAT_RGBA_8888:
+    case HAL_PIXEL_FORMAT_RGBX_8888:
+    case HAL_PIXEL_FORMAT_RGBA_1010102:
+    case HAL_PIXEL_FORMAT_RGBX_1010102:
+      bpp = GetBppForUncompressedRGB(format);
+      size = alignedw * alignedh * bpp;
+      size += GetRgbUBwcMetaBufferSize(width, height, bpp);
+      break;
+    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+      size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+      size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height);
+      break;
+    default:
+      ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
+      break;
+  }
+
+  return size;
+}
+
+int Allocator::GetRgbDataAddress(private_handle_t *hnd, void **rgb_data) {
+  int err = 0;
+
+  // This api is for RGB* formats
+  if (!gralloc1::IsUncompressedRGBFormat(hnd->format)) {
+    return -EINVAL;
+  }
+
+  // linear buffer, nothing to do further
+  if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
+    *rgb_data = reinterpret_cast<void *>(hnd->base);
+    return err;
+  }
+
+  unsigned int meta_size = 0;
+  uint32_t bpp = GetBppForUncompressedRGB(hnd->format);
+  switch (hnd->format) {
+    case HAL_PIXEL_FORMAT_BGR_565:
+    case HAL_PIXEL_FORMAT_RGBA_8888:
+    case HAL_PIXEL_FORMAT_RGBX_8888:
+      meta_size = GetRgbUBwcMetaBufferSize(hnd->width, hnd->height, bpp);
+      break;
+    default:
+      ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format);
+      err = -EINVAL;
+      break;
+  }
+  *rgb_data = reinterpret_cast<void *>(hnd->base + meta_size);
+
+  return err;
+}
+
+void Allocator::GetAlignedWidthAndHeight(const BufferDescriptor &descriptor, unsigned int *alignedw,
+                                         unsigned int *alignedh) {
+  int width = descriptor.GetWidth();
+  int height = descriptor.GetHeight();
+  int format = descriptor.GetFormat();
+  gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
+  gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
+
+  // Currently surface padding is only computed for RGB* surfaces.
+  bool ubwc_enabled = IsUBwcEnabled(format, prod_usage, cons_usage);
+  int tile = ubwc_enabled || IsMacroTileEnabled(format, prod_usage, cons_usage);
+
+  if (IsUncompressedRGBFormat(format)) {
+    adreno_helper_->AlignUnCompressedRGB(width, height, format, tile, alignedw, alignedh);
+    return;
+  }
+
+  if (ubwc_enabled) {
+    GetYuvUBwcWidthAndHeight(width, height, format, alignedw, alignedh);
+    return;
+  }
+
+  if (IsCompressedRGBFormat(format)) {
+    adreno_helper_->AlignCompressedRGB(width, height, format, alignedw, alignedh);
+    return;
+  }
+
+  int aligned_w = width;
+  int aligned_h = height;
+  unsigned int alignment = 32;
+
+  // Below should be only YUV family
+  switch (format) {
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+      alignment = adreno_helper_->GetGpuPixelAlignment();
+      aligned_w = ALIGN(width, alignment);
+      break;
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
+      aligned_w = ALIGN(width, alignment);
+      break;
+    case HAL_PIXEL_FORMAT_RAW16:
+      aligned_w = ALIGN(width, 16);
+      break;
+    case HAL_PIXEL_FORMAT_RAW10:
+      aligned_w = ALIGN(width * 10 / 8, 16);
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
+      aligned_w = ALIGN(width, 128);
+      break;
+    case HAL_PIXEL_FORMAT_YV12:
+    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+    case HAL_PIXEL_FORMAT_YCbCr_422_I:
+    case HAL_PIXEL_FORMAT_YCrCb_422_I:
+      aligned_w = ALIGN(width, 16);
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+      aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV12, width));
+      aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV12, height));
+      break;
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
+      aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV21, width));
+      aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV21, height));
+      break;
+    case HAL_PIXEL_FORMAT_BLOB:
+    case HAL_PIXEL_FORMAT_RAW_OPAQUE:
+      break;
+    case HAL_PIXEL_FORMAT_NV21_ZSL:
+      aligned_w = ALIGN(width, 64);
+      aligned_h = ALIGN(height, 64);
+      break;
+    default:
+      break;
+  }
+
+  *alignedw = (unsigned int)aligned_w;
+  *alignedh = (unsigned int)aligned_h;
+}
+
+}  // namespace gralloc1
diff --git a/libgralloc1/gr_allocator.h b/libgralloc1/gr_allocator.h
new file mode 100644
index 0000000..583b2d7
--- /dev/null
+++ b/libgralloc1/gr_allocator.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __GR_ALLOCATOR_H__
+#define __GR_ALLOCATOR_H__
+
+#ifdef MASTER_SIDE_CP
+#define SECURE_ALIGN SZ_4K
+#else
+#define SECURE_ALIGN SZ_1M
+#endif
+
+#include "gralloc_priv.h"
+#include "gr_buf_descriptor.h"
+#include "gr_adreno_info.h"
+#include "gr_ion_alloc.h"
+
+namespace gralloc1 {
+
+class Allocator {
+ public:
+  Allocator();
+  ~Allocator();
+  bool Init();
+  int AllocateBuffer(const BufferDescriptor &descriptor, private_handle_t **pHnd);
+  int MapBuffer(void **base, unsigned int size, unsigned int offset, int fd);
+  int FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd);
+  int CleanBuffer(void *base, unsigned int size, unsigned int offset, int fd, int op);
+  int AllocateMem(AllocData *data, gralloc1_producer_usage_t prod_usage,
+                  gralloc1_consumer_usage_t cons_usage);
+  bool IsMacroTileEnabled(int format, gralloc1_producer_usage_t prod_usage,
+                          gralloc1_consumer_usage_t cons_usage);
+  // @return : index of the descriptor with maximum buffer size req
+  bool CheckForBufferSharing(uint32_t num_descriptors, const BufferDescriptor *descriptors,
+                             int *max_index);
+  int GetImplDefinedFormat(gralloc1_producer_usage_t prod_usage,
+                           gralloc1_consumer_usage_t cons_usage, int format);
+  unsigned int GetSize(const BufferDescriptor &d, unsigned int alignedw, unsigned int alignedh);
+  void GetBufferSizeAndDimensions(const BufferDescriptor &d, unsigned int *size,
+                                  unsigned int *alignedw, unsigned int *alignedh);
+  void GetBufferSizeAndDimensions(int width, int height, int format, unsigned int *size,
+                                  unsigned int *alignedw, unsigned int *alignedh);
+  void GetAlignedWidthAndHeight(const BufferDescriptor &d, unsigned int *aligned_w,
+                                unsigned int *aligned_h);
+  void GetBufferAttributes(const BufferDescriptor &d, unsigned int *alignedw,
+                           unsigned int *alignedh, int *tiled, unsigned int *size);
+  int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr *ycbcr);
+  int GetRgbDataAddress(private_handle_t *hnd, void **rgb_data);
+  bool UseUncached(gralloc1_producer_usage_t usage);
+  bool IsUBwcFormat(int format);
+  bool IsUBwcSupported(int format);
+  bool IsUBwcEnabled(int format, gralloc1_producer_usage_t prod_usage,
+                     gralloc1_consumer_usage_t cons_usage);
+
+ private:
+  void GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
+                                unsigned int *aligned_h);
+  void GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp,
+                         struct android_ycbcr *ycbcr);
+  void GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, int color_format,
+                             struct android_ycbcr *ycbcr);
+  void GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height);
+  unsigned int GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp);
+  unsigned int GetUBwcSize(int width, int height, int format, unsigned int alignedw,
+                           unsigned int alignedh);
+  void GetIonHeapInfo(gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage,
+                      unsigned int *ion_heap_id, unsigned int *alloc_type, unsigned int *ion_flags);
+
+  bool gpu_support_macrotile = false;
+  bool display_support_macrotile = false;
+  IonAlloc *ion_allocator_ = NULL;
+  AdrenoMemInfo *adreno_helper_ = NULL;
+};
+
+}  // namespace gralloc1
+
+#endif  // __GR_ALLOCATOR_H__
diff --git a/libgralloc1/gr_buf_descriptor.h b/libgralloc1/gr_buf_descriptor.h
new file mode 100644
index 0000000..1c3572d
--- /dev/null
+++ b/libgralloc1/gr_buf_descriptor.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __GR_BUF_DESCRIPTOR_H__
+#define __GR_BUF_DESCRIPTOR_H__
+
+#include <hardware/gralloc1.h>
+
+#define BUF_DESCRIPTOR(exp) reinterpret_cast<BufferDescriptor *>(exp)
+
+class BufferDescriptor {
+ public:
+  BufferDescriptor() {}
+
+  BufferDescriptor(int w, int h, int f)
+      : width_(w),
+        height_(h),
+        format_(f),
+        producer_usage_(GRALLOC1_PRODUCER_USAGE_NONE),
+        consumer_usage_(GRALLOC1_CONSUMER_USAGE_NONE) {}
+
+  BufferDescriptor(int w, int h, int f, gralloc1_producer_usage_t prod_usage,
+                   gralloc1_consumer_usage_t cons_usage)
+      : width_(w),
+        height_(h),
+        format_(f),
+        producer_usage_(prod_usage),
+        consumer_usage_(cons_usage) {}
+
+  bool IsValid() { return (magic == kMagic); }
+
+  void SetConsumerUsage(gralloc1_consumer_usage_t usage) { consumer_usage_ = usage; }
+
+  void SetProducerUsage(gralloc1_producer_usage_t usage) { producer_usage_ = usage; }
+
+  void SetDimensions(int w, int h) {
+    width_ = w;
+    height_ = h;
+  }
+
+  void SetColorFormat(int format) { format_ = format; }
+
+  gralloc1_consumer_usage_t GetConsumerUsage() const { return consumer_usage_; }
+
+  gralloc1_producer_usage_t GetProducerUsage() const { return producer_usage_; }
+
+  int GetWidth() const { return width_; }
+
+  int GetHeight() const { return height_; }
+
+  int GetFormat() const { return format_; }
+
+ private:
+  static const int kMagic = 'gr1d';
+
+  int magic = kMagic;
+  int width_ = -1;
+  int height_ = -1;
+  int format_ = -1;
+  gralloc1_producer_usage_t producer_usage_ = GRALLOC1_PRODUCER_USAGE_NONE;
+  gralloc1_consumer_usage_t consumer_usage_ = GRALLOC1_CONSUMER_USAGE_NONE;
+};
+
+#endif  // __GR_BUF_DESCRIPTOR_H__
diff --git a/libgralloc1/gr_buf_mgr.cpp b/libgralloc1/gr_buf_mgr.cpp
new file mode 100644
index 0000000..33abd40
--- /dev/null
+++ b/libgralloc1/gr_buf_mgr.cpp
@@ -0,0 +1,641 @@
+/*
+ * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ *
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <utility>
+
+#include "qd_utils.h"
+#include "gr_priv_handle.h"
+#include "gr_buf_descriptor.h"
+#include "gr_utils.h"
+#include "gr_buf_mgr.h"
+#include "qdMetaData.h"
+
+namespace gralloc1 {
+
+BufferManager::BufferManager() {
+  char property[PROPERTY_VALUE_MAX];
+
+  // Map framebuffer memory
+  if ((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
+      (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
+       (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
+    map_fb_mem_ = true;
+  }
+
+  // Enable UBWC for framebuffer
+  if ((property_get("debug.gralloc.enable_fb_ubwc", property, NULL) > 0) &&
+      (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
+       (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
+    ubwc_for_fb_ = true;
+  }
+
+  handles_map_.clear();
+}
+
+BufferManager::~BufferManager() {
+  if (allocator_) {
+    delete allocator_;
+  }
+}
+
+bool BufferManager::Init() {
+  allocator_ = new Allocator();
+
+  return allocator_->Init();
+}
+
+gralloc1_error_t BufferManager::AllocateBuffers(uint32_t num_descriptors,
+                                                const BufferDescriptor *descriptors,
+                                                buffer_handle_t *out_buffers) {
+  bool shared = true;
+  gralloc1_error_t status = GRALLOC1_ERROR_NONE;
+
+  // since GRALLOC1_CAPABILITY_TEST_ALLOCATE capability is supported
+  // client can ask to test the allocation by passing NULL out_buffers
+  bool test_allocate = !out_buffers;
+
+  // Check if input descriptors can be supported AND
+  // Find out if a single buffer can be shared for all the given input descriptors
+  uint32_t i = 0;
+  int max_buf_index = -1;
+  shared = allocator_->CheckForBufferSharing(num_descriptors, descriptors, &max_buf_index);
+
+  if (test_allocate) {
+    status = shared ? GRALLOC1_ERROR_NOT_SHARED : status;
+    return status;
+  }
+
+  if (shared && (max_buf_index >= 0)) {
+    // Allocate one and duplicate/copy the handles for each descriptor
+    if (AllocateBuffer(descriptors[max_buf_index], &out_buffers[max_buf_index])) {
+      return GRALLOC1_ERROR_NO_RESOURCES;
+    }
+
+    for (i = 0; i < num_descriptors; i++) {
+      // Create new handle for a given descriptor.
+      // Current assumption is even MetaData memory would be same
+      // Need to revisit if there is a need for own metadata memory
+      if (i != UINT(max_buf_index)) {
+        CreateSharedHandle(out_buffers[max_buf_index], descriptors[i], &out_buffers[i]);
+
+        // since we just created handle out of existing handle add it to map
+        locker_.lock();
+        handles_map_.insert(std::pair<private_handle_t const *, int>(
+            reinterpret_cast<private_handle_t const *>(out_buffers[i]), 1));
+        locker_.unlock();
+      }
+    }
+  } else {
+    // Buffer sharing is not feasible.
+    // Allocate seperate buffer for each descriptor
+    for (i = 0; i < num_descriptors; i++) {
+      if (AllocateBuffer(descriptors[i], &out_buffers[i])) {
+        return GRALLOC1_ERROR_NO_RESOURCES;
+      }
+    }
+  }
+
+  // Allocation is successful. If backstore is not shared inform the client.
+  if (!shared) {
+    return GRALLOC1_ERROR_NOT_SHARED;
+  }
+
+  return status;
+}
+
+void BufferManager::CreateSharedHandle(buffer_handle_t inbuffer, const BufferDescriptor &descriptor,
+                                       buffer_handle_t *outbuffer) {
+  private_handle_t const *input = reinterpret_cast<private_handle_t const *>(inbuffer);
+
+  // Get Buffer attributes or dimension
+  unsigned int alignedw = 0, alignedh = 0;
+  allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
+
+  // create new handle from input reference handle and given descriptor
+  int flags = GetHandleFlags(descriptor.GetFormat(), descriptor.GetProducerUsage(),
+                             descriptor.GetConsumerUsage());
+  int buffer_type = GetBufferType(descriptor.GetFormat());
+
+  // Duplicate the fds
+  private_handle_t *out_hnd = new private_handle_t(
+      dup(input->fd), input->size, flags, buffer_type, descriptor.GetFormat(), INT(alignedw),
+      INT(alignedh), dup(input->fd_metadata), input->offset_metadata, input->base_metadata,
+      descriptor.GetWidth(), descriptor.GetHeight(), descriptor.GetProducerUsage(),
+      descriptor.GetConsumerUsage());
+
+  *outbuffer = out_hnd;
+}
+
+gralloc1_error_t BufferManager::FreeBuffer(private_handle_t const *hnd) {
+  if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
+                             hnd->fd) != 0) {
+    return GRALLOC1_ERROR_BAD_HANDLE;
+  }
+
+  unsigned int meta_size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
+  if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base_metadata), meta_size,
+                             hnd->offset_metadata, hnd->fd_metadata) != 0) {
+    return GRALLOC1_ERROR_BAD_HANDLE;
+  }
+
+  // delete handle also
+  private_handle_t *handle = const_cast<private_handle_t *>(hnd);
+  delete handle;
+
+  return GRALLOC1_ERROR_NONE;
+}
+
+gralloc1_error_t BufferManager::MapBuffer(private_handle_t const *handle) {
+  private_handle_t *hnd = const_cast<private_handle_t *>(handle);
+
+  hnd->base = 0;
+  hnd->base_metadata = 0;
+  if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base), hnd->size, hnd->offset,
+                            hnd->fd) != 0) {
+    return GRALLOC1_ERROR_BAD_HANDLE;
+  }
+
+  unsigned int size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
+  if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base_metadata), size,
+                            hnd->offset_metadata, hnd->fd_metadata) != 0) {
+    return GRALLOC1_ERROR_BAD_HANDLE;
+  }
+
+  return GRALLOC1_ERROR_NONE;
+}
+
+gralloc1_error_t BufferManager::RetainBuffer(private_handle_t const *hnd) {
+  locker_.lock();
+
+  // find if this handle is already in map
+  auto it = handles_map_.find(hnd);
+  if (it != handles_map_.end()) {
+    // It's already in map, Just increment refcnt
+    // No need to mmap the memory.
+    it->second = it->second + 1;
+  } else {
+    // not present in the map. mmap and then add entry to map
+    if (MapBuffer(hnd) == GRALLOC1_ERROR_NONE) {
+      handles_map_.insert(std::pair<private_handle_t const *, int>(hnd, 1));
+    }
+  }
+
+  locker_.unlock();
+  return GRALLOC1_ERROR_NONE;
+}
+
+gralloc1_error_t BufferManager::ReleaseBuffer(private_handle_t const *hnd) {
+  locker_.lock();
+
+  // find if this handle is already in map
+  auto it = handles_map_.find(hnd);
+  if (it == handles_map_.end()) {
+    // Corrupt handle or map.
+    locker_.unlock();
+    return GRALLOC1_ERROR_BAD_HANDLE;
+  } else {
+    it->second = it->second - 1;
+  }
+
+  if (!it->second) {
+    handles_map_.erase(it);
+    FreeBuffer(hnd);
+  }
+
+  locker_.unlock();
+  return GRALLOC1_ERROR_NONE;
+}
+
+gralloc1_error_t BufferManager::LockBuffer(const private_handle_t *hnd,
+                                           gralloc1_producer_usage_t prod_usage,
+                                           gralloc1_consumer_usage_t cons_usage) {
+  gralloc1_error_t err = GRALLOC1_ERROR_NONE;
+
+  // If buffer is not meant for CPU return err
+  if (!CpuCanAccess(prod_usage, cons_usage)) {
+    return GRALLOC1_ERROR_BAD_VALUE;
+  }
+
+  if (hnd->base == 0) {
+    // we need to map for real
+    locker_.lock();
+    err = MapBuffer(hnd);
+    locker_.unlock();
+  }
+
+  // Invalidate if CPU reads in software and there are non-CPU
+  // writers. No need to do this for the metadata buffer as it is
+  // only read/written in software.
+  if (!err && (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) &&
+      (hnd->flags & private_handle_t::PRIV_FLAGS_CACHED)) {
+    if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
+                                hnd->fd, CACHE_INVALIDATE)) {
+      return GRALLOC1_ERROR_BAD_HANDLE;
+    }
+  }
+
+  // Mark the buffer to be flushed after CPU write.
+  if (!err && CpuCanWrite(prod_usage)) {
+    private_handle_t *handle = const_cast<private_handle_t *>(hnd);
+    handle->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
+  }
+
+  return err;
+}
+
+gralloc1_error_t BufferManager::UnlockBuffer(const private_handle_t *handle) {
+  gralloc1_error_t status = GRALLOC1_ERROR_NONE;
+
+  locker_.lock();
+  private_handle_t *hnd = const_cast<private_handle_t *>(handle);
+
+  if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
+    if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
+                                hnd->fd, CACHE_CLEAN) != 0) {
+      status = GRALLOC1_ERROR_BAD_HANDLE;
+    }
+    hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
+  }
+
+  locker_.unlock();
+  return status;
+}
+
+int BufferManager::GetDataAlignment(int format, gralloc1_producer_usage_t prod_usage,
+                                    gralloc1_consumer_usage_t cons_usage) {
+  int align = getpagesize();
+  if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
+    align = 8192;
+  }
+
+  if (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) {
+    if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) {
+      // The alignment here reflects qsee mmu V7L/V8L requirement
+      align = SZ_2M;
+    } else {
+      align = SECURE_ALIGN;
+    }
+  }
+
+  return align;
+}
+
+int BufferManager::GetHandleFlags(int format, gralloc1_producer_usage_t prod_usage,
+                                  gralloc1_consumer_usage_t cons_usage) {
+  int flags = 0;
+  if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_EXTERNAL_ONLY) {
+    flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY;
+  }
+
+  if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_INTERNAL_ONLY) {
+    flags |= private_handle_t::PRIV_FLAGS_INTERNAL_ONLY;
+  }
+
+  if (cons_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) {
+    flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
+  }
+
+  if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
+    flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
+  }
+
+  if (prod_usage & GRALLOC1_CONSUMER_USAGE_CAMERA) {
+    flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
+  }
+
+  if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
+    flags |= private_handle_t::PRIV_FLAGS_HW_COMPOSER;
+  }
+
+  if (prod_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) {
+    flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
+  }
+
+  if (prod_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) {
+    flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
+  }
+
+  if (allocator_->IsMacroTileEnabled(format, prod_usage, cons_usage)) {
+    flags |= private_handle_t::PRIV_FLAGS_TILE_RENDERED;
+  }
+
+  if (allocator_->IsUBwcEnabled(format, prod_usage, cons_usage)) {
+    flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+  }
+
+  if (prod_usage & (GRALLOC1_PRODUCER_USAGE_CPU_READ | GRALLOC1_PRODUCER_USAGE_CPU_WRITE)) {
+    flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
+  }
+
+  // TODO(user): is this correct???
+  if ((cons_usage &
+       (GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER | GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET)) ||
+      (prod_usage & (GRALLOC1_PRODUCER_USAGE_CAMERA | GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET))) {
+    flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
+  }
+
+  if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
+    flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER;
+  }
+
+  if (!allocator_->UseUncached(prod_usage)) {
+    flags |= private_handle_t::PRIV_FLAGS_CACHED;
+  }
+
+  return flags;
+}
+
+int BufferManager::AllocateBuffer(unsigned int size, int aligned_w, int aligned_h, int real_w,
+                                  int real_h, int format, int bufferType,
+                                  gralloc1_producer_usage_t prod_usage,
+                                  gralloc1_consumer_usage_t cons_usage, buffer_handle_t *handle) {
+  int err = 0;
+  int flags = 0;
+  size = ALIGN(size, PAGE_SIZE);
+  AllocData data;
+  data.align = (unsigned int)GetDataAlignment(format, prod_usage, cons_usage);
+  size = ALIGN(size, data.align);
+  data.size = size;
+  data.handle = (uintptr_t)handle;
+
+  // Allocate memory
+  data.uncached = allocator_->UseUncached(prod_usage);
+  err = allocator_->AllocateMem(&data, prod_usage, cons_usage);
+  if (err) {
+    ALOGE("gralloc failed to allocate err=%s", strerror(-err));
+    *handle = 0;
+    return err;
+  }
+
+  // allocate memory for MetaData
+  AllocData e_data;
+  e_data.size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
+  e_data.handle = data.handle;
+  e_data.align = (unsigned int)getpagesize();
+
+  ColorSpace_t colorSpace = ITU_R_601;
+  if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
+    colorSpace = ITU_R_601_FR;
+  }
+
+  err =
+      allocator_->AllocateMem(&e_data, GRALLOC1_PRODUCER_USAGE_NONE, GRALLOC1_CONSUMER_USAGE_NONE);
+  ALOGE_IF(err, "gralloc failed for e_daata error=%s", strerror(-err));
+
+  flags = GetHandleFlags(format, prod_usage, cons_usage);
+  flags |= data.alloc_type;
+
+  // Create handle
+  uint64_t eBaseAddr = (uint64_t)(e_data.base) + e_data.offset;
+  private_handle_t *hnd = new private_handle_t(data.fd, size, flags, bufferType, format, aligned_w,
+                                               aligned_h, e_data.fd, e_data.offset, eBaseAddr,
+                                               real_w, real_h, prod_usage, cons_usage);
+
+  hnd->offset = data.offset;
+  hnd->base = (uint64_t)(data.base) + data.offset;
+  hnd->gpuaddr = 0;
+
+  setMetaData(hnd, UPDATE_COLOR_SPACE, reinterpret_cast<void *>(&colorSpace));
+
+  *handle = hnd;
+
+  // we have just allocated the buffer & mmapped. Add to map
+  locker_.lock();
+  handles_map_.insert(std::pair<private_handle_t const *, int>(hnd, 1));
+  locker_.unlock();
+
+  return err;
+}
+
+int BufferManager::GetBufferType(int inputFormat) {
+  int buffer_type = BUFFER_TYPE_VIDEO;
+  if (IsUncompressedRGBFormat(inputFormat)) {
+    // RGB formats
+    buffer_type = BUFFER_TYPE_UI;
+  }
+
+  return buffer_type;
+}
+
+int BufferManager::AllocateBuffer(const BufferDescriptor &descriptor, buffer_handle_t *handle,
+                                  unsigned int bufferSize) {
+  if (!handle)
+    return -EINVAL;
+
+  int format = descriptor.GetFormat();
+  gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
+  gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
+
+  // Get implementation defined format
+  int gralloc_format = allocator_->GetImplDefinedFormat(prod_usage, cons_usage, format);
+
+  bool use_fb_mem = false;
+  if ((cons_usage & GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET) && map_fb_mem_) {
+    use_fb_mem = true;
+  }
+
+  if ((cons_usage & GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET) && ubwc_for_fb_) {
+    prod_usage =
+        (gralloc1_producer_usage_t)(prod_usage | GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC);
+  }
+
+  unsigned int size;
+  unsigned int alignedw, alignedh;
+  int buffer_type = GetBufferType(gralloc_format);
+  allocator_->GetBufferSizeAndDimensions(descriptor, &size, &alignedw, &alignedh);
+
+  size = (bufferSize >= size) ? bufferSize : size;
+
+  int err = 0;
+  if (use_fb_mem) {
+    // TODO(user): TBD Framebuffer specific implementation in a seperate file/class
+  } else {
+    err = AllocateBuffer(size, INT(alignedw), INT(alignedh), descriptor.GetWidth(),
+                         descriptor.GetHeight(), format, buffer_type, descriptor.GetProducerUsage(),
+                         descriptor.GetConsumerUsage(), handle);
+  }
+
+  if (err < 0) {
+    return err;
+  }
+
+  return 0;
+}
+
+gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
+  switch (operation) {
+    case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER: {
+      int fd = va_arg(args, int);
+      unsigned int size = va_arg(args, unsigned int);
+      unsigned int offset = va_arg(args, unsigned int);
+      void *base = va_arg(args, void *);
+      int width = va_arg(args, int);
+      int height = va_arg(args, int);
+      int format = va_arg(args, int);
+
+      native_handle_t **handle = va_arg(args, native_handle_t **);
+      private_handle_t *hnd = reinterpret_cast<private_handle_t *>(
+          native_handle_create(private_handle_t::kNumFds, private_handle_t::NumInts()));
+      if (hnd) {
+        hnd->magic = private_handle_t::kMagic;
+        hnd->fd = fd;
+        hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION;
+        hnd->size = size;
+        hnd->offset = offset;
+        hnd->base = uint64_t(base) + offset;
+        hnd->gpuaddr = 0;
+        hnd->width = width;
+        hnd->height = height;
+        hnd->format = format;
+        *handle = reinterpret_cast<native_handle_t *>(hnd);
+      }
+    } break;
+
+    case GRALLOC_MODULE_PERFORM_GET_STRIDE: {
+      int width = va_arg(args, int);
+      int format = va_arg(args, int);
+      int *stride = va_arg(args, int *);
+      unsigned int alignedw = 0, alignedh = 0;
+      BufferDescriptor descriptor(width, width, format);
+      allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
+      *stride = INT(alignedw);
+    } break;
+
+    case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE: {
+      private_handle_t *hnd = va_arg(args, private_handle_t *);
+      int *stride = va_arg(args, int *);
+      if (private_handle_t::validate(hnd) != 0) {
+        return GRALLOC1_ERROR_BAD_HANDLE;
+      }
+
+      MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
+      if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
+        *stride = metadata->bufferDim.sliceWidth;
+      } else {
+        *stride = hnd->width;
+      }
+    } break;
+
+    // TODO(user) : this alone should be sufficient, ask gfx to get rid of above
+    case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE: {
+      private_handle_t *hnd = va_arg(args, private_handle_t *);
+      int *stride = va_arg(args, int *);
+      int *height = va_arg(args, int *);
+      if (private_handle_t::validate(hnd) != 0) {
+        return GRALLOC1_ERROR_BAD_HANDLE;
+      }
+
+      MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
+      if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
+        *stride = metadata->bufferDim.sliceWidth;
+        *height = metadata->bufferDim.sliceHeight;
+      } else {
+        *stride = hnd->width;
+        *height = hnd->height;
+      }
+    } break;
+
+    case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES: {
+      // TODO(user): Usage is split now. take care of it from Gfx client.
+      // see if we can directly expect descriptor from gfx client.
+      int width = va_arg(args, int);
+      int height = va_arg(args, int);
+      int format = va_arg(args, int);
+      uint64_t producer_usage = va_arg(args, uint64_t);
+      uint64_t consumer_usage = va_arg(args, uint64_t);
+      gralloc1_producer_usage_t prod_usage = static_cast<gralloc1_producer_usage_t>(producer_usage);
+      gralloc1_consumer_usage_t cons_usage = static_cast<gralloc1_consumer_usage_t>(consumer_usage);
+
+      int *aligned_width = va_arg(args, int *);
+      int *aligned_height = va_arg(args, int *);
+      int *tile_enabled = va_arg(args, int *);
+      unsigned int alignedw, alignedh;
+      BufferDescriptor descriptor(width, height, format, prod_usage, cons_usage);
+      *tile_enabled = allocator_->IsUBwcEnabled(format, prod_usage, cons_usage) ||
+                      allocator_->IsMacroTileEnabled(format, prod_usage, cons_usage);
+
+      allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
+      *aligned_width = INT(alignedw);
+      *aligned_height = INT(alignedh);
+    } break;
+
+    case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE: {
+      private_handle_t *hnd = va_arg(args, private_handle_t *);
+      int *color_space = va_arg(args, int *);
+      if (private_handle_t::validate(hnd) != 0) {
+        return GRALLOC1_ERROR_BAD_HANDLE;
+      }
+      MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
+      if (metadata && metadata->operation & UPDATE_COLOR_SPACE) {
+        *color_space = metadata->colorSpace;
+      }
+    } break;
+    case GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO: {
+      private_handle_t *hnd = va_arg(args, private_handle_t *);
+      android_ycbcr *ycbcr = va_arg(args, struct android_ycbcr *);
+      if (private_handle_t::validate(hnd) != 0) {
+        return GRALLOC1_ERROR_BAD_HANDLE;
+      }
+      if (allocator_->GetYUVPlaneInfo(hnd, ycbcr)) {
+        return GRALLOC1_ERROR_UNDEFINED;
+      }
+    } break;
+
+    case GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO: {
+      private_handle_t *hnd = va_arg(args, private_handle_t *);
+      int *map_secure_buffer = va_arg(args, int *);
+      if (private_handle_t::validate(hnd) != 0) {
+        return GRALLOC1_ERROR_BAD_HANDLE;
+      }
+      MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
+      if (metadata && metadata->operation & MAP_SECURE_BUFFER) {
+        *map_secure_buffer = metadata->mapSecureBuffer;
+      } else {
+        *map_secure_buffer = 0;
+      }
+    } break;
+
+    case GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG: {
+      private_handle_t *hnd = va_arg(args, private_handle_t *);
+      int *flag = va_arg(args, int *);
+      if (private_handle_t::validate(hnd) != 0) {
+        return GRALLOC1_ERROR_BAD_HANDLE;
+      }
+      *flag = hnd->flags &private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+    } break;
+
+    case GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS: {
+      private_handle_t *hnd = va_arg(args, private_handle_t *);
+      void **rgb_data = va_arg(args, void **);
+      if (private_handle_t::validate(hnd) != 0) {
+        return GRALLOC1_ERROR_BAD_HANDLE;
+      }
+      if (allocator_->GetRgbDataAddress(hnd, rgb_data)) {
+        return GRALLOC1_ERROR_UNDEFINED;
+      }
+    } break;
+
+    default:
+      break;
+  }
+
+  return GRALLOC1_ERROR_NONE;
+}
+
+}  //  namespace gralloc1
diff --git a/libgralloc1/gr_buf_mgr.h b/libgralloc1/gr_buf_mgr.h
new file mode 100644
index 0000000..d3c0e67
--- /dev/null
+++ b/libgralloc1/gr_buf_mgr.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __GR_BUF_MGR_H__
+#define __GR_BUF_MGR_H__
+
+#include <pthread.h>
+#include <unordered_map>
+#include <mutex>
+
+#include "gralloc_priv.h"
+#include "gr_allocator.h"
+
+namespace gralloc1 {
+
+class BufferManager {
+ public:
+  BufferManager();
+  ~BufferManager();
+  bool Init();
+  gralloc1_error_t AllocateBuffers(uint32_t numDescriptors, const BufferDescriptor *descriptors,
+                                   buffer_handle_t *outBuffers);
+  gralloc1_error_t RetainBuffer(private_handle_t const *hnd);
+  gralloc1_error_t ReleaseBuffer(private_handle_t const *hnd);
+  gralloc1_error_t LockBuffer(const private_handle_t *hnd, gralloc1_producer_usage_t prod_usage,
+                              gralloc1_consumer_usage_t cons_usage);
+  gralloc1_error_t UnlockBuffer(const private_handle_t *hnd);
+  gralloc1_error_t Perform(int operation, va_list args);
+
+ private:
+  gralloc1_error_t MapBuffer(private_handle_t const *hnd);
+  gralloc1_error_t FreeBuffer(private_handle_t const *hnd);
+  int GetBufferType(int format);
+  int AllocateBuffer(const BufferDescriptor &descriptor, buffer_handle_t *handle,
+                     unsigned int bufferSize = 0);
+  int AllocateBuffer(unsigned int size, int aligned_w, int aligned_h, int real_w, int real_h,
+                     int format, int bufferType, gralloc1_producer_usage_t prod_usage,
+                     gralloc1_consumer_usage_t cons_usage, buffer_handle_t *handle);
+  int GetDataAlignment(int format, gralloc1_producer_usage_t prod_usage,
+                       gralloc1_consumer_usage_t cons_usage);
+  int GetHandleFlags(int format, gralloc1_producer_usage_t prod_usage,
+                     gralloc1_consumer_usage_t cons_usage);
+  void CreateSharedHandle(buffer_handle_t inbuffer, const BufferDescriptor &descriptor,
+                          buffer_handle_t *out_buffer);
+
+  bool map_fb_mem_ = false;
+  bool ubwc_for_fb_ = false;
+  Allocator *allocator_ = NULL;
+  std::mutex locker_;
+  std::unordered_map<private_handle_t const *, int> handles_map_ = {};
+};
+
+}  // namespace gralloc1
+
+#endif  // __GR_BUF_MGR_H__
diff --git a/libgralloc1/gr_device_impl.cpp b/libgralloc1/gr_device_impl.cpp
new file mode 100644
index 0000000..6258941
--- /dev/null
+++ b/libgralloc1/gr_device_impl.cpp
@@ -0,0 +1,458 @@
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <cutils/log.h>
+#include <sync/sync.h>
+
+#include "gr_device_impl.h"
+#include "gr_buf_descriptor.h"
+#include "gralloc_priv.h"
+#include "qd_utils.h"
+#include "qdMetaData.h"
+#include "gr_utils.h"
+
+int gralloc_device_open(const struct hw_module_t *module, const char *name, hw_device_t **device);
+
+int gralloc_device_close(struct hw_device_t *device);
+
+static struct hw_module_methods_t gralloc_module_methods = {.open = gralloc_device_open};
+
+struct hw_module_t gralloc_module = {};
+
+struct private_module_t HAL_MODULE_INFO_SYM = {
+  .base = {
+    .tag = HARDWARE_MODULE_TAG,
+    .version_major = 1,
+    .version_minor = 0,
+    .id = GRALLOC_HARDWARE_MODULE_ID,
+    .name = "Graphics Memory Module",
+    .author = "Code Aurora Forum",
+    .methods = &gralloc_module_methods,
+    .dso = 0,
+    .reserved = {0},
+  },
+};
+
+int gralloc_device_open(const struct hw_module_t *module, const char *name, hw_device_t **device) {
+  int status = -EINVAL;
+  if (!strcmp(name, GRALLOC_HARDWARE_MODULE_ID)) {
+    const private_module_t *m = reinterpret_cast<const private_module_t *>(module);
+    gralloc1::GrallocImpl * /*gralloc1_device_t*/ dev = new gralloc1::GrallocImpl(m);
+    *device = reinterpret_cast<hw_device_t *>(dev);
+
+    if (dev->Init()) {
+      status = 0;
+    } else {
+      ALOGE(" Error in opening gralloc1 device");
+      return status;
+    }
+  }
+
+  return status;
+}
+
+namespace gralloc1 {
+
+GrallocImpl::GrallocImpl(const private_module_t *module) {
+  common.tag = HARDWARE_DEVICE_TAG;
+  common.version = 1;  // TODO(user): cross check version
+  common.module = const_cast<hw_module_t *>(&module->base);
+  common.close = CloseDevice;
+  getFunction = GetFunction;
+  getCapabilities = GetCapabilities;
+}
+
+bool GrallocImpl::Init() {
+  buf_mgr_ = new BufferManager();
+
+  return buf_mgr_->Init();
+}
+
+GrallocImpl::~GrallocImpl() {
+  if (buf_mgr_) {
+    delete buf_mgr_;
+  }
+}
+
+int GrallocImpl::CloseDevice(hw_device_t *device) {
+  GrallocImpl *impl = reinterpret_cast<GrallocImpl *>(device);
+  delete impl;
+
+  return 0;
+}
+
+void GrallocImpl::GetCapabilities(struct gralloc1_device *device, uint32_t *out_count,
+                                  int32_t /*gralloc1_capability_t*/ *out_capabilities) {
+  if (!device) {
+    // Need to plan for adding more capabilities
+    if (out_capabilities == NULL) {
+      *out_count = 1;
+    } else {
+      *out_capabilities = GRALLOC1_CAPABILITY_TEST_ALLOCATE;
+    }
+  }
+
+  return;
+}
+
+gralloc1_function_pointer_t GrallocImpl::GetFunction(gralloc1_device_t *device, int32_t function) {
+  if (!device) {
+    return NULL;
+  }
+
+  switch (function) {
+    case GRALLOC1_FUNCTION_CREATE_DESCRIPTOR:
+      return reinterpret_cast<gralloc1_function_pointer_t>(CreateBufferDescriptor);
+    case GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR:
+      return reinterpret_cast<gralloc1_function_pointer_t>(DestroyBufferDescriptor);
+    case GRALLOC1_FUNCTION_SET_CONSUMER_USAGE:
+      return reinterpret_cast<gralloc1_function_pointer_t>(SetConsumerUsage);
+    case GRALLOC1_FUNCTION_SET_DIMENSIONS:
+      return reinterpret_cast<gralloc1_function_pointer_t>(SetBufferDimensions);
+    case GRALLOC1_FUNCTION_SET_FORMAT:
+      return reinterpret_cast<gralloc1_function_pointer_t>(SetColorFormat);
+    case GRALLOC1_FUNCTION_SET_PRODUCER_USAGE:
+      return reinterpret_cast<gralloc1_function_pointer_t>(SetProducerUsage);
+    case GRALLOC1_FUNCTION_GET_BACKING_STORE:
+      return reinterpret_cast<gralloc1_function_pointer_t>(GetBackingStore);
+    case GRALLOC1_FUNCTION_GET_CONSUMER_USAGE:
+      return reinterpret_cast<gralloc1_function_pointer_t>(GetConsumerUsage);
+    case GRALLOC1_FUNCTION_GET_DIMENSIONS:
+      return reinterpret_cast<gralloc1_function_pointer_t>(GetBufferDimensions);
+    case GRALLOC1_FUNCTION_GET_FORMAT:
+      return reinterpret_cast<gralloc1_function_pointer_t>(GetColorFormat);
+    case GRALLOC1_FUNCTION_GET_PRODUCER_USAGE:
+      return reinterpret_cast<gralloc1_function_pointer_t>(GetProducerUsage);
+    case GRALLOC1_FUNCTION_GET_STRIDE:
+      return reinterpret_cast<gralloc1_function_pointer_t>(GetBufferStride);
+    case GRALLOC1_FUNCTION_ALLOCATE:
+      return reinterpret_cast<gralloc1_function_pointer_t>(AllocateBuffers);
+    case GRALLOC1_FUNCTION_RETAIN:
+      return reinterpret_cast<gralloc1_function_pointer_t>(RetainBuffer);
+    case GRALLOC1_FUNCTION_RELEASE:
+      return reinterpret_cast<gralloc1_function_pointer_t>(ReleaseBuffer);
+    /*  TODO(user) :definition of flex plane is not known yet
+     *  Need to implement after clarification from Google.
+    * case GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES:
+      return reinterpret_cast<gralloc1_function_pointer_t> (; */
+    case GRALLOC1_FUNCTION_LOCK:
+      return reinterpret_cast<gralloc1_function_pointer_t>(LockBuffer);
+    /*  TODO(user) : LOCK_YCBCR changed to LOCK_FLEX but structure is not known yet.
+     *  Need to implement after clarification from Google.
+    case GRALLOC1_PFN_LOCK_FLEX:
+      return reinterpret_cast<gralloc1_function_pointer_t> (LockYCbCrBuffer;
+    */
+    case GRALLOC1_FUNCTION_UNLOCK:
+      return reinterpret_cast<gralloc1_function_pointer_t>(UnlockBuffer);
+    case GRALLOC1_FUNCTION_PERFORM:
+      return reinterpret_cast<gralloc1_function_pointer_t>(Gralloc1Perform);
+    default:
+      ALOGE("%s:Gralloc Error. Client Requested for unsupported function", __FUNCTION__);
+      return NULL;
+  }
+
+  return NULL;
+}
+
+gralloc1_error_t GrallocImpl::CheckDeviceAndDescriptor(gralloc1_device_t *device,
+                                                       gralloc1_buffer_descriptor_t descriptor) {
+  if (!device || !BUF_DESCRIPTOR(descriptor)->IsValid()) {
+    ALOGE("Gralloc Error : device=%p, descriptor=%p", (void *)device, (void *)descriptor);
+    return GRALLOC1_ERROR_BAD_DESCRIPTOR;
+  }
+
+  return GRALLOC1_ERROR_NONE;
+}
+
+gralloc1_error_t GrallocImpl::CheckDeviceAndHandle(gralloc1_device_t *device,
+                                                   buffer_handle_t buffer) {
+  const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
+  if (!device || (private_handle_t::validate(hnd) != 0)) {
+    ALOGE("Gralloc Error : device= %p, buffer-handle=%p", (void *)device, (void *)buffer);
+    return GRALLOC1_ERROR_BAD_HANDLE;
+  }
+
+  return GRALLOC1_ERROR_NONE;
+}
+
+gralloc1_error_t GrallocImpl::CreateBufferDescriptor(gralloc1_device_t *device,
+                                                     gralloc1_buffer_descriptor_t *out_descriptor) {
+  if (!device) {
+    return GRALLOC1_ERROR_BAD_DESCRIPTOR;
+  }
+
+  BufferDescriptor *descriptor = new BufferDescriptor();
+  if (descriptor == NULL) {
+    return GRALLOC1_ERROR_NO_RESOURCES;
+  }
+
+  *out_descriptor = reinterpret_cast<gralloc1_buffer_descriptor_t>(descriptor);
+
+  return GRALLOC1_ERROR_NONE;
+}
+
+gralloc1_error_t GrallocImpl::DestroyBufferDescriptor(gralloc1_device_t *device,
+                                                      gralloc1_buffer_descriptor_t descriptor) {
+  gralloc1_error_t status = CheckDeviceAndDescriptor(device, descriptor);
+  if (status == GRALLOC1_ERROR_NONE) {
+    delete reinterpret_cast<BufferDescriptor *>(descriptor);
+  }
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::SetConsumerUsage(gralloc1_device_t *device,
+                                               gralloc1_buffer_descriptor_t descriptor,
+                                               gralloc1_consumer_usage_t usage) {
+  gralloc1_error_t status = CheckDeviceAndDescriptor(device, descriptor);
+  if (status == GRALLOC1_ERROR_NONE) {
+    BUF_DESCRIPTOR(descriptor)->SetConsumerUsage(usage);
+  }
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::SetBufferDimensions(gralloc1_device_t *device,
+                                                  gralloc1_buffer_descriptor_t descriptor,
+                                                  uint32_t width, uint32_t height) {
+  gralloc1_error_t status = CheckDeviceAndDescriptor(device, descriptor);
+  if (status == GRALLOC1_ERROR_NONE) {
+    BUF_DESCRIPTOR(descriptor)->SetDimensions(INT(width), INT(height));
+  }
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::SetColorFormat(gralloc1_device_t *device,
+                                             gralloc1_buffer_descriptor_t descriptor,
+                                             int32_t format) {
+  gralloc1_error_t status = CheckDeviceAndDescriptor(device, descriptor);
+  if (status == GRALLOC1_ERROR_NONE) {
+    BUF_DESCRIPTOR(descriptor)->SetColorFormat(format);
+  }
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::SetProducerUsage(gralloc1_device_t *device,
+                                               gralloc1_buffer_descriptor_t descriptor,
+                                               gralloc1_producer_usage_t usage) {
+  gralloc1_error_t status = CheckDeviceAndDescriptor(device, descriptor);
+  if (status == GRALLOC1_ERROR_NONE) {
+    BUF_DESCRIPTOR(descriptor)->SetProducerUsage(usage);
+  }
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::GetBackingStore(gralloc1_device_t *device, buffer_handle_t buffer,
+                                              gralloc1_backing_store_t *out_backstore) {
+  if (!device || !buffer) {
+    return GRALLOC1_ERROR_BAD_HANDLE;
+  }
+
+  *out_backstore =
+      static_cast<gralloc1_backing_store_t>(PRIV_HANDLE_CONST(buffer)->GetBackingstore());
+
+  return GRALLOC1_ERROR_NONE;
+}
+
+gralloc1_error_t GrallocImpl::GetConsumerUsage(gralloc1_device_t *device, buffer_handle_t buffer,
+                                               gralloc1_consumer_usage_t *outUsage) {
+  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
+  if (status == GRALLOC1_ERROR_NONE) {
+    *outUsage = PRIV_HANDLE_CONST(buffer)->GetConsumerUsage();
+  }
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::GetBufferDimensions(gralloc1_device_t *device, buffer_handle_t buffer,
+                                                  uint32_t *outWidth, uint32_t *outHeight) {
+  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
+  if (status == GRALLOC1_ERROR_NONE) {
+    const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
+    *outWidth = UINT(hnd->GetRealWidth());
+    *outHeight = UINT(hnd->GetRealHeight());
+  }
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::GetColorFormat(gralloc1_device_t *device, buffer_handle_t buffer,
+                                             int32_t *outFormat) {
+  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
+  if (status == GRALLOC1_ERROR_NONE) {
+    *outFormat = PRIV_HANDLE_CONST(buffer)->GetColorFormat();
+  }
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::GetProducerUsage(gralloc1_device_t *device, buffer_handle_t buffer,
+                                               gralloc1_producer_usage_t *outUsage) {
+  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
+  if (status == GRALLOC1_ERROR_NONE) {
+    const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
+    *outUsage = hnd->GetProducerUsage();
+  }
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::GetBufferStride(gralloc1_device_t *device, buffer_handle_t buffer,
+                                              uint32_t *outStride) {
+  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
+  if (status == GRALLOC1_ERROR_NONE) {
+    *outStride = UINT(PRIV_HANDLE_CONST(buffer)->GetStride());
+  }
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::AllocateBuffers(gralloc1_device_t *device, uint32_t num_dptors,
+                                              const gralloc1_buffer_descriptor_t *dptors,
+                                              buffer_handle_t *outBuffers) {
+  if (!num_dptors || !dptors) {
+    return GRALLOC1_ERROR_BAD_DESCRIPTOR;
+  }
+
+  GrallocImpl const *dev = GRALLOC_IMPL(device);
+  const BufferDescriptor *descriptors = reinterpret_cast<const BufferDescriptor *>(dptors);
+  gralloc1_error_t status = dev->buf_mgr_->AllocateBuffers(num_dptors, descriptors, outBuffers);
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::RetainBuffer(gralloc1_device_t *device, buffer_handle_t buffer) {
+  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
+  if (status == GRALLOC1_ERROR_NONE) {
+    const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
+    GrallocImpl const *dev = GRALLOC_IMPL(device);
+    status = dev->buf_mgr_->RetainBuffer(hnd);
+  }
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::ReleaseBuffer(gralloc1_device_t *device, buffer_handle_t buffer) {
+  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
+  if (status == GRALLOC1_ERROR_NONE) {
+    const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
+    GrallocImpl const *dev = GRALLOC_IMPL(device);
+    status = dev->buf_mgr_->ReleaseBuffer(hnd);
+  }
+
+  return status;
+}
+
+gralloc1_error_t GrallocImpl::LockBuffer(gralloc1_device_t *device, buffer_handle_t buffer,
+                                         gralloc1_producer_usage_t prod_usage,
+                                         gralloc1_consumer_usage_t cons_usage,
+                                         const gralloc1_rect_t *region, void **out_data,
+                                         int32_t acquire_fence) {
+  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
+  if (status == GRALLOC1_ERROR_NONE && (acquire_fence > 0)) {
+    int error = sync_wait(acquire_fence, 1000);
+    if (error < 0) {
+      ALOGE("%s: sync_wait timedout! error = %s", __FUNCTION__, strerror(errno));
+      return GRALLOC1_ERROR_UNDEFINED;
+    }
+  }
+
+  const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
+  GrallocImpl const *dev = GRALLOC_IMPL(device);
+
+  // Either producer usage or consumer usage must be *_USAGE_NONE
+  if ((prod_usage != GRALLOC1_PRODUCER_USAGE_NONE) &&
+      (cons_usage != GRALLOC1_CONSUMER_USAGE_NONE)) {
+    return GRALLOC1_ERROR_BAD_VALUE;
+  }
+
+  // currently we ignore the region/rect client wants to lock
+  if (region == NULL) {
+    return GRALLOC1_ERROR_BAD_VALUE;
+  }
+
+  status = dev->buf_mgr_->LockBuffer(hnd, prod_usage, cons_usage);
+
+  *out_data = reinterpret_cast<void *>(hnd->base);
+
+  return status;
+}
+
+/*  TODO(user) : LOCK_YCBCR changed to LOCK_FLEX but structure definition is not known yet.
+ *  Need to implement after clarification from Google.
+gralloc1_error_t GrallocImpl::LockYCbCrBuffer(gralloc1_device_t* device, buffer_handle_t buffer,
+    gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage,
+    const gralloc1_rect_t* region, struct android_ycbcr* outYCbCr, int32_t* outAcquireFence) {
+  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
+
+  if (status == GRALLOC1_ERROR_NONE) {
+    void **outData = 0;
+    status = LockBuffer(device, buffer, prod_usage, cons_usage, region, outData, outAcquireFence);
+  }
+
+  if (status == GRALLOC1_ERROR_NONE) {
+    const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
+    GrallocImpl const *dev = GRALLOC_IMPL(device);
+    dev->allocator_->GetYUVPlaneInfo(hnd, outYCbCr);
+  }
+
+  return status;
+}
+ */
+
+gralloc1_error_t GrallocImpl::UnlockBuffer(gralloc1_device_t *device, buffer_handle_t buffer,
+                                           int32_t *release_fence) {
+  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
+
+  if (status != GRALLOC1_ERROR_NONE) {
+    return status;
+  }
+
+  const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
+  GrallocImpl const *dev = GRALLOC_IMPL(device);
+
+  *release_fence = -1;
+
+  return dev->buf_mgr_->UnlockBuffer(hnd);
+}
+
+gralloc1_error_t GrallocImpl::Gralloc1Perform(gralloc1_device_t *device, int operation, ...) {
+  va_list args;
+  va_start(args, operation);
+  GrallocImpl const *dev = GRALLOC_IMPL(device);
+  gralloc1_error_t err = dev->buf_mgr_->Perform(operation, args);
+  va_end(args);
+
+  return err;
+}
+
+}  // namespace gralloc1
diff --git a/libgralloc1/gr_device_impl.h b/libgralloc1/gr_device_impl.h
new file mode 100644
index 0000000..4fc8e3c
--- /dev/null
+++ b/libgralloc1/gr_device_impl.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __GR_DEVICE_IMPL_H__
+#define __GR_DEVICE_IMPL_H__
+
+#include <hardware/hardware.h>
+#include <hardware/gralloc1.h>
+#include "gr_buf_mgr.h"
+
+struct private_module_t {
+  hw_module_t base;
+};
+
+#define GRALLOC_IMPL(exp) reinterpret_cast<GrallocImpl const *>(exp)
+
+namespace gralloc1 {
+
+class GrallocImpl : public gralloc1_device_t {
+ public:
+  explicit GrallocImpl(const private_module_t *module);
+  ~GrallocImpl();
+  bool Init();
+  static int CloseDevice(hw_device_t *device);
+  static void GetCapabilities(struct gralloc1_device *device, uint32_t *out_count,
+                              int32_t * /*gralloc1_capability_t*/ out_capabilities);
+  static gralloc1_function_pointer_t GetFunction(
+      struct gralloc1_device *device, int32_t /*gralloc1_function_descriptor_t*/ descriptor);
+
+ private:
+  static inline gralloc1_error_t CheckDeviceAndDescriptor(gralloc1_device_t *device,
+                                                          gralloc1_buffer_descriptor_t descriptor);
+  static inline gralloc1_error_t CheckDeviceAndHandle(gralloc1_device_t *device,
+                                                      buffer_handle_t buffer);
+  static gralloc1_error_t CreateBufferDescriptor(gralloc1_device_t *device,
+                                                 gralloc1_buffer_descriptor_t *out_descriptor);
+  static gralloc1_error_t DestroyBufferDescriptor(gralloc1_device_t *device,
+                                                  gralloc1_buffer_descriptor_t descriptor);
+  static gralloc1_error_t SetConsumerUsage(gralloc1_device_t *device,
+                                           gralloc1_buffer_descriptor_t descriptor,
+                                           gralloc1_consumer_usage_t usage);
+  static gralloc1_error_t SetBufferDimensions(gralloc1_device_t *device,
+                                              gralloc1_buffer_descriptor_t descriptor,
+                                              uint32_t width, uint32_t height);
+  static gralloc1_error_t SetColorFormat(gralloc1_device_t *device,
+                                         gralloc1_buffer_descriptor_t descriptor, int32_t format);
+  static gralloc1_error_t SetProducerUsage(gralloc1_device_t *device,
+                                           gralloc1_buffer_descriptor_t descriptor,
+                                           gralloc1_producer_usage_t usage);
+  static gralloc1_error_t GetBackingStore(gralloc1_device_t *device, buffer_handle_t buffer,
+                                          gralloc1_backing_store_t *out_store);
+  static gralloc1_error_t GetConsumerUsage(gralloc1_device_t *device, buffer_handle_t buffer,
+                                           gralloc1_consumer_usage_t *out_usage);
+  static gralloc1_error_t GetBufferDimensions(gralloc1_device_t *device, buffer_handle_t buffer,
+                                              uint32_t *out_width, uint32_t *out_height);
+  static gralloc1_error_t GetColorFormat(gralloc1_device_t *device, buffer_handle_t descriptor,
+                                         int32_t *outFormat);
+  static gralloc1_error_t GetProducerUsage(gralloc1_device_t *device, buffer_handle_t buffer,
+                                           gralloc1_producer_usage_t *out_usage);
+  static gralloc1_error_t GetBufferStride(gralloc1_device_t *device, buffer_handle_t buffer,
+                                          uint32_t *out_stride);
+  static gralloc1_error_t AllocateBuffers(gralloc1_device_t *device, uint32_t num_dptors,
+                                          const gralloc1_buffer_descriptor_t *descriptors,
+                                          buffer_handle_t *out_buffers);
+  static gralloc1_error_t RetainBuffer(gralloc1_device_t *device, buffer_handle_t buffer);
+  static gralloc1_error_t ReleaseBuffer(gralloc1_device_t *device, buffer_handle_t buffer);
+  static gralloc1_error_t getNumFlexPlanes(gralloc1_device_t *device, buffer_handle_t buffer,
+                                           uint32_t *out_num_planes);
+  static gralloc1_error_t LockBuffer(gralloc1_device_t *device, buffer_handle_t buffer,
+                                     gralloc1_producer_usage_t prod_usage,
+                                     gralloc1_consumer_usage_t cons_usage,
+                                     const gralloc1_rect_t *access_region, void **out_data,
+                                     int32_t acquire_fence);
+  static gralloc1_error_t LockFlex(gralloc1_device_t *device, buffer_handle_t buffer,
+                                   gralloc1_producer_usage_t prod_usage,
+                                   gralloc1_consumer_usage_t cons_usage,
+                                   const gralloc1_rect_t *access_region,
+                                   struct android_flex_layout *out_flex_layout,
+                                   int32_t acquireFence);
+  /*  TODO(user) : LOCK_YCBCR changed to LOCK_FLEX but structure is not known yet.
+   *  Need to implement after clarification from Google.
+  static gralloc1_error_t LockYCbCrBuffer(gralloc1_device_t* device, buffer_handle_t buffer,
+      gralloc1_producer_usage_t producerUsage, gralloc1_consumer_usage_t consumerUsage,
+      const gralloc1_rect_t* Region, struct android_ycbcr* outYCbCr, int32_t* outAcquireFence);
+   */
+  static gralloc1_error_t UnlockBuffer(gralloc1_device_t *device, buffer_handle_t buffer,
+                                       int32_t *release_fence);
+  static gralloc1_error_t Gralloc1Perform(gralloc1_device_t *device, int operation, ...);
+
+  BufferManager *buf_mgr_ = NULL;
+};
+
+}  // namespace gralloc1
+
+#endif  // __GR_DEVICE_IMPL_H__
diff --git a/libgralloc1/gr_ion_alloc.cpp b/libgralloc1/gr_ion_alloc.cpp
new file mode 100644
index 0000000..ca93a63
--- /dev/null
+++ b/libgralloc1/gr_ion_alloc.cpp
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define DEBUG 0
+#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <cutils/log.h>
+#include <errno.h>
+#include <utils/Trace.h>
+
+#include "gralloc_priv.h"
+#include "gr_utils.h"
+#include "gr_ion_alloc.h"
+
+namespace gralloc1 {
+
+bool IonAlloc::Init() {
+  if (ion_dev_fd_ == FD_INIT) {
+    ion_dev_fd_ = open(kIonDevice, O_RDONLY);
+  }
+
+  if (ion_dev_fd_ < 0) {
+    ALOGE("%s: Failed to open ion device - %s", __FUNCTION__, strerror(errno));
+    ion_dev_fd_ = FD_INIT;
+    return false;
+  }
+
+  return true;
+}
+
+void IonAlloc::CloseIonDevice() {
+  if (ion_dev_fd_ > FD_INIT) {
+    close(ion_dev_fd_);
+  }
+
+  ion_dev_fd_ = FD_INIT;
+}
+
+int IonAlloc::AllocBuffer(AllocData *data) {
+  ATRACE_CALL();
+  int err = 0;
+  struct ion_handle_data handle_data;
+  struct ion_fd_data fd_data;
+  struct ion_allocation_data ion_alloc_data;
+  void *base = NULL;
+
+  ion_alloc_data.len = data->size;
+  ion_alloc_data.align = data->align;
+  ion_alloc_data.heap_id_mask = data->heap_id;
+  ion_alloc_data.flags = data->flags;
+  ion_alloc_data.flags |= data->uncached ? 0 : ION_FLAG_CACHED;
+
+  if (ioctl(ion_dev_fd_, INT(ION_IOC_ALLOC), &ion_alloc_data)) {
+    err = -errno;
+    ALOGE("ION_IOC_ALLOC failed with error - %s", strerror(errno));
+    return err;
+  }
+
+  fd_data.handle = ion_alloc_data.handle;
+  handle_data.handle = ion_alloc_data.handle;
+  if (ioctl(ion_dev_fd_, INT(ION_IOC_MAP), &fd_data)) {
+    err = -errno;
+    ALOGE("%s: ION_IOC_MAP failed with error - %s", __FUNCTION__, strerror(errno));
+    ioctl(ion_dev_fd_, INT(ION_IOC_FREE), &handle_data);
+    return err;
+  }
+
+  if (!(INT(data->flags) & INT(ION_SECURE))) {
+    base = mmap(0, ion_alloc_data.len, PROT_READ | PROT_WRITE, MAP_SHARED, fd_data.fd, 0);
+    if (base == MAP_FAILED) {
+      err = -errno;
+      ALOGE("%s: Failed to map the allocated memory: %s", __FUNCTION__, strerror(errno));
+      ioctl(ion_dev_fd_, INT(ION_IOC_FREE), &handle_data);
+      return err;
+    }
+  }
+
+  data->base = base;
+  data->fd = fd_data.fd;
+  ioctl(ion_dev_fd_, INT(ION_IOC_FREE), &handle_data);
+  ALOGD_IF(DEBUG, "ion: Allocated buffer base:%p size:%zu fd:%d", data->base, ion_alloc_data.len,
+           data->fd);
+
+  return 0;
+}
+
+int IonAlloc::FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd) {
+  ATRACE_CALL();
+  int err = 0;
+  ALOGD_IF(DEBUG, "ion: Freeing buffer base:%p size:%u fd:%d", base, size, fd);
+
+  if (base) {
+    err = UnmapBuffer(base, size, offset);
+  }
+  close(fd);
+
+  return err;
+}
+
+int IonAlloc::MapBuffer(void **base, unsigned int size, unsigned int offset, int fd) {
+  ATRACE_CALL();
+  int err = 0;
+  void *addr = 0;
+
+  // It is a (quirky) requirement of ION to have opened the
+  // ion fd in the process that is doing the mapping
+  addr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+  *base = addr;
+  if (addr == MAP_FAILED) {
+    err = -errno;
+    ALOGE("ion: Failed to map memory in the client: %s", strerror(errno));
+  } else {
+    ALOGD_IF(DEBUG, "ion: Mapped buffer base:%p size:%u offset:%u fd:%d", addr, size, offset, fd);
+  }
+
+  return err;
+}
+
+int IonAlloc::UnmapBuffer(void *base, unsigned int size, unsigned int /*offset*/) {
+  ATRACE_CALL();
+  ALOGD_IF(DEBUG, "ion: Unmapping buffer  base:%p size:%u", base, size);
+
+  int err = 0;
+  if (munmap(base, size)) {
+    err = -errno;
+    ALOGE("ion: Failed to unmap memory at %p : %s", base, strerror(errno));
+  }
+
+  return err;
+}
+
+int IonAlloc::CleanBuffer(void *base, unsigned int size, unsigned int offset, int fd, int op) {
+  ATRACE_CALL();
+  ATRACE_INT("operation id", op);
+  struct ion_flush_data flush_data;
+  struct ion_fd_data fd_data;
+  struct ion_handle_data handle_data;
+  int err = 0;
+
+  fd_data.fd = fd;
+  if (ioctl(ion_dev_fd_, INT(ION_IOC_IMPORT), &fd_data)) {
+    err = -errno;
+    ALOGE("%s: ION_IOC_IMPORT failed with error - %s", __FUNCTION__, strerror(errno));
+    return err;
+  }
+
+  handle_data.handle = fd_data.handle;
+  flush_data.handle = fd_data.handle;
+  flush_data.vaddr = base;
+  // offset and length are unsigned int
+  flush_data.offset = offset;
+  flush_data.length = size;
+
+  struct ion_custom_data d;
+  switch (op) {
+    case CACHE_CLEAN:
+      d.cmd = ION_IOC_CLEAN_CACHES;
+      break;
+    case CACHE_INVALIDATE:
+      d.cmd = ION_IOC_INV_CACHES;
+      break;
+    case CACHE_CLEAN_AND_INVALIDATE:
+    default:
+      d.cmd = ION_IOC_CLEAN_INV_CACHES;
+  }
+
+  d.arg = (unsigned long)(&flush_data);  // NOLINT
+  if (ioctl(ion_dev_fd_, INT(ION_IOC_CUSTOM), &d)) {
+    err = -errno;
+    ALOGE("%s: ION_IOC_CLEAN_INV_CACHES failed with error - %s", __FUNCTION__, strerror(errno));
+    ioctl(ion_dev_fd_, INT(ION_IOC_FREE), &handle_data);
+    return err;
+  }
+
+  ioctl(ion_dev_fd_, INT(ION_IOC_FREE), &handle_data);
+
+  return 0;
+}
+
+}  // namespace gralloc1
diff --git a/libgralloc1/gr_ion_alloc.h b/libgralloc1/gr_ion_alloc.h
new file mode 100644
index 0000000..baef8aa
--- /dev/null
+++ b/libgralloc1/gr_ion_alloc.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __GR_ION_ALLOC_H__
+#define __GR_ION_ALLOC_H__
+
+#include <linux/msm_ion.h>
+
+#define FD_INIT -1
+
+namespace gralloc1 {
+
+enum {
+  CACHE_CLEAN = 0x1,
+  CACHE_INVALIDATE,
+  CACHE_CLEAN_AND_INVALIDATE,
+};
+
+struct AllocData {
+  void *base = NULL;
+  int fd = -1;
+  unsigned int offset = 0;
+  unsigned int size = 0;
+  unsigned int align = 1;
+  uintptr_t handle = 0;
+  bool uncached = false;
+  unsigned int flags = 0x0;
+  unsigned int heap_id = 0x0;
+  unsigned int alloc_type = 0x0;
+};
+
+class IonAlloc {
+ public:
+  IonAlloc() { ion_dev_fd_ = FD_INIT; }
+
+  ~IonAlloc() { CloseIonDevice(); }
+
+  bool Init();
+  int AllocBuffer(AllocData *data);
+  int FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd);
+  int MapBuffer(void **base, unsigned int size, unsigned int offset, int fd);
+  int UnmapBuffer(void *base, unsigned int size, unsigned int offset);
+  int CleanBuffer(void *base, unsigned int size, unsigned int offset, int fd, int op);
+
+ private:
+  const char *kIonDevice = "/dev/ion";
+
+  int OpenIonDevice();
+  void CloseIonDevice();
+
+  int ion_dev_fd_;
+};
+
+}  // namespace gralloc1
+
+#endif  // __GR_ION_ALLOC_H__
diff --git a/libgralloc1/gr_priv_handle.h b/libgralloc1/gr_priv_handle.h
new file mode 100644
index 0000000..444fc80
--- /dev/null
+++ b/libgralloc1/gr_priv_handle.h
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __GR_PRIV_HANDLE_H__
+#define __GR_PRIV_HANDLE_H__
+
+#include <cutils/log.h>
+#include <hardware/gralloc1.h>
+
+#define GRALLOC1_FUNCTION_PERFORM 0x00001000
+
+#define DBG_HANDLE false
+
+typedef gralloc1_error_t (*GRALLOC1_PFN_PERFORM)(gralloc1_device_t *device, int operation, ...);
+
+typedef int BackStoreFd;
+
+#define PRIV_HANDLE_CONST(exp) static_cast<const private_handle_t *>(exp)
+
+struct private_handle_t : public native_handle_t {
+  // TODO(user): Moving PRIV_FLAGS to #defs & check for each PRIV_FLAG and remove unused.
+  enum {
+    PRIV_FLAGS_FRAMEBUFFER = 0x00000001,
+    PRIV_FLAGS_USES_ION = 0x00000008,
+    PRIV_FLAGS_USES_ASHMEM = 0x00000010,
+    PRIV_FLAGS_NEEDS_FLUSH = 0x00000020,
+    PRIV_FLAGS_INTERNAL_ONLY = 0x00000040,
+    PRIV_FLAGS_NON_CPU_WRITER = 0x00000080,
+    PRIV_FLAGS_NONCONTIGUOUS_MEM = 0x00000100,
+    PRIV_FLAGS_CACHED = 0x00000200,
+    PRIV_FLAGS_SECURE_BUFFER = 0x00000400,
+    PRIV_FLAGS_EXTERNAL_ONLY = 0x00002000,
+    PRIV_FLAGS_PROTECTED_BUFFER = 0x00004000,
+    PRIV_FLAGS_VIDEO_ENCODER = 0x00010000,
+    PRIV_FLAGS_CAMERA_WRITE = 0x00020000,
+    PRIV_FLAGS_CAMERA_READ = 0x00040000,
+    PRIV_FLAGS_HW_COMPOSER = 0x00080000,
+    PRIV_FLAGS_HW_TEXTURE = 0x00100000,
+    PRIV_FLAGS_ITU_R_601 = 0x00200000,     // Unused from display
+    PRIV_FLAGS_ITU_R_601_FR = 0x00400000,  // Unused from display
+    PRIV_FLAGS_ITU_R_709 = 0x00800000,     // Unused from display
+    PRIV_FLAGS_SECURE_DISPLAY = 0x01000000,
+    PRIV_FLAGS_TILE_RENDERED = 0x02000000,
+    PRIV_FLAGS_CPU_RENDERED = 0x04000000,
+    PRIV_FLAGS_UBWC_ALIGNED = 0x08000000,
+    PRIV_FLAGS_DISP_CONSUMER = 0x10000000
+  };
+
+  // file-descriptors
+  int fd;
+  int fd_metadata;
+
+  // ints
+  int magic;
+  int flags;
+  unsigned int size;
+  unsigned int offset;
+  int buffer_type;
+  uint64_t base __attribute__((aligned(8)));
+  unsigned int offset_metadata;
+
+  // The gpu address mapped into the mmu.
+  uint64_t gpuaddr __attribute__((aligned(8)));
+
+  int format;
+  int width;   // holds width of the actual buffer allocated
+  int height;  // holds height of the  actual buffer allocated
+
+  int stride;
+  uint64_t base_metadata __attribute__((aligned(8)));
+
+  // added for gralloc1
+  int real_width;   // holds width client asked to allocate
+  int real_height;  // holds height client asked to allocate// holds width client asked to allocate
+  gralloc1_producer_usage_t producer_usage __attribute__((aligned(8)));
+  gralloc1_consumer_usage_t consumer_usage __attribute__((aligned(8)));
+
+  static const int kNumFds = 2;
+  static const int kMagic = 'gmsm';
+
+  static inline int NumInts() {
+    return ((sizeof(private_handle_t) - sizeof(native_handle_t)) / sizeof(int)) - kNumFds;
+  }
+
+  private_handle_t(int fd, unsigned int size, int flags, int buf_type, int format, int width,
+                   int height, int meta_fd = -1, unsigned int meta_offset = 0,
+                   uint64_t meta_base = 0, int rw = 0, int rh = 0,
+                   gralloc1_producer_usage_t prod_usage = GRALLOC1_PRODUCER_USAGE_NONE,
+                   gralloc1_consumer_usage_t cons_usage = GRALLOC1_CONSUMER_USAGE_NONE)
+      : fd(fd),
+        fd_metadata(meta_fd),
+        magic(kMagic),
+        flags(flags),
+        size(size),
+        offset(0),
+        buffer_type(buf_type),
+        base(0),
+        offset_metadata(meta_offset),
+        gpuaddr(0),
+        format(format),
+        width(width),
+        height(height),
+        base_metadata(meta_base),
+        real_width(rw),
+        real_height(rh),
+        producer_usage(prod_usage),
+        consumer_usage(cons_usage) {
+    version = static_cast<int>(sizeof(native_handle));
+    numInts = NumInts();
+    numFds = kNumFds;
+  }
+
+  ~private_handle_t() {
+    magic = 0;
+    ALOGE_IF(DBG_HANDLE, "deleting buffer handle %p", this);
+  }
+
+  static int validate(const native_handle *h) {
+    const private_handle_t *hnd = (const private_handle_t *)h;
+    if (!h || h->version != sizeof(native_handle) || h->numInts != NumInts() ||
+        h->numFds != kNumFds || hnd->magic != kMagic) {
+      ALOGE(
+          "Invalid gralloc handle (at %p): ver(%d/%zu) ints(%d/%d) fds(%d/%d) "
+          "magic(%c%c%c%c/%c%c%c%c)",
+          h, h ? h->version : -1, sizeof(native_handle), h ? h->numInts : -1, NumInts(),
+          h ? h->numFds : -1, kNumFds,
+          hnd ? (((hnd->magic >> 24) & 0xFF) ? ((hnd->magic >> 24) & 0xFF) : '-') : '?',
+          hnd ? (((hnd->magic >> 16) & 0xFF) ? ((hnd->magic >> 16) & 0xFF) : '-') : '?',
+          hnd ? (((hnd->magic >> 8) & 0xFF) ? ((hnd->magic >> 8) & 0xFF) : '-') : '?',
+          hnd ? (((hnd->magic >> 0) & 0xFF) ? ((hnd->magic >> 0) & 0xFF) : '-') : '?',
+          (kMagic >> 24) & 0xFF, (kMagic >> 16) & 0xFF, (kMagic >> 8) & 0xFF, (kMagic >> 0) & 0xFF);
+      return -EINVAL;
+    }
+
+    return 0;
+  }
+
+  int GetRealWidth() const { return real_width; }
+
+  int GetRealHeight() const { return real_height; }
+
+  int GetColorFormat() const { return format; }
+
+  int GetStride() const {
+    // In handle we are storing aligned width after allocation.
+    // Why GetWidth & GetStride?? Are we supposed to maintain unaligned values??
+    return width;
+  }
+
+  gralloc1_consumer_usage_t GetConsumerUsage() const { return consumer_usage; }
+
+  gralloc1_producer_usage_t GetProducerUsage() const { return producer_usage; }
+
+  BackStoreFd GetBackingstore() const { return fd; }
+};
+
+#endif  // __GR_PRIV_HANDLE_H__
diff --git a/libgralloc1/gr_utils.cpp b/libgralloc1/gr_utils.cpp
new file mode 100644
index 0000000..98b6889
--- /dev/null
+++ b/libgralloc1/gr_utils.cpp
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "gr_utils.h"
+
+namespace gralloc1 {
+
+bool IsUncompressedRGBFormat(int format) {
+  switch (format) {
+    case HAL_PIXEL_FORMAT_RGBA_8888:
+    case HAL_PIXEL_FORMAT_RGBX_8888:
+    case HAL_PIXEL_FORMAT_RGB_888:
+    case HAL_PIXEL_FORMAT_RGB_565:
+    case HAL_PIXEL_FORMAT_BGR_565:
+    case HAL_PIXEL_FORMAT_BGRA_8888:
+    case HAL_PIXEL_FORMAT_RGBA_5551:
+    case HAL_PIXEL_FORMAT_RGBA_4444:
+    case HAL_PIXEL_FORMAT_R_8:
+    case HAL_PIXEL_FORMAT_RG_88:
+    case HAL_PIXEL_FORMAT_BGRX_8888:
+    case HAL_PIXEL_FORMAT_RGBA_1010102:
+    case HAL_PIXEL_FORMAT_ARGB_2101010:
+    case HAL_PIXEL_FORMAT_RGBX_1010102:
+    case HAL_PIXEL_FORMAT_XRGB_2101010:
+    case HAL_PIXEL_FORMAT_BGRA_1010102:
+    case HAL_PIXEL_FORMAT_ABGR_2101010:
+    case HAL_PIXEL_FORMAT_BGRX_1010102:
+    case HAL_PIXEL_FORMAT_XBGR_2101010:
+      return true;
+    default:
+      break;
+  }
+
+  return false;
+}
+
+bool IsCompressedRGBFormat(int format) {
+  switch (format) {
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
+      return true;
+    default:
+      break;
+  }
+
+  return false;
+}
+
+uint32_t GetBppForUncompressedRGB(int format) {
+  uint32_t bpp = 0;
+  switch (format) {
+    case HAL_PIXEL_FORMAT_RGBA_8888:
+    case HAL_PIXEL_FORMAT_RGBX_8888:
+    case HAL_PIXEL_FORMAT_BGRA_8888:
+    case HAL_PIXEL_FORMAT_BGRX_8888:
+      bpp = 4;
+      break;
+    case HAL_PIXEL_FORMAT_RGB_888:
+      bpp = 3;
+      break;
+    case HAL_PIXEL_FORMAT_RGB_565:
+    case HAL_PIXEL_FORMAT_BGR_565:
+    case HAL_PIXEL_FORMAT_RGBA_5551:
+    case HAL_PIXEL_FORMAT_RGBA_4444:
+      bpp = 2;
+      break;
+    default:
+      ALOGE("Error : %s New format request", __FUNCTION__);
+      break;
+  }
+
+  return bpp;
+}
+
+bool CpuCanAccess(gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage) {
+  return CpuCanRead(prod_usage, cons_usage) || CpuCanWrite(prod_usage);
+}
+
+bool CpuCanRead(gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage) {
+  if (prod_usage & GRALLOC1_PRODUCER_USAGE_CPU_READ) {
+    return true;
+  }
+
+  if (cons_usage & GRALLOC1_CONSUMER_USAGE_CPU_READ) {
+    return true;
+  }
+
+  return false;
+}
+
+bool CpuCanWrite(gralloc1_producer_usage_t prod_usage) {
+  if (prod_usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE) {
+    // Application intends to use CPU for rendering
+    return true;
+  }
+
+  return false;
+}
+
+}  // namespace gralloc1
diff --git a/libgralloc1/gr_utils.h b/libgralloc1/gr_utils.h
new file mode 100644
index 0000000..20f0be5
--- /dev/null
+++ b/libgralloc1/gr_utils.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __GR_UTILS_H__
+#define __GR_UTILS_H__
+
+#include "gralloc_priv.h"
+
+#define SZ_2M 0x200000
+#define SZ_1M 0x100000
+#define SZ_4K 0x1000
+
+#define SIZE_4K 4096
+#define SIZE_8K 4096
+
+#define INT(exp) static_cast<int>(exp)
+#define UINT(exp) static_cast<unsigned int>(exp)
+
+namespace gralloc1 {
+
+template <class Type1, class Type2>
+inline Type1 ALIGN(Type1 x, Type2 align) {
+  return (Type1)((x + (Type1)align - 1) & ~((Type1)align - 1));
+}
+
+bool IsCompressedRGBFormat(int format);
+bool IsUncompressedRGBFormat(int format);
+uint32_t GetBppForUncompressedRGB(int format);
+bool CpuCanAccess(gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage);
+bool CpuCanRead(gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage);
+bool CpuCanWrite(gralloc1_producer_usage_t prod_usage);
+
+}  // namespace gralloc1
+
+#endif  // __GR_UTILS_H__
diff --git a/libgralloc1/gralloc_priv.h b/libgralloc1/gralloc_priv.h
new file mode 100644
index 0000000..64cb1f5
--- /dev/null
+++ b/libgralloc1/gralloc_priv.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __GRALLOC_PRIV_H__
+#define __GRALLOC_PRIV_H__
+
+#include "gr_priv_handle.h"
+
+#define ROUND_UP_PAGESIZE(x) ((((unsigned int)(x)) + PAGE_SIZE - 1) & (~(PAGE_SIZE - 1)))
+
+/* Gralloc usage bits indicating the type of allocation that should be used */
+/* Refer gralloc1_producer_usage_t & gralloc1_consumer_usage-t in gralloc1.h */
+
+/* GRALLOC_USAGE_PRIVATE_0 is unused */
+
+/* Non linear, Universal Bandwidth Compression */
+#define GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC GRALLOC1_PRODUCER_USAGE_PRIVATE_1
+
+/* IOMMU heap comes from manually allocated pages, can be cached/uncached, is not secured */
+#define GRALLOC1_PRODUCER_USAGE_PRIVATE_IOMMU_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_2
+
+/* MM heap is a carveout heap for video, can be secured */
+#define GRALLOC1_PRODUCER_USAGE_PRIVATE_MM_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_3
+
+/* ADSP heap is a carveout heap, is not secured */
+#define GRALLOC1_PRODUCER_USAGE_PRIVATE_ADSP_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_4
+
+/* CAMERA heap is a carveout heap for camera, is not secured */
+#define GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_5
+
+/* Set this for allocating uncached memory (using O_DSYNC),
+ * cannot be used with noncontiguous heaps */
+#define GRALLOC1_PRODUCER_USAGE_PRIVATE_UNCACHED GRALLOC1_PRODUCER_USAGE_PRIVATE_6
+
+#define GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_ZSL GRALLOC1_PRODUCER_USAGE_PRIVATE_7
+
+/* Buffer content should be displayed on a primary display only */
+#define GRALLOC1_CONSUMER_USAGE_PRIVATE_INTERNAL_ONLY GRALLOC1_CONSUMER_USAGE_PRIVATE_1
+
+/* Buffer content should be displayed on an external display only */
+#define GRALLOC1_CONSUMER_USAGE_PRIVATE_EXTERNAL_ONLY GRALLOC1_CONSUMER_USAGE_PRIVATE_2
+
+/* This flag is set for WFD usecase */
+#define GRALLOC1_CONSUMER_USAGE_PRIVATE_WFD GRALLOC1_CONSUMER_USAGE_PRIVATE_3
+
+/* This flag is used for SECURE display usecase */
+#define GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY GRALLOC1_CONSUMER_USAGE_PRIVATE_4
+
+// for PERFORM API :
+// TODO(user): Move it to enum if it's ookay for gfx
+#define GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER 1
+#define GRALLOC_MODULE_PERFORM_GET_STRIDE 2
+#define GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE 3
+#define GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE 4
+#define GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES 5
+#define GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE 6
+#define GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO 7
+#define GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO 8
+#define GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG 9
+#define GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS 10
+#define GRALLOC_MODULE_PERFORM_GET_IGC 11
+#define GRALLOC_MODULE_PERFORM_SET_IGC 12
+#define GRALLOC_MODULE_PERFORM_SET_SINGLE_BUFFER_MODE 13
+
+// OEM specific HAL formats
+#define HAL_PIXEL_FORMAT_RGBA_5551 6
+#define HAL_PIXEL_FORMAT_RGBA_4444 7
+#define HAL_PIXEL_FORMAT_NV12_ENCODEABLE 0x102
+#define HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS 0x7FA30C04
+#define HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED 0x7FA30C03
+#define HAL_PIXEL_FORMAT_YCbCr_420_SP 0x109
+#define HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO 0x7FA30C01
+#define HAL_PIXEL_FORMAT_YCrCb_422_SP 0x10B
+#define HAL_PIXEL_FORMAT_R_8 0x10D
+#define HAL_PIXEL_FORMAT_RG_88 0x10E
+#define HAL_PIXEL_FORMAT_YCbCr_444_SP 0x10F
+#define HAL_PIXEL_FORMAT_YCrCb_444_SP 0x110
+#define HAL_PIXEL_FORMAT_YCrCb_422_I 0x111
+#define HAL_PIXEL_FORMAT_BGRX_8888 0x112
+#define HAL_PIXEL_FORMAT_NV21_ZSL 0x113
+#define HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS 0x114
+#define HAL_PIXEL_FORMAT_BGR_565 0x115
+
+// 10 bit
+#define HAL_PIXEL_FORMAT_RGBA_1010102 0x116
+#define HAL_PIXEL_FORMAT_ARGB_2101010 0x117
+#define HAL_PIXEL_FORMAT_RGBX_1010102 0x118
+#define HAL_PIXEL_FORMAT_XRGB_2101010 0x119
+#define HAL_PIXEL_FORMAT_BGRA_1010102 0x11A
+#define HAL_PIXEL_FORMAT_ABGR_2101010 0x11B
+#define HAL_PIXEL_FORMAT_BGRX_1010102 0x11C
+#define HAL_PIXEL_FORMAT_XBGR_2101010 0x11D
+#define HAL_PIXEL_FORMAT_YCbCr_420_P010 0x11F
+#define HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC 0x120
+
+#define HAL_PIXEL_FORMAT_INTERLACE 0x180
+
+// v4l2_fourcc('Y', 'U', 'Y', 'L'). 24 bpp YUYV 4:2:2 10 bit per component
+#define HAL_PIXEL_FORMAT_YCbCr_422_I_10BIT 0x4C595559
+
+// v4l2_fourcc('Y', 'B', 'W', 'C'). 10 bit per component. This compressed
+// format reduces the memory access bandwidth
+#define HAL_PIXEL_FORMAT_YCbCr_422_I_10BIT_COMPRESSED 0x43574259
+
+// UBWC aligned Venus format
+#define HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC 0x7FA30C06
+
+// Khronos ASTC formats
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC
+#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC
+#define HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD
+
+/* possible values for inverse gamma correction */
+#define HAL_IGC_NOT_SPECIFIED 0
+#define HAL_IGC_s_RGB 1
+
+/* possible formats for 3D content*/
+enum {
+  HAL_NO_3D = 0x0,
+  HAL_3D_SIDE_BY_SIDE_L_R = 0x1,
+  HAL_3D_SIDE_BY_SIDE_R_L = 0x2,
+  HAL_3D_TOP_BOTTOM = 0x4,
+  HAL_3D_IN_SIDE_BY_SIDE_L_R = 0x10000,  // unused legacy format
+};
+
+enum { BUFFER_TYPE_UI = 0, BUFFER_TYPE_VIDEO };
+
+#endif  // __GRALLOC_PRIV_H__
diff --git a/libmemtrack/kgsl.c b/libmemtrack/kgsl.c
index 4ad94ce..5a6b075 100644
--- a/libmemtrack/kgsl.c
+++ b/libmemtrack/kgsl.c
@@ -83,7 +83,7 @@
      * count the entry as accounted else count the entry as unaccounted.
      */
     while (1) {
-        unsigned long size;
+        unsigned long size, mapsize;
         char line_type[7];
         char flags[8];
         char line_usage[19];
@@ -94,20 +94,21 @@
         }
 
         /* Format:
-         *  gpuaddr useraddr     size    id flags       type            usage sglen
-         * 545ba000 545ba000     4096     1 -----pY     gpumem      arraybuffer     1
+         *  gpuaddr useraddr     size    id flags       type            usage sglen mapsize
+         * 545ba000 545ba000     4096     1 -----pY     gpumem      arraybuffer     1  4096
          */
-        ret = sscanf(line, "%*x %*x %lu %*d %7s %6s %18s %*d\n",
-                     &size, flags, line_type, line_usage);
-        if (ret != 4) {
+        ret = sscanf(line, "%*x %*x %lu %*d %7s %6s %18s %*d %lu\n",
+                     &size, flags, line_type, line_usage, &mapsize);
+        if (ret != 5) {
             continue;
         }
 
         if (type == MEMTRACK_TYPE_GL && strcmp(line_type, "gpumem") == 0) {
 
-            if (flags[6] == 'Y')
-                accounted_size += size;
-            else
+            if (flags[6] == 'Y') {
+                accounted_size += mapsize;
+		unaccounted_size += size - mapsize;
+	    } else
                 unaccounted_size += size;
 
         } else if (type == MEMTRACK_TYPE_GRAPHICS && strcmp(line_type, "ion") == 0) {
diff --git a/libqservice/IQService.cpp b/libqservice/IQService.cpp
index 6545427..d47f2e9 100644
--- a/libqservice/IQService.cpp
+++ b/libqservice/IQService.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2016, The Linux Foundation. All rights reserved.
  *
  * Not a Contribution, Apache license notifications and license are
  * retained for attribution purposes only.
@@ -91,6 +91,7 @@
     const bool permission = (callerUid == AID_MEDIA ||
             callerUid == AID_GRAPHICS ||
             callerUid == AID_ROOT ||
+            callerUid == AID_CAMERASERVER ||
             callerUid == AID_SYSTEM);
 
     if (code == CONNECT_HWC_CLIENT) {
diff --git a/sdm/.clang-format b/sdm/.clang-format
new file mode 100644
index 0000000..9082c40
--- /dev/null
+++ b/sdm/.clang-format
@@ -0,0 +1,13 @@
+---
+Language:        Cpp
+BasedOnStyle:  Google
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: Inline
+AllowShortBlocksOnASingleLine: false
+ColumnLimit:     100
+ConstructorInitializerAllOnOneLineOrOnePerLine: true
+ConstructorInitializerIndentWidth: 4
+DerivePointerAlignment: false
+PointerAlignment: Right
+#ReflowComments: false
diff --git a/sdm/include/utils/debug.h b/sdm/include/utils/debug.h
index 6f6b3e6..23ba181 100644
--- a/sdm/include/utils/debug.h
+++ b/sdm/include/utils/debug.h
@@ -45,6 +45,7 @@
 #define DLOGV_IF(tag, format, ...) DLOG(tag, Verbose, format, ##__VA_ARGS__)
 
 #define DLOGE(format, ...) DLOGE_IF(kTagNone, format, ##__VA_ARGS__)
+#define DLOGD(format, ...) DLOGD_IF(kTagNone, format, ##__VA_ARGS__)
 #define DLOGW(format, ...) DLOGW_IF(kTagNone, format, ##__VA_ARGS__)
 #define DLOGI(format, ...) DLOGI_IF(kTagNone, format, ##__VA_ARGS__)
 #define DLOGV(format, ...) DLOGV_IF(kTagNone, format, ##__VA_ARGS__)
diff --git a/sdm/libs/hwc/Android.mk b/sdm/libs/hwc/Android.mk
index 795ba39..259a727 100644
--- a/sdm/libs/hwc/Android.mk
+++ b/sdm/libs/hwc/Android.mk
@@ -1,6 +1,7 @@
 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
 include $(LOCAL_PATH)/../../../common.mk
+ifeq ($(use_hwc2),false)
 
 LOCAL_MODULE                  := hwcomposer.$(TARGET_BOARD_PLATFORM)
 LOCAL_MODULE_RELATIVE_PATH    := hw
@@ -30,3 +31,4 @@
                                  cpuhint.cpp
 
 include $(BUILD_SHARED_LIBRARY)
+endif
diff --git a/sdm/libs/hwc/hwc_display_primary.cpp b/sdm/libs/hwc/hwc_display_primary.cpp
index 8915bba..32ff73b 100644
--- a/sdm/libs/hwc/hwc_display_primary.cpp
+++ b/sdm/libs/hwc/hwc_display_primary.cpp
@@ -123,13 +123,11 @@
   bool isEncrypted = false;
   bool main_class_services_started = false;
   if (property_get("ro.crypto.state", cryptoState, "unencrypted")) {
-    DLOGI("%s: cryptostate= %s", __FUNCTION__, cryptoState);
     if (!strcmp(cryptoState, "encrypted")) {
       isEncrypted = true;
       if (property_get("vold.decrypt", voldDecryptState, "") &&
             !strcmp(voldDecryptState, "trigger_restart_framework"))
         main_class_services_started = true;
-      DLOGI("%s: vold= %s", __FUNCTION__, voldDecryptState);
     }
   }
   if ((!isEncrypted ||(isEncrypted && main_class_services_started)) &&
diff --git a/sdm/libs/hwc/hwc_session.cpp b/sdm/libs/hwc/hwc_session.cpp
index 8e1dd24..8df0555 100644
--- a/sdm/libs/hwc/hwc_session.cpp
+++ b/sdm/libs/hwc/hwc_session.cpp
@@ -155,9 +155,11 @@
       // HDMI is primary display. If already connected, then create it and store in
       // primary display slot. If not connected, create a NULL display for now.
       HWCDebugHandler::Get()->SetProperty("persist.sys.is_hdmi_primary", "1");
+      is_hdmi_primary_ = true;
       if (hw_disp_info.is_connected) {
         status = HWCDisplayExternal::Create(core_intf_, &hwc_procs_, qservice_,
                                             &hwc_display_[HWC_DISPLAY_PRIMARY]);
+        is_hdmi_yuv_ = IsDisplayYUV(HWC_DISPLAY_PRIMARY);
       } else {
         // NullDisplay simply closes all its fences, and advertizes a standard
         // resolution to SurfaceFlinger
@@ -165,14 +167,14 @@
                                         &hwc_display_[HWC_DISPLAY_PRIMARY]);
       }
     } else {
-        // Create and power on primary display
-        status = HWCDisplayPrimary::Create(core_intf_, buffer_allocator_, &hwc_procs_, qservice_,
-                                           &hwc_display_[HWC_DISPLAY_PRIMARY]);
+      // Create and power on primary display
+      status = HWCDisplayPrimary::Create(core_intf_, buffer_allocator_, &hwc_procs_, qservice_,
+                                         &hwc_display_[HWC_DISPLAY_PRIMARY]);
     }
   } else {
-        // Create and power on primary display
-        status = HWCDisplayPrimary::Create(core_intf_, buffer_allocator_, &hwc_procs_, qservice_,
-                                           &hwc_display_[HWC_DISPLAY_PRIMARY]);
+    // Create and power on primary display
+    status = HWCDisplayPrimary::Create(core_intf_, buffer_allocator_, &hwc_procs_, qservice_,
+                                       &hwc_display_[HWC_DISPLAY_PRIMARY]);
   }
 
   if (status) {
@@ -301,8 +303,11 @@
       // If virtual display content list is invalid, disconnect virtual display if connected.
       // If external display connection is pending, connect external display when virtual
       // display is destroyed.
+      // If HDMI is primary and the output format is YUV then ignore the virtual display
+      // content list.
       if (dpy == HWC_DISPLAY_VIRTUAL) {
-        if (hwc_session->hwc_display_[HWC_DISPLAY_EXTERNAL]) {
+        if (hwc_session->hwc_display_[HWC_DISPLAY_EXTERNAL] ||
+                (hwc_session->is_hdmi_primary_ && hwc_session->is_hdmi_yuv_)) {
           continue;
         }
 
@@ -432,9 +437,31 @@
   }
 }
 
-int HWCSession::EventControl(hwc_composer_device_1 *device, int disp, int event, int enable) {
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_);
+bool HWCSession::IsDisplayYUV(int disp) {
+  int error = -EINVAL;
+  bool is_yuv = false;
+  DisplayConfigVariableInfo attributes = {};
 
+  if (disp < 0 || disp >= HWC_NUM_DISPLAY_TYPES || !hwc_display_[disp]) {
+    DLOGE("Invalid input parameters. Display = %d", disp);
+    return is_yuv;
+  }
+
+  uint32_t active_config = 0;
+  error = hwc_display_[disp]->GetActiveDisplayConfig(&active_config);
+  if (!error) {
+    error = hwc_display_[disp]->GetDisplayAttributesForConfig(INT(active_config), &attributes);
+    if (error == 0) {
+      is_yuv = attributes.is_yuv;
+    } else {
+      DLOGW("Error querying display attributes. Display = %d, Config = %d", disp, active_config);
+    }
+  }
+
+  return is_yuv;
+}
+
+int HWCSession::EventControl(hwc_composer_device_1 *device, int disp, int event, int enable) {
   if (!device) {
     return -EINVAL;
   }
@@ -1334,7 +1361,6 @@
 int HWCSession::HotPlugHandler(bool connected) {
   int status = 0;
   bool notify_hotplug = false;
-  bool hdmi_primary = false;
 
   // To prevent sending events to client while a lock is held, acquire scope locks only within
   // below scope so that those get automatically unlocked after the scope ends.
@@ -1352,20 +1378,15 @@
     HWCDisplay *null_display = NULL;
 
     if (primary_display->GetDisplayClass() == DISPLAY_CLASS_EXTERNAL) {
-        external_display = static_cast<HWCDisplayExternal *>(hwc_display_[HWC_DISPLAY_PRIMARY]);
+      external_display = static_cast<HWCDisplayExternal *>(hwc_display_[HWC_DISPLAY_PRIMARY]);
     } else if (primary_display->GetDisplayClass() == DISPLAY_CLASS_NULL) {
-        null_display = static_cast<HWCDisplayNull *>(hwc_display_[HWC_DISPLAY_PRIMARY]);
-    }
-
-    if (external_display || null_display) {
-      hdmi_primary = true;
+      null_display = static_cast<HWCDisplayNull *>(hwc_display_[HWC_DISPLAY_PRIMARY]);
     }
 
     // If primary display connected is a NULL display, then replace it with the external display
     if (connected) {
       // If we are in HDMI as primary and the primary display just got plugged in
-      if (null_display) {
-        assert(hdmi_primary);
+      if (is_hdmi_primary_ && null_display) {
         uint32_t primary_width, primary_height;
         null_display->GetFrameBufferResolution(&primary_width, &primary_height);
         delete null_display;
@@ -1383,6 +1404,8 @@
           return -1;
         }
 
+        is_hdmi_yuv_ = IsDisplayYUV(HWC_DISPLAY_PRIMARY);
+
         // Next, go ahead and enable vsync on external display. This is expliclity required
         // because in HDMI as primary case, SurfaceFlinger may not be aware of underlying
         // changing display. and thus may not explicitly enable vsync
@@ -1395,22 +1418,22 @@
         notify_hotplug = false;
       } else {
         if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
-            DLOGE("HDMI is already connected");
-            return -1;
+          DLOGE("HDMI is already connected");
+          return -1;
         }
 
         // Connect external display if virtual display is not connected.
         // Else, defer external display connection and process it when virtual display
         // tears down; Do not notify SurfaceFlinger since connection is deferred now.
         if (!hwc_display_[HWC_DISPLAY_VIRTUAL]) {
-            status = ConnectDisplay(HWC_DISPLAY_EXTERNAL, NULL);
-            if (status) {
+          status = ConnectDisplay(HWC_DISPLAY_EXTERNAL, NULL);
+          if (status) {
             return status;
-            }
-            notify_hotplug = true;
+          }
+          notify_hotplug = true;
         } else {
-            DLOGI("Virtual display is connected, pending connection");
-            external_pending_connect_ = true;
+          DLOGI("Virtual display is connected, pending connection");
+          external_pending_connect_ = true;
         }
       }
     } else {
@@ -1418,8 +1441,7 @@
       // Due to virtual display concurrency, external display connection might be still pending
       // but hdmi got disconnected before pending connection could be processed.
 
-      if (hdmi_primary) {
-        assert(external_display != NULL);
+      if (is_hdmi_primary_ && external_display) {
         uint32_t x_res, y_res;
         external_display->GetFrameBufferResolution(&x_res, &y_res);
         // Need to manually disable VSYNC as SF is not aware of connect/disconnect cases
@@ -1444,8 +1466,8 @@
         notify_hotplug = false;
       } else {
         if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
-            status = DisconnectDisplay(HWC_DISPLAY_EXTERNAL);
-            notify_hotplug = true;
+          status = DisconnectDisplay(HWC_DISPLAY_EXTERNAL);
+          notify_hotplug = true;
         }
         external_pending_connect_ = false;
       }
diff --git a/sdm/libs/hwc/hwc_session.h b/sdm/libs/hwc/hwc_session.h
index 270751a..efcafcf 100644
--- a/sdm/libs/hwc/hwc_session.h
+++ b/sdm/libs/hwc/hwc_session.h
@@ -73,6 +73,7 @@
   static int SetActiveConfig(hwc_composer_device_1 *device, int disp, int index);
   static int SetCursorPositionAsync(hwc_composer_device_1 *device, int disp, int x, int y);
   static void CloseAcquireFds(hwc_display_contents_1_t *content_list);
+  bool IsDisplayYUV(int disp);
 
   // Uevent thread
   static void* HWCUeventThread(void *context);
@@ -140,6 +141,8 @@
   bool need_invalidate_ = false;
   int bw_mode_release_fd_ = -1;
   qService::QService *qservice_ = NULL;
+  bool is_hdmi_primary_ = false;
+  bool is_hdmi_yuv_ = false;
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/hwc2/Android.mk b/sdm/libs/hwc2/Android.mk
new file mode 100644
index 0000000..f633d7e
--- /dev/null
+++ b/sdm/libs/hwc2/Android.mk
@@ -0,0 +1,37 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+include $(LOCAL_PATH)/../../../common.mk
+
+ifeq ($(use_hwc2),true)
+
+LOCAL_MODULE                  := hwcomposer.$(TARGET_BOARD_PLATFORM)
+LOCAL_MODULE_RELATIVE_PATH    := hw
+LOCAL_MODULE_TAGS             := optional
+LOCAL_C_INCLUDES              := $(common_includes)
+
+LOCAL_CFLAGS                  := -Wno-missing-field-initializers -Wno-unused-parameter \
+                                 -std=c++11 -fcolor-diagnostics\
+                                 -DLOG_TAG=\"SDM\" $(common_flags) \
+                                 -I $(display_top)/sdm/libs/hwc
+LOCAL_CLANG                   := true
+
+LOCAL_SHARED_LIBRARIES        := libsdmcore libqservice libbinder libhardware libhardware_legacy \
+                                 libutils libcutils libsync libmemalloc libqdutils libdl \
+                                 libpowermanager libsdmutils libc++
+
+LOCAL_SRC_FILES               := hwc_session.cpp \
+                                 hwc_display.cpp \
+                                 hwc_display_primary.cpp \
+                                 hwc_display_external.cpp \
+                                 hwc_display_virtual.cpp \
+                                 ../hwc/hwc_debugger.cpp \
+                                 ../hwc/hwc_buffer_allocator.cpp \
+                                 ../hwc/hwc_buffer_sync_handler.cpp \
+                                 hwc_color_manager.cpp \
+                                 hwc_layers.cpp \
+                                 hwc_callbacks.cpp \
+                                 ../hwc/blit_engine_c2d.cpp \
+                                 ../hwc/cpuhint.cpp
+
+include $(BUILD_SHARED_LIBRARY)
+endif
diff --git a/sdm/libs/hwc2/hwc_callbacks.cpp b/sdm/libs/hwc2/hwc_callbacks.cpp
new file mode 100644
index 0000000..48ae398
--- /dev/null
+++ b/sdm/libs/hwc2/hwc_callbacks.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *    * Neither the name of The Linux Foundation. nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <utils/constants.h>
+#include <utils/debug.h>
+#include "hwc_callbacks.h"
+
+#define __CLASS__ "HWCCallbacks"
+
+namespace sdm {
+
+void HWCCallbacks::Hotplug(hwc2_display_t display, HWC2::Connection state) {
+  if (hotplug_) {
+    hotplug_(hotplug_data_, display, INT32(state));
+  }
+}
+
+void HWCCallbacks::Refresh(hwc2_display_t display) {
+  if (refresh_) {
+    refresh_(refresh_data_, display);
+  }
+}
+
+void HWCCallbacks::Vsync(hwc2_display_t display, int64_t timestamp) {
+  if (vsync_) {
+    vsync_(vsync_data_, display, timestamp);
+  }
+}
+
+HWC2::Error HWCCallbacks::Register(HWC2::Callback descriptor, hwc2_callback_data_t callback_data,
+                                   hwc2_function_pointer_t pointer) {
+  switch (descriptor) {
+    case HWC2::Callback::Hotplug:
+      hotplug_data_ = callback_data;
+      hotplug_ = reinterpret_cast<HWC2_PFN_HOTPLUG>(pointer);
+      break;
+    case HWC2::Callback::Refresh:
+      refresh_data_ = callback_data;
+      refresh_ = reinterpret_cast<HWC2_PFN_REFRESH>(pointer);
+      break;
+    case HWC2::Callback::Vsync:
+      vsync_data_ = callback_data;
+      vsync_ = reinterpret_cast<HWC2_PFN_VSYNC>(pointer);
+      break;
+    default:
+      return HWC2::Error::BadParameter;
+  }
+  return HWC2::Error::None;
+}
+
+}  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_callbacks.h b/sdm/libs/hwc2/hwc_callbacks.h
new file mode 100644
index 0000000..835a06a
--- /dev/null
+++ b/sdm/libs/hwc2/hwc_callbacks.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *    * Neither the name of The Linux Foundation. nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __HWC_CALLBACKS_H__
+#define __HWC_CALLBACKS_H__
+
+#define HWC2_INCLUDE_STRINGIFICATION
+#define HWC2_USE_CPP11
+#include <hardware/hwcomposer2.h>
+#undef HWC2_INCLUDE_STRINGIFICATION
+#undef HWC2_USE_CPP11
+
+namespace sdm {
+
+class HWCCallbacks {
+ public:
+  void Hotplug(hwc2_display_t display, HWC2::Connection state);
+  void Refresh(hwc2_display_t display);
+  void Vsync(hwc2_display_t display, int64_t timestamp);
+  HWC2::Error Register(HWC2::Callback, hwc2_callback_data_t callback_data,
+                       hwc2_function_pointer_t pointer);
+
+ private:
+  hwc2_callback_data_t hotplug_data_ = nullptr;
+  hwc2_callback_data_t refresh_data_ = nullptr;
+  hwc2_callback_data_t vsync_data_ = nullptr;
+
+  HWC2_PFN_HOTPLUG hotplug_ = nullptr;
+  HWC2_PFN_REFRESH refresh_ = nullptr;
+  HWC2_PFN_VSYNC vsync_ = nullptr;
+};
+
+}  // namespace sdm
+
+#endif  // __HWC_CALLBACKS_H__
diff --git a/sdm/libs/hwc2/hwc_color_manager.cpp b/sdm/libs/hwc2/hwc_color_manager.cpp
new file mode 100644
index 0000000..0be9724
--- /dev/null
+++ b/sdm/libs/hwc2/hwc_color_manager.cpp
@@ -0,0 +1,564 @@
+/*
+* Copyright (c) 2015 - 2016, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*     * Redistributions of source code must retain the above copyright
+*       notice, this list of conditions and the following disclaimer.
+*     * Redistributions in binary form must reproduce the above
+*       copyright notice, this list of conditions and the following
+*       disclaimer in the documentation and/or other materials provided
+*       with the distribution.
+*     * Neither the name of The Linux Foundation nor the names of its
+*       contributors may be used to endorse or promote products derived
+*       from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <dlfcn.h>
+#include <powermanager/IPowerManager.h>
+#include <cutils/sockets.h>
+#include <cutils/native_handle.h>
+#include <utils/String16.h>
+#include <binder/Parcel.h>
+#include <gralloc_priv.h>
+#include <hardware/hwcomposer.h>
+#include <hardware/hwcomposer_defs.h>
+#include <QService.h>
+
+#include <core/dump_interface.h>
+#include <utils/constants.h>
+#include <utils/debug.h>
+#include <core/buffer_allocator.h>
+#include <private/color_params.h>
+#include "hwc_buffer_allocator.h"
+#include "hwc_buffer_sync_handler.h"
+#include "hwc_session.h"
+#include "hwc_debugger.h"
+
+#define __CLASS__ "HWCColorManager"
+
+namespace sdm {
+
+uint32_t HWCColorManager::Get8BitsARGBColorValue(const PPColorFillParams &params) {
+  uint32_t argb_color = ((params.color.r << 16) & 0xff0000) | ((params.color.g) & 0xff) |
+                        ((params.color.b << 8) & 0xff00);
+  return argb_color;
+}
+
+int HWCColorManager::CreatePayloadFromParcel(const android::Parcel &in, uint32_t *disp_id,
+                                             PPDisplayAPIPayload *sink) {
+  int ret = 0;
+  uint32_t id(0);
+  uint32_t size(0);
+
+  id = UINT32(in.readInt32());
+  size = UINT32(in.readInt32());
+  if (size > 0 && size == in.dataAvail()) {
+    const void *data = in.readInplace(size);
+    const uint8_t *temp = reinterpret_cast<const uint8_t *>(data);
+
+    sink->size = size;
+    sink->payload = const_cast<uint8_t *>(temp);
+    *disp_id = id;
+  } else {
+    DLOGW("Failing size checking, size = %d", size);
+    ret = -EINVAL;
+  }
+
+  return ret;
+}
+
+void HWCColorManager::MarshallStructIntoParcel(const PPDisplayAPIPayload &data,
+                                               android::Parcel *out_parcel) {
+  out_parcel->writeInt32(INT32(data.size));
+  if (data.payload)
+    out_parcel->write(data.payload, data.size);
+}
+
+HWCColorManager *HWCColorManager::CreateColorManager() {
+  HWCColorManager *color_mgr = new HWCColorManager();
+
+  if (color_mgr) {
+    void *&color_lib = color_mgr->color_apis_lib_;
+    // Load display API interface library. And retrieve color API function tables.
+    color_lib = ::dlopen(DISPLAY_API_INTERFACE_LIBRARY_NAME, RTLD_NOW);
+    if (color_lib) {
+      color_mgr->color_apis_ = ::dlsym(color_lib, DISPLAY_API_FUNC_TABLES);
+      if (!color_mgr->color_apis_) {
+        DLOGE("Fail to retrieve = %s from %s", DISPLAY_API_FUNC_TABLES,
+              DISPLAY_API_INTERFACE_LIBRARY_NAME);
+        ::dlclose(color_lib);
+        delete color_mgr;
+        return NULL;
+      }
+    } else {
+      DLOGW("Unable to load = %s", DISPLAY_API_INTERFACE_LIBRARY_NAME);
+      delete color_mgr;
+      return NULL;
+    }
+    DLOGI("Successfully loaded %s", DISPLAY_API_INTERFACE_LIBRARY_NAME);
+
+    // Load diagclient library and invokes its entry point to pass in display APIs.
+    void *&diag_lib = color_mgr->diag_client_lib_;
+    diag_lib = ::dlopen(QDCM_DIAG_CLIENT_LIBRARY_NAME, RTLD_NOW);
+    if (diag_lib) {
+      *(reinterpret_cast<void **>(&color_mgr->qdcm_diag_init_)) =
+          ::dlsym(diag_lib, INIT_QDCM_DIAG_CLIENT_NAME);
+      *(reinterpret_cast<void **>(&color_mgr->qdcm_diag_deinit_)) =
+          ::dlsym(diag_lib, DEINIT_QDCM_DIAG_CLIENT_NAME);
+
+      if (!color_mgr->qdcm_diag_init_ || !color_mgr->qdcm_diag_deinit_) {
+        DLOGE("Fail to retrieve = %s from %s", INIT_QDCM_DIAG_CLIENT_NAME,
+              QDCM_DIAG_CLIENT_LIBRARY_NAME);
+        ::dlclose(diag_lib);
+      } else {
+        // invoke Diag Client entry point to initialize.
+        color_mgr->qdcm_diag_init_(color_mgr->color_apis_);
+        DLOGI("Successfully loaded %s and %s and diag_init'ed", DISPLAY_API_INTERFACE_LIBRARY_NAME,
+              QDCM_DIAG_CLIENT_LIBRARY_NAME);
+      }
+    } else {
+      DLOGW("Unable to load = %s", QDCM_DIAG_CLIENT_LIBRARY_NAME);
+      // only QDCM Diag client failed to be loaded and system still should function.
+    }
+  } else {
+    DLOGE("Unable to create HWCColorManager");
+    return NULL;
+  }
+
+  return color_mgr;
+}
+
+HWCColorManager::~HWCColorManager() {
+}
+
+void HWCColorManager::DestroyColorManager() {
+  if (qdcm_mode_mgr_) {
+    delete qdcm_mode_mgr_;
+  }
+  if (qdcm_diag_deinit_) {
+    qdcm_diag_deinit_();
+  }
+  if (diag_client_lib_) {
+    ::dlclose(diag_client_lib_);
+  }
+  if (color_apis_lib_) {
+    ::dlclose(color_apis_lib_);
+  }
+  delete this;
+}
+
+int HWCColorManager::EnableQDCMMode(bool enable, HWCDisplay *hwc_display) {
+  int ret = 0;
+
+  if (!qdcm_mode_mgr_) {
+    qdcm_mode_mgr_ = HWCQDCMModeManager::CreateQDCMModeMgr();
+    if (!qdcm_mode_mgr_) {
+      DLOGE("Unable to create QDCM operating mode manager.");
+      ret = -EFAULT;
+    }
+  }
+
+  if (qdcm_mode_mgr_) {
+    ret = qdcm_mode_mgr_->EnableQDCMMode(enable, hwc_display);
+  }
+
+  return ret;
+}
+
+bool HWCColorManager::SolidFillLayersPrepare(hwc_display_contents_1_t **displays,
+                                             HWCDisplay *hwc_display) {
+  SCOPE_LOCK(locker_);
+
+  // Query HWCColorManager if QDCM tool requesting SOLID_FILL mode.
+  uint32_t solid_fill_color = Get8BitsARGBColorValue(solid_fill_params_);
+  hwc_display_contents_1_t *layer_list = displays[HWC_DISPLAY_PRIMARY];
+
+  if (solid_fill_enable_ && solid_fill_layers_ && layer_list) {
+    // 1. shallow copy HWC_FRAMEBUFFER_TARGET layer info solid fill layer list.
+    solid_fill_layers_->hwLayers[1] = layer_list->hwLayers[layer_list->numHwLayers - 1];
+
+    // 2. continue the prepare<> on solid_fill_layers.
+    hwc_display->Perform(HWCDisplayPrimary::SET_QDCM_SOLID_FILL_INFO, solid_fill_color);
+    // TODO(user): Remove the display_contents generated here and
+    // use the solid fill layer support in HWC2 to set this up
+    // hwc_display->Prepare(solid_fill_layers_);  // RECT info included.
+
+    // 3. Set HWC_OVERLAY to all SF layers before returning to framework.
+    for (size_t i = 0; i < (layer_list->numHwLayers - 1); i++) {
+      hwc_layer_1_t *layer = &layer_list->hwLayers[i];
+      layer->compositionType = HWC_OVERLAY;
+    }
+
+    return true;
+  } else if (!solid_fill_enable_) {
+    hwc_display->Perform(HWCDisplayPrimary::UNSET_QDCM_SOLID_FILL_INFO, 0);
+  }
+
+  return false;
+}
+
+bool HWCColorManager::SolidFillLayersSet(hwc_display_contents_1_t **displays,
+                                         HWCDisplay *hwc_display) {
+  // Query HWCColorManager if QDCM tool requesting SOLID_FILL mode.
+  SCOPE_LOCK(locker_);
+  hwc_display_contents_1_t *layer_list = displays[HWC_DISPLAY_PRIMARY];
+  if (solid_fill_enable_ && solid_fill_layers_ && layer_list) {
+    // TODO(user): Present solid fill
+    // hwc_display->Commit(solid_fill_layers_);
+
+    // SurfaceFlinger layer stack is dropped in solid fill case and replaced with local layer stack
+    // Close acquire fence fds associated with SF layer stack
+    // Close release/retire fence fds returned along with local layer stack
+    for (size_t i = 0; i < (layer_list->numHwLayers - 1); i++) {
+      int &fence_fd = layer_list->hwLayers[i].acquireFenceFd;
+      if (fence_fd >= 0) {
+        close(fence_fd);
+        fence_fd = -1;
+      }
+    }
+
+    for (size_t i = 0; i < (solid_fill_layers_->numHwLayers - 1); i++) {
+      int &fence_fd = solid_fill_layers_->hwLayers[i].releaseFenceFd;
+      if (fence_fd >= 0) {
+        close(fence_fd);
+        fence_fd = -1;
+      }
+    }
+    if (solid_fill_layers_->retireFenceFd >= 0) {
+      close(solid_fill_layers_->retireFenceFd);
+      solid_fill_layers_->retireFenceFd = -1;
+    }
+
+    return true;
+  }
+
+  return false;
+}
+
+int HWCColorManager::CreateSolidFillLayers(HWCDisplay *hwc_display) {
+  int ret = 0;
+
+  if (!solid_fill_layers_) {
+    uint32_t size = sizeof(hwc_display_contents_1) + kNumSolidFillLayers * sizeof(hwc_layer_1_t);
+    uint32_t primary_width = 0;
+    uint32_t primary_height = 0;
+
+    hwc_display->GetPanelResolution(&primary_width, &primary_height);
+    uint8_t *buf = new uint8_t[size]();
+    // handle for solid fill layer with fd = -1.
+    private_handle_t *handle = new private_handle_t(-1, 0, private_handle_t::PRIV_FLAGS_FRAMEBUFFER,
+                                                    BUFFER_TYPE_UI, HAL_PIXEL_FORMAT_RGBA_8888,
+                                                    INT32(primary_width), INT32(primary_height));
+
+    if (!buf || !handle) {
+      DLOGE("Failed to allocate memory.");
+      if (buf)
+        delete[] buf;
+      if (handle)
+        delete handle;
+
+      return -ENOMEM;
+    }
+
+    solid_fill_layers_ = reinterpret_cast<hwc_display_contents_1 *>(buf);
+    hwc_layer_1_t &layer = solid_fill_layers_->hwLayers[0];
+    layer.handle = handle;
+  }
+
+  solid_fill_layers_->flags = HWC_GEOMETRY_CHANGED;
+  solid_fill_layers_->numHwLayers = kNumSolidFillLayers;
+  solid_fill_layers_->retireFenceFd = -1;
+  solid_fill_layers_->outbuf = NULL;
+  solid_fill_layers_->outbufAcquireFenceFd = -1;
+
+  hwc_layer_1_t &layer = solid_fill_layers_->hwLayers[0];
+  hwc_rect_t solid_fill_rect = {
+      INT(solid_fill_params_.rect.x), INT(solid_fill_params_.rect.y),
+      solid_fill_params_.rect.x + INT(solid_fill_params_.rect.width),
+      solid_fill_params_.rect.y + INT(solid_fill_params_.rect.height),
+  };
+
+  layer.compositionType = HWC_FRAMEBUFFER;
+  layer.blending = HWC_BLENDING_PREMULT;
+  layer.sourceCropf.left = solid_fill_params_.rect.x;
+  layer.sourceCropf.top = solid_fill_params_.rect.y;
+  layer.sourceCropf.right = UINT32(solid_fill_params_.rect.x) + solid_fill_params_.rect.width;
+  layer.sourceCropf.bottom = UINT32(solid_fill_params_.rect.y) + solid_fill_params_.rect.height;
+  layer.acquireFenceFd = -1;
+  layer.releaseFenceFd = -1;
+  layer.flags = 0;
+  layer.transform = 0;
+  layer.hints = 0;
+  layer.planeAlpha = 0xff;
+  layer.displayFrame = solid_fill_rect;
+  layer.visibleRegionScreen.numRects = 1;
+  layer.visibleRegionScreen.rects = &layer.displayFrame;
+  layer.surfaceDamage.numRects = 0;
+
+  return ret;
+}
+
+void HWCColorManager::DestroySolidFillLayers() {
+  if (solid_fill_layers_) {
+    hwc_layer_1_t &layer = solid_fill_layers_->hwLayers[0];
+    uint8_t *buf = reinterpret_cast<uint8_t *>(solid_fill_layers_);
+    private_handle_t const *hnd = reinterpret_cast<private_handle_t const *>(layer.handle);
+
+    if (hnd)
+      delete hnd;
+
+    if (buf)
+      delete[] buf;
+
+    solid_fill_layers_ = NULL;
+  }
+}
+
+int HWCColorManager::SetSolidFill(const void *params, bool enable, HWCDisplay *hwc_display) {
+  SCOPE_LOCK(locker_);
+  int ret = 0;
+
+  if (params) {
+    solid_fill_params_ = *reinterpret_cast<const PPColorFillParams *>(params);
+  } else {
+    solid_fill_params_ = PPColorFillParams();
+  }
+
+  if (enable) {
+    // will create solid fill layers for rendering if not present.
+    ret = CreateSolidFillLayers(hwc_display);
+  } else {
+    DestroySolidFillLayers();
+  }
+  solid_fill_enable_ = enable;
+
+  return ret;
+}
+
+int HWCColorManager::SetFrameCapture(void *params, bool enable, HWCDisplay *hwc_display) {
+  SCOPE_LOCK(locker_);
+  int ret = 0;
+
+  PPFrameCaptureData *frame_capture_data = reinterpret_cast<PPFrameCaptureData *>(params);
+
+  if (enable) {
+    std::memset(&buffer_info, 0x00, sizeof(buffer_info));
+    hwc_display->GetFrameBufferResolution(&buffer_info.buffer_config.width,
+                                          &buffer_info.buffer_config.height);
+    if (frame_capture_data->input_params.out_pix_format == PP_PIXEL_FORMAT_RGB_888) {
+      buffer_info.buffer_config.format = kFormatRGB888;
+    } else if (frame_capture_data->input_params.out_pix_format == PP_PIXEL_FORMAT_RGB_2101010) {
+      // TODO(user): Complete the implementation
+      DLOGE("RGB 10-bit format NOT supported");
+      return -EFAULT;
+    } else {
+      DLOGE("Pixel-format: %d NOT support.", frame_capture_data->input_params.out_pix_format);
+      return -EFAULT;
+    }
+
+    buffer_info.buffer_config.buffer_count = 1;
+    buffer_info.alloc_buffer_info.fd = -1;
+    buffer_info.alloc_buffer_info.stride = 0;
+    buffer_info.alloc_buffer_info.size = 0;
+
+    buffer_allocator_ = new HWCBufferAllocator();
+    if (buffer_allocator_ == NULL) {
+      DLOGE("Memory allocation for buffer_allocator_ FAILED");
+      return -ENOMEM;
+    }
+
+    ret = buffer_allocator_->AllocateBuffer(&buffer_info);
+    if (ret != 0) {
+      DLOGE("Buffer allocation failed. ret: %d", ret);
+      delete[] buffer_allocator_;
+      buffer_allocator_ = NULL;
+      return -ENOMEM;
+    } else {
+      void *buffer = mmap(NULL, buffer_info.alloc_buffer_info.size, PROT_READ | PROT_WRITE,
+                          MAP_SHARED, buffer_info.alloc_buffer_info.fd, 0);
+
+      if (buffer == MAP_FAILED) {
+        DLOGE("mmap failed. err = %d", errno);
+        frame_capture_data->buffer = NULL;
+        ret = buffer_allocator_->FreeBuffer(&buffer_info);
+        delete[] buffer_allocator_;
+        buffer_allocator_ = NULL;
+        return -EFAULT;
+      } else {
+        frame_capture_data->buffer = reinterpret_cast<uint8_t *>(buffer);
+        frame_capture_data->buffer_stride = buffer_info.alloc_buffer_info.stride;
+        frame_capture_data->buffer_size = buffer_info.alloc_buffer_info.size;
+      }
+      // TODO(user): Call HWC interface to provide the buffer and rectangle information
+    }
+  } else {
+    if (frame_capture_data->buffer != NULL) {
+      if (munmap(frame_capture_data->buffer, buffer_info.alloc_buffer_info.size) != 0) {
+        DLOGE("munmap failed. err = %d", errno);
+      }
+    }
+    if (buffer_allocator_ != NULL) {
+      std::memset(frame_capture_data, 0x00, sizeof(PPFrameCaptureData));
+      ret = buffer_allocator_->FreeBuffer(&buffer_info);
+      if (ret != 0) {
+        DLOGE("FreeBuffer failed. ret = %d", ret);
+      }
+      delete[] buffer_allocator_;
+      buffer_allocator_ = NULL;
+    }
+  }
+  return ret;
+}
+
+const HWCQDCMModeManager::ActiveFeatureCMD HWCQDCMModeManager::kActiveFeatureCMD[] = {
+    HWCQDCMModeManager::ActiveFeatureCMD("cabl:on", "cabl:off", "cabl:status", "running"),
+    HWCQDCMModeManager::ActiveFeatureCMD("ad:on", "ad:off", "ad:query:status", "running"),
+    HWCQDCMModeManager::ActiveFeatureCMD("svi:on", "svi:off", "svi:status", "running"),
+};
+
+const char *const HWCQDCMModeManager::kSocketName = "pps";
+const char *const HWCQDCMModeManager::kTagName = "surfaceflinger";
+const char *const HWCQDCMModeManager::kPackageName = "colormanager";
+
+HWCQDCMModeManager *HWCQDCMModeManager::CreateQDCMModeMgr() {
+  HWCQDCMModeManager *mode_mgr = new HWCQDCMModeManager();
+
+  if (!mode_mgr) {
+    DLOGW("No memory to create HWCQDCMModeManager.");
+    return NULL;
+  } else {
+    mode_mgr->socket_fd_ =
+        ::socket_local_client(kSocketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
+    if (mode_mgr->socket_fd_ < 0) {
+      // it should not be disastrous and we still can grab wakelock in QDCM mode.
+      DLOGW("Unable to connect to dpps socket!");
+    }
+
+    // retrieve system GPU idle timeout value for later to recover.
+    mode_mgr->entry_timeout_ = UINT32(HWCDebugHandler::GetIdleTimeoutMs());
+
+    // acquire the binder handle to Android system PowerManager for later use.
+    android::sp<android::IBinder> binder =
+        android::defaultServiceManager()->checkService(android::String16("power"));
+    if (binder == NULL) {
+      DLOGW("Application can't connect to  power manager service");
+      delete mode_mgr;
+      mode_mgr = NULL;
+    } else {
+      mode_mgr->power_mgr_ = android::interface_cast<android::IPowerManager>(binder);
+    }
+  }
+
+  return mode_mgr;
+}
+
+HWCQDCMModeManager::~HWCQDCMModeManager() {
+  if (socket_fd_ >= 0)
+    ::close(socket_fd_);
+}
+
+int HWCQDCMModeManager::AcquireAndroidWakeLock(bool enable) {
+  int ret = 0;
+
+  if (enable) {
+    if (wakelock_token_ == NULL) {
+      android::sp<android::IBinder> binder = new android::BBinder();
+      android::status_t status = power_mgr_->acquireWakeLock(
+          (kFullWakeLock | kAcquireCauseWakeup | kONAfterRelease), binder,
+          android::String16(kTagName), android::String16(kPackageName));
+      if (status == android::NO_ERROR) {
+        wakelock_token_ = binder;
+      }
+    }
+  } else {
+    if (wakelock_token_ != NULL && power_mgr_ != NULL) {
+      power_mgr_->releaseWakeLock(wakelock_token_, 0);
+      wakelock_token_.clear();
+      wakelock_token_ = NULL;
+    }
+  }
+
+  return ret;
+}
+
+int HWCQDCMModeManager::EnableActiveFeatures(bool enable,
+                                             const HWCQDCMModeManager::ActiveFeatureCMD &cmds,
+                                             bool *was_running) {
+  int ret = 0;
+  ssize_t size = 0;
+  char response[kSocketCMDMaxLength] = {
+      0,
+  };
+
+  if (socket_fd_ < 0) {
+    DLOGW("No socket connection available!");
+    return -EFAULT;
+  }
+
+  if (!enable) {  // if client requesting to disable it.
+    // query CABL status, if off, no action. keep the status.
+    size = ::write(socket_fd_, cmds.cmd_query_status, strlen(cmds.cmd_query_status));
+    if (size < 0) {
+      DLOGW("Unable to send data over socket %s", ::strerror(errno));
+      ret = -EFAULT;
+    } else {
+      size = ::read(socket_fd_, response, kSocketCMDMaxLength);
+      if (size < 0) {
+        DLOGW("Unable to read data over socket %s", ::strerror(errno));
+        ret = -EFAULT;
+      } else if (!strncmp(response, cmds.running, strlen(cmds.running))) {
+        *was_running = true;
+      }
+    }
+
+    if (*was_running) {  // if was running, it's requested to disable it.
+      size = ::write(socket_fd_, cmds.cmd_off, strlen(cmds.cmd_off));
+      if (size < 0) {
+        DLOGW("Unable to send data over socket %s", ::strerror(errno));
+        ret = -EFAULT;
+      }
+    }
+  } else {  // if was running, need enable it back.
+    if (*was_running) {
+      size = ::write(socket_fd_, cmds.cmd_on, strlen(cmds.cmd_on));
+      if (size < 0) {
+        DLOGW("Unable to send data over socket %s", ::strerror(errno));
+        ret = -EFAULT;
+      }
+    }
+  }
+
+  return ret;
+}
+
+int HWCQDCMModeManager::EnableQDCMMode(bool enable, HWCDisplay *hwc_display) {
+  int ret = 0;
+
+  ret = EnableActiveFeatures((enable ? false : true), kActiveFeatureCMD[kCABLFeature],
+                             &cabl_was_running_);
+  ret = AcquireAndroidWakeLock(enable);
+
+  // if enter QDCM mode, disable GPU fallback idle timeout.
+  if (hwc_display) {
+    uint32_t timeout = enable ? 0 : entry_timeout_;
+    hwc_display->SetIdleTimeoutMs(timeout);
+  }
+
+  return ret;
+}
+
+}  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
new file mode 100644
index 0000000..eb477d0
--- /dev/null
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -0,0 +1,1403 @@
+/*
+ * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright 2015 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 <math.h>
+#include <errno.h>
+#include <gralloc_priv.h>
+#include <gr.h>
+#include <utils/constants.h>
+#include <utils/formats.h>
+#include <utils/rect.h>
+#include <utils/debug.h>
+#include <sync/sync.h>
+#include <cutils/properties.h>
+#include <map>
+#include <string>
+#include <sstream>
+#include <utility>
+
+#include "hwc_display.h"
+#include "hwc_debugger.h"
+#include "blit_engine_c2d.h"
+
+#ifdef QTI_BSP
+#include <hardware/display_defs.h>
+#endif
+
+#define __CLASS__ "HWCDisplay"
+
+namespace sdm {
+
+static void ApplyDeInterlaceAdjustment(Layer *layer) {
+  // De-interlacing adjustment
+  if (layer->input_buffer->flags.interlace) {
+    float height = (layer->src_rect.bottom - layer->src_rect.top) / 2.0f;
+    layer->src_rect.top = ROUND_UP_ALIGN_DOWN(layer->src_rect.top / 2.0f, 2);
+    layer->src_rect.bottom = layer->src_rect.top + floorf(height);
+  }
+}
+
+HWCDisplay::HWCDisplay(CoreInterface *core_intf, HWCCallbacks *callbacks, DisplayType type,
+                       hwc2_display_t id, bool needs_blit, qService::QService *qservice,
+                       DisplayClass display_class)
+    : core_intf_(core_intf),
+      callbacks_(callbacks),
+      type_(type),
+      id_(id),
+      needs_blit_(needs_blit),
+      qservice_(qservice),
+      display_class_(display_class) {
+}
+
+int HWCDisplay::Init() {
+  DisplayError error = core_intf_->CreateDisplay(type_, this, &display_intf_);
+  if (error != kErrorNone) {
+    DLOGE("Display create failed. Error = %d display_type %d event_handler %p disp_intf %p", error,
+          type_, this, &display_intf_);
+    return -EINVAL;
+  }
+
+  int property_swap_interval = 1;
+  HWCDebugHandler::Get()->GetProperty("debug.egl.swapinterval", &property_swap_interval);
+  if (property_swap_interval == 0) {
+    swap_interval_zero_ = true;
+  }
+
+  framebuffer_config_ = new DisplayConfigVariableInfo();
+  if (!framebuffer_config_) {
+    DLOGV("Failed to allocate memory for custom framebuffer config.");
+    core_intf_->DestroyDisplay(display_intf_);
+    return -EINVAL;
+  }
+
+  client_target_ = new HWCLayer(id_);
+  int blit_enabled = 0;
+  HWCDebugHandler::Get()->GetProperty("persist.hwc.blit.comp", &blit_enabled);
+  if (needs_blit_ && blit_enabled) {
+    blit_engine_ = new BlitEngineC2d();
+    if (!blit_engine_) {
+      DLOGI("Create Blit Engine C2D failed");
+    } else {
+      if (blit_engine_->Init() < 0) {
+        DLOGI("Blit Engine Init failed, Blit Composition will not be used!!");
+        delete blit_engine_;
+        blit_engine_ = NULL;
+      }
+    }
+  }
+
+  display_intf_->GetRefreshRateRange(&min_refresh_rate_, &max_refresh_rate_);
+  current_refresh_rate_ = max_refresh_rate_;
+  DLOGI("Display created with id: %d", id_);
+  return 0;
+}
+
+int HWCDisplay::Deinit() {
+  DisplayError error = core_intf_->DestroyDisplay(display_intf_);
+  if (error != kErrorNone) {
+    DLOGE("Display destroy failed. Error = %d", error);
+    return -EINVAL;
+  }
+
+  delete framebuffer_config_;
+  delete client_target_;
+
+  if (blit_engine_) {
+    blit_engine_->DeInit();
+    delete blit_engine_;
+    blit_engine_ = NULL;
+  }
+
+  return 0;
+}
+
+// LayerStack operations
+HWC2::Error HWCDisplay::CreateLayer(hwc2_layer_t *out_layer_id) {
+  HWCLayer *layer = *layer_set_.emplace(new HWCLayer(id_));
+  layer_map_.emplace(std::make_pair(layer->GetId(), layer));
+  *out_layer_id = layer->GetId();
+  geometry_changes_ |= GeometryChanges::kAdded;
+  return HWC2::Error::None;
+}
+
+HWCLayer *HWCDisplay::GetHWCLayer(hwc2_layer_t layer_id) {
+  const auto map_layer = layer_map_.find(layer_id);
+  if (map_layer == layer_map_.end()) {
+    DLOGE("[%" PRIu64 "] GetLayer(%" PRIu64 ") failed: no such layer", id_, layer_id);
+    return nullptr;
+  } else {
+    return map_layer->second;
+  }
+}
+
+HWC2::Error HWCDisplay::DestroyLayer(hwc2_layer_t layer_id) {
+  const auto map_layer = layer_map_.find(layer_id);
+  if (map_layer == layer_map_.end()) {
+    DLOGE("[%" PRIu64 "] destroyLayer(%" PRIu64 ") failed: no such layer", id_, layer_id);
+    return HWC2::Error::BadLayer;
+  }
+  const auto layer = map_layer->second;
+  layer_map_.erase(map_layer);
+  const auto z_range = layer_set_.equal_range(layer);
+  for (auto current = z_range.first; current != z_range.second; ++current) {
+    if (*current == layer) {
+      current = layer_set_.erase(current);
+      break;
+    }
+  }
+
+  geometry_changes_ |= GeometryChanges::kRemoved;
+  return HWC2::Error::None;
+}
+
+void HWCDisplay::BuildLayerStack() {
+  layer_stack_ = LayerStack();
+  display_rect_ = LayerRect();
+  metadata_refresh_rate_ = 0;
+
+  // Add one layer for fb target
+  // TODO(user): Add blit target layers
+  for (auto hwc_layer : layer_set_) {
+    Layer *layer = hwc_layer->GetSDMLayer();
+
+    if (swap_interval_zero_) {
+      if (layer->input_buffer->acquire_fence_fd >= 0) {
+        close(layer->input_buffer->acquire_fence_fd);
+        layer->input_buffer->acquire_fence_fd = -1;
+      }
+    }
+
+    const private_handle_t *handle =
+        reinterpret_cast<const private_handle_t *>(layer->input_buffer->buffer_id);
+    if (handle) {
+      if (handle->bufferType == BUFFER_TYPE_VIDEO) {
+        layer_stack_.flags.video_present = true;
+      }
+      // TZ Protected Buffer - L1
+      if (handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
+        layer_stack_.flags.secure_present = true;
+      }
+      // Gralloc Usage Protected Buffer - L3 - which needs to be treated as Secure & avoid fallback
+      if (handle->flags & private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER) {
+        layer_stack_.flags.secure_present = true;
+      }
+    }
+
+    if (layer->flags.skip) {
+      layer_stack_.flags.skip_present = true;
+    }
+
+    if (layer->flags.cursor) {
+      layer_stack_.flags.cursor_present = true;
+    }
+    // TODO(user): Move to a getter if this is needed at other places
+    hwc_rect_t scaled_display_frame = {INT(layer->dst_rect.left), INT(layer->dst_rect.top),
+                                       INT(layer->dst_rect.right), INT(layer->dst_rect.bottom)};
+    ScaleDisplayFrame(&scaled_display_frame);
+    ApplyScanAdjustment(&scaled_display_frame);
+    hwc_layer->SetLayerDisplayFrame(scaled_display_frame);
+    ApplyDeInterlaceAdjustment(layer);
+    // TODO(user): Verify if we still need to configure the solid fill layerbuffer,
+    // it should already have a valid dst_rect by this point
+
+    if (layer->frame_rate > metadata_refresh_rate_) {
+      metadata_refresh_rate_ = SanitizeRefreshRate(layer->frame_rate);
+    } else {
+      layer->frame_rate = current_refresh_rate_;
+    }
+    display_rect_ = Union(display_rect_, layer->dst_rect);
+    // TODO(user): Set correctly when implementing caching
+    layer->flags.updating = true;
+    geometry_changes_ |= hwc_layer->GetGeometryChanges();
+
+    layer_stack_.layers.push_back(layer);
+  }
+  layer_stack_.flags.geometry_changed = UINT32(geometry_changes_ > 0);
+  // Append client target to the layer stack
+  layer_stack_.layers.push_back(client_target_->GetSDMLayer());
+}
+
+HWC2::Error HWCDisplay::SetLayerZOrder(hwc2_layer_t layer_id, uint32_t z) {
+  const auto map_layer = layer_map_.find(layer_id);
+  if (map_layer == layer_map_.end()) {
+    DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer", id_);
+    return HWC2::Error::BadLayer;
+  }
+
+  const auto layer = map_layer->second;
+  const auto z_range = layer_set_.equal_range(layer);
+  bool layer_on_display = false;
+  for (auto current = z_range.first; current != z_range.second; ++current) {
+    if (*current == layer) {
+      if ((*current)->GetZ() == z) {
+        // Don't change anything if the Z hasn't changed
+        return HWC2::Error::None;
+      }
+      current = layer_set_.erase(current);
+      layer_on_display = true;
+      break;
+    }
+  }
+
+  if (!layer_on_display) {
+    DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer on display", id_);
+    return HWC2::Error::BadLayer;
+  }
+
+  layer->SetLayerZOrder(z);
+  layer_set_.emplace(layer);
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCDisplay::SetVsyncEnabled(HWC2::Vsync enabled) {
+  DLOGV("Display ID: %d enabled: %s", id_, to_string(enabled).c_str());
+  DisplayError error = kErrorNone;
+
+  if (shutdown_pending_) {
+    return HWC2::Error::None;
+  }
+
+  bool state;
+  if (enabled == HWC2::Vsync::Enable)
+    state = true;
+  else if (enabled == HWC2::Vsync::Disable)
+    state = false;
+  else
+    return HWC2::Error::BadParameter;
+
+  error = display_intf_->SetVSyncState(state);
+
+  if (error != kErrorNone) {
+    if (error == kErrorShutDown) {
+      shutdown_pending_ = true;
+      return HWC2::Error::None;
+    }
+    DLOGE("Failed. enabled = %s, error = %d", to_string(enabled).c_str(), error);
+    return HWC2::Error::BadDisplay;
+  }
+
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCDisplay::SetPowerMode(HWC2::PowerMode mode) {
+  DLOGV("display = %d, mode = %s", id_, to_string(mode).c_str());
+  DisplayState state = kStateOff;
+  bool flush_on_error = flush_on_error_;
+
+  if (shutdown_pending_) {
+    return HWC2::Error::None;
+  }
+
+  switch (mode) {
+    case HWC2::PowerMode::Off:
+      // During power off, all of the buffers are released.
+      // Do not flush until a buffer is successfully submitted again.
+      flush_on_error = false;
+      state = kStateOff;
+      break;
+    case HWC2::PowerMode::On:
+      state = kStateOn;
+      last_power_mode_ = HWC2::PowerMode::On;
+      break;
+    case HWC2::PowerMode::Doze:
+      state = kStateDoze;
+      last_power_mode_ = HWC2::PowerMode::Doze;
+      break;
+    case HWC2::PowerMode::DozeSuspend:
+      state = kStateDozeSuspend;
+      last_power_mode_ = HWC2::PowerMode::DozeSuspend;
+      break;
+    default:
+      return HWC2::Error::BadParameter;
+  }
+
+  DisplayError error = display_intf_->SetDisplayState(state);
+  if (error == kErrorNone) {
+    flush_on_error_ = flush_on_error;
+  } else {
+    if (error == kErrorShutDown) {
+      shutdown_pending_ = true;
+      return HWC2::Error::None;
+    }
+    DLOGE("Set state failed. Error = %d", error);
+    return HWC2::Error::BadParameter;
+  }
+
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCDisplay::GetClientTargetSupport(uint32_t width, uint32_t height, int32_t format,
+                                               int32_t dataspace) {
+  // TODO(user): Support scaled configurations, other formats and other dataspaces
+  if (format != HAL_PIXEL_FORMAT_RGBA_8888 || dataspace != HAL_DATASPACE_UNKNOWN ||
+      width != framebuffer_config_->x_pixels || height != framebuffer_config_->y_pixels) {
+    return HWC2::Error::Unsupported;
+  } else {
+    return HWC2::Error::None;
+  }
+}
+
+HWC2::Error HWCDisplay::GetDisplayConfigs(uint32_t *out_num_configs, hwc2_config_t *out_configs) {
+  // TODO(user): Actually handle multiple configs
+  if (out_configs == nullptr) {
+    *out_num_configs = 1;
+  } else {
+    *out_num_configs = 1;
+    out_configs[0] = 0;
+  }
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCDisplay::GetDisplayAttribute(hwc2_config_t config, HWC2::Attribute attribute,
+                                            int32_t *out_value) {
+  DisplayConfigVariableInfo variable_config = *framebuffer_config_;
+
+  switch (attribute) {
+    case HWC2::Attribute::VsyncPeriod:
+      *out_value = INT32(variable_config.vsync_period_ns);
+      break;
+    case HWC2::Attribute::Width:
+      *out_value = INT32(variable_config.x_pixels);
+      break;
+    case HWC2::Attribute::Height:
+      *out_value = INT32(variable_config.y_pixels);
+      break;
+    case HWC2::Attribute::DpiX:
+      *out_value = INT32(variable_config.x_dpi * 1000.0f);
+      break;
+    case HWC2::Attribute::DpiY:
+      *out_value = INT32(variable_config.y_dpi * 1000.0f);
+      break;
+    default:
+      DLOGW("Spurious attribute type = %s", to_string(attribute).c_str());
+      return HWC2::Error::BadConfig;
+  }
+
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCDisplay::GetDisplayName(uint32_t *out_size, char *out_name) {
+  // TODO(user): Get panel name and EDID name and populate it here
+  if (out_name == nullptr) {
+    *out_size = 32;
+  } else {
+    std::string name;
+    switch (id_) {
+      case HWC_DISPLAY_PRIMARY:
+        name = "Primary Display";
+        break;
+      case HWC_DISPLAY_EXTERNAL:
+        name = "External Display";
+        break;
+      case HWC_DISPLAY_VIRTUAL:
+        name = "Virtual Display";
+        break;
+      default:
+        name = "Unknown";
+        break;
+    }
+    std::strncpy(out_name, name.c_str(), name.size());
+    *out_size = UINT32(name.size());
+  }
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCDisplay::GetDisplayType(int32_t *out_type) {
+  if (out_type != nullptr) {
+    if (id_ == HWC_DISPLAY_VIRTUAL) {
+      *out_type = HWC2_DISPLAY_TYPE_VIRTUAL;
+    } else {
+      *out_type = HWC2_DISPLAY_TYPE_PHYSICAL;
+    }
+    return HWC2::Error::None;
+  } else {
+    return HWC2::Error::BadParameter;
+  }
+}
+
+// TODO(user): Store configurations and hook them up here
+HWC2::Error HWCDisplay::GetActiveConfig(hwc2_config_t *out_config) {
+  if (out_config != nullptr) {
+    *out_config = 0;
+    return HWC2::Error::None;
+  } else {
+    return HWC2::Error::BadParameter;
+  }
+}
+
+HWC2::Error HWCDisplay::SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
+                                        int32_t dataspace) {
+  // TODO(user): SurfaceFlinger gives us a null pointer here when doing full SDE composition
+  // The error is problematic for layer caching as it would overwrite our cached client target.
+  // Reported bug 28569722 to resolve this.
+  // For now, continue to use the last valid buffer reported to us for layer caching.
+  if (target == nullptr) {
+    return HWC2::Error::None;
+  }
+  client_target_->SetLayerBuffer(target, acquire_fence);
+  // Ignoring dataspace for now
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCDisplay::SetActiveConfig(hwc2_config_t config) {
+  // We have only one config right now - do nothing
+  return HWC2::Error::None;
+}
+
+void HWCDisplay::SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type) {
+  dump_frame_count_ = count;
+  dump_frame_index_ = 0;
+  dump_input_layers_ = ((bit_mask_layer_type & (1 << INPUT_LAYER_DUMP)) != 0);
+
+  if (blit_engine_) {
+    blit_engine_->SetFrameDumpConfig(count);
+  }
+
+  DLOGI("num_frame_dump %d, input_layer_dump_enable %d", dump_frame_count_, dump_input_layers_);
+}
+
+HWC2::PowerMode HWCDisplay::GetLastPowerMode() {
+  return last_power_mode_;
+}
+
+DisplayError HWCDisplay::VSync(const DisplayEventVSync &vsync) {
+  callbacks_->Vsync(id_, vsync.timestamp);
+  return kErrorNone;
+}
+
+DisplayError HWCDisplay::Refresh() {
+  return kErrorNotSupported;
+}
+
+DisplayError HWCDisplay::CECMessage(char *message) {
+  if (qservice_) {
+    qservice_->onCECMessageReceived(message, 0);
+  } else {
+    DLOGW("Qservice instance not available.");
+  }
+
+  return kErrorNone;
+}
+
+HWC2::Error HWCDisplay::PrepareLayerStack(uint32_t *out_num_types, uint32_t *out_num_requests) {
+  layer_changes_.clear();
+  layer_requests_.clear();
+  if (shutdown_pending_) {
+    return HWC2::Error::BadDisplay;
+  }
+
+  if (!skip_prepare_) {
+    DisplayError error = display_intf_->Prepare(&layer_stack_);
+    if (error != kErrorNone) {
+      if (error == kErrorShutDown) {
+        shutdown_pending_ = true;
+      } else if (error != kErrorPermission) {
+        DLOGE("Prepare failed. Error = %d", error);
+        // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
+        // so that previous buffer and fences are released, and override the error.
+        flush_ = true;
+      }
+      return HWC2::Error::BadDisplay;
+    }
+  } else {
+    // Skip is not set
+    MarkLayersForGPUBypass();
+    skip_prepare_ = false;
+    DLOGI("SecureDisplay %s, Skip Prepare/Commit and Flush",
+          secure_display_active_ ? "Starting" : "Stopping");
+    flush_ = true;
+  }
+
+  // If current draw cycle has different set of layers updating in comparison to previous cycle,
+  // cache content using GPU again.
+  // If set of updating layers remains same, use cached buffer and replace layers marked for GPU
+  // composition with SDE so that SurfaceFlinger does not compose them. Set cache inuse here.
+  bool needs_fb_refresh = NeedsFrameBufferRefresh();
+  for (auto hwc_layer : layer_set_) {
+    Layer *layer = hwc_layer->GetSDMLayer();
+    LayerComposition &composition = layer->composition;
+
+    if ((composition == kCompositionSDE) || (composition == kCompositionHybrid) ||
+        (composition == kCompositionBlit)) {
+      layer_requests_[hwc_layer->GetId()] = HWC2::LayerRequest::ClearClientTarget;
+    }
+
+    if (!needs_fb_refresh && composition == kCompositionGPU) {
+      composition = kCompositionSDE;
+    }
+    HWC2::Composition current_hwc_composition  = hwc_layer->GetCompositionType();
+    // Convert the SDM layer composition to HWC2 type
+    hwc_layer->SetComposition(composition);
+    // Update the changes list only if the HWC2 comp type changed from the previous cycle
+    if (current_hwc_composition != hwc_layer->GetCompositionType()) {
+      layer_changes_[hwc_layer->GetId()] = hwc_layer->GetCompositionType();
+    }
+  }
+  *out_num_types = UINT32(layer_changes_.size());
+  *out_num_requests = UINT32(layer_requests_.size());
+  validated_ = true;
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCDisplay::AcceptDisplayChanges() {
+  if (!validated_) {
+    return HWC2::Error::NotValidated;
+  }
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCDisplay::GetChangedCompositionTypes(uint32_t *out_num_elements,
+                                                   hwc2_layer_t *out_layers, int32_t *out_types) {
+  *out_num_elements = UINT32(layer_changes_.size());
+  if (out_layers != nullptr && out_types != nullptr) {
+    int i = 0;
+    for (auto change : layer_changes_) {
+      out_layers[i] = change.first;
+      out_types[i] = INT32(change.second);
+      i++;
+    }
+  }
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCDisplay::GetReleaseFences(uint32_t *out_num_elements, hwc2_layer_t *out_layers,
+                                         int32_t *out_fences) {
+  if (out_layers != nullptr && out_fences != nullptr) {
+    int i = 0;
+    for (auto hwc_layer : layer_set_) {
+      out_layers[i] = hwc_layer->GetId();
+      out_fences[i] = hwc_layer->PopReleaseFence();
+      i++;
+    }
+  }
+  *out_num_elements = UINT32(layer_set_.size());
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCDisplay::GetDisplayRequests(int32_t *out_display_requests,
+                                           uint32_t *out_num_elements, hwc2_layer_t *out_layers,
+                                           int32_t *out_layer_requests) {
+  // No display requests for now
+  // Use for sharing blit buffers and
+  // writing wfd buffer directly to output if there is full GPU composition
+  // and no color conversion needed
+  if (!validated_) {
+    DLOGW("Display is not validated");
+    return HWC2::Error::NotValidated;
+  }
+  *out_display_requests = 0;
+  *out_num_elements = UINT32(layer_requests_.size());
+  if (out_layers != nullptr && out_layer_requests != nullptr) {
+    int i = 0;
+    for (auto &request : layer_requests_) {
+      out_layers[i] = request.first;
+      out_layer_requests[i] = INT32(request.second);
+      i++;
+    }
+  }
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCDisplay::CommitLayerStack(void) {
+  if (shutdown_pending_) {
+    return HWC2::Error::None;
+  }
+
+  if (!validated_) {
+    DLOGW("Display is not validated");
+    return HWC2::Error::NotValidated;
+  }
+
+  DumpInputBuffers();
+
+  if (!flush_) {
+    DisplayError error = kErrorUndefined;
+    error = display_intf_->Commit(&layer_stack_);
+    validated_ = false;
+
+    if (error == kErrorNone) {
+      // A commit is successfully submitted, start flushing on failure now onwards.
+      flush_on_error_ = true;
+    } else {
+      if (error == kErrorShutDown) {
+        shutdown_pending_ = true;
+        return HWC2::Error::Unsupported;
+      } else if (error != kErrorPermission) {
+        DLOGE("Commit failed. Error = %d", error);
+        // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
+        // so that previous buffer and fences are released, and override the error.
+        flush_ = true;
+      }
+    }
+  }
+
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCDisplay::PostCommitLayerStack(int32_t *out_retire_fence) {
+  auto status = HWC2::Error::None;
+
+  // Do no call flush on errors, if a successful buffer is never submitted.
+  if (flush_ && flush_on_error_) {
+    display_intf_->Flush();
+  }
+
+  // TODO(user): No way to set the client target release fence on SF
+  int32_t &client_target_release_fence =
+      client_target_->GetSDMLayer()->input_buffer->release_fence_fd;
+  if (client_target_release_fence >= 0) {
+    close(client_target_release_fence);
+    client_target_release_fence = -1;
+  }
+
+  for (auto hwc_layer : layer_set_) {
+    hwc_layer->ResetGeometryChanges();
+    Layer *layer = hwc_layer->GetSDMLayer();
+    LayerBuffer *layer_buffer = layer->input_buffer;
+
+    if (!flush_) {
+      // If swapinterval property is set to 0 or for single buffer layers, do not update f/w
+      // release fences and discard fences from driver
+      if (swap_interval_zero_ || layer->flags.single_buffer) {
+        close(layer_buffer->release_fence_fd);
+        layer_buffer->release_fence_fd = -1;
+      } else if (layer->composition != kCompositionGPU) {
+        hwc_layer->PushReleaseFence(layer_buffer->release_fence_fd);
+      }
+    }
+
+    if (layer_buffer->acquire_fence_fd >= 0) {
+      close(layer_buffer->acquire_fence_fd);
+      layer_buffer->acquire_fence_fd = -1;
+    }
+  }
+
+  if (!flush_) {
+    // if swapinterval property is set to 0 then close and reset the list retire fence
+    if (swap_interval_zero_) {
+      close(layer_stack_.retire_fence_fd);
+      layer_stack_.retire_fence_fd = -1;
+    }
+    *out_retire_fence = stored_retire_fence_;
+    stored_retire_fence_ = layer_stack_.retire_fence_fd;
+
+    if (dump_frame_count_) {
+      dump_frame_count_--;
+      dump_frame_index_++;
+    }
+  }
+  geometry_changes_ = GeometryChanges::kNone;
+  flush_ = false;
+
+  return status;
+}
+
+bool HWCDisplay::NeedsFrameBufferRefresh(void) {
+  // Frame buffer needs to be refreshed for the following reasons:
+  // 1. Any layer is marked skip in the current layer stack.
+  // 2. Any layer is added/removed/layer properties changes in the current layer stack.
+  // 3. Any layer handle is changed and it is marked for GPU composition
+  // 4. Any layer's current composition is different from previous composition.
+  if (layer_stack_.flags.skip_present || layer_stack_.flags.geometry_changed) {
+    return true;
+  }
+
+  for (auto layer : layer_stack_.layers) {
+    // need FB refresh for s3d case
+    if (layer->input_buffer->s3d_format != kS3dFormatNone) {
+      return true;
+    }
+
+    if (layer->composition == kCompositionGPUTarget ||
+        layer->composition == kCompositionBlitTarget) {
+      continue;
+    }
+  }
+
+  return false;
+}
+
+void HWCDisplay::SetIdleTimeoutMs(uint32_t timeout_ms) {
+  return;
+}
+
+DisplayError HWCDisplay::SetMaxMixerStages(uint32_t max_mixer_stages) {
+  DisplayError error = kErrorNone;
+
+  if (display_intf_) {
+    error = display_intf_->SetMaxMixerStages(max_mixer_stages);
+  }
+
+  return error;
+}
+
+DisplayError HWCDisplay::ControlPartialUpdate(bool enable, uint32_t *pending) {
+  DisplayError error = kErrorNone;
+
+  if (display_intf_) {
+    error = display_intf_->ControlPartialUpdate(enable, pending);
+  }
+
+  return error;
+}
+
+LayerBufferFormat HWCDisplay::GetSDMFormat(const int32_t &source, const int flags) {
+  LayerBufferFormat format = kFormatInvalid;
+  if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
+    switch (source) {
+      case HAL_PIXEL_FORMAT_RGBA_8888:
+        format = kFormatRGBA8888Ubwc;
+        break;
+      case HAL_PIXEL_FORMAT_RGBX_8888:
+        format = kFormatRGBX8888Ubwc;
+        break;
+      case HAL_PIXEL_FORMAT_BGR_565:
+        format = kFormatBGR565Ubwc;
+        break;
+      case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+      case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+      case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+        format = kFormatYCbCr420SPVenusUbwc;
+        break;
+      case HAL_PIXEL_FORMAT_RGBA_1010102:
+        format = kFormatRGBA1010102Ubwc;
+        break;
+      case HAL_PIXEL_FORMAT_RGBX_1010102:
+        format = kFormatRGBX1010102Ubwc;
+        break;
+      case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+        format = kFormatYCbCr420TP10Ubwc;
+        break;
+      default:
+        DLOGE("Unsupported format type for UBWC %d", source);
+        return kFormatInvalid;
+    }
+    return format;
+  }
+
+  switch (source) {
+    case HAL_PIXEL_FORMAT_RGBA_8888:
+      format = kFormatRGBA8888;
+      break;
+    case HAL_PIXEL_FORMAT_RGBA_5551:
+      format = kFormatRGBA5551;
+      break;
+    case HAL_PIXEL_FORMAT_RGBA_4444:
+      format = kFormatRGBA4444;
+      break;
+    case HAL_PIXEL_FORMAT_BGRA_8888:
+      format = kFormatBGRA8888;
+      break;
+    case HAL_PIXEL_FORMAT_RGBX_8888:
+      format = kFormatRGBX8888;
+      break;
+    case HAL_PIXEL_FORMAT_BGRX_8888:
+      format = kFormatBGRX8888;
+      break;
+    case HAL_PIXEL_FORMAT_RGB_888:
+      format = kFormatRGB888;
+      break;
+    case HAL_PIXEL_FORMAT_RGB_565:
+      format = kFormatRGB565;
+      break;
+    case HAL_PIXEL_FORMAT_BGR_565:
+      format = kFormatBGR565;
+      break;
+    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+      format = kFormatYCbCr420SemiPlanarVenus;
+      break;
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
+      format = kFormatYCrCb420SemiPlanarVenus;
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+      format = kFormatYCbCr420SPVenusUbwc;
+      break;
+    case HAL_PIXEL_FORMAT_YV12:
+      format = kFormatYCrCb420PlanarStride16;
+      break;
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+      format = kFormatYCrCb420SemiPlanar;
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+      format = kFormatYCbCr420SemiPlanar;
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+      format = kFormatYCbCr422H2V1SemiPlanar;
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_422_I:
+      format = kFormatYCbCr422H2V1Packed;
+      break;
+    case HAL_PIXEL_FORMAT_RGBA_1010102:
+      format = kFormatRGBA1010102;
+      break;
+    case HAL_PIXEL_FORMAT_ARGB_2101010:
+      format = kFormatARGB2101010;
+      break;
+    case HAL_PIXEL_FORMAT_RGBX_1010102:
+      format = kFormatRGBX1010102;
+      break;
+    case HAL_PIXEL_FORMAT_XRGB_2101010:
+      format = kFormatXRGB2101010;
+      break;
+    case HAL_PIXEL_FORMAT_BGRA_1010102:
+      format = kFormatBGRA1010102;
+      break;
+    case HAL_PIXEL_FORMAT_ABGR_2101010:
+      format = kFormatABGR2101010;
+      break;
+    case HAL_PIXEL_FORMAT_BGRX_1010102:
+      format = kFormatBGRX1010102;
+      break;
+    case HAL_PIXEL_FORMAT_XBGR_2101010:
+      format = kFormatXBGR2101010;
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_420_P010:
+      format = kFormatYCbCr420P010;
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+      format = kFormatYCbCr420TP10Ubwc;
+      break;
+    default:
+      DLOGW("Unsupported format type = %d", source);
+      return kFormatInvalid;
+  }
+
+  return format;
+}
+
+void HWCDisplay::DumpInputBuffers() {
+  char dir_path[PATH_MAX];
+
+  if (!dump_frame_count_ || flush_ || !dump_input_layers_) {
+    return;
+  }
+
+  snprintf(dir_path, sizeof(dir_path), "/data/misc/display/frame_dump_%s", GetDisplayString());
+
+  if (mkdir(dir_path, 0777) != 0 && errno != EEXIST) {
+    DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
+    return;
+  }
+
+  // if directory exists already, need to explicitly change the permission.
+  if (errno == EEXIST && chmod(dir_path, 0777) != 0) {
+    DLOGW("Failed to change permissions on %s directory", dir_path);
+    return;
+  }
+
+  for (uint32_t i = 0; i < layer_stack_.layers.size(); i++) {
+    auto layer = layer_stack_.layers.at(i);
+    const private_handle_t *pvt_handle =
+        reinterpret_cast<const private_handle_t *>(layer->input_buffer->buffer_id);
+    auto acquire_fence_fd = layer->input_buffer->acquire_fence_fd;
+
+    if (acquire_fence_fd >= 0) {
+      int error = sync_wait(acquire_fence_fd, 1000);
+      if (error < 0) {
+        DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
+        return;
+      }
+    }
+
+    if (pvt_handle && pvt_handle->base) {
+      char dump_file_name[PATH_MAX];
+      size_t result = 0;
+
+      snprintf(dump_file_name, sizeof(dump_file_name), "%s/input_layer%d_%dx%d_%s_frame%d.raw",
+               dir_path, i, pvt_handle->width, pvt_handle->height,
+               GetHALPixelFormatString(pvt_handle->format), dump_frame_index_);
+
+      FILE *fp = fopen(dump_file_name, "w+");
+      if (fp) {
+        result = fwrite(reinterpret_cast<void *>(pvt_handle->base), pvt_handle->size, 1, fp);
+        fclose(fp);
+      }
+
+      DLOGI("Frame Dump %s: is %s", dump_file_name, result ? "Successful" : "Failed");
+    }
+  }
+}
+
+void HWCDisplay::DumpOutputBuffer(const BufferInfo &buffer_info, void *base, int fence) {
+  char dir_path[PATH_MAX];
+
+  snprintf(dir_path, sizeof(dir_path), "/data/misc/display/frame_dump_%s", GetDisplayString());
+
+  if (mkdir(dir_path, 777) != 0 && errno != EEXIST) {
+    DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
+    return;
+  }
+
+  // if directory exists already, need to explicitly change the permission.
+  if (errno == EEXIST && chmod(dir_path, 0777) != 0) {
+    DLOGW("Failed to change permissions on %s directory", dir_path);
+    return;
+  }
+
+  if (base) {
+    char dump_file_name[PATH_MAX];
+    size_t result = 0;
+
+    if (fence >= 0) {
+      int error = sync_wait(fence, 1000);
+      if (error < 0) {
+        DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
+        return;
+      }
+    }
+
+    snprintf(dump_file_name, sizeof(dump_file_name), "%s/output_layer_%dx%d_%s_frame%d.raw",
+             dir_path, buffer_info.buffer_config.width, buffer_info.buffer_config.height,
+             GetFormatString(buffer_info.buffer_config.format), dump_frame_index_);
+
+    FILE *fp = fopen(dump_file_name, "w+");
+    if (fp) {
+      result = fwrite(base, buffer_info.alloc_buffer_info.size, 1, fp);
+      fclose(fp);
+    }
+
+    DLOGI("Frame Dump of %s is %s", dump_file_name, result ? "Successful" : "Failed");
+  }
+}
+
+const char *HWCDisplay::GetHALPixelFormatString(int format) {
+  switch (format) {
+    case HAL_PIXEL_FORMAT_RGBA_8888:
+      return "RGBA_8888";
+    case HAL_PIXEL_FORMAT_RGBX_8888:
+      return "RGBX_8888";
+    case HAL_PIXEL_FORMAT_RGB_888:
+      return "RGB_888";
+    case HAL_PIXEL_FORMAT_RGB_565:
+      return "RGB_565";
+    case HAL_PIXEL_FORMAT_BGR_565:
+      return "BGR_565";
+    case HAL_PIXEL_FORMAT_BGRA_8888:
+      return "BGRA_8888";
+    case HAL_PIXEL_FORMAT_RGBA_5551:
+      return "RGBA_5551";
+    case HAL_PIXEL_FORMAT_RGBA_4444:
+      return "RGBA_4444";
+    case HAL_PIXEL_FORMAT_YV12:
+      return "YV12";
+    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+      return "YCbCr_422_SP_NV16";
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+      return "YCrCb_420_SP_NV21";
+    case HAL_PIXEL_FORMAT_YCbCr_422_I:
+      return "YCbCr_422_I_YUY2";
+    case HAL_PIXEL_FORMAT_YCrCb_422_I:
+      return "YCrCb_422_I_YVYU";
+    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+      return "NV12_ENCODEABLE";
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
+      return "YCbCr_420_SP_TILED_TILE_4x2";
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+      return "YCbCr_420_SP";
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
+      return "YCrCb_420_SP_ADRENO";
+    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+      return "YCrCb_422_SP";
+    case HAL_PIXEL_FORMAT_R_8:
+      return "R_8";
+    case HAL_PIXEL_FORMAT_RG_88:
+      return "RG_88";
+    case HAL_PIXEL_FORMAT_INTERLACE:
+      return "INTERLACE";
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+      return "YCbCr_420_SP_VENUS";
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
+      return "YCrCb_420_SP_VENUS";
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+      return "YCbCr_420_SP_VENUS_UBWC";
+    case HAL_PIXEL_FORMAT_RGBA_1010102:
+      return "RGBA_1010102";
+    case HAL_PIXEL_FORMAT_ARGB_2101010:
+      return "ARGB_2101010";
+    case HAL_PIXEL_FORMAT_RGBX_1010102:
+      return "RGBX_1010102";
+    case HAL_PIXEL_FORMAT_XRGB_2101010:
+      return "XRGB_2101010";
+    case HAL_PIXEL_FORMAT_BGRA_1010102:
+      return "BGRA_1010102";
+    case HAL_PIXEL_FORMAT_ABGR_2101010:
+      return "ABGR_2101010";
+    case HAL_PIXEL_FORMAT_BGRX_1010102:
+      return "BGRX_1010102";
+    case HAL_PIXEL_FORMAT_XBGR_2101010:
+      return "XBGR_2101010";
+    case HAL_PIXEL_FORMAT_YCbCr_420_P010:
+      return "YCbCr_420_P010";
+    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+      return "YCbCr_420_TP10_UBWC";
+    default:
+      return "Unknown_format";
+  }
+}
+
+const char *HWCDisplay::GetDisplayString() {
+  switch (type_) {
+    case kPrimary:
+      return "primary";
+    case kHDMI:
+      return "hdmi";
+    case kVirtual:
+      return "virtual";
+    default:
+      return "invalid";
+  }
+}
+
+int HWCDisplay::SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels) {
+  if (x_pixels <= 0 || y_pixels <= 0) {
+    DLOGV("Unsupported config: x_pixels=%d, y_pixels=%d", x_pixels, y_pixels);
+    return -EINVAL;
+  }
+
+  if (framebuffer_config_->x_pixels == x_pixels && framebuffer_config_->y_pixels == y_pixels) {
+    return 0;
+  }
+
+  DisplayConfigVariableInfo active_config;
+  uint32_t active_config_index = 0;
+  display_intf_->GetActiveConfig(&active_config_index);
+  DisplayError error = display_intf_->GetConfig(active_config_index, &active_config);
+  if (error != kErrorNone) {
+    DLOGV("GetConfig variable info failed. Error = %d", error);
+    return -EINVAL;
+  }
+
+  if (active_config.x_pixels <= 0 || active_config.y_pixels <= 0) {
+    DLOGV("Invalid panel resolution (%dx%d)", active_config.x_pixels, active_config.y_pixels);
+    return -EINVAL;
+  }
+
+  // Create rects to represent the new source and destination crops
+  LayerRect crop = LayerRect(0, 0, FLOAT(x_pixels), FLOAT(y_pixels));
+  LayerRect dst = LayerRect(0, 0, FLOAT(active_config.x_pixels), FLOAT(active_config.y_pixels));
+  // Set rotate90 to false since this is taken care of during regular composition.
+  bool rotate90 = false;
+  error = display_intf_->IsScalingValid(crop, dst, rotate90);
+  if (error != kErrorNone) {
+    DLOGV("Unsupported resolution: (%dx%d)", x_pixels, y_pixels);
+    return -EINVAL;
+  }
+
+  framebuffer_config_->x_pixels = x_pixels;
+  framebuffer_config_->y_pixels = y_pixels;
+  framebuffer_config_->vsync_period_ns = active_config.vsync_period_ns;
+  framebuffer_config_->x_dpi = active_config.x_dpi;
+  framebuffer_config_->y_dpi = active_config.y_dpi;
+
+  auto client_target_layer = client_target_->GetSDMLayer();
+  client_target_layer->src_rect = crop;
+  client_target_layer->dst_rect = dst;
+
+  int aligned_width;
+  int aligned_height;
+  int usage = GRALLOC_USAGE_HW_FB;
+  int format = HAL_PIXEL_FORMAT_RGBA_8888;
+  int ubwc_enabled = 0;
+  int flags = 0;
+  HWCDebugHandler::Get()->GetProperty("debug.gralloc.enable_fb_ubwc", &ubwc_enabled);
+  if (ubwc_enabled == 1) {
+    usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
+    flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+  }
+  AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(INT(x_pixels), INT(y_pixels), format, usage,
+                                                        aligned_width, aligned_height);
+
+  // TODO(user): How does the dirty region get set on the client target? File bug on Google
+  client_target_layer->composition = kCompositionGPUTarget;
+  client_target_layer->input_buffer->format = GetSDMFormat(format, flags);
+  client_target_layer->input_buffer->width = UINT32(aligned_width);
+  client_target_layer->input_buffer->height = UINT32(aligned_height);
+  client_target_layer->plane_alpha = 255;
+
+  DLOGI("New framebuffer resolution (%dx%d)", framebuffer_config_->x_pixels,
+        framebuffer_config_->y_pixels);
+
+  return 0;
+}
+
+void HWCDisplay::GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
+  *x_pixels = framebuffer_config_->x_pixels;
+  *y_pixels = framebuffer_config_->y_pixels;
+}
+
+void HWCDisplay::ScaleDisplayFrame(hwc_rect_t *display_frame) {
+  if (!IsFrameBufferScaled()) {
+    return;
+  }
+
+  uint32_t active_config_index = 0;
+  display_intf_->GetActiveConfig(&active_config_index);
+  DisplayConfigVariableInfo active_config;
+  DisplayError error = display_intf_->GetConfig(active_config_index, &active_config);
+  if (error != kErrorNone) {
+    DLOGE("GetConfig variable info failed. Error = %d", error);
+    return;
+  }
+
+  float custom_x_pixels = FLOAT(framebuffer_config_->x_pixels);
+  float custom_y_pixels = FLOAT(framebuffer_config_->y_pixels);
+  float active_x_pixels = FLOAT(active_config.x_pixels);
+  float active_y_pixels = FLOAT(active_config.y_pixels);
+  float x_pixels_ratio = active_x_pixels / custom_x_pixels;
+  float y_pixels_ratio = active_y_pixels / custom_y_pixels;
+  float layer_width = FLOAT(display_frame->right - display_frame->left);
+  float layer_height = FLOAT(display_frame->bottom - display_frame->top);
+
+  display_frame->left = INT(x_pixels_ratio * FLOAT(display_frame->left));
+  display_frame->top = INT(y_pixels_ratio * FLOAT(display_frame->top));
+  display_frame->right = INT(FLOAT(display_frame->left) + layer_width * x_pixels_ratio);
+  display_frame->bottom = INT(FLOAT(display_frame->top) + layer_height * y_pixels_ratio);
+}
+
+bool HWCDisplay::IsFrameBufferScaled() {
+  if (framebuffer_config_->x_pixels == 0 || framebuffer_config_->y_pixels == 0) {
+    return false;
+  }
+  uint32_t panel_x_pixels = 0;
+  uint32_t panel_y_pixels = 0;
+  GetPanelResolution(&panel_x_pixels, &panel_y_pixels);
+  return (framebuffer_config_->x_pixels != panel_x_pixels) ||
+         (framebuffer_config_->y_pixels != panel_y_pixels);
+}
+
+void HWCDisplay::GetPanelResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
+  DisplayConfigVariableInfo active_config;
+  uint32_t active_config_index = 0;
+  display_intf_->GetActiveConfig(&active_config_index);
+  DisplayError error = display_intf_->GetConfig(active_config_index, &active_config);
+  if (error != kErrorNone) {
+    DLOGE("GetConfig variable info failed. Error = %d", error);
+    return;
+  }
+  *x_pixels = active_config.x_pixels;
+  *y_pixels = active_config.y_pixels;
+}
+
+int HWCDisplay::SetDisplayStatus(uint32_t display_status) {
+  int status = 0;
+
+  switch (display_status) {
+    case kDisplayStatusResume:
+      display_paused_ = false;
+    case kDisplayStatusOnline:
+      status = INT32(SetPowerMode(HWC2::PowerMode::On));
+      break;
+    case kDisplayStatusPause:
+      display_paused_ = true;
+    case kDisplayStatusOffline:
+      status = INT32(SetPowerMode(HWC2::PowerMode::Off));
+      break;
+    default:
+      DLOGW("Invalid display status %d", display_status);
+      return -EINVAL;
+  }
+
+  if (display_status == kDisplayStatusResume || display_status == kDisplayStatusPause) {
+    callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
+  }
+
+  return status;
+}
+
+HWC2::Error HWCDisplay::SetCursorPosition(hwc2_layer_t layer, int x, int y) {
+  if (shutdown_pending_) {
+    return HWC2::Error::None;
+  }
+
+  // TODO(user): Validate layer
+  // TODO(user): Check if we're in a validate/present cycle
+
+  auto error = display_intf_->SetCursorPosition(x, y);
+  if (error != kErrorNone) {
+    if (error == kErrorShutDown) {
+      shutdown_pending_ = true;
+      return HWC2::Error::None;
+    }
+
+    DLOGE("Failed for x = %d y = %d, Error = %d", x, y, error);
+    return HWC2::Error::BadDisplay;
+  }
+
+  return HWC2::Error::None;
+}
+
+int HWCDisplay::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
+  DisplayError error = display_intf_->OnMinHdcpEncryptionLevelChange(min_enc_level);
+  if (error != kErrorNone) {
+    DLOGE("Failed. Error = %d", error);
+    return -1;
+  }
+
+  return 0;
+}
+
+void HWCDisplay::MarkLayersForGPUBypass() {
+  for (auto hwc_layer : layer_set_) {
+    auto layer = hwc_layer->GetSDMLayer();
+    layer->composition = kCompositionSDE;
+  }
+}
+
+void HWCDisplay::ApplyScanAdjustment(hwc_rect_t *display_frame) {
+}
+
+int HWCDisplay::SetPanelBrightness(int level) {
+  int ret = 0;
+  if (display_intf_)
+    ret = display_intf_->SetPanelBrightness(level);
+  else
+    ret = -EINVAL;
+
+  return ret;
+}
+
+int HWCDisplay::GetPanelBrightness(int *level) {
+  return display_intf_->GetPanelBrightness(level);
+}
+
+int HWCDisplay::ToggleScreenUpdates(bool enable) {
+  display_paused_ = enable ? false : true;
+  callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
+  return 0;
+}
+
+int HWCDisplay::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
+                                     PPDisplayAPIPayload *out_payload,
+                                     PPPendingParams *pending_action) {
+  int ret = 0;
+
+  if (display_intf_)
+    ret = display_intf_->ColorSVCRequestRoute(in_payload, out_payload, pending_action);
+  else
+    ret = -EINVAL;
+
+  return ret;
+}
+
+int HWCDisplay::GetVisibleDisplayRect(hwc_rect_t *visible_rect) {
+  if (!IsValid(display_rect_)) {
+    return -EINVAL;
+  }
+
+  visible_rect->left = INT(display_rect_.left);
+  visible_rect->top = INT(display_rect_.top);
+  visible_rect->right = INT(display_rect_.right);
+  visible_rect->bottom = INT(display_rect_.bottom);
+  DLOGI("Dpy = %d Visible Display Rect(%d %d %d %d)", visible_rect->left, visible_rect->top,
+        visible_rect->right, visible_rect->bottom);
+
+  return 0;
+}
+
+void HWCDisplay::SetSecureDisplay(bool secure_display_active) {
+  secure_display_active_ = secure_display_active;
+  return;
+}
+
+int HWCDisplay::SetActiveDisplayConfig(int config) {
+  return display_intf_->SetActiveConfig(UINT32(config)) == kErrorNone ? 0 : -1;
+}
+
+int HWCDisplay::GetActiveDisplayConfig(uint32_t *config) {
+  return display_intf_->GetActiveConfig(config) == kErrorNone ? 0 : -1;
+}
+
+int HWCDisplay::GetDisplayConfigCount(uint32_t *count) {
+  return display_intf_->GetNumVariableInfoConfigs(count) == kErrorNone ? 0 : -1;
+}
+
+int HWCDisplay::GetDisplayAttributesForConfig(int config, DisplayConfigVariableInfo *attributes) {
+  return display_intf_->GetConfig(UINT32(config), attributes) == kErrorNone ? 0 : -1;
+}
+
+bool HWCDisplay::SingleLayerUpdating(void) {
+  uint32_t updating_count = 0;
+
+  for (uint i = 0; i < layer_set_.size(); i++) {
+    auto layer = layer_stack_.layers.at(i);
+    if (layer->flags.updating) {
+      updating_count++;
+    }
+  }
+
+  return (updating_count == 1);
+}
+
+uint32_t HWCDisplay::SanitizeRefreshRate(uint32_t req_refresh_rate) {
+  uint32_t refresh_rate = req_refresh_rate;
+
+  if (refresh_rate < min_refresh_rate_) {
+    // Pick the next multiple of request which is within the range
+    refresh_rate =
+        (((min_refresh_rate_ / refresh_rate) + ((min_refresh_rate_ % refresh_rate) ? 1 : 0)) *
+         refresh_rate);
+  }
+
+  if (refresh_rate > max_refresh_rate_) {
+    refresh_rate = max_refresh_rate_;
+  }
+
+  return refresh_rate;
+}
+
+DisplayClass HWCDisplay::GetDisplayClass() {
+  return display_class_;
+}
+
+void HWCDisplay::CloseAcquireFds() {
+  for (auto hwc_layer : layer_set_) {
+    auto layer = hwc_layer->GetSDMLayer();
+    if (layer->input_buffer->acquire_fence_fd >= 0) {
+      close(layer->input_buffer->acquire_fence_fd);
+      layer->input_buffer->acquire_fence_fd = -1;
+    }
+  }
+  int32_t &client_target_acquire_fence =
+      client_target_->GetSDMLayer()->input_buffer->acquire_fence_fd;
+  if (client_target_acquire_fence >= 0) {
+    close(client_target_acquire_fence);
+    client_target_acquire_fence = -1;
+  }
+}
+
+std::string HWCDisplay::Dump() {
+  std::ostringstream os;
+  os << "-------------------------------" << std::endl;
+  os << "HWC2 LayerDump:" << std::endl;
+  for (auto layer : layer_set_) {
+    auto sdm_layer = layer->GetSDMLayer();
+    os << "-------------------------------" << std::endl;
+    os << "layer_id: " << layer->GetId() << std::endl;
+    os << "\tz: " << layer->GetZ() << std::endl;
+    os << "\tcomposition: " << to_string(layer->GetCompositionType()).c_str() << std::endl;
+    os << "\tplane_alpha: " << std::to_string(sdm_layer->plane_alpha).c_str() << std::endl;
+    os << "\tformat: " << GetFormatString(sdm_layer->input_buffer->format) << std::endl;
+    os << "\tbuffer_id: " << std::hex << "0x" << sdm_layer->input_buffer->buffer_id << std::dec
+       << std::endl;
+  }
+  os << "-------------------------------" << std::endl;
+  return os.str();
+}
+}  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
new file mode 100644
index 0000000..51e7d13
--- /dev/null
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright 2015 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 __HWC_DISPLAY_H__
+#define __HWC_DISPLAY_H__
+
+#include <hardware/hwcomposer.h>
+#include <core/core_interface.h>
+#include <qdMetaData.h>
+#include <QService.h>
+#include <private/color_params.h>
+#include <map>
+#include <set>
+#include <string>
+#include <queue>
+#include <utility>
+#include "hwc_callbacks.h"
+#include "hwc_layers.h"
+
+namespace sdm {
+
+class BlitEngine;
+
+// Subclasses set this to their type. This has to be different from DisplayType.
+// This is to avoid RTTI and dynamic_cast
+enum DisplayClass {
+  DISPLAY_CLASS_PRIMARY,
+  DISPLAY_CLASS_EXTERNAL,
+  DISPLAY_CLASS_VIRTUAL,
+  DISPLAY_CLASS_NULL
+};
+
+class HWCDisplay : public DisplayEventHandler {
+ public:
+  virtual ~HWCDisplay() {}
+  virtual int Init();
+  virtual int Deinit();
+
+  // Framebuffer configurations
+  virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
+  virtual void SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type);
+  virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages);
+  virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending);
+  virtual HWC2::PowerMode GetLastPowerMode();
+  virtual int SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels);
+  virtual void GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels);
+  virtual void GetPanelResolution(uint32_t *x_pixels, uint32_t *y_pixels);
+  virtual int SetDisplayStatus(uint32_t display_status);
+  virtual int OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level);
+  virtual int Perform(uint32_t operation, ...);
+  virtual void SetSecureDisplay(bool secure_display_active);
+  virtual std::string Dump(void);
+
+  // Captures frame output in the buffer specified by output_buffer_info. The API is
+  // non-blocking and the client is expected to check operation status later on.
+  // Returns -1 if the input is invalid.
+  virtual int FrameCaptureAsync(const BufferInfo &output_buffer_info, bool post_processed) {
+    return -1;
+  }
+  // Returns the status of frame capture operation requested with FrameCaptureAsync().
+  // -EAGAIN : No status obtain yet, call API again after another frame.
+  // < 0 : Operation happened but failed.
+  // 0 : Success.
+  virtual int GetFrameCaptureStatus() { return -EAGAIN; }
+
+  // Display Configurations
+  virtual int SetActiveDisplayConfig(int config);
+  virtual int GetActiveDisplayConfig(uint32_t *config);
+  virtual int GetDisplayConfigCount(uint32_t *count);
+  virtual int GetDisplayAttributesForConfig(int config, DisplayConfigVariableInfo *attributes);
+
+  int SetPanelBrightness(int level);
+  int GetPanelBrightness(int *level);
+  int ToggleScreenUpdates(bool enable);
+  int ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload, PPDisplayAPIPayload *out_payload,
+                           PPPendingParams *pending_action);
+  DisplayClass GetDisplayClass();
+  int GetVisibleDisplayRect(hwc_rect_t *rect);
+  void BuildLayerStack(void);
+  HWCLayer *GetHWCLayer(hwc2_layer_t layer);
+
+  // HWC2 APIs
+  virtual HWC2::Error AcceptDisplayChanges(void);
+  virtual HWC2::Error GetActiveConfig(hwc2_config_t *out_config);
+  virtual HWC2::Error SetActiveConfig(hwc2_config_t config);
+  virtual HWC2::Error SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
+                                      int32_t dataspace);
+  virtual HWC2::Error GetDisplayConfigs(uint32_t *out_num_configs, hwc2_config_t *out_configs);
+  virtual HWC2::Error GetDisplayAttribute(hwc2_config_t config, HWC2::Attribute attribute,
+                                          int32_t *out_value);
+  virtual HWC2::Error GetClientTargetSupport(uint32_t width, uint32_t height, int32_t format,
+                                             int32_t dataspace);
+  virtual HWC2::Error GetChangedCompositionTypes(uint32_t *out_num_elements,
+                                                 hwc2_layer_t *out_layers, int32_t *out_types);
+  virtual HWC2::Error GetDisplayRequests(int32_t *out_display_requests, uint32_t *out_num_elements,
+                                         hwc2_layer_t *out_layers, int32_t *out_layer_requests);
+  virtual HWC2::Error GetDisplayName(uint32_t *out_size, char *out_name);
+  virtual HWC2::Error GetDisplayType(int32_t *out_type);
+  virtual HWC2::Error SetCursorPosition(hwc2_layer_t layer, int x, int y);
+  virtual HWC2::Error SetVsyncEnabled(HWC2::Vsync enabled);
+  virtual HWC2::Error SetPowerMode(HWC2::PowerMode mode);
+  virtual HWC2::Error CreateLayer(hwc2_layer_t *out_layer_id);
+  virtual HWC2::Error DestroyLayer(hwc2_layer_t layer_id);
+  virtual HWC2::Error SetLayerZOrder(hwc2_layer_t layer_id, uint32_t z);
+  virtual HWC2::Error Validate(uint32_t *out_num_types, uint32_t *out_num_requests) = 0;
+  virtual HWC2::Error GetReleaseFences(uint32_t *out_num_elements, hwc2_layer_t *out_layers,
+                                       int32_t *out_fences);
+  virtual HWC2::Error Present(int32_t *out_retire_fence) = 0;
+
+ protected:
+  enum DisplayStatus {
+    kDisplayStatusOffline = 0,
+    kDisplayStatusOnline,
+    kDisplayStatusPause,
+    kDisplayStatusResume,
+  };
+
+  // Maximum number of layers supported by display manager.
+  static const uint32_t kMaxLayerCount = 32;
+
+  HWCDisplay(CoreInterface *core_intf, HWCCallbacks *callbacks, DisplayType type, hwc2_display_t id,
+             bool needs_blit, qService::QService *qservice, DisplayClass display_class);
+
+  // DisplayEventHandler methods
+  virtual DisplayError VSync(const DisplayEventVSync &vsync);
+  virtual DisplayError Refresh();
+  virtual DisplayError CECMessage(char *message);
+  virtual void DumpOutputBuffer(const BufferInfo &buffer_info, void *base, int fence);
+  virtual HWC2::Error PrepareLayerStack(uint32_t *out_num_types, uint32_t *out_num_requests);
+  virtual HWC2::Error CommitLayerStack(void);
+  virtual HWC2::Error PostCommitLayerStack(int32_t *out_retire_fence);
+  LayerBufferFormat GetSDMFormat(const int32_t &source, const int flags);
+  const char *GetHALPixelFormatString(int format);
+  const char *GetDisplayString();
+  void ScaleDisplayFrame(hwc_rect_t *display_frame);
+  void MarkLayersForGPUBypass(void);
+  virtual void ApplyScanAdjustment(hwc_rect_t *display_frame);
+  bool NeedsFrameBufferRefresh(void);
+  bool SingleLayerUpdating(void);
+  uint32_t SanitizeRefreshRate(uint32_t req_refresh_rate);
+  virtual void CloseAcquireFds();
+
+  enum {
+    INPUT_LAYER_DUMP,
+    OUTPUT_LAYER_DUMP,
+  };
+
+  CoreInterface *core_intf_ = nullptr;
+  HWCCallbacks *callbacks_  = nullptr;
+  DisplayType type_;
+  hwc2_display_t id_;
+  bool needs_blit_ = false;
+  DisplayInterface *display_intf_ = NULL;
+  LayerStack layer_stack_;
+  HWCLayer *client_target_ = nullptr;                   // Also known as framebuffer target
+  std::map<hwc2_layer_t, HWCLayer *> layer_map_;        // Look up by Id - TODO
+  std::multiset<HWCLayer *, SortLayersByZ> layer_set_;  // Maintain a set sorted by Z
+  std::map<hwc2_layer_t, HWC2::Composition> layer_changes_;
+  std::map<hwc2_layer_t, HWC2::LayerRequest> layer_requests_;
+  bool flush_on_error_ = false;
+  bool flush_ = false;
+  uint32_t dump_frame_count_ = 0;
+  uint32_t dump_frame_index_ = 0;
+  bool dump_input_layers_ = false;
+  HWC2::PowerMode last_power_mode_;
+  bool swap_interval_zero_ = false;
+  DisplayConfigVariableInfo *framebuffer_config_ = NULL;
+  bool display_paused_ = false;
+  uint32_t min_refresh_rate_ = 0;
+  uint32_t max_refresh_rate_ = 0;
+  uint32_t current_refresh_rate_ = 0;
+  bool use_metadata_refresh_rate_ = false;
+  uint32_t metadata_refresh_rate_ = 0;
+  uint32_t force_refresh_rate_ = 0;
+  bool boot_animation_completed_ = false;
+  bool shutdown_pending_ = false;
+  bool use_blit_comp_ = false;
+  bool secure_display_active_ = false;
+  bool skip_prepare_ = false;
+  bool solid_fill_enable_ = false;
+  uint32_t solid_fill_color_ = 0;
+  LayerRect display_rect_;
+  bool validated_ = false;
+
+ private:
+  bool IsFrameBufferScaled();
+  void DumpInputBuffers(void);
+  BlitEngine *blit_engine_ = NULL;
+  qService::QService *qservice_ = NULL;
+  DisplayClass display_class_;
+  int32_t stored_retire_fence_ = -1;
+  uint32_t geometry_changes_ = GeometryChanges::kNone;
+};
+
+inline int HWCDisplay::Perform(uint32_t operation, ...) {
+  return 0;
+}
+
+}  // namespace sdm
+
+#endif  // __HWC_DISPLAY_H__
diff --git a/sdm/libs/hwc2/hwc_display_external.cpp b/sdm/libs/hwc2/hwc_display_external.cpp
new file mode 100644
index 0000000..73ed0e8
--- /dev/null
+++ b/sdm/libs/hwc2/hwc_display_external.cpp
@@ -0,0 +1,206 @@
+/*
+* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*     * Redistributions of source code must retain the above copyright
+*       notice, this list of conditions and the following disclaimer.
+*     * Redistributions in binary form must reproduce the above
+*       copyright notice, this list of conditions and the following
+*       disclaimer in the documentation and/or other materials provided
+*       with the distribution.
+*     * Neither the name of The Linux Foundation nor the names of its
+*       contributors may be used to endorse or promote products derived
+*       from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <cutils/properties.h>
+#include <utils/constants.h>
+#include <utils/debug.h>
+
+#include "hwc_display_external.h"
+#include "hwc_debugger.h"
+
+#define __CLASS__ "HWCDisplayExternal"
+
+namespace sdm {
+
+int HWCDisplayExternal::Create(CoreInterface *core_intf, HWCCallbacks *callbacks,
+                               qService::QService *qservice, HWCDisplay **hwc_display) {
+  return Create(core_intf, callbacks, 0, 0, qservice, false, hwc_display);
+}
+
+int HWCDisplayExternal::Create(CoreInterface *core_intf, HWCCallbacks *callbacks,
+                               uint32_t primary_width, uint32_t primary_height,
+                               qService::QService *qservice, bool use_primary_res,
+                               HWCDisplay **hwc_display) {
+  uint32_t external_width = 0;
+  uint32_t external_height = 0;
+
+  HWCDisplay *hwc_display_external = new HWCDisplayExternal(core_intf, callbacks, qservice);
+  int status = hwc_display_external->Init();
+  if (status) {
+    delete hwc_display_external;
+    return status;
+  }
+
+  hwc_display_external->GetPanelResolution(&external_width, &external_height);
+
+  if (primary_width && primary_height) {
+    // use_primary_res means HWCDisplayExternal should directly set framebuffer resolution to the
+    // provided primary_width and primary_height
+    if (use_primary_res) {
+      external_width = primary_width;
+      external_height = primary_height;
+    } else {
+      int downscale_enabled = 0;
+      HWCDebugHandler::Get()->GetProperty("sdm.debug.downscale_external", &downscale_enabled);
+      if (downscale_enabled) {
+        GetDownscaleResolution(primary_width, primary_height, &external_width, &external_height);
+      }
+    }
+  }
+
+  status = hwc_display_external->SetFrameBufferResolution(external_width, external_height);
+  if (status) {
+    Destroy(hwc_display_external);
+    return status;
+  }
+
+  *hwc_display = hwc_display_external;
+
+  return status;
+}
+
+void HWCDisplayExternal::Destroy(HWCDisplay *hwc_display) {
+  hwc_display->Deinit();
+  delete hwc_display;
+}
+
+HWCDisplayExternal::HWCDisplayExternal(CoreInterface *core_intf, HWCCallbacks *callbacks,
+                                       qService::QService *qservice)
+    : HWCDisplay(core_intf, callbacks, kHDMI, HWC_DISPLAY_EXTERNAL, false, qservice,
+                 DISPLAY_CLASS_EXTERNAL) {
+}
+
+HWC2::Error HWCDisplayExternal::Validate(uint32_t *out_num_types, uint32_t *out_num_requests) {
+  auto status = HWC2::Error::None;
+
+  if (secure_display_active_) {
+    MarkLayersForGPUBypass();
+    return status;
+  }
+
+  BuildLayerStack();
+
+  if (layer_set_.empty()) {
+    flush_ = true;
+    return status;
+  }
+
+  status = PrepareLayerStack(out_num_types, out_num_requests);
+  return status;
+}
+
+HWC2::Error HWCDisplayExternal::Present(int32_t *out_retire_fence) {
+  auto status = HWC2::Error::None;
+
+  if (!secure_display_active_) {
+    status = HWCDisplay::CommitLayerStack();
+    if (status == HWC2::Error::None) {
+      status = HWCDisplay::PostCommitLayerStack(out_retire_fence);
+    }
+  }
+  CloseAcquireFds();
+  return status;
+}
+
+void HWCDisplayExternal::ApplyScanAdjustment(hwc_rect_t *display_frame) {
+  if (display_intf_->IsUnderscanSupported()) {
+    return;
+  }
+
+  // Read user defined width and height ratio
+  int width = 0, height = 0;
+  HWCDebugHandler::Get()->GetProperty("sdm.external_action_safe_width", &width);
+  float width_ratio = FLOAT(width) / 100.0f;
+  HWCDebugHandler::Get()->GetProperty("sdm.external_action_safe_height", &height);
+  float height_ratio = FLOAT(height) / 100.0f;
+
+  if (width_ratio == 0.0f || height_ratio == 0.0f) {
+    return;
+  }
+
+  uint32_t panel_width = 0;
+  uint32_t panel_height = 0;
+  GetPanelResolution(&panel_width, &panel_height);
+
+  if (panel_width == 0 || panel_height == 0) {
+    DLOGV("Invalid panel dimensions (%d, %d)", panel_width, panel_height);
+    return;
+  }
+
+  uint32_t new_panel_width = UINT32(panel_width * FLOAT(1.0f - width_ratio));
+  uint32_t new_panel_height = UINT32(panel_height * FLOAT(1.0f - height_ratio));
+
+  int x_offset = INT((FLOAT(panel_width) * width_ratio) / 2.0f);
+  int y_offset = INT((FLOAT(panel_height) * height_ratio) / 2.0f);
+
+  display_frame->left =
+      (display_frame->left * INT32(new_panel_width) / INT32(panel_width)) + x_offset;
+  display_frame->top =
+      (display_frame->top * INT32(new_panel_height) / INT32(panel_height)) + y_offset;
+  display_frame->right =
+      ((display_frame->right * INT32(new_panel_width)) / INT32(panel_width)) + x_offset;
+  display_frame->bottom =
+      ((display_frame->bottom * INT32(new_panel_height)) / INT32(panel_height)) + y_offset;
+}
+
+void HWCDisplayExternal::SetSecureDisplay(bool secure_display_active) {
+  if (secure_display_active_ != secure_display_active) {
+    secure_display_active_ = secure_display_active;
+
+    if (secure_display_active_) {
+      DisplayError error = display_intf_->Flush();
+      if (error != kErrorNone) {
+        DLOGE("Flush failed. Error = %d", error);
+      }
+    }
+  }
+  return;
+}
+
+static void AdjustSourceResolution(uint32_t dst_width, uint32_t dst_height, uint32_t *src_width,
+                                   uint32_t *src_height) {
+  *src_height = (dst_width * (*src_height)) / (*src_width);
+  *src_width = dst_width;
+}
+
+void HWCDisplayExternal::GetDownscaleResolution(uint32_t primary_width, uint32_t primary_height,
+                                                uint32_t *non_primary_width,
+                                                uint32_t *non_primary_height) {
+  uint32_t primary_area = primary_width * primary_height;
+  uint32_t non_primary_area = (*non_primary_width) * (*non_primary_height);
+
+  if (primary_area > non_primary_area) {
+    if (primary_height > primary_width) {
+      Swap(primary_height, primary_width);
+    }
+    AdjustSourceResolution(primary_width, primary_height, non_primary_width, non_primary_height);
+  }
+}
+
+}  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_display_external.h b/sdm/libs/hwc2/hwc_display_external.h
new file mode 100644
index 0000000..ce7547c
--- /dev/null
+++ b/sdm/libs/hwc2/hwc_display_external.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of The Linux Foundation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __HWC_DISPLAY_EXTERNAL_H__
+#define __HWC_DISPLAY_EXTERNAL_H__
+
+#include "hwc_display.h"
+
+namespace sdm {
+
+class HWCDisplayExternal : public HWCDisplay {
+ public:
+  static int Create(CoreInterface *core_intf, HWCCallbacks *callbacks, uint32_t primary_width,
+                    uint32_t primary_height, qService::QService *qservice, bool use_primary_res,
+                    HWCDisplay **hwc_display);
+  static int Create(CoreInterface *core_intf, HWCCallbacks *callbacks, qService::QService *qservice,
+                    HWCDisplay **hwc_display);
+  static void Destroy(HWCDisplay *hwc_display);
+  virtual HWC2::Error Validate(uint32_t *out_num_types, uint32_t *out_num_requests);
+  virtual HWC2::Error Present(int32_t *out_retire_fence);
+  virtual void SetSecureDisplay(bool secure_display_active);
+
+ private:
+  HWCDisplayExternal(CoreInterface *core_intf, HWCCallbacks *callbacks,
+                     qService::QService *qservice);
+  void ApplyScanAdjustment(hwc_rect_t *display_frame);
+  static void GetDownscaleResolution(uint32_t primary_width, uint32_t primary_height,
+                                     uint32_t *virtual_width, uint32_t *virtual_height);
+};
+
+}  // namespace sdm
+
+#endif  // __HWC_DISPLAY_EXTERNAL_H__
diff --git a/sdm/libs/hwc2/hwc_display_primary.cpp b/sdm/libs/hwc2/hwc_display_primary.cpp
new file mode 100644
index 0000000..40ac723
--- /dev/null
+++ b/sdm/libs/hwc2/hwc_display_primary.cpp
@@ -0,0 +1,471 @@
+/*
+* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*     * Redistributions of source code must retain the above copyright
+*       notice, this list of conditions and the following disclaimer.
+*     * Redistributions in binary form must reproduce the above
+*       copyright notice, this list of conditions and the following
+*       disclaimer in the documentation and/or other materials provided
+*       with the distribution.
+*     * Neither the name of The Linux Foundation nor the names of its
+*       contributors may be used to endorse or promote products derived
+*       from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <cutils/properties.h>
+#include <sync/sync.h>
+#include <utils/constants.h>
+#include <utils/debug.h>
+#include <stdarg.h>
+#include <sys/mman.h>
+
+#include "hwc_display_primary.h"
+#include "hwc_debugger.h"
+
+#define __CLASS__ "HWCDisplayPrimary"
+
+namespace sdm {
+
+int HWCDisplayPrimary::Create(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
+                              HWCCallbacks *callbacks, qService::QService *qservice,
+                              HWCDisplay **hwc_display) {
+  int status = 0;
+  uint32_t primary_width = 0;
+  uint32_t primary_height = 0;
+
+  HWCDisplay *hwc_display_primary =
+      new HWCDisplayPrimary(core_intf, buffer_allocator, callbacks, qservice);
+  status = hwc_display_primary->Init();
+  if (status) {
+    delete hwc_display_primary;
+    return status;
+  }
+
+  hwc_display_primary->GetPanelResolution(&primary_width, &primary_height);
+  int width = 0, height = 0;
+  HWCDebugHandler::Get()->GetProperty("sdm.fb_size_width", &width);
+  HWCDebugHandler::Get()->GetProperty("sdm.fb_size_height", &height);
+  if (width > 0 && height > 0) {
+    primary_width = UINT32(width);
+    primary_height = UINT32(height);
+  }
+
+  status = hwc_display_primary->SetFrameBufferResolution(primary_width, primary_height);
+  if (status) {
+    Destroy(hwc_display_primary);
+    return status;
+  }
+
+  *hwc_display = hwc_display_primary;
+
+  return status;
+}
+
+void HWCDisplayPrimary::Destroy(HWCDisplay *hwc_display) {
+  hwc_display->Deinit();
+  delete hwc_display;
+}
+
+HWCDisplayPrimary::HWCDisplayPrimary(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
+                                     HWCCallbacks *callbacks, qService::QService *qservice)
+    : HWCDisplay(core_intf, callbacks, kPrimary, HWC_DISPLAY_PRIMARY, true, qservice,
+                 DISPLAY_CLASS_PRIMARY),
+      buffer_allocator_(buffer_allocator),
+      cpu_hint_(NULL) {
+}
+
+int HWCDisplayPrimary::Init() {
+  cpu_hint_ = new CPUHint();
+  if (cpu_hint_->Init(static_cast<HWCDebugHandler *>(HWCDebugHandler::Get())) != kErrorNone) {
+    delete cpu_hint_;
+    cpu_hint_ = NULL;
+  }
+
+  use_metadata_refresh_rate_ = true;
+  int disable_metadata_dynfps = 0;
+  HWCDebugHandler::Get()->GetProperty("persist.metadata_dynfps.disable", &disable_metadata_dynfps);
+  if (disable_metadata_dynfps) {
+    use_metadata_refresh_rate_ = false;
+  }
+
+  return HWCDisplay::Init();
+}
+
+void HWCDisplayPrimary::ProcessBootAnimCompleted() {
+  uint32_t numBootUpLayers = 0;
+  // TODO(user): Remove this hack
+
+  numBootUpLayers = static_cast<uint32_t>(Debug::GetBootAnimLayerCount());
+
+  if (numBootUpLayers == 0) {
+    numBootUpLayers = 2;
+  }
+  /* All other checks namely "init.svc.bootanim" or
+  * HWC_GEOMETRY_CHANGED fail in correctly identifying the
+  * exact bootup transition to homescreen
+  */
+  char cryptoState[PROPERTY_VALUE_MAX];
+  char voldDecryptState[PROPERTY_VALUE_MAX];
+  bool isEncrypted = false;
+  bool main_class_services_started = false;
+  if (property_get("ro.crypto.state", cryptoState, "unencrypted")) {
+    if (!strcmp(cryptoState, "encrypted")) {
+      isEncrypted = true;
+      if (property_get("vold.decrypt", voldDecryptState, "") &&
+          !strcmp(voldDecryptState, "trigger_restart_framework"))
+        main_class_services_started = true;
+    }
+  }
+  if ((!isEncrypted || (isEncrypted && main_class_services_started)) &&
+      (layer_set_.size() > numBootUpLayers)) {
+    boot_animation_completed_ = true;
+    // Applying default mode after bootanimation is finished And
+    // If Data is Encrypted, it is ready for access.
+    if (display_intf_)
+      display_intf_->ApplyDefaultDisplayMode();
+  }
+}
+
+HWC2::Error HWCDisplayPrimary::Validate(uint32_t *out_num_types, uint32_t *out_num_requests) {
+  auto status = HWC2::Error::None;
+  DisplayError error = kErrorNone;
+
+  if (!boot_animation_completed_)
+    ProcessBootAnimCompleted();
+
+  if (display_paused_) {
+    MarkLayersForGPUBypass();
+    return status;
+  }
+
+  // Fill in the remaining blanks in the layers and add them to the SDM layerstack
+  BuildLayerStack();
+
+  bool pending_output_dump = dump_frame_count_ && dump_output_to_file_;
+
+  if (frame_capture_buffer_queued_ || pending_output_dump) {
+    // RHS values were set in FrameCaptureAsync() called from a binder thread. They are picked up
+    // here in a subsequent draw round.
+    layer_stack_.output_buffer = &output_buffer_;
+    layer_stack_.flags.post_processed_output = post_processed_output_;
+  }
+
+  bool one_updating_layer = SingleLayerUpdating();
+  ToggleCPUHint(one_updating_layer);
+
+  uint32_t refresh_rate = GetOptimalRefreshRate(one_updating_layer);
+  if (current_refresh_rate_ != refresh_rate) {
+    error = display_intf_->SetRefreshRate(refresh_rate);
+  }
+
+  if (error == kErrorNone) {
+    // On success, set current refresh rate to new refresh rate
+    current_refresh_rate_ = refresh_rate;
+  }
+
+  if (handle_idle_timeout_) {
+    handle_idle_timeout_ = false;
+  }
+
+  // TODO(user): Validate this
+  if (layer_set_.empty()) {
+    flush_ = true;
+    return status;
+  }
+
+  status = PrepareLayerStack(out_num_types, out_num_requests);
+  return status;
+}
+
+HWC2::Error HWCDisplayPrimary::Present(int32_t *out_retire_fence) {
+  auto status = HWC2::Error::None;
+  if (display_paused_) {
+    // TODO(user): From old HWC implementation
+    // If we do not handle the frame set retireFenceFd to outbufAcquireFenceFd
+    // Revisit this when validating display_paused
+    DisplayError error = display_intf_->Flush();
+    if (error != kErrorNone) {
+      DLOGE("Flush failed. Error = %d", error);
+    }
+  } else {
+    status = HWCDisplay::CommitLayerStack();
+    if (status == HWC2::Error::None) {
+      HandleFrameOutput();
+      status = HWCDisplay::PostCommitLayerStack(out_retire_fence);
+    }
+  }
+  CloseAcquireFds();
+  return status;
+}
+
+int HWCDisplayPrimary::Perform(uint32_t operation, ...) {
+  va_list args;
+  va_start(args, operation);
+  int val = va_arg(args, int32_t);
+  va_end(args);
+  switch (operation) {
+    case SET_METADATA_DYN_REFRESH_RATE:
+      SetMetaDataRefreshRateFlag(val);
+      break;
+    case SET_BINDER_DYN_REFRESH_RATE:
+      ForceRefreshRate(UINT32(val));
+      break;
+    case SET_DISPLAY_MODE:
+      SetDisplayMode(UINT32(val));
+      break;
+    case SET_QDCM_SOLID_FILL_INFO:
+      SetQDCMSolidFillInfo(true, UINT32(val));
+      break;
+    case UNSET_QDCM_SOLID_FILL_INFO:
+      SetQDCMSolidFillInfo(false, UINT32(val));
+      break;
+    default:
+      DLOGW("Invalid operation %d", operation);
+      return -EINVAL;
+  }
+
+  return 0;
+}
+
+DisplayError HWCDisplayPrimary::SetDisplayMode(uint32_t mode) {
+  DisplayError error = kErrorNone;
+
+  if (display_intf_) {
+    error = display_intf_->SetDisplayMode(mode);
+  }
+
+  return error;
+}
+
+void HWCDisplayPrimary::SetMetaDataRefreshRateFlag(bool enable) {
+  int disable_metadata_dynfps = 0;
+
+  HWCDebugHandler::Get()->GetProperty("persist.metadata_dynfps.disable", &disable_metadata_dynfps);
+  if (disable_metadata_dynfps) {
+    return;
+  }
+  use_metadata_refresh_rate_ = enable;
+}
+
+void HWCDisplayPrimary::SetQDCMSolidFillInfo(bool enable, uint32_t color) {
+  solid_fill_enable_ = enable;
+  solid_fill_color_ = color;
+}
+
+void HWCDisplayPrimary::ToggleCPUHint(bool set) {
+  if (!cpu_hint_) {
+    return;
+  }
+
+  if (set) {
+    cpu_hint_->Set();
+  } else {
+    cpu_hint_->Reset();
+  }
+}
+
+void HWCDisplayPrimary::SetSecureDisplay(bool secure_display_active) {
+  if (secure_display_active_ != secure_display_active) {
+    // Skip Prepare and call Flush for null commit
+    DLOGI("SecureDisplay state changed from %d to %d Needs Flush!!", secure_display_active_,
+          secure_display_active);
+    secure_display_active_ = secure_display_active;
+    skip_prepare_ = true;
+  }
+  return;
+}
+
+void HWCDisplayPrimary::ForceRefreshRate(uint32_t refresh_rate) {
+  if ((refresh_rate && (refresh_rate < min_refresh_rate_ || refresh_rate > max_refresh_rate_)) ||
+      force_refresh_rate_ == refresh_rate) {
+    // Cannot honor force refresh rate, as its beyond the range or new request is same
+    return;
+  }
+
+  force_refresh_rate_ = refresh_rate;
+
+  callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
+
+  return;
+}
+
+uint32_t HWCDisplayPrimary::GetOptimalRefreshRate(bool one_updating_layer) {
+  if (force_refresh_rate_) {
+    return force_refresh_rate_;
+  } else if (handle_idle_timeout_) {
+    return min_refresh_rate_;
+  } else if (use_metadata_refresh_rate_ && one_updating_layer && metadata_refresh_rate_) {
+    return metadata_refresh_rate_;
+  }
+
+  return max_refresh_rate_;
+}
+
+DisplayError HWCDisplayPrimary::Refresh() {
+  DisplayError error = kErrorNone;
+
+  callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
+  handle_idle_timeout_ = true;
+
+  return error;
+}
+
+void HWCDisplayPrimary::SetIdleTimeoutMs(uint32_t timeout_ms) {
+  display_intf_->SetIdleTimeoutMs(timeout_ms);
+}
+
+static void SetLayerBuffer(const BufferInfo &output_buffer_info, LayerBuffer *output_buffer) {
+  output_buffer->width = output_buffer_info.buffer_config.width;
+  output_buffer->height = output_buffer_info.buffer_config.height;
+  output_buffer->format = output_buffer_info.buffer_config.format;
+  output_buffer->planes[0].fd = output_buffer_info.alloc_buffer_info.fd;
+  output_buffer->planes[0].stride = output_buffer_info.alloc_buffer_info.stride;
+}
+
+void HWCDisplayPrimary::HandleFrameOutput() {
+  if (frame_capture_buffer_queued_) {
+    HandleFrameCapture();
+  } else if (dump_output_to_file_) {
+    HandleFrameDump();
+  }
+}
+
+void HWCDisplayPrimary::HandleFrameCapture() {
+  if (output_buffer_.release_fence_fd >= 0) {
+    frame_capture_status_ = sync_wait(output_buffer_.release_fence_fd, 1000);
+    ::close(output_buffer_.release_fence_fd);
+    output_buffer_.release_fence_fd = -1;
+  }
+
+  frame_capture_buffer_queued_ = false;
+  post_processed_output_ = false;
+  output_buffer_ = {};
+
+  uint32_t pending = 0;  // Just a temporary to satisfy the API
+  ControlPartialUpdate(true /* enable */, &pending);
+}
+
+void HWCDisplayPrimary::HandleFrameDump() {
+  if (dump_frame_count_ && output_buffer_.release_fence_fd >= 0) {
+    int ret = sync_wait(output_buffer_.release_fence_fd, 1000);
+    ::close(output_buffer_.release_fence_fd);
+    output_buffer_.release_fence_fd = -1;
+    if (ret < 0) {
+      DLOGE("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
+    } else {
+      DumpOutputBuffer(output_buffer_info_, output_buffer_base_, layer_stack_.retire_fence_fd);
+    }
+  }
+
+  if (0 == dump_frame_count_) {
+    dump_output_to_file_ = false;
+    // Unmap and Free buffer
+    if (munmap(output_buffer_base_, output_buffer_info_.alloc_buffer_info.size) != 0) {
+      DLOGE("unmap failed with err %d", errno);
+    }
+    if (buffer_allocator_->FreeBuffer(&output_buffer_info_) != 0) {
+      DLOGE("FreeBuffer failed");
+    }
+
+    post_processed_output_ = false;
+    output_buffer_ = {};
+    output_buffer_info_ = {};
+    output_buffer_base_ = nullptr;
+
+    uint32_t pending = 0;  // Just a temporary to satisfy the API
+    ControlPartialUpdate(true /* enable */, &pending);
+  }
+}
+
+void HWCDisplayPrimary::SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type) {
+  HWCDisplay::SetFrameDumpConfig(count, bit_mask_layer_type);
+  dump_output_to_file_ = bit_mask_layer_type & (1 << OUTPUT_LAYER_DUMP);
+  DLOGI("output_layer_dump_enable %d", dump_output_to_file_);
+
+  if (!count || !dump_output_to_file_) {
+    return;
+  }
+
+  // Allocate and map output buffer
+  output_buffer_info_ = {};
+  // Since we dump DSPP output use Panel resolution.
+  GetPanelResolution(&output_buffer_info_.buffer_config.width,
+                     &output_buffer_info_.buffer_config.height);
+  output_buffer_info_.buffer_config.format = kFormatRGB888;
+  output_buffer_info_.buffer_config.buffer_count = 1;
+  if (buffer_allocator_->AllocateBuffer(&output_buffer_info_) != 0) {
+    DLOGE("Buffer allocation failed");
+    output_buffer_info_ = {};
+    return;
+  }
+
+  void *buffer = mmap(NULL, output_buffer_info_.alloc_buffer_info.size, PROT_READ | PROT_WRITE,
+                      MAP_SHARED, output_buffer_info_.alloc_buffer_info.fd, 0);
+
+  if (buffer == MAP_FAILED) {
+    DLOGE("mmap failed with err %d", errno);
+    buffer_allocator_->FreeBuffer(&output_buffer_info_);
+    output_buffer_info_ = {};
+    return;
+  }
+
+  output_buffer_base_ = buffer;
+  post_processed_output_ = true;
+  uint32_t pending = 0;  // Just a temporary to satisfy the API
+  ControlPartialUpdate(false /* enable */, &pending);
+}
+
+int HWCDisplayPrimary::FrameCaptureAsync(const BufferInfo &output_buffer_info,
+                                         bool post_processed_output) {
+  // Note: This function is called in context of a binder thread and a lock is already held
+  if (output_buffer_info.alloc_buffer_info.fd < 0) {
+    DLOGE("Invalid fd %d", output_buffer_info.alloc_buffer_info.fd);
+    return -1;
+  }
+
+  auto panel_width = 0u;
+  auto panel_height = 0u;
+  auto fb_width = 0u;
+  auto fb_height = 0u;
+
+  GetPanelResolution(&panel_width, &panel_height);
+  GetFrameBufferResolution(&fb_width, &fb_height);
+
+  if (post_processed_output && (output_buffer_info_.buffer_config.width < panel_width ||
+                                output_buffer_info_.buffer_config.height < panel_height)) {
+    DLOGE("Buffer dimensions should not be less than panel resolution");
+    return -1;
+  } else if (!post_processed_output && (output_buffer_info_.buffer_config.width < fb_width ||
+                                        output_buffer_info_.buffer_config.height < fb_height)) {
+    DLOGE("Buffer dimensions should not be less than FB resolution");
+    return -1;
+  }
+
+  SetLayerBuffer(output_buffer_info, &output_buffer_);
+  post_processed_output_ = post_processed_output;
+  frame_capture_buffer_queued_ = true;
+  // Status is only cleared on a new call to dump and remains valid otherwise
+  frame_capture_status_ = -EAGAIN;
+
+  uint32_t pending = 0;  // Just a temporary to satisfy the API
+  ControlPartialUpdate(false /* enable */, &pending);
+
+  return 0;
+}
+
+}  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_display_primary.h b/sdm/libs/hwc2/hwc_display_primary.h
new file mode 100644
index 0000000..2779f1b
--- /dev/null
+++ b/sdm/libs/hwc2/hwc_display_primary.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of The Linux Foundation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __HWC_DISPLAY_PRIMARY_H__
+#define __HWC_DISPLAY_PRIMARY_H__
+
+#include "cpuhint.h"
+#include "hwc_display.h"
+
+namespace sdm {
+
+class HWCDisplayPrimary : public HWCDisplay {
+ public:
+  enum {
+    SET_METADATA_DYN_REFRESH_RATE,
+    SET_BINDER_DYN_REFRESH_RATE,
+    SET_DISPLAY_MODE,
+    SET_QDCM_SOLID_FILL_INFO,
+    UNSET_QDCM_SOLID_FILL_INFO,
+  };
+
+  static int Create(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
+                    HWCCallbacks *callbacks, qService::QService *qservice,
+                    HWCDisplay **hwc_display);
+  static void Destroy(HWCDisplay *hwc_display);
+  virtual int Init();
+  virtual HWC2::Error Validate(uint32_t *out_num_types, uint32_t *out_num_requests);
+  virtual HWC2::Error Present(int32_t *out_retire_fence);
+  virtual int Perform(uint32_t operation, ...);
+  virtual void SetSecureDisplay(bool secure_display_active);
+  virtual DisplayError Refresh();
+  virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
+  virtual void SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type);
+  virtual int FrameCaptureAsync(const BufferInfo &output_buffer_info, bool post_processed);
+  virtual int GetFrameCaptureStatus() { return frame_capture_status_; }
+
+ private:
+  HWCDisplayPrimary(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
+                    HWCCallbacks *callbacks, qService::QService *qservice);
+  void SetMetaDataRefreshRateFlag(bool enable);
+  virtual DisplayError SetDisplayMode(uint32_t mode);
+  void ProcessBootAnimCompleted(void);
+  void SetQDCMSolidFillInfo(bool enable, uint32_t color);
+  void ToggleCPUHint(bool set);
+  void ForceRefreshRate(uint32_t refresh_rate);
+  uint32_t GetOptimalRefreshRate(bool one_updating_layer);
+  void HandleFrameOutput();
+  void HandleFrameCapture();
+  void HandleFrameDump();
+
+  BufferAllocator *buffer_allocator_ = nullptr;
+  CPUHint *cpu_hint_ = nullptr;
+  bool handle_idle_timeout_ = false;
+
+  // Primary output buffer configuration
+  LayerBuffer output_buffer_ = {};
+  bool post_processed_output_ = false;
+
+  // Members for 1 frame capture in a client provided buffer
+  bool frame_capture_buffer_queued_ = false;
+  int frame_capture_status_ = -EAGAIN;
+
+  // Members for N frame output dump to file
+  bool dump_output_to_file_ = false;
+  BufferInfo output_buffer_info_ = {};
+  void *output_buffer_base_ = nullptr;
+};
+
+}  // namespace sdm
+
+#endif  // __HWC_DISPLAY_PRIMARY_H__
diff --git a/sdm/libs/hwc2/hwc_display_virtual.cpp b/sdm/libs/hwc2/hwc_display_virtual.cpp
new file mode 100644
index 0000000..6c7edfb
--- /dev/null
+++ b/sdm/libs/hwc2/hwc_display_virtual.cpp
@@ -0,0 +1,194 @@
+/*
+* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*     * Redistributions of source code must retain the above copyright
+*       notice, this list of conditions and the following disclaimer.
+*     * Redistributions in binary form must reproduce the above
+*       copyright notice, this list of conditions and the following
+*       disclaimer in the documentation and/or other materials provided
+*       with the distribution.
+*     * Neither the name of The Linux Foundation nor the names of its
+*       contributors may be used to endorse or promote products derived
+*       from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <utils/constants.h>
+#include <utils/debug.h>
+#include <sync/sync.h>
+#include <stdarg.h>
+#include <gr.h>
+
+#include "hwc_display_virtual.h"
+#include "hwc_debugger.h"
+
+#define __CLASS__ "HWCDisplayVirtual"
+
+namespace sdm {
+
+int HWCDisplayVirtual::Create(CoreInterface *core_intf, HWCCallbacks *callbacks, uint32_t width,
+                              uint32_t height, HWCDisplay **hwc_display) {
+  int status = 0;
+  HWCDisplayVirtual *hwc_display_virtual = new HWCDisplayVirtual(core_intf, callbacks);
+  uint32_t virtual_width = 0, virtual_height = 0;
+
+  status = hwc_display_virtual->Init();
+  if (status) {
+    delete hwc_display_virtual;
+    return status;
+  }
+
+  status = INT32(hwc_display_virtual->SetPowerMode(HWC2::PowerMode::On));
+  if (status) {
+    Destroy(hwc_display_virtual);
+    return status;
+  }
+
+  hwc_display_virtual->GetPanelResolution(&virtual_width, &virtual_height);
+
+  status = hwc_display_virtual->SetFrameBufferResolution(width, height);
+
+  if (status) {
+    Destroy(hwc_display_virtual);
+    return status;
+  }
+
+  *hwc_display = static_cast<HWCDisplay *>(hwc_display_virtual);
+
+  return 0;
+}
+
+void HWCDisplayVirtual::Destroy(HWCDisplay *hwc_display) {
+  hwc_display->Deinit();
+  delete hwc_display;
+}
+
+HWCDisplayVirtual::HWCDisplayVirtual(CoreInterface *core_intf, HWCCallbacks *callbacks)
+    : HWCDisplay(core_intf, callbacks, kVirtual, HWC_DISPLAY_VIRTUAL, false, NULL,
+                 DISPLAY_CLASS_VIRTUAL) {
+}
+
+int HWCDisplayVirtual::Init() {
+  return HWCDisplay::Init();
+}
+
+int HWCDisplayVirtual::Deinit() {
+  int status = 0;
+
+  status = HWCDisplay::Deinit();
+
+  return status;
+}
+
+HWC2::Error HWCDisplayVirtual::Validate(uint32_t *out_num_types, uint32_t *out_num_requests) {
+  auto status = HWC2::Error::None;
+
+  if (display_paused_) {
+    MarkLayersForGPUBypass();
+    return status;
+  }
+
+  BuildLayerStack();
+  status = PrepareLayerStack(out_num_types, out_num_requests);
+  return status;
+}
+
+HWC2::Error HWCDisplayVirtual::Present(int32_t *out_retire_fence) {
+  auto status = HWC2::Error::None;
+  if (display_paused_) {
+    DisplayError error = display_intf_->Flush();
+    if (error != kErrorNone) {
+      DLOGE("Flush failed. Error = %d", error);
+    }
+  } else {
+    status = HWCDisplay::CommitLayerStack();
+    if (status == HWC2::Error::None) {
+      if (dump_frame_count_ && !flush_ && dump_output_layer_) {
+        if (output_handle_ && output_handle_->base) {
+          BufferInfo buffer_info;
+          const private_handle_t *output_handle =
+              reinterpret_cast<const private_handle_t *>(output_buffer_->buffer_id);
+          buffer_info.buffer_config.width = static_cast<uint32_t>(output_handle->width);
+          buffer_info.buffer_config.height = static_cast<uint32_t>(output_handle->height);
+          buffer_info.buffer_config.format =
+              GetSDMFormat(output_handle->format, output_handle->flags);
+          buffer_info.alloc_buffer_info.size = static_cast<uint32_t>(output_handle->size);
+          DumpOutputBuffer(buffer_info, reinterpret_cast<void *>(output_handle->base),
+                           layer_stack_.retire_fence_fd);
+        }
+      }
+
+      status = HWCDisplay::PostCommitLayerStack(out_retire_fence);
+    }
+  }
+  CloseAcquireFds();
+  return status;
+}
+
+HWC2::Error HWCDisplayVirtual::SetOutputBuffer(buffer_handle_t buf, int32_t release_fence) {
+  const private_handle_t *output_handle = static_cast<const private_handle_t *>(buf);
+
+  // Fill output buffer parameters (width, height, format, plane information, fence)
+  output_buffer_->acquire_fence_fd = dup(release_fence);
+
+  if (output_handle) {
+    output_buffer_->buffer_id = reinterpret_cast<uint64_t>(output_handle);
+    int output_handle_format = output_handle->format;
+
+    if (output_handle_format == HAL_PIXEL_FORMAT_RGBA_8888) {
+      output_handle_format = HAL_PIXEL_FORMAT_RGBX_8888;
+    }
+
+    output_buffer_->format = GetSDMFormat(output_handle_format, output_handle->flags);
+
+    if (output_buffer_->format == kFormatInvalid) {
+      return HWC2::Error::BadParameter;
+    }
+
+    int output_buffer_width, output_buffer_height;
+    AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(output_handle, output_buffer_width,
+                                                          output_buffer_height);
+
+    output_buffer_->width = UINT32(output_buffer_width);
+    output_buffer_->height = UINT32(output_buffer_height);
+    // TODO(mkavm): Handle DRC and metadata changes
+    output_buffer_->flags.secure = 0;
+    output_buffer_->flags.video = 0;
+
+    // TZ Protected Buffer - L1
+    if (output_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
+      output_buffer_->flags.secure = 1;
+    }
+
+    // ToDo: Need to extend for non-RGB formats
+    output_buffer_->planes[0].fd = output_handle->fd;
+    output_buffer_->planes[0].offset = output_handle->offset;
+    output_buffer_->planes[0].stride = UINT32(output_handle->width);
+  }
+
+  layer_stack_.output_buffer = output_buffer_;
+  return HWC2::Error::None;
+}
+
+void HWCDisplayVirtual::SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type) {
+  HWCDisplay::SetFrameDumpConfig(count, bit_mask_layer_type);
+  dump_output_layer_ = ((bit_mask_layer_type & (1 << OUTPUT_LAYER_DUMP)) != 0);
+
+  DLOGI("output_layer_dump_enable %d", dump_output_layer_);
+}
+
+}  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_display_virtual.h b/sdm/libs/hwc2/hwc_display_virtual.h
new file mode 100644
index 0000000..271d15d
--- /dev/null
+++ b/sdm/libs/hwc2/hwc_display_virtual.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of The Linux Foundation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __HWC_DISPLAY_VIRTUAL_H__
+#define __HWC_DISPLAY_VIRTUAL_H__
+
+#include <qdMetaData.h>
+#include <gralloc_priv.h>
+#include "hwc_display.h"
+
+namespace sdm {
+
+class HWCDisplayVirtual : public HWCDisplay {
+ public:
+  static int Create(CoreInterface *core_intf, HWCCallbacks *callbacks, uint32_t primary_width,
+                    uint32_t primary_height, HWCDisplay **hwc_display);
+  static void Destroy(HWCDisplay *hwc_display);
+  virtual int Init();
+  virtual int Deinit();
+  virtual HWC2::Error Validate(uint32_t *out_num_types, uint32_t *out_num_requests);
+  virtual HWC2::Error Present(int32_t *out_retire_fence);
+  virtual void SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type);
+  HWC2::Error SetOutputBuffer(buffer_handle_t buf, int32_t release_fence);
+
+ private:
+  HWCDisplayVirtual(CoreInterface *core_intf, HWCCallbacks *callbacks);
+
+  bool dump_output_layer_ = false;
+  LayerBuffer *output_buffer_ = NULL;
+  const private_handle_t *output_handle_ = nullptr;
+};
+
+}  // namespace sdm
+
+#endif  // __HWC_DISPLAY_VIRTUAL_H__
diff --git a/sdm/libs/hwc2/hwc_layers.cpp b/sdm/libs/hwc2/hwc_layers.cpp
new file mode 100644
index 0000000..ada1cac
--- /dev/null
+++ b/sdm/libs/hwc2/hwc_layers.cpp
@@ -0,0 +1,522 @@
+/*
+ * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright 2015 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 "hwc_layers.h"
+#include <gr.h>
+#include <utils/debug.h>
+#include <cmath>
+
+#define __CLASS__ "HWCLayer"
+
+namespace sdm {
+
+std::atomic<hwc2_layer_t> HWCLayer::next_id_(1);
+
+// Layer operations
+HWCLayer::HWCLayer(hwc2_display_t display_id) : id_(next_id_++), display_id_(display_id) {
+  layer_ = new Layer();
+  layer_->input_buffer = new LayerBuffer();
+  // Fences are deferred, so the first time this layer is presented, return -1
+  // TODO(user): Verify that fences are properly obtained on suspend/resume
+  release_fences_.push(-1);
+}
+
+HWCLayer::~HWCLayer() {
+  // Close any fences left for this layer
+  while (!release_fences_.empty()) {
+    close(release_fences_.front());
+    release_fences_.pop();
+  }
+
+  if (layer_) {
+    if (layer_->input_buffer) {
+      delete (layer_->input_buffer);
+    }
+    delete layer_;
+  }
+}
+
+HWC2::Error HWCLayer::SetLayerBuffer(buffer_handle_t buffer, int32_t acquire_fence) {
+  if (!buffer) {
+    DLOGE("Invalid buffer handle: %p on layer: %d", buffer, id_);
+    return HWC2::Error::BadParameter;
+  }
+
+  const private_handle_t *handle = static_cast<const private_handle_t *>(buffer);
+  LayerBuffer *layer_buffer = layer_->input_buffer;
+  layer_buffer->width = UINT32(handle->width);
+  layer_buffer->height = UINT32(handle->height);
+  layer_buffer->format = GetSDMFormat(handle->format, handle->flags);
+  if (SetMetaData(handle, layer_) != kErrorNone) {
+    return HWC2::Error::BadLayer;
+  }
+
+  if (handle->bufferType == BUFFER_TYPE_VIDEO) {
+    layer_buffer->flags.video = true;
+  }
+  // TZ Protected Buffer - L1
+  if (handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
+    layer_buffer->flags.secure = true;
+  }
+  if (handle->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY) {
+    layer_buffer->flags.secure_display = true;
+  }
+
+  layer_buffer->planes[0].fd = handle->fd;
+  layer_buffer->planes[0].offset = handle->offset;
+  layer_buffer->planes[0].stride = UINT32(handle->width);
+  layer_buffer->acquire_fence_fd = acquire_fence;
+  layer_buffer->buffer_id = reinterpret_cast<uint64_t>(handle);
+
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCLayer::SetLayerSurfaceDamage(hwc_region_t damage) {
+  auto num_dirty_rects = damage.numRects;
+  if (num_dirty_rects > 0) {
+    for (uint32_t i = 0; i <= damage.numRects; i++) {
+      LayerRect rect;
+      SetRect(damage.rects[i], &rect);
+      layer_->dirty_regions.push_back(rect);
+    }
+  }
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCLayer::SetLayerBlendMode(HWC2::BlendMode mode) {
+  switch (mode) {
+    case HWC2::BlendMode::Coverage:
+      layer_->blending = kBlendingCoverage;
+      break;
+    case HWC2::BlendMode::Premultiplied:
+      layer_->blending = kBlendingPremultiplied;
+      break;
+    case HWC2::BlendMode::None:
+      layer_->blending = kBlendingOpaque;
+      break;
+    default:
+      return HWC2::Error::BadParameter;
+  }
+  geometry_changes_ |= kBlendMode;
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCLayer::SetLayerColor(hwc_color_t color) {
+  layer_->solid_fill_color = GetUint32Color(color);
+  layer_->input_buffer->format = kFormatARGB8888;
+  DLOGD("Layer color set to: %u", layer_->solid_fill_color);
+  DLOGD("[%" PRIu64 "][%" PRIu64 "] Layer color set to %u  %" PRIu64, display_id_, id_,
+        layer_->solid_fill_color);
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCLayer::SetLayerCompositionType(HWC2::Composition type) {
+  layer_->flags = {};   // Reset earlier flags
+  composition_ = type;  // Used to compute changes
+  switch (type) {
+    case HWC2::Composition::Client:
+      layer_->flags.skip = true;
+      break;
+    case HWC2::Composition::Device:
+      // We try and default to this in SDM
+      break;
+    case HWC2::Composition::SolidColor:
+      layer_->flags.solid_fill = true;
+      break;
+    case HWC2::Composition::Cursor:
+      layer_->flags.cursor = true;
+      break;
+    case HWC2::Composition::Invalid:
+      return HWC2::Error::BadParameter;
+    default:
+      return HWC2::Error::Unsupported;
+  }
+  // TODO(user): Check if this should be set here or somewhere else
+  layer_->flags.updating = true;
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCLayer::SetLayerDataspace(int32_t dataspace) {
+  // TODO(user): Implement later
+  geometry_changes_ |= kDataspace;
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCLayer::SetLayerDisplayFrame(hwc_rect_t frame) {
+  SetRect(frame, &layer_->dst_rect);
+  geometry_changes_ |= kDisplayFrame;
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCLayer::SetLayerPlaneAlpha(float alpha) {
+  // Conversion of float alpha in range 0.0 to 1.0 similar to the HWC Adapter
+  layer_->plane_alpha = static_cast<uint8_t>(std::round(255.0f * alpha));
+  geometry_changes_ |= kPlaneAlpha;
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCLayer::SetLayerSourceCrop(hwc_frect_t crop) {
+  SetRect(crop, &layer_->src_rect);
+  geometry_changes_ |= kSourceCrop;
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCLayer::SetLayerTransform(HWC2::Transform transform) {
+  switch (transform) {
+    case HWC2::Transform::FlipH:
+      layer_->transform.flip_horizontal = true;
+      break;
+    case HWC2::Transform::FlipV:
+      layer_->transform.flip_vertical = true;
+      break;
+    case HWC2::Transform::Rotate90:
+      layer_->transform.rotation = 90.0f;
+      break;
+    case HWC2::Transform::Rotate180:
+      layer_->transform.rotation = 180.0f;
+      break;
+    case HWC2::Transform::Rotate270:
+      layer_->transform.rotation = 270.0f;
+      break;
+    case HWC2::Transform::FlipHRotate90:
+      layer_->transform.rotation = 90.0f;
+      layer_->transform.flip_horizontal = true;
+      break;
+    case HWC2::Transform::FlipVRotate90:
+      layer_->transform.rotation = 90.0f;
+      layer_->transform.flip_vertical = true;
+      break;
+    default:
+      layer_->transform.rotation = 0.0f;
+      layer_->transform.flip_horizontal = false;
+      layer_->transform.flip_vertical = false;
+  }
+  geometry_changes_ |= kTransform;
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCLayer::SetLayerVisibleRegion(hwc_region_t visible) {
+  auto num_dirty_rects = visible.numRects;
+  if (num_dirty_rects > 0) {
+    for (uint32_t i = 0; i <= visible.numRects; i++) {
+      LayerRect rect;
+      SetRect(visible.rects[i], &rect);
+      layer_->visible_regions.push_back(rect);
+    }
+  }
+
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCLayer::SetLayerZOrder(uint32_t z) {
+  z_ = z;
+  geometry_changes_ |= kZOrder;
+  return HWC2::Error::None;
+}
+
+void HWCLayer::SetRect(const hwc_rect_t &source, LayerRect *target) {
+  target->left = FLOAT(source.left);
+  target->top = FLOAT(source.top);
+  target->right = FLOAT(source.right);
+  target->bottom = FLOAT(source.bottom);
+}
+
+void HWCLayer::SetRect(const hwc_frect_t &source, LayerRect *target) {
+  // Recommended way of rounding as in hwcomposer2.h - SetLayerSourceCrop
+  target->left = std::ceil(source.left);
+  target->top = std::ceil(source.top);
+  target->right = std::floor(source.right);
+  target->bottom = std::floor(source.bottom);
+}
+
+uint32_t HWCLayer::GetUint32Color(const hwc_color_t &source) {
+  // Returns 32 bit ARGB
+  uint32_t a = UINT32(source.a) << 24;
+  uint32_t r = UINT32(source.r) << 16;
+  uint32_t g = UINT32(source.g) << 8;
+  uint32_t b = UINT32(source.b);
+  uint32_t color = a & r & g & b;
+  return color;
+}
+
+LayerBufferFormat HWCLayer::GetSDMFormat(const int32_t &source, const int flags) {
+  LayerBufferFormat format = kFormatInvalid;
+  if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
+    switch (source) {
+      case HAL_PIXEL_FORMAT_RGBA_8888:
+        format = kFormatRGBA8888Ubwc;
+        break;
+      case HAL_PIXEL_FORMAT_RGBX_8888:
+        format = kFormatRGBX8888Ubwc;
+        break;
+      case HAL_PIXEL_FORMAT_BGR_565:
+        format = kFormatBGR565Ubwc;
+        break;
+      case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+      case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+      case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+        format = kFormatYCbCr420SPVenusUbwc;
+        break;
+      default:
+        DLOGE("Unsupported format type for UBWC %d", source);
+        return kFormatInvalid;
+    }
+    return format;
+  }
+
+  switch (source) {
+    case HAL_PIXEL_FORMAT_RGBA_8888:
+      format = kFormatRGBA8888;
+      break;
+    case HAL_PIXEL_FORMAT_RGBA_5551:
+      format = kFormatRGBA5551;
+      break;
+    case HAL_PIXEL_FORMAT_RGBA_4444:
+      format = kFormatRGBA4444;
+      break;
+    case HAL_PIXEL_FORMAT_BGRA_8888:
+      format = kFormatBGRA8888;
+      break;
+    case HAL_PIXEL_FORMAT_RGBX_8888:
+      format = kFormatRGBX8888;
+      break;
+    case HAL_PIXEL_FORMAT_BGRX_8888:
+      format = kFormatBGRX8888;
+      break;
+    case HAL_PIXEL_FORMAT_RGB_888:
+      format = kFormatRGB888;
+      break;
+    case HAL_PIXEL_FORMAT_RGB_565:
+      format = kFormatRGB565;
+      break;
+    case HAL_PIXEL_FORMAT_BGR_565:
+      format = kFormatBGR565;
+      break;
+    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+      format = kFormatYCbCr420SemiPlanarVenus;
+      break;
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
+      format = kFormatYCrCb420SemiPlanarVenus;
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+      format = kFormatYCbCr420SPVenusUbwc;
+      break;
+    case HAL_PIXEL_FORMAT_YV12:
+      format = kFormatYCrCb420PlanarStride16;
+      break;
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+      format = kFormatYCrCb420SemiPlanar;
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+      format = kFormatYCbCr420SemiPlanar;
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+      format = kFormatYCbCr422H2V1SemiPlanar;
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_422_I:
+      format = kFormatYCbCr422H2V1Packed;
+      break;
+    case HAL_PIXEL_FORMAT_RGBA_1010102:
+      format = kFormatRGBA1010102;
+      break;
+    case HAL_PIXEL_FORMAT_ARGB_2101010:
+      format = kFormatARGB2101010;
+      break;
+    case HAL_PIXEL_FORMAT_RGBX_1010102:
+      format = kFormatRGBX1010102;
+      break;
+    case HAL_PIXEL_FORMAT_XRGB_2101010:
+      format = kFormatXRGB2101010;
+      break;
+    case HAL_PIXEL_FORMAT_BGRA_1010102:
+      format = kFormatBGRA1010102;
+      break;
+    case HAL_PIXEL_FORMAT_ABGR_2101010:
+      format = kFormatABGR2101010;
+      break;
+    case HAL_PIXEL_FORMAT_BGRX_1010102:
+      format = kFormatBGRX1010102;
+      break;
+    case HAL_PIXEL_FORMAT_XBGR_2101010:
+      format = kFormatXBGR2101010;
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_420_P010:
+      format = kFormatYCbCr420P010;
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+      format = kFormatYCbCr420TP10Ubwc;
+      break;
+    default:
+      DLOGW("Unsupported format type = %d", source);
+      return kFormatInvalid;
+  }
+
+  return format;
+}
+
+LayerBufferS3DFormat HWCLayer::GetS3DFormat(uint32_t s3d_format) {
+  LayerBufferS3DFormat sdm_s3d_format = kS3dFormatNone;
+  switch (s3d_format) {
+    case HAL_NO_3D:
+      sdm_s3d_format = kS3dFormatNone;
+      break;
+    case HAL_3D_SIDE_BY_SIDE_L_R:
+      sdm_s3d_format = kS3dFormatLeftRight;
+      break;
+    case HAL_3D_SIDE_BY_SIDE_R_L:
+      sdm_s3d_format = kS3dFormatRightLeft;
+      break;
+    case HAL_3D_TOP_BOTTOM:
+      sdm_s3d_format = kS3dFormatTopBottom;
+      break;
+    default:
+      DLOGW("Invalid S3D format %d", s3d_format);
+  }
+  return sdm_s3d_format;
+}
+
+DisplayError HWCLayer::SetMetaData(const private_handle_t *pvt_handle, Layer *layer) {
+  const MetaData_t *meta_data = reinterpret_cast<MetaData_t *>(pvt_handle->base_metadata);
+  LayerBuffer *layer_buffer = layer->input_buffer;
+
+  if (!meta_data) {
+    return kErrorNone;
+  }
+
+  if (meta_data->operation & UPDATE_COLOR_SPACE) {
+    if (SetCSC(meta_data->colorSpace, &layer->csc) != kErrorNone) {
+      return kErrorNotSupported;
+    }
+  }
+
+  if (meta_data->operation & SET_IGC) {
+    if (SetIGC(meta_data->igc, &layer->igc) != kErrorNone) {
+      return kErrorNotSupported;
+    }
+  }
+
+  if (meta_data->operation & UPDATE_REFRESH_RATE) {
+    layer->frame_rate = RoundToStandardFPS(meta_data->refreshrate);
+  }
+
+  if ((meta_data->operation & PP_PARAM_INTERLACED) && meta_data->interlaced) {
+    layer_buffer->flags.interlace = true;
+  }
+
+  if (meta_data->operation & LINEAR_FORMAT) {
+    layer_buffer->format = GetSDMFormat(INT32(meta_data->linearFormat), 0);
+  }
+
+  if (meta_data->operation & UPDATE_BUFFER_GEOMETRY) {
+    int actual_width = pvt_handle->width;
+    int actual_height = pvt_handle->height;
+    AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(pvt_handle, actual_width, actual_height);
+    layer_buffer->width = UINT32(actual_width);
+    layer_buffer->height = UINT32(actual_height);
+  }
+
+  if (meta_data->operation & S3D_FORMAT) {
+    layer_buffer->s3d_format = GetS3DFormat(meta_data->s3dFormat);
+  }
+
+  return kErrorNone;
+}
+
+DisplayError HWCLayer::SetCSC(ColorSpace_t source, LayerCSC *target) {
+  switch (source) {
+    case ITU_R_601:
+      *target = kCSCLimitedRange601;
+      break;
+    case ITU_R_601_FR:
+      *target = kCSCFullRange601;
+      break;
+    case ITU_R_709:
+      *target = kCSCLimitedRange709;
+      break;
+    default:
+      DLOGE("Unsupported CSC: %d", source);
+      return kErrorNotSupported;
+  }
+
+  return kErrorNone;
+}
+
+DisplayError HWCLayer::SetIGC(IGC_t source, LayerIGC *target) {
+  switch (source) {
+    case IGC_NotSpecified:
+      *target = kIGCNotSpecified;
+      break;
+    case IGC_sRGB:
+      *target = kIGCsRGB;
+      break;
+    default:
+      DLOGE("Unsupported IGC: %d", source);
+      return kErrorNotSupported;
+  }
+
+  return kErrorNone;
+}
+
+uint32_t HWCLayer::RoundToStandardFPS(uint32_t fps) {
+  static const uint32_t standard_fps[4] = {30, 24, 48, 60};
+
+  int count = INT(sizeof(standard_fps) / sizeof(standard_fps[0]));
+  for (int i = 0; i < count; i++) {
+    if ((standard_fps[i] - fps) < 2) {
+      // Most likely used for video, the fps can fluctuate
+      // Ex: b/w 29 and 30 for 30 fps clip
+      return standard_fps[i];
+    }
+  }
+
+  return fps;
+}
+
+void HWCLayer::SetComposition(const LayerComposition &source) {
+  auto composition = HWC2::Composition::Invalid;
+  switch (source) {
+    case kCompositionGPU:
+      composition = HWC2::Composition::Client;
+      break;
+    case kCompositionHWCursor:
+      composition = HWC2::Composition::Cursor;
+      break;
+    default:
+      composition = HWC2::Composition::Device;
+      break;
+  }
+  // Update solid fill composition
+  if (layer_->composition == kCompositionSDE && layer_->flags.solid_fill != 0) {
+    composition = HWC2::Composition::SolidColor;
+  }
+  composition_ = composition;
+}
+void HWCLayer::PushReleaseFence(int32_t fence) {
+  release_fences_.push(fence);
+}
+int32_t HWCLayer::PopReleaseFence(void) {
+  if (release_fences_.empty())
+    return -1;
+  auto fence = release_fences_.front();
+  release_fences_.pop();
+  return fence;
+}
+
+}  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_layers.h b/sdm/libs/hwc2/hwc_layers.h
new file mode 100644
index 0000000..b756c38
--- /dev/null
+++ b/sdm/libs/hwc2/hwc_layers.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright 2015 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 __HWC_LAYERS_H__
+#define __HWC_LAYERS_H__
+
+/* This class translates HWC2 Layer functions to the SDM LayerStack
+ */
+
+#include <gralloc_priv.h>
+#include <qdMetaData.h>
+#include <core/layer_stack.h>
+#define HWC2_INCLUDE_STRINGIFICATION
+#define HWC2_USE_CPP11
+#include <hardware/hwcomposer2.h>
+#undef HWC2_INCLUDE_STRINGIFICATION
+#undef HWC2_USE_CPP11
+#include <set>
+#include <map>
+#include <queue>
+
+namespace sdm {
+
+enum GeometryChanges {
+  kNone         = 0x000,
+  kBlendMode    = 0x001,
+  kDataspace    = 0x002,
+  kDisplayFrame = 0x004,
+  kPlaneAlpha   = 0x008,
+  kSourceCrop   = 0x010,
+  kTransform    = 0x020,
+  kZOrder       = 0x040,
+  kAdded        = 0x080,
+  kRemoved      = 0x100,
+};
+
+class HWCLayer {
+ public:
+  explicit HWCLayer(hwc2_display_t display_id);
+  ~HWCLayer();
+  uint32_t GetZ() const { return z_; }
+  hwc2_layer_t GetId() const { return id_; }
+  Layer *GetSDMLayer() { return layer_; }
+
+  HWC2::Error SetLayerBlendMode(HWC2::BlendMode mode);
+  HWC2::Error SetLayerBuffer(buffer_handle_t buffer, int32_t acquire_fence);
+  HWC2::Error SetLayerColor(hwc_color_t color);
+  HWC2::Error SetLayerCompositionType(HWC2::Composition type);
+  HWC2::Error SetLayerDataspace(int32_t dataspace);
+  HWC2::Error SetLayerDisplayFrame(hwc_rect_t frame);
+  HWC2::Error SetLayerPlaneAlpha(float alpha);
+  HWC2::Error SetLayerSourceCrop(hwc_frect_t crop);
+  HWC2::Error SetLayerSurfaceDamage(hwc_region_t damage);
+  HWC2::Error SetLayerTransform(HWC2::Transform transform);
+  HWC2::Error SetLayerVisibleRegion(hwc_region_t visible);
+  HWC2::Error SetLayerZOrder(uint32_t z);
+  void SetComposition(const LayerComposition &source);
+  HWC2::Composition GetCompositionType() { return composition_; }
+  uint32_t GetGeometryChanges() { return geometry_changes_; }
+  void ResetGeometryChanges() { geometry_changes_ = GeometryChanges::kNone; }
+  void PushReleaseFence(int32_t fence);
+  int32_t PopReleaseFence(void);
+
+ private:
+  Layer *layer_ = nullptr;
+  uint32_t z_ = 0;
+  const hwc2_layer_t id_;
+  const hwc2_display_t display_id_;
+  static std::atomic<hwc2_layer_t> next_id_;
+  std::queue<int32_t> release_fences_;
+
+  HWC2::Composition composition_ = HWC2::Composition::Device;
+  uint32_t geometry_changes_ = GeometryChanges::kNone;
+
+  void SetRect(const hwc_rect_t &source, LayerRect *target);
+  void SetRect(const hwc_frect_t &source, LayerRect *target);
+  uint32_t GetUint32Color(const hwc_color_t &source);
+  LayerBufferFormat GetSDMFormat(const int32_t &source, const int flags);
+  LayerBufferS3DFormat GetS3DFormat(uint32_t s3d_format);
+  DisplayError SetMetaData(const private_handle_t *pvt_handle, Layer *layer);
+  DisplayError SetCSC(ColorSpace_t source, LayerCSC *target);
+  DisplayError SetIGC(IGC_t source, LayerIGC *target);
+  uint32_t RoundToStandardFPS(uint32_t fps);
+};
+
+struct SortLayersByZ {
+  bool operator()(const HWCLayer *lhs, const HWCLayer *rhs) {
+    return lhs->GetZ() < rhs->GetZ();
+  }
+};
+
+}  // namespace sdm
+#endif  // __HWC_LAYERS_H__
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
new file mode 100644
index 0000000..66eeb1e
--- /dev/null
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -0,0 +1,1514 @@
+/*
+ * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright 2015 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 <core/dump_interface.h>
+#include <core/buffer_allocator.h>
+#include <private/color_params.h>
+#include <utils/constants.h>
+#include <utils/String16.h>
+#include <cutils/properties.h>
+#include <hardware_legacy/uevent.h>
+#include <sys/resource.h>
+#include <sys/prctl.h>
+#include <binder/Parcel.h>
+#include <QService.h>
+#include <gr.h>
+#include <gralloc_priv.h>
+#include <display_config.h>
+#include <utils/debug.h>
+#include <sync/sync.h>
+#include <profiler.h>
+#include <string>
+
+#include "hwc_buffer_allocator.h"
+#include "hwc_buffer_sync_handler.h"
+#include "hwc_session.h"
+#include "hwc_debugger.h"
+#include "hwc_display_primary.h"
+#include "hwc_display_virtual.h"
+
+#define __CLASS__ "HWCSession"
+
+#define HWC_UEVENT_SWITCH_HDMI "change@/devices/virtual/switch/hdmi"
+#define HWC_UEVENT_GRAPHICS_FB0 "change@/devices/virtual/graphics/fb0"
+
+static sdm::HWCSession::HWCModuleMethods g_hwc_module_methods;
+
+hwc_module_t HAL_MODULE_INFO_SYM = {
+  .common = {
+    .tag = HARDWARE_MODULE_TAG,
+    .version_major = 3,
+    .version_minor = 0,
+    .id = HWC_HARDWARE_MODULE_ID,
+    .name = "QTI Hardware Composer Module",
+    .author = "CodeAurora Forum",
+    .methods = &g_hwc_module_methods,
+    .dso = 0,
+    .reserved = {0},
+  }
+};
+
+namespace sdm {
+Locker HWCSession::locker_;
+
+HWCSession::HWCSession(const hw_module_t *module) {
+  hwc2_device_t::common.tag = HARDWARE_DEVICE_TAG;
+  hwc2_device_t::common.version = HWC_DEVICE_API_VERSION_2_0;
+  hwc2_device_t::common.module = const_cast<hw_module_t *>(module);
+  hwc2_device_t::common.close = Close;
+  hwc2_device_t::getCapabilities = GetCapabilities;
+  hwc2_device_t::getFunction = GetFunction;
+}
+
+int HWCSession::Init() {
+  int status = -EINVAL;
+  const char *qservice_name = "display.qservice";
+
+  // Start QService and connect to it.
+  qService::QService::init();
+  android::sp<qService::IQService> iqservice = android::interface_cast<qService::IQService>(
+      android::defaultServiceManager()->getService(android::String16(qservice_name)));
+
+  if (iqservice.get()) {
+    iqservice->connect(android::sp<qClient::IQClient>(this));
+    qservice_ = reinterpret_cast<qService::QService *>(iqservice.get());
+  } else {
+    DLOGE("Failed to acquire %s", qservice_name);
+    return -EINVAL;
+  }
+
+  buffer_allocator_ = new HWCBufferAllocator();
+  if (buffer_allocator_ == NULL) {
+    DLOGE("Display core initialization failed due to no memory");
+    return -ENOMEM;
+  }
+
+  buffer_sync_handler_ = new HWCBufferSyncHandler();
+  if (buffer_sync_handler_ == NULL) {
+    DLOGE("Display core initialization failed due to no memory");
+    return -ENOMEM;
+  }
+
+  DisplayError error = CoreInterface::CreateCore(HWCDebugHandler::Get(), buffer_allocator_,
+                                                 buffer_sync_handler_, &core_intf_);
+  if (error != kErrorNone) {
+    DLOGE("Display core initialization failed. Error = %d", error);
+    return -EINVAL;
+  }
+
+  // Read which display is first, and create it and store it in primary slot
+  // TODO(user): This will need to be redone for HWC2 - right now we validate only
+  // the primary physical path
+  HWDisplayInterfaceInfo hw_disp_info;
+  error = core_intf_->GetFirstDisplayInterfaceType(&hw_disp_info);
+  if (error == kErrorNone && hw_disp_info.type == kHDMI && hw_disp_info.is_connected) {
+    // HDMI is primary display. If already connected, then create it and store in
+    // primary display slot. If not connected, create a NULL display for now.
+    status = HWCDisplayExternal::Create(core_intf_, &callbacks_, qservice_,
+                                        &hwc_display_[HWC_DISPLAY_PRIMARY]);
+  } else {
+    // Create and power on primary display
+    status = HWCDisplayPrimary::Create(core_intf_, buffer_allocator_, &callbacks_, qservice_,
+                                       &hwc_display_[HWC_DISPLAY_PRIMARY]);
+  }
+
+  if (status) {
+    CoreInterface::DestroyCore();
+    return status;
+  }
+
+  color_mgr_ = HWCColorManager::CreateColorManager();
+  if (!color_mgr_) {
+    DLOGW("Failed to load HWCColorManager.");
+  }
+
+  if (pthread_create(&uevent_thread_, NULL, &HWCUeventThread, this) < 0) {
+    DLOGE("Failed to start = %s, error = %s", uevent_thread_name_, strerror(errno));
+    HWCDisplayPrimary::Destroy(hwc_display_[HWC_DISPLAY_PRIMARY]);
+    hwc_display_[HWC_DISPLAY_PRIMARY] = 0;
+    CoreInterface::DestroyCore();
+    return -errno;
+  }
+
+  return 0;
+}
+
+int HWCSession::Deinit() {
+  HWCDisplayPrimary::Destroy(hwc_display_[HWC_DISPLAY_PRIMARY]);
+  hwc_display_[HWC_DISPLAY_PRIMARY] = 0;
+  if (color_mgr_) {
+    color_mgr_->DestroyColorManager();
+  }
+  uevent_thread_exit_ = true;
+  pthread_join(uevent_thread_, NULL);
+
+  DisplayError error = CoreInterface::DestroyCore();
+  if (error != kErrorNone) {
+    DLOGE("Display core de-initialization failed. Error = %d", error);
+  }
+
+  return 0;
+}
+
+int HWCSession::Open(const hw_module_t *module, const char *name, hw_device_t **device) {
+  SEQUENCE_WAIT_SCOPE_LOCK(locker_);
+
+  if (!module || !name || !device) {
+    DLOGE("Invalid parameters.");
+    return -EINVAL;
+  }
+
+  if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
+    HWCSession *hwc_session = new HWCSession(module);
+    if (!hwc_session) {
+      return -ENOMEM;
+    }
+
+    int status = hwc_session->Init();
+    if (status != 0) {
+      delete hwc_session;
+      return status;
+    }
+
+    hwc2_device_t *composer_device = hwc_session;
+    *device = reinterpret_cast<hw_device_t *>(composer_device);
+  }
+
+  return 0;
+}
+
+int HWCSession::Close(hw_device_t *device) {
+  SEQUENCE_WAIT_SCOPE_LOCK(locker_);
+
+  if (!device) {
+    return -EINVAL;
+  }
+
+  hwc2_device_t *composer_device = reinterpret_cast<hwc2_device_t *>(device);
+  HWCSession *hwc_session = static_cast<HWCSession *>(composer_device);
+
+  hwc_session->Deinit();
+  delete hwc_session;
+
+  return 0;
+}
+
+void HWCSession::GetCapabilities(struct hwc2_device *device, uint32_t *outCount,
+                                 int32_t *outCapabilities) {
+  if (outCapabilities == NULL) {
+    *outCount = 0;
+  }
+}
+
+template <typename PFN, typename T>
+static hwc2_function_pointer_t AsFP(T function) {
+  static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
+  return reinterpret_cast<hwc2_function_pointer_t>(function);
+}
+
+// HWC2 functions returned in GetFunction
+// Defined in the same order as in the HWC2 header
+
+static int32_t AcceptDisplayChanges(hwc2_device_t *device, hwc2_display_t display) {
+  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::AcceptDisplayChanges);
+}
+
+int32_t HWCSession::CreateLayer(hwc2_device_t *device, hwc2_display_t display,
+                                hwc2_layer_t *out_layer_id) {
+  SCOPE_LOCK(locker_);
+  return CallDisplayFunction(device, display, &HWCDisplay::CreateLayer, out_layer_id);
+}
+
+int32_t HWCSession::CreateVirtualDisplay(hwc2_device_t *device, uint32_t width, uint32_t height,
+                                         hwc2_display_t *out_display_id) {
+  if (!device) {
+    return HWC2_ERROR_BAD_DISPLAY;
+  }
+
+  HWCSession *hwc_session = static_cast<HWCSession *>(device);
+  auto status = hwc_session->CreateVirtualDisplayObject(width, height);
+  if (status == HWC2::Error::None)
+    *out_display_id = HWC_DISPLAY_VIRTUAL;
+  return INT32(status);
+}
+
+int32_t HWCSession::DestroyLayer(hwc2_device_t *device, hwc2_display_t display,
+                                 hwc2_layer_t layer) {
+  SCOPE_LOCK(locker_);
+  return CallDisplayFunction(device, display, &HWCDisplay::DestroyLayer, layer);
+}
+
+int32_t HWCSession::DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t display) {
+  if (!device) {
+    return HWC2_ERROR_BAD_DISPLAY;
+  }
+
+  auto *hwc_session = static_cast<HWCSession *>(device);
+
+  if (hwc_session->hwc_display_[display]) {
+    HWCDisplayVirtual::Destroy(hwc_session->hwc_display_[display]);
+    return HWC2_ERROR_NONE;
+  } else {
+    return HWC2_ERROR_BAD_DISPLAY;
+  }
+}
+
+void HWCSession::Dump(hwc2_device_t *device, uint32_t *out_size, char *out_buffer) {
+  SEQUENCE_WAIT_SCOPE_LOCK(locker_);
+
+  if (!device) {
+    return;
+  }
+  auto *hwc_session = static_cast<HWCSession *>(device);
+
+  if (out_buffer == nullptr) {
+    *out_size = 8192;  // TODO(user): Adjust required dump size
+  } else {
+    char sdm_dump[4096];
+    DumpInterface::GetDump(sdm_dump, 4096);  // TODO(user): Fix this workaround
+    std::string s = hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY]->Dump();
+    s += sdm_dump;
+    s.copy(out_buffer, s.size(), 0);
+    *out_size = sizeof(out_buffer);
+  }
+}
+
+static int32_t GetActiveConfig(hwc2_device_t *device, hwc2_display_t display,
+                               hwc2_config_t *out_config) {
+  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetActiveConfig, out_config);
+}
+
+static int32_t GetChangedCompositionTypes(hwc2_device_t *device, hwc2_display_t display,
+                                          uint32_t *out_num_elements, hwc2_layer_t *out_layers,
+                                          int32_t *out_types) {
+  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetChangedCompositionTypes,
+                                         out_num_elements, out_layers, out_types);
+}
+
+static int32_t GetClientTargetSupport(hwc2_device_t *device, hwc2_display_t display, uint32_t width,
+                                      uint32_t height, int32_t format, int32_t dataspace) {
+  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetClientTargetSupport,
+                                         width, height, format, dataspace);
+}
+
+// TODO(user): GetColorModes
+
+static int32_t GetDisplayAttribute(hwc2_device_t *device, hwc2_display_t display,
+                                   hwc2_config_t config, int32_t int_attribute,
+                                   int32_t *out_value) {
+  auto attribute = static_cast<HWC2::Attribute>(int_attribute);
+  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayAttribute, config,
+                                         attribute, out_value);
+}
+
+static int32_t GetDisplayConfigs(hwc2_device_t *device, hwc2_display_t display,
+                                 uint32_t *out_num_configs, hwc2_config_t *out_configs) {
+  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayConfigs,
+                                         out_num_configs, out_configs);
+}
+
+static int32_t GetDisplayName(hwc2_device_t *device, hwc2_display_t display, uint32_t *out_size,
+                              char *out_name) {
+  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayName, out_size,
+                                         out_name);
+}
+
+static int32_t GetDisplayRequests(hwc2_device_t *device, hwc2_display_t display,
+                                  int32_t *out_display_requests, uint32_t *out_num_elements,
+                                  hwc2_layer_t *out_layers, int32_t *out_layer_requests) {
+  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayRequests,
+                                         out_display_requests, out_num_elements, out_layers,
+                                         out_layer_requests);
+}
+
+static int32_t GetDisplayType(hwc2_device_t *device, hwc2_display_t display, int32_t *out_type) {
+  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayType, out_type);
+}
+
+static int32_t GetDozeSupport(hwc2_device_t *device, hwc2_display_t display, int32_t *out_support) {
+  // TODO(user): Check if it is an HDMI as primary display and disable support for it
+  if (display == HWC_DISPLAY_PRIMARY) {
+    *out_support = 1;
+  } else {
+    *out_support = 0;
+  }
+  return HWC2_ERROR_NONE;
+}
+
+static int32_t GetHdrCapabilities(hwc2_device_t* device, hwc2_display_t display,
+                                  uint32_t* out_num_types, int32_t* out_types,
+                                  float* out_max_luminance, float* out_max_average_luminance,
+                                  float* out_min_luminance) {
+  *out_num_types = 0;
+  return HWC2_ERROR_NONE;
+}
+
+static uint32_t GetMaxVirtualDisplayCount(hwc2_device_t *device) {
+  return 1;
+}
+
+static int32_t GetReleaseFences(hwc2_device_t *device, hwc2_display_t display,
+                                uint32_t *out_num_elements, hwc2_layer_t *out_layers,
+                                int32_t *out_fences) {
+  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetReleaseFences,
+                                         out_num_elements, out_layers, out_fences);
+}
+
+int32_t HWCSession::PresentDisplay(hwc2_device_t *device, hwc2_display_t display,
+                                   int32_t *out_retire_fence) {
+  HWCSession *hwc_session = static_cast<HWCSession *>(device);
+  DTRACE_SCOPED();
+  SEQUENCE_EXIT_SCOPE_LOCK(locker_);
+  if (!device) {
+    return HWC2_ERROR_BAD_DISPLAY;
+  }
+  // TODO(user): Handle solid fill layers
+  auto status = HWC2::Error::BadDisplay;
+  // TODO(user): Handle virtual display/HDMI concurrency
+
+  if (hwc_session->hwc_display_[display]) {
+    status = hwc_session->hwc_display_[display]->Present(out_retire_fence);
+    // This is only indicative of how many times SurfaceFlinger posts
+    // frames to the display.
+    CALC_FPS();
+  }
+
+  return INT32(status);
+}
+
+int32_t HWCSession::RegisterCallback(hwc2_device_t *device, int32_t descriptor,
+                                     hwc2_callback_data_t callback_data,
+                                     hwc2_function_pointer_t pointer) {
+  HWCSession *hwc_session = static_cast<HWCSession *>(device);
+  if (!device) {
+    return HWC2_ERROR_BAD_DISPLAY;
+  }
+  auto desc = static_cast<HWC2::Callback>(descriptor);
+  auto error = hwc_session->callbacks_.Register(desc, callback_data, pointer);
+  DLOGD("Registering callback: %s", to_string(desc).c_str());
+  if (descriptor == HWC2_CALLBACK_HOTPLUG)
+    hwc_session->callbacks_.Hotplug(HWC_DISPLAY_PRIMARY, HWC2::Connection::Connected);
+  return INT32(error);
+}
+
+static int32_t SetActiveConfig(hwc2_device_t *device, hwc2_display_t display,
+                               hwc2_config_t config) {
+  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetActiveConfig, config);
+}
+
+static int32_t SetClientTarget(hwc2_device_t *device, hwc2_display_t display,
+                               buffer_handle_t target, int32_t acquire_fence, int32_t dataspace) {
+  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetClientTarget, target,
+                                         acquire_fence, dataspace);
+}
+
+// TODO(user): SetColorMode, SetColorTransform
+
+static int32_t SetCursorPosition(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
+                                 int32_t x, int32_t y) {
+  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetCursorPosition, layer, x,
+                                         y);
+}
+
+static int32_t SetLayerBlendMode(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
+                                 int32_t int_mode) {
+  auto mode = static_cast<HWC2::BlendMode>(int_mode);
+  return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerBlendMode, mode);
+}
+
+static int32_t SetLayerBuffer(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
+                              buffer_handle_t buffer, int32_t acquire_fence) {
+  return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerBuffer, buffer,
+                                       acquire_fence);
+}
+
+static int32_t SetLayerColor(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
+                             hwc_color_t color) {
+  return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerColor, color);
+}
+
+static int32_t SetLayerCompositionType(hwc2_device_t *device, hwc2_display_t display,
+                                       hwc2_layer_t layer, int32_t int_type) {
+  auto type = static_cast<HWC2::Composition>(int_type);
+  return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerCompositionType,
+                                       type);
+}
+
+static int32_t SetLayerDataspace(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
+                                 int32_t dataspace) {
+  return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerDataspace,
+                                       dataspace);
+}
+
+static int32_t SetLayerDisplayFrame(hwc2_device_t *device, hwc2_display_t display,
+                                    hwc2_layer_t layer, hwc_rect_t frame) {
+  return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerDisplayFrame,
+                                       frame);
+}
+
+static int32_t SetLayerPlaneAlpha(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
+                                  float alpha) {
+  return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerPlaneAlpha,
+                                       alpha);
+}
+
+static int32_t SetLayerSourceCrop(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
+                                  hwc_frect_t crop) {
+  return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerSourceCrop, crop);
+}
+
+static int32_t SetLayerSurfaceDamage(hwc2_device_t *device, hwc2_display_t display,
+                                     hwc2_layer_t layer, hwc_region_t damage) {
+  return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerSurfaceDamage,
+                                       damage);
+}
+
+static int32_t SetLayerTransform(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
+                                 int32_t int_transform) {
+  auto transform = static_cast<HWC2::Transform>(int_transform);
+  return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerTransform,
+                                       transform);
+}
+
+static int32_t SetLayerVisibleRegion(hwc2_device_t *device, hwc2_display_t display,
+                                     hwc2_layer_t layer, hwc_region_t visible) {
+  return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerVisibleRegion,
+                                       visible);
+}
+
+int32_t HWCSession::SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display,
+                                   hwc2_layer_t layer, uint32_t z) {
+  SCOPE_LOCK(locker_);
+  return CallDisplayFunction(device, display, &HWCDisplay::SetLayerZOrder, layer, z);
+}
+
+int32_t HWCSession::SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
+                                    buffer_handle_t buffer, int32_t releaseFence) {
+  if (!device) {
+    return HWC2_ERROR_BAD_DISPLAY;
+  }
+
+  auto *hwc_session = static_cast<HWCSession *>(device);
+  if (display == HWC_DISPLAY_VIRTUAL && hwc_session->hwc_display_[display]) {
+    auto vds = reinterpret_cast<HWCDisplayVirtual *>(hwc_session->hwc_display_[display]);
+    auto status = vds->SetOutputBuffer(buffer, releaseFence);
+    return INT32(status);
+  } else {
+    return HWC2_ERROR_BAD_DISPLAY;
+  }
+}
+
+int32_t HWCSession::SetPowerMode(hwc2_device_t *device, hwc2_display_t display, int32_t int_mode) {
+  auto mode = static_cast<HWC2::PowerMode>(int_mode);
+  SEQUENCE_WAIT_SCOPE_LOCK(locker_);
+  return CallDisplayFunction(device, display, &HWCDisplay::SetPowerMode, mode);
+}
+
+static int32_t SetVsyncEnabled(hwc2_device_t *device, hwc2_display_t display, int32_t int_enabled) {
+  auto enabled = static_cast<HWC2::Vsync>(int_enabled);
+  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetVsyncEnabled, enabled);
+}
+
+int32_t HWCSession::ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
+                                    uint32_t *out_num_types, uint32_t *out_num_requests) {
+  DTRACE_SCOPED();
+  HWCSession *hwc_session = static_cast<HWCSession *>(device);
+  if (!device) {
+    return HWC2_ERROR_BAD_DISPLAY;
+  }
+
+  // TODO(user): Handle secure session, handle QDCM solid fill
+  // Handle external_pending_connect_ in CreateVirtualDisplay
+  auto status = HWC2::Error::BadDisplay;
+  if (hwc_session->hwc_display_[display]) {
+    SEQUENCE_ENTRY_SCOPE_LOCK(locker_);
+    if (display == HWC_DISPLAY_PRIMARY) {
+      // TODO(user): This can be moved to HWCDisplayPrimary
+      if (hwc_session->reset_panel_) {
+        DLOGW("panel is in bad state, resetting the panel");
+        hwc_session->ResetPanel();
+      }
+
+      if (hwc_session->need_invalidate_) {
+        hwc_session->callbacks_.Refresh(display);
+      }
+    }
+
+    status = hwc_session->hwc_display_[display]->Validate(out_num_types, out_num_requests);
+  }
+  // If validate fails, cancel the sequence lock so that other operations
+  // (such as Dump or SetPowerMode) may succeed without blocking on the condition
+  if (status != HWC2::Error::None) {
+    SEQUENCE_CANCEL_SCOPE_LOCK(locker_);
+  }
+  return INT32(status);
+}
+
+hwc2_function_pointer_t HWCSession::GetFunction(struct hwc2_device *device,
+                                                int32_t int_descriptor) {
+  auto descriptor = static_cast<HWC2::FunctionDescriptor>(int_descriptor);
+
+  switch (descriptor) {
+    case HWC2::FunctionDescriptor::AcceptDisplayChanges:
+      return AsFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(AcceptDisplayChanges);
+    case HWC2::FunctionDescriptor::CreateLayer:
+      return AsFP<HWC2_PFN_CREATE_LAYER>(CreateLayer);
+    case HWC2::FunctionDescriptor::CreateVirtualDisplay:
+      return AsFP<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(HWCSession::CreateVirtualDisplay);
+    case HWC2::FunctionDescriptor::DestroyLayer:
+      return AsFP<HWC2_PFN_DESTROY_LAYER>(DestroyLayer);
+    case HWC2::FunctionDescriptor::DestroyVirtualDisplay:
+      return AsFP<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(HWCSession::DestroyVirtualDisplay);
+    case HWC2::FunctionDescriptor::Dump:
+      return AsFP<HWC2_PFN_DUMP>(HWCSession::Dump);
+    case HWC2::FunctionDescriptor::GetActiveConfig:
+      return AsFP<HWC2_PFN_GET_ACTIVE_CONFIG>(GetActiveConfig);
+    case HWC2::FunctionDescriptor::GetChangedCompositionTypes:
+      return AsFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(GetChangedCompositionTypes);
+    case HWC2::FunctionDescriptor::GetClientTargetSupport:
+      return AsFP<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(GetClientTargetSupport);
+    // case HWC2::FunctionDescriptor::GetColorModes:
+    // TODO(user): Support later
+    case HWC2::FunctionDescriptor::GetDisplayAttribute:
+      return AsFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(GetDisplayAttribute);
+    case HWC2::FunctionDescriptor::GetDisplayConfigs:
+      return AsFP<HWC2_PFN_GET_DISPLAY_CONFIGS>(GetDisplayConfigs);
+    case HWC2::FunctionDescriptor::GetDisplayName:
+      return AsFP<HWC2_PFN_GET_DISPLAY_NAME>(GetDisplayName);
+    case HWC2::FunctionDescriptor::GetDisplayRequests:
+      return AsFP<HWC2_PFN_GET_DISPLAY_REQUESTS>(GetDisplayRequests);
+    case HWC2::FunctionDescriptor::GetDisplayType:
+      return AsFP<HWC2_PFN_GET_DISPLAY_TYPE>(GetDisplayType);
+    case HWC2::FunctionDescriptor::GetHdrCapabilities:
+      return AsFP<HWC2_PFN_GET_HDR_CAPABILITIES>(GetHdrCapabilities);
+    case HWC2::FunctionDescriptor::GetDozeSupport:
+      return AsFP<HWC2_PFN_GET_DOZE_SUPPORT>(GetDozeSupport);
+    case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount:
+      return AsFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(GetMaxVirtualDisplayCount);
+    case HWC2::FunctionDescriptor::GetReleaseFences:
+      return AsFP<HWC2_PFN_GET_RELEASE_FENCES>(GetReleaseFences);
+    case HWC2::FunctionDescriptor::PresentDisplay:
+      return AsFP<HWC2_PFN_PRESENT_DISPLAY>(PresentDisplay);
+    case HWC2::FunctionDescriptor::RegisterCallback:
+      return AsFP<HWC2_PFN_REGISTER_CALLBACK>(RegisterCallback);
+    case HWC2::FunctionDescriptor::SetActiveConfig:
+      return AsFP<HWC2_PFN_SET_ACTIVE_CONFIG>(SetActiveConfig);
+    case HWC2::FunctionDescriptor::SetClientTarget:
+      return AsFP<HWC2_PFN_SET_CLIENT_TARGET>(SetClientTarget);
+    // TODO(user): Support later
+    // case HWC2::FunctionDescriptor::SetColorMode:
+    // case HWC2::FunctionDescriptor::SetColorTransform:
+    // break;
+    case HWC2::FunctionDescriptor::SetCursorPosition:
+      return AsFP<HWC2_PFN_SET_CURSOR_POSITION>(SetCursorPosition);
+    case HWC2::FunctionDescriptor::SetLayerBlendMode:
+      return AsFP<HWC2_PFN_SET_LAYER_BLEND_MODE>(SetLayerBlendMode);
+    case HWC2::FunctionDescriptor::SetLayerBuffer:
+      return AsFP<HWC2_PFN_SET_LAYER_BUFFER>(SetLayerBuffer);
+    case HWC2::FunctionDescriptor::SetLayerColor:
+      return AsFP<HWC2_PFN_SET_LAYER_COLOR>(SetLayerColor);
+    case HWC2::FunctionDescriptor::SetLayerCompositionType:
+      return AsFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(SetLayerCompositionType);
+    case HWC2::FunctionDescriptor::SetLayerDataspace:
+      return AsFP<HWC2_PFN_SET_LAYER_DATASPACE>(SetLayerDataspace);
+    case HWC2::FunctionDescriptor::SetLayerDisplayFrame:
+      return AsFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(SetLayerDisplayFrame);
+    case HWC2::FunctionDescriptor::SetLayerPlaneAlpha:
+      return AsFP<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(SetLayerPlaneAlpha);
+    // Sideband stream is not supported
+    // case HWC2::FunctionDescriptor::SetLayerSidebandStream:
+    case HWC2::FunctionDescriptor::SetLayerSourceCrop:
+      return AsFP<HWC2_PFN_SET_LAYER_SOURCE_CROP>(SetLayerSourceCrop);
+    case HWC2::FunctionDescriptor::SetLayerSurfaceDamage:
+      return AsFP<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(SetLayerSurfaceDamage);
+    case HWC2::FunctionDescriptor::SetLayerTransform:
+      return AsFP<HWC2_PFN_SET_LAYER_TRANSFORM>(SetLayerTransform);
+    case HWC2::FunctionDescriptor::SetLayerVisibleRegion:
+      return AsFP<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(SetLayerVisibleRegion);
+    case HWC2::FunctionDescriptor::SetLayerZOrder:
+      return AsFP<HWC2_PFN_SET_LAYER_Z_ORDER>(SetLayerZOrder);
+    case HWC2::FunctionDescriptor::SetOutputBuffer:
+      return AsFP<HWC2_PFN_SET_OUTPUT_BUFFER>(SetOutputBuffer);
+    case HWC2::FunctionDescriptor::SetPowerMode:
+      return AsFP<HWC2_PFN_SET_POWER_MODE>(SetPowerMode);
+    case HWC2::FunctionDescriptor::SetVsyncEnabled:
+      return AsFP<HWC2_PFN_SET_VSYNC_ENABLED>(SetVsyncEnabled);
+    case HWC2::FunctionDescriptor::ValidateDisplay:
+      return AsFP<HWC2_PFN_VALIDATE_DISPLAY>(HWCSession::ValidateDisplay);
+    default:
+      DLOGD("Unknown/Unimplemented function descriptor: %d (%s)", int_descriptor,
+            to_string(descriptor).c_str());
+      return nullptr;
+  }
+  return nullptr;
+}
+
+// TODO(user): handle locking
+
+HWC2::Error HWCSession::CreateVirtualDisplayObject(uint32_t width, uint32_t height) {
+  if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
+    return HWC2::Error::NoResources;
+  }
+  auto status = HWCDisplayVirtual::Create(core_intf_, &callbacks_, width, height,
+                                          &hwc_display_[HWC_DISPLAY_VIRTUAL]);
+  // TODO(user): validate width and height support
+  if (status)
+    return HWC2::Error::Unsupported;
+
+  return HWC2::Error::None;
+}
+
+int32_t HWCSession::ConnectDisplay(int disp) {
+  DLOGI("Display = %d", disp);
+
+  int status = 0;
+  uint32_t primary_width = 0;
+  uint32_t primary_height = 0;
+
+  hwc_display_[HWC_DISPLAY_PRIMARY]->GetFrameBufferResolution(&primary_width, &primary_height);
+
+  if (disp == HWC_DISPLAY_EXTERNAL) {
+    status = HWCDisplayExternal::Create(core_intf_, &callbacks_, primary_width, primary_height,
+                                        qservice_, false, &hwc_display_[disp]);
+  } else {
+    DLOGE("Invalid display type");
+    return -1;
+  }
+
+  if (!status) {
+    hwc_display_[disp]->SetSecureDisplay(secure_display_active_);
+  }
+
+  return status;
+}
+
+int HWCSession::DisconnectDisplay(int disp) {
+  DLOGI("Display = %d", disp);
+
+  if (disp == HWC_DISPLAY_EXTERNAL) {
+    HWCDisplayExternal::Destroy(hwc_display_[disp]);
+  } else if (disp == HWC_DISPLAY_VIRTUAL) {
+    HWCDisplayVirtual::Destroy(hwc_display_[disp]);
+  } else {
+    DLOGE("Invalid display type");
+    return -1;
+  }
+
+  hwc_display_[disp] = NULL;
+
+  return 0;
+}
+
+// Qclient methods
+android::status_t HWCSession::notifyCallback(uint32_t command, const android::Parcel *input_parcel,
+                                             android::Parcel *output_parcel) {
+  SEQUENCE_WAIT_SCOPE_LOCK(locker_);
+
+  android::status_t status = 0;
+
+  switch (command) {
+    case qService::IQService::DYNAMIC_DEBUG:
+      DynamicDebug(input_parcel);
+      break;
+
+    case qService::IQService::SCREEN_REFRESH:
+      callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+      break;
+
+    case qService::IQService::SET_IDLE_TIMEOUT:
+      if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+        uint32_t timeout = UINT32(input_parcel->readInt32());
+        hwc_display_[HWC_DISPLAY_PRIMARY]->SetIdleTimeoutMs(timeout);
+      }
+      break;
+
+    case qService::IQService::SET_FRAME_DUMP_CONFIG:
+      SetFrameDumpConfig(input_parcel);
+      break;
+
+    case qService::IQService::SET_MAX_PIPES_PER_MIXER:
+      status = SetMaxMixerStages(input_parcel);
+      break;
+
+    case qService::IQService::SET_DISPLAY_MODE:
+      status = SetDisplayMode(input_parcel);
+      break;
+
+    case qService::IQService::SET_SECONDARY_DISPLAY_STATUS:
+      status = SetSecondaryDisplayStatus(input_parcel, output_parcel);
+      break;
+
+    case qService::IQService::CONFIGURE_DYN_REFRESH_RATE:
+      status = ConfigureRefreshRate(input_parcel);
+      break;
+
+    case qService::IQService::SET_VIEW_FRAME:
+      break;
+
+    case qService::IQService::TOGGLE_SCREEN_UPDATES:
+      status = ToggleScreenUpdates(input_parcel, output_parcel);
+      break;
+
+    case qService::IQService::QDCM_SVC_CMDS:
+      status = QdcmCMDHandler(input_parcel, output_parcel);
+      break;
+
+    case qService::IQService::MIN_HDCP_ENCRYPTION_LEVEL_CHANGED:
+      status = OnMinHdcpEncryptionLevelChange(input_parcel, output_parcel);
+      break;
+
+    case qService::IQService::CONTROL_PARTIAL_UPDATE:
+      status = ControlPartialUpdate(input_parcel, output_parcel);
+      break;
+
+    case qService::IQService::SET_ACTIVE_CONFIG:
+      status = HandleSetActiveDisplayConfig(input_parcel, output_parcel);
+      break;
+
+    case qService::IQService::GET_ACTIVE_CONFIG:
+      status = HandleGetActiveDisplayConfig(input_parcel, output_parcel);
+      break;
+
+    case qService::IQService::GET_CONFIG_COUNT:
+      status = HandleGetDisplayConfigCount(input_parcel, output_parcel);
+      break;
+
+    case qService::IQService::GET_DISPLAY_ATTRIBUTES_FOR_CONFIG:
+      status = HandleGetDisplayAttributesForConfig(input_parcel, output_parcel);
+      break;
+
+    case qService::IQService::GET_PANEL_BRIGHTNESS:
+      status = GetPanelBrightness(input_parcel, output_parcel);
+      break;
+
+    case qService::IQService::SET_PANEL_BRIGHTNESS:
+      status = SetPanelBrightness(input_parcel, output_parcel);
+      break;
+
+    case qService::IQService::GET_DISPLAY_VISIBLE_REGION:
+      status = GetVisibleDisplayRect(input_parcel, output_parcel);
+      break;
+
+    case qService::IQService::SET_CAMERA_STATUS:
+      status = SetDynamicBWForCamera(input_parcel, output_parcel);
+      break;
+
+    case qService::IQService::GET_BW_TRANSACTION_STATUS:
+      status = GetBWTransactionStatus(input_parcel, output_parcel);
+      break;
+
+    default:
+      DLOGW("QService command = %d is not supported", command);
+      return -EINVAL;
+  }
+
+  return status;
+}
+
+android::status_t HWCSession::ToggleScreenUpdates(const android::Parcel *input_parcel,
+                                                  android::Parcel *output_parcel) {
+  int input = input_parcel->readInt32();
+  int error = android::BAD_VALUE;
+
+  if (hwc_display_[HWC_DISPLAY_PRIMARY] && (input <= 1) && (input >= 0)) {
+    error = hwc_display_[HWC_DISPLAY_PRIMARY]->ToggleScreenUpdates(input == 1);
+    if (error != 0) {
+      DLOGE("Failed to toggle screen updates = %d. Error = %d", input, error);
+    }
+  }
+  output_parcel->writeInt32(error);
+
+  return error;
+}
+
+android::status_t HWCSession::SetPanelBrightness(const android::Parcel *input_parcel,
+                                                 android::Parcel *output_parcel) {
+  int level = input_parcel->readInt32();
+  int error = android::BAD_VALUE;
+
+  if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+    error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(level);
+    if (error != 0) {
+      DLOGE("Failed to set the panel brightness = %d. Error = %d", level, error);
+    }
+  }
+  output_parcel->writeInt32(error);
+
+  return error;
+}
+
+android::status_t HWCSession::GetPanelBrightness(const android::Parcel *input_parcel,
+                                                 android::Parcel *output_parcel) {
+  int error = android::BAD_VALUE;
+  int ret = error;
+
+  if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+    error = hwc_display_[HWC_DISPLAY_PRIMARY]->GetPanelBrightness(&ret);
+    if (error != 0) {
+      ret = error;
+      DLOGE("Failed to get the panel brightness. Error = %d", error);
+    }
+  }
+  output_parcel->writeInt32(ret);
+
+  return error;
+}
+
+android::status_t HWCSession::ControlPartialUpdate(const android::Parcel *input_parcel,
+                                                   android::Parcel *out) {
+  DisplayError error = kErrorNone;
+  int ret = 0;
+  uint32_t disp_id = UINT32(input_parcel->readInt32());
+  uint32_t enable = UINT32(input_parcel->readInt32());
+
+  if (disp_id != HWC_DISPLAY_PRIMARY) {
+    DLOGW("CONTROL_PARTIAL_UPDATE is not applicable for display = %d", disp_id);
+    ret = -EINVAL;
+    out->writeInt32(ret);
+    return ret;
+  }
+
+  if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
+    DLOGE("primary display object is not instantiated");
+    ret = -EINVAL;
+    out->writeInt32(ret);
+    return ret;
+  }
+
+  uint32_t pending = 0;
+  error = hwc_display_[HWC_DISPLAY_PRIMARY]->ControlPartialUpdate(enable, &pending);
+
+  if (error == kErrorNone) {
+    if (!pending) {
+      out->writeInt32(ret);
+      return ret;
+    }
+  } else if (error == kErrorNotSupported) {
+    out->writeInt32(ret);
+    return ret;
+  } else {
+    ret = -EINVAL;
+    out->writeInt32(ret);
+    return ret;
+  }
+
+  // Todo(user): Unlock it before sending events to client. It may cause deadlocks in future.
+  callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+
+  // Wait until partial update control is complete
+  ret = locker_.WaitFinite(kPartialUpdateControlTimeoutMs);
+
+  out->writeInt32(ret);
+
+  return ret;
+}
+
+android::status_t HWCSession::HandleSetActiveDisplayConfig(const android::Parcel *input_parcel,
+                                                           android::Parcel *output_parcel) {
+  int config = input_parcel->readInt32();
+  int dpy = input_parcel->readInt32();
+  int error = android::BAD_VALUE;
+
+  if (dpy > HWC_DISPLAY_VIRTUAL) {
+    return android::BAD_VALUE;
+  }
+
+  if (hwc_display_[dpy]) {
+    error = hwc_display_[dpy]->SetActiveDisplayConfig(config);
+    if (error == 0) {
+      callbacks_.Refresh(0);
+    }
+  }
+
+  return error;
+}
+
+android::status_t HWCSession::HandleGetActiveDisplayConfig(const android::Parcel *input_parcel,
+                                                           android::Parcel *output_parcel) {
+  int dpy = input_parcel->readInt32();
+  int error = android::BAD_VALUE;
+
+  if (dpy > HWC_DISPLAY_VIRTUAL) {
+    return android::BAD_VALUE;
+  }
+
+  if (hwc_display_[dpy]) {
+    uint32_t config = 0;
+    error = hwc_display_[dpy]->GetActiveDisplayConfig(&config);
+    if (error == 0) {
+      output_parcel->writeInt32(INT(config));
+    }
+  }
+
+  return error;
+}
+
+android::status_t HWCSession::HandleGetDisplayConfigCount(const android::Parcel *input_parcel,
+                                                          android::Parcel *output_parcel) {
+  int dpy = input_parcel->readInt32();
+  int error = android::BAD_VALUE;
+
+  if (dpy > HWC_DISPLAY_VIRTUAL) {
+    return android::BAD_VALUE;
+  }
+
+  uint32_t count = 0;
+  if (hwc_display_[dpy]) {
+    error = hwc_display_[dpy]->GetDisplayConfigCount(&count);
+    if (error == 0) {
+      output_parcel->writeInt32(INT(count));
+    }
+  }
+
+  return error;
+}
+
+android::status_t HWCSession::HandleGetDisplayAttributesForConfig(
+    const android::Parcel *input_parcel, android::Parcel *output_parcel) {
+  int config = input_parcel->readInt32();
+  int dpy = input_parcel->readInt32();
+  int error = android::BAD_VALUE;
+  DisplayConfigVariableInfo attributes;
+
+  if (dpy > HWC_DISPLAY_VIRTUAL) {
+    return android::BAD_VALUE;
+  }
+
+  if (hwc_display_[dpy]) {
+    error = hwc_display_[dpy]->GetDisplayAttributesForConfig(config, &attributes);
+    if (error == 0) {
+      output_parcel->writeInt32(INT(attributes.vsync_period_ns));
+      output_parcel->writeInt32(INT(attributes.x_pixels));
+      output_parcel->writeInt32(INT(attributes.y_pixels));
+      output_parcel->writeFloat(attributes.x_dpi);
+      output_parcel->writeFloat(attributes.y_dpi);
+      output_parcel->writeInt32(0);  // Panel type, unsupported.
+    }
+  }
+
+  return error;
+}
+
+android::status_t HWCSession::SetSecondaryDisplayStatus(const android::Parcel *input_parcel,
+                                                        android::Parcel *output_parcel) {
+  int ret = -EINVAL;
+
+  uint32_t display_id = UINT32(input_parcel->readInt32());
+  uint32_t display_status = UINT32(input_parcel->readInt32());
+
+  DLOGI("Display = %d, Status = %d", display_id, display_status);
+
+  if (display_id >= HWC_NUM_DISPLAY_TYPES) {
+    DLOGE("Invalid display_id");
+  } else if (display_id == HWC_DISPLAY_PRIMARY) {
+    DLOGE("Not supported for this display");
+  } else if (!hwc_display_[display_id]) {
+    DLOGW("Display is not connected");
+  } else {
+    ret = hwc_display_[display_id]->SetDisplayStatus(display_status);
+  }
+
+  output_parcel->writeInt32(ret);
+
+  return ret;
+}
+
+android::status_t HWCSession::ConfigureRefreshRate(const android::Parcel *input_parcel) {
+  uint32_t operation = UINT32(input_parcel->readInt32());
+  switch (operation) {
+    case qdutils::DISABLE_METADATA_DYN_REFRESH_RATE:
+      return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(
+          HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, false);
+    case qdutils::ENABLE_METADATA_DYN_REFRESH_RATE:
+      return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(
+          HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, true);
+    case qdutils::SET_BINDER_DYN_REFRESH_RATE: {
+      uint32_t refresh_rate = UINT32(input_parcel->readInt32());
+      return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(
+          HWCDisplayPrimary::SET_BINDER_DYN_REFRESH_RATE, refresh_rate);
+    }
+    default:
+      DLOGW("Invalid operation %d", operation);
+      return -EINVAL;
+  }
+
+  return 0;
+}
+
+android::status_t HWCSession::SetDisplayMode(const android::Parcel *input_parcel) {
+  uint32_t mode = UINT32(input_parcel->readInt32());
+  return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(HWCDisplayPrimary::SET_DISPLAY_MODE, mode);
+}
+
+android::status_t HWCSession::SetMaxMixerStages(const android::Parcel *input_parcel) {
+  DisplayError error = kErrorNone;
+  uint32_t bit_mask_display_type = UINT32(input_parcel->readInt32());
+  uint32_t max_mixer_stages = UINT32(input_parcel->readInt32());
+
+  if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_PRIMARY)) {
+    if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+      error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetMaxMixerStages(max_mixer_stages);
+      if (error != kErrorNone) {
+        return -EINVAL;
+      }
+    }
+  }
+
+  if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_EXTERNAL)) {
+    if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
+      error = hwc_display_[HWC_DISPLAY_EXTERNAL]->SetMaxMixerStages(max_mixer_stages);
+      if (error != kErrorNone) {
+        return -EINVAL;
+      }
+    }
+  }
+
+  if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_VIRTUAL)) {
+    if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
+      error = hwc_display_[HWC_DISPLAY_VIRTUAL]->SetMaxMixerStages(max_mixer_stages);
+      if (error != kErrorNone) {
+        return -EINVAL;
+      }
+    }
+  }
+
+  return 0;
+}
+
+android::status_t HWCSession::SetDynamicBWForCamera(const android::Parcel *input_parcel,
+                                                    android::Parcel *output_parcel) {
+  DisplayError error = kErrorNone;
+  uint32_t camera_status = UINT32(input_parcel->readInt32());
+  HWBwModes mode = camera_status > 0 ? kBwCamera : kBwDefault;
+
+  // trigger invalidate to apply new bw caps.
+  callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+
+  error = core_intf_->SetMaxBandwidthMode(mode);
+  if (error != kErrorNone) {
+    return -EINVAL;
+  }
+
+  new_bw_mode_ = true;
+  need_invalidate_ = true;
+
+  return 0;
+}
+
+android::status_t HWCSession::GetBWTransactionStatus(const android::Parcel *input_parcel,
+                                                     android::Parcel *output_parcel) {
+  bool state = true;
+
+  if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+    if (sync_wait(bw_mode_release_fd_, 0) < 0) {
+      DLOGI("bw_transaction_release_fd is not yet signalled: err= %s", strerror(errno));
+      state = false;
+    }
+    output_parcel->writeInt32(state);
+  }
+
+  return 0;
+}
+
+void HWCSession::SetFrameDumpConfig(const android::Parcel *input_parcel) {
+  uint32_t frame_dump_count = UINT32(input_parcel->readInt32());
+  uint32_t bit_mask_display_type = UINT32(input_parcel->readInt32());
+  uint32_t bit_mask_layer_type = UINT32(input_parcel->readInt32());
+
+  if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_PRIMARY)) {
+    if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+      hwc_display_[HWC_DISPLAY_PRIMARY]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
+    }
+  }
+
+  if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_EXTERNAL)) {
+    if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
+      hwc_display_[HWC_DISPLAY_EXTERNAL]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
+    }
+  }
+
+  if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_VIRTUAL)) {
+    if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
+      hwc_display_[HWC_DISPLAY_VIRTUAL]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
+    }
+  }
+}
+
+void HWCSession::DynamicDebug(const android::Parcel *input_parcel) {
+  int type = input_parcel->readInt32();
+  bool enable = (input_parcel->readInt32() > 0);
+  DLOGI("type = %d enable = %d", type, enable);
+  int verbose_level = input_parcel->readInt32();
+
+  switch (type) {
+    case qService::IQService::DEBUG_ALL:
+      HWCDebugHandler::DebugAll(enable, verbose_level);
+      break;
+
+    case qService::IQService::DEBUG_MDPCOMP:
+      HWCDebugHandler::DebugStrategy(enable, verbose_level);
+      HWCDebugHandler::DebugCompManager(enable, verbose_level);
+      break;
+
+    case qService::IQService::DEBUG_PIPE_LIFECYCLE:
+      HWCDebugHandler::DebugResources(enable, verbose_level);
+      break;
+
+    case qService::IQService::DEBUG_DRIVER_CONFIG:
+      HWCDebugHandler::DebugDriverConfig(enable, verbose_level);
+      break;
+
+    case qService::IQService::DEBUG_ROTATOR:
+      HWCDebugHandler::DebugResources(enable, verbose_level);
+      HWCDebugHandler::DebugDriverConfig(enable, verbose_level);
+      HWCDebugHandler::DebugRotator(enable, verbose_level);
+      break;
+
+    case qService::IQService::DEBUG_QDCM:
+      HWCDebugHandler::DebugQdcm(enable, verbose_level);
+      break;
+
+    default:
+      DLOGW("type = %d is not supported", type);
+  }
+}
+
+android::status_t HWCSession::QdcmCMDHandler(const android::Parcel *input_parcel,
+                                             android::Parcel *output_parcel) {
+  int ret = 0;
+  int32_t *brightness_value = NULL;
+  uint32_t display_id(0);
+  PPPendingParams pending_action;
+  PPDisplayAPIPayload resp_payload, req_payload;
+
+  if (!color_mgr_) {
+    return -1;
+  }
+
+  pending_action.action = kNoAction;
+  pending_action.params = NULL;
+
+  // Read display_id, payload_size and payload from in_parcel.
+  ret = HWCColorManager::CreatePayloadFromParcel(*input_parcel, &display_id, &req_payload);
+  if (!ret) {
+    if (HWC_DISPLAY_PRIMARY == display_id && hwc_display_[HWC_DISPLAY_PRIMARY])
+      ret = hwc_display_[HWC_DISPLAY_PRIMARY]->ColorSVCRequestRoute(req_payload, &resp_payload,
+                                                                    &pending_action);
+
+    if (HWC_DISPLAY_EXTERNAL == display_id && hwc_display_[HWC_DISPLAY_EXTERNAL])
+      ret = hwc_display_[HWC_DISPLAY_EXTERNAL]->ColorSVCRequestRoute(req_payload, &resp_payload,
+                                                                     &pending_action);
+  }
+
+  if (ret) {
+    output_parcel->writeInt32(ret);  // first field in out parcel indicates return code.
+    req_payload.DestroyPayload();
+    resp_payload.DestroyPayload();
+    return ret;
+  }
+
+  switch (pending_action.action) {
+    case kInvalidating:
+      callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+      break;
+    case kEnterQDCMMode:
+      ret = color_mgr_->EnableQDCMMode(true, hwc_display_[HWC_DISPLAY_PRIMARY]);
+      break;
+    case kExitQDCMMode:
+      ret = color_mgr_->EnableQDCMMode(false, hwc_display_[HWC_DISPLAY_PRIMARY]);
+      break;
+    case kApplySolidFill:
+      ret =
+          color_mgr_->SetSolidFill(pending_action.params, true, hwc_display_[HWC_DISPLAY_PRIMARY]);
+      callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+      break;
+    case kDisableSolidFill:
+      ret =
+          color_mgr_->SetSolidFill(pending_action.params, false, hwc_display_[HWC_DISPLAY_PRIMARY]);
+      callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+      break;
+    case kSetPanelBrightness:
+      brightness_value = reinterpret_cast<int32_t *>(resp_payload.payload);
+      if (brightness_value == NULL) {
+        DLOGE("Brightness value is Null");
+        return -EINVAL;
+      }
+      if (HWC_DISPLAY_PRIMARY == display_id)
+        ret = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(*brightness_value);
+      break;
+    case kEnableFrameCapture:
+      ret = color_mgr_->SetFrameCapture(pending_action.params, true,
+                                        hwc_display_[HWC_DISPLAY_PRIMARY]);
+      callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+      break;
+    case kDisableFrameCapture:
+      ret = color_mgr_->SetFrameCapture(pending_action.params, false,
+                                        hwc_display_[HWC_DISPLAY_PRIMARY]);
+      break;
+    case kNoAction:
+      break;
+    default:
+      DLOGW("Invalid pending action = %d!", pending_action.action);
+      break;
+  }
+
+  // for display API getter case, marshall returned params into out_parcel.
+  output_parcel->writeInt32(ret);
+  HWCColorManager::MarshallStructIntoParcel(resp_payload, output_parcel);
+  req_payload.DestroyPayload();
+  resp_payload.DestroyPayload();
+
+  return (ret ? -EINVAL : 0);
+}
+
+android::status_t HWCSession::OnMinHdcpEncryptionLevelChange(const android::Parcel *input_parcel,
+                                                             android::Parcel *output_parcel) {
+  int ret = -EINVAL;
+  uint32_t display_id = UINT32(input_parcel->readInt32());
+  uint32_t min_enc_level = UINT32(input_parcel->readInt32());
+
+  DLOGI("Display %d", display_id);
+
+  if (display_id >= HWC_NUM_DISPLAY_TYPES) {
+    DLOGE("Invalid display_id");
+  } else if (display_id != HWC_DISPLAY_EXTERNAL) {
+    DLOGE("Not supported for display");
+  } else if (!hwc_display_[display_id]) {
+    DLOGW("Display is not connected");
+  } else {
+    ret = hwc_display_[display_id]->OnMinHdcpEncryptionLevelChange(min_enc_level);
+  }
+
+  output_parcel->writeInt32(ret);
+
+  return ret;
+}
+
+void *HWCSession::HWCUeventThread(void *context) {
+  if (context) {
+    return reinterpret_cast<HWCSession *>(context)->HWCUeventThreadHandler();
+  }
+
+  return NULL;
+}
+
+void *HWCSession::HWCUeventThreadHandler() {
+  static char uevent_data[PAGE_SIZE];
+  int length = 0;
+  prctl(PR_SET_NAME, uevent_thread_name_, 0, 0, 0);
+  setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
+  if (!uevent_init()) {
+    DLOGE("Failed to init uevent");
+    pthread_exit(0);
+    return NULL;
+  }
+
+  while (!uevent_thread_exit_) {
+    // keep last 2 zeroes to ensure double 0 termination
+    length = uevent_next_event(uevent_data, INT32(sizeof(uevent_data)) - 2);
+
+    if (strcasestr(HWC_UEVENT_SWITCH_HDMI, uevent_data)) {
+      DLOGI("Uevent HDMI = %s", uevent_data);
+      int connected = GetEventValue(uevent_data, length, "SWITCH_STATE=");
+      if (connected >= 0) {
+        DLOGI("HDMI = %s", connected ? "connected" : "disconnected");
+        if (HotPlugHandler(connected) == -1) {
+          DLOGE("Failed handling Hotplug = %s", connected ? "connected" : "disconnected");
+        }
+      }
+    } else if (strcasestr(HWC_UEVENT_GRAPHICS_FB0, uevent_data)) {
+      DLOGI("Uevent FB0 = %s", uevent_data);
+      int panel_reset = GetEventValue(uevent_data, length, "PANEL_ALIVE=");
+      if (panel_reset == 0) {
+        callbacks_.Refresh(0);
+        reset_panel_ = true;
+      }
+    }
+  }
+  pthread_exit(0);
+
+  return NULL;
+}
+
+int HWCSession::GetEventValue(const char *uevent_data, int length, const char *event_info) {
+  const char *iterator_str = uevent_data;
+  while (((iterator_str - uevent_data) <= length) && (*iterator_str)) {
+    char *pstr = strstr(iterator_str, event_info);
+    if (pstr != NULL) {
+      return (atoi(iterator_str + strlen(event_info)));
+    }
+    iterator_str += strlen(iterator_str) + 1;
+  }
+
+  return -1;
+}
+
+void HWCSession::ResetPanel() {
+  HWC2::Error status;
+
+  DLOGI("Powering off primary");
+  status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(HWC2::PowerMode::Off);
+  if (status != HWC2::Error::None) {
+    DLOGE("power-off on primary failed with error = %d", status);
+  }
+
+  DLOGI("Restoring power mode on primary");
+  HWC2::PowerMode mode = hwc_display_[HWC_DISPLAY_PRIMARY]->GetLastPowerMode();
+  status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(mode);
+  if (status != HWC2::Error::None) {
+    DLOGE("Setting power mode = %d on primary failed with error = %d", mode, status);
+  }
+
+  status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetVsyncEnabled(HWC2::Vsync::Enable);
+  if (status != HWC2::Error::None) {
+    DLOGE("enabling vsync failed for primary with error = %d", status);
+  }
+
+  reset_panel_ = false;
+}
+
+int HWCSession::HotPlugHandler(bool connected) {
+  int status = 0;
+  bool notify_hotplug = false;
+  bool hdmi_primary = false;
+
+  // To prevent sending events to client while a lock is held, acquire scope locks only within
+  // below scope so that those get automatically unlocked after the scope ends.
+  {
+    SEQUENCE_WAIT_SCOPE_LOCK(locker_);
+
+    if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
+      DLOGE("Primary display is not connected.");
+      return -1;
+    }
+
+    HWCDisplay *primary_display = hwc_display_[HWC_DISPLAY_PRIMARY];
+    HWCDisplay *external_display = NULL;
+
+    if (primary_display->GetDisplayClass() == DISPLAY_CLASS_EXTERNAL) {
+      external_display = static_cast<HWCDisplayExternal *>(hwc_display_[HWC_DISPLAY_PRIMARY]);
+      hdmi_primary = true;
+    }
+
+    // If primary display connected is a NULL display, then replace it with the external display
+    if (connected) {
+      // If we are in HDMI as primary and the primary display just got plugged in
+      if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
+        DLOGE("HDMI is already connected");
+        return -1;
+      }
+
+      // Connect external display if virtual display is not connected.
+      // Else, defer external display connection and process it when virtual display
+      // tears down; Do not notify SurfaceFlinger since connection is deferred now.
+      if (!hwc_display_[HWC_DISPLAY_VIRTUAL]) {
+        status = ConnectDisplay(HWC_DISPLAY_EXTERNAL);
+        if (status) {
+          return status;
+        }
+        notify_hotplug = true;
+      } else {
+        DLOGI("Virtual display is connected, pending connection");
+        external_pending_connect_ = true;
+      }
+    } else {
+      // Do not return error if external display is not in connected status.
+      // Due to virtual display concurrency, external display connection might be still pending
+      // but hdmi got disconnected before pending connection could be processed.
+
+      if (hdmi_primary) {
+        assert(external_display != NULL);
+        uint32_t x_res, y_res;
+        external_display->GetFrameBufferResolution(&x_res, &y_res);
+        // Need to manually disable VSYNC as SF is not aware of connect/disconnect cases
+        // for HDMI as primary
+        external_display->SetVsyncEnabled(HWC2::Vsync::Disable);
+        HWCDisplayExternal::Destroy(external_display);
+
+        // In HWC2, primary displays can be hotplugged out
+        notify_hotplug = true;
+      } else {
+        if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
+          status = DisconnectDisplay(HWC_DISPLAY_EXTERNAL);
+          notify_hotplug = true;
+        }
+        external_pending_connect_ = false;
+      }
+    }
+  }
+
+  if (connected && notify_hotplug) {
+    // trigger screen refresh to ensure sufficient resources are available to process new
+    // new display connection.
+    callbacks_.Refresh(0);
+    uint32_t vsync_period = UINT32(GetVsyncPeriod(HWC_DISPLAY_PRIMARY));
+    usleep(vsync_period * 2 / 1000);
+  }
+  // notify client
+  // Handle HDMI as primary here
+  if (notify_hotplug) {
+    callbacks_.Hotplug(HWC_DISPLAY_EXTERNAL,
+                       connected ? HWC2::Connection::Connected : HWC2::Connection::Disconnected);
+  }
+
+  qservice_->onHdmiHotplug(INT(connected));
+
+  return 0;
+}
+
+int HWCSession::GetVsyncPeriod(int disp) {
+  SCOPE_LOCK(locker_);
+  // default value
+  int32_t vsync_period = 1000000000l / 60;
+  auto attribute = HWC2::Attribute::VsyncPeriod;
+
+  if (hwc_display_[disp]) {
+    hwc_display_[disp]->GetDisplayAttribute(0, attribute, &vsync_period);
+  }
+
+  return vsync_period;
+}
+
+android::status_t HWCSession::GetVisibleDisplayRect(const android::Parcel *input_parcel,
+                                                    android::Parcel *output_parcel) {
+  int dpy = input_parcel->readInt32();
+
+  if (dpy < HWC_DISPLAY_PRIMARY || dpy > HWC_DISPLAY_VIRTUAL) {
+    return android::BAD_VALUE;
+  }
+
+  if (!hwc_display_[dpy]) {
+    return android::NO_INIT;
+  }
+
+  hwc_rect_t visible_rect = {0, 0, 0, 0};
+  int error = hwc_display_[dpy]->GetVisibleDisplayRect(&visible_rect);
+  if (error < 0) {
+    return error;
+  }
+
+  output_parcel->writeInt32(visible_rect.left);
+  output_parcel->writeInt32(visible_rect.top);
+  output_parcel->writeInt32(visible_rect.right);
+  output_parcel->writeInt32(visible_rect.bottom);
+
+  return android::NO_ERROR;
+}
+
+}  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
new file mode 100644
index 0000000..679619c
--- /dev/null
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright 2015 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 __HWC_SESSION_H__
+#define __HWC_SESSION_H__
+
+#include <core/core_interface.h>
+#include <utils/locker.h>
+
+#include "hwc_callbacks.h"
+#include "hwc_layers.h"
+#include "hwc_display.h"
+#include "hwc_display_primary.h"
+#include "hwc_display_external.h"
+#include "hwc_display_virtual.h"
+#include "hwc_color_manager.h"
+
+namespace sdm {
+
+class HWCSession : hwc2_device_t, public qClient::BnQClient {
+ public:
+  struct HWCModuleMethods : public hw_module_methods_t {
+    HWCModuleMethods() { hw_module_methods_t::open = HWCSession::Open; }
+  };
+
+  explicit HWCSession(const hw_module_t *module);
+  int Init();
+  int Deinit();
+  HWC2::Error CreateVirtualDisplayObject(uint32_t width, uint32_t height);
+
+  template <typename... Args>
+  static int32_t CallDisplayFunction(hwc2_device_t *device, hwc2_display_t display,
+                                     HWC2::Error (HWCDisplay::*member)(Args...), Args... args) {
+    if (!device) {
+      return HWC2_ERROR_BAD_DISPLAY;
+    }
+
+    HWCSession *hwc_session = static_cast<HWCSession *>(device);
+    auto status = HWC2::Error::BadDisplay;
+    if (hwc_session->hwc_display_[display]) {
+      auto hwc_display = hwc_session->hwc_display_[display];
+      status = (hwc_display->*member)(std::forward<Args>(args)...);
+    }
+    return INT32(status);
+  }
+
+  template <typename... Args>
+  static int32_t CallLayerFunction(hwc2_device_t *device, hwc2_display_t display,
+                                   hwc2_layer_t layer, HWC2::Error (HWCLayer::*member)(Args...),
+                                   Args... args) {
+    if (!device) {
+      return HWC2_ERROR_BAD_DISPLAY;
+    }
+
+    HWCSession *hwc_session = static_cast<HWCSession *>(device);
+    auto status = HWC2::Error::BadDisplay;
+    if (hwc_session->hwc_display_[display]) {
+      status = HWC2::Error::BadLayer;
+      auto hwc_layer = hwc_session->hwc_display_[display]->GetHWCLayer(layer);
+      if (hwc_layer != nullptr) {
+        status = (hwc_layer->*member)(std::forward<Args>(args)...);
+      }
+    }
+    return INT32(status);
+  }
+
+  // HWC2 Functions that require a concrete implementation in hwc session
+  // and hence need to be member functions
+  static int32_t CreateLayer(hwc2_device_t *device, hwc2_display_t display,
+                             hwc2_layer_t *out_layer_id);
+  static int32_t CreateVirtualDisplay(hwc2_device_t *device, uint32_t width, uint32_t height,
+                                      hwc2_display_t *out_display_id);
+  static int32_t DestroyLayer(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer);
+  static int32_t DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t display);
+  static void Dump(hwc2_device_t *device, uint32_t *out_size, char *out_buffer);
+  static int32_t PresentDisplay(hwc2_device_t *device, hwc2_display_t display,
+                                int32_t *out_retire_fence);
+  static int32_t RegisterCallback(hwc2_device_t *device, int32_t descriptor,
+                                  hwc2_callback_data_t callback_data,
+                                  hwc2_function_pointer_t pointer);
+  static int32_t SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
+                                 buffer_handle_t buffer, int32_t releaseFence);
+  static int32_t SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
+                                uint32_t z);
+  static int32_t SetPowerMode(hwc2_device_t *device, hwc2_display_t display, int32_t int_mode);
+  static int32_t ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
+                                 uint32_t *out_num_types, uint32_t *out_num_requests);
+
+ private:
+  static const int kExternalConnectionTimeoutMs = 500;
+  static const int kPartialUpdateControlTimeoutMs = 100;
+
+  // hwc methods
+  static int Open(const hw_module_t *module, const char *name, hw_device_t **device);
+  static int Close(hw_device_t *device);
+  static void GetCapabilities(struct hwc2_device *device, uint32_t *outCount,
+                              int32_t *outCapabilities);
+  static hwc2_function_pointer_t GetFunction(struct hwc2_device *device, int32_t descriptor);
+
+  // Uevent thread
+  static void *HWCUeventThread(void *context);
+  void *HWCUeventThreadHandler();
+  int GetEventValue(const char *uevent_data, int length, const char *event_info);
+  int HotPlugHandler(bool connected);
+  void ResetPanel();
+  int32_t ConnectDisplay(int disp);
+  int DisconnectDisplay(int disp);
+  int GetVsyncPeriod(int disp);
+
+  // QClient methods
+  virtual android::status_t notifyCallback(uint32_t command, const android::Parcel *input_parcel,
+                                           android::Parcel *output_parcel);
+  void DynamicDebug(const android::Parcel *input_parcel);
+  void SetFrameDumpConfig(const android::Parcel *input_parcel);
+  android::status_t SetMaxMixerStages(const android::Parcel *input_parcel);
+  android::status_t SetDisplayMode(const android::Parcel *input_parcel);
+  android::status_t SetSecondaryDisplayStatus(const android::Parcel *input_parcel,
+                                              android::Parcel *output_parcel);
+  android::status_t ToggleScreenUpdates(const android::Parcel *input_parcel,
+                                        android::Parcel *output_parcel);
+  android::status_t ConfigureRefreshRate(const android::Parcel *input_parcel);
+  android::status_t QdcmCMDHandler(const android::Parcel *input_parcel,
+                                   android::Parcel *output_parcel);
+  android::status_t ControlPartialUpdate(const android::Parcel *input_parcel, android::Parcel *out);
+  android::status_t OnMinHdcpEncryptionLevelChange(const android::Parcel *input_parcel,
+                                                   android::Parcel *output_parcel);
+  android::status_t SetPanelBrightness(const android::Parcel *input_parcel,
+                                       android::Parcel *output_parcel);
+  android::status_t GetPanelBrightness(const android::Parcel *input_parcel,
+                                       android::Parcel *output_parcel);
+  // These functions return the actual display config info as opposed to FB
+  android::status_t HandleSetActiveDisplayConfig(const android::Parcel *input_parcel,
+                                                 android::Parcel *output_parcel);
+  android::status_t HandleGetActiveDisplayConfig(const android::Parcel *input_parcel,
+                                                 android::Parcel *output_parcel);
+  android::status_t HandleGetDisplayConfigCount(const android::Parcel *input_parcel,
+                                                android::Parcel *output_parcel);
+  android::status_t HandleGetDisplayAttributesForConfig(const android::Parcel *input_parcel,
+                                                        android::Parcel *output_parcel);
+  android::status_t GetVisibleDisplayRect(const android::Parcel *input_parcel,
+                                          android::Parcel *output_parcel);
+
+  android::status_t SetDynamicBWForCamera(const android::Parcel *input_parcel,
+                                          android::Parcel *output_parcel);
+  android::status_t GetBWTransactionStatus(const android::Parcel *input_parcel,
+                                           android::Parcel *output_parcel);
+  static Locker locker_;
+  CoreInterface *core_intf_ = NULL;
+  HWCDisplay *hwc_display_[HWC_NUM_DISPLAY_TYPES] = {NULL};
+  HWCCallbacks callbacks_;
+  pthread_t uevent_thread_;
+  bool uevent_thread_exit_ = false;
+  const char *uevent_thread_name_ = "HWC_UeventThread";
+  HWCBufferAllocator *buffer_allocator_ = NULL;
+  HWCBufferSyncHandler *buffer_sync_handler_ = NULL;
+  HWCColorManager *color_mgr_ = NULL;
+  bool reset_panel_ = false;
+  bool secure_display_active_ = false;
+  bool external_pending_connect_ = false;
+  bool new_bw_mode_ = false;
+  bool need_invalidate_ = false;
+  int bw_mode_release_fd_ = -1;
+  qService::QService *qservice_ = NULL;
+};
+
+}  // namespace sdm
+
+#endif  // __HWC_SESSION_H__
