summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-09-07 23:00:47 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2012-09-07 23:24:22 +0100
commit2c8e48f8149499040342836491333402fd05b762 (patch)
tree51cc579c3d65e8d1df0c9a047b325987e60d1ed9
parented7b8db24921dc0bb6ea59dacf35ea41a61d59bf (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.c128
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,