Merge "gralloc1: update aligned size of buffer in native handle"
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index 1d9d85a..f40f324 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -543,9 +543,11 @@
    * Commit the params set via Perform(). Also resets the properties after commit. Needs to be
    * called every frame.
    * [input]: synchronous: Determines if the call should block until a h/w flip
+   * [input]: retain_planes: Retains already staged planes. Useful when not explicitly programming
+   *          planes but still need the previously staged ones to not be unstaged
    * [return]: Error code if the API fails, 0 on success.
    */
-  virtual int Commit(bool synchronous) = 0;
+  virtual int Commit(bool synchronous, bool retain_planes) = 0;
   /*
    * Validate the params set via Perform().
    * [return]: Error code if the API fails, 0 on success.
diff --git a/libgralloc1/gr_buf_mgr.cpp b/libgralloc1/gr_buf_mgr.cpp
index 82aadaf..d78cc94 100644
--- a/libgralloc1/gr_buf_mgr.cpp
+++ b/libgralloc1/gr_buf_mgr.cpp
@@ -124,7 +124,7 @@
   std::lock_guard<std::mutex> buffer_lock(buffer_lock_);
   if (shared && (max_buf_index >= 0)) {
     // Allocate one and duplicate/copy the handles for each descriptor
-    if (AllocateBuffer(*descriptors[UINT(max_buf_index)], &out_buffers[max_buf_index])) {
+    if (AllocateBufferLocked(*descriptors[UINT(max_buf_index)], &out_buffers[max_buf_index])) {
       return GRALLOC1_ERROR_NO_RESOURCES;
     }
 
@@ -140,7 +140,7 @@
     // Buffer sharing is not feasible.
     // Allocate separate buffer for each descriptor
     for (i = 0; i < num_descriptors; i++) {
-      if (AllocateBuffer(*descriptors[i], &out_buffers[i])) {
+      if (AllocateBufferLocked(*descriptors[i], &out_buffers[i])) {
         return GRALLOC1_ERROR_NO_RESOURCES;
       }
     }
@@ -447,8 +447,8 @@
   return buffer_type;
 }
 
-int BufferManager::AllocateBuffer(const BufferDescriptor &descriptor, buffer_handle_t *handle,
-                                  unsigned int bufferSize) {
+int BufferManager::AllocateBufferLocked(const BufferDescriptor &descriptor, buffer_handle_t *handle,
+                                        unsigned int bufferSize) {
   if (!handle)
     return -EINVAL;
 
@@ -739,22 +739,6 @@
 
       // TODO(user): Break out similar functionality, preferably moving to a common lib.
 
-    case GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER: {
-      int width = va_arg(args, int);
-      int height = va_arg(args, int);
-      int format = va_arg(args, int);
-      uint64_t p_usage = va_arg(args, uint64_t);
-      uint64_t c_usage = va_arg(args, uint64_t);
-      buffer_handle_t *hnd = va_arg(args, buffer_handle_t*);
-      gralloc1_producer_usage_t producer_usage = static_cast<gralloc1_producer_usage_t>(p_usage);
-      gralloc1_consumer_usage_t consumer_usage = static_cast<gralloc1_consumer_usage_t>(c_usage);
-      BufferDescriptor descriptor(width, height, format, producer_usage, consumer_usage);
-      unsigned int size;
-      unsigned int alignedw, alignedh;
-      GetBufferSizeAndDimensions(GetBufferInfo(descriptor), &size, &alignedw, &alignedh);
-      AllocateBuffer(descriptor, hnd, size);
-    } break;
-
     case GRALLOC1_MODULE_PERFORM_GET_INTERLACE_FLAG: {
       private_handle_t *hnd = va_arg(args, private_handle_t *);
       int *flag = va_arg(args, int *);
diff --git a/libgralloc1/gr_buf_mgr.h b/libgralloc1/gr_buf_mgr.h
index 861a7a7..e021afd 100644
--- a/libgralloc1/gr_buf_mgr.h
+++ b/libgralloc1/gr_buf_mgr.h
@@ -73,8 +73,8 @@
   BufferManager();
   gralloc1_error_t MapBuffer(private_handle_t const *hnd);
   int GetBufferType(int format);
-  int AllocateBuffer(const BufferDescriptor &descriptor, buffer_handle_t *handle,
-                     unsigned int bufferSize = 0);
+  int AllocateBufferLocked(const BufferDescriptor &descriptor, buffer_handle_t *handle,
+                           unsigned int bufferSize = 0);
   uint32_t GetDataAlignment(int format, gralloc1_producer_usage_t prod_usage,
                        gralloc1_consumer_usage_t cons_usage);
   int GetHandleFlags(int format, gralloc1_producer_usage_t prod_usage,
diff --git a/libgralloc1/gralloc_priv.h b/libgralloc1/gralloc_priv.h
index cec4af0..ef1bbc3 100644
--- a/libgralloc1/gralloc_priv.h
+++ b/libgralloc1/gralloc_priv.h
@@ -99,8 +99,7 @@
 #define GRALLOC_MODULE_PERFORM_SET_IGC 12
 #define GRALLOC_MODULE_PERFORM_SET_SINGLE_BUFFER_MODE 13
 #define GRALLOC1_MODULE_PERFORM_GET_BUFFER_SIZE_AND_DIMENSIONS 14
-#define GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER 15
-#define GRALLOC1_MODULE_PERFORM_GET_INTERLACE_FLAG 16
+#define GRALLOC1_MODULE_PERFORM_GET_INTERLACE_FLAG 15
 
 // OEM specific HAL formats
 #define HAL_PIXEL_FORMAT_RGBA_5551 6
diff --git a/libqdutils/display_config.cpp b/libqdutils/display_config.cpp
index 83d912e..87ca401 100644
--- a/libqdutils/display_config.cpp
+++ b/libqdutils/display_config.cpp
@@ -366,3 +366,25 @@
     return err;
 }
 
+// returns 0 if composer is up
+extern "C" int waitForComposerInit() {
+    int status = false;
+    sp<IQService> binder = getBinder();
+    if (binder == NULL) {
+        sleep(2);
+        binder = getBinder();
+    }
+
+    if (binder != NULL) {
+        Parcel inParcel, outParcel;
+        binder->dispatch(IQService::GET_COMPOSER_STATUS, &inParcel, &outParcel);
+        status = !!outParcel.readInt32();
+        if (!status) {
+            sleep(2);
+            binder->dispatch(IQService::GET_COMPOSER_STATUS, &inParcel, &outParcel);
+            status = !!outParcel.readInt32();
+        }
+    }
+
+    return !status;
+}
diff --git a/libqdutils/display_config.h b/libqdutils/display_config.h
index 6512bf5..c692699 100644
--- a/libqdutils/display_config.h
+++ b/libqdutils/display_config.h
@@ -160,4 +160,6 @@
 
 }; //namespace
 
+
+extern "C" int waitForComposerInit();
 #endif
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index 8985dd6..610cd4e 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -76,6 +76,7 @@
         SET_COLOR_MODE = 34, // Overrides the QDCM mode on the display
         GET_HDR_CAPABILITIES = 35, // Get HDR capabilities for legacy HWC interface
         SET_COLOR_MODE_BY_ID = 36, // Overrides the QDCM mode using the given mode ID
+        GET_COMPOSER_STATUS = 37, // Get composer init status-true if primary display init is done
         COMMAND_LIST_END = 400,
     };
 
diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h
index 142d2c6..2f25bde 100644
--- a/sdm/include/core/display_interface.h
+++ b/sdm/include/core/display_interface.h
@@ -674,6 +674,20 @@
   */
   virtual DisplayError SetCompositionState(LayerComposition composition_type, bool enable) = 0;
 
