[PATCH xf86-video-ati 3/3] Allow DRI page flipping when some CRTCs use separate scanout buffers

Michel Dänzer michel at daenzer.net
Mon Jul 31 09:48:08 UTC 2017


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

As long as the CRTC we're synchronizing to doesn't.

Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---
 man/radeon.man        |  2 +-
 src/drmmode_display.c |  2 +-
 src/drmmode_display.h |  4 +++-
 src/radeon_dri2.c     | 18 +++++++-----------
 src/radeon_present.c  | 12 ++++--------
 5 files changed, 16 insertions(+), 22 deletions(-)

diff --git a/man/radeon.man b/man/radeon.man
index 3e1723f21..1e9a7bebf 100644
--- a/man/radeon.man
+++ b/man/radeon.man
@@ -285,7 +285,7 @@ Set the default value of the per-output 'TearFree' property, which controls
 tearing prevention using the hardware page flipping mechanism. TearFree is
 on for any CRTC associated with one or more outputs with TearFree on. Two
 separate scanout buffers need to be allocated for each CRTC with TearFree
-on. While TearFree is on for any CRTC, it currently prevents clients from using
+on. While TearFree is on for any CRTC, it may prevent clients from using
 DRI page flipping. If this option is set, the default value of the property
 is 'on' or 'off' accordingly. If this option isn't set, the default value of the
 property is
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 6be6513af..d8031875b 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -3007,7 +3007,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
 	for (i = 0; i < config->num_crtc; i++) {
 		crtc = config->crtc[i];
 
-		if (!crtc->enabled)
+		if (!drmmode_crtc_can_flip(crtc))
 			continue;
 
 		flipdata->flip_count++;
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index 4378be86f..f859377c2 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -146,7 +146,9 @@ drmmode_crtc_can_flip(xf86CrtcPtr crtc)
     drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 
     return crtc->enabled &&
-	drmmode_crtc->pending_dpms_mode == DPMSModeOn;
+	drmmode_crtc->pending_dpms_mode == DPMSModeOn &&
+	!drmmode_crtc->rotate.bo &&
+	!drmmode_crtc->scanout[drmmode_crtc->scanout_id].bo;
 }
 
 
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 70751b0bf..42ef9ae77 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -754,9 +754,10 @@ can_exchange(ScrnInfoPtr pScrn, DrawablePtr draw,
 }
 
 static Bool
-can_flip(ScrnInfoPtr pScrn, DrawablePtr draw,
+can_flip(xf86CrtcPtr crtc, DrawablePtr draw,
 	 DRI2BufferPtr front, DRI2BufferPtr back)
 {
+    ScrnInfoPtr pScrn = crtc->scrn;
     RADEONInfoPtr info = RADEONPTR(pScrn);
     xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
     int num_crtcs_on;
@@ -771,15 +772,10 @@ can_flip(ScrnInfoPtr pScrn, DrawablePtr draw,
 	return FALSE;
 
     for (i = 0, num_crtcs_on = 0; i < config->num_crtc; i++) {
-	xf86CrtcPtr crtc = config->crtc[i];
-	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-
-	if (!drmmode_crtc || drmmode_crtc->rotate.bo ||
-	    drmmode_crtc->scanout[drmmode_crtc->scanout_id].bo)
-	    return FALSE;
-
-	if (drmmode_crtc_can_flip(crtc))
+	if (drmmode_crtc_can_flip(config->crtc[i]))
 	    num_crtcs_on++;
+	else if (config->crtc[i] == crtc)
+	    return FALSE;
     }
 
     return num_crtcs_on > 0 && can_exchange(pScrn, draw, front, back);
@@ -859,7 +855,7 @@ static void radeon_dri2_frame_event_handler(xf86CrtcPtr crtc, uint32_t seq,
 
     switch (event->type) {
     case DRI2_FLIP:
-	if (can_flip(scrn, drawable, event->front, event->back) &&
+	if (can_flip(crtc, drawable, event->front, event->back) &&
 	    radeon_dri2_schedule_flip(crtc,
 				      event->client,
 				      drawable,
@@ -1352,7 +1348,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
     current_msc &= 0xffffffff;
 
     /* Flips need to be submitted one frame before */
-    if (can_flip(scrn, draw, front, back)) {
+    if (can_flip(crtc, draw, front, back)) {
 	swap_info->type = DRI2_FLIP;
 	flip = 1;
     }
diff --git a/src/radeon_present.c b/src/radeon_present.c
index 85da655db..4d43733e9 100644
--- a/src/radeon_present.c
+++ b/src/radeon_present.c
@@ -243,14 +243,7 @@ radeon_present_check_unflip(ScrnInfoPtr scrn)
 	return FALSE;
 
     for (i = 0, num_crtcs_on = 0; i < config->num_crtc; i++) {
-	xf86CrtcPtr crtc = config->crtc[i];
-	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-
-	if (!drmmode_crtc || drmmode_crtc->rotate.bo ||
-	    drmmode_crtc->scanout[drmmode_crtc->scanout_id].bo)
-	    return FALSE;
-
-	if (drmmode_crtc_can_flip(crtc))
+	if (drmmode_crtc_can_flip(config->crtc[i]))
 	    num_crtcs_on++;
     }
 
@@ -286,6 +279,9 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap,
 	radeon_present_get_pixmap_tiling_flags(info, screen_pixmap))
 	return FALSE;
 
+    if (!drmmode_crtc_can_flip(crtc->devPrivate))
+	return FALSE;
+
     return radeon_present_check_unflip(scrn);
 }
 
-- 
2.13.3



More information about the amd-gfx mailing list