diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-09-07 23:00:47 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-09-07 23:24:22 +0100 |
commit | 2c8e48f8149499040342836491333402fd05b762 (patch) | |
tree | 51cc579c3d65e8d1df0c9a047b325987e60d1ed9 | |
parent | ed7b8db24921dc0bb6ea59dacf35ea41a61d59bf (diff) |
sna: Remember that LineDoubleDash involves updating the GC between segments
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/sna_accel.c | 128 |
1 files changed, 100 insertions, 28 deletions
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 98810502..7574847c 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -5088,6 +5088,13 @@ struct sna_fill_spans { }; static void +sna_poly_point__cpu(DrawablePtr drawable, GCPtr gc, + int mode, int n, DDXPointPtr pt) +{ + fbPolyPoint(drawable, gc, mode, n, pt, -1); +} + +static void sna_poly_point__fill(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt) { @@ -5123,6 +5130,52 @@ sna_poly_point__fill(DrawablePtr drawable, GCPtr gc, } static void +sna_poly_point__gpu(DrawablePtr drawable, GCPtr gc, + int mode, int n, DDXPointPtr pt) +{ + struct sna_fill_spans *data = sna_gc(gc)->priv; + struct sna_fill_op fill; + BoxRec box[512]; + DDXPointRec last; + + if (!sna_fill_init_blt(&fill, + data->sna, data->pixmap, + data->bo, gc->alu, gc->fgPixel)) + return; + + DBG(("%s: count=%d\n", __FUNCTION__, n)); + + last.x = drawable->x; + last.y = drawable->y; + while (n) { + BoxRec *b = box; + unsigned nbox = n; + if (nbox > ARRAY_SIZE(box)) + nbox = ARRAY_SIZE(box); + n -= nbox; + do { + *(DDXPointRec *)b = *pt++; + + b->x1 += last.x; + b->y1 += last.y; + if (mode == CoordModePrevious) + last = *(DDXPointRec *)b; + + if (RegionContainsPoint(&data->region, + b->x1, b->y1, NULL)) { + b->x1 += data->dx; + b->y1 += data->dy; + b->x2 = b->x1 + 1; + b->y2 = b->y1 + 1; + b++; + } + } while (--nbox); + fill.boxes(data->sna, &fill, box, b - box); + } + fill.done(data->sna, &fill); +} + +static void sna_poly_point__fill_clip_extents(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt) { @@ -9275,45 +9328,64 @@ sna_poly_arc(DrawablePtr drawable, GCPtr gc, int n, xArc *arc) get_drawable_deltas(drawable, data.pixmap, &data.dx, &data.dy); if (gc_is_solid(gc, &color)) { - struct sna_fill_op fill; + sna_gc(gc)->priv = &data; - if (!sna_fill_init_blt(&fill, - data.sna, data.pixmap, - data.bo, gc->alu, color)) - goto fallback; + assert(gc->miTranslate); + if (gc->lineStyle == LineSolid) { + struct sna_fill_op fill; - data.op = &fill; - sna_gc(gc)->priv = &data; + if (!sna_fill_init_blt(&fill, + data.sna, data.pixmap, + data.bo, gc->alu, color)) + goto fallback; - if ((data.flags & 2) == 0) { - if (data.dx | data.dy) - sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill_offset; + if ((data.flags & 2) == 0) { + if (data.dx | data.dy) + sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill_offset; + else + sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill; + sna_gc_ops__tmp.PolyPoint = sna_poly_point__fill; + } else { + region_maybe_clip(&data.region, + gc->pCompositeClip); + if (!RegionNotEmpty(&data.region)) + return; + + if (region_is_singular(&data.region)) { + sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill_clip_extents; + sna_gc_ops__tmp.PolyPoint = sna_poly_point__fill_clip_extents; + } else { + sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill_clip_boxes; + sna_gc_ops__tmp.PolyPoint = sna_poly_point__fill_clip_boxes; + } + } + + data.op = &fill; + gc->ops = &sna_gc_ops__tmp; + if (gc->lineWidth == 0) + miZeroPolyArc(drawable, gc, n, arc); else - sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill; - sna_gc_ops__tmp.PolyPoint = sna_poly_point__fill; + miPolyArc(drawable, gc, n, arc); + gc->ops = (GCOps *)&sna_gc_ops; + + fill.done(data.sna, &fill); } else { region_maybe_clip(&data.region, gc->pCompositeClip); if (!RegionNotEmpty(&data.region)) return; - if (region_is_singular(&data.region)) { - sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill_clip_extents; - sna_gc_ops__tmp.PolyPoint = sna_poly_point__fill_clip_extents; - } else { - sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill_clip_boxes; - sna_gc_ops__tmp.PolyPoint = sna_poly_point__fill_clip_boxes; - } + sna_gc_ops__tmp.FillSpans = sna_fill_spans__gpu; + sna_gc_ops__tmp.PolyPoint = sna_poly_point__gpu; + + gc->ops = &sna_gc_ops__tmp; + if (gc->lineWidth == 0) + miZeroPolyArc(drawable, gc, n, arc); + else + miPolyArc(drawable, gc, n, arc); + gc->ops = (GCOps *)&sna_gc_ops; } - assert(gc->miTranslate); - gc->ops = &sna_gc_ops__tmp; - if (gc->lineWidth == 0) - miZeroPolyArc(drawable, gc, n, arc); - else - miPolyArc(drawable, gc, n, arc); - gc->ops = (GCOps *)&sna_gc_ops; - fill.done(data.sna, &fill); if (data.damage) { if (data.dx | data.dy) pixman_region_translate(&data.region, data.dx, data.dy); @@ -13431,7 +13503,7 @@ static const GCOps sna_gc_ops__cpu = { fbPutImage, fbCopyArea, fbCopyPlane, - fbPolyPoint, + sna_poly_point__cpu, fbPolyLine, fbPolySegment, miPolyRectangle, |