[PATCH xf86-video-ati 2/2] Don't try DRI2/Present flipping while the HW cursor can't be used

Michel Dänzer michel at daenzer.net
Fri Mar 18 07:28:33 UTC 2016


From: Michel Dänzer <michel.daenzer at amd.com>

Flipping doesn't interact correctly with SW cursor: A flip makes the SW
cursor disappear. It will only appear again when the cursor is moved,
but it will be surrounded by corruption, because the SW cursor code
will restore stale screen contents at the old cursor location before
drawing the cursor at the new location.

Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---
 src/drmmode_display.c | 15 ++++++++++++++-
 src/radeon.h          |  5 +++++
 src/radeon_dri2.c     |  1 +
 src/radeon_kms.c      |  7 +++++--
 src/radeon_present.c  |  3 +++
 5 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 36a7957..635f71c 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -857,7 +857,20 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 		}
 	}
 
-	if (drmmode_can_use_hw_cursor(crtc))
+	/* Compute index of this CRTC into xf86_config->crtc */
+	for (i = 0; i < xf86_config->num_crtc; i++) {
+		if (xf86_config->crtc[i] != crtc)
+			continue;
+
+		if (!crtc->enabled || drmmode_can_use_hw_cursor(crtc))
+			info->hwcursor_disabled &= ~(1 << i);
+		else
+			info->hwcursor_disabled |= 1 << i;
+
+		break;
+	}
+
+	if (!info->hwcursor_disabled)
 		xf86_reload_cursors(pScreen);
 
 done:
diff --git a/src/radeon.h b/src/radeon.h
index fe26df4..b9afd8e 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -547,6 +547,11 @@ typedef struct {
     int cursor_w;
     int cursor_h;
 
+    /* If bit n of this field is set, xf86_config->crtc[n] currently can't
+     * use the HW cursor
+     */
+    unsigned hwcursor_disabled;
+
 #ifdef USE_GLAMOR
     struct {
 	CreateGCProcPtr SavedCreateGC;
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 657e6a6..474611a 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -823,6 +823,7 @@ can_flip(ScrnInfoPtr pScrn, DrawablePtr draw,
 
     return draw->type == DRAWABLE_WINDOW &&
 	   info->allowPageFlip &&
+	   !info->hwcursor_disabled &&
 	   !info->drmmode.present_flipping &&
 	   pScrn->vtSema &&
 	   DRI2CanFlip(draw) &&
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 8048c95..d89c376 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -1285,15 +1285,18 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
 	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TearFree enabled\n");
 
     if (info->dri2.pKernelDRMVersion->version_minor >= 8) {
+	Bool sw_cursor = xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE);
+
 	info->allowPageFlip = xf86ReturnOptValBool(info->Options,
 						   OPTION_PAGE_FLIP, TRUE);
 
-	if (info->tear_free || info->shadow_primary) {
+	if (sw_cursor || info->tear_free || info->shadow_primary) {
 	    xf86DrvMsg(pScrn->scrnIndex,
 		       info->allowPageFlip ? X_WARNING : X_DEFAULT,
 		       "KMS Pageflipping: disabled%s\n",
 		       info->allowPageFlip ?
-		       " because of ShadowPrimary/TearFree" : "");
+		       (sw_cursor ? " because of SWcursor" :
+			" because of ShadowPrimary/TearFree") : "");
 	    info->allowPageFlip = FALSE;
 	} else {
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
diff --git a/src/radeon_present.c b/src/radeon_present.c
index e0a549d..3be3360 100644
--- a/src/radeon_present.c
+++ b/src/radeon_present.c
@@ -244,6 +244,9 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap,
     if (!info->allowPageFlip)
 	return FALSE;
 
+    if (info->hwcursor_disabled)
+	return FALSE;
+
     if (!sync_flip)
 	return FALSE;
 
-- 
2.7.0



More information about the xorg-driver-ati mailing list