drm_hwcomposer: Rework CreateLayer/DestroyLayer

- Make HwcDisplay CreateLayer/DestroyLayer frontend-agnostic.
- Provide LayerId as an input for CreateLayer. It is necessary to add
  the HWC3 LayerLifecycleBatchCommand feature, where layer ID is
  generated by the client.

Change-Id: I317dcf22461fe4390ced9f0c0c780cffaa3b8f5d
Signed-off-by: Roman Stratiienko <r.stratiienko@gmail.com>
diff --git a/compositor/LayerData.h b/compositor/LayerData.h
index 962141f..90ae7be 100644
--- a/compositor/LayerData.h
+++ b/compositor/LayerData.h
@@ -30,6 +30,8 @@
 
 class DrmFbIdHandle;
 
+using ILayerId = int64_t;
+
 /* Rotation is defined in the clockwise direction */
 /* The flip is done before rotation */
 struct LayerTransform {
diff --git a/hwc2_device/HwcDisplay.cpp b/hwc2_device/HwcDisplay.cpp
index 9db384b..26a60be 100644
--- a/hwc2_device/HwcDisplay.cpp
+++ b/hwc2_device/HwcDisplay.cpp
@@ -330,8 +330,8 @@
 }
 
 auto HwcDisplay::AcceptValidatedComposition() -> void {
-  for (std::pair<const hwc2_layer_t, HwcLayer> &l : layers_) {
-    l.second.AcceptTypeChange();
+  for (auto &[_, layer] : layers_) {
+    layer.AcceptTypeChange();
   }
 }
 
@@ -480,20 +480,18 @@
   return SetActiveConfig(configs_.preferred_config_id);
 }
 
