[xserver] xf86-video-modesetting: Add cursor plane to leased objects when creating DRM lease

Submitted by Lu, Kechen on May 28, 2019, 7:03 a.m.

Details

Message ID 20190528070345.10937-1-kechen.lu@intel.com
State New
Headers show
Series "xf86-video-modesetting: Add cursor plane to leased objects when creating DRM lease" ( rev: 1 ) in X.org

Not browsing as part of any series.

Commit Message

Lu, Kechen May 28, 2019, 7:03 a.m.
Under the circumstances of enabling universal planes in the userspace,
the kernel commit(204f640) adds the check and forbids the DRM leasing
of implicit planes(e.g. cursor planes). However, in the Xorg xserver
modesetting driver, it only defaultly adds the primary plane to leased
resource objs. So here we want to add the cursor plane besides primary
when drmmode_create_lease().

Signed-off-by: Kechen Lu <kechen.lu@intel.com>
Signed-off-by: Tina Zhang <tina.zhang@intel.com>
---
 .../drivers/modesetting/drmmode_display.c     | 99 ++++++++++++++++++-
 1 file changed, 97 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index cb48aa46b..d6d26d387 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -2028,6 +2028,99 @@  populate_format_modifiers(xf86CrtcPtr crtc, const drmModePlane *kplane,
     return TRUE;
 }
 
+static uint32_t
+drmmode_crtc_get_cursor_plane(xf86CrtcPtr crtc)
+{
+    drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+    drmmode_ptr drmmode = drmmode_crtc->drmmode;
+    drmModePlaneRes *kplane_res;
+    drmModePlane *kplane;
+    drmModeRes *res;
+    drmModeObjectProperties *props;
+    uint32_t i, type, pipe = 0, cursor_plane_id = 0;
+
+    drmmode_prop_enum_info_rec plane_type_enums[] = {
+        [DRMMODE_PLANE_TYPE_PRIMARY] = {
+            .name = "Primary",
+            .valid = FALSE,
+        },
+        [DRMMODE_PLANE_TYPE_OVERLAY] = {
+            .name = "Overlay",
+            .valid = FALSE,
+        },
+        [DRMMODE_PLANE_TYPE_CURSOR] = {
+            .name = "Cursor",
+            .valid = FALSE,
+        },
+    };
+    drmmode_prop_info_rec plane_props[] = {
+        [DRMMODE_PLANE_TYPE] = {
+            .name = "type",
+            .enum_values = plane_type_enums,
+            .num_enum_values = DRMMODE_PLANE_TYPE__COUNT,
+        },
+    };
+
+    res = drmModeGetResources(drmmode->fd);
+    if (!res) {
+        xf86DrvMsg(drmmode->scrn->scrnIndex, X_ERROR,
+                   "cannot retrieve DRM resources: %s\n",
+		   strerror(errno));
+        goto ret;
+    }
+
+    for (i = 0; i < res->count_crtcs; i++) {
+        if (res->crtcs[i] == drmmode_crtc->mode_crtc->crtc_id) {
+	    pipe = i;
+	    break;
+        }
+    }
+
+    kplane_res = drmModeGetPlaneResources(drmmode->fd);
+    if (!kplane_res) {
+        xf86DrvMsg(drmmode->scrn->scrnIndex, X_ERROR,
+                   "failed to get plane resources: %s\n", strerror(errno));
+        goto free_res;
+    }
+
+    for (i = 0; i < kplane_res->count_planes; i++) {
+        int plane_id;
+
+        kplane = drmModeGetPlane(drmmode->fd, kplane_res->planes[i]);
+        if (!kplane)
+            continue;
+
+        plane_id = kplane->plane_id;
+
+        props = drmModeObjectGetProperties(drmmode->fd, plane_id,
+                                           DRM_MODE_OBJECT_PLANE);
+        if (!props) {
+            xf86DrvMsg(drmmode->scrn->scrnIndex, X_ERROR,
+                    "couldn't get plane properties\n");
+            drmModeFreePlane(kplane);
+            continue;
+        }
+
+        drmmode_prop_info_update(drmmode, plane_props, 1, props);
+
+        type = drmmode_prop_get_value(&plane_props[DRMMODE_PLANE_TYPE],
+                                      props, DRMMODE_PLANE_TYPE__COUNT);
+
+        if ((kplane->possible_crtcs & (1 << pipe)) &&
+            (type == DRMMODE_PLANE_TYPE_CURSOR)) {
+            cursor_plane_id = plane_id;
+        }
+        drmModeFreePlane(kplane);
+        drmModeFreeObjectProperties(props);
+    }
+
+    drmModeFreePlaneResources(kplane_res);
+free_res:
+    drmModeFreeResources(res);
+ret:
+    return cursor_plane_id;
+}
+
 static void
 drmmode_crtc_create_planes(xf86CrtcPtr crtc, int num)
 {
@@ -3259,7 +3352,7 @@  drmmode_create_lease(RRLeasePtr lease, int *fd)
     nobjects = ncrtc + noutput;
 
     if (ms->atomic_modeset)
-        nobjects += ncrtc; /* account for planes as well */
+        nobjects += ncrtc * 2; /* account for planes (primary and cursor plane) as well */
 
     if (nobjects == 0)
         return BadValue;
@@ -3283,8 +3376,10 @@  drmmode_create_lease(RRLeasePtr lease, int *fd)
         drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 
         objects[i++] = drmmode_crtc->mode_crtc->crtc_id;
-        if (ms->atomic_modeset)
+        if (ms->atomic_modeset) {
             objects[i++] = drmmode_crtc->plane_id;
+            objects[i++] = drmmode_crtc_get_cursor_plane(crtc);
+	}
     }
 
     /* Add connector ids */