Merge "sdm: Add virtual pipe listing support"
diff --git a/common.mk b/common.mk
index 941b0a4..88d1aee 100644
--- a/common.mk
+++ b/common.mk
@@ -4,9 +4,7 @@
 #Common C flags
 common_flags := -DDEBUG_CALC_FPS -Wno-missing-field-initializers
 common_flags += -Wconversion -Wall -Werror -std=c++11
-ifneq ($(TARGET_IS_HEADLESS), true)
-    common_flags += -DCOMPILE_DRM
-else
+ifeq ($(TARGET_IS_HEADLESS), true)
     common_flags += -DTARGET_HEADLESS
     LOCAL_CLANG := false
 endif
@@ -50,7 +48,6 @@
 common_includes += $(display_top)/gpu_tonemapper
 ifneq ($(TARGET_IS_HEADLESS), true)
     common_includes += $(display_top)/libcopybit
-    common_includes += $(display_top)/libdrmutils
 endif
 
 common_includes += $(display_top)/include
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index 6e87b71..8c97215 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -116,6 +116,12 @@
    */
   PLANE_SET_INPUT_FENCE,
   /*
+   * Op: Sets scaler config on this plane.
+   * Arg: uint32_t - Plane ID
+   *      uint64_t - Address of the scaler config object (version based)
+   */
+  PLANE_SET_SCALER_CONFIG,
+  /*
    * Op: Activate or deactivate a CRTC
    * Arg: uint32_t - CRTC ID
    *      uint32_t - 1 to enable, 0 to disable
@@ -308,6 +314,15 @@
   void *payload;
 };
 
+struct DRMScalerLUTInfo {
+  uint32_t dir_lut_size = 0;
+  uint32_t cir_lut_size = 0;
+  uint32_t sep_lut_size = 0;
+  uint64_t dir_lut = 0;
+  uint64_t cir_lut = 0;
+  uint64_t sep_lut = 0;
+};
+
 /* DRM Atomic Request Property Set.
  *
  * Helper class to create and populate atomic properties of DRM components
@@ -416,6 +431,13 @@
    * [return]: Error code if the API fails, 0 on success.
    */
   virtual int DestroyAtomicReq(DRMAtomicReqInterface *intf) = 0;
+  /*
+   * Sets the global scaler LUT
+   * [input]: LUT Info
+   * [return]: Error code if the API fails, 0 on success.
+   */
+  virtual int SetScalerLUT(const DRMScalerLUTInfo &lut_info) = 0;
 };
+
 }  // namespace sde_drm
 #endif  // __DRM_INTERFACE_H__
diff --git a/libdrmutils/drm_master.cpp b/libdrmutils/drm_master.cpp
index e12b933..09e0729 100644
--- a/libdrmutils/drm_master.cpp
+++ b/libdrmutils/drm_master.cpp
@@ -94,8 +94,9 @@
   dev_fd_ = -1;
 }
 
