From 2c8e48f8149499040342836491333402fd05b762 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 7 Sep 2012 23:00:47 +0100 Subject: sna: Remember that LineDoubleDash involves updating the GC between segments Signed-off-by: Chris Wilson --- src/sna/sna_accel.c | 128 ++++++++++++++++++++++++++++++++++++++++------------ 1 file 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 @@ -5087,6 +5087,13 @@ struct sna_fill_spans { void *op; }; +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) @@ -5122,6 +5129,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, -- cgit v1.2.3