From fdb3a008e991131870cf28a7c8eb2b373e023fad Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 6 Jan 2015 14:11:40 +0000 Subject: [PATCH] sna: Clip copy to CRTC shadow If the user sets the CRTC position before resizing the framebuffer, we end up with an out-of-bounds CRTC and install a shadow (as the current framebuffer does not cover the CRTC). In this case, we copy the visible region before displaying on the CRTC. However, this needs to be clipped for self-consistency. Reported-by: Zdenek Kabelac Signed-off-by: Chris Wilson --- src/sna/sna_display.c | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index c2c74068..d1111c70 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -1992,7 +1992,6 @@ force_shadow: } if (__sna_pixmap_get_bo(sna->front) && !crtc->transformPresent) { - DrawableRec tmp; BoxRec b; b.x1 = crtc->x; @@ -2000,21 +1999,34 @@ force_shadow: b.x2 = crtc->x + crtc->mode.HDisplay; b.y2 = crtc->y + crtc->mode.VDisplay; - DBG(("%s: copying onto shadow CRTC: (%d, %d)x(%d, %d), handle=%d\n", - __FUNCTION__, - b.x1, b.y1, - b.x2, b.y2, - bo->handle)); + if (b.x1 < 0) + b.x1 = 0; + if (b.y1 < 0) + b.y1 = 0; + if (b.x2 > scrn->virtualX) + b.x2 = scrn->virtualX; + if (b.y2 > scrn->virtualY) + b.y2 = scrn->virtualY; + if (b.y2 > b.y1 && b.x2 > b.x1) { + DrawableRec tmp; - tmp.width = crtc->mode.HDisplay; - tmp.height = crtc->mode.VDisplay; - tmp.depth = sna->front->drawable.depth; - tmp.bitsPerPixel = sna->front->drawable.bitsPerPixel; + DBG(("%s: copying onto shadow CRTC: (%d, %d)x(%d, %d) [fb=%dx%d], handle=%d\n", + __FUNCTION__, + b.x1, b.y1, + b.x2-b.x1, b.y2-b.y1, + scrn->virtualX, scrn->virtualY, + bo->handle)); - (void)sna->render.copy_boxes(sna, GXcopy, - &sna->front->drawable, __sna_pixmap_get_bo(sna->front), 0, 0, - &tmp, bo, -b.x1, -b.y1, - &b, 1, 0); + tmp.width = crtc->mode.HDisplay; + tmp.height = crtc->mode.VDisplay; + tmp.depth = sna->front->drawable.depth; + tmp.bitsPerPixel = sna->front->drawable.bitsPerPixel; + + (void)sna->render.copy_boxes(sna, GXcopy, + &sna->front->drawable, __sna_pixmap_get_bo(sna->front), 0, 0, + &tmp, bo, -crtc->x, -crtc->y, + &b, 1, 0); + } } sna_crtc->shadow_bo_width = crtc->mode.HDisplay;