xf86-video-intel: 2 commits - src/sna/kgem.c src/sna/sna_render.c src/sna/sna_tiling.c src/sna/sna_trapezoids.c

Chris Wilson ickle at kemper.freedesktop.org
Mon Sep 19 10:16:59 PDT 2011


 src/sna/kgem.c           |    2 -
 src/sna/sna_render.c     |    4 +-
 src/sna/sna_tiling.c     |    3 +
 src/sna/sna_trapezoids.c |   71 +++++++++++++++++++++++++++++++++++++----------
 4 files changed, 62 insertions(+), 18 deletions(-)

New commits:
commit 686a5ec52c9ae475fac22c36fff18814372def71
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Sep 19 18:14:05 2011 +0100

    sna/trapezoids: Fix overflow during sorting of mono edge step
    
    We were tracking the 32bit value of the prev_x using only a 16bit
    variable, and so failing to sort the edges after advancing to the next
    scanline.
    
    Fixes cairo a1-clip-fill-rule.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_trapezoids.c b/src/sna/sna_trapezoids.c
index bf2f8bc..d1602e0 100644
--- a/src/sna/sna_trapezoids.c
+++ b/src/sna/sna_trapezoids.c
@@ -1439,7 +1439,7 @@ struct mono {
 #define I(x) pixman_fixed_to_int ((x) + pixman_fixed_1_minus_e/2)
 
 static bool
-mono_polygon_init (struct mono_polygon *polygon, BoxPtr box, int num_edges)
+mono_polygon_init(struct mono_polygon *polygon, BoxPtr box, int num_edges)
 {
 	unsigned h = box->y2 - box->y1;
 
@@ -1515,8 +1515,10 @@ mono_add_line(struct mono *mono,
 	y = I(bottom) + dst_y;
 	ybot = MIN(y, mono->clip.extents.y2);
 
-	if (ybot <= ytop)
+	if (ybot <= ytop) {
+		DBG(("discard clipped line\n"));
 		return;
+	}
 
 	e = polygon->edges + polygon->num_edges++;
 	e->height_left = ybot - ytop;
@@ -1555,7 +1557,7 @@ mono_add_line(struct mono *mono,
 }
 
 static struct mono_edge *
-mono_merge_sorted_edges (struct mono_edge *head_a, struct mono_edge *head_b)
+mono_merge_sorted_edges(struct mono_edge *head_a, struct mono_edge *head_b)
 {
 	struct mono_edge *head, **next, *prev;
 	int32_t x;
@@ -1599,7 +1601,7 @@ start_with_b:
 }
 
 static struct mono_edge *
-mono_sort_edges (struct mono_edge *list,
+mono_sort_edges(struct mono_edge *list,
 	    unsigned int level,
 	    struct mono_edge **head_out)
 {
@@ -1626,33 +1628,67 @@ mono_sort_edges (struct mono_edge *list,
 	}
 
 	for (i = 0; i < level && remaining; i++) {
-		remaining = mono_sort_edges (remaining, i, &head_other);
-		*head_out = mono_merge_sorted_edges (*head_out, head_other);
+		remaining = mono_sort_edges(remaining, i, &head_other);
+		*head_out = mono_merge_sorted_edges(*head_out, head_other);
 	}
 
 	return remaining;
 }
 
 static struct mono_edge *
-mono_merge_unsorted_edges (struct mono_edge *head, struct mono_edge *unsorted)
+mono_merge_unsorted_edges(struct mono_edge *head, struct mono_edge *unsorted)
+{
+	mono_sort_edges(unsorted, UINT_MAX, &unsorted);
+	return mono_merge_sorted_edges(head, unsorted);
+}
+
+#if DEBUG_TRAPEZOIDS
+static inline void
+__dbg_mono_edges(const char *function, struct mono_edge *edges)
+{
+	ErrorF("%s: ", function);
+	while (edges) {
+		if (edges->x.quo < INT16_MAX << 16) {
+			ErrorF("(%d.%06d)+(%d.%06d)x%d, ",
+			       edges->x.quo, edges->x.rem,
+			       edges->dxdy.quo, edges->dxdy.rem,
+			       edges->dy*edges->dir);
+		}
+		edges = edges->next;
+	}
+	ErrorF("\n");
+}
+#define DBG_MONO_EDGES(x) __dbg_mono_edges(__FUNCTION__, x)
+static inline void
+VALIDATE_MONO_EDGES(struct mono_edge *edges)
 {
-	mono_sort_edges (unsorted, UINT_MAX, &unsorted);
-	return mono_merge_sorted_edges (head, unsorted);
+	int prev_x = edges->x.quo;
+	while ((edges = edges->next)) {
+		assert(edges->x.quo >= prev_x);
+		prev_x = edges->x.quo;
+	}
 }
 
+#else
+#define DBG_MONO_EDGES(x)
+#define VALIDATE_MONO_EDGES(x)
+#endif
+
 inline static void
-mono_merge_edges (struct mono *c, struct mono_edge *edges)
+mono_merge_edges(struct mono *c, struct mono_edge *edges)
 {
 	struct mono_edge *e;
 
+	DBG_MONO_EDGES(edges);
+
 	for (e = edges; c->is_vertical && e; e = e->next)
 		c->is_vertical = e->vertical;
 
-	c->head.next = mono_merge_unsorted_edges (c->head.next, edges);
+	c->head.next = mono_merge_unsorted_edges(c->head.next, edges);
 }
 
 inline static void
-mono_span (struct mono *c, int x1, int x2, BoxPtr box)
+mono_span(struct mono *c, int x1, int x2, BoxPtr box)
 {
 	if (x1 < c->clip.extents.x1)
 		x1 = c->clip.extents.x1;
@@ -1688,10 +1724,14 @@ inline static void
 mono_row(struct mono *c, int16_t y, int16_t h)
 {
 	struct mono_edge *edge = c->head.next;
-	int16_t xstart = INT16_MIN, prev_x = INT16_MIN;
+	int prev_x = INT_MIN;
+	int16_t xstart = INT16_MIN;
 	int winding = 0;
 	BoxRec box;
 
+	DBG_MONO_EDGES(edge);
+	VALIDATE_MONO_EDGES(&c->head);
+
 	box.y1 = c->clip.extents.y1 + y;
 	box.y2 = box.y1 + h;
 
@@ -1737,12 +1777,15 @@ mono_row(struct mono *c, int16_t y, int16_t h)
 
 		edge = next;
 	}
+
+	DBG_MONO_EDGES(c->head.next);
+	VALIDATE_MONO_EDGES(&c->head);
 }
 
 static bool
 mono_init(struct mono *c, int num_edges)
 {
-	if (!mono_polygon_init (&c->polygon, &c->clip.extents, num_edges))
+	if (!mono_polygon_init(&c->polygon, &c->clip.extents, num_edges))
 		return false;
 
 	c->head.vertical = 1;
commit 0390105bc239bf2ac22189f39fccc9d98bae4992
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Sep 19 12:48:38 2011 +0100

    sna: compile fixes for debugging
    
    Update the DBG messages to reflect changes in function parameters.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index e154972..7df019a 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1974,7 +1974,7 @@ struct kgem_bo *kgem_upload_source_image(struct kgem *kgem,
 	void *dst;
 
 	DBG(("%s : (%d, %d), (%d, %d), stride=%d, bpp=%d\n",
-	     __FUNCTION__, x, y, width, height, stride, bpp));
+	     __FUNCTION__, box->x1, box->y1, box->x2, box->y2, stride, bpp));
 
 	bo = kgem_create_buffer(kgem, size, KGEM_BUFFER_WRITE, &dst);
 	if (bo == NULL)
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 60e9844..292853a 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -310,8 +310,8 @@ static struct kgem_bo *upload(struct sna *sna,
 {
 	struct kgem_bo *bo;
 
-	DBG(("%s: origin=(%d, %d), box=(%d, %d), (%d, %d), pixmap=%dx%d\n",
-	     __FUNCTION__, x, y, box->x1, box->y1, box->x2, box->y2, pixmap->drawable.width, pixmap->drawable.height));
+	DBG(("%s: box=(%d, %d), (%d, %d), pixmap=%dx%d\n",
+	     __FUNCTION__, box->x1, box->y1, box->x2, box->y2, pixmap->drawable.width, pixmap->drawable.height));
 	assert(box->x1 >= 0);
 	assert(box->y1 >= 0);
 	assert(box->x2 <= pixmap->drawable.width);
diff --git a/src/sna/sna_tiling.c b/src/sna/sna_tiling.c
index 27b0fbf..80989d8 100644
--- a/src/sna/sna_tiling.c
+++ b/src/sna/sna_tiling.c
@@ -228,7 +228,8 @@ sna_tiling_composite(uint32_t op,
 	struct sna_pixmap *priv;
 
 	DBG(("%s size=(%d, %d), tile=%d\n",
-	     __FUNCTION__, width, height, sna->render.max_3d_size));
+	     __FUNCTION__, width, height,
+	     to_sna_from_drawable(dst->pDrawable)->render.max_3d_size));
 
 	priv = sna_pixmap(get_drawable_pixmap(dst->pDrawable));
 	if (priv == NULL || priv->gpu_bo == NULL)


More information about the xorg-commit mailing list