drm_hwcomposer: Cursor plane buffer validation

This change adds a check to DrmPlane::IsValidForLayer which
checks cursor-plane-specific requirements that the layer's
buffer has an acceptable size according to either the plane's
SIZE_HINTS or the device's DRM_CAP_CURSOR_{WIDTH|HEIGHT}
properties.

Change-Id: Ic88699996c6616e8da7a4527b03a12c12422fb8f
Signed-off-by: Andrew Wolfers <aswolfers@google.com>
diff --git a/drm/DrmPlane.cpp b/drm/DrmPlane.cpp
index 235f59d..0fe060d 100644
--- a/drm/DrmPlane.cpp
+++ b/drm/DrmPlane.cpp
@@ -214,6 +214,13 @@
     return false;
   }
 
+  if (type_ == DRM_PLANE_TYPE_CURSOR &&
+      !IsBufferValidForCursorPlane(layer->bi.value())) {
+    ALOGV("Buffer size %dx%d is not supported by cursor plane %d",
+          layer->bi->width, layer->bi->height, GetId());
+    return false;
+  }
+
   return true;
 }
 
@@ -348,4 +355,21 @@
   return true;
 }
 
+bool DrmPlane::HasCursorSizeConstraints() const {
+  return drm_->GetCapCursorSize().has_value() || !size_hints_.empty();
+}
+
+bool DrmPlane::IsBufferValidForCursorPlane(const BufferInfo &bi) const {
+  if (std::find_if(size_hints_.begin(), size_hints_.end(),
+                   [&](const auto &hint) -> bool {
+                     return bi.width == hint.width && bi.height == hint.height;
+                   }) != size_hints_.end()) {
+    return true;
+  }
+
+  const auto &cap_size = drm_->GetCapCursorSize();
+  return cap_size.has_value() && bi.width == cap_size->first &&
+         bi.height == cap_size->second;
+}
+
 }  // namespace android
diff --git a/drm/DrmPlane.h b/drm/DrmPlane.h
index b744b2d..2fa6388 100644
--- a/drm/DrmPlane.h
+++ b/drm/DrmPlane.h
@@ -65,6 +65,8 @@
     return plane_->plane_id;
   }
 
+  bool HasCursorSizeConstraints() const;
+
  private:
   DrmPlane(DrmDevice &dev, DrmModePlaneUnique plane)
       : drm_(&dev), plane_(std::move(plane)){};
@@ -76,6 +78,7 @@
   auto Init() -> int;
   auto GetPlaneProperty(const char *prop_name, DrmProperty &property,
                         Presence presence = Presence::kMandatory) -> bool;
+  bool IsBufferValidForCursorPlane(const BufferInfo &bi) const;
 
   uint32_t type_{};