[PATCH 4/4] modesetting: Fix hw cursor check at the first call

Takashi Iwai tiwai at suse.de
Mon Feb 16 08:00:55 PST 2015

With the previous patch, the modesetting driver can now return whether
the driver supports hw cursor.  However, it alone doesn't suffice,
unfortunately. drmmode_load_cursor_argb_check() is called in the
following chain:

    -> xf86SetCursor()
       -> xf86DriverLoadCursorARGB()
         -> xf86_load_cursor_argb()
           -> xf86_crtc_load_cursor_argb()
             -> drmmode_load_cursor_argb_check()

*but* at first with drmmode_crtc->cursor_up = FALSE.  Then the
function doesn't actually set the cursor but returns TRUE
unconditionally.  The actual call of drmmode_set_cursor() is done at
first via the show_cursor callback, and there is no check of sw cursor
fallback any longer at this place. Since it's called only once per
cursor setup, so the xserver still thinks as if the hw cursor is

This patch is an ad hoc fix to correct the behavior somehow: it does
call drmmode_set_cursor() at the very first time even if cursor_up is
FALSE, then quickly hides again.  In that way, whether the hw cursor
is supported is evaluated in the right place at the right time.

Of course, it might be more elegant if we have a more proper mechanism
to fall back to sw cursor at any call path.  But it'd need more
rework, so I leave this workaround as is for now.

Signed-off-by: Takashi Iwai <tiwai at suse.de>
 hw/xfree86/drivers/modesetting/drmmode_display.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 25e4d367de46..707c336b06a7 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -457,6 +457,7 @@ drmmode_load_cursor_argb_check(xf86CrtcPtr crtc, CARD32 *image)
     drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
     int i;
     uint32_t *ptr;
+    static Bool first_time = TRUE;
     /* cursor should be mapped already */
     ptr = (uint32_t *) (drmmode_crtc->cursor_bo->ptr);
@@ -464,8 +465,13 @@ drmmode_load_cursor_argb_check(xf86CrtcPtr crtc, CARD32 *image)
     for (i = 0; i < ms->cursor_width * ms->cursor_height; i++)
         ptr[i] = image[i];      // cpu_to_le32(image[i]);
-    if (drmmode_crtc->cursor_up)
-        return drmmode_set_cursor(crtc);
+    if (drmmode_crtc->cursor_up || first_time) {
+        Bool ret = drmmode_set_cursor(crtc);
+        if (!drmmode_crtc->cursor_up)
+	    drmmode_hide_cursor(crtc);
+        first_time = FALSE;
+        return ret;
+    }
     return TRUE;

More information about the xorg-devel mailing list