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

Chris Wilson ickle at kemper.freedesktop.org
Wed Jun 18 08:56:05 PDT 2014


 src/sna/sna_display.c |   33 +++++++++++++++------------------
 1 file changed, 15 insertions(+), 18 deletions(-)

New commits:
commit 83c0f034454ef0f474126a3398e5e790ac5ef842
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jun 18 16:51:46 2014 +0100

    sna: Pass desired CRTC viewport for completing single CRTC flips
    
    We cannot simply compare against the crtc->shadow_bo for all our needs,
    so pass in exactly the setup we want and apply that. In particular this
    is required when flipping away from the single CRTC setup on secondary
    pipes.
    
    Fixes TearFree multi-monitor regression from
    commit 3932e97057fca16615adaefbc1eb25a0d51a1d8b [2.99.912]
    Author: Chris Wilson <chris at chris-wilson.co.uk>
    Date:   Mon Jun 9 08:58:15 2014 +0100
    
        sna/dri2: Allow TearFree flipping to individual CRTC
    
    Reported-by: Leo Wolf <jclw at ymail.com>
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=80191

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 0c0ae8a..f97e83e 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -4504,10 +4504,9 @@ sna_cursors_fini(struct sna *sna)
 }
 
 static bool
-sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc)
+sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc, struct kgem_bo *bo, int x, int y)
 {
 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
-	struct kgem_bo *bo = crtc->shadow_bo ? crtc->shadow_bo : crtc->bo;
 	struct drm_mode_crtc arg;
 	uint32_t output_ids[32];
 	int output_count = 0;
@@ -4541,15 +4540,8 @@ sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc)
 	arg.crtc_id = crtc->id;
 	arg.fb_id = fb_id(bo);
 	assert(arg.fb_id);
-	if (bo != crtc->bo) {
-		arg.x = 0;
-		arg.y = 0;
-		crtc->offset = 0;
-	} else {
-		arg.x = crtc->base->x;
-		arg.y = crtc->base->y;
-		crtc->offset = arg.y << 16 | arg.x;
-	}
+	arg.x = x;
+	arg.y = y;
 	arg.set_connectors_ptr = (uintptr_t)output_ids;
 	arg.count_connectors = output_count;
 	arg.mode = crtc->kmode;
@@ -4565,7 +4557,11 @@ sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc)
 	     bo != crtc->bo ? " [shadow]" : "",
 	     output_count, output_count ? output_ids[0] : 0));
 
-	return drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg) == 0;
+	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg))
+		return false;
+
+	crtc->offset = y << 16 | x;
+	return true;
 }
 
 static int do_page_flip(struct sna *sna, struct kgem_bo *bo,
@@ -4621,7 +4617,7 @@ static int do_page_flip(struct sna *sna, struct kgem_bo *bo,
 			     bo->pitch, crtc->bo->pitch,
 			     crtc_offset, crtc->offset));
 fixup_flip:
-			if (crtc->bo != bo && sna_crtc_flip(sna, crtc)) {
+			if (crtc->bo != bo && sna_crtc_flip(sna, crtc, bo, crtc->base->x, crtc->base->y)) {
 				assert(crtc->bo->active_scanout);
 				assert(crtc->bo->refcnt >= crtc->bo->active_scanout);
 				crtc->bo->active_scanout--;
@@ -6298,7 +6294,7 @@ fixup_shadow:
 		for (i = 0; i < sna->mode.num_real_crtc; i++) {
 			struct sna_crtc *crtc = config->crtc[i]->driver_private;
 			struct kgem_bo *flip_bo;
-			uint32_t crtc_offset = 0;
+			int x, y;
 
 			assert(crtc != NULL);
 			DBG(("%s: crtc %d [%d, pipe=%d] active? %d, transformed? %d\n",
@@ -6320,23 +6316,24 @@ fixup_shadow:
 						   crtc->base->mode.HDisplay,
 						   crtc->base->mode.VDisplay);
 				flip_bo = crtc->shadow_bo;
-				crtc_offset = 0;
+				x = y = 0;
 			} else {
 				arg.fb_id = fb_id;
 				flip_bo = new;
-				crtc_offset = crtc->base->y << 16 | crtc->base->x;
+				x = crtc->base->x;
+				y = crtc->base->y;
 			}
 
 			if (crtc->bo == flip_bo)
 				continue;
 
-			if (flip_bo->pitch != crtc->bo->pitch || crtc_offset != crtc->offset) {
+			if (flip_bo->pitch != crtc->bo->pitch || (y << 16 | x)  != crtc->offset) {
 				DBG(("%s: changing pitch (%d == %d) or offset (%x == %x)\n",
 				     __FUNCTION__,
 				     flip_bo->pitch, crtc->bo->pitch,
 				     crtc_offset, crtc->offset));
 fixup_flip:
-				if (sna_crtc_flip(sna, crtc)) {
+				if (sna_crtc_flip(sna, crtc, flip_bo, x, y)) {
 					assert(flip_bo != crtc->bo);
 					assert(crtc->bo->active_scanout);
 					assert(crtc->bo->refcnt >= crtc->bo->active_scanout);


More information about the xorg-commit mailing list