-int DRMMaster::CreateFbId(const DRMBuffer &drm_buffer, uint32_t *gem_handle, uint32_t *fb_id) {
-  int ret = drmPrimeFDToHandle(dev_fd_, drm_buffer.fd, gem_handle);
+int DRMMaster::CreateFbId(const DRMBuffer &drm_buffer, uint32_t *fb_id) {
+  uint32_t gem_handle = 0;
+  int ret = drmPrimeFDToHandle(dev_fd_, drm_buffer.fd, &gem_handle);
   if (ret) {
     DRM_LOGE("drmPrimeFDToHandle failed with error %d", ret);
     return ret;
@@ -106,7 +107,7 @@
   cmd2.height = drm_buffer.height;
   cmd2.pixel_format = drm_buffer.drm_format;
   cmd2.flags = DRM_MODE_FB_MODIFIERS;
-  fill(begin(cmd2.handles), begin(cmd2.handles) + drm_buffer.num_planes, *gem_handle);
+  fill(begin(cmd2.handles), begin(cmd2.handles) + drm_buffer.num_planes, gem_handle);
   copy(begin(drm_buffer.stride), end(drm_buffer.stride), begin(cmd2.pitches));
   copy(begin(drm_buffer.offset), end(drm_buffer.offset), begin(cmd2.offsets));
   fill(begin(cmd2.modifier), begin(cmd2.modifier) + drm_buffer.num_planes,
@@ -114,28 +115,23 @@
 
   if ((ret = drmIoctl(dev_fd_, DRM_IOCTL_MODE_ADDFB2, &cmd2))) {
     DRM_LOGE("DRM_IOCTL_MODE_ADDFB2 failed with error %d", ret);
-    struct drm_gem_close gem_close = {};
-    gem_close.handle = *gem_handle;
-    int ret1 = drmIoctl(dev_fd_, DRM_IOCTL_GEM_CLOSE, &gem_close);
-    if (ret1) {
-      DRM_LOGE("drmIoctl::DRM_IOCTL_GEM_CLOSE failed with error %d", ret1);
-      return ret1;
-    }
-    return ret;
+  } else {
+    *fb_id = cmd2.fb_id;
   }
 
-  *fb_id = cmd2.fb_id;
-  return 0;
-}
-
-int DRMMaster::RemoveFbId(uint32_t gem_handle, uint32_t fb_id) {
   struct drm_gem_close gem_close = {};
   gem_close.handle = gem_handle;
-  int ret = drmIoctl(dev_fd_, DRM_IOCTL_GEM_CLOSE, &gem_close);
-  if (ret) {
-    DRM_LOGE("drmIoctl::DRM_IOCTL_GEM_CLOSE failed with error %d", errno);
+  int ret1 = drmIoctl(dev_fd_, DRM_IOCTL_GEM_CLOSE, &gem_close);
+  if (ret1) {
+    DRM_LOGE("drmIoctl::DRM_IOCTL_GEM_CLOSE failed with error %d", ret1);
+    return ret1;
   }
 
+  return ret;
+}
+
+int DRMMaster::RemoveFbId(uint32_t fb_id) {
+  int ret = 0;
 #ifdef DRM_IOCTL_MSM_RMFB2
   ret = drmIoctl(dev_fd_, DRM_IOCTL_MSM_RMFB2, &fb_id);
   if (ret) {
diff --git a/libdrmutils/drm_master.h b/libdrmutils/drm_master.h
index 15fae68..52a8b02 100644
--- a/libdrmutils/drm_master.h
+++ b/libdrmutils/drm_master.h
@@ -58,14 +58,14 @@
    * Returns:
    *   ioctl error code
    */
-  int CreateFbId(const DRMBuffer &drm_buffer, uint32_t *gem_handle, uint32_t *fb_id);
+  int CreateFbId(const DRMBuffer &drm_buffer, uint32_t *fb_id);
   /* Removes the fb_id from DRM
    * Input:
    *   fb_id: DRM FB to be removed
    * Returns:
    *   ioctl error code
    */
-  int RemoveFbId(uint32_t gem_handle, uint32_t fb_id);
+  int RemoveFbId(uint32_t fb_id);
   /* Poplulates master DRM fd
    * Input:
    *   fd: Pointer to store master fd into
diff --git a/libgralloc/Android.mk b/libgralloc/Android.mk
index b911999..76be57d 100644
--- a/libgralloc/Android.mk
+++ b/libgralloc/Android.mk
@@ -30,7 +30,7 @@
 LOCAL_HEADER_LIBRARIES        := display_headers
 LOCAL_SHARED_LIBRARIES        := $(common_libs) libmemalloc libqdMetaData libqdutils
 ifneq ($(TARGET_IS_HEADLESS), true)
-LOCAL_SHARED_LIBRARIES        += libGLESv1_CM libdrmutils
+LOCAL_SHARED_LIBRARIES        += libGLESv1_CM
 endif
 LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion
 LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 38e2050..1779312 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -27,9 +27,6 @@
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifdef COMPILE_DRM
-#include <drm/drm_fourcc.h>
-#endif
 #include <cutils/log.h>
 #include <fcntl.h>
 #include <dlfcn.h>
@@ -76,18 +73,6 @@
 #define ION_SC_PREVIEW_FLAGS ION_SECURE
 #endif
 
-#ifdef COMPILE_DRM
-#ifndef DRM_FORMAT_MOD_QCOM_COMPRESSED
-#define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1)
-#endif
-#ifndef DRM_FORMAT_MOD_QCOM_DX
-#define DRM_FORMAT_MOD_QCOM_DX fourcc_mod_code(QCOM, 0x2)
-#endif
-#ifndef DRM_FORMAT_MOD_QCOM_TIGHT
-#define DRM_FORMAT_MOD_QCOM_TIGHT fourcc_mod_code(QCOM, 0x4)
-#endif
-#endif
-
 #ifndef COLOR_FMT_P010_UBWC
 #define COLOR_FMT_P010_UBWC 9
 #endif
@@ -1140,9 +1125,8 @@
     return err;
 }
 
-#ifdef COMPILE_DRM
-int getPlaneStrideOffset(private_handle_t *hnd, uint32_t *stride,
-        uint32_t *offset, uint32_t *num_planes) {
+int getBufferLayout(private_handle_t *hnd, uint32_t stride[4],
+        uint32_t offset[4], uint32_t *num_planes) {
     if (!hnd || !stride || !offset || !num_planes) {
         return -EINVAL;
     }
@@ -1231,110 +1215,3 @@
 
     return 0;
 }
-
-void getDRMFormat(int hal_format, int flags, uint32_t *drm_format,
-        uint64_t *drm_format_modifier) {
-
-    if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
-        *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
-    }
-
-    switch (hal_format) {
-        case HAL_PIXEL_FORMAT_RGBA_8888:
-            *drm_format = DRM_FORMAT_ABGR8888;
-            break;
-        case HAL_PIXEL_FORMAT_RGBA_5551:
-            *drm_format = DRM_FORMAT_ABGR1555;
-            break;
-        case HAL_PIXEL_FORMAT_RGBA_4444:
-            *drm_format = DRM_FORMAT_ABGR4444;
-            break;
-        case HAL_PIXEL_FORMAT_BGRA_8888:
-            *drm_format = DRM_FORMAT_ARGB8888;
-            break;
-        case HAL_PIXEL_FORMAT_RGBX_8888:
-            *drm_format = DRM_FORMAT_XBGR8888;
-            break;
-        case HAL_PIXEL_FORMAT_BGRX_8888:
-            *drm_format = DRM_FORMAT_XRGB8888;
-            break;
-        case HAL_PIXEL_FORMAT_RGB_888:
-            *drm_format = DRM_FORMAT_BGR888;
-            break;
-        case HAL_PIXEL_FORMAT_RGB_565:
-            *drm_format = DRM_FORMAT_BGR565;
-            break;
-        case HAL_PIXEL_FORMAT_BGR_565:
-            *drm_format = DRM_FORMAT_RGB565;
-            break;
-        case HAL_PIXEL_FORMAT_RGBA_1010102:
-            *drm_format = DRM_FORMAT_ABGR2101010;
-            break;
-        case HAL_PIXEL_FORMAT_ARGB_2101010:
-            *drm_format = DRM_FORMAT_BGRA1010102;
-            break;
-        case HAL_PIXEL_FORMAT_RGBX_1010102:
-            *drm_format = DRM_FORMAT_XBGR2101010;
-            break;
-        case HAL_PIXEL_FORMAT_XRGB_2101010:
-            *drm_format = DRM_FORMAT_BGRX1010102;
-            break;
-        case HAL_PIXEL_FORMAT_BGRA_1010102:
-            *drm_format = DRM_FORMAT_ARGB2101010;
-            break;
-        case HAL_PIXEL_FORMAT_ABGR_2101010:
-            *drm_format = DRM_FORMAT_RGBA1010102;
-            break;
-        case HAL_PIXEL_FORMAT_BGRX_1010102:
-            *drm_format = DRM_FORMAT_XRGB2101010;
-            break;
-        case HAL_PIXEL_FORMAT_XBGR_2101010:
-            *drm_format = DRM_FORMAT_RGBX1010102;
-            break;
-        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
-            *drm_format = DRM_FORMAT_NV12;
-            break;
-        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
-        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
-            *drm_format = DRM_FORMAT_NV12;
-            break;
-        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
-            *drm_format = DRM_FORMAT_NV12;
-            *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
-            break;
-        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-            *drm_format = DRM_FORMAT_NV21;
-            break;
-        case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
-            *drm_format = DRM_FORMAT_NV21;
-            break;
-        case HAL_PIXEL_FORMAT_YCbCr_420_P010:
-            *drm_format = DRM_FORMAT_NV12;
-            *drm_format_modifier = DRM_FORMAT_MOD_QCOM_DX;
-            break;
-        case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
-            *drm_format = DRM_FORMAT_NV12;
-            *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED |
-               DRM_FORMAT_MOD_QCOM_DX;
-            break;
-        case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
-            *drm_format = DRM_FORMAT_NV12;
-            *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED |
-               DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_TIGHT;
-            break;
-        case HAL_PIXEL_FORMAT_YCbCr_422_SP:
-            *drm_format = DRM_FORMAT_NV16;
-            break;
-        case HAL_PIXEL_FORMAT_YCrCb_422_SP:
-            *drm_format = DRM_FORMAT_NV61;
-            break;
-        case HAL_PIXEL_FORMAT_YV12:
-            *drm_format = DRM_FORMAT_YVU420;
-            break;
-        default:
-            ALOGW("%s: Unsupported format %s", __FUNCTION__,
-                    qdutils::GetHALPixelFormatString(hal_format));
-    }
-}
-#endif
-
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index 641712c..c57ff90 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -21,12 +21,7 @@
 #include <cutils/properties.h>
 #include <sys/mman.h>
 #include <linux/msm_ion.h>
-#ifdef COMPILE_DRM
-#include <drm_master.h>
-#endif
 #include <qdMetaData.h>
-#include <qd_utils.h>
-
 #include <algorithm>
 
 #include "gr.h"
@@ -34,10 +29,6 @@
 #include "memalloc.h"
 #include "alloc_controller.h"
 
-#ifdef COMPILE_DRM
-using namespace drm_utils;
-#endif
-
 using namespace gralloc;
 
 gpu_context_t::gpu_context_t(const private_module_t* module,
@@ -178,43 +169,6 @@
         hnd->gpuaddr = 0;
         ColorSpace_t colorSpace = ITU_R_601;
         setMetaData(hnd, UPDATE_COLOR_SPACE, (void*) &colorSpace);
-
-#ifdef COMPILE_DRM
-        if (qdutils::getDriverType() == qdutils::DriverType::DRM &&
-                usage & GRALLOC_USAGE_HW_COMPOSER) {
-            DRMBuffer buf = {};
-            int ret = getPlaneStrideOffset(hnd, buf.stride, buf.offset,
-                    &buf.num_planes);
-            if (ret < 0) {
-                ALOGE("%s failed", __FUNCTION__);
-                return ret;
-            }
-
-            buf.fd = hnd->fd;
-            buf.width = hnd->width;
-            buf.height = hnd->height;
-            getDRMFormat(hnd->format, flags, &buf.drm_format,
-                    &buf.drm_format_modifier);
-
-            DRMMaster *master = nullptr;
-            ret = DRMMaster::GetInstance(&master);
-            if (ret < 0) {
-                ALOGE("%s Failed to acquire DRMMaster instance", __FUNCTION__);
-                return ret;
-            }
-
-            ret = master->CreateFbId(buf, &hnd->gem_handle, &hnd->fb_id);
-            if (ret < 0) {
-                ALOGE("%s: CreateFbId failed. width %d, height %d, " \
-                        "format: %s, stride %u, error %d", __FUNCTION__,
-                        buf.width, buf.height,
-                        qdutils::GetHALPixelFormatString(hnd->format),
-                        buf.stride[0], errno);
-                return ret;
-            }
-        }
-#endif
-
         *pHandle = hnd;
     }
 
@@ -415,22 +369,6 @@
             return err;
     }
 
-#ifdef COMPILE_DRM
-    if (hnd->fb_id) {
-        DRMMaster *master = nullptr;
-        int ret = DRMMaster::GetInstance(&master);
-        if (ret < 0) {
-            ALOGE("%s Failed to acquire DRMMaster instance", __FUNCTION__);
-            return ret;
-        }
-        ret = master->RemoveFbId(hnd->gem_handle, hnd->fb_id);
-        if (ret < 0) {
-            ALOGE("%s: Removing fb_id %d failed with error %d", __FUNCTION__,
-                    hnd->fb_id, errno);
-        }
-    }
-#endif
-
     delete hnd;
     return 0;
 }
diff --git a/libgralloc/gr.h b/libgralloc/gr.h
index edeca3f..dad4a38 100644
--- a/libgralloc/gr.h
+++ b/libgralloc/gr.h
@@ -71,13 +71,9 @@
 // Function to check if the format is an RGB format
 bool isUncompressedRgbFormat(int format);
 
-#ifdef COMPILE_DRM
-int getPlaneStrideOffset(private_handle_t *hnd, uint32_t *stride,
-        uint32_t *offset, uint32_t *num_planes);
-
-void getDRMFormat(int hal_format, int flags, uint32_t *drm_format,
-        uint64_t *drm_format_modifier);
-#endif
+// Returns number of planes, stride and offset of each plane for a given w,h,f
+int getBufferLayout(private_handle_t *hnd, uint32_t stride[4],
+        uint32_t offset[4], uint32_t *num_planes);
 /*****************************************************************************/
 
 class Locker {
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index 82fdcdb..0f1f97a 100644
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -249,8 +249,6 @@
         uint64_t base_metadata __attribute__((aligned(8)));
         int unaligned_width;   // holds width client asked to allocate
         int unaligned_height;  // holds height client asked to allocate
-        unsigned int gem_handle;
-        unsigned int fb_id;
 
 #ifdef __cplusplus
         static const int sNumFds = 2;
@@ -267,7 +265,7 @@
             base(0), offset_metadata(0), gpuaddr(0),
             format(format), width(width), height(height),
             base_metadata(0), unaligned_width(width),
-            unaligned_height(height), gem_handle(0), fb_id(0)
+            unaligned_height(height)
         {
             version = (int) sizeof(native_handle);
             numInts = sNumInts();
diff --git a/libgralloc1/Android.mk b/libgralloc1/Android.mk
index 0afe5f9..d8ee429 100644
--- a/libgralloc1/Android.mk
+++ b/libgralloc1/Android.mk
@@ -16,20 +16,31 @@
                                  external/libcxx/include/
 
 LOCAL_HEADER_LIBRARIES        := display_headers
-LOCAL_SHARED_LIBRARIES        := $(common_libs) libqdMetaData libsync libqdutils
-ifneq ($(TARGET_IS_HEADLESS), true)
-LOCAL_SHARED_LIBRARIES        += libdrmutils
-endif
+LOCAL_SHARED_LIBRARIES        := $(common_libs) libqdMetaData libsync libgrallocutils
 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 \
+LOCAL_SRC_FILES               := gr_ion_alloc.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)
+
+#libgrallocutils
+include $(CLEAR_VARS)
+LOCAL_MODULE                  := libgrallocutils
+ifneq ($(TARGET_IS_HEADLESS), true)
+LOCAL_MODULE_PATH_32          := $(TARGET_OUT_VENDOR)/lib
+LOCAL_MODULE_PATH_64          := $(TARGET_OUT_VENDOR)/lib64
+endif
+LOCAL_MODULE_TAGS             := optional
+LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes)
+LOCAL_HEADER_LIBRARIES        := display_headers
+LOCAL_SHARED_LIBRARIES        := $(common_libs) libqdutils libqdMetaData libdl
+LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"grallocutils\" -Wno-sign-conversion
+LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
+LOCAL_SRC_FILES               := gr_utils.cpp gr_adreno_info.cpp
+include $(BUILD_SHARED_LIBRARY)
diff --git a/libgralloc1/gr_adreno_info.cpp b/libgralloc1/gr_adreno_info.cpp
index f8b1af6..2736fad 100644
--- a/libgralloc1/gr_adreno_info.cpp
+++ b/libgralloc1/gr_adreno_info.cpp
@@ -30,14 +30,31 @@
 #include <cutils/log.h>
 #include <cutils/properties.h>
 #include <dlfcn.h>
+#include <mutex>
 
 #include "gralloc_priv.h"
 #include "gr_adreno_info.h"
 #include "gr_utils.h"
 
+using std::lock_guard;
+using std::mutex;
+
 namespace gralloc1 {
 
-AdrenoMemInfo::AdrenoMemInfo() {
+AdrenoMemInfo *AdrenoMemInfo::s_instance = nullptr;
+
+AdrenoMemInfo *AdrenoMemInfo::GetInstance() {
+  static mutex s_lock;
+  lock_guard<mutex> obj(s_lock);
+  if (!s_instance) {
+    s_instance = new AdrenoMemInfo();
+    if (!s_instance->Init()) {
+      delete s_instance;
+      s_instance = nullptr;
+    }
+  }
+
+  return s_instance;
 }
 
 bool AdrenoMemInfo::Init() {
@@ -182,6 +199,12 @@
     case HAL_PIXEL_FORMAT_YCbCr_420_P010:
     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
       return ADRENO_PIXELFORMAT_P010;
+    case HAL_PIXEL_FORMAT_RGBA_1010102:
+       return ADRENO_PIXELFORMAT_R10G10B10A2_UNORM;
+    case HAL_PIXEL_FORMAT_RGBX_1010102:
+       return ADRENO_PIXELFORMAT_R10G10B10X2_UNORM;
+    case HAL_PIXEL_FORMAT_ABGR_2101010:
+       return ADRENO_PIXELFORMAT_A2B10G10R10_UNORM;
     default:
       ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format);
       break;
diff --git a/libgralloc1/gr_adreno_info.h b/libgralloc1/gr_adreno_info.h
index 5a3b531..1c85c8c 100644
--- a/libgralloc1/gr_adreno_info.h
+++ b/libgralloc1/gr_adreno_info.h
@@ -37,6 +37,7 @@
 // Adreno Pixel Formats
 typedef enum {
   ADRENO_PIXELFORMAT_UNKNOWN = 0,
+  ADRENO_PIXELFORMAT_R10G10B10A2_UNORM = 24,  // Vertex, Normalized GL_UNSIGNED_INT_10_10_10_2_OES
   ADRENO_PIXELFORMAT_R8G8B8A8 = 28,
   ADRENO_PIXELFORMAT_R8G8B8A8_SRGB = 29,
   ADRENO_PIXELFORMAT_B5G6R5 = 85,
@@ -54,6 +55,10 @@
   ADRENO_PIXELFORMAT_A1B5G5R5 = 519,       //  GL_RGB5_A1
   ADRENO_PIXELFORMAT_R8G8B8X8_SRGB = 520,  //  GL_SRGB8
   ADRENO_PIXELFORMAT_R8G8B8_SRGB = 521,    //  GL_SRGB8
+  ADRENO_PIXELFORMAT_A2B10G10R10_UNORM = 532,
+                                          // Vertex, Normalized GL_UNSIGNED_INT_10_10_10_2_OES
+  ADRENO_PIXELFORMAT_R10G10B10X2_UNORM = 537,
+                                          // Vertex, Normalized GL_UNSIGNED_INT_10_10_10_2_OES
   ADRENO_PIXELFORMAT_R5G6B5 = 610,         //  RGBA version of B5G6R5
   ADRENO_PIXELFORMAT_R5G5B5A1 = 611,       //  RGBA version of B5G5R5A1
   ADRENO_PIXELFORMAT_R4G4B4A4 = 612,       //  RGBA version of B4G4R4A4
@@ -61,15 +66,11 @@
   ADRENO_PIXELFORMAT_NV21 = 619,
   ADRENO_PIXELFORMAT_Y8U8V8A8 = 620,  // YUV 4:4:4 packed (1 plane)
   ADRENO_PIXELFORMAT_Y8 = 625,        //  Single 8-bit luma only channel YUV format
-  ADRENO_PIXELFORMAT_TP10 = 654,      // YUV 4:2:0 planar 10 bits/comp (2 planes)
+  ADRENO_PIXELFORMAT_TP10 = 648,      // YUV 4:2:0 planar 10 bits/comp (2 planes)
 } ADRENOPIXELFORMAT;
 
 class AdrenoMemInfo {
  public:
-  AdrenoMemInfo();
-
-  ~AdrenoMemInfo();
-
   bool Init();
 
   /*
@@ -119,7 +120,10 @@
    */
   ADRENOPIXELFORMAT GetGpuPixelFormat(int hal_format);
 
+  static AdrenoMemInfo *GetInstance();
+
  private:
+  ~AdrenoMemInfo();
   // 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;
@@ -136,6 +140,8 @@
   bool gfx_ubwc_disable_ = false;
   bool map_fb_ = false;
   void *libadreno_utils_ = NULL;
+
+  static AdrenoMemInfo *s_instance;
 };
 
 }  // namespace gralloc1
diff --git a/libgralloc1/gr_allocator.cpp b/libgralloc1/gr_allocator.cpp
index ddcf41d..5e3ee9b 100644
--- a/libgralloc1/gr_allocator.cpp
+++ b/libgralloc1/gr_allocator.cpp
@@ -33,13 +33,9 @@
 
 #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
@@ -69,16 +65,17 @@
 #define ION_SC_PREVIEW_FLAGS ION_SECURE
 #endif
 
-#ifndef COLOR_FMT_P010_UBWC
-#define COLOR_FMT_P010_UBWC 9
-#endif
-
 using std::vector;
 using std::shared_ptr;
 
 namespace gralloc1 {
 
-Allocator::Allocator() : ion_allocator_(NULL), adreno_helper_(NULL) {
+static BufferInfo GetBufferInfo(const BufferDescriptor &descriptor) {
+  return BufferInfo(descriptor.GetWidth(), descriptor.GetHeight(), descriptor.GetFormat(),
+                    descriptor.GetProducerUsage(), descriptor.GetConsumerUsage());
+}
+
+Allocator::Allocator() : ion_allocator_(NULL) {
 }
 
 bool Allocator::Init() {
@@ -87,11 +84,6 @@
     return false;
   }
 
-  adreno_helper_ = new AdrenoMemInfo();
-  if (!adreno_helper_->Init()) {
-    return false;
-  }
-
   return true;
 }
 
@@ -99,10 +91,6 @@
   if (ion_allocator_) {
     delete ion_allocator_;
   }
-
-  if (adreno_helper_) {
-    delete adreno_helper_;
-  }
 }
 
 int Allocator::AllocateMem(AllocData *alloc_data, gralloc1_producer_usage_t prod_usage,
@@ -180,8 +168,8 @@
     }
 
     // For same format type, find the descriptor with bigger size
-    GetAlignedWidthAndHeight(*descriptors[i], &alignedw, &alignedh);
-    unsigned int size = GetSize(*descriptors[i], alignedw, alignedh);
+    GetAlignedWidthAndHeight(GetBufferInfo(*descriptors[i]), &alignedw, &alignedh);
+    unsigned int size = GetSize(GetBufferInfo(*descriptors[i]), alignedw, alignedh);
     if (max_size < size) {
       *max_index = INT(i);
       max_size = size;
@@ -196,261 +184,6 @@
   return true;
 }
 
-// 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:
-    case HAL_PIXEL_FORMAT_RAW12:
-      size = ALIGN(alignedw * alignedh, SIZE_4K);
-      break;
-    case HAL_PIXEL_FORMAT_RAW8:
-      size = alignedw * alignedh * 1;
-      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_420_P010:
-      size = ALIGN((alignedw * alignedh * 2) + (alignedw * alignedh) + 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::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_YCbCr_420_P010_UBWC:
-      GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_P010_UBWC, ycbcr);
-      ycbcr->chroma_step = 4;
-      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:
-    case HAL_PIXEL_FORMAT_RAW8:
-      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;
@@ -489,34 +222,6 @@
   return gr_format;
 }
 
-// Explicitly defined UBWC formats
-bool Allocator::IsUBwcFormat(int format) {
-  switch (format) {
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
-    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010_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. */
@@ -598,258 +303,4 @@
   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;
-    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
-      // The macro returns the stride which is 4/3 times the width, hence * 3/4
-      *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, width) * 3) / 4;
-      *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, height);
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
-      // The macro returns the stride which is 2 times the width, hence / 2
-      *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_P010_UBWC, width) / 2);
-      *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_P010_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;
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
-      size = VENUS_BUFFER_SIZE(COLOR_FMT_P010_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;
-
-  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_RAW12:
-      aligned_w = ALIGN(width * 12 / 8, 8);
-      break;
-    case HAL_PIXEL_FORMAT_RAW10:
-      aligned_w = ALIGN(width * 10 / 8, 8);
-      break;
-    case HAL_PIXEL_FORMAT_RAW8:
-      aligned_w = ALIGN(width, 8);
-      break;
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
-      aligned_w = ALIGN(width, 128);
-      break;
-    case HAL_PIXEL_FORMAT_YV12:
-    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
-    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
-    case HAL_PIXEL_FORMAT_YCbCr_422_I:
-    case HAL_PIXEL_FORMAT_YCrCb_422_I:
-    case HAL_PIXEL_FORMAT_YCbCr_420_P010:
-      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
index df1a30c..6f9de30 100644
--- a/libgralloc1/gr_allocator.h
+++ b/libgralloc1/gr_allocator.h
@@ -40,7 +40,6 @@
 
 #include "gralloc_priv.h"
 #include "gr_buf_descriptor.h"
-#include "gr_adreno_info.h"
 #include "gr_ion_alloc.h"
 
 namespace gralloc1 {
@@ -62,37 +61,13 @@
                              ssize_t *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);
-  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);
 
   IonAlloc *ion_allocator_ = NULL;
-  AdrenoMemInfo *adreno_helper_ = NULL;
 };
 
 }  // namespace gralloc1
diff --git a/libgralloc1/gr_buf_descriptor.h b/libgralloc1/gr_buf_descriptor.h
index 1f86867..c909fa4 100644
--- a/libgralloc1/gr_buf_descriptor.h
+++ b/libgralloc1/gr_buf_descriptor.h
@@ -31,6 +31,7 @@
 #define __GR_BUF_DESCRIPTOR_H__
 
 #include <hardware/gralloc1.h>
+#include <atomic>
 
 namespace gralloc1 {
 class BufferDescriptor {
diff --git a/libgralloc1/gr_buf_mgr.cpp b/libgralloc1/gr_buf_mgr.cpp
index d3a307b..66a8e17 100644
--- a/libgralloc1/gr_buf_mgr.cpp
+++ b/libgralloc1/gr_buf_mgr.cpp
@@ -18,6 +18,7 @@
  */
 
 #define DEBUG 0
+
 #include <iomanip>
 #include <utility>
 #include <vector>
@@ -33,6 +34,11 @@
 namespace gralloc1 {
 std::atomic<gralloc1_buffer_descriptor_t> BufferDescriptor::next_id_(1);
 
+static BufferInfo GetBufferInfo(const BufferDescriptor &descriptor) {
+  return BufferInfo(descriptor.GetWidth(), descriptor.GetHeight(), descriptor.GetFormat(),
+                    descriptor.GetProducerUsage(), descriptor.GetConsumerUsage());
+}
+
 BufferManager::BufferManager() : next_id_(0) {
   char property[PROPERTY_VALUE_MAX];
 
@@ -160,7 +166,9 @@
 
   // Get Buffer attributes or dimension
   unsigned int alignedw = 0, alignedh = 0;
-  allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
+  BufferInfo info = GetBufferInfo(descriptor);
+
+  GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
 
   // create new handle from input reference handle and given descriptor
   int flags = GetHandleFlags(descriptor.GetFormat(), descriptor.GetProducerUsage(),
@@ -425,7 +433,7 @@
     flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
   }
 
-  if (allocator_->IsUBwcEnabled(format, prod_usage, cons_usage)) {
+  if (IsUBwcEnabled(format, prod_usage, cons_usage)) {
     flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
   }
 
@@ -477,7 +485,8 @@
   unsigned int size;
   unsigned int alignedw, alignedh;
   int buffer_type = GetBufferType(gralloc_format);
-  allocator_->GetBufferSizeAndDimensions(descriptor, &size, &alignedw, &alignedh);
+  BufferInfo info = GetBufferInfo(descriptor);
+  GetBufferSizeAndDimensions(info, &size, &alignedw, &alignedh);
   size = (bufferSize >= size) ? bufferSize : size;
   size = size * layer_count;
 
@@ -566,8 +575,8 @@
         hnd->offset = offset;
         hnd->base = uint64_t(base) + offset;
         hnd->gpuaddr = 0;
-        BufferDescriptor descriptor(width, height, format);
-        allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
+        BufferInfo info(width, height, format);
+        GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
         hnd->unaligned_width = width;
         hnd->unaligned_height = height;
         hnd->width = INT(alignedw);
@@ -582,8 +591,8 @@
       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);
+      BufferInfo info(width, width, format);
+      GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
       *stride = INT(alignedw);
     } break;
 
@@ -636,10 +645,9 @@
       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_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
+      BufferInfo info(width, height, format, prod_usage, cons_usage);
+      *tile_enabled = IsUBwcEnabled(format, prod_usage, cons_usage);
+      GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
       *aligned_width = INT(alignedw);
       *aligned_height = INT(alignedh);
     } break;
@@ -681,7 +689,7 @@
       if (private_handle_t::validate(hnd) != 0) {
         return GRALLOC1_ERROR_BAD_HANDLE;
       }
-      if (allocator_->GetYUVPlaneInfo(hnd, ycbcr)) {
+      if (GetYUVPlaneInfo(hnd, ycbcr)) {
         return GRALLOC1_ERROR_UNDEFINED;
       }
     } break;
@@ -713,7 +721,7 @@
       if (private_handle_t::validate(hnd) != 0) {
         return GRALLOC1_ERROR_BAD_HANDLE;
       }
-      if (allocator_->GetRgbDataAddress(hnd, rgb_data)) {
+      if (GetRgbDataAddress(hnd, rgb_data)) {
         return GRALLOC1_ERROR_UNDEFINED;
       }
     } break;
@@ -729,8 +737,8 @@
       uint32_t *aligned_width = va_arg(args, uint32_t *);
       uint32_t *aligned_height = va_arg(args, uint32_t *);
       uint32_t *size = va_arg(args, uint32_t *);
-      auto descriptor = BufferDescriptor(width, height, format, producer_usage, consumer_usage);
-      allocator_->GetBufferSizeAndDimensions(descriptor, size, aligned_width, aligned_height);
+      auto info = BufferInfo(width, height, format, producer_usage, consumer_usage);
+      GetBufferSizeAndDimensions(info, size, aligned_width, aligned_height);
       // Align size
       auto align = GetDataAlignment(format, producer_usage, consumer_usage);
       *size = ALIGN(*size, align);
@@ -750,7 +758,7 @@
       BufferDescriptor descriptor(width, height, format, producer_usage, consumer_usage);
       unsigned int size;
       unsigned int alignedw, alignedh;
-      allocator_->GetBufferSizeAndDimensions(descriptor, &size, &alignedw, &alignedh);
+      GetBufferSizeAndDimensions(GetBufferInfo(descriptor), &size, &alignedw, &alignedh);
       AllocateBuffer(descriptor, hnd, size);
     } break;
 
@@ -798,7 +806,7 @@
   }
 
   android_ycbcr ycbcr;
-  int err = allocator_->GetYUVPlaneInfo(hnd, &ycbcr);
+  int err = GetYUVPlaneInfo(hnd, &ycbcr);
 
   if (err != 0) {
     return GRALLOC1_ERROR_BAD_HANDLE;
diff --git a/libgralloc1/gr_priv_handle.h b/libgralloc1/gr_priv_handle.h
index 5948aab..49e09a5 100644
--- a/libgralloc1/gr_priv_handle.h
+++ b/libgralloc1/gr_priv_handle.h
@@ -76,7 +76,6 @@
   unsigned int size;
   unsigned int offset;
   unsigned int offset_metadata;
-  unsigned int fb_id;
   uint64_t base                            __attribute__((aligned(8)));
   uint64_t base_metadata                   __attribute__((aligned(8)));
   uint64_t gpuaddr                         __attribute__((aligned(8)));
@@ -118,7 +117,6 @@
         size(size),
         offset(0),
         offset_metadata(0),
-        fb_id(0),
         base(0),
         base_metadata(0),
         gpuaddr(0),
diff --git a/libgralloc1/gr_utils.cpp b/libgralloc1/gr_utils.cpp
index f3c4ba8..444de8c 100644
--- a/libgralloc1/gr_utils.cpp
+++ b/libgralloc1/gr_utils.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017, 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
@@ -27,7 +27,18 @@
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <media/msm_media_info.h>
+#include <algorithm>
+
 #include "gr_utils.h"
+#include "gr_adreno_info.h"
+#include "qdMetaData.h"
+
+#define ASTC_BLOCK_SIZE 16
+
+#ifndef COLOR_FMT_P010_UBWC
+#define COLOR_FMT_P010_UBWC 9
+#endif
 
 namespace gralloc1 {
 
@@ -109,6 +120,14 @@
     case HAL_PIXEL_FORMAT_RGBX_8888:
     case HAL_PIXEL_FORMAT_BGRA_8888:
     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:
       bpp = 4;
       break;
     case HAL_PIXEL_FORMAT_RGB_888:
@@ -121,7 +140,7 @@
       bpp = 2;
       break;
     default:
-      ALOGE("Error : %s New format request", __FUNCTION__);
+      ALOGE("Error : %s New format request = 0x%x", __FUNCTION__, format);
       break;
   }
 
@@ -153,4 +172,620 @@
   return false;
 }
 
+unsigned int GetSize(const BufferInfo &info, unsigned int alignedw,
+                     unsigned int alignedh) {
+  unsigned int size = 0;
+  int format = info.format;
+  int width = info.width;
+  int height = info.height;
+  gralloc1_producer_usage_t prod_usage = info.prod_usage;
+  gralloc1_consumer_usage_t cons_usage = info.cons_usage;
+
+  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:
+    case HAL_PIXEL_FORMAT_RAW12:
+      size = ALIGN(alignedw * alignedh, SIZE_4K);
+      break;
+    case HAL_PIXEL_FORMAT_RAW8:
+      size = alignedw * alignedh * 1;
+      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_420_P010:
+      size = ALIGN((alignedw * alignedh * 2) + (alignedw * alignedh) + 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 GetBufferSizeAndDimensions(const BufferInfo &info, unsigned int *size,
+                                unsigned int *alignedw, unsigned int *alignedh) {
+  GetAlignedWidthAndHeight(info, alignedw, alignedh);
+  *size = GetSize(info, *alignedw, *alignedh);
+}
+
+void 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 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 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;
+    }
+
+    BufferInfo info(metadata->bufferDim.sliceWidth, metadata->bufferDim.sliceHeight, format,
+                    prod_usage, cons_usage);
+    GetAlignedWidthAndHeight(info, &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_YCbCr_420_P010_UBWC:
+      GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_P010_UBWC, ycbcr);
+      ycbcr->chroma_step = 4;
+      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:
+    case HAL_PIXEL_FORMAT_RAW8:
+      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;
+}
+
+// Explicitly defined UBWC formats
+bool IsUBwcFormat(int format) {
+  switch (format) {
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+    case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
+      return true;
+    default:
+      return false;
+  }
+}
+
+bool 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:
+    case HAL_PIXEL_FORMAT_RGBA_1010102:
+    case HAL_PIXEL_FORMAT_RGBX_1010102:
+      return true;
+    default:
+      break;
+  }
+
+  return false;
+}
+
+bool 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 = AdrenoMemInfo::GetInstance()->IsUBWCSupportedByGPU(format);
+    }
+
+    // Allow UBWC, only if CPU usage flags are not set
+    if (enable && !(CpuCanAccess(prod_usage, cons_usage))) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+void 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;
+    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+      // The macro returns the stride which is 4/3 times the width, hence * 3/4
+      *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, width) * 3) / 4;
+      *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, height);
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
+      // The macro returns the stride which is 2 times the width, hence / 2
+      *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_P010_UBWC, width) / 2);
+      *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_P010_UBWC, height);
+      break;
+    default:
+      ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
+      *aligned_w = 0;
+      *aligned_h = 0;
+      break;
+  }
+}
+
+void 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 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 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;
+    case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
+      size = VENUS_BUFFER_SIZE(COLOR_FMT_P010_UBWC, width, height);
+      break;
+    default:
+      ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
+      break;
+  }
+
+  return size;
+}
+
+int GetRgbDataAddress(private_handle_t *hnd, void **rgb_data) {
+  int err = 0;
+
+  // This api is for RGB* formats
+  if (!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:
+    case HAL_PIXEL_FORMAT_RGBA_1010102:
+    case HAL_PIXEL_FORMAT_RGBX_1010102:
+      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 GetAlignedWidthAndHeight(const BufferInfo &info, unsigned int *alignedw,
+                              unsigned int *alignedh) {
+  int width = info.width;
+  int height = info.height;
+  int format = info.format;
+  gralloc1_producer_usage_t prod_usage = info.prod_usage;
+  gralloc1_consumer_usage_t cons_usage = info.cons_usage;
+
+  // Currently surface padding is only computed for RGB* surfaces.
+  bool ubwc_enabled = IsUBwcEnabled(format, prod_usage, cons_usage);
+  int tile = ubwc_enabled;
+
+  if (IsUncompressedRGBFormat(format)) {
+    AdrenoMemInfo::GetInstance()->AlignUnCompressedRGB(width, height, format, tile, alignedw,
+                                                       alignedh);
+    return;
+  }
+
+  if (ubwc_enabled) {
+    GetYuvUBwcWidthAndHeight(width, height, format, alignedw, alignedh);
+    return;
+  }
+
+  if (IsCompressedRGBFormat(format)) {
+    AdrenoMemInfo::GetInstance()->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 = AdrenoMemInfo::GetInstance()->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_RAW12:
+      aligned_w = ALIGN(width * 12 / 8, 8);
+      break;
+    case HAL_PIXEL_FORMAT_RAW10:
+      aligned_w = ALIGN(width * 10 / 8, 8);
+      break;
+    case HAL_PIXEL_FORMAT_RAW8:
+      aligned_w = ALIGN(width, 8);
+      break;
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
+      aligned_w = ALIGN(width, 128);
+      break;
+    case HAL_PIXEL_FORMAT_YV12:
+    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+    case HAL_PIXEL_FORMAT_YCbCr_422_I:
+    case HAL_PIXEL_FORMAT_YCrCb_422_I:
+    case HAL_PIXEL_FORMAT_YCbCr_420_P010:
+      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;
+}
+
+int GetBufferLayout(private_handle_t *hnd, uint32_t stride[4],
+                    uint32_t offset[4], uint32_t *num_planes) {
+  if (!hnd || !stride || !offset || !num_planes) {
+    return -EINVAL;
+  }
+
+  struct android_ycbcr yuvInfo = {};
+  *num_planes = 1;
+  stride[0] = 0;
+
+  switch (hnd->format) {
+    case HAL_PIXEL_FORMAT_RGB_565:
+    case HAL_PIXEL_FORMAT_BGR_565:
+    case HAL_PIXEL_FORMAT_RGBA_5551:
+    case HAL_PIXEL_FORMAT_RGBA_4444:
+      stride[0] = static_cast<uint32_t>(hnd->width * 2);
+      break;
+    case HAL_PIXEL_FORMAT_RGB_888:
+      stride[0] = static_cast<uint32_t>(hnd->width * 3);
+      break;
+    case HAL_PIXEL_FORMAT_RGBA_8888:
+    case HAL_PIXEL_FORMAT_BGRA_8888:
+    case HAL_PIXEL_FORMAT_RGBX_8888:
+    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:
+      stride[0] = static_cast<uint32_t>(hnd->width * 4);
+      break;
+  }
+
+  // Format is RGB
+  if (stride[0]) {
+    return 0;
+  }
+
+  (*num_planes)++;
+  int ret = GetYUVPlaneInfo(hnd, &yuvInfo);
+  if (ret < 0) {
+    ALOGE("%s failed", __FUNCTION__);
+    return ret;
+  }
+
+  stride[0] = static_cast<uint32_t>(yuvInfo.ystride);
+  offset[0] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.y) - hnd->base);
+  stride[1] = static_cast<uint32_t>(yuvInfo.cstride);
+  switch (hnd->format) {
+    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:
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+    case HAL_PIXEL_FORMAT_YCbCr_420_P010:
+    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
+    case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
+      offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
+      break;
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
+    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+      offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
+      break;
+    case HAL_PIXEL_FORMAT_YV12:
+      offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
+      stride[2] = static_cast<uint32_t>(yuvInfo.cstride);
+      offset[2] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
+      (*num_planes)++;
+      break;
+    default:
+      ALOGW("%s: Unsupported format", __FUNCTION__);
+      ret = -EINVAL;
+  }
+
+  if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
+    std::fill(offset, offset + 4, 0);
+  }
+
+  return 0;
+}
+
 }  // namespace gralloc1