+  /*! @brief Method to check whether a client target with the given properties
+      can be supported/handled by hardware.
+
+    @param[in] width client target width
+    @param[in] height client target height
+    @param[in] format client target format
+    @param[in] colorMetaData client target colorMetaData
+
+    @return \link DisplayError \endlink
+  */
+  virtual DisplayError GetClientTargetSupport(uint32_t width, uint32_t height,
+                                              LayerBufferFormat format,
+                                              const ColorMetaData &color_metadata) = 0;
+
  protected:
   virtual ~DisplayInterface() { }
 };
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 1ffe862..dde3e8e 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -1493,4 +1493,93 @@
   return kErrorNone;
 }
 
+DisplayError DisplayBase::GetClientTargetSupport(uint32_t width, uint32_t height,
+                                                 LayerBufferFormat format,
+                                                 const ColorMetaData &color_metadata) {
+  DisplayError error = kErrorNone;
+
+  if (format != kFormatRGBA8888 && format != kFormatRGBA1010102) {
+    DLOGW("Unsupported format = %d", format);
+    error = kErrorNotSupported;
+  } else if (ValidateScaling(width, height) != kErrorNone) {
+    DLOGW("Unsupported width = %d height = %d", width, height);
+    error = kErrorNotSupported;
+  } else {
+    error = ValidateDataspace(color_metadata);
+    if (error != kErrorNone) {
+      return error;
+    }
+
+    // Check for BT2020 support
+    if (color_metadata.colorPrimaries == ColorPrimaries_BT2020) {
+      DLOGW("Unsupported dataspace");
+      error = kErrorNotSupported;
+    }
+  }
+
+  return error;
+}
+
+DisplayError DisplayBase::ValidateScaling(uint32_t width, uint32_t height) {
+  uint32_t display_width = display_attributes_.x_pixels;
+  uint32_t display_height = display_attributes_.y_pixels;
+
+  HWResourceInfo hw_resource_info = HWResourceInfo();
+  hw_info_intf_->GetHWResourceInfo(&hw_resource_info);
+  float max_scale_down = FLOAT(hw_resource_info.max_scale_down);
+  float max_scale_up = FLOAT(hw_resource_info.max_scale_up);
+
+  float scale_x = FLOAT(width / display_width);
+  float scale_y = FLOAT(height / display_height);
+
+  if (scale_x > max_scale_down || scale_y > max_scale_down) {
+    return kErrorNotSupported;
+  }
+
+  if (UINT32(scale_x) < 1 && scale_x > 0.0f) {
+    if ((1.0f / scale_x) > max_scale_up) {
+      return kErrorNotSupported;
+    }
+  }
+
+  if (UINT32(scale_y) < 1 && scale_y > 0.0f) {
+    if ((1.0f / scale_y) > max_scale_up) {
+      return kErrorNotSupported;
+    }
+  }
+
+  return kErrorNone;
+}
+
+DisplayError DisplayBase::ValidateDataspace(const ColorMetaData &color_metadata) {
+  // Handle transfer
+  switch (color_metadata.transfer) {
+    case Transfer_sRGB:
+    case Transfer_SMPTE_170M:
+    case Transfer_SMPTE_ST2084:
+    case Transfer_HLG:
+    case Transfer_Linear:
+    case Transfer_Gamma2_2:
+      break;
+    default:
+      DLOGW("Unsupported Transfer Request = %d", color_metadata.transfer);
+      return kErrorNotSupported;
+  }
+
+  // Handle colorPrimaries
+  switch (color_metadata.colorPrimaries) {
+    case ColorPrimaries_BT709_5:
+    case ColorPrimaries_BT601_6_525:
+    case ColorPrimaries_BT601_6_625:
+    case ColorPrimaries_DCIP3:
+    case ColorPrimaries_BT2020:
+      break;
+    default:
+      DLOGW("Unsupported Color Primary = %d", color_metadata.colorPrimaries);
+      return kErrorNotSupported;
+  }
+
+  return kErrorNone;
+}
+
 }  // namespace sdm
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index 979a465..fc03cc7 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -115,6 +115,9 @@
   virtual DisplayError GetDisplayPort(DisplayPort *port);
   virtual bool IsPrimaryDisplay();
   virtual DisplayError SetCompositionState(LayerComposition composition_type, bool enable);
