summaryrefslogtreecommitdiff
path: root/src/sna/sna_trapezoids_mono.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-09-24 08:05:01 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2014-09-24 08:10:07 +0100
commit911a0ad8d0520554dc55883997dd59dc3f5f9139 (patch)
treee0fccb6f241e8fee566e3f9aefd880a7cde235d1 /src/sna/sna_trapezoids_mono.c
parentdbe6d105a60ff28419b549d439bbb29f50b28f08 (diff)
sna/trapezoids: Flesh out alternate rasterisers for tristrips
And undo the accidental commit of commit 4e00cbe35d1a409a02ee27d991213d9a0807e500 Author: Chris Wilson <chris@chris-wilson.co.uk> Date: Mon Sep 22 08:54:57 2014 +0100 traps Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna/sna_trapezoids_mono.c')
-rw-r--r--src/sna/sna_trapezoids_mono.c159
1 files changed, 156 insertions, 3 deletions
diff --git a/src/sna/sna_trapezoids_mono.c b/src/sna/sna_trapezoids_mono.c
index acd2b101..d53e5359 100644
--- a/src/sna/sna_trapezoids_mono.c
+++ b/src/sna/sna_trapezoids_mono.c
@@ -356,7 +356,7 @@ static struct mono_edge *mono_filter(struct mono_edge *edges)
struct mono_edge *e;
e = edges;
- do {
+ while (e->next) {
struct mono_edge *n = e->next;
if (e->dir == -n->dir &&
e->height_left == n->height_left &&
@@ -373,8 +373,8 @@ static struct mono_edge *mono_filter(struct mono_edge *edges)
e = n->next;
} else
- e = e->next;
- } while (e->next);
+ e = n;
+ }
return edges;
}
@@ -1425,3 +1425,156 @@ mono_triangles_span_converter(struct sna *sna,
REGION_UNINIT(NULL, &mono.clip);
return true;
}
+
+bool
+mono_tristrip_span_converter(struct sna *sna,
+ CARD8 op, PicturePtr src, PicturePtr dst,
+ INT16 src_x, INT16 src_y,
+ int count, xPointFixed *points)
+{
+ struct mono mono;
+ BoxRec extents;
+ int16_t dst_x, dst_y;
+ int16_t dx, dy;
+ bool was_clear;
+ int n;
+
+ mono.sna = sna;
+
+ dst_x = pixman_fixed_to_int(points[0].x);
+ dst_y = pixman_fixed_to_int(points[0].y);
+
+ miPointFixedBounds(count, points, &extents);
+ DBG(("%s: extents (%d, %d), (%d, %d)\n",
+ __FUNCTION__, extents.x1, extents.y1, extents.x2, extents.y2));
+
+ if (extents.y1 >= extents.y2 || extents.x1 >= extents.x2)
+ return true;
+
+ if (!sna_compute_composite_region(&mono.clip,
+ src, NULL, dst,
+ src_x + extents.x1 - dst_x,
+ src_y + extents.y1 - dst_y,
+ 0, 0,
+ extents.x1, extents.y1,
+ extents.x2 - extents.x1,
+ extents.y2 - extents.y1)) {
+ DBG(("%s: triangles do not intersect drawable clips\n",
+ __FUNCTION__)) ;
+ return true;
+ }
+
+ dx = dst->pDrawable->x;
+ dy = dst->pDrawable->y;
+
+ DBG(("%s: after clip -- extents (%d, %d), (%d, %d), delta=(%d, %d) src -> (%d, %d)\n",
+ __FUNCTION__,
+ mono.clip.extents.x1, mono.clip.extents.y1,
+ mono.clip.extents.x2, mono.clip.extents.y2,
+ dx, dy,
+ src_x + mono.clip.extents.x1 - dst_x - dx,
+ src_y + mono.clip.extents.y1 - dst_y - dy));
+
+ was_clear = sna_drawable_is_clear(dst->pDrawable);
+
+ if (!mono_init(&mono, 2*count))
+ return false;
+
+ mono_add_line(&mono, dx, dy,
+ points[0].y, points[1].y,
+ &points[0], &points[1], -1);
+ n = 2;
+ do {
+ mono_add_line(&mono, dx, dy,
+ points[n-2].y, points[n].y,
+ &points[n-2], &points[n], 1);
+ if (++n == count)
+ break;
+
+ mono_add_line(&mono, dx, dy,
+ points[n-2].y, points[n].y,
+ &points[n-2], &points[n], -1);
+ if (++n == count)
+ break;
+ } while (1);
+ mono_add_line(&mono, dx, dy,
+ points[n-2].y, points[n-1].y,
+ &points[n-2], &points[n-1], 1);
+
+ if (mono.sna->render.composite(mono.sna, op, src, NULL, dst,
+ src_x + mono.clip.extents.x1 - dst_x - dx,
+ src_y + mono.clip.extents.y1 - dst_y - dy,
+ 0, 0,
+ mono.clip.extents.x1, mono.clip.extents.y1,
+ mono.clip.extents.x2 - mono.clip.extents.x1,
+ mono.clip.extents.y2 - mono.clip.extents.y1,
+ COMPOSITE_PARTIAL, memset(&mono.op, 0, sizeof(mono.op)))) {
+ if (mono.clip.data == NULL && mono.op.damage == NULL)
+ mono.span = mono_span__fast;
+ else
+ mono.span = mono_span;
+ mono_render(&mono);
+ mono.op.done(mono.sna, &mono.op);
+ }
+
+ if (!was_clear && !operator_is_bounded(op)) {
+ xPointFixed p1, p2;
+
+ if (!mono_init(&mono, 2+2*count))
+ return false;
+
+ p1.y = mono.clip.extents.y1 * pixman_fixed_1;
+ p2.y = mono.clip.extents.y2 * pixman_fixed_1;
+
+ p1.x = mono.clip.extents.x1 * pixman_fixed_1;
+ p2.x = mono.clip.extents.x1 * pixman_fixed_1;
+ mono_add_line(&mono, 0, 0, p1.y, p2.y, &p1, &p2, -1);
+
+ p1.x = mono.clip.extents.x2 * pixman_fixed_1;
+ p2.x = mono.clip.extents.x2 * pixman_fixed_1;
+ mono_add_line(&mono, 0, 0, p1.y, p2.y, &p1, &p2, 1);
+
+ mono_add_line(&mono, dx, dy,
+ points[0].y, points[1].y,
+ &points[0], &points[1], -1);
+ n = 2;
+ do {
+ mono_add_line(&mono, dx, dy,
+ points[n-2].y, points[n].y,
+ &points[n-2], &points[n], 1);
+ if (++n == count)
+ break;
+
+ mono_add_line(&mono, dx, dy,
+ points[n-2].y, points[n].y,
+ &points[n-2], &points[n], -1);
+ if (++n == count)
+ break;
+ } while (1);
+ mono_add_line(&mono, dx, dy,
+ points[n-2].y, points[n-1].y,
+ &points[n-2], &points[n-1], 1);
+
+ if (mono.sna->render.composite(mono.sna,
+ PictOpClear,
+ mono.sna->clear, NULL, dst,
+ 0, 0,
+ 0, 0,
+ mono.clip.extents.x1, mono.clip.extents.y1,
+ mono.clip.extents.x2 - mono.clip.extents.x1,
+ mono.clip.extents.y2 - mono.clip.extents.y1,
+ COMPOSITE_PARTIAL, memset(&mono.op, 0, sizeof(mono.op)))) {
+ if (mono.clip.data == NULL && mono.op.damage == NULL)
+ mono.span = mono_span__fast;
+ else
+ mono.span = mono_span;
+ mono_render(&mono);
+ mono.op.done(mono.sna, &mono.op);
+ }
+ mono_fini(&mono);
+ }
+
+ mono_fini(&mono);
+ REGION_UNINIT(NULL, &mono.clip);
+ return true;
+}