diff --git a/libgralloc1/gr_utils.h b/libgralloc1/gr_utils.h
index 20f0be5..aa66fd0 100644
--- a/libgralloc1/gr_utils.h
+++ b/libgralloc1/gr_utils.h
@@ -44,6 +44,17 @@
 
 namespace gralloc1 {
 
+struct BufferInfo {
+  BufferInfo(int w, int h, int f, gralloc1_producer_usage_t prod = GRALLOC1_PRODUCER_USAGE_NONE,
+             gralloc1_consumer_usage_t cons = GRALLOC1_CONSUMER_USAGE_NONE) : width(w), height(h),
+    format(f), prod_usage(prod), cons_usage(cons) {}
+  int width;
+  int height;
+  int format;
+  gralloc1_producer_usage_t prod_usage;
+  gralloc1_consumer_usage_t cons_usage;
+};
+
 template <class Type1, class Type2>
 inline Type1 ALIGN(Type1 x, Type2 align) {
   return (Type1)((x + (Type1)align - 1) & ~((Type1)align - 1));
@@ -55,7 +66,29 @@
 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);
-
+unsigned int GetSize(const BufferInfo &d, unsigned int alignedw, unsigned int alignedh);
+void GetBufferSizeAndDimensions(const BufferInfo &d, unsigned int *size,
+                                unsigned int *alignedw, unsigned int *alignedh);
+void GetAlignedWidthAndHeight(const BufferInfo &d, unsigned int *aligned_w,
+                              unsigned int *aligned_h);
+int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr *ycbcr);
+int GetRgbDataAddress(private_handle_t *hnd, void **rgb_data);
+bool IsUBwcFormat(int format);
+bool IsUBwcSupported(int format);
+bool IsUBwcEnabled(int format, gralloc1_producer_usage_t prod_usage,
+                   gralloc1_consumer_usage_t cons_usage);
+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);
+int GetBufferLayout(private_handle_t *hnd, uint32_t stride[4],
+                    uint32_t offset[4], uint32_t *num_planes);
 }  // namespace gralloc1
 
 #endif  // __GR_UTILS_H__