+  virtual DisplayError GetClientTargetSupport(uint32_t width, uint32_t height,
+                                              LayerBufferFormat format,
+                                              const ColorMetaData &color_metadata);
 
  protected:
   DisplayError BuildLayerStackStats(LayerStack *layer_stack);
@@ -124,6 +127,8 @@
   DisplayError HandleHDR(LayerStack *layer_stack);
   DisplayError ValidateHDR(LayerStack *layer_stack);
   DisplayError SetHDRMode(bool set);
+  DisplayError ValidateScaling(uint32_t width, uint32_t height);
+  DisplayError ValidateDataspace(const ColorMetaData &color_metadata);
 
   // DumpImpl method
   void AppendDump(char *buffer, uint32_t length);
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index bd09a38..345aeb2 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -353,7 +353,7 @@
       drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id,
                                 &connector_info_.modes[current_mode_index_]);
       drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
-      if (drm_atomic_intf_->Commit(true /* synchronous */)) {
+      if (drm_atomic_intf_->Commit(true /* synchronous */, false /* retain_planes*/)) {
         DRM_LOGI("Setting up CRTC %d, Connector %d for %s failed", token_.crtc_id,
           token_.conn_id, device_name_);
         return kErrorResources;
@@ -669,7 +669,7 @@
 
   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
   drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::ON);
-  int ret = drm_atomic_intf_->Commit(true /* synchronous */);
+  int ret = drm_atomic_intf_->Commit(true /* synchronous */, true /* retain_planes */);
   if (ret) {
     DLOGE("Failed with error: %d", ret);
     return kErrorHardware;
@@ -678,6 +678,7 @@
 }
 
 DisplayError HWDeviceDRM::PowerOff() {
+  DTRACE_SCOPED();
   if (!drm_atomic_intf_) {
     DLOGE("DRM Atomic Interface is null!");
     return kErrorUndefined;
@@ -685,7 +686,7 @@
 
   drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::OFF);
   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 0);
-  int ret = drm_atomic_intf_->Commit(true /* synchronous */);
+  int ret = drm_atomic_intf_->Commit(true /* synchronous */, false /* retain_planes */);
   if (ret) {
     DLOGE("Failed with error: %d", ret);
     return kErrorHardware;
@@ -694,9 +695,10 @@
 }
 
 DisplayError HWDeviceDRM::Doze() {
+  DTRACE_SCOPED();
   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
   drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::DOZE);
-  int ret = drm_atomic_intf_->Commit(false /* synchronous */);
+  int ret = drm_atomic_intf_->Commit(true /* synchronous */, true /* retain_planes */);
   if (ret) {
     DLOGE("Failed with error: %d", ret);
     return kErrorHardware;
@@ -706,8 +708,16 @@
 }
 
 DisplayError HWDeviceDRM::DozeSuspend() {
+  DTRACE_SCOPED();
+  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
   drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id,
                             DRMPowerMode::DOZE_SUSPEND);
+  int ret = drm_atomic_intf_->Commit(true /* synchronous */, true /* retain_planes */);
+  if (ret) {
+    DLOGE("Failed with error: %d", ret);
+    return kErrorHardware;
+  }
+
   return kErrorNone;
 }
 
