xf86-video-intel: src/sna/sna_display.c src/sna/sna.h

Chris Wilson ickle at kemper.freedesktop.org
Tue May 19 04:52:45 PDT 2015


 src/sna/sna.h         |    3 ++-
 src/sna/sna_display.c |   38 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 39 insertions(+), 2 deletions(-)

New commits:
commit e617c1941c4e5ee90b69221013aab799eace925d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue May 19 12:14:24 2015 +0100

    sna: Force restoration of SW cursor after HW cursor fails
    
    In order to reset the SW cursor, we need to call xf86CursorSetCursor.
    However, the parameters we need to call SetCursor with are not exposed
    we need to be a little tricky and call a pair of functions that will
    save and then restore the cursor.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 374754b..8a40580 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -322,7 +322,8 @@ struct sna {
 		uint32_t fg, bg;
 		int size;
 
-		int active;
+		bool disable;
+		bool active;
 		int last_x;
 		int last_y;
 
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index e62c6be..daa1402 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -5215,6 +5215,28 @@ static inline void sigio_unblock(int was_blocked)
 }
 #endif
 
+static void __restore_swcursor(ScrnInfoPtr scrn)
+{
+	DBG(("%s: attempting to restore SW cursor\n", __FUNCTION__));
+	scrn->EnableDisableFBAccess(scrn, FALSE);
+	scrn->EnableDisableFBAccess(scrn, TRUE);
+
+	RemoveBlockAndWakeupHandlers((BlockHandlerProcPtr)__restore_swcursor,
+				     (WakeupHandlerProcPtr)NoopDDA,
+				     scrn);
+}
+
+static void restore_swcursor(struct sna *sna)
+{
+	/* XXX Force the cursor to be restored (avoiding recursion) */
+	FreeCursor(sna->cursor.ref, None);
+	sna->cursor.ref = NULL;
+
+	RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)__restore_swcursor,
+				       (WakeupHandlerProcPtr)NoopDDA,
+				       sna->scrn);
+}
+
 static void
 sna_show_cursors(ScrnInfoPtr scrn)
 {
@@ -5268,10 +5290,17 @@ sna_show_cursors(ScrnInfoPtr scrn)
 			cursor->ref++;
 			sna_crtc->cursor = cursor;
 			sna_crtc->last_cursor_size = cursor->size;
+		} else {
+			ERR(("%s: failed to show cursor on CRTC:%d [pipe=%d], disabling hwcursor\n",
+			     __FUNCTION__, sna_crtc_id(crtc), sna_crtc_pipe(crtc)));
+			sna->cursor.disable = true;
 		}
 	}
 	sigio_unblock(sigio);
 	sna->cursor.active = true;
+
+	if (unlikely(sna->cursor.disable))
+		restore_swcursor(sna);
 }
 
 static void
@@ -5493,14 +5522,17 @@ disable:
 		} else {
 			ERR(("%s: failed to update cursor on CRTC:%d [pipe=%d], disabling hwcursor\n",
 			     __FUNCTION__, sna_crtc_id(crtc), sna_crtc_pipe(crtc)));
-			sna_crtc->hwcursor = false;
 			/* XXX How to force switch back to SW cursor?
 			 * Right now we just want until the next cursor image
 			 * change, which is fairly frequent.
 			 */
+			sna->cursor.disable = true;
 		}
 	}
 	sigio_unblock(sigio);
+
+	if (unlikely(sna->cursor.disable))
+		restore_swcursor(sna);
 }
 
 #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,902,2)
@@ -5596,6 +5628,9 @@ sna_use_hw_cursor(ScreenPtr screen, CursorPtr cursor)
 	DBG(("%s (%dx%d)?\n", __FUNCTION__,
 	     cursor->bits->width, cursor->bits->height));
 
+	if (sna->cursor.disable)
+		return FALSE;
+
 	/* cursors are invariant */
 	if (cursor == sna->cursor.ref)
 		return TRUE;
@@ -6453,6 +6488,7 @@ sna_crtc_config_notify(ScreenPtr screen)
 	}
 
 	update_flush_interval(sna);
+	sna->cursor.disable = false; /* Reset HW cursor until the next fail */
 	sna_cursors_reload(sna);
 
 	probe_capabilities(sna);


More information about the xorg-commit mailing list