diff --git a/libqdutils/qdMetaData.cpp b/libqdutils/qdMetaData.cpp
index f1eece9..ae23b53 100644
--- a/libqdutils/qdMetaData.cpp
+++ b/libqdutils/qdMetaData.cpp
@@ -35,6 +35,10 @@
 #include <gralloc_priv.h>
 #include "qdMetaData.h"
 
+unsigned long getMetaDataSize() {
+    return static_cast<unsigned long>(ROUND_UP_PAGESIZE(sizeof(MetaData_t)));
+}
+
 static int validateAndMap(private_handle_t* handle) {
     if (private_handle_t::validate(handle)) {
         ALOGE("%s: Private handle is invalid - handle:%p", __func__, handle);
@@ -47,7 +51,7 @@
     }
 
     if (!handle->base_metadata) {
-        unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
+        auto size = getMetaDataSize();
         void *base = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED,
                 handle->fd_metadata, 0);
         if (base == reinterpret_cast<void*>(MAP_FAILED)) {
@@ -62,12 +66,18 @@
 }
 
 int setMetaData(private_handle_t *handle, DispParamType paramType,
-                                                    void *param) {
+                void *param) {
     auto err = validateAndMap(handle);
     if (err != 0)
         return err;
+    return setMetaDataVa(reinterpret_cast<MetaData_t*>(handle->base_metadata),
+                         paramType, param);
+}
 
-    MetaData_t *data = reinterpret_cast <MetaData_t *>(handle->base_metadata);
+int setMetaDataVa(MetaData_t *data, DispParamType paramType,
+                  void *param) {
+    if (data == nullptr)
+        return -EINVAL;
     // If parameter is NULL reset the specific MetaData Key
     if (!param) {
        data->operation &= ~paramType;
@@ -126,8 +136,13 @@
     auto err = validateAndMap(handle);
     if (err != 0)
         return err;
+    return clearMetaDataVa(reinterpret_cast<MetaData_t *>(handle->base_metadata),
+            paramType);
+}
 
-    MetaData_t *data = reinterpret_cast <MetaData_t *>(handle->base_metadata);
+int clearMetaDataVa(MetaData_t *data, DispParamType paramType) {
+    if (data == nullptr)
+        return -EINVAL;
     data->operation &= ~paramType;
     switch (paramType) {
         case SET_S3D_COMP:
@@ -146,9 +161,16 @@
     int ret = validateAndMap(handle);
     if (ret != 0)
         return ret;
-    MetaData_t *data = reinterpret_cast <MetaData_t *>(handle->base_metadata);
+    return getMetaDataVa(reinterpret_cast<MetaData_t *>(handle->base_metadata),
+                         paramType, param);
+}
+
+int getMetaDataVa(MetaData_t *data, DispFetchParamType paramType,
+                  void *param) {
     // Make sure we send 0 only if the operation queried is present
-    ret = -EINVAL;
+    int ret = -EINVAL;
+    if (data == nullptr)
+        return ret;
 
     switch (paramType) {
         case GET_PP_PARAM_INTERLACED:
@@ -241,9 +263,49 @@
     if (err != 0)
         return err;
 
-    unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
     MetaData_t *src_data = reinterpret_cast <MetaData_t *>(src->base_metadata);
     MetaData_t *dst_data = reinterpret_cast <MetaData_t *>(dst->base_metadata);
-    memcpy(src_data, dst_data, size);
+    memcpy(src_data, dst_data, getMetaDataSize());
     return 0;
 }
+
+int copyMetaDataVaToHandle(MetaData_t *src_data, struct private_handle_t *dst) {
+    int err = -EINVAL;
+    if (src_data == nullptr)
+        return err;
+
+    err = validateAndMap(dst);
+    if (err != 0)
+        return err;
+
+    MetaData_t *dst_data = reinterpret_cast <MetaData_t *>(dst->base_metadata);
+    memcpy(src_data, dst_data, getMetaDataSize());
+    return 0;
+}
+
+int copyMetaDataHandleToVa(struct private_handle_t *src, MetaData_t *dst_data) {
+    int err = -EINVAL;
+    if (dst_data == nullptr)
+        return err;
+
+    err = validateAndMap(src);
+    if (err != 0)
+        return err;
+
+    MetaData_t *src_data = reinterpret_cast <MetaData_t *>(src->base_metadata);
+    memcpy(src_data, dst_data, getMetaDataSize());
+    return 0;
+}
+
+int copyMetaDataVaToVa(MetaData_t *src_data, MetaData_t *dst_data) {
+    int err = -EINVAL;
+    if (src_data == nullptr)
+        return err;
+
+    if (dst_data == nullptr)
+        return err;
+
+    memcpy(src_data, dst_data, getMetaDataSize());
+    return 0;
+}
+
diff --git a/libqdutils/qdMetaData.h b/libqdutils/qdMetaData.h
index a0ac324..e704f6c 100644
--- a/libqdutils/qdMetaData.h
+++ b/libqdutils/qdMetaData.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017, 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
@@ -38,6 +38,8 @@
 extern "C" {
 #endif
 
+#define MAX_UBWC_STATS_LENGTH 32
+
 enum ColorSpace_t{
     ITU_R_601,
     ITU_R_601_FR,
@@ -63,6 +65,35 @@
     int32_t sliceHeight;
 };
 
+enum UBWC_Version {
+    UBWC_UNUSED      = 0,
+    UBWC_1_0         = 0x1,
+    UBWC_2_0         = 0x2,
+    UBWC_MAX_VERSION = 0xFF,
+};
+
+struct UBWC_2_0_Stats {
+    uint32_t nCRStatsTile32;  /**< UBWC Stats info for  32 Byte Tile */
+    uint32_t nCRStatsTile64;  /**< UBWC Stats info for  64 Byte Tile */
+    uint32_t nCRStatsTile96;  /**< UBWC Stats info for  96 Byte Tile */
+    uint32_t nCRStatsTile128; /**< UBWC Stats info for 128 Byte Tile */
+    uint32_t nCRStatsTile160; /**< UBWC Stats info for 160 Byte Tile */
+    uint32_t nCRStatsTile192; /**< UBWC Stats info for 192 Byte Tile */
+    uint32_t nCRStatsTile256; /**< UBWC Stats info for 256 Byte Tile */
+};
+
+struct UBWCStats {
+    enum UBWC_Version version; /* Union depends on this version. */
+    uint8_t bDataValid;      /* If [non-zero], CR Stats data is valid.
+                               * Consumers may use stats data.
+                               * If [zero], CR Stats data is invalid.
+                               * Consumers *Shall* not use stats data */
+    union {
+        struct UBWC_2_0_Stats ubwc_stats;
+        uint32_t reserved[MAX_UBWC_STATS_LENGTH]; /* This is for future */
+    };
+};
+
 struct S3DGpuComp_t {
     int32_t displayId; /* on which display S3D is composed by client */
     uint32_t s3dMode; /* the S3D format of this layer to be accessed by client */
@@ -99,6 +130,14 @@
     /* Color Aspects + HDR info */
     ColorMetaData color;
 #endif
+    /* Consumer should read this data as follows based on
+     * Gralloc flag "interlaced" listed above.
+     * [0] : If it is progressive.
+     * [0] : Top field, if it is interlaced.
+     * [1] : Do not read, if it is progressive.
+     * [1] : Bottom field, if it is interlaced.
+     */
+    struct UBWCStats ubwcCRStats[2];
 };
 
 enum DispParamType {
@@ -108,7 +147,7 @@
     UNUSED2                  = 0x0008,
     UNUSED3                  = 0x0010,
     UNUSED4                  = 0x0020,
-    UNUSED5                  = 0x0040,
+    SET_UBWC_CR_STATS_INFO   = 0x0040,
     UPDATE_BUFFER_GEOMETRY   = 0x0080,
     UPDATE_REFRESH_RATE      = 0x0100,
     UPDATE_COLOR_SPACE       = 0x0200,
@@ -124,6 +163,7 @@
     GET_VT_TIMESTAMP         = 0x0001,
     GET_COLOR_METADATA       = 0x0002,
     GET_PP_PARAM_INTERLACED  = 0x0004,
+    GET_UBWC_CR_STATS_INFO   = 0x0040,
     GET_BUFFER_GEOMETRY      = 0x0080,
     GET_REFRESH_RATE         = 0x0100,
     GET_COLOR_SPACE          = 0x0200,
@@ -137,14 +177,25 @@
 
 struct private_handle_t;
 int setMetaData(struct private_handle_t *handle, enum DispParamType paramType,
-        void *param);
+                void *param);
+int setMetaDataVa(struct MetaData_t* data, enum DispParamType paramType,
+                  void *param);
 
-int getMetaData(struct private_handle_t *handle, enum DispFetchParamType paramType,
-        void *param);
+int getMetaData(struct private_handle_t *handle,
+                enum DispFetchParamType paramType,
+                void *param);
+int getMetaDataVa(struct MetaData_t* data, enum DispFetchParamType paramType,
+                  void *param);
 
 int copyMetaData(struct private_handle_t *src, struct private_handle_t *dst);
+int copyMetaDataVaToHandle(struct MetaData_t *src, struct private_handle_t *dst);
+int copyMetaDataHandleToVa(struct private_handle_t* src, struct MetaData_t *dst);
+int copyMetaDataVaToVa(struct MetaData_t *src, struct MetaData_t *dst);
 
 int clearMetaData(struct private_handle_t *handle, enum DispParamType paramType);
+int clearMetaDataVa(struct MetaData_t *data, enum DispParamType paramType);
+
+unsigned long getMetaDataSize();
 
 #ifdef __cplusplus
 }
diff --git a/sdm/include/core/buffer_allocator.h b/sdm/include/core/buffer_allocator.h
index 3d805ae..ccb9a1b 100644
--- a/sdm/include/core/buffer_allocator.h
+++ b/sdm/include/core/buffer_allocator.h
@@ -67,9 +67,8 @@
   uint32_t stride = 0;           //!< Specifies allocated buffer stride in bytes.
   uint32_t aligned_width = 0;    //!< Specifies aligned allocated buffer width in pixels.
   uint32_t aligned_height = 0;   //!< Specifies aligned allocated buffer height in pixels.
+  LayerBufferFormat format = kFormatInvalid;  // Specifies buffer format for allocated buffer.
   uint32_t size = 0;             //!< Specifies the size of the allocated buffer.
-  uint32_t fb_id = 0;            // Registered id with the DRM driver
-  uint32_t gem_handle = 0;       // GEM driver handle for correspoding import of ION buffer
 };
 
 /*! @brief Holds the information about the input/output configuration of an output buffer.
@@ -140,6 +139,15 @@
   virtual DisplayError GetAllocatedBufferInfo(const BufferConfig &buffer_config,
                                               AllocatedBufferInfo *allocated_buffer_info) = 0;
 
+  /*
+   * Retuns a buffer's layout in terms of number of planes, stride and offset of each plane
+   * Input: AllocatedBufferInfo with a valid aligned width, aligned height, SDM format
+   * Output: stride for each plane, offset of each plane from base, number of planes
+   */
+  virtual DisplayError GetBufferLayout(const AllocatedBufferInfo &buf_info,
+                                       uint32_t stride[4], uint32_t offset[4],
+                                       uint32_t *num_planes) { return kErrorNotSupported; }
+
  protected:
   virtual ~BufferAllocator() { }
 };
diff --git a/sdm/include/core/layer_buffer.h b/sdm/include/core/layer_buffer.h
index 9029c12..c86e020 100644
--- a/sdm/include/core/layer_buffer.h
+++ b/sdm/include/core/layer_buffer.h
@@ -268,7 +268,6 @@
                                 //!< could be modified by both client and SDM.
   uint64_t buffer_id __attribute__((aligned(8))) = 0;
                                 //!< Specifies the buffer id.
-  uint32_t fb_id = 0;  // DRM f/w registered framebuffer id
 };
 
 // This enum represents buffer layout types.
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index 1f8090b..4ab50a2 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -240,12 +240,12 @@
   DisplayPort port = kPortDefault;    // Display port
   HWDisplayMode mode = kModeDefault;  // Display mode
   bool partial_update = false;        // Partial update feature
-  int left_align = 0;                 // ROI left alignment restriction
-  int width_align = 0;                // ROI width alignment restriction
-  int top_align = 0;                  // ROI top alignment restriction
-  int height_align = 0;               // ROI height alignment restriction
-  int min_roi_width = 0;              // Min width needed for ROI
-  int min_roi_height = 0;             // Min height needed for ROI
+  int left_align = 1;                 // ROI left alignment restriction
+  int width_align = 1;                // ROI width alignment restriction
+  int top_align = 1;                  // ROI top alignment restriction
+  int height_align = 1;               // ROI height alignment restriction
+  int min_roi_width = 1;              // Min width needed for ROI
+  int min_roi_height = 1;             // Min height needed for ROI
   bool needs_roi_merge = false;       // Merge ROI's of both the DSI's
   bool dynamic_fps = false;           // Panel Supports dynamic fps
   bool dfps_porch_mode = false;       // dynamic fps VFP or HFP mode
diff --git a/sdm/libs/core/Android.mk b/sdm/libs/core/Android.mk
index 874b150..4ef9a22 100644
--- a/sdm/libs/core/Android.mk
+++ b/sdm/libs/core/Android.mk
@@ -21,7 +21,7 @@
 LOCAL_SHARED_LIBRARIES        := libdl libsdmutils
 
 ifneq ($(TARGET_IS_HEADLESS), true)
-    LOCAL_CFLAGS              += -isystem external/libdrm
+    LOCAL_CFLAGS              += -DCOMPILE_DRM -isystem external/libdrm
     LOCAL_SHARED_LIBRARIES    += libdrm libdrmutils
     LOCAL_HW_INTF_PATH_2      := drm
 endif
@@ -58,6 +58,7 @@
     LOCAL_SRC_FILES           += $(LOCAL_HW_INTF_PATH_2)/hw_info_drm.cpp \
                                  $(LOCAL_HW_INTF_PATH_2)/hw_device_drm.cpp \
                                  $(LOCAL_HW_INTF_PATH_2)/hw_events_drm.cpp \
+                                 $(LOCAL_HW_INTF_PATH_2)/hw_scale_drm.cpp \
                                  $(LOCAL_HW_INTF_PATH_2)/hw_color_manager_drm.cpp
 endif
 
diff --git a/sdm/libs/core/core_impl.cpp b/sdm/libs/core/core_impl.cpp
index 369e2dd..661616e 100644
--- a/sdm/libs/core/core_impl.cpp
+++ b/sdm/libs/core/core_impl.cpp
@@ -125,15 +125,15 @@
   switch (type) {
   case kPrimary:
     display_base = new DisplayPrimary(event_handler, hw_info_intf_, buffer_sync_handler_,
-                                      &comp_mgr_);
+                                      buffer_allocator_, &comp_mgr_);
     break;
   case kHDMI:
     display_base = new DisplayHDMI(event_handler, hw_info_intf_, buffer_sync_handler_,
-                                   &comp_mgr_);
+                                   buffer_allocator_, &comp_mgr_);
     break;
   case kVirtual:
     display_base = new DisplayVirtual(event_handler, hw_info_intf_, buffer_sync_handler_,
-                                      &comp_mgr_);
+                                      buffer_allocator_, &comp_mgr_);
     break;
   default:
     DLOGE("Spurious display type %d", type);
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 631b24b..93970a4 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -41,10 +41,11 @@
 // TODO(user): Have a single structure handle carries all the interface pointers and variables.
 DisplayBase::DisplayBase(DisplayType display_type, DisplayEventHandler *event_handler,
                          HWDeviceType hw_device_type, BufferSyncHandler *buffer_sync_handler,
-                         CompManager *comp_manager, HWInfoInterface *hw_info_intf)
+                         BufferAllocator *buffer_allocator, CompManager *comp_manager,
+                         HWInfoInterface *hw_info_intf)
   : display_type_(display_type), event_handler_(event_handler), hw_device_type_(hw_device_type),