@@ -976,7 +986,7 @@
   DTRACE_SCOPED();
   SetupAtomic(hw_layers, false /* validate */);
 
-  int ret = drm_atomic_intf_->Commit(false /* synchronous */);
+  int ret = drm_atomic_intf_->Commit(false /* synchronous */, false /* retain_planes*/);
   if (ret) {
     DLOGE("%s failed with error %d crtc %d", __FUNCTION__, ret, token_.crtc_id);
     return kErrorHardware;
@@ -1008,7 +1018,8 @@
 }
 
 DisplayError HWDeviceDRM::Flush() {
-  int ret = drm_atomic_intf_->Commit(false /* synchronous */);
+  DTRACE_SCOPED();
+  int ret = drm_atomic_intf_->Commit(false /* synchronous */, false /* retain_planes*/);
   if (ret) {
     DLOGE("failed with error %d", ret);
     return kErrorHardware;
diff --git a/sdm/libs/core/drm/hw_tv_drm.cpp b/sdm/libs/core/drm/hw_tv_drm.cpp
index d19b706..bd9ddc2 100644
--- a/sdm/libs/core/drm/hw_tv_drm.cpp
+++ b/sdm/libs/core/drm/hw_tv_drm.cpp
@@ -110,14 +110,19 @@
   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
 
   // Commit to setup pipeline with mode, which then tells us the topology etc
-  if (drm_atomic_intf_->Commit(true /* synchronous */)) {
+  if (drm_atomic_intf_->Commit(true /* synchronous */, false /* retain_planes*/)) {
     DLOGE("Setting up CRTC %d, Connector %d for %s failed", token_.crtc_id,
           token_.conn_id, device_name_);
     return kErrorResources;
   }
 
-  // Reload connector info for updated info after 1st commit
+  // Reload connector info for updated info after 1st commit and validate
   drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
+  if (index >= connector_info_.modes.size()) {
+    DLOGE("Invalid mode index %d mode size %d", index, UINT32(connector_info_.modes.size()));
+    return kErrorNotSupported;
+  }
+
   DLOGI("Setup CRTC %d, Connector %d for %s", token_.crtc_id, token_.conn_id, device_name_);
 
   current_mode_index_ = index;
@@ -172,7 +177,7 @@
 DisplayError HWTVDRM::PowerOff() {
   DTRACE_SCOPED();
 
-  int ret = drm_atomic_intf_->Commit(true /* synchronous */);
+  int ret = drm_atomic_intf_->Commit(true /* synchronous */, false /* retain_planes*/);
   if (ret) {
     DLOGE("%s failed with error %d", __FUNCTION__, ret);
     return kErrorHardware;
diff --git a/sdm/libs/hwc2/display_null.h b/sdm/libs/hwc2/display_null.h
index fa88c28..cde9991 100644
--- a/sdm/libs/hwc2/display_null.h
+++ b/sdm/libs/hwc2/display_null.h
@@ -95,6 +95,8 @@
   MAKE_NO_OP(SetDetailEnhancerData(const DisplayDetailEnhancerData &))
   MAKE_NO_OP(GetDisplayPort(DisplayPort *))
   MAKE_NO_OP(SetCompositionState(LayerComposition, bool))
+  MAKE_NO_OP(GetClientTargetSupport(uint32_t, uint32_t, LayerBufferFormat,
+                                    const ColorMetaData &))
 
  private:
   bool active_ = false;
diff --git a/sdm/libs/hwc2/hwc_buffer_allocator.cpp b/sdm/libs/hwc2/hwc_buffer_allocator.cpp
index c32a236..62b64be 100644
--- a/sdm/libs/hwc2/hwc_buffer_allocator.cpp
+++ b/sdm/libs/hwc2/hwc_buffer_allocator.cpp
@@ -59,12 +59,26 @@
     return kErrorResources;
   }
 
+  CreateBufferDescriptor_ = reinterpret_cast<GRALLOC1_PFN_CREATE_DESCRIPTOR>(
+      gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_CREATE_DESCRIPTOR));
+  DestroyBufferDescriptor_ = reinterpret_cast<GRALLOC1_PFN_DESTROY_DESCRIPTOR>(
+      gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR));
+  AllocateBuffer_ = reinterpret_cast<GRALLOC1_PFN_ALLOCATE>(
+      gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_ALLOCATE));
   ReleaseBuffer_ = reinterpret_cast<GRALLOC1_PFN_RELEASE>(
       gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_RELEASE));
