sdm/hwc/gralloc: Move fb_id lifecycle to DAL

--Move fb_id creation/deletion from gralloc to DAL and make it per
cycle
--Make Gralloc/HWC/SDM structures independent of libdrmutils
and fb_id / gemhandles
--Pass BufferAllocator pointer to Display* and HWDevice*
--Add new GetBufferLayout API to BufferAllocator that can be called
by DAL before creating fb_id

Change-Id: I102f432cccee912ad4bcce622764938fa3d36ed3
CRs-fixed: 1114808
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_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/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/libs/core/Android.mk b/sdm/libs/core/Android.mk
index 7d71eec..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
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 8746095..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;
@@ -136,6 +351,7 @@
 
 DisplayError HWDeviceDRM::Deinit() {
   delete hw_scale_;
+  registry_.Clear();
   drm_mgr_intf_->DestroyAtomicReq(drm_atomic_intf_);
   drm_atomic_intf_ = {};
   drm_mgr_intf_->UnregisterDisplay(token_);
@@ -390,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);
@@ -423,7 +640,7 @@
         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,
@@ -448,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();
@@ -461,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) {
@@ -505,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;
   }
 
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index 41aec9e..cc2ae7b 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -35,6 +35,7 @@
 #include <pthread.h>
 #include <xf86drmMode.h>
 #include <string>
+#include <unordered_map>
 #include <vector>
 
 #include "hw_interface.h"
@@ -48,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();
@@ -99,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,
@@ -118,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_ = {};
@@ -134,8 +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 cbd585b..bfd5c98 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/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