-    buffer_sync_handler_(buffer_sync_handler), comp_manager_(comp_manager),
-    hw_info_intf_(hw_info_intf) {
+    buffer_sync_handler_(buffer_sync_handler), buffer_allocator_(buffer_allocator),
+    comp_manager_(comp_manager), hw_info_intf_(hw_info_intf) {
 }
 
 DisplayError DisplayBase::Init() {
@@ -1114,7 +1115,6 @@
     hw_layer.input_buffer.planes[0].stride = sdm_layer->input_buffer.planes[0].stride;
     hw_layer.input_buffer.size = sdm_layer->input_buffer.size;
     hw_layer.input_buffer.acquire_fence_fd = sdm_layer->input_buffer.acquire_fence_fd;
-    hw_layer.input_buffer.fb_id = sdm_layer->input_buffer.fb_id;
   }
 
   return;
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index 3507502..378026e 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -48,7 +48,8 @@
  public:
   DisplayBase(DisplayType display_type, DisplayEventHandler *event_handler,
               HWDeviceType hw_device_type, BufferSyncHandler *buffer_sync_handler,
-              CompManager *comp_manager, HWInfoInterface *hw_info_intf);
+              BufferAllocator *buffer_allocator, CompManager *comp_manager,
+              HWInfoInterface *hw_info_intf);
   virtual ~DisplayBase() { }
   virtual DisplayError Init();
   virtual DisplayError Deinit();
@@ -138,6 +139,7 @@
   HWInterface *hw_intf_ = NULL;
   HWPanelInfo hw_panel_info_;
   BufferSyncHandler *buffer_sync_handler_ = NULL;
+  BufferAllocator *buffer_allocator_ {};
   CompManager *comp_manager_ = NULL;
   DisplayState state_ = kStateOff;
   bool active_ = false;
diff --git a/sdm/libs/core/display_hdmi.cpp b/sdm/libs/core/display_hdmi.cpp
index 783cad9..2ee863c 100644
--- a/sdm/libs/core/display_hdmi.cpp
+++ b/sdm/libs/core/display_hdmi.cpp
@@ -37,16 +37,17 @@
 namespace sdm {
 
 DisplayHDMI::DisplayHDMI(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
-                         BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager)
-  : DisplayBase(kHDMI, event_handler, kDeviceHDMI, buffer_sync_handler, comp_manager,
-                hw_info_intf) {
+                         BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
+                         CompManager *comp_manager)
+  : DisplayBase(kHDMI, event_handler, kDeviceHDMI, buffer_sync_handler, buffer_allocator,
+                comp_manager, hw_info_intf) {
 }
 
 DisplayError DisplayHDMI::Init() {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
 
   DisplayError error = HWInterface::Create(kHDMI, hw_info_intf_, buffer_sync_handler_,
-                                           &hw_intf_);
+                                           buffer_allocator_, &hw_intf_);
   if (error != kErrorNone) {
     return error;
   }
diff --git a/sdm/libs/core/display_hdmi.h b/sdm/libs/core/display_hdmi.h
index f3e64bc..a6c1f51 100644
--- a/sdm/libs/core/display_hdmi.h
+++ b/sdm/libs/core/display_hdmi.h
@@ -39,7 +39,8 @@
 class DisplayHDMI : public DisplayBase, HWEventHandler {
  public:
   DisplayHDMI(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
-              BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager);
+              BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
+              CompManager *comp_manager);
   virtual DisplayError Init();
   virtual DisplayError Prepare(LayerStack *layer_stack);
   virtual DisplayError GetRefreshRateRange(uint32_t *min_refresh_rate, uint32_t *max_refresh_rate);
diff --git a/sdm/libs/core/display_primary.cpp b/sdm/libs/core/display_primary.cpp
index f799b20..d89e9db 100644
--- a/sdm/libs/core/display_primary.cpp
+++ b/sdm/libs/core/display_primary.cpp
@@ -39,16 +39,17 @@
 namespace sdm {
 
 DisplayPrimary::DisplayPrimary(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
-                               BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager)
-  : DisplayBase(kPrimary, event_handler, kDevicePrimary, buffer_sync_handler, comp_manager,
-                hw_info_intf) {
+                               BufferSyncHandler *buffer_sync_handler,
+                               BufferAllocator *buffer_allocator, CompManager *comp_manager)
+  : DisplayBase(kPrimary, event_handler, kDevicePrimary, buffer_sync_handler, buffer_allocator,
+                comp_manager, hw_info_intf) {
 }
 
 DisplayError DisplayPrimary::Init() {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
 
   DisplayError error = HWInterface::Create(kPrimary, hw_info_intf_, buffer_sync_handler_,
-                                           &hw_intf_);
+                                           buffer_allocator_, &hw_intf_);
   if (error != kErrorNone) {
     return error;
   }
diff --git a/sdm/libs/core/display_primary.h b/sdm/libs/core/display_primary.h
index 46feb37..5578f36 100644
--- a/sdm/libs/core/display_primary.h
+++ b/sdm/libs/core/display_primary.h
@@ -38,7 +38,8 @@
 class DisplayPrimary : public DisplayBase, HWEventHandler {
  public:
   DisplayPrimary(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
-                 BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager);
+                 BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
+                 CompManager *comp_manager);
   virtual DisplayError Init();
   virtual DisplayError Prepare(LayerStack *layer_stack);
   virtual DisplayError Commit(LayerStack *layer_stack);
diff --git a/sdm/libs/core/display_virtual.cpp b/sdm/libs/core/display_virtual.cpp
index 6baa3ed..fcdc152 100644
--- a/sdm/libs/core/display_virtual.cpp
+++ b/sdm/libs/core/display_virtual.cpp
@@ -34,16 +34,17 @@
 namespace sdm {
 
 DisplayVirtual::DisplayVirtual(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
-                               BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager)
-  : DisplayBase(kVirtual, event_handler, kDeviceVirtual, buffer_sync_handler, comp_manager,
-                hw_info_intf) {
+                               BufferSyncHandler *buffer_sync_handler,
+                               BufferAllocator *buffer_allocator, CompManager *comp_manager)
+  : DisplayBase(kVirtual, event_handler, kDeviceVirtual, buffer_sync_handler, buffer_allocator,
+                comp_manager, hw_info_intf) {
 }
 
 DisplayError DisplayVirtual::Init() {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
 
   DisplayError error = HWInterface::Create(kVirtual, hw_info_intf_, buffer_sync_handler_,
-                                           &hw_intf_);
+                                           buffer_allocator_, &hw_intf_);
   if (error != kErrorNone) {
     return error;
   }
diff --git a/sdm/libs/core/display_virtual.h b/sdm/libs/core/display_virtual.h
index 3cc2e24..aaebf46 100644
--- a/sdm/libs/core/display_virtual.h
+++ b/sdm/libs/core/display_virtual.h
@@ -36,7 +36,8 @@
 class DisplayVirtual : public DisplayBase {
  public:
   DisplayVirtual(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
-                 BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager);
+                 BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
+                 CompManager *comp_manager);
   virtual DisplayError Init();
   virtual DisplayError Prepare(LayerStack *layer_stack);
   virtual DisplayError GetNumVariableInfoConfigs(uint32_t *count);
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index 7708c83..85dee22 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -30,6 +30,7 @@
 #define __STDC_FORMAT_MACROS
 
 #include <ctype.h>
+#include <drm/drm_fourcc.h>
 #include <drm_lib_loader.h>
 #include <drm_master.h>
 #include <drm_res_mgr.h>
@@ -45,11 +46,13 @@
 #include <unistd.h>
 #include <utils/constants.h>
 #include <utils/debug.h>
+#include <utils/formats.h>
 #include <utils/sys.h>
 #include <private/color_params.h>
 
 #include <algorithm>
 #include <string>
+#include <unordered_map>
 #include <utility>
 #include <vector>
 
@@ -59,12 +62,24 @@
 
 #define __CLASS__ "HWDeviceDRM"
 
+#ifndef DRM_FORMAT_MOD_QCOM_COMPRESSED
+#define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1)
+#endif
+#ifndef DRM_FORMAT_MOD_QCOM_DX
+#define DRM_FORMAT_MOD_QCOM_DX fourcc_mod_code(QCOM, 0x2)
+#endif
+#ifndef DRM_FORMAT_MOD_QCOM_TIGHT
+#define DRM_FORMAT_MOD_QCOM_TIGHT fourcc_mod_code(QCOM, 0x4)
+#endif
+
 using std::string;
 using std::to_string;
 using std::fstream;
+using std::unordered_map;
 using drm_utils::DRMMaster;
 using drm_utils::DRMResMgr;
 using drm_utils::DRMLibLoader;
+using drm_utils::DRMBuffer;
 using sde_drm::GetDRMManager;
 using sde_drm::DestroyDRMManager;
 using sde_drm::DRMDisplayType;
@@ -79,8 +94,208 @@
 
 namespace sdm {
 
-HWDeviceDRM::HWDeviceDRM(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_intf)
-    : hw_info_intf_(hw_info_intf), buffer_sync_handler_(buffer_sync_handler) {
+static void GetDRMFormat(LayerBufferFormat format, uint32_t *drm_format,
+                         uint64_t *drm_format_modifier) {
+  switch (format) {
+    case kFormatRGBA8888:
+      *drm_format = DRM_FORMAT_ABGR8888;
+      break;
+    case kFormatRGBA8888Ubwc:
+      *drm_format = DRM_FORMAT_ABGR8888;
+      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
+      break;
+    case kFormatRGBA5551:
+      *drm_format = DRM_FORMAT_ABGR1555;
+      break;
+    case kFormatRGBA4444:
+      *drm_format = DRM_FORMAT_ABGR4444;
+      break;
+    case kFormatBGRA8888:
+      *drm_format = DRM_FORMAT_ARGB8888;
+      break;
+    case kFormatRGBX8888:
+      *drm_format = DRM_FORMAT_XBGR8888;
+      break;
+    case kFormatRGBX8888Ubwc:
+      *drm_format = DRM_FORMAT_XBGR8888;
+      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
+      break;
+    case kFormatBGRX8888:
+      *drm_format = DRM_FORMAT_XRGB8888;
+      break;
+    case kFormatRGB888:
+      *drm_format = DRM_FORMAT_BGR888;
+      break;
+    case kFormatRGB565:
+      *drm_format = DRM_FORMAT_BGR565;
+      break;
+    case kFormatBGR565:
+      *drm_format = DRM_FORMAT_RGB565;
+      break;
+    case kFormatBGR565Ubwc:
+      *drm_format = DRM_FORMAT_BGR565;
+      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
+      break;
+    case kFormatRGBA1010102:
+      *drm_format = DRM_FORMAT_ABGR2101010;
+      break;
+    case kFormatRGBA1010102Ubwc:
+      *drm_format = DRM_FORMAT_ABGR2101010;
+      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
+      break;
+    case kFormatARGB2101010:
+      *drm_format = DRM_FORMAT_BGRA1010102;
+      break;
+    case kFormatRGBX1010102:
+      *drm_format = DRM_FORMAT_XBGR2101010;
+      break;
+    case kFormatRGBX1010102Ubwc:
+      *drm_format = DRM_FORMAT_XBGR2101010;
+      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
+      break;
+    case kFormatXRGB2101010:
+      *drm_format = DRM_FORMAT_BGRX1010102;
+      break;
+    case kFormatBGRA1010102:
+      *drm_format = DRM_FORMAT_ARGB2101010;
+      break;
+    case kFormatABGR2101010:
+      *drm_format = DRM_FORMAT_RGBA1010102;
+      break;
+    case kFormatBGRX1010102:
+      *drm_format = DRM_FORMAT_XRGB2101010;
+      break;
+    case kFormatXBGR2101010:
+      *drm_format = DRM_FORMAT_RGBX1010102;
+      break;
+    case kFormatYCbCr420SemiPlanar:
+      *drm_format = DRM_FORMAT_NV12;
+      break;
+    case kFormatYCbCr420SemiPlanarVenus:
+      *drm_format = DRM_FORMAT_NV12;
+      break;
+    case kFormatYCbCr420SPVenusUbwc:
+      *drm_format = DRM_FORMAT_NV12;
+      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
+      break;
+    case kFormatYCrCb420SemiPlanar:
+      *drm_format = DRM_FORMAT_NV21;
+      break;
+    case kFormatYCrCb420SemiPlanarVenus:
+      *drm_format = DRM_FORMAT_NV21;
+      break;
+    case kFormatYCbCr420P010:
+      *drm_format = DRM_FORMAT_NV12;
+      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_DX;
+      break;
+    case kFormatYCbCr420P010Ubwc:
+      *drm_format = DRM_FORMAT_NV12;
+      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED |
+        DRM_FORMAT_MOD_QCOM_DX;
+      break;
+    case kFormatYCbCr420TP10Ubwc:
+      *drm_format = DRM_FORMAT_NV12;
+      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED |
+        DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_TIGHT;
+      break;
+    case kFormatYCbCr422H2V1SemiPlanar:
+      *drm_format = DRM_FORMAT_NV16;
+      break;
+    case kFormatYCrCb422H2V1SemiPlanar:
+      *drm_format = DRM_FORMAT_NV61;
+      break;
+    case kFormatYCrCb420PlanarStride16:
+      *drm_format = DRM_FORMAT_YVU420;
+      break;
+    default:
+      DLOGW("Unsupported format %s", GetFormatString(format));
+  }
+}
+
+void HWDeviceDRM::Registry::RegisterCurrent(HWLayers *hw_layers) {
+  DRMMaster *master = nullptr;
+  DRMMaster::GetInstance(&master);
+
+  if (!master) {
+    DLOGE("Failed to acquire DRM Master instance");
+    return;
+  }
+
+  HWLayersInfo &hw_layer_info = hw_layers->info;
+  uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size());
+
+  for (uint32_t i = 0; i < hw_layer_count; i++) {
+    Layer &layer = hw_layer_info.hw_layers.at(i);
+    LayerBuffer *input_buffer = &layer.input_buffer;
+    HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
+    HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[0];
+
+    if (hw_rotate_info->valid) {
+      input_buffer = &hw_rotator_session->output_buffer;
+    }
+
+    int fd = input_buffer->planes[0].fd;
+    if (fd >= 0 && hashmap_[current_index_].find(fd) == hashmap_[current_index_].end()) {
+      AllocatedBufferInfo buf_info {};
+      DRMBuffer layout {};
+      buf_info.fd = layout.fd = fd;
+      buf_info.aligned_width = layout.width = input_buffer->width;
+      buf_info.aligned_height = layout.height = input_buffer->height;
+      buf_info.format = input_buffer->format;
+      GetDRMFormat(buf_info.format, &layout.drm_format, &layout.drm_format_modifier);
+      buffer_allocator_->GetBufferLayout(buf_info, layout.stride, layout.offset,
+                                         &layout.num_planes);
+      uint32_t fb_id = 0;
+      int ret = master->CreateFbId(layout, &fb_id);
+      if (ret < 0) {
+        DLOGE("CreateFbId failed. width %d, height %d, format: %s, stride %u, error %d",
+              layout.width, layout.height, GetFormatString(buf_info.format), layout.stride[0],
+              errno);
+      } else {
+        hashmap_[current_index_][fd] = fb_id;
+      }
+    }
+  }
+}
+
+void HWDeviceDRM::Registry::UnregisterNext() {
+  DRMMaster *master = nullptr;
+  DRMMaster::GetInstance(&master);
+
+  if (!master) {
+    DLOGE("Failed to acquire DRM Master instance");
+    return;
+  }
+
+  current_index_ = (current_index_ + 1) % kCycleDelay;
+  auto &curr_map = hashmap_[current_index_];
+  for (auto &pair : curr_map) {
+    uint32_t fb_id = pair.second;
+    int ret = master->RemoveFbId(fb_id);
+    if (ret < 0) {
+      DLOGE("Removing fb_id %d failed with error %d", fb_id, errno);
+    }
+  }
+
+  curr_map.clear();
+}
+
+void HWDeviceDRM::Registry::Clear() {
+  for (int i = 0; i < kCycleDelay; i++) {
+    UnregisterNext();
+  }
+  current_index_ = 0;
+}
+
+uint32_t HWDeviceDRM::Registry::GetFbId(int fd) {
+  auto it = hashmap_[current_index_].find(fd);
+  return (it == hashmap_[current_index_].end()) ? 0 : it->second;
+}
+
+HWDeviceDRM::HWDeviceDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
+                         HWInfoInterface *hw_info_intf)
+    : hw_info_intf_(hw_info_intf), buffer_sync_handler_(buffer_sync_handler),
+      registry_(buffer_allocator) {
   device_type_ = kDevicePrimary;
   device_name_ = "Peripheral Display";
   hw_info_intf_ = hw_info_intf;
@@ -126,10 +341,17 @@
   UpdateMixerAttributes();
   hw_info_intf_->GetHWResourceInfo(&hw_resource_);
 
+  // TODO(user): In future, remove has_qseed3 member, add version and pass version to constructor
+  if (hw_resource_.has_qseed3) {
+    hw_scale_ = new HWScaleDRM(HWScaleDRM::Version::V2);
+  }
+
   return kErrorNone;
 }
 
 DisplayError HWDeviceDRM::Deinit() {
+  delete hw_scale_;
+  registry_.Clear();
   drm_mgr_intf_->DestroyAtomicReq(drm_atomic_intf_);
   drm_atomic_intf_ = {};
   drm_mgr_intf_->UnregisterDisplay(token_);
@@ -384,7 +606,8 @@
         needs_rotation = true;
       }
 
-      if (pipe_info->valid && input_buffer->fb_id) {
+      uint32_t fb_id = registry_.GetFbId(input_buffer->planes[0].fd);
+      if (pipe_info->valid && fb_id) {
         uint32_t pipe_id = pipe_info->pipe_id;
         drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ALPHA, pipe_id, layer.plane_alpha);
         drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ZORDER, pipe_id, pipe_info->z_order);
@@ -417,12 +640,21 @@
         uint32_t config = 0;
         SetSrcConfig(layer.input_buffer, &config);
         drm_atomic_intf_->Perform(DRMOps::PLANE_SET_SRC_CONFIG, pipe_id, config);;
-        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_FB_ID, pipe_id, input_buffer->fb_id);
+        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_FB_ID, pipe_id, fb_id);
         drm_atomic_intf_->Perform(DRMOps::PLANE_SET_CRTC, pipe_id, token_.crtc_id);
         if (!validate && input_buffer->acquire_fence_fd >= 0) {
           drm_atomic_intf_->Perform(DRMOps::PLANE_SET_INPUT_FENCE, pipe_id,
                                     input_buffer->acquire_fence_fd);
         }
+        if (hw_scale_) {
+          SDEScaler scaler_output = {};
+          hw_scale_->SetPlaneScaler(pipe_info->scale_data, &scaler_output);
+          // TODO(user): Remove qseed3 and add version check, then send appropriate scaler object
+          if (hw_resource_.has_qseed3) {
+            drm_atomic_intf_->Perform(DRMOps::PLANE_SET_SCALER_CONFIG, pipe_id,
+                                      reinterpret_cast<uint64_t>(&scaler_output.scaler_v2));
+          }
+        }
       }
     }
 