+  SetBufferDimensions_ = reinterpret_cast<GRALLOC1_PFN_SET_DIMENSIONS>(
+      gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_SET_DIMENSIONS));
+  SetBufferFormat_ = reinterpret_cast<GRALLOC1_PFN_SET_FORMAT>(
+      gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_SET_FORMAT));
+  SetConsumerUsage_ = reinterpret_cast<GRALLOC1_PFN_SET_CONSUMER_USAGE>(
+      gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_SET_CONSUMER_USAGE));
+  SetProducerUsage_ = reinterpret_cast<GRALLOC1_PFN_SET_PRODUCER_USAGE>(
+      gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_SET_PRODUCER_USAGE));
+  LockBuffer_ = reinterpret_cast<GRALLOC1_PFN_LOCK>(
+      gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_LOCK));
   Perform_ = reinterpret_cast<GRALLOC1_PFN_PERFORM>(
       gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_PERFORM));
-  Lock_ = reinterpret_cast<GRALLOC1_PFN_LOCK>(
-      gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_LOCK));
 
   return kErrorNone;
 }
@@ -81,6 +95,7 @@
 }
 
 DisplayError HWCBufferAllocator::AllocateBuffer(BufferInfo *buffer_info) {
+  DisplayError sdm_err = kErrorNone;
   const BufferConfig &buffer_config = buffer_info->buffer_config;
   AllocatedBufferInfo *alloc_buffer_info = &buffer_info->alloc_buffer_info;
   uint32_t width = buffer_config.width;
@@ -109,29 +124,58 @@
     alloc_flags |= GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE;
   }
 
