From 43fffc8ea93bef012928f077981d9bf7bb7c3023 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 27 Jan 2016 10:42:47 +0000 Subject: sna: Perform composite rotation on the individual damage elements As the rotation may need to perform intermediate copies (e.g. displays larger than the render pipeline), we can reduce the amount of overdraw by using the damage boxes rather than preparing to redraw the entire output. Reported-by: Frank Delache Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93864 Signed-off-by: Chris Wilson --- src/sna/sna_display.c | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index 511aa84d..77dd3bed 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -8215,36 +8215,38 @@ sna_crtc_redisplay__composite(xf86CrtcPtr crtc, RegionPtr region, struct kgem_bo ValidatePicture(src); ValidatePicture(dst); - if (!sna->render.composite(sna, - PictOpSrc, src, NULL, dst, - sx, sy, - 0, 0, - 0, 0, - crtc->mode.HDisplay, crtc->mode.VDisplay, - COMPOSITE_PARTIAL, memset(&tmp, 0, sizeof(tmp)))) { - DBG(("%s: unsupported operation!\n", __FUNCTION__)); - sna_crtc_redisplay__fallback(crtc, region, bo); - goto free_dst; - } - + /* Composite each box individually as if we are dealing with a rotation + * on a large display, we may have to perform intermediate copies. We + * can then minimise the overdraw by looking at individual boxes rather + * than the bbox. + */ n = region_num_rects(region); b = region_rects(region); do { - BoxRec box; - - box = *b++; + BoxRec box = *b; transformed_box(&box, crtc); DBG(("%s: (%d, %d)x(%d, %d) -> (%d, %d), (%d, %d)\n", __FUNCTION__, - b[-1].x1, b[-1].y1, b[-1].x2-b[-1].x1, b[-1].y2-b[-1].y1, + b->x1, b->y1, b->x2-b->x1, b->y2-b->y1, box.x1, box.y1, box.x2, box.y2)); - tmp.box(sna, &tmp, &box); - } while (--n); - tmp.done(sna, &tmp); + if (!sna->render.composite(sna, + PictOpSrc, src, NULL, dst, + sx + box.x1, sy + box.y1, + 0, 0, + box.x1, box.y1, + box.x2 - box.x1, box.y2 - box.y1, + 0, memset(&tmp, 0, sizeof(tmp)))) { + DBG(("%s: unsupported operation!\n", __FUNCTION__)); + sna_crtc_redisplay__fallback(crtc, region, bo); + break; + } else { + tmp.box(sna, &tmp, &box); + tmp.done(sna, &tmp); + } + } while (b++, --n); -free_dst: FreePicture(dst, None); free_src: FreePicture(src, None); -- cgit v1.2.3