-HWC2::Error HwcDisplay::CreateLayer(hwc2_layer_t *layer) {
-  layers_.emplace(static_cast<hwc2_layer_t>(layer_idx_), HwcLayer(this));
-  *layer = static_cast<hwc2_layer_t>(layer_idx_);
-  ++layer_idx_;
-  return HWC2::Error::None;
+auto HwcDisplay::CreateLayer(ILayerId new_layer_id) -> bool {
+  if (layers_.count(new_layer_id) > 0)
+    return false;
+
+  layers_.emplace(new_layer_id, HwcLayer(this));
+
+  return true;
 }
 
-HWC2::Error HwcDisplay::DestroyLayer(hwc2_layer_t layer) {
-  if (!get_layer(layer)) {
-    return HWC2::Error::BadLayer;
-  }
-
-  layers_.erase(layer);
-  return HWC2::Error::None;
+auto HwcDisplay::DestroyLayer(ILayerId layer_id) -> bool {
+  auto count = layers_.erase(layer_id);
+  return count != 0;
 }
 
 HWC2::Error HwcDisplay::GetActiveConfig(hwc2_config_t *config) const {
@@ -742,15 +740,15 @@
   bool use_client_layer = false;
   uint32_t client_z_order = UINT32_MAX;
   std::map<uint32_t, HwcLayer *> z_map;
-  for (std::pair<const hwc2_layer_t, HwcLayer> &l : layers_) {
-    switch (l.second.GetValidatedType()) {
+  for (auto &[_, layer] : layers_) {
+    switch (layer.GetValidatedType()) {
       case HWC2::Composition::Device:
-        z_map.emplace(l.second.GetZOrder(), &l.second);
+        z_map.emplace(layer.GetZOrder(), &layer);
         break;
       case HWC2::Composition::Client:
         // Place it at the z_order of the lowest client layer
         use_client_layer = true;
-        client_z_order = std::min(client_z_order, l.second.GetZOrder());
+        client_z_order = std::min(client_z_order, layer.GetZOrder());
         break;
       default:
         continue;
diff --git a/hwc2_device/HwcDisplay.h b/hwc2_device/HwcDisplay.h
index c3a5f1a..7c24dea 100644
--- a/hwc2_device/HwcDisplay.h
+++ b/hwc2_device/HwcDisplay.h
@@ -101,7 +101,7 @@
   // To be called after SetDisplayProperties. Returns an empty vector if the
   // requested layers have been validated, otherwise the vector describes
   // the requested composition type changes.
-  using ChangedLayer = std::pair<hwc2_layer_t, HWC2::Composition>;
+  using ChangedLayer = std::pair<ILayerId, HWC2::Composition>;
   auto ValidateStagedComposition() -> std::vector<ChangedLayer>;
 
   // Mark previously validated properties as ready to present.
@@ -110,7 +110,7 @@
   // Present previously staged properties, and return fences to indicate when
   // the new content has been presented, and when the previous buffers have
   // been released.
-  using ReleaseFence = std::pair<hwc2_layer_t, SharedFd>;
+  using ReleaseFence = std::pair<ILayerId, SharedFd>;
   auto PresentStagedComposition(SharedFd &out_present_fence,
                                 std::vector<ReleaseFence> &out_release_fences)
       -> bool;
@@ -123,9 +123,10 @@
     frontend_private_data_ = std::move(data);
   }
 
+  auto CreateLayer(ILayerId new_layer_id) -> bool;
+  auto DestroyLayer(ILayerId layer_id) -> bool;
+
   // HWC2 Hooks - these should not be used outside of the hwc2 device.
-  HWC2::Error CreateLayer(hwc2_layer_t *layer);
-  HWC2::Error DestroyLayer(hwc2_layer_t layer);
   HWC2::Error GetActiveConfig(hwc2_config_t *config) const;
   HWC2::Error GetColorModes(uint32_t *num_modes, int32_t *modes);
   HWC2::Error GetDisplayAttribute(hwc2_config_t config, int32_t attribute,
@@ -168,7 +169,7 @@
   HWC2::Error SetColorTransform(const float *matrix, int32_t hint);
   HWC2::Error SetPowerMode(int32_t mode);
   HWC2::Error SetVsyncEnabled(int32_t enabled);
-  HwcLayer *get_layer(hwc2_layer_t layer) {
+  HwcLayer *get_layer(ILayerId layer) {
     auto it = layers_.find(layer);
     if (it == layers_.end())
       return nullptr;
@@ -201,7 +202,7 @@
     return hwc_;
   }
 
-  std::map<hwc2_layer_t, HwcLayer> &layers() {
+  auto layers() -> std::map<ILayerId, HwcLayer> & {
     return layers_;
   }
 
@@ -269,9 +270,7 @@
   const hwc2_display_t handle_;
   HWC2::DisplayType type_;
 
-  uint32_t layer_idx_{};
-
-  std::map<hwc2_layer_t, HwcLayer> layers_;
+  std::map<ILayerId, HwcLayer> layers_;
   HwcLayer client_layer_;
   std::unique_ptr<HwcLayer> writeback_layer_;
   uint16_t virtual_disp_width_{};
diff --git a/hwc2_device/hwc2_device.cpp b/hwc2_device/hwc2_device.cpp
index 72d0aa9..c1c5157 100644
--- a/hwc2_device/hwc2_device.cpp
+++ b/hwc2_device/hwc2_device.cpp
@@ -53,6 +53,8 @@
  public:
   std::vector<HwcDisplay::ReleaseFence> release_fences;
   std::vector<HwcDisplay::ChangedLayer> changed_layers;
+
+  int64_t next_layer_id = 1;
 };
 
 static auto GetHwc2DeviceDisplay(HwcDisplay &display)
@@ -267,6 +269,37 @@
 }
 
 /* Display functions */
+static int32_t CreateLayer(hwc2_device_t *device, hwc2_display_t display,
+                           hwc2_layer_t *out_layer) {
+  ALOGV("CreateLayer");
+  LOCK_COMPOSER(device);
+  GET_DISPLAY(display);
+
+  auto hwc2display = GetHwc2DeviceDisplay(*idisplay);
+
+  if (!idisplay->CreateLayer(hwc2display->next_layer_id)) {
+    return static_cast<int32_t>(HWC2::Error::BadDisplay);
+  }
+
+  *out_layer = (hwc2_layer_t)hwc2display->next_layer_id;
+  hwc2display->next_layer_id++;
+
+  return 0;
+}
+
+static int32_t DestroyLayer(hwc2_device_t *device, hwc2_display_t display,
+                            hwc2_layer_t layer) {
+  ALOGV("DestroyLayer");
+  LOCK_COMPOSER(device);
+  GET_DISPLAY(display);
+
+  if (!idisplay->DestroyLayer((ILayerId)layer)) {
+    return static_cast<int32_t>(HWC2::Error::BadLayer);
+  }
+
+  return 0;
+}
+
 static int32_t GetDisplayRequests(hwc2_device_t * /*device*/,
                                   hwc2_display_t /*display*/,
                                   int32_t * /* out_display_requests */,
@@ -763,13 +796,9 @@
     case HWC2::FunctionDescriptor::AcceptDisplayChanges:
       return (hwc2_function_pointer_t)AcceptDisplayChanges;
     case HWC2::FunctionDescriptor::CreateLayer:
-      return ToHook<HWC2_PFN_CREATE_LAYER>(
-          DisplayHook<decltype(&HwcDisplay::CreateLayer),
-                      &HwcDisplay::CreateLayer, hwc2_layer_t *>);
+      return (hwc2_function_pointer_t)CreateLayer;
     case HWC2::FunctionDescriptor::DestroyLayer:
-      return ToHook<HWC2_PFN_DESTROY_LAYER>(
-          DisplayHook<decltype(&HwcDisplay::DestroyLayer),
-                      &HwcDisplay::DestroyLayer, hwc2_layer_t>);
+      return (hwc2_function_pointer_t)DestroyLayer;
     case HWC2::FunctionDescriptor::GetActiveConfig:
       return ToHook<HWC2_PFN_GET_ACTIVE_CONFIG>(
           DisplayHook<decltype(&HwcDisplay::GetActiveConfig),
diff --git a/hwc3/ComposerClient.cpp b/hwc3/ComposerClient.cpp
index a1a1e26..09d8817 100644
--- a/hwc3/ComposerClient.cpp
+++ b/hwc3/ComposerClient.cpp
@@ -494,13 +494,16 @@
     return ToBinderStatus(hwc3::Error::kBadDisplay);
   }
 
-  hwc2_layer_t hwc2_layer_id = 0;
-  auto err = Hwc2toHwc3Error(display->CreateLayer(&hwc2_layer_id));
-  if (err != hwc3::Error::kNone) {
-    return ToBinderStatus(err);
+  auto hwc3display = DrmHwcThree::GetHwc3Display(*display);
+
+  if (!display->CreateLayer(hwc3display->next_layer_id)) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
   }
 
-  *layer_id = Hwc2LayerToHwc3(hwc2_layer_id);
+  *layer_id = hwc3display->next_layer_id;
+
+  hwc3display->next_layer_id++;
+
   return ndk::ScopedAStatus::ok();
 }
 
@@ -534,12 +537,11 @@
     return ToBinderStatus(hwc3::Error::kBadDisplay);
   }
 
-  auto err = Hwc2toHwc3Error(display->DestroyLayer(Hwc3LayerToHwc2(layer_id)));
-  if (err != hwc3::Error::kNone) {
-    return ToBinderStatus(err);
+  if (!display->DestroyLayer(layer_id)) {
+    return ToBinderStatus(hwc3::Error::kBadLayer);
   }
 
-  return ToBinderStatus(err);
+  return ToBinderStatus(hwc3::Error::kNone);
 }
 
 ndk::ScopedAStatus ComposerClient::destroyVirtualDisplay(int64_t display_id) {
@@ -698,8 +700,7 @@
         changed_layers = display->ValidateStagedComposition();
     DisplayChanges changes{};
     for (auto [layer_id, composition_type] : changed_layers) {
-      changes.AddLayerCompositionChange(command.display,
-                                        Hwc2LayerToHwc3(layer_id),
+      changes.AddLayerCompositionChange(command.display, layer_id,
                                         static_cast<Composition>(
                                             composition_type));
     }
@@ -743,8 +744,7 @@
 
     std::unordered_map<int64_t, unique_fd> hal_release_fences;
     for (const auto& [layer_id, release_fence] : release_fences) {
-      hal_release_fences[Hwc2LayerToHwc3(layer_id)] =  //
-          unique_fd(::android::DupFd(release_fence));
+      hal_release_fences[layer_id] = unique_fd(::android::DupFd(release_fence));
     }
     cmd_result_writer_->AddReleaseFence(display_id, hal_release_fences);
   }
diff --git a/hwc3/DrmHwcThree.h b/hwc3/DrmHwcThree.h
index 44168aa..10470ea 100644
--- a/hwc3/DrmHwcThree.h
+++ b/hwc3/DrmHwcThree.h
@@ -26,6 +26,8 @@
 class Hwc3Display : public ::android::FrontendDisplayBase {
  public:
   bool must_validate = false;
+
+  int64_t next_layer_id = 1;
 };
 
 class DrmHwcThree : public ::android::DrmHwc {
diff --git a/hwc3/Utils.h b/hwc3/Utils.h
index 642c777..e892832 100644
--- a/hwc3/Utils.h
+++ b/hwc3/Utils.h
@@ -57,12 +57,6 @@
   return ToBinderStatus(Hwc2toHwc3Error(error));
 }
 
-// ID conversion. HWC2 uses typedef'd unsigned integer types while HWC3 uses
-// signed integer types. static_cast in between these.
-inline int64_t Hwc2LayerToHwc3(hwc2_layer_t layer) {
-  return static_cast<int64_t>(layer);
-}
-
 inline int64_t Hwc2DisplayToHwc3(hwc2_display_t display) {
   return static_cast<int64_t>(display);
 }
@@ -71,10 +65,6 @@
   return static_cast<int32_t>(config_id);
 }
 
-inline hwc2_layer_t Hwc3LayerToHwc2(int64_t layer) {
-  return static_cast<hwc2_layer_t>(layer);
-}
-
 inline hwc2_display_t Hwc3DisplayToHwc2(int64_t display) {
   return static_cast<hwc2_display_t>(display);
 }