-  uint64_t producer_usage = alloc_flags;
-  uint64_t consumer_usage = (alloc_flags | GRALLOC1_CONSUMER_USAGE_HWCOMPOSER);
-  // CreateBuffer
+  gralloc1_producer_usage_t producer_usage = static_cast<gralloc1_producer_usage_t>(alloc_flags);
+  gralloc1_consumer_usage_t consumer_usage = static_cast<gralloc1_consumer_usage_t>(alloc_flags |
+                                             GRALLOC1_CONSUMER_USAGE_HWCOMPOSER);
+  gralloc1_buffer_descriptor_t descriptor_id = {};
+  buffer_handle_t buf = nullptr;
   private_handle_t *hnd = nullptr;
-  Perform_(gralloc_device_, GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER, width, height, format,
-           producer_usage, consumer_usage, &hnd);
 
-  if (hnd) {
-    alloc_buffer_info->fd = hnd->fd;
-    alloc_buffer_info->stride = UINT32(hnd->width);
-    alloc_buffer_info->size = hnd->size;
-  } else {
-    DLOGE("Failed to allocate memory");
-    return kErrorMemory;
+  // CreateBuffer
+  if (CreateBufferDescriptor_(gralloc_device_, &descriptor_id) != GRALLOC1_ERROR_NONE) {
+    DLOGE("CreateBufferDescriptor failed gr_device=%p", gralloc_device_);
+    return kErrorParameters;
+  }
+  if (SetBufferDimensions_(gralloc_device_, descriptor_id, width, height) != GRALLOC1_ERROR_NONE) {
+    DLOGE("SetBufferDimensions failed gr_device=%x desc=%d", gralloc_device_, descriptor_id);
+    sdm_err = kErrorParameters;
+    goto CleanupOnError;
+  }
+  if (SetBufferFormat_(gralloc_device_, descriptor_id, format) != GRALLOC1_ERROR_NONE) {
+    DLOGE("SetBufferFormat failed gr_device=%x desc=%d", gralloc_device_, descriptor_id);
+    sdm_err = kErrorParameters;
+    goto CleanupOnError;
+  }
+  if (SetConsumerUsage_(gralloc_device_, descriptor_id, consumer_usage) != GRALLOC1_ERROR_NONE) {
+    DLOGE("SetConsumerUsage failed gr_device=%x desc=%d", gralloc_device_, descriptor_id);
+    sdm_err = kErrorParameters;
+    goto CleanupOnError;
+  }
+  if (SetProducerUsage_(gralloc_device_, descriptor_id, producer_usage) != GRALLOC1_ERROR_NONE) {
+    DLOGE("SetProducerUsage failed gr_device=%x desc=%d", gralloc_device_, descriptor_id);
+    sdm_err = kErrorParameters;
+    goto CleanupOnError;
+  }
+  if (AllocateBuffer_(gralloc_device_, 1, &descriptor_id, &buf) != GRALLOC1_ERROR_NONE) {
+    DLOGE("AllocateBuffer failed gr_device=%x desc=%d", gralloc_device_, descriptor_id);
+    sdm_err = kErrorMemory;
+    goto CleanupOnError;
   }
 
+  hnd = (private_handle_t *)buf;  // NOLINT
+  alloc_buffer_info->fd = hnd->fd;
+  alloc_buffer_info->stride = UINT32(hnd->width);
+  alloc_buffer_info->size = hnd->size;
+
   buffer_info->private_data = reinterpret_cast<void *>(hnd);
-  return kErrorNone;
+CleanupOnError:
+  DestroyBufferDescriptor_(gralloc_device_, descriptor_id);
+  return sdm_err;
 }
 
 DisplayError HWCBufferAllocator::FreeBuffer(BufferInfo *buffer_info) {
   DisplayError err = kErrorNone;
-  buffer_handle_t hnd = static_cast<private_handle_t *>(buffer_info->private_data);
+  buffer_handle_t hnd = static_cast<buffer_handle_t>(buffer_info->private_data);
   ReleaseBuffer_(gralloc_device_, hnd);
   AllocatedBufferInfo *alloc_buffer_info = &buffer_info->alloc_buffer_info;
 
@@ -389,8 +433,8 @@
         .width = 0,
         .height = 0
   };
