[PATCH xserver v2] xfree86: Immediately handle failure to set HW cursor

Alexandre Courbot acourbot at nvidia.com
Thu Apr 7 06:43:50 UTC 2016


Hello Michael,

On 04/06/2016 02:40 AM, Michael Thayer wrote:
> On 04.04.2016 22:09, Michael Thayer wrote:
>> Hello,
>>
>> Please excuse the top posting.  Tested this in a dual-head non-mirrored
>> virtual machine and hit the following problem: xf86CursorSetCursor() in
>> hw/xfree86/ramdac/xf86Cursor.c calls xf86SetCursor() which fails because
>> the cursor is not visible on one of the two screens, and falls back to
>> software cursor rendering as a result.  Perhaps xf86_crtc_show_cursor()
>> should return TRUE if crtc->cursor_shown is FALSE?
>>
>> I'm afraid I will be away from the computer again for a few weeks, so it
>> will be a while before I can test again.
>
> I would suggest changing this function as follows:
>
> static Bool
> xf86_crtc_show_cursor(xf86CrtcPtr crtc)
> {
>      if (!crtc->cursor_shown && crtc->cursor_in_range) {
>          crtc->cursor_shown = TRUE;
>          if (crtc->funcs->show_cursor_check) {
>              return crtc->funcs->show_cursor_check(crtc);
>          } else {
>              crtc->funcs->show_cursor(crtc);
>          }
>      }
>      return TRUE;
> }
>
> As mentioned previously, crtc->cursor_shown will be FALSE if the cursor
> is hidden on a particular crtc, and that is not an error. Also,
> xf86_crtc_show_cursor() is called from xf86_crtc_set_cursor_position()
> without checking the return value, sometimes with cursor_shown FALSE
> when the cursor moves from one screen to another, and if we keep
> cursor_shown FALSE we will get a call to the kernel driver every time
> the position changes.

Thanks for catching that! Indeed I clearly overlooked the multi-head case.

Your proposed function looks fine, but maybe cursor_shown should not be 
set to TRUE if show_cursor_check fails? How about the following:

static Bool
xf86_crtc_show_cursor(xf86CrtcPtr crtc)
{
     if (!crtc->cursor_in_range)
         return TRUE;

     if (!crtc->cursor_shown) {
         if (crtc->funcs->show_cursor_check) {
             crtc->cursor_shown = crtc->funcs->show_cursor_check(crtc);
         } else {
             crtc->funcs->show_cursor(crtc);
             crtc->cursor_shown = TRUE;
         }
     }

     return crtc->cursor_shown;
}

Basically we want to return TRUE if the cursor is not supposed to be 
visible on this CRTC, which is what the first two lines do.

> However, I also just realised that modesetting still does not implement
> load_cursor_argb_check() - I really don't know how I forgot that.
> Perhaps just implementing that would solve your problem?

Ah, we discussed this in a previous email actually (see 
https://patchwork.freedesktop.org/patch/77422/ ). IIRC the problem with 
relying on load_cursor_argb_check() is that drmmode_show_cursor()'s 
errors are still not caught, which is ultimately what we need to do to 
fix this issue.

I will send a v3 with the fixed xf86_crtc_show_cursor() function - 
thanks again!

Alex.



More information about the xorg-devel mailing list