From 37cf561fd2f26a51ef60078e2e31ed02e5380c41 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 21 Apr 2015 14:33:24 +0100 Subject: [PATCH] sna: Allow flips to continue after successfully fixing up the CRTC If we receive an error from the pageflip ioctl, we attempt to set the framebuffer using SETCRTC instead. This is so that we can transition between pitches and offsets for a CRTC. However, the kernel may reject a flip also for tiling changes, or for any reason, which we also want to transparently handle. Rearrange the error message and flip->blit fallback handling to only do so if we try to flip twice (i.e. after resetting the CRTC) and we still fail. Signed-off-by: Chris Wilson --- src/sna/sna_display.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index 0183246d..3ba2df98 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -5928,6 +5928,7 @@ sna_page_flip(struct sna *sna, struct sna_crtc *crtc = config->crtc[i]->driver_private; struct drm_mode_crtc_page_flip arg; uint32_t crtc_offset; + int fixup; DBG(("%s: crtc %d id=%d, pipe=%d active? %d\n", __FUNCTION__, i, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), crtc->bo != NULL)); @@ -5949,6 +5950,7 @@ sna_page_flip(struct sna *sna, return 0; } + fixup = 0; crtc_offset = crtc->base->y << 16 | crtc->base->x; if (bo->pitch != crtc->bo->pitch || crtc_offset != crtc->offset) { @@ -5957,6 +5959,7 @@ sna_page_flip(struct sna *sna, bo->pitch, crtc->bo->pitch, crtc_offset, crtc->offset)); fixup_flip: + fixup = 1; if (crtc->bo != bo && sna_crtc_flip(sna, crtc, bo, crtc->base->x, crtc->base->y)) { update_scanout: DBG(("%s: removing handle=%d [active_scanout=%d] from scanout, installing handle=%d [active_scanout=%d]\n", @@ -5979,11 +5982,8 @@ update_scanout: goto next_crtc; /* queue a flip in order to send the event */ - } else { - if (count) - sna_mode_restore(sna); - return 0; - } + } else + goto error; } /* Only the reference crtc will finally deliver its page flip @@ -6029,16 +6029,18 @@ retry_flip: goto retry_flip; } - if (sna->flags & (data ? SNA_HAS_FLIP : SNA_HAS_ASYNC_FLIP)) { - xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, - "page flipping failed, on CRTC:%d (pipe=%d), disabling %s page flips\n", - __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), data ? "synchronous": "asynchronous"); - sna->flags &= ~(data ? SNA_HAS_FLIP : SNA_HAS_ASYNC_FLIP); + if (!fixup) goto fixup_flip; - } + +error: + xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, + "page flipping failed, on CRTC:%d (pipe=%d), disabling %s page flips\n", + __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), data ? "synchronous": "asynchronous"); if (count) sna_mode_restore(sna); + + sna->flags &= ~(data ? SNA_HAS_FLIP : SNA_HAS_ASYNC_FLIP); return 0; }