Merge "sdm: Add support for single buffer layers"
diff --git a/libgralloc1/gr_buf_mgr.cpp b/libgralloc1/gr_buf_mgr.cpp
index 8aeee40..9974834 100644
--- a/libgralloc1/gr_buf_mgr.cpp
+++ b/libgralloc1/gr_buf_mgr.cpp
@@ -809,6 +809,17 @@
       }
     } break;
 
+    case GRALLOC_MODULE_PERFORM_SET_SINGLE_BUFFER_MODE: {
+      private_handle_t* hnd =  va_arg(args, private_handle_t*);
+      uint32_t *enable = va_arg(args, uint32_t*);
+      if (private_handle_t::validate(hnd) != 0) {
+        return GRALLOC1_ERROR_BAD_HANDLE;
+      }
+      if (setMetaData(hnd, SET_SINGLE_BUFFER_MODE, enable) != 0) {
+        return GRALLOC1_ERROR_UNSUPPORTED;
+      }
+    } break;
+
     default:
       break;
   }
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index 7829fcd..0c48b05 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -542,6 +542,12 @@
       secure_display_active = true;
     }
 
+    if (hwc_layer->IsSingleBuffered() &&
+       !(hwc_layer->IsRotationPresent() || hwc_layer->IsScalingPresent())) {
+      layer->flags.single_buffer = true;
+      layer_stack_.flags.single_buffered_layer_present = 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()) {
@@ -2061,7 +2067,8 @@
   }
 
   // Layer Stack checks
-  if (layer_stack_.flags.hdr_present && (tone_mapper_ && tone_mapper_->IsActive())) {
+  if ((layer_stack_.flags.hdr_present && (tone_mapper_ && tone_mapper_->IsActive())) ||
+     layer_stack_.flags.single_buffered_layer_present) {
     DLOGV_IF(kTagClient, "HDR content present with tone mapping enabled. Returning false.");
     return false;
   }
diff --git a/sdm/libs/hwc2/hwc_layers.cpp b/sdm/libs/hwc2/hwc_layers.cpp
index cd9ce7b..51384f9 100644
--- a/sdm/libs/hwc2/hwc_layers.cpp
+++ b/sdm/libs/hwc2/hwc_layers.cpp
@@ -772,6 +772,9 @@
     GetUBWCStatsFromMetaData(&cr_stats[0], &(layer_buffer->ubwc_crstats[0]));
   }  // if (getMetaData)
 
+  single_buffer_ = false;
+  getMetaData(const_cast<private_handle_t *>(handle), GET_SINGLE_BUFFER_MODE, &single_buffer_);
+
   return kErrorNone;
 }
 
@@ -891,4 +894,19 @@
   return fence;
 }
 
+bool HWCLayer::IsRotationPresent() {
+  return ((layer_->transform.rotation != 0.0f) ||
+         layer_->transform.flip_horizontal ||
+         layer_->transform.flip_vertical);
+}
+
+bool HWCLayer::IsScalingPresent() {
+  uint32_t src_width  = static_cast<uint32_t>(layer_->src_rect.right - layer_->src_rect.left);
+  uint32_t src_height = static_cast<uint32_t>(layer_->src_rect.bottom - layer_->src_rect.top);
+  uint32_t dst_width  = static_cast<uint32_t>(layer_->dst_rect.right - layer_->dst_rect.left);
+  uint32_t dst_height = static_cast<uint32_t>(layer_->dst_rect.bottom - layer_->dst_rect.top);
+
+  return ((src_width != dst_width) || (dst_height != src_height));
+}
+
 }  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_layers.h b/sdm/libs/hwc2/hwc_layers.h
index a7b65c8..5f5792f 100644
--- a/sdm/libs/hwc2/hwc_layers.h
+++ b/sdm/libs/hwc2/hwc_layers.h
@@ -94,6 +94,9 @@
   bool SupportLocalConversion(ColorPrimaries working_primaries);
   void ResetValidation() { needs_validate_ = false; }
   bool NeedsValidation() { return (needs_validate_ || geometry_changes_); }
+  bool IsSingleBuffered() { return single_buffer_; }
+  bool IsScalingPresent();
+  bool IsRotationPresent();
 
  private:
   Layer *layer_ = nullptr;
@@ -107,6 +110,7 @@
   LayerTransform layer_transform_ = {};
   LayerRect dst_rect_ = {};
   bool needs_validate_ = true;
+  bool single_buffer_ = false;
 
   // Composition requested by client(SF)
   HWC2::Composition client_requested_ = HWC2::Composition::Device;