diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-10-27 21:50:25 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-10-27 21:50:25 +0100 |
commit | f006fac72a733e047b9468704e9c9206f62f96f5 (patch) | |
tree | c1403d03ad0c3066b1868b039f46768f4d4e7c8a | |
parent | d6f543011bf3d03b9298b5ceeddfc1fc20fc534b (diff) |
sna: Fast path typically unclipped tiled rects
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/sna_accel.c | 164 |
1 files changed, 75 insertions, 89 deletions
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 70bbad65..31f40138 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -4686,8 +4686,8 @@ static Bool sna_poly_fill_rect_blt(DrawablePtr drawable, struct kgem_bo *bo, struct sna_damage **damage, - GCPtr gc, int n, - xRectangle *rect, + GCPtr gc, uint32_t pixel, + int n, xRectangle *rect, const BoxRec *extents, bool clipped) { @@ -4695,7 +4695,6 @@ sna_poly_fill_rect_blt(DrawablePtr drawable, PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna_fill_op fill; BoxRec boxes[512], *b = boxes, *const last_box = boxes+ARRAY_SIZE(boxes); - uint32_t pixel = gc->fillStyle == FillSolid ? gc->fgPixel : gc->tile.pixel; int16_t dx, dy; DBG(("%s x %d [(%d, %d)+(%d, %d)...], clipped?=%d\n", @@ -4844,14 +4843,14 @@ static Bool sna_poly_fill_rect_tiled(DrawablePtr drawable, struct kgem_bo *bo, struct sna_damage **damage, - GCPtr gc, int n, - xRectangle *rect) + GCPtr gc, int n, xRectangle *rect, + const BoxRec *extents, unsigned clipped) { struct sna *sna = to_sna_from_drawable(drawable); PixmapPtr pixmap = get_drawable_pixmap(drawable); PixmapPtr tile = gc->tile.pixmap; - RegionPtr clip = fbGetCompositeClip(gc); - DDXPointPtr origin = &gc->patOrg; + const DDXPointRec * const origin = &gc->patOrg; + struct sna_copy_op copy; CARD32 alu = gc->alu; int tile_width, tile_height; int16_t dx, dy; @@ -4861,90 +4860,71 @@ sna_poly_fill_rect_tiled(DrawablePtr drawable, tile_width = tile->drawable.width; tile_height = tile->drawable.height; + if (tile_width == 1 && tile_height == 1) + return sna_poly_fill_rect_blt(drawable, bo, damage, + gc, get_pixel(tile), + n, rect, + extents, clipped); - get_drawable_deltas(drawable, pixmap, &dx, &dy); - - if (tile_width == 1 && tile_height == 1) { - struct sna_fill_op fill; - - if (!sna_fill_init_blt(&fill, sna, pixmap, bo, alu, get_pixel(tile))) { - DBG(("%s: unsupported blt\n", __FUNCTION__)); - return FALSE; - } - - if (clip->data == NULL) { - BoxPtr box = &clip->extents; - while (n--) { - BoxRec r; - - r.x1 = rect->x + drawable->x; - r.y1 = rect->y + drawable->y; - r.x2 = bound(r.x1, rect->width); - r.y2 = bound(r.y1, rect->height); - rect++; - - if (box_intersect(&r, box)) { - r.x1 += dx; - r.x2 += dx; - r.y1 += dy; - r.y2 += dy; - fill.box(sna, &fill, &r); - if (damage) { - assert_pixmap_contains_box(pixmap, &r); - sna_damage_add_box(damage, &r); - } - } - } - } else { - while (n--) { - RegionRec region; - BoxRec *box; - int nbox; + if (!sna_pixmap_move_to_gpu(tile)) + return FALSE; - region.extents.x1 = rect->x + drawable->x; - region.extents.y1 = rect->y + drawable->y; - region.extents.x2 = bound(region.extents.x1, rect->width); - region.extents.y2 = bound(region.extents.y1, rect->height); - rect++; + if (!sna_copy_init_blt(©, sna, + tile, sna_pixmap_get_bo(tile), + pixmap, bo, + alu)) { + DBG(("%s: unsupported blt\n", __FUNCTION__)); + return FALSE; + } - region.data = NULL; - RegionIntersect(®ion, ®ion, clip); + get_drawable_deltas(drawable, pixmap, &dx, &dy); + if (!clipped) { + dx += drawable->x; + dy += drawable->y; - nbox = REGION_NUM_RECTS(®ion); - box = REGION_RECTS(®ion); - while (nbox--) { - box->x1 += dx; - box->x2 += dx; - box->y1 += dy; - box->y2 += dy; - fill.box(sna, &fill, box); - if (damage) { - assert_pixmap_contains_box(pixmap, box); - sna_damage_add_box(damage, box); - } - box++; - } + sna_damage_add_rectangles(damage, rect, n, dx, dy); + do { + xRectangle r = *rect++; + int16_t tile_y = (r.y - origin->y) % tile_height; - RegionUninit(®ion); - } - } - fill.done(sna, &fill); + r.y += dy; + do { + int16_t width = r.width; + int16_t x = r.x + dx; + int16_t tile_x = (r.x - origin->x) % tile_width; + int16_t h = tile_height - tile_y; + if (h > r.height) + h = r.height; + r.height -= h; + + do { + int16_t w = tile_width - tile_x; + if (w > width) + w = width; + width -= w; + + copy.blt(sna, ©, + tile_x, tile_y, + w, h, + x, r.y); + + x += w; + tile_x = 0; + } while (width); + r.y += h; + tile_y = 0; + } while (r.height); + } while (--n); } else { - struct sna_copy_op copy; - - if (!sna_pixmap_move_to_gpu(tile)) - return FALSE; + RegionRec clip; - if (!sna_copy_init_blt(©, sna, - tile, sna_pixmap_get_bo(tile), - pixmap, bo, - alu)) { - DBG(("%s: unsupported blt\n", __FUNCTION__)); - return FALSE; - } + region_set(&clip, extents); + region_maybe_clip(&clip, gc->pCompositeClip); + if (!RegionNotEmpty(&clip)) + goto done; - if (clip->data == NULL) { - const BoxRec *box = &clip->extents; + if (clip.data == NULL) { + const BoxRec *box = &clip.extents; while (n--) { BoxRec r; @@ -5008,7 +4988,7 @@ sna_poly_fill_rect_tiled(DrawablePtr drawable, rect++; region.data = NULL; - RegionIntersect(®ion, ®ion, clip); + RegionIntersect(®ion, ®ion, &clip); nbox = REGION_NUM_RECTS(®ion); box = REGION_RECTS(®ion); @@ -5059,8 +5039,11 @@ sna_poly_fill_rect_tiled(DrawablePtr drawable, RegionUninit(®ion); } } - copy.done(sna, ©); + + RegionUninit(&clip); } +done: + copy.done(sna, ©); return TRUE; } @@ -5131,6 +5114,7 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect) if (gc->fillStyle == FillSolid || (gc->fillStyle == FillTiled && gc->tileIsPixel)) { struct sna_pixmap *priv = sna_pixmap_from_drawable(draw); + uint32_t color = gc->fillStyle == FillSolid ? gc->fgPixel : gc->tile.pixel; DBG(("%s: solid fill [%08lx], testing for blt\n", __FUNCTION__, @@ -5140,7 +5124,7 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect) sna_poly_fill_rect_blt(draw, priv->gpu_bo, priv->gpu_only ? NULL : reduce_damage(draw, &priv->gpu_damage, ®ion.extents), - gc, n, rect, + gc, color, n, rect, ®ion.extents, flags & 2)) return; @@ -5148,7 +5132,7 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect) sna_poly_fill_rect_blt(draw, priv->cpu_bo, reduce_damage(draw, &priv->cpu_damage, ®ion.extents), - gc, n, rect, + gc, color, n, rect, ®ion.extents, flags & 2)) return; } else if (gc->fillStyle == FillTiled) { @@ -5160,14 +5144,16 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect) sna_poly_fill_rect_tiled(draw, priv->gpu_bo, priv->gpu_only ? NULL : reduce_damage(draw, &priv->gpu_damage, ®ion.extents), - gc, n, rect)) + gc, n, rect, + ®ion.extents, flags & 2)) return; if (sna_drawable_use_cpu_bo(draw, ®ion.extents) && sna_poly_fill_rect_tiled(draw, priv->cpu_bo, reduce_damage(draw, &priv->cpu_damage, ®ion.extents), - gc, n, rect)) + gc, n, rect, + ®ion.extents, flags & 2)) return; } |