-  Lock_(gralloc_device_, handle, GRALLOC1_PRODUCER_USAGE_CPU_READ, GRALLOC1_CONSUMER_USAGE_NONE,
-        &accessRegion, &buffer_ptr, acquire_fence);
+  LockBuffer_(gralloc_device_, handle, GRALLOC1_PRODUCER_USAGE_CPU_READ,
+              GRALLOC1_CONSUMER_USAGE_NONE, &accessRegion, &buffer_ptr, acquire_fence);
   if (!buffer_ptr) {
     return kErrorUndefined;
   }
diff --git a/sdm/libs/hwc2/hwc_buffer_allocator.h b/sdm/libs/hwc2/hwc_buffer_allocator.h
index 8101d85..8a73ccb 100644
--- a/sdm/libs/hwc2/hwc_buffer_allocator.h
+++ b/sdm/libs/hwc2/hwc_buffer_allocator.h
@@ -64,10 +64,17 @@
 
  private:
   gralloc1_device_t *gralloc_device_ = nullptr;
-  const hw_module_t *module_;
+  const hw_module_t *module_ = nullptr;
+  GRALLOC1_PFN_CREATE_DESCRIPTOR CreateBufferDescriptor_ = nullptr;
+  GRALLOC1_PFN_DESTROY_DESCRIPTOR DestroyBufferDescriptor_ = nullptr;
+  GRALLOC1_PFN_ALLOCATE AllocateBuffer_ = nullptr;
   GRALLOC1_PFN_RELEASE ReleaseBuffer_ = nullptr;
+  GRALLOC1_PFN_SET_DIMENSIONS SetBufferDimensions_ = nullptr;
+  GRALLOC1_PFN_SET_FORMAT SetBufferFormat_ = nullptr;
+  GRALLOC1_PFN_SET_CONSUMER_USAGE SetConsumerUsage_ = nullptr;
+  GRALLOC1_PFN_SET_PRODUCER_USAGE SetProducerUsage_ = nullptr;
+  GRALLOC1_PFN_LOCK LockBuffer_ = nullptr;
   GRALLOC1_PFN_PERFORM Perform_ = nullptr;
-  GRALLOC1_PFN_LOCK Lock_ = nullptr;
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index 723148b..f58fe8b 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -462,6 +462,7 @@
   display_rect_ = LayerRect();
   metadata_refresh_rate_ = 0;
   auto working_primaries = ColorPrimaries_BT709_5;
+  bool secure_display_active = false;
 
   // Add one layer for fb target
   // TODO(user): Add blit target layers
@@ -520,6 +521,10 @@
       layer_stack_.flags.skip_present = true;
     }
 
