summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-11-07 20:06:35 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2011-11-07 20:10:27 +0000
commitafdf931e61821985b31b339d1f346ddd7c4e9e3c (patch)
tree9534eca9e0fe34ca106ea6c22a3a7b1301131025
parent8f3c845782fdb2fa8bdf751bdd7dd83ca02c42ac (diff)
sna: Add some more debugging in the hunt for overflows
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/sna_accel.c91
-rw-r--r--src/sna/sna_io.c10
2 files changed, 90 insertions, 11 deletions
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index e33d45a4..9fddd4f0 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1087,11 +1087,15 @@ static void sna_gc_move_to_cpu(GCPtr gc, DrawablePtr drawable)
}
sgc->changes = 0;
- if (gc->stipple)
- sna_drawable_move_to_cpu(&gc->stipple->drawable, false);
-
- if (gc->fillStyle == FillTiled)
+ switch (gc->fillStyle) {
+ case FillTiled:
sna_drawable_move_to_cpu(&gc->tile.pixmap->drawable, false);
+ break;
+ case FillStippled:
+ case FillOpaqueStippled:
+ sna_drawable_move_to_cpu(&gc->stipple->drawable, false);
+ break;
+ }
}
static inline bool clip_box(BoxPtr box, GCPtr gc)
@@ -2142,6 +2146,10 @@ fallback:
__FUNCTION__,
box->x1, box->y1,
box->x2, box->y2));
+ assert(box->x1 + src_dx >= 0);
+ assert(box->y1 + src_dy >= 0);
+ assert(box->x1 + dst_dx >= 0);
+ assert(box->y1 + dst_dy >= 0);
fbBlt(src_bits + (box->y1 + src_dy) * src_stride,
src_stride,
(box->x1 + src_dx) * bpp,
@@ -4717,7 +4725,7 @@ sna_poly_segment_extents(DrawablePtr drawable, GCPtr gc,
if (gc->capStyle != CapProjecting)
extra >>= 1;
- if (seg->x2 > seg->x1) {
+ if (seg->x2 >= seg->x1) {
box.x1 = seg->x1;
box.x2 = seg->x2;
} else {
@@ -4725,7 +4733,7 @@ sna_poly_segment_extents(DrawablePtr drawable, GCPtr gc,
box.x1 = seg->x2;
}
- if (seg->y2 > seg->y1) {
+ if (seg->y2 >= seg->y1) {
box.y1 = seg->y1;
box.y2 = seg->y2;
} else {
@@ -4766,9 +4774,13 @@ sna_poly_segment_extents(DrawablePtr drawable, GCPtr gc,
box.y2 += extra;
}
+ DBG(("%s: unclipped, untranslated extents (%d, %d), (%d, %d)\n",
+ __FUNCTION__, box.x1, box.y1, box.x2, box.y2));
+
clipped = trim_and_translate_box(&box, drawable, gc);
if (box_empty(&box))
return 0;
+
*out = box;
return 1 | clipped << 1 | can_blit << 2;
}
@@ -5575,9 +5587,10 @@ sna_poly_fill_rect_blt(DrawablePtr drawable,
BoxRec boxes[512], *b = boxes, *const last_box = boxes+ARRAY_SIZE(boxes);
int16_t dx, dy;
- DBG(("%s x %d [(%d, %d)+(%d, %d)...], clipped?=%d\n",
- __FUNCTION__,
- n, rect->x, rect->y, rect->width, rect->height,
+ DBG(("%s x %d [(%d, %d)x(%d, %d)...]+(%d,%d), clipped?=%d\n",
+ __FUNCTION__, n,
+ rect->x, rect->y, rect->width, rect->height,
+ drawable->x, drawable->y,
clipped));
if (n == 1 && gc->pCompositeClip->data == NULL) {
@@ -6764,10 +6777,66 @@ fallback:
sna_gc_move_to_cpu(gc, draw);
sna_drawable_move_region_to_cpu(draw, &region, true);
- RegionUninit(&region);
DBG(("%s: fallback - fbPolyFillRect\n", __FUNCTION__));
- fbPolyFillRect(draw, gc, n, rect);
+ if (region.data == NULL) {
+ do {
+ BoxRec box;
+
+ box.x1 = rect->x + draw->x;
+ box.y1 = rect->y + draw->y;
+ box.x2 = bound(box.x1, rect->width);
+ box.y2 = bound(box.y1, rect->height);
+ rect++;
+
+ if (box_intersect(&box, &region.extents)) {
+ DBG(("%s: fallback - fbFill((%d, %d), (%d, %d))\n",
+ __FUNCTION__,
+ box.x1, box.y1,
+ box.x2-box.x1, box.y2-box.y1));
+ fbFill(draw, gc,
+ box.x1, box.y1,
+ box.x2-box.x1, box.y2-box.y1);
+ }
+ } while (--n);
+ } else {
+ const BoxRec * const clip_start = RegionBoxptr(&region);
+ const BoxRec * const clip_end = clip_start + region.data->numRects;
+ const BoxRec *c;
+
+ do {
+ BoxRec box;
+
+ box.x1 = rect->x + draw->x;
+ box.y1 = rect->y + draw->y;
+ box.x2 = bound(box.x1, rect->width);
+ box.y2 = bound(box.y1, rect->height);
+ rect++;
+
+ c = find_clip_box_for_y(clip_start,
+ clip_end,
+ box.y1);
+
+ while (c != clip_end) {
+ BoxRec b;
+
+ if (box.y2 <= c->y1)
+ break;
+
+ b = box;
+ if (box_intersect(&b, c++)) {
+ DBG(("%s: fallback - fbFill((%d, %d), (%d, %d))\n",
+ __FUNCTION__,
+ b.x1, b.y1,
+ b.x2-b.x1, b.y2-b.y1));
+ fbFill(draw, gc,
+ b.x1, b.y1,
+ b.x2-b.x1, b.y2-b.y1);
+ }
+ }
+ } while (--n);
+ }
+ RegionUninit(&region);
}
struct sna_font {
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index a36adc96..963efb34 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -61,6 +61,16 @@ static void read_boxes_inplace(struct kgem *kgem,
return;
do {
+ assert(box->x1 + src_dx >= 0);
+ assert(box->y1 + src_dy >= 0);
+ assert(box->x2 + src_dx <= pixmap->drawable.width);
+ assert(box->y2 + src_dy <= pixmap->drawable.height);
+
+ assert(box->x1 + dst_dx >= 0);
+ assert(box->y1 + dst_dy >= 0);
+ assert(box->x2 + dst_dx <= pixmap->drawable.width);
+ assert(box->y2 + dst_dy <= pixmap->drawable.height);
+
memcpy_blt(src, dst, bpp,
src_pitch, dst_pitch,
box->x1 + src_dx, box->y1 + src_dy,