Merge "gralloc1: Get color space from metadata handle"
diff --git a/libgralloc1/gr_buf_mgr.cpp b/libgralloc1/gr_buf_mgr.cpp
index 1e461d5..c5d91d9 100644
--- a/libgralloc1/gr_buf_mgr.cpp
+++ b/libgralloc1/gr_buf_mgr.cpp
@@ -812,6 +812,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;
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index d139d0c..4138cc6 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -328,10 +328,6 @@
 // Defined in the same order as in the HWC2 header
 
 int32_t HWCSession::AcceptDisplayChanges(hwc2_device_t *device, hwc2_display_t display) {
-  if (display >= HWC_NUM_DISPLAY_TYPES) {
-    return  HWC2_ERROR_BAD_DISPLAY;
-  }
-  SCOPE_LOCK(locker_[display]);
   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::AcceptDisplayChanges);
 }
 
@@ -340,10 +336,7 @@
   if (!out_layer_id) {
     return  HWC2_ERROR_BAD_PARAMETER;
   }
-  if (display >= HWC_NUM_DISPLAY_TYPES) {
-    return  HWC2_ERROR_BAD_DISPLAY;
-  }
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[display]);
+
   return CallDisplayFunction(device, display, &HWCDisplay::CreateLayer, out_layer_id);
 }
 
@@ -373,10 +366,6 @@
 
 int32_t HWCSession::DestroyLayer(hwc2_device_t *device, hwc2_display_t display,
                                  hwc2_layer_t layer) {
-  if (display >= HWC_NUM_DISPLAY_TYPES) {
-    return  HWC2_ERROR_BAD_DISPLAY;
-  }
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[display]);
   return CallDisplayFunction(device, display, &HWCDisplay::DestroyLayer, layer);
 }
 
@@ -411,7 +400,7 @@
   } else {
     std::string s {};
     for (int id = HWC_DISPLAY_PRIMARY; id <= HWC_DISPLAY_VIRTUAL; id++) {
-      SEQUENCE_WAIT_SCOPE_LOCK(locker_[id]);
+      SCOPE_LOCK(locker_[id]);
       if (hwc_session->hwc_display_[id]) {
         s += hwc_session->hwc_display_[id]->Dump();
       }
@@ -537,6 +526,11 @@
   bool notify_hotplug = false;
   auto status = HWC2::Error::BadDisplay;
   DTRACE_SCOPED();
+
+  if (display >= HWC_NUM_DISPLAY_TYPES) {
+    return HWC2_ERROR_BAD_DISPLAY;
+  }
+
   {
     SEQUENCE_EXIT_SCOPE_LOCK(locker_[display]);
     if (!device) {
@@ -556,6 +550,10 @@
     }
   }
 
+  if (status != HWC2::Error::None && status != HWC2::Error::NotValidated) {
+    SEQUENCE_CANCEL_SCOPE_LOCK(locker_[display]);
+  }
+
   // Handle Pending external display connection
   if (hwc_session->external_pending_connect_ && (display == HWC_DISPLAY_PRIMARY)) {
     Locker::ScopeLock lock_e(locker_[HWC_DISPLAY_EXTERNAL]);
@@ -611,28 +609,20 @@
 
 int32_t HWCSession::SetColorMode(hwc2_device_t *device, hwc2_display_t display,
                                  int32_t /*android_color_mode_t*/ int_mode) {
-  if (display >= HWC_NUM_DISPLAY_TYPES) {
-    return HWC2_ERROR_BAD_DISPLAY;
-  }
   if (int_mode < HAL_COLOR_MODE_NATIVE || int_mode > HAL_COLOR_MODE_DISPLAY_P3) {
     return HWC2_ERROR_BAD_PARAMETER;
   }
   auto mode = static_cast<android_color_mode_t>(int_mode);
-  SCOPE_LOCK(locker_[display]);
   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
 }
 
 int32_t HWCSession::SetColorTransform(hwc2_device_t *device, hwc2_display_t display,
                                       const float *matrix,
                                       int32_t /*android_color_transform_t*/ hint) {
-  if (display >= HWC_NUM_DISPLAY_TYPES) {
-    return HWC2_ERROR_BAD_DISPLAY;
-  }
   if (!matrix || hint < HAL_COLOR_TRANSFORM_IDENTITY ||
        hint > HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA) {
     return HWC2_ERROR_BAD_PARAMETER;
   }
-  SCOPE_LOCK(locker_[display]);
   android_color_transform_t transform_hint = static_cast<android_color_transform_t>(hint);
   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorTransform, matrix,
                                          transform_hint);
@@ -719,15 +709,9 @@
                                        visible);
 }
 
-int32_t HWCSession::SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display,
-                                   hwc2_layer_t layer, uint32_t z) {
-  if (display >= HWC_NUM_DISPLAY_TYPES) {
-    return HWC2_ERROR_BAD_DISPLAY;
-  }
-
-  SCOPE_LOCK(locker_[display]);
-
-  return CallDisplayFunction(device, display, &HWCDisplay::SetLayerZOrder, layer, z);
+static int32_t SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
+                              uint32_t z) {
+  return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetLayerZOrder, layer, z);
 }
 
 int32_t HWCSession::SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
