diff options
| author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-11-14 13:39:34 +0000 |
|---|---|---|
| committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-11-14 13:49:50 +0000 |
| commit | ae9de984adb275e028e7fbcb8b74a3ce11920eed (patch) | |
| tree | 1403a3d4386802dbfa35b57c8189ee1072396a2f | |
| parent | e861e816f53989ce3ab3ec89dd1d9a35155f999a (diff) | |
sna: Convert non-FillSolid rectilinear lines to boxes
And render using the tiled/stippled rect routines instead.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
| -rw-r--r-- | src/sna/sna_accel.c | 98 |
1 files changed, 89 insertions, 9 deletions
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index c3c08a5d..00001f7e 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -4063,7 +4063,7 @@ sna_poly_line_extents(DrawablePtr drawable, GCPtr gc, return 0; *out = box; - return 1 | blt << 1 | clip << 2; + return 1 | blt << 2 | clip << 1; } static void @@ -4101,24 +4101,32 @@ sna_poly_line(DrawablePtr drawable, GCPtr gc, gc->lineStyle, gc->lineStyle == LineSolid, gc->lineWidth, gc->planemask, PM_IS_SOLID(drawable, gc->planemask), - flags & 2)); - if (gc->fillStyle == FillSolid && gc->lineStyle == LineSolid && - (gc->lineWidth == 0 || (gc->lineWidth == 1 && (n == 1 || gc->alu == GXcopy))) && - PM_IS_SOLID(drawable, gc->planemask)) { + flags & 4)); + + if (!PM_IS_SOLID(drawable, gc->planemask)) + goto fallback; + + if (gc->lineStyle != LineSolid) + goto spans_fallback; + if (!(gc->lineWidth == 0 || + (gc->lineWidth == 1 && (n == 1 || gc->alu == GXcopy)))) + goto spans_fallback; + + if (gc->fillStyle == FillSolid) { struct sna_pixmap *priv = sna_pixmap(pixmap); struct sna_damage **damage; DBG(("%s: trying solid fill [%08lx]\n", __FUNCTION__, gc->fgPixel)); - if (flags & 2) { + if (flags & 4) { if (sna_drawable_use_gpu_bo(drawable, ®ion.extents, &damage) && sna_poly_line_blt(drawable, priv->gpu_bo, damage, gc, mode, n, pt, - ®ion.extents, flags & 4)) + ®ion.extents, flags & 2)) return; if (sna_drawable_use_cpu_bo(drawable, @@ -4127,7 +4135,7 @@ sna_poly_line(DrawablePtr drawable, GCPtr gc, sna_poly_line_blt(drawable, priv->cpu_bo, damage, gc, mode, n, pt, - ®ion.extents, flags & 4)) + ®ion.extents, flags & 2)) return; } else { /* !rectilinear */ if (USE_ZERO_SPANS && @@ -4137,12 +4145,84 @@ sna_poly_line(DrawablePtr drawable, GCPtr gc, sna_poly_zero_line_blt(drawable, priv->gpu_bo, damage, gc, mode, n, pt, - ®ion.extents, flags & 4)) + ®ion.extents, flags & 2)) return; } + } else if (flags & 4) { + struct sna_pixmap *priv = sna_pixmap(pixmap); + struct sna_damage **damage; + + /* Try converting these to a set of rectangles instead */ + if (sna_drawable_use_gpu_bo(drawable, ®ion.extents, &damage)) { + DDXPointRec p1, p2; + xRectangle *rect; + int i; + + DBG(("%s: converting to rectagnles\n", __FUNCTION__)); + + rect = malloc (n * sizeof (xRectangle)); + if (rect == NULL) + return; + + p1 = pt[0]; + for (i = 1; i < n; i++) { + if (mode == CoordModePrevious) { + p2.x = p1.x + pt[i].x; + p2.y = p1.y + pt[i].y; + } else { + p2 = pt[i]; + } + if (p1.x < p2.x) { + rect[i].x = p1.x; + rect[i].width = p2.x - p1.x; + } else if (p1.x > p2.x) { + rect[i].x = p2.x; + rect[i].width = p1.x - p2.x; + } else { + rect[i].x = p1.x; + rect[i].width = 1; + } + if (p1.y < p2.y) { + rect[i].y = p1.y; + rect[i].height = p2.y - p1.y; + } else if (p1.y > p2.y) { + rect[i].y = p2.y; + rect[i].height = p1.y - p2.y; + } else { + rect[i].y = p1.y; + rect[i].height = 1; + } + + /* don't paint last pixel */ + if (gc->capStyle == CapNotLast) { + if (p1.x == p2.x) + rect[i].height--; + else + rect[i].width--; + } + p1 = p2; + } + + if (gc->fillStyle == FillTiled) { + i = sna_poly_fill_rect_tiled_blt(drawable, + priv->gpu_bo, damage, + gc, n - 1, rect + 1, + ®ion.extents, flags & 2); + } else { + i = sna_poly_fill_rect_stippled_blt(drawable, + priv->gpu_bo, damage, + gc, n - 1, rect + 1, + ®ion.extents, flags & 2); + } + free (rect); + + if (i) + return; + } } +spans_fallback: if (USE_SPANS && can_fill_spans(drawable, gc) && sna_drawable_use_gpu_bo(drawable, ®ion.extents, NULL)) { |
