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