summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2017-03-10 00:42:01 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2017-03-10 00:51:07 +0000
commit57daa3742ef7a46d77d8f9deafb93f3b144f96d2 (patch)
tree05c5d9e9fd978ac10d43d2a91c1149ea1a37b1b6
parentd1fe45c8f1966eb8f67c408c954754ca5de43a31 (diff)
sna: Filter out all degenerate PolySegment
After converting the segment into a box, discard all that are empty and that we have no overflow. References: https://bugs.gentoo.org/show_bug.cgi?id=611926 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/sna_accel.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 4e74fd68..99b0def4 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -10164,7 +10164,7 @@ out:
RegionUninit(&data.region);
}
-static inline void box_from_seg(BoxPtr b, const xSegment *seg, GCPtr gc)
+static inline bool box_from_seg(BoxPtr b, const xSegment *seg, GCPtr gc)
{
if (seg->x1 == seg->x2) {
if (seg->y1 > seg->y2) {
@@ -10178,6 +10178,9 @@ static inline void box_from_seg(BoxPtr b, const xSegment *seg, GCPtr gc)
if (gc->capStyle != CapNotLast)
b->y2++;
}
+ if (b->y1 >= b->y2)
+ return false;
+
b->x1 = seg->x1;
b->x2 = seg->x1 + 1;
} else {
@@ -10192,6 +10195,9 @@ static inline void box_from_seg(BoxPtr b, const xSegment *seg, GCPtr gc)
if (gc->capStyle != CapNotLast)
b->x2++;
}
+ if (b->x1 >= b->x2)
+ return false;
+
b->y1 = seg->y1;
b->y2 = seg->y1 + 1;
}
@@ -10200,6 +10206,7 @@ static inline void box_from_seg(BoxPtr b, const xSegment *seg, GCPtr gc)
__FUNCTION__,
seg->x1, seg->y1, seg->x2, seg->y2,
b->x1, b->y1, b->x2, b->y2));
+ return true;
}
static bool
@@ -10234,12 +10241,13 @@ sna_poly_segment_blt(DrawablePtr drawable,
nbox = ARRAY_SIZE(boxes);
n -= nbox;
do {
- box_from_seg(b, seg++, gc);
- if (b->y2 > b->y1 && b->x2 > b->x1) {
+ if (box_from_seg(b, seg++, gc)) {
+ assert(!box_empty(b));
b->x1 += dx;
b->x2 += dx;
b->y1 += dy;
b->y2 += dy;
+ assert(!box_empty(b));
b++;
}
} while (--nbox);
@@ -10258,7 +10266,10 @@ sna_poly_segment_blt(DrawablePtr drawable,
nbox = ARRAY_SIZE(boxes);
n -= nbox;
do {
- box_from_seg(b++, seg++, gc);
+ if (box_from_seg(b, seg++, gc)) {
+ assert(!box_empty(b));
+ b++;
+ }
} while (--nbox);
if (b != boxes) {
@@ -10283,7 +10294,10 @@ sna_poly_segment_blt(DrawablePtr drawable,
do {
BoxRec box;
- box_from_seg(&box, seg++, gc);
+ if (!box_from_seg(&box, seg++, gc))
+ continue;
+
+ assert(!box_empty(&box));
box.x1 += drawable->x;
box.x2 += drawable->x;
box.y1 += drawable->y;
@@ -10301,6 +10315,7 @@ sna_poly_segment_blt(DrawablePtr drawable,
b->x2 += dx;
b->y1 += dy;
b->y2 += dy;
+ assert(!box_empty(b));
if (++b == last_box) {
fill.boxes(sna, &fill, boxes, last_box-boxes);
if (damage)
@@ -10312,7 +10327,10 @@ sna_poly_segment_blt(DrawablePtr drawable,
} while (--n);
} else {
do {
- box_from_seg(b, seg++, gc);
+ if (!box_from_seg(b, seg++, gc))
+ continue;
+
+ assert(!box_empty(b));
b->x1 += drawable->x;
b->x2 += drawable->x;
b->y1 += drawable->y;
@@ -10322,6 +10340,7 @@ sna_poly_segment_blt(DrawablePtr drawable,
b->x2 += dx;
b->y1 += dy;
b->y2 += dy;
+ assert(!box_empty(b));
if (++b == last_box) {
fill.boxes(sna, &fill, boxes, last_box-boxes);
if (damage)