@@ -770,7 +754,6 @@
     return HWC2_ERROR_UNSUPPORTED;
   }
 
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[display]);
   return CallDisplayFunction(device, display, &HWCDisplay::SetPowerMode, mode);
 }
 
@@ -824,9 +807,8 @@
     }
   }
 
-  // If validate fails, cancel the sequence lock so that other operations
-  // (such as Dump or SetPowerMode) may succeed without blocking on the condition
-  if (status == HWC2::Error::BadDisplay) {
+  // Sequence locking currently begins on Validate, so cancel the sequence lock on failures
+  if (status != HWC2::Error::None) {
     SEQUENCE_CANCEL_SCOPE_LOCK(locker_[display]);
   }
 
@@ -1410,14 +1392,10 @@
   auto mode = static_cast<android_color_mode_t>(input_parcel->readInt32());
   auto device = static_cast<hwc2_device_t *>(this);
 
-  if (display >= HWC_NUM_DISPLAY_TYPES) {
-    return -EINVAL;
-  }
-
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[display]);
   auto err = CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
   if (err != HWC2_ERROR_NONE)
     return -EINVAL;
+
   return 0;
 }
 
@@ -1426,14 +1404,10 @@
   auto mode = input_parcel->readInt32();
   auto device = static_cast<hwc2_device_t *>(this);
 
-  if (display >= HWC_NUM_DISPLAY_TYPES) {
-    return -EINVAL;
-  }
-
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[display]);
   auto err = CallDisplayFunction(device, display, &HWCDisplay::SetColorModeById, mode);
   if (err != HWC2_ERROR_NONE)
     return -EINVAL;
+
   return 0;
 }
 
@@ -1902,4 +1876,12 @@
                                      use_primary_res, &hwc_display_[disp_id]);
 }
 
+#ifdef DISPLAY_CONFIG_1_1
+// Methods from ::vendor::hardware::display::config::V1_1::IDisplayConfig follow.
+Return<int32_t> HWCSession::setDisplayAnimating(uint64_t display_id, bool animating ) {
+  return CallDisplayFunction(static_cast<hwc2_device_t *>(this), display_id,
+                             &HWCDisplay::SetDisplayAnimating, animating);
+}
+#endif
+
 }  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
index 84abd7b..8d25989 100644
--- a/sdm/libs/hwc2/hwc_session.h
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -94,6 +94,7 @@
       return HWC2_ERROR_BAD_DISPLAY;
     }
 
+    SCOPE_LOCK(locker_[display]);
     HWCSession *hwc_session = static_cast<HWCSession *>(device);
     auto status = HWC2::Error::BadDisplay;
     if (hwc_session->hwc_display_[display]) {
@@ -115,6 +116,7 @@
       return HWC2_ERROR_BAD_DISPLAY;
     }
 
+    SCOPE_LOCK(locker_[display]);
     HWCSession *hwc_session = static_cast<HWCSession *>(device);
     auto status = HWC2::Error::BadDisplay;
     if (hwc_session->hwc_display_[display]) {
@@ -147,8 +149,6 @@
                                   hwc2_function_pointer_t pointer);
   static int32_t SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
                                  buffer_handle_t buffer, int32_t releaseFence);
-  static int32_t SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
-                                uint32_t z);
   static int32_t SetPowerMode(hwc2_device_t *device, hwc2_display_t display, int32_t int_mode);
   static int32_t ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
                                  uint32_t *out_num_types, uint32_t *out_num_requests);
diff --git a/sdm/libs/hwc2/hwc_session_services.cpp b/sdm/libs/hwc2/hwc_session_services.cpp
index 23a2a6f..4cef884 100644
--- a/sdm/libs/hwc2/hwc_session_services.cpp
+++ b/sdm/libs/hwc2/hwc_session_services.cpp
@@ -510,14 +510,4 @@
   return Void();
 }
 
-#ifdef DISPLAY_CONFIG_1_1
-// Methods from ::vendor::hardware::display::config::V1_1::IDisplayConfig follow.
-Return<int32_t> HWCSession::setDisplayAnimating(uint64_t display_id, bool animating ) {
-  SEQUENCE_WAIT_SCOPE_LOCK(locker_[display_id]);
-  return CallDisplayFunction(static_cast<hwc2_device_t *>(this), display_id,
-                             &HWCDisplay::SetDisplayAnimating, animating);
-}
-#endif
-
-
 }  // namespace sdm