+    if (layer->input_buffer.flags.secure_display) {
+      secure_display_active = true;
+    }
+
     if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::Cursor) {
       // Currently we support only one HWCursor & only at top most z-order
       if ((*layer_set_.rbegin())->GetId() == hwc_layer->GetId()) {
@@ -599,6 +604,8 @@
     // Must fall back to client composition
     MarkLayersForClientComposition();
   }
+  // set secure display
+  SetSecureDisplay(secure_display_active);
 }
 
 void HWCDisplay::BuildSolidFillStack() {
@@ -729,28 +736,18 @@
 
 HWC2::Error HWCDisplay::GetClientTargetSupport(uint32_t width, uint32_t height, int32_t format,
                                                int32_t dataspace) {
-  DisplayConfigVariableInfo variable_config;
-  HWC2::Error supported = HWC2::Error::None;
-  display_intf_->GetFrameBufferConfig(&variable_config);
-  if (format != HAL_PIXEL_FORMAT_RGBA_8888 && format != HAL_PIXEL_FORMAT_RGBA_1010102) {
-     DLOGW("Unsupported format = %d", format);
-    supported = HWC2::Error::Unsupported;
-  } else if (width != variable_config.x_pixels || height != variable_config.y_pixels) {
-    DLOGW("Unsupported width = %d height = %d", width, height);
-    supported = HWC2::Error::Unsupported;
-  } else if (dataspace != HAL_DATASPACE_UNKNOWN) {
-    ColorMetaData color_metadata = {};
-    if (sdm::GetSDMColorSpace(dataspace, &color_metadata) == false) {
-      DLOGW("Unsupported dataspace = %d", dataspace);
-      supported = HWC2::Error::Unsupported;
-    }
-    if (sdm::IsBT2020(color_metadata.colorPrimaries)) {
-      DLOGW("Unsupported color Primary BT2020");
-      supported = HWC2::Error::Unsupported;
-    }
+  ColorMetaData color_metadata = {};
+  LayerBufferFormat sdm_format = GetSDMFormat(format, 0);
+  GetColorPrimary(dataspace, &(color_metadata.colorPrimaries));
+  GetTransfer(dataspace, &(color_metadata.transfer));
+  GetRange(dataspace, &(color_metadata.range));
+
+  if (display_intf_->GetClientTargetSupport(width, height, sdm_format,
+                                            color_metadata) != kErrorNone) {
+    return HWC2::Error::Unsupported;
   }
 
-  return supported;
+  return HWC2::Error::None;
 }
 
 HWC2::Error HWCDisplay::GetColorModes(uint32_t *out_num_modes, android_color_mode_t *out_modes) {
@@ -1844,7 +1841,12 @@
 }
 
 void HWCDisplay::SetSecureDisplay(bool secure_display_active) {
-  secure_display_active_ = secure_display_active;
+  if (secure_display_active_ != secure_display_active) {
+    DLOGI("SecureDisplay state changed from %d to %d Needs Flush!!", secure_display_active_,
+          secure_display_active);
+    secure_display_active_ = secure_display_active;
+    skip_prepare_ = true;
+  }
   return;
 }
 
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index 89de074..e0396b6 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -212,6 +212,7 @@
     return status;
   }
 
+  is_composer_up_ = true;
   struct rlimit fd_limit = {};
   getrlimit(RLIMIT_NOFILE, &fd_limit);
   fd_limit.rlim_cur = fd_limit.rlim_cur * 2;
@@ -1014,6 +1015,10 @@
       status = SetColorModeById(input_parcel);
       break;
 
+    case qService::IQService::GET_COMPOSER_STATUS:
+      output_parcel->writeInt32(getComposerStatus());
+      break;
+
     default:
       DLOGW("QService command = %d is not supported", command);
       return -EINVAL;
@@ -1022,6 +1027,10 @@
   return status;
 }
 
+android::status_t HWCSession::getComposerStatus() {
+  return is_composer_up_;
+}
+
 android::status_t HWCSession::HandleGetDisplayAttributesForConfig(const android::Parcel
                                                                   *input_parcel,
                                                                   android::Parcel *output_parcel) {
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
index 4dbcf9b..18c652d 100644
--- a/sdm/libs/hwc2/hwc_session.h
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -223,6 +223,7 @@
   android::status_t SetColorModeOverride(const android::Parcel *input_parcel);
 
   android::status_t SetColorModeById(const android::Parcel *input_parcel);
+  android::status_t getComposerStatus();
 
   void Refresh(hwc2_display_t display);
   void HotPlug(hwc2_display_t display, HWC2::Connection state);
@@ -243,6 +244,7 @@
   qService::QService *qservice_ = nullptr;
   HWCSocketHandler socket_handler_;
   bool hdmi_is_primary_ = false;
+  bool is_composer_up_ = false;
   Locker callbacks_lock_;
 };