drm_hwcomposer: Cursor plane binding

This change adds cursor plane binding into DrmDisplayPipeline.
The signature of DrmDisplayPipeline::GetUsablePlanes is updated
to return a pair where the second element points to the bound
cursor plane (if it exists), and the first element points to
all other planes.

Change-Id: Ic6a623b10383b7dd0a0c2e79fc2d87329ebc6214
Signed-off-by: Andrew Wolfers <aswolfers@google.com>
diff --git a/drm/DrmDisplayPipeline.cpp b/drm/DrmDisplayPipeline.cpp
index 7588ee2..8062b2c 100644
--- a/drm/DrmDisplayPipeline.cpp
+++ b/drm/DrmDisplayPipeline.cpp
@@ -65,18 +65,21 @@
   }
 
   std::vector<DrmPlane *> primary_planes;
-  std::vector<DrmPlane *> overlay_planes;
 
   /* Attach necessary resources */
   auto display_planes = std::vector<DrmPlane *>();
   for (const auto &plane : dev.GetPlanes()) {
     if (plane->IsCrtcSupported(crtc)) {
-      if (plane->GetType() == DRM_PLANE_TYPE_PRIMARY) {
-        primary_planes.emplace_back(plane.get());
-      } else if (plane->GetType() == DRM_PLANE_TYPE_OVERLAY) {
-        overlay_planes.emplace_back(plane.get());
-      } else {
-        ALOGI("Ignoring cursor plane %d", plane->GetId());
+      switch (plane->GetType()) {
+        case DRM_PLANE_TYPE_PRIMARY:
+          primary_planes.emplace_back(plane.get());
+          break;
+        case DRM_PLANE_TYPE_OVERLAY:
+        case DRM_PLANE_TYPE_CURSOR:
+          break;
+        default:
+          ALOGE("Unknown type for plane %d", plane->GetId());
+          break;
       }
     }
   }
@@ -158,25 +161,34 @@
   return {};
 }
 
-auto DrmDisplayPipeline::GetUsablePlanes()
-    -> std::vector<std::shared_ptr<BindingOwner<DrmPlane>>> {
-  std::vector<std::shared_ptr<BindingOwner<DrmPlane>>> planes;
+auto DrmDisplayPipeline::GetUsablePlanes() -> UsablePlanes {
+  UsablePlanes pair;
+  auto &[planes, cursor] = pair;
+
   planes.emplace_back(primary_plane);
 
-  if (Properties::UseOverlayPlanes()) {
-    for (const auto &plane : device->GetPlanes()) {
-      if (plane->IsCrtcSupported(*crtc->Get())) {
-        if (plane->GetType() == DRM_PLANE_TYPE_OVERLAY) {
-          auto op = plane->BindPipeline(this, true);
-          if (op) {
-            planes.emplace_back(op);
-          }
+  for (const auto &plane : device->GetPlanes()) {
+    if (plane->IsCrtcSupported(*crtc->Get())) {
+      if (Properties::UseOverlayPlanes() &&
+          plane->GetType() == DRM_PLANE_TYPE_OVERLAY) {
+        auto op = plane->BindPipeline(this, true);
+        if (op) {
+          planes.emplace_back(op);
+        }
+      } else if (plane->GetType() == DRM_PLANE_TYPE_CURSOR) {
+        if (cursor) {
+          ALOGW(
+              "Encountered multiple cursor planes for CRTC %d. Ignoring "
+              "plane %d",
+              crtc->Get()->GetId(), plane->GetId());
+        } else {
+          cursor = plane->BindPipeline(this, true);
         }
       }
     }
   }
 
-  return planes;
+  return pair;
 }
 
 DrmDisplayPipeline::~DrmDisplayPipeline() {
diff --git a/drm/DrmDisplayPipeline.h b/drm/DrmDisplayPipeline.h
index cf64a36..0d05288 100644
--- a/drm/DrmDisplayPipeline.h
+++ b/drm/DrmDisplayPipeline.h
@@ -67,12 +67,15 @@
   B *const bindable_;
 };
 
+using UsablePlanes = std::pair<
+    std::vector<std::shared_ptr<BindingOwner<DrmPlane>>>,
+    std::shared_ptr<BindingOwner<DrmPlane>>>;
+
 struct DrmDisplayPipeline {
   static auto CreatePipeline(DrmConnector &connector)
       -> std::unique_ptr<DrmDisplayPipeline>;
 
-  auto GetUsablePlanes()
-      -> std::vector<std::shared_ptr<BindingOwner<DrmPlane>>>;
+  auto GetUsablePlanes() -> UsablePlanes;
 
   ~DrmDisplayPipeline();