From 1a65e2b8a2ebfb4d736efb7631515babad75faf2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 21 Feb 2012 08:09:52 +0000 Subject: [PATCH] sna: Split up/down edge walking in order to handle endpoint clipping In order to prevent walking upwards off the top of the pixmap when rendering a clipped vertical edge, we need to tweak the boundary conditions for the vertical edge walker. Reported-by: Clemens Eisserer References: https://bugs.freedesktop.org/show_bug.cgi?id=46261 Signed-off-by: Chris Wilson --- src/sna/sna_accel.c | 130 ++++++++++++++++++++++++++------------------ 1 file changed, 78 insertions(+), 52 deletions(-) diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index c8fcc75b..215dbcaf 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -5669,35 +5669,48 @@ X_continue2: } b->x2 = b->x1 = x; - b->y1 = y; - while (length--) { - e += e1; - y += sdy; - if (e >= 0) { - b->y2 = y; - if (b->y2 < b->y1) { - int16_t t = b->y1; - b->y1 = b->y2; - b->y2 = t; + if (sdy < 0) { + b->y2 = y + 1; + while (length--) { + e += e1; + y--; + if (e >= 0) { + b->y1 = y; + b->x2++; + if (++b == last_box) { + ret = &&Y_up_continue; + goto *jump; +Y_up_continue: + b = box; + } + e += e3; + b->x2 = b->x1 = ++x; + b->y2 = y; } - b->x2++; - if (++b == last_box) { - ret = &&Y_continue; - goto *jump; -Y_continue: - b = box; - } - e += e3; - b->x2 = b->x1 = ++x; - b->y1 = y; } - } - b->y2 = y + sdy; - if (b->y2 < b->y1) { - int16_t t = b->y1; - b->y1 = b->y2; - b->y2 = t; + b->y1 = y; + } else { + b->y1 = y; + while (length--) { + e += e1; + y++; + if (e >= 0) { + b->y2 = y; + b->x2++; + if (++b == last_box) { + ret = &&Y_down_continue; + goto *jump; +Y_down_continue: + b = box; + } + e += e3; + b->x2 = b->x1 = ++x; + b->y1 = y; + } + } + + b->y2 = ++y; } b->x2++; if (++b == last_box) { @@ -6949,35 +6962,48 @@ X_continue2: } b->x2 = b->x1 = x1; - b->y1 = y1; - while (--length) { - e += e1; - y1 += sdy; - if (e >= 0) { - b->y2 = y1; - if (b->y2 < b->y1) { - int16_t t = b->y1; - b->y1 = b->y2; - b->y2 = t; + if (sdy < 0) { + b->y2 = y1 + 1; + while (--length) { + e += e1; + y1--; + if (e >= 0) { + b->y1 = y1; + b->x2++; + if (++b == last_box) { + ret = &&Y_up_continue; + goto *jump; +Y_up_continue: + b = box; + } + e += e3; + b->x2 = b->x1 = ++x1; + b->y2 = y1; } - b->x2++; - if (++b == last_box) { - ret = &&Y_continue; - goto *jump; -Y_continue: - b = box; - } - e += e3; - b->x2 = b->x1 = ++x1; - b->y1 = y1; } - } - b->y2 = y1 + sdy; - if (b->y2 < b->y1) { - int16_t t = b->y1; - b->y1 = b->y2; - b->y2 = t; + b->y1 = y1; + } else { + b->y1 = y1; + while (--length) { + e += e1; + y1++; + if (e >= 0) { + b->y2 = y1; + b->x2++; + if (++b == last_box) { + ret = &&Y_down_continue; + goto *jump; +Y_down_continue: + b = box; + } + e += e3; + b->x2 = b->x1 = ++x1; + b->y1 = y1; + } + } + + b->y2 = ++y1; } b->x2++; if (++b == last_box) {