summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-02-21 08:09:52 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2012-02-21 08:13:25 +0000
commit1a65e2b8a2ebfb4d736efb7631515babad75faf2 (patch)
treef05e2ec5e64e5cde6f34c56cd7fc327db5ee2ff4
parent7ea44997553ffdf57b346dc9d83742c511c9e5a4 (diff)
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 <linuxhippy@gmail.com> References: https://bugs.freedesktop.org/show_bug.cgi?id=46261 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/sna_accel.c126
1 files changed, 76 insertions, 50 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;
+ }
+
+ 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;
}
- 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->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;
+ }
+
+ 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;
}
- 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->y2 = ++y1;
}
b->x2++;
if (++b == last_box) {