@@ -433,6 +665,8 @@
 
 DisplayError HWDeviceDRM::Validate(HWLayers *hw_layers) {
   DTRACE_SCOPED();
+
+  registry_.RegisterCurrent(hw_layers);
   SetupAtomic(hw_layers, true /* validate */);
 
   int ret = drm_atomic_intf_->Validate();
@@ -446,11 +680,19 @@
 
 DisplayError HWDeviceDRM::Commit(HWLayers *hw_layers) {
   DTRACE_SCOPED();
+
+  DisplayError err = kErrorNone;
+  registry_.RegisterCurrent(hw_layers);
+
   if (default_mode_) {
-    return DefaultCommit(hw_layers);
+    err = DefaultCommit(hw_layers);
+  } else {
+    err = AtomicCommit(hw_layers);
   }
 
-  return AtomicCommit(hw_layers);
+  registry_.UnregisterNext();
+
+  return err;
 }
 
 DisplayError HWDeviceDRM::DefaultCommit(HWLayers *hw_layers) {
@@ -490,12 +732,12 @@
   drmModeModeInfo mode;
   res_mgr->GetMode(&mode);
 
-  LayerBuffer &input_buffer = hw_layer_info.hw_layers.at(0).input_buffer;
-  ret = drmModeSetCrtc(dev_fd, crtc_id, input_buffer.fb_id, 0 /* x */, 0 /* y */, &connector_id,
+  uint32_t fb_id = registry_.GetFbId(hw_layer_info.hw_layers.at(0).input_buffer.planes[0].fd);
+  ret = drmModeSetCrtc(dev_fd, crtc_id, fb_id, 0 /* x */, 0 /* y */, &connector_id,
                        1 /* num_connectors */, &mode);
   if (ret < 0) {
     DLOGE("drmModeSetCrtc failed dev fd %d, fb_id %d, crtc id %d, connector id %d, %s", dev_fd,
-          input_buffer.fb_id, crtc_id, connector_id, strerror(errno));
+          fb_id, crtc_id, connector_id, strerror(errno));
     return kErrorHardware;
   }
 
@@ -719,6 +961,15 @@
 }
 
 DisplayError HWDeviceDRM::SetScaleLutConfig(HWScaleLutInfo *lut_info) {
+  sde_drm::DRMScalerLUTInfo drm_lut_info = {};
+  drm_lut_info.cir_lut = lut_info->cir_lut;
+  drm_lut_info.dir_lut = lut_info->dir_lut;
+  drm_lut_info.sep_lut = lut_info->sep_lut;
+  drm_lut_info.cir_lut_size = lut_info->cir_lut_size;
+  drm_lut_info.dir_lut_size = lut_info->dir_lut_size;
+  drm_lut_info.sep_lut_size = lut_info->sep_lut_size;
+  drm_mgr_intf_->SetScalerLUT(drm_lut_info);
+
   return kErrorNone;
 }
 
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index 034826c..cc2ae7b 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -35,9 +35,11 @@
 #include <pthread.h>
 #include <xf86drmMode.h>
 #include <string>
+#include <unordered_map>
 #include <vector>
 
 #include "hw_interface.h"
+#include "hw_scale_drm.h"
 
 #define IOCTL_LOGE(ioctl, type) \
   DLOGE("ioctl %s, device = %d errno = %d, desc = %s", #ioctl, type, errno, strerror(errno))
@@ -47,7 +49,8 @@
 
 class HWDeviceDRM : public HWInterface {
  public:
-  explicit HWDeviceDRM(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_intf);
+  explicit HWDeviceDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
+                       HWInfoInterface *hw_info_intf);
   virtual ~HWDeviceDRM() {}
   virtual DisplayError Init();
   virtual DisplayError Deinit();
@@ -98,6 +101,8 @@
   static const int kMaxStringLength = 1024;
   static const int kNumPhysicalDisplays = 2;
   static const int kMaxSysfsCommandLength = 12;
+  static constexpr const char *kBrightnessNode =
+    "/sys/class/backlight/panel0-backlight/brightness";
 
   DisplayError SetFormat(const LayerBufferFormat &source, uint32_t *target);
   DisplayError SetStride(HWDeviceType device_type, LayerBufferFormat format, uint32_t width,
@@ -117,6 +122,27 @@
   DisplayError AtomicCommit(HWLayers *hw_layers);
   void SetupAtomic(HWLayers *hw_layers, bool validate);
 
+  class Registry {
+   public:
+    explicit Registry(BufferAllocator *buffer_allocator) : buffer_allocator_(buffer_allocator) {}
+    // Call on each validate and commit to register layer buffers
+    void RegisterCurrent(HWLayers *hw_layers);
+    // Call at the end of draw cycle to clear the next slot for business
+    void UnregisterNext();
+    // Call on display disconnect to release all gem handles and fb_ids
+    void Clear();
+    // Finds an fb_id corresponding to an fd in current map
+    uint32_t GetFbId(int fd);
+
+   private:
+    static const int kCycleDelay = 1;  // N cycle delay before destroy
+    // fd to fb_id map. fd is used as key only for a single draw cycle between
+    // prepare and commit. It should not be used for caching in future due to fd recycling
+    std::unordered_map<int, uint32_t> hashmap_[kCycleDelay] {};
+    int current_index_ = 0;
+    BufferAllocator *buffer_allocator_ = {};
+  };
+
   HWResourceInfo hw_resource_ = {};
   HWPanelInfo hw_panel_info_ = {};
   HWInfoInterface *hw_info_intf_ = {};
@@ -133,7 +159,8 @@
   bool default_mode_ = false;
   sde_drm::DRMConnectorInfo connector_info_ = {};
   std::string interface_str_ = "DSI";
-  const char *kBrightnessNode = "/sys/class/backlight/panel0-backlight/brightness";
+  HWScaleDRM *hw_scale_ = {};
+  Registry registry_;
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/core/drm/hw_info_drm.cpp b/sdm/libs/core/drm/hw_info_drm.cpp
index 48464e9..f7ce652 100644
--- a/sdm/libs/core/drm/hw_info_drm.cpp
+++ b/sdm/libs/core/drm/hw_info_drm.cpp
@@ -54,7 +54,6 @@
 
 #include "hw_info_drm.h"
 
-#ifdef COMPILE_DRM
 #ifndef DRM_FORMAT_MOD_QCOM_COMPRESSED
 #define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1)
 #endif
@@ -64,7 +63,6 @@
 #ifndef DRM_FORMAT_MOD_QCOM_TIGHT
 #define DRM_FORMAT_MOD_QCOM_TIGHT fourcc_mod_code(QCOM, 0x4)
 #endif
-#endif
 
 #define __CLASS__ "HWInfoDRM"
 
diff --git a/sdm/libs/core/drm/hw_scale_drm.cpp b/sdm/libs/core/drm/hw_scale_drm.cpp
new file mode 100644
index 0000000..96f084e
--- /dev/null
+++ b/sdm/libs/core/drm/hw_scale_drm.cpp
@@ -0,0 +1,157 @@
+/*
+* Copyright (c) 2016-2017, 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 <stdio.h>
+#include <utils/debug.h>
+
+#include "hw_scale_drm.h"
+
+#define __CLASS__ "HWScaleDRM"
+
+namespace sdm {
+
+static uint32_t GetScalingFilter(ScalingFilterConfig filter_cfg) {
+  switch (filter_cfg) {
+    case kFilterEdgeDirected:
+      return FILTER_EDGE_DIRECTED_2D;
+    case kFilterCircular:
+      return FILTER_CIRCULAR_2D;
+    case kFilterSeparable:
+      return FILTER_SEPARABLE_1D;
+    case kFilterBilinear:
+      return FILTER_BILINEAR;
+    default:
+      DLOGE("Invalid Scaling Filter");
+      return kFilterMax;
+  }
+}
+
+static uint32_t GetAlphaInterpolation(HWAlphaInterpolation alpha_filter_cfg) {
+  switch (alpha_filter_cfg) {
+    case kInterpolationPixelRepeat:
+      return FILTER_ALPHA_DROP_REPEAT;
+    case kInterpolationBilinear:
+      return FILTER_ALPHA_BILINEAR;
+    default:
+      DLOGE("Invalid Alpha Interpolation");
+      return kInterpolationMax;
+  }
+}
+
+void HWScaleDRM::SetPlaneScaler(const HWScaleData &scale_data, SDEScaler *scaler) {
+  if (version_ == Version::V2) {
+    SetPlaneScalerV2(scale_data, &scaler->scaler_v2);
+  }
+}
+
+void HWScaleDRM::SetPlaneScalerV2(const HWScaleData &scale_data, sde_drm_scaler_v2 *scaler) {
+  if (!scale_data.enable.scale && !scale_data.enable.direction_detection &&
+      !scale_data.enable.detail_enhance) {
+    return;
+  }
+
+  scaler->enable = scale_data.enable.scale;
+  scaler->dir_en = scale_data.enable.direction_detection;
+  scaler->de.enable = scale_data.detail_enhance.enable;
+
+  for (int i = 0; i < SDE_MAX_PLANES; i++) {
+    const HWPlane &plane = scale_data.plane[i];
+    scaler->init_phase_x[i] = plane.init_phase_x;
+    scaler->phase_step_x[i] = plane.phase_step_x;
+    scaler->init_phase_y[i] = plane.init_phase_y;
+    scaler->phase_step_y[i] = plane.phase_step_y;
+
+    // TODO(user): Remove right, bottom from HWPlane and rename to LR, TB similar to qseed3
+    // Also remove roi_width which is unused.
+    scaler->pe.num_ext_pxls_lr[i] = plane.left.extension;
+    scaler->pe.num_ext_pxls_tb[i] = plane.top.extension;
+
+    scaler->pe.left_ftch[i] = plane.left.overfetch;
+    scaler->pe.top_ftch[i] = plane.top.overfetch;
+    scaler->pe.right_ftch[i] = plane.right.overfetch;
+    scaler->pe.btm_ftch[i] = plane.bottom.overfetch;
+
+    scaler->pe.left_rpt[i] = plane.left.repeat;
+    scaler->pe.top_rpt[i] = plane.top.repeat;
+    scaler->pe.right_rpt[i] = plane.right.repeat;
+    scaler->pe.btm_rpt[i] = plane.bottom.repeat;
+
+    scaler->preload_x[i] = UINT32(plane.preload_x);
+    scaler->preload_y[i] = UINT32(plane.preload_y);
+
+    scaler->src_width[i] = plane.src_width;
+    scaler->src_height[i] = plane.src_height;
+  }
+
+  scaler->dst_width = scale_data.dst_width;
+  scaler->dst_height = scale_data.dst_height;
+
+  scaler->y_rgb_filter_cfg = GetScalingFilter(scale_data.y_rgb_filter_cfg);
+  scaler->uv_filter_cfg = GetScalingFilter(scale_data.uv_filter_cfg);
+  scaler->alpha_filter_cfg = GetAlphaInterpolation(scale_data.alpha_filter_cfg);
+  scaler->blend_cfg = scale_data.blend_cfg;
+
+  scaler->lut_flag = (scale_data.lut_flag.lut_swap ? SCALER_LUT_SWAP : 0) |
+                     (scale_data.lut_flag.lut_dir_wr ? SCALER_LUT_DIR_WR : 0) |
+                     (scale_data.lut_flag.lut_y_cir_wr ? SCALER_LUT_Y_CIR_WR : 0) |
+                     (scale_data.lut_flag.lut_uv_cir_wr ? SCALER_LUT_UV_CIR_WR : 0) |
+                     (scale_data.lut_flag.lut_y_sep_wr ? SCALER_LUT_Y_SEP_WR : 0) |
+                     (scale_data.lut_flag.lut_uv_sep_wr ? SCALER_LUT_UV_SEP_WR : 0);
+
+  scaler->dir_lut_idx = scale_data.dir_lut_idx;
+  scaler->y_rgb_cir_lut_idx = scale_data.y_rgb_cir_lut_idx;
+  scaler->uv_cir_lut_idx = scale_data.uv_cir_lut_idx;
+  scaler->y_rgb_sep_lut_idx = scale_data.y_rgb_sep_lut_idx;
+  scaler->uv_sep_lut_idx = scale_data.uv_sep_lut_idx;
+
+  /* TODO(user): Uncomment when de support is added
+  if (scaler->de.enable) {
+    sde_drm_de_v1 *det_enhance = &scaler->de;
+    det_enhance->sharpen_level1 = scale_data.detail_enhance.sharpen_level1;
+    det_enhance->sharpen_level2 = scale_data.detail_enhance.sharpen_level2;
+    det_enhance->clip = scale_data.detail_enhance.clip;
+    det_enhance->limit = scale_data.detail_enhance.limit;
+    det_enhance->thr_quiet = scale_data.detail_enhance.thr_quiet;
+    det_enhance->thr_dieout = scale_data.detail_enhance.thr_dieout;
+    det_enhance->thr_low = scale_data.detail_enhance.thr_low;
+    det_enhance->thr_high = scale_data.detail_enhance.thr_high;
+    det_enhance->prec_shift = scale_data.detail_enhance.prec_shift;
+
+    for (int i = 0; i < SDE_MAX_DE_CURVES; i++) {
+      det_enhance->adjust_a[i] = scale_data.detail_enhance.adjust_a[i];
+      det_enhance->adjust_b[i] = scale_data.detail_enhance.adjust_b[i];
+      det_enhance->adjust_c[i] = scale_data.detail_enhance.adjust_c[i];
+    }
+  }
+  */
+
+  return;
+}
+
+}  // namespace sdm
diff --git a/sdm/libs/core/drm/hw_scale_drm.h b/sdm/libs/core/drm/hw_scale_drm.h
new file mode 100644
index 0000000..8a4be70
--- /dev/null
+++ b/sdm/libs/core/drm/hw_scale_drm.h
@@ -0,0 +1,63 @@
+/*
+* Copyright (c) 2016-2017, 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 __HW_SCALE_DRM_H__
+#define __HW_SCALE_DRM_H__
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <drm.h>
+// The 3 headers above are a workaround to prevent kernel drm.h from being used that has the
+// "virtual" keyword used for a variable. In future replace libdrm version drm.h with kernel
+// version drm/drm.h
+#include <drm/sde_drm.h>
+#include <private/hw_info_types.h>
+
+namespace sdm {
+
+struct SDEScaler {
+  struct sde_drm_scaler_v2 scaler_v2 = {};
+  // More here, maybe in a union
+};
+
+class HWScaleDRM {
+ public:
+  enum class Version { V2 };
+  explicit HWScaleDRM(Version v) : version_(v) {}
+  void SetPlaneScaler(const HWScaleData &scale, SDEScaler *scaler);
+
+ private:
+  void SetPlaneScalerV2(const HWScaleData &scale, sde_drm_scaler_v2 *scaler_v2);
+
+  Version version_ = Version::V2;
+};
+
+}  // namespace sdm
+
+#endif  // __HW_SCALE_DRM_H__
diff --git a/sdm/libs/core/hw_interface.cpp b/sdm/libs/core/hw_interface.cpp
index b328831..b5c9fe9 100644
--- a/sdm/libs/core/hw_interface.cpp
+++ b/sdm/libs/core/hw_interface.cpp
@@ -45,7 +45,7 @@
 
 DisplayError HWInterface::Create(DisplayType type, HWInfoInterface *hw_info_intf,
                                  BufferSyncHandler *buffer_sync_handler,
-                                 HWInterface **intf) {
+                                 BufferAllocator *buffer_allocator, HWInterface **intf) {
   DisplayError error = kErrorNone;
   HWInterface *hw = nullptr;
   DriverType driver_type = GetDriverType();
@@ -56,7 +56,7 @@
         hw = new HWPrimary(buffer_sync_handler, hw_info_intf);
       } else {
 #ifdef COMPILE_DRM
-        hw = new HWDeviceDRM(buffer_sync_handler, hw_info_intf);
+        hw = new HWDeviceDRM(buffer_sync_handler, buffer_allocator, hw_info_intf);
 #endif
       }
       break;
diff --git a/sdm/libs/core/hw_interface.h b/sdm/libs/core/hw_interface.h
index 23c6114..5dbeb11 100644
--- a/sdm/libs/core/hw_interface.h
+++ b/sdm/libs/core/hw_interface.h
@@ -25,11 +25,12 @@
 #ifndef __HW_INTERFACE_H__
 #define __HW_INTERFACE_H__
 
+#include <core/buffer_allocator.h>
+#include <core/buffer_sync_handler.h>
 #include <core/display_interface.h>
 #include <private/hw_info_types.h>
 #include <private/color_interface.h>
 #include <utils/constants.h>
-#include <core/buffer_sync_handler.h>
 
 #include "hw_info_interface.h"
 
@@ -68,7 +69,8 @@
 class HWInterface {
  public:
   static DisplayError Create(DisplayType type, HWInfoInterface *hw_info_intf,
-                             BufferSyncHandler *buffer_sync_handler, HWInterface **intf);
+                             BufferSyncHandler *buffer_sync_handler,
+                             BufferAllocator *buffer_allocator, HWInterface **intf);
   static DisplayError Destroy(HWInterface *intf);
 
   virtual DisplayError Init() = 0;
diff --git a/sdm/libs/hwc/hwc_buffer_allocator.cpp b/sdm/libs/hwc/hwc_buffer_allocator.cpp
index 80d72f7..25f366f 100644
--- a/sdm/libs/hwc/hwc_buffer_allocator.cpp
+++ b/sdm/libs/hwc/hwc_buffer_allocator.cpp
@@ -34,17 +34,12 @@
 #include <utils/constants.h>
 #include <utils/debug.h>
 #include <core/buffer_allocator.h>
-#include <drm_master.h>
-#include <qd_utils.h>
 
 #include "hwc_debugger.h"
 #include "hwc_buffer_allocator.h"
 
 #define __CLASS__ "HWCBufferAllocator"
 
-using drm_utils::DRMMaster;
-using drm_utils::DRMBuffer;
-
 namespace sdm {
 
 HWCBufferAllocator::HWCBufferAllocator() {
@@ -123,49 +118,6 @@
 
   buffer_info->private_data = meta_buffer_info;
 
-  if (qdutils::getDriverType() == qdutils::DriverType::DRM) {
-    private_handle_t handle(-1, 0, 0, 0, 0, 0, 0);
-    // Setup only the required stuff, skip rest
-    handle.base = reinterpret_cast<uint64_t>(data.base);
-    handle.format = format;
-    handle.width = aligned_width;
-    handle.height = aligned_height;
-    if (alloc_flags & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) {
-      handle.flags = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
-    }
-    private_handle_t *hnd = &handle;
-    DRMBuffer buf = {};
-    int ret = getPlaneStrideOffset(hnd, buf.stride, buf.offset,
-                                   &buf.num_planes);
-    if (ret < 0) {
-      DLOGE("getPlaneStrideOffset failed");
-      return kErrorParameters;
-    }
-
-    buf.fd = data.fd;
-    buf.width = UINT32(hnd->width);
-    buf.height = UINT32(hnd->height);
-    getDRMFormat(hnd->format, hnd->flags, &buf.drm_format,
-                 &buf.drm_format_modifier);
-
-    DRMMaster *master = nullptr;
-    ret = DRMMaster::GetInstance(&master);
-    if (ret < 0) {
-      DLOGE("Failed to acquire DRMMaster instance");
-      return kErrorParameters;
-    }
-
-    ret = master->CreateFbId(buf, &alloc_buffer_info->gem_handle, &alloc_buffer_info->fb_id);
-    if (ret < 0) {
-      DLOGE("CreateFbId failed. width %d, height %d, " \
-            "format: %s, stride %u, error %d",
-            buf.width, buf.height,
-            qdutils::GetHALPixelFormatString(hnd->format),
-            buf.stride[0], errno);
-      return kErrorParameters;
-    }
-  }
-
   return kErrorNone;
 }
 
@@ -201,25 +153,6 @@
 
     delete meta_buffer_info;
     meta_buffer_info = NULL;
-
-    if (alloc_buffer_info->fb_id) {
-      DRMMaster *master = nullptr;
-      int ret = DRMMaster::GetInstance(&master);
-      if (ret < 0) {
-        DLOGE("Failed to acquire DRMMaster instance");
-        return kErrorParameters;
-      }
-
-      ret = master->RemoveFbId(alloc_buffer_info->gem_handle, alloc_buffer_info->fb_id);
-      if (ret < 0) {
-        DLOGE("Removing fb_id %d failed with error %d",
-              alloc_buffer_info->fb_id, errno);
-        return kErrorParameters;
-      }
-
-      alloc_buffer_info->fb_id = 0;
-      alloc_buffer_info->gem_handle = 0;
-    }
   }
 
   return kErrorNone;
@@ -364,6 +297,32 @@
   allocated_buffer_info->aligned_width = UINT32(width_aligned);
   allocated_buffer_info->aligned_height = UINT32(height_aligned);
   allocated_buffer_info->size = UINT32(buffer_size);
+  allocated_buffer_info->format = buffer_config.format;
+
+  return kErrorNone;
+}
+
+DisplayError HWCBufferAllocator::GetBufferLayout(const AllocatedBufferInfo &buf_info,
+                                                 uint32_t stride[4], uint32_t offset[4],
+                                                 uint32_t *num_planes) {
+  private_handle_t hnd(-1, 0, 0, 0, 0, 0, 0);
+  int format = HAL_PIXEL_FORMAT_RGBA_8888;
+  int flags = 0;
+
+  SetBufferInfo(buf_info.format, &format, &flags);
+  // Setup only the required stuff, skip rest
+  hnd.format = format;
+  hnd.width = buf_info.aligned_width;
+  hnd.height = buf_info.aligned_height;
+  if (flags & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) {
+    hnd.flags = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+  }
+
+  int ret = getBufferLayout(&hnd, stride, offset, num_planes);
+  if (ret < 0) {
+    DLOGE("getBufferLayout failed");
+    return kErrorParameters;
+  }
 
   return kErrorNone;
 }
diff --git a/sdm/libs/hwc/hwc_buffer_allocator.h b/sdm/libs/hwc/hwc_buffer_allocator.h
index af8e9a3..a8cf462 100644
--- a/sdm/libs/hwc/hwc_buffer_allocator.h
+++ b/sdm/libs/hwc/hwc_buffer_allocator.h
@@ -51,7 +51,9 @@
   uint32_t GetBufferSize(BufferInfo *buffer_info);
   DisplayError GetAllocatedBufferInfo(const BufferConfig &buffer_config,
                                       AllocatedBufferInfo *allocated_buffer_info);
-
+  DisplayError GetBufferLayout(const AllocatedBufferInfo &buf_info,
+                               uint32_t stride[4], uint32_t offset[4],
+                               uint32_t *num_planes);
   int SetBufferInfo(LayerBufferFormat format, int *target, int *flags);
 
  private:
diff --git a/sdm/libs/hwc/hwc_display.cpp b/sdm/libs/hwc/hwc_display.cpp
index bb062cd..770ced6 100644
--- a/sdm/libs/hwc/hwc_display.cpp
+++ b/sdm/libs/hwc/hwc_display.cpp
@@ -436,6 +436,7 @@
   LayerBuffer &layer_buffer = layer->input_buffer;
 
   if (pvt_handle) {
+    layer_buffer.planes[0].fd = pvt_handle->fd;
     layer_buffer.format = GetSDMFormat(pvt_handle->format, pvt_handle->flags);
     int aligned_width, aligned_height;
     int unaligned_width, unaligned_height;
@@ -449,7 +450,6 @@
     layer_buffer.height = UINT32(aligned_height);
     layer_buffer.unaligned_width = UINT32(unaligned_width);
     layer_buffer.unaligned_height = UINT32(unaligned_height);
-    layer_buffer.fb_id = pvt_handle->fb_id;
 
     if (SetMetaData(pvt_handle, layer) != kErrorNone) {
       return -EINVAL;
@@ -521,7 +521,6 @@
     layer_buffer.planes[0].offset = pvt_handle->offset;
     layer_buffer.planes[0].stride = UINT32(pvt_handle->width);
     layer_buffer.size = pvt_handle->size;
-    layer_buffer.fb_id = pvt_handle->fb_id;
   }
 
   // if swapinterval property is set to 0 then close and reset the acquireFd
diff --git a/sdm/libs/hwc/hwc_session.cpp b/sdm/libs/hwc/hwc_session.cpp
index e6aa70f..8a5bd81 100644
--- a/sdm/libs/hwc/hwc_session.cpp
+++ b/sdm/libs/hwc/hwc_session.cpp
@@ -140,12 +140,18 @@
     return -EINVAL;
   }
 
+  SCOPE_LOCK(uevent_locker_);
+
   if (pthread_create(&uevent_thread_, NULL, &HWCUeventThread, this) < 0) {
     DLOGE("Failed to start = %s, error = %s", uevent_thread_name_, strerror(errno));
     CoreInterface::DestroyCore();
     return -errno;
   }
 
+  // Wait for uevent_init() to happen and let the uevent thread wait for uevents, so that hdmi
+  // connect/disconnect events won't be missed
+  uevent_locker_.Wait();
+
   // Read which display is first, and create it and store it in primary slot
   HWDisplayInterfaceInfo hw_disp_info;
   error = core_intf_->GetFirstDisplayInterfaceType(&hw_disp_info);
@@ -465,6 +471,8 @@
 }
 
 int HWCSession::EventControl(hwc_composer_device_1 *device, int disp, int event, int enable) {
+  SCOPE_LOCK(locker_);
+
   if (!device) {
     return -EINVAL;
   }
@@ -1418,14 +1426,21 @@
 void* HWCSession::HWCUeventThreadHandler() {
   static char uevent_data[PAGE_SIZE];
   int length = 0;
+
+  uevent_locker_.Lock();
   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);
+    uevent_locker_.Signal();
+    uevent_locker_.Unlock();
     return NULL;
   }
 
+  uevent_locker_.Signal();
+  uevent_locker_.Unlock();
+
   while (!uevent_thread_exit_) {
     // keep last 2 zeroes to ensure double 0 termination
     length = uevent_next_event(uevent_data, INT32(sizeof(uevent_data)) - 2);
diff --git a/sdm/libs/hwc/hwc_session.h b/sdm/libs/hwc/hwc_session.h
index c3ffa98..1cd3e33 100644
--- a/sdm/libs/hwc/hwc_session.h
+++ b/sdm/libs/hwc/hwc_session.h
@@ -153,6 +153,7 @@
   bool is_hdmi_yuv_ = false;
   std::bitset<HWC_NUM_DISPLAY_TYPES> connected_displays_;  // Bit mask of connected displays
   HWCSocketHandler socket_handler_;
+  Locker uevent_locker_;
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/hwc2/Android.mk b/sdm/libs/hwc2/Android.mk
index ca1ebae..0bc5acf 100644
--- a/sdm/libs/hwc2/Android.mk
+++ b/sdm/libs/hwc2/Android.mk
@@ -24,7 +24,7 @@
 
 LOCAL_SHARED_LIBRARIES        := libsdmcore libqservice libbinder libhardware libhardware_legacy \
                                  libutils libcutils libsync libqdutils libqdMetaData libdl \
-                                 libpowermanager libsdmutils libc++ liblog libdrmutils
+                                 libpowermanager libsdmutils libc++ liblog libgrallocutils
 
 ifneq ($(TARGET_USES_GRALLOC1), true)
     LOCAL_SHARED_LIBRARIES += libmemalloc
diff --git a/sdm/libs/hwc2/hwc_buffer_allocator.cpp b/sdm/libs/hwc2/hwc_buffer_allocator.cpp
index 3cfaf0a..b7fcac3 100644
--- a/sdm/libs/hwc2/hwc_buffer_allocator.cpp
+++ b/sdm/libs/hwc2/hwc_buffer_allocator.cpp
@@ -35,8 +35,10 @@
 
 #include "hwc_buffer_allocator.h"
 #include "hwc_debugger.h"
+#include "gr_utils.h"
 
 #define __CLASS__ "HWCBufferAllocator"
+
 namespace sdm {
 
 HWCBufferAllocator::HWCBufferAllocator() {
@@ -64,7 +66,7 @@
   uint32_t width = buffer_config.width;
   uint32_t height = buffer_config.height;
   int format;
-  int alloc_flags = 0;
+  uint64_t alloc_flags = 0;
   int error = SetBufferInfo(buffer_config.format, &format, &alloc_flags);
   if (error != 0) {
     return kErrorParameters;
@@ -78,8 +80,8 @@
     // Allocate uncached buffers
     alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
   }
-  uint64_t producer_usage = UINT64(alloc_flags);
-  uint64_t consumer_usage = UINT64(alloc_flags);
+  uint64_t producer_usage = alloc_flags;
+  uint64_t consumer_usage = alloc_flags;
   // CreateBuffer
   private_handle_t *hnd = nullptr;
   Perform_(gralloc_device_, GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER, width, height, format,
@@ -103,6 +105,7 @@
   buffer_handle_t hnd = static_cast<private_handle_t *>(buffer_info->private_data);
   ReleaseBuffer_(gralloc_device_, hnd);
   AllocatedBufferInfo *alloc_buffer_info = &buffer_info->alloc_buffer_info;
+
   alloc_buffer_info->fd = -1;
   alloc_buffer_info->stride = 0;
   alloc_buffer_info->size = 0;
@@ -136,7 +139,7 @@
 
 uint32_t HWCBufferAllocator::GetBufferSize(BufferInfo *buffer_info) {
   const BufferConfig &buffer_config = buffer_info->buffer_config;
-  int alloc_flags = INT(GRALLOC_USAGE_PRIVATE_IOMMU_HEAP);
+  uint64_t alloc_flags = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
 
   int width = INT(buffer_config.width);
   int height = INT(buffer_config.height);
@@ -156,17 +159,17 @@
   }
 
   uint32_t aligned_width = 0, aligned_height = 0, buffer_size = 0;
-  uint64_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE;
-  uint64_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE;
+  gralloc1_producer_usage_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE;
+  gralloc1_consumer_usage_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE;
   // TODO(user): Currently both flags are treated similarly in gralloc
-  producer_usage = UINT64(alloc_flags);
-  consumer_usage = producer_usage;
-  Perform_(gralloc_device_, GRALLOC1_MODULE_PERFORM_GET_BUFFER_SIZE_AND_DIMENSIONS, width, height,
-           format, producer_usage, consumer_usage, &aligned_width, &aligned_height, &buffer_size);
+  producer_usage = gralloc1_producer_usage_t(alloc_flags);
+  consumer_usage = gralloc1_consumer_usage_t(alloc_flags);
+  gralloc1::BufferInfo info(width, height, format, producer_usage, consumer_usage);
+  GetBufferSizeAndDimensions(info, &aligned_width, &aligned_height, &buffer_size);
   return buffer_size;
 }
 
-int HWCBufferAllocator::SetBufferInfo(LayerBufferFormat format, int *target, int *flags) {
+int HWCBufferAllocator::SetBufferInfo(LayerBufferFormat format, int *target, uint64_t *flags) {
   switch (format) {
     case kFormatRGBA8888:
       *target = HAL_PIXEL_FORMAT_RGBA_8888;
@@ -209,6 +212,7 @@
       break;
     case kFormatYCbCr420SPVenusUbwc:
       *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
+      *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
       break;
     case kFormatRGBA5551:
       *target = HAL_PIXEL_FORMAT_RGBA_5551;
@@ -245,9 +249,11 @@
       break;
     case kFormatYCbCr420TP10Ubwc:
       *target = HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC;
+      *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
       break;
     case kFormatYCbCr420P010Ubwc:
       *target = HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC;
+      *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
       break;
     case kFormatRGBA8888Ubwc:
       *target = HAL_PIXEL_FORMAT_RGBA_8888;
@@ -280,7 +286,7 @@
     const BufferConfig &buffer_config, AllocatedBufferInfo *allocated_buffer_info) {
   // TODO(user): This API should pass the buffer_info of the already allocated buffer
   // The private_data can then be typecast to the private_handle and used directly.
-  int alloc_flags = INT(GRALLOC_USAGE_PRIVATE_IOMMU_HEAP);
+  uint64_t alloc_flags = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
 
   int width = INT(buffer_config.width);
   int height = INT(buffer_config.height);
@@ -300,13 +306,13 @@
   }
 
   uint32_t aligned_width = 0, aligned_height = 0, buffer_size = 0;
-  uint64_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE;
-  uint64_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE;
+  gralloc1_producer_usage_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE;
+  gralloc1_consumer_usage_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE;
   // TODO(user): Currently both flags are treated similarly in gralloc
-  producer_usage = UINT64(alloc_flags);
-  consumer_usage = producer_usage;
-  Perform_(gralloc_device_, GRALLOC1_MODULE_PERFORM_GET_BUFFER_SIZE_AND_DIMENSIONS, width, height,
-           format, producer_usage, consumer_usage, &aligned_width, &aligned_height, &buffer_size);
+  producer_usage = gralloc1_producer_usage_t(alloc_flags);
+  consumer_usage = gralloc1_consumer_usage_t(alloc_flags);
+  gralloc1::BufferInfo info(width, height, format, producer_usage, consumer_usage);
+  GetBufferSizeAndDimensions(info, &aligned_width, &aligned_height, &buffer_size);
   allocated_buffer_info->stride = UINT32(aligned_width);
   allocated_buffer_info->aligned_width = UINT32(aligned_width);
   allocated_buffer_info->aligned_height = UINT32(aligned_height);
@@ -315,4 +321,30 @@
   return kErrorNone;
 }
 
+DisplayError HWCBufferAllocator::GetBufferLayout(const AllocatedBufferInfo &buf_info,
+                                                 uint32_t stride[4], uint32_t offset[4],
+                                                 uint32_t *num_planes) {
+  // TODO(user): Transition APIs to not need a private handle
+  private_handle_t hnd(-1, 0, 0, 0, 0, 0, 0);
+  int format = HAL_PIXEL_FORMAT_RGBA_8888;
+  uint64_t flags = 0;
+
+  SetBufferInfo(buf_info.format, &format, &flags);
+  // Setup only the required stuff, skip rest
+  hnd.format = format;
+  hnd.width = INT32(buf_info.aligned_width);
+  hnd.height = INT32(buf_info.aligned_height);
+  if (flags & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) {
+    hnd.flags = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+  }
+
+  int ret = gralloc1::GetBufferLayout(&hnd, stride, offset, num_planes);
+  if (ret < 0) {
+    DLOGE("GetBufferLayout failed");
+    return kErrorParameters;
+  }
+
+  return kErrorNone;
+}
+
 }  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_buffer_allocator.h b/sdm/libs/hwc2/hwc_buffer_allocator.h
index c28a94e..d574401 100644
--- a/sdm/libs/hwc2/hwc_buffer_allocator.h
+++ b/sdm/libs/hwc2/hwc_buffer_allocator.h
@@ -57,7 +57,10 @@
                                 int *aligned_width, int *aligned_height);
   DisplayError GetAllocatedBufferInfo(const BufferConfig &buffer_config,
                                       AllocatedBufferInfo *allocated_buffer_info);
-  int SetBufferInfo(LayerBufferFormat format, int *target, int *flags);
+  DisplayError GetBufferLayout(const AllocatedBufferInfo &buf_info,
+                               uint32_t stride[4], uint32_t offset[4],
+                               uint32_t *num_planes);
+  int SetBufferInfo(LayerBufferFormat format, int *target, uint64_t *flags);
 
  private:
   gralloc1_device_t *gralloc_device_ = nullptr;
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index 0aaad8e..a39476e 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -189,6 +189,8 @@
       PopulateTransform(HAL_COLOR_MODE_ADOBE_RGB, mode_string);
     } else if (mode_string.find("hal_dci_p3") != std::string::npos) {
       PopulateTransform(HAL_COLOR_MODE_DCI_P3, mode_string);
+    } else if (mode_string.find("hal_display_p3") != std::string::npos) {
+      PopulateTransform(HAL_COLOR_MODE_DISPLAY_P3, mode_string);
     }
   }
 }
@@ -573,6 +575,10 @@
     return HWC2::Error::BadDisplay;
   }
 
+  if (config != 0) {  // We only use config[0] - see TODO above
+      return HWC2::Error::BadConfig;
+  }
+
   switch (attribute) {
     case HWC2::Attribute::VsyncPeriod:
       *out_value = INT32(variable_config.vsync_period_ns);
@@ -591,6 +597,7 @@
       break;
     default:
       DLOGW("Spurious attribute type = %s", to_string(attribute).c_str());
+      *out_value = -1;
       return HWC2::Error::BadConfig;
   }
 
@@ -668,6 +675,9 @@
 }
 
 HWC2::Error HWCDisplay::SetActiveConfig(hwc2_config_t config) {
+  if (config != 0) {
+    return HWC2::Error::BadConfig;
+  }
   // We have only one config right now - do nothing
   return HWC2::Error::None;
 }
diff --git a/sdm/libs/hwc2/hwc_layers.cpp b/sdm/libs/hwc2/hwc_layers.cpp
index 302e339..aec44ad 100644
--- a/sdm/libs/hwc2/hwc_layers.cpp
+++ b/sdm/libs/hwc2/hwc_layers.cpp
@@ -154,7 +154,6 @@
   layer_buffer->acquire_fence_fd = acquire_fence;
   layer_buffer->size = handle->size;
   layer_buffer->buffer_id = reinterpret_cast<uint64_t>(handle);
-  layer_buffer->fb_id = handle->fb_id;
 
   return HWC2::Error::None;
 }
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index bf52ef6..255cb48 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -140,9 +140,11 @@
   struct rlimit fd_limit = {};
   getrlimit(RLIMIT_NOFILE, &fd_limit);
   fd_limit.rlim_cur = fd_limit.rlim_cur * 2;
-  auto err = setrlimit(RLIMIT_NOFILE, &fd_limit);
-  if (err) {
-    DLOGW("Unable to increase fd limit -  err:%d, %s", errno, strerror(errno));
+  if (fd_limit.rlim_cur < fd_limit.rlim_max) {
+    auto err = setrlimit(RLIMIT_NOFILE, &fd_limit);
+    if (err) {
+      DLOGW("Unable to increase fd limit -  err:%d, %s", errno, strerror(errno));
+    }
   }
   return 0;
 }
@@ -369,11 +371,13 @@
 }
 
 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 {
+    // TODO(user): Port over connect_display_ from HWC1
+    // Return no error for connected displays
     *out_support = 0;
+    return HWC2_ERROR_BAD_DISPLAY;
   }
   return HWC2_ERROR_NONE;
 }