diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-07-10 12:43:46 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-07-10 18:37:04 +0100 |
commit | 85fdc3143b157fd7ba3453efc86da8238d9de316 (patch) | |
tree | ad0631ef635ffec57c9b1c5b12410efc2dd8d7ba /src | |
parent | 747ed0ca28bb46fc45ff20acd1f82212fa2b46bd (diff) |
sna: Avoid the expensive recomputation of the region when copying
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src')
-rw-r--r-- | src/sna/kgem.h | 2 | ||||
-rw-r--r-- | src/sna/sna_accel.c | 445 | ||||
-rw-r--r-- | src/sna/sna_trapezoids.c | 2 |
3 files changed, 275 insertions, 174 deletions
diff --git a/src/sna/kgem.h b/src/sna/kgem.h index 8d01807b..44d43274 100644 --- a/src/sna/kgem.h +++ b/src/sna/kgem.h @@ -433,7 +433,7 @@ static inline bool kgem_bo_blt_pitch_is_ok(struct kgem *kgem, pitch /= 4; if (pitch > MAXSHORT) { DBG(("%s: can not blt to handle=%d, adjusted pitch=%d\n", - __FUNCTION__, pitch)); + __FUNCTION__, bo->handle, pitch)); return false; } diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 5a37a281..192d8439 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -3673,10 +3673,8 @@ move_to_gpu(PixmapPtr pixmap, struct sna_pixmap *priv, static void sna_self_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, - BoxPtr box, int n, - int dx, int dy, - Bool reverse, Bool upsidedown, Pixel bitplane, - void *closure) + RegionPtr region,int dx, int dy, + Pixel bitplane, void *closure) { PixmapPtr pixmap = get_drawable_pixmap(src); struct sna *sna = to_sna_from_pixmap(pixmap); @@ -3684,12 +3682,14 @@ sna_self_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, int alu = gc ? gc->alu : GXcopy; int16_t tx, ty; - if (n == 0 || ((dx | dy) == 0 && alu == GXcopy)) + assert(RegionNumRects(region)); + if (((dx | dy) == 0 && alu == GXcopy)) return; DBG(("%s (boxes=%dx[(%d, %d), (%d, %d)...], src=+(%d, %d), alu=%d, pix.size=%dx%d)\n", - __FUNCTION__, n, - box[0].x1, box[0].y1, box[0].x2, box[0].y2, + __FUNCTION__, RegionNumRects(region), + region->extents.x1, region->extents.y1, + region->extents.x2, region->extents.y2, dx, dy, alu, pixmap->drawable.width, pixmap->drawable.height)); @@ -3713,27 +3713,32 @@ sna_self_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, if (!sna->render.copy_boxes(sna, alu, pixmap, priv->gpu_bo, dx, dy, pixmap, priv->gpu_bo, tx, ty, - box, n, 0)) { + RegionRects(region), + RegionNumRects(region), + 0)) { DBG(("%s: fallback - accelerated copy boxes failed\n", __FUNCTION__)); goto fallback; } - if (!DAMAGE_IS_ALL(priv->gpu_damage)) - sna_damage_add_boxes(&priv->gpu_damage, box, n, tx, ty); + if (!DAMAGE_IS_ALL(priv->gpu_damage)) { + RegionTranslate(region, tx, ty); + sna_damage_add(&priv->gpu_damage, region); + } assert_pixmap_damage(pixmap); } else { - FbBits *dst_bits, *src_bits; - int stride, bpp; - fallback: DBG(("%s: fallback", __FUNCTION__)); if (!sna_pixmap_move_to_cpu(pixmap, MOVE_READ | MOVE_WRITE)) return; - stride = pixmap->devKind; - bpp = pixmap->drawable.bitsPerPixel; - if (alu == GXcopy && bpp >= 8) { + if (alu == GXcopy && pixmap->drawable.bitsPerPixel >= 8) { + BoxPtr box = RegionRects(region); + int n = RegionNumRects(region); + FbBits *dst_bits, *src_bits; + int stride = pixmap->devKind; + int bpp = pixmap->drawable.bitsPerPixel; + dst_bits = (FbBits *) ((char *)pixmap->devPrivate.ptr + ty * stride + tx * bpp / 8); @@ -3748,26 +3753,15 @@ fallback: box++; } while (--n); } else { - DBG(("%s: alu==GXcopy? %d, reverse? %d, upsidedown? %d, bpp? %d\n", - __FUNCTION__, alu == GXcopy, reverse, upsidedown, bpp)); - dst_bits = pixmap->devPrivate.ptr; - stride /= sizeof(FbBits); - do { - fbBlt(dst_bits + (box->y1 + dy) * stride, - stride, - (box->x1 + dx) * bpp, - - dst_bits + (box->y1 + ty) * stride, - stride, - (box->x1 + tx) * bpp, + if (!sna_gc_move_to_cpu(gc, dst, region)) + return; - (box->x2 - box->x1) * bpp, - (box->y2 - box->y1), + get_drawable_deltas(src, pixmap, &tx, &ty); + miCopyRegion(src, dst, gc, + region, dx - tx, dy - ty, + fbCopyNtoN, 0, NULL); - alu, -1, bpp, - reverse, upsidedown); - box++; - } while (--n); + sna_gc_move_to_gpu(gc); } } } @@ -3797,10 +3791,8 @@ source_prefer_gpu(struct sna_pixmap *priv) static void sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, - BoxPtr box, int n, - int dx, int dy, - Bool reverse, Bool upsidedown, Pixel bitplane, - void *closure) + RegionPtr region, int dx, int dy, + Pixel bitplane, void *closure) { PixmapPtr src_pixmap = get_drawable_pixmap(src); struct sna_pixmap *src_priv = sna_pixmap(src_pixmap); @@ -3812,9 +3804,10 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, int alu = gc ? gc->alu : GXcopy; int16_t src_dx, src_dy; int16_t dst_dx, dst_dy; + BoxPtr box = RegionRects(region); + int n = RegionNumRects(region); int stride, bpp; char *bits; - RegionRec region; Bool replaces; if (n == 0) @@ -3822,10 +3815,8 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, if (src_pixmap == dst_pixmap) return sna_self_copy_boxes(src, dst, gc, - box, n, - dx, dy, - reverse, upsidedown, bitplane, - closure); + region, dx, dy, + bitplane, closure); DBG(("%s (boxes=%dx[(%d, %d), (%d, %d)...], src=+(%d, %d), alu=%d, src.size=%dx%d, dst.size=%dx%d)\n", __FUNCTION__, n, @@ -3837,8 +3828,6 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, assert_pixmap_damage(dst_pixmap); assert_pixmap_damage(src_pixmap); - pixman_region_init_rects(®ion, box, n); - bpp = dst_pixmap->drawable.bitsPerPixel; get_drawable_deltas(dst, dst_pixmap, &dst_dx, &dst_dy); @@ -3846,11 +3835,15 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, src_dx += dx; src_dy += dy; + RegionTranslate(region, dst_dx, dst_dy); + src_dx -= dst_dx; + src_dy -= dst_dy; + replaces = n == 1 && - box->x1 + dst_dx <= 0 && - box->y1 + dst_dy <= 0 && - box->x2 + dst_dx >= dst_pixmap->drawable.width && - box->y2 + dst_dy >= dst_pixmap->drawable.height; + box->x1 <= 0 && + box->y1 <= 0 && + box->x2 >= dst_pixmap->drawable.width && + box->y2 >= dst_pixmap->drawable.height; DBG(("%s: dst=(priv=%p, gpu_bo=%p, cpu_bo=%p), src=(priv=%p, gpu_bo=%p, cpu_bo=%p), replaces=%d\n", __FUNCTION__, @@ -3862,14 +3855,12 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, src_priv ? src_priv->cpu_bo : NULL, replaces)); - RegionTranslate(®ion, dst_dx, dst_dy); - if (dst_priv == NULL) goto fallback; if (dst_priv->cpu_damage && alu_overwrites(alu)) { DBG(("%s: overwritting CPU damage\n", __FUNCTION__)); - sna_damage_subtract(&dst_priv->cpu_damage, ®ion); + sna_damage_subtract(&dst_priv->cpu_damage, region); if (dst_priv->cpu_damage == NULL) { list_del(&dst_priv->list); dst_priv->undamaged = false; @@ -3879,15 +3870,15 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, bo = sna_drawable_use_bo(&dst_pixmap->drawable, source_prefer_gpu(src_priv) ?: - region_inplace(sna, dst_pixmap, ®ion, + region_inplace(sna, dst_pixmap, region, dst_priv, alu_overwrites(alu)), - ®ion.extents, &damage); + ®ion->extents, &damage); if (bo) { if (src_priv && src_priv->clear) { DBG(("%s: applying src clear[%08x] to dst\n", __FUNCTION__, src_priv->clear_color)); assert_pixmap_contains_box(dst_pixmap, - RegionExtents(®ion)); + RegionExtents(region)); if (n == 1) { if (!sna->render.fill_one(sna, dst_pixmap, bo, @@ -3915,19 +3906,19 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, } if (damage) - sna_damage_add(damage, ®ion); + sna_damage_add(damage, region); - goto out; + return; } if (src_priv && - move_to_gpu(src_pixmap, src_priv, ®ion.extents, alu) && + move_to_gpu(src_pixmap, src_priv, ®ion->extents, alu) && sna_pixmap_move_to_gpu(src_pixmap, MOVE_READ)) { DBG(("%s: move whole src_pixmap to GPU and copy\n", __FUNCTION__)); if (!sna->render.copy_boxes(sna, alu, src_pixmap, src_priv->gpu_bo, src_dx, src_dy, - dst_pixmap, bo, dst_dx, dst_dy, + dst_pixmap, bo, 0, 0, box, n, 0)) { DBG(("%s: fallback - accelerated copy boxes failed\n", __FUNCTION__)); @@ -3936,21 +3927,21 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, if (damage) { assert_pixmap_contains_box(dst_pixmap, - RegionExtents(®ion)); - sna_damage_add(damage, ®ion); + RegionExtents(region)); + sna_damage_add(damage, region); } - goto out; + return; } if (src_priv && - region_overlaps_damage(®ion, src_priv->gpu_damage, + region_overlaps_damage(region, src_priv->gpu_damage, src_dx, src_dy)) { BoxRec area; DBG(("%s: region overlaps GPU damage, upload and copy\n", __FUNCTION__)); - area = region.extents; + area = region->extents; area.x1 += src_dx; area.x2 += src_dx; area.y1 += src_dy; @@ -3962,7 +3953,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, if (!sna->render.copy_boxes(sna, alu, src_pixmap, src_priv->gpu_bo, src_dx, src_dy, - dst_pixmap, bo, dst_dx, dst_dy, + dst_pixmap, bo, 0, 0, box, n, 0)) { DBG(("%s: fallback - accelerated copy boxes failed\n", __FUNCTION__)); @@ -3971,10 +3962,10 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, if (damage) { assert_pixmap_contains_box(dst_pixmap, - RegionExtents(®ion)); - sna_damage_add(damage, ®ion); + RegionExtents(region)); + sna_damage_add(damage, region); } - goto out; + return; } if (bo != dst_priv->gpu_bo) @@ -3988,17 +3979,17 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, assert(bo != dst_priv->cpu_bo); - RegionTranslate(®ion, src_dx-dst_dx, src_dy-dst_dy); + RegionTranslate(region, src_dx, src_dy); ret = sna_drawable_move_region_to_cpu(&src_pixmap->drawable, - ®ion, + region, MOVE_READ | MOVE_ASYNC_HINT); - RegionTranslate(®ion, dst_dx-src_dx, dst_dy-src_dy); + RegionTranslate(region, -src_dx, -src_dy); if (!ret) goto fallback; if (!sna->render.copy_boxes(sna, alu, src_pixmap, src_priv->cpu_bo, src_dx, src_dy, - dst_pixmap, bo, dst_dx, dst_dy, + dst_pixmap, bo, 0, 0, box, n, 0)) { DBG(("%s: fallback - accelerated copy boxes failed\n", __FUNCTION__)); @@ -4007,10 +3998,10 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, if (damage) { assert_pixmap_contains_box(dst_pixmap, - RegionExtents(®ion)); - sna_damage_add(damage, ®ion); + RegionExtents(region)); + sna_damage_add(damage, region); } - goto out; + return; } if (alu != GXcopy) { @@ -4023,15 +4014,15 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, __FUNCTION__, alu)); tmp = sna_pixmap_create_upload(src->pScreen, - region.extents.x2 - region.extents.x1, - region.extents.y2 - region.extents.y1, + region->extents.x2 - region->extents.x1, + region->extents.y2 - region->extents.y1, src->depth, KGEM_BUFFER_WRITE_INPLACE); if (tmp == NullPixmap) - goto out; + return; - dx = -region.extents.x1; - dy = -region.extents.y1; + dx = -region->extents.x1; + dy = -region->extents.y1; for (i = 0; i < n; i++) { assert(box[i].x1 + src_dx >= 0); assert(box[i].y1 + src_dy >= 0); @@ -4058,7 +4049,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, if (!sna->render.copy_boxes(sna, alu, tmp, sna_pixmap_get_bo(tmp), dx, dy, - dst_pixmap, bo, dst_dx, dst_dy, + dst_pixmap, bo, 0, 0, box, n, 0)) { DBG(("%s: fallback - accelerated copy boxes failed\n", __FUNCTION__)); @@ -4069,10 +4060,10 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, if (damage) { assert_pixmap_contains_box(dst_pixmap, - RegionExtents(®ion)); - sna_damage_add(damage, ®ion); + RegionExtents(region)); + sna_damage_add(damage, region); } - goto out; + return; } else { DBG(("%s: dst is on the GPU, src is on the CPU, uploading into dst\n", __FUNCTION__)); @@ -4085,7 +4076,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, } if (src_pixmap->devPrivate.ptr == NULL) { if (!src_priv->ptr) /* uninitialised!*/ - goto out; + return; assert(src_priv->stride); src_pixmap->devPrivate.ptr = src_priv->ptr; src_pixmap->devKind = src_priv->stride; @@ -4104,7 +4095,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, } else { assert(!DAMAGE_IS_ALL(dst_priv->cpu_damage)); if (!sna_write_boxes(sna, dst_pixmap, - dst_priv->gpu_bo, dst_dx, dst_dy, + dst_priv->gpu_bo, 0, 0, src_pixmap->devPrivate.ptr, src_pixmap->devKind, src_dx, src_dy, @@ -4123,15 +4114,15 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, dst_priv->undamaged = false; } else { assert_pixmap_contains_box(dst_pixmap, - RegionExtents(®ion)); + RegionExtents(region)); sna_damage_add(&dst_priv->gpu_damage, - ®ion); + region); } assert_pixmap_damage(dst_pixmap); } } - goto out; + return; } fallback: @@ -4141,19 +4132,19 @@ fallback: if (dst_priv) { assert_pixmap_contains_box(dst_pixmap, - RegionExtents(®ion)); + RegionExtents(region)); if (!sna_drawable_move_region_to_cpu(&dst_pixmap->drawable, - ®ion, + region, MOVE_WRITE | MOVE_INPLACE_HINT)) - goto out; + return; } do { pixman_fill(dst_pixmap->devPrivate.ptr, dst_pixmap->devKind/sizeof(uint32_t), dst_pixmap->drawable.bitsPerPixel, - box->x1 + dst_dx, box->y1 + dst_dy, + box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1, src_priv->clear_color); @@ -4168,68 +4159,65 @@ fallback: if (src_priv) { unsigned mode; - RegionTranslate(®ion, src_dx-dst_dx, src_dy-dst_dy); + RegionTranslate(region, src_dx, src_dy); assert_pixmap_contains_box(src_pixmap, - RegionExtents(®ion)); + RegionExtents(region)); mode = MOVE_READ; if (src_priv->cpu_bo == NULL) mode |= MOVE_INPLACE_HINT; if (!sna_drawable_move_region_to_cpu(&src_pixmap->drawable, - ®ion, mode)) - goto out; + region, mode)) + return; - RegionTranslate(®ion, dst_dx-src_dx, dst_dy-src_dy); + RegionTranslate(region, -src_dx, -src_dy); } if (dst_priv) { unsigned mode; assert_pixmap_contains_box(dst_pixmap, - RegionExtents(®ion)); + RegionExtents(region)); if (alu_overwrites(alu)) mode = MOVE_WRITE | MOVE_INPLACE_HINT; else mode = MOVE_WRITE | MOVE_READ; if (!sna_drawable_move_region_to_cpu(&dst_pixmap->drawable, - ®ion, mode)) - goto out; + region, mode)) + return; } dst_stride = dst_pixmap->devKind; src_stride = src_pixmap->devKind; if (alu == GXcopy && bpp >= 8) { - dst_bits = (FbBits *) - ((char *)dst_pixmap->devPrivate.ptr + - dst_dy * dst_stride + dst_dx * bpp / 8); + dst_bits = (FbBits *)dst_pixmap->devPrivate.ptr; src_bits = (FbBits *) ((char *)src_pixmap->devPrivate.ptr + src_dy * src_stride + src_dx * bpp / 8); do { - DBG(("%s: memcpy_blt(box=(%d, %d), (%d, %d), src=(%d, %d), dst=(%d, %d), pitches=(%d, %d))\n", + DBG(("%s: memcpy_blt(box=(%d, %d), (%d, %d), src=(%d, %d), pitches=(%d, %d))\n", __FUNCTION__, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1, src_dx, src_dy, - dst_dx, dst_dy, src_stride, dst_stride)); + assert(box->x1 >= 0); + assert(box->y1 >= 0); + assert(box->x2 <= dst_pixmap->drawable.width); + assert(box->y2 <= dst_pixmap->drawable.height); + assert(box->x1 + src_dx >= 0); assert(box->y1 + src_dy >= 0); assert(box->x2 + src_dx <= src_pixmap->drawable.width); assert(box->y2 + src_dy <= src_pixmap->drawable.height); - assert(box->x1 + dst_dx >= 0); - assert(box->y1 + dst_dy >= 0); - assert(box->x2 + dst_dx <= dst_pixmap->drawable.width); - assert(box->y2 + dst_dy <= dst_pixmap->drawable.height); - memcpy_blt(src_bits, dst_bits, bpp, src_stride, dst_stride, box->x1, box->y1, @@ -4239,42 +4227,144 @@ fallback: box++; } while (--n); } else { - DBG(("%s: alu==GXcopy? %d, reverse? %d, upsidedown? %d, bpp? %d\n", - __FUNCTION__, alu == GXcopy, reverse, upsidedown, bpp)); - dst_bits = dst_pixmap->devPrivate.ptr; - src_bits = src_pixmap->devPrivate.ptr; + DBG(("%s: fallback -- miCopyRegion\n", __FUNCTION__)); - dst_stride /= sizeof(FbBits); - src_stride /= sizeof(FbBits); - do { - DBG(("%s: fbBlt (%d, %d), (%d, %d)\n", - __FUNCTION__, - box->x1, box->y1, - box->x2, box->y2)); - assert(box->x1 + src_dx >= 0); - assert(box->y1 + src_dy >= 0); - assert(box->x1 + dst_dx >= 0); - assert(box->y1 + dst_dy >= 0); - fbBlt(src_bits + (box->y1 + src_dy) * src_stride, - src_stride, - (box->x1 + src_dx) * bpp, + RegionTranslate(region, -dst_dx, -dst_dy); - dst_bits + (box->y1 + dst_dy) * dst_stride, - dst_stride, - (box->x1 + dst_dx) * bpp, + if (!sna_gc_move_to_cpu(gc, dst, region)) + return; - (box->x2 - box->x1) * bpp, - (box->y2 - box->y1), + miCopyRegion(src, dst, gc, + region, dx, dy, + fbCopyNtoN, 0, NULL); - alu, -1, bpp, - reverse, upsidedown); - box++; - } while (--n); + sna_gc_move_to_gpu(gc); + } + } +} + +typedef void (*sna_copy_func)(DrawablePtr src, DrawablePtr dst, GCPtr gc, + RegionPtr region, int dx, int dy, + Pixel bitPlane, void *closure); + +static RegionPtr +sna_do_copy(DrawablePtr src, DrawablePtr dst, GCPtr gc, + int sx, int sy, + int width, int height, + int dx, int dy, + sna_copy_func copy, Pixel bitPlane, void *closure) +{ + RegionPtr clip = NULL, free_clip = NULL; + RegionRec region; + bool expose = false; + + /* Short cut for unmapped windows */ + if (dst->type == DRAWABLE_WINDOW && !((WindowPtr)dst)->realized) + return NULL; + + if (src->pScreen->SourceValidate) + src->pScreen->SourceValidate(src, sx, sy, + width, height, + gc->subWindowMode); + + sx += src->x; + sy += src->y; + + dx += dst->x; + dy += dst->y; + + region.extents.x1 = dx; + region.extents.y1 = dy; + region.extents.x2 = dx + width; + region.extents.y2 = dy + height; + region.data = NULL; + + { + BoxPtr box = &gc->pCompositeClip->extents; + if (region.extents.x1 < box->x1) + region.extents.x1 = box->x1; + if (region.extents.x2 > box->x2) + region.extents.x2 = box->x2; + if (region.extents.y1 < box->y1) + region.extents.y1 = box->y1; + if (region.extents.y2 > box->y2) + region.extents.y2 = box->y2; + } + if (box_empty(®ion.extents)) + return NULL; + + region.extents.x1 += sx - dx; + region.extents.x2 += sx - dx; + region.extents.y1 += sy - dy; + region.extents.y2 += sy - dy; + + /* Compute source clip region */ + if (src->type == DRAWABLE_PIXMAP) { + if (src == dst && gc->clientClipType == CT_NONE) + clip = gc->pCompositeClip; + } else { + if (gc->subWindowMode == IncludeInferiors) { + /* + * XFree86 DDX empties the border clip when the + * VT is inactive, make sure the region isn't empty + */ + if (!((WindowPtr) src)->parent && + RegionNotEmpty(&((WindowPtr) src)->borderClip)) { + /* + * special case bitblt from root window in + * IncludeInferiors mode; just like from a pixmap + */ + } else if (src == dst && gc->clientClipType == CT_NONE) { + clip = gc->pCompositeClip; + } else { + free_clip = clip = + NotClippedByChildren((WindowPtr) src); + } + } else + clip = &((WindowPtr)src)->clipList; + } + if (clip == NULL) { + expose = true; + if (region.extents.x1 < src->x) { + region.extents.x1 = src->x; + expose = false; } + if (region.extents.y1 < src->y) { + region.extents.y1 = src->y; + expose = false; + } + if (region.extents.x2 > src->x + (int) src->width) { + region.extents.x2 = src->x + (int) src->width; + expose = false; + } + if (region.extents.y2 > src->y + (int) src->height) { + region.extents.y2 = src->y + (int) src->height; + expose = false; + } + if (box_empty(®ion.extents)) + return NULL; + } else { + RegionIntersect(®ion, ®ion, clip); + if (free_clip) + RegionDestroy(free_clip); } + RegionTranslate(®ion, dx-sx, dy-sy); + if (gc->pCompositeClip->data) + RegionIntersect(®ion, ®ion, gc->pCompositeClip); -out: + if (RegionNotEmpty(®ion)) + copy(src, dst, gc, ®ion, sx-dx, sy-dy, bitPlane, closure); RegionUninit(®ion); + + /* Pixmap sources generate a NoExposed (we return NULL to do this) */ + clip = NULL; + if (!expose && gc->fExpose) + clip = miHandleExposures(src, dst, gc, + sx - src->x, sy - src->y, + width, height, + dx - dst->x, dy - dst->y, + (unsigned long) bitPlane); + return clip; } static RegionPtr @@ -4367,12 +4457,12 @@ out: return ret; } - return miDoCopy(src, dst, gc, - src_x, src_y, - width, height, - dst_x, dst_y, - src == dst ? sna_self_copy_boxes : sna_copy_boxes, - 0, NULL); + return sna_do_copy(src, dst, gc, + src_x, src_y, + width, height, + dst_x, dst_y, + src == dst ? sna_self_copy_boxes : sna_copy_boxes, + 0, NULL); } inline static Bool @@ -5350,10 +5440,8 @@ struct sna_copy_plane { static void sna_copy_bitmap_blt(DrawablePtr _bitmap, DrawablePtr drawable, GCPtr gc, - BoxPtr box, int n, - int sx, int sy, - Bool reverse, Bool upsidedown, Pixel bitplane, - void *closure) + RegionRec *region, int sx, int sy, + Pixel bitplane, void *closure) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); @@ -5361,17 +5449,20 @@ sna_copy_bitmap_blt(DrawablePtr _bitmap, DrawablePtr drawable, GCPtr gc, PixmapPtr bitmap = (PixmapPtr)_bitmap; uint32_t br00, br13; int16_t dx, dy; + BoxPtr box; + int n; - DBG(("%s: plane=%x x%d\n", __FUNCTION__, (unsigned)bitplane, n)); + DBG(("%s: plane=%x (%d,%d),(%d,%d)x%d\n", + __FUNCTION__, (unsigned)bitplane, RegionNumRects(region), + region->extents.x1, region->extents.y1, + region->extents.x2, region->extents.y2)); - if (n == 0) - return; + box = RegionRects(region); + n = RegionNumRects(region); + assert(n); get_drawable_deltas(drawable, pixmap, &dx, &dy); assert_pixmap_contains_boxes(pixmap, box, n, dx, dy); - if (arg->damage) - sna_damage_add_boxes(arg->damage, box, n, dx, dy); - assert_pixmap_damage(pixmap); br00 = 3 << 20; br13 = arg->bo->pitch; @@ -5501,15 +5592,18 @@ sna_copy_bitmap_blt(DrawablePtr _bitmap, DrawablePtr drawable, GCPtr gc, box++; } while (--n); + if (arg->damage) { + RegionTranslate(region, dx, dy); + sna_damage_add(arg->damage, region); + } + assert_pixmap_damage(pixmap); sna->blt_state.fill_bo = 0; } static void sna_copy_plane_blt(DrawablePtr source, DrawablePtr drawable, GCPtr gc, - BoxPtr box, int n, - int sx, int sy, - Bool reverse, Bool upsidedown, Pixel bitplane, - void *closure) + RegionPtr region, int sx, int sy, + Pixel bitplane, void *closure) { PixmapPtr dst_pixmap = get_drawable_pixmap(drawable); PixmapPtr src_pixmap = get_drawable_pixmap(source); @@ -5518,6 +5612,8 @@ sna_copy_plane_blt(DrawablePtr source, DrawablePtr drawable, GCPtr gc, int16_t dx, dy; int bit = ffs(bitplane) - 1; uint32_t br00, br13; + BoxPtr box = RegionRects(region); + int n = RegionNumRects(region); DBG(("%s: plane=%x [%d] x%d\n", __FUNCTION__, (unsigned)bitplane, bit, n)); @@ -5531,9 +5627,6 @@ sna_copy_plane_blt(DrawablePtr source, DrawablePtr drawable, GCPtr gc, get_drawable_deltas(drawable, dst_pixmap, &dx, &dy); assert_pixmap_contains_boxes(dst_pixmap, box, n, dx, dy); - if (arg->damage) - sna_damage_add_boxes(arg->damage, box, n, dx, dy); - assert_pixmap_damage(dst_pixmap); br00 = XY_MONO_SRC_COPY; if (drawable->bitsPerPixel == 32) @@ -5707,6 +5800,11 @@ sna_copy_plane_blt(DrawablePtr source, DrawablePtr drawable, GCPtr gc, box++; } while (--n); + if (arg->damage) { + RegionTranslate(region, dx, dy); + sna_damage_add(arg->damage, region); + } + assert_pixmap_damage(dst_pixmap); sna->blt_state.fill_bo = 0; } @@ -5802,12 +5900,12 @@ sna_copy_plane(DrawablePtr src, DrawablePtr dst, GCPtr gc, } } RegionUninit(®ion); - return miDoCopy(src, dst, gc, - src_x, src_y, - w, h, - dst_x, dst_y, - src->depth == 1 ? sna_copy_bitmap_blt :sna_copy_plane_blt, - (Pixel)bit, &arg); + return sna_do_copy(src, dst, gc, + src_x, src_y, + w, h, + dst_x, dst_y, + src->depth == 1 ? sna_copy_bitmap_blt : sna_copy_plane_blt, + (Pixel)bit, &arg); } fallback: @@ -12105,8 +12203,11 @@ sna_copy_window(WindowPtr win, DDXPointRec origin, RegionPtr src) RegionNull(&dst); RegionIntersect(&dst, &win->borderClip, src); + if (!RegionNotEmpty(&dst)) + return; + #ifdef COMPOSITE - if (pixmap->screen_x || pixmap->screen_y) + if (pixmap->screen_x | pixmap->screen_y) RegionTranslate(&dst, -pixmap->screen_x, -pixmap->screen_y); #endif @@ -12118,8 +12219,8 @@ sna_copy_window(WindowPtr win, DDXPointRec origin, RegionPtr src) miCopyRegion(&pixmap->drawable, &pixmap->drawable, 0, &dst, dx, dy, fbCopyNtoN, 0, NULL); } else { - miCopyRegion(&pixmap->drawable, &pixmap->drawable, - NULL, &dst, dx, dy, sna_self_copy_boxes, 0, NULL); + sna_self_copy_boxes(&pixmap->drawable, &pixmap->drawable, NULL, + &dst, dx, dy, 0, NULL); } RegionUninit(&dst); @@ -12389,7 +12490,7 @@ static void sna_accel_flush(struct sna *sna) struct sna_pixmap *priv = sna_accel_scanout(sna); bool busy; - DBG(("%s (time=%ld), cpu damage? %p, exec? %d nbatch=%d, busy? %d\n", + DBG(("%s (time=%ld), cpu damage? %d, exec? %d nbatch=%d, busy? %d\n", __FUNCTION__, (long)TIME, priv && priv->cpu_damage, priv && priv->gpu_bo->exec != NULL, diff --git a/src/sna/sna_trapezoids.c b/src/sna/sna_trapezoids.c index 744818f5..2341cb38 100644 --- a/src/sna/sna_trapezoids.c +++ b/src/sna/sna_trapezoids.c @@ -3184,7 +3184,7 @@ composite_unaligned_boxes_inplace__solid(CARD8 op, uint32_t color, /* XXX a8 boxes */ if (!(dst->format == PICT_a8r8g8b8 || dst->format == PICT_x8r8g8b8)) { DBG(("%s: fallback -- can not perform operation in place, unhanbled format %08lx\n", - __FUNCTION__, dst->format)); + __FUNCTION__, (long)dst->format)); goto pixman; } |