NEWS | 68 configure.ac | 169 + src/Makefile.am | 3 src/common.h | 107 src/compat-api.h | 105 src/i830_render.c | 17 src/i915_render.c | 449 +-- src/i915_video.c | 2 src/i965_render.c | 256 +- src/i965_video.c | 2 src/intel.h | 34 src/intel_batchbuffer.c | 41 src/intel_batchbuffer.h | 5 src/intel_display.c | 331 ++ src/intel_dri.c | 144 - src/intel_driver.c | 216 - src/intel_driver.h | 3 src/intel_glamor.c | 32 src/intel_hwmc.c | 2 src/intel_list.h | 19 src/intel_memory.c | 2 src/intel_module.c | 115 src/intel_options.c | 52 src/intel_options.h | 49 src/intel_shadow.c | 4 src/intel_uxa.c | 109 src/intel_video.c | 26 src/legacy/i810/Makefile.am | 14 src/legacy/i810/i810.h | 15 src/legacy/i810/i810_accel.c | 10 src/legacy/i810/i810_common.h | 2 src/legacy/i810/i810_cursor.c | 6 src/legacy/i810/i810_dga.c | 26 src/legacy/i810/i810_dri.c | 132 - src/legacy/i810/i810_driver.c | 729 ++--- src/legacy/i810/i810_hwmc.c | 4 src/legacy/i810/i810_video.c | 111 src/legacy/legacy.h | 2 src/sna/Makefile.am | 22 src/sna/blt.c | 170 + src/sna/compiler.h | 2 src/sna/fb/Makefile.am | 38 src/sna/fb/README | 1 src/sna/fb/fb.h | 559 ++++ src/sna/fb/fbarc.c | 122 src/sna/fb/fbarcbits.h | 204 + src/sna/fb/fbbitmap.c | 142 + src/sna/fb/fbblt.c | 322 ++ src/sna/fb/fbbltone.c | 413 +++ src/sna/fb/fbclip.c | 87 src/sna/fb/fbclip.h | 92 src/sna/fb/fbcopy.c | 240 + src/sna/fb/fbfill.c | 235 + src/sna/fb/fbgc.c | 192 + src/sna/fb/fbglyph.c | 277 ++ src/sna/fb/fbglyphbits.h | 140 + src/sna/fb/fbimage.c | 254 ++ src/sna/fb/fbline.c | 179 + src/sna/fb/fblinebits.h | 284 ++ src/sna/fb/fbpict.c | 330 ++ src/sna/fb/fbpict.h | 45 src/sna/fb/fbpoint.c | 120 src/sna/fb/fbpointbits.h | 110 src/sna/fb/fbpush.c | 177 + src/sna/fb/fbrop.h | 111 src/sna/fb/fbseg.c | 563 ++++ src/sna/fb/fbsegbits.h | 212 + src/sna/fb/fbspan.c | 131 + src/sna/fb/fbstipple.c | 223 + src/sna/fb/fbtile.c | 152 + src/sna/fb/fbutil.c | 126 + src/sna/fb/sfb.h | 40 src/sna/gen2_render.c | 459 +-- src/sna/gen3_render.c | 842 ++++-- src/sna/gen4_render.c | 871 ++++-- src/sna/gen5_render.c | 901 ++++--- src/sna/gen6_render.c | 1031 ++++---- src/sna/gen7_render.c | 1345 ++++++---- src/sna/kgem.c | 1827 ++++++++++---- src/sna/kgem.h | 153 - src/sna/kgem_debug.c | 4 src/sna/kgem_debug_gen2.c | 4 src/sna/kgem_debug_gen3.c | 99 src/sna/kgem_debug_gen4.c | 6 src/sna/kgem_debug_gen5.c | 6 src/sna/kgem_debug_gen6.c | 22 src/sna/kgem_debug_gen7.c | 45 src/sna/sna.h | 279 +- src/sna/sna_accel.c | 5282 +++++++++++++++++++++++++----------------- src/sna/sna_blt.c | 554 ++-- src/sna/sna_composite.c | 297 +- src/sna/sna_damage.c | 324 +- src/sna/sna_damage.h | 26 src/sna/sna_display.c | 2352 ++++++++++++------ src/sna/sna_dri.c | 1692 +++++++------ src/sna/sna_driver.c | 424 +-- src/sna/sna_glyphs.c | 840 +++++- src/sna/sna_gradient.c | 86 src/sna/sna_io.c | 223 - src/sna/sna_module.h | 4 src/sna/sna_render.c | 518 ++-- src/sna/sna_render.h | 115 src/sna/sna_render_inline.h | 79 src/sna/sna_stream.c | 7 src/sna/sna_tiling.c | 324 ++ src/sna/sna_transform.c | 41 src/sna/sna_trapezoids.c | 2884 ++++++++++++++++++---- src/sna/sna_video.c | 118 src/sna/sna_video.h | 17 src/sna/sna_video_overlay.c | 50 src/sna/sna_video_sprite.c | 430 +++ src/sna/sna_video_textured.c | 28 test/Makefile.am | 9 test/basic-rectangle.c | 223 + test/basic-string.c | 102 test/dri2-swap.c | 172 + test/dri2.c | 668 +++++ test/dri2.h | 108 uxa/uxa-glyphs.c | 519 +--- uxa/uxa-priv.h | 4 uxa/uxa-render.c | 235 - uxa/uxa.c | 42 122 files changed, 25498 insertions(+), 10921 deletions(-)
New commits: commit 6a18a0936eafc45ab920ab0eecf2fc2a601c41a7 Author: Chris Wilson <ch...@chris-wilson.co.uk> Date: Sun Jul 15 20:26:00 2012 +0100 configure: version bump for 2.20.0 release The day SNA hits mainstream... Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk> diff --git a/NEWS b/NEWS index cc74879..8e30d9e 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,45 @@ +Release 2.12.0 (2012-07-15) +=========================== +First the big news, a new acceleration method that aims to be faster and +consume far less CPU than UXA is now available for selection at runtime. +This snazzy new architecture can be selected through use of + Option "AccelMethod" "sna" +in your xorg.conf. Whilst it has been under development for some time, it +has not yet had the same degree of widespread testing of UXA, so tread +lightly. Try it and if you spot anything that can be improved, please do +report a bug. + +Otherwise we have the usual smattering of bug fixes for UXA: + + * Use a white source whilst adding glyphs to the glyph mask + (This fixes blank glyphs if using a font that mixes ARGB and A glyphs.) + + * Avoid fallbacks for glyph-to-dst in e.g. gnome-terminal + https://bugs.freedesktop.org/show_bug.cgi?id=50508 + + * Force unused outputs off when VT switching + https://bugs.freedesktop.org/show_bug.cgi?id=50772 + + * Copy the fbcon across to the Screen pixmap at startup. + (This patch has been kicking around in the distributions for years.) + + * Many missed malloc failures checks and forgotten frees found by a static + analyzer. Thanks Zdenek Kabelac! + + * Leak of the back buffer when terminating an application after pageflipping + https://bugs.freedesktop.org/show_bug.cgi?id=50670 + + * Double check that the pipe is on before emitting a WAIT_ON_EVENT. + In conjunction with an uptodate kernel, this should eliminate any + hangs when changing resolutions or adding/removing displays. + https://bugs.freedesktop.org/show_bug.cgi?id=50668 + + * Update to new Xorg APIs. Future proofing for the next generation of + hotplug Xorg display servers. + +Many thanks to everyone who has reported a bug and otherwise helped to +improve the driver. + Release 2.19.0 (2012-04-29) =========================== More stability fixes for UXA and support for another variant of IvyBridge. diff --git a/configure.ac b/configure.ac index 8cbbbc1..90dae7e 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ # Initialize Autoconf AC_PREREQ([2.60]) AC_INIT([xf86-video-intel], - [2.19.0], + [2.20.0], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [xf86-video-intel]) AC_CONFIG_SRCDIR([Makefile.am]) commit 6fa059330decd1437eef4928d732ec91fd4e17e7 Author: Chris Wilson <ch...@chris-wilson.co.uk> Date: Sun Jul 15 14:04:48 2012 +0100 sna: Avoid creating a CPU bo for uploads if we already have a large GPU bo And vice-versa if already have a large CPU bo. Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk> diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index bc73dee..1734a8f 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -2990,6 +2990,19 @@ static bool upload_inplace(struct sna *sna, struct sna_pixmap *priv, RegionRec *region) { + if (priv->create & KGEM_CAN_CREATE_LARGE) { + if (priv->gpu_bo) { + DBG(("%s: yes, large buffer and already have GPU bo\n", + __FUNCTION__)); + return true; + } + if (priv->cpu_bo){ + DBG(("%s: no, large buffer and already have CPU bo\n", + __FUNCTION__)); + return false; + } + } + if (!region_inplace(sna, pixmap, region, priv, true)) { DBG(("%s? no, region not suitable\n", __FUNCTION__)); return false; commit a253c95ec63b2b075e66ae7380fed6a73469eba5 Author: Chris Wilson <ch...@chris-wilson.co.uk> Date: Sun Jul 15 13:32:35 2012 +0100 sna: Prefer uploads to be staged in snoopable bo Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk> diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 92aca23..bc73dee 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -2995,6 +2995,25 @@ static bool upload_inplace(struct sna *sna, return false; } + if (sna->kgem.has_llc) { + if (priv->cpu_bo) { + if (priv->cpu_damage && + kgem_bo_is_busy(priv->cpu_bo) && + !region_subsumes_damage(region, priv->cpu_damage)) { + DBG(("%s? yes, CPU bo is busy\n", __FUNCTION__)); + return true; + } + + DBG(("%s? no, have CPU bo\n", __FUNCTION__)); + return false; + } + + if (priv->create & KGEM_CAN_CREATE_CPU) { + DBG(("%s? no, can create CPU bo\n", __FUNCTION__)); + return false; + } + } + if (priv->gpu_bo) { assert(priv->gpu_bo->proxy == NULL); @@ -3016,13 +3035,6 @@ static bool upload_inplace(struct sna *sna, } - if (priv->cpu_bo) { - if (kgem_bo_is_busy(priv->cpu_bo)) { - DBG(("%s? yes, CPU bo is busy\n", __FUNCTION__)); - return true; - } - } - DBG(("%s? no\n", __FUNCTION__)); return false; } commit ef6d94a8444927941db108811e1a26357dc3f18e Author: Chris Wilson <ch...@chris-wilson.co.uk> Date: Sun Jul 15 11:46:53 2012 +0100 sna: Simply reverse all the boxes if dx <= 0 and dy <= 0 In this fairly common case, avoid both the double pass and use a simpler algorithm as we can simply reverse the order of the boxes. Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk> diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index ad12615..92aca23 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -3699,7 +3699,17 @@ reorder_boxes(BoxPtr box, int n, int dx, int dy) DBG(("%s x %d dx=%d, dy=%d\n", __FUNCTION__, n, dx, dy)); - if (dy < 0) { + if (dy <= 0 && dx <= 0) { + new = malloc(sizeof(BoxRec) * n); + if (new == NULL) + return NULL; + + tmp = new; + next = box + n; + do { + *tmp++ = *--next; + } while (next != box); + } else if (dy < 0) { new = malloc(sizeof(BoxRec) * n); if (new == NULL) return NULL; @@ -3714,16 +3724,11 @@ reorder_boxes(BoxPtr box, int n, int dx, int dy) base = next; } new -= n; - box = new; - } - - if (dx < 0) { + } else { new = malloc(sizeof(BoxRec) * n); - if (!new) { - if (dy < 0) - free(box); + if (!new) return NULL; - } + base = next = box; while (base < box + n) { while (next < box + n && next->y1 == base->y1) @@ -3734,10 +3739,9 @@ reorder_boxes(BoxPtr box, int n, int dx, int dy) base = next; } new -= n; - box = new; } - return box; + return new; } static void commit 6601a943ff968ac39ba198351c50dc883cb4232e Author: Chris Wilson <ch...@chris-wilson.co.uk> Date: Sun Jul 15 11:39:56 2012 +0100 sna: Keep track of the base pointer for the reordered boxes So that we avoid freeing an invalid pointer. Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk> diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index d3787c1..ad12615 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -3814,6 +3814,7 @@ fallback: FbBits *dst_bits, *src_bits; int stride = pixmap->devKind; int bpp = pixmap->drawable.bitsPerPixel; + int i; dst_bits = (FbBits *) ((char *)pixmap->devPrivate.ptr + @@ -3822,12 +3823,10 @@ fallback: ((char *)pixmap->devPrivate.ptr + dy * stride + dx * bpp / 8); - do { + for (i = 0; i < n; i++) memmove_box(src_bits, dst_bits, - bpp, stride, box, + bpp, stride, box+i, dx, dy); - box++; - } while (--n); } else { if (gc && !sna_gc_move_to_cpu(gc, dst, region)) goto out; commit ef34d5cf415ad7459ab44b0ec2e70b14150735fc Author: Chris Wilson <ch...@chris-wilson.co.uk> Date: Sat Jul 14 23:25:17 2012 +0100 sna: Make sure we check for a busy CPU bo before declaring is-cpu Even if the pixmap is entirely damaged on the CPU, we still may be in the process of transferring it and so cause an unwanted stall. Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk> diff --git a/src/sna/sna_render_inline.h b/src/sna/sna_render_inline.h index 32eb54e..fff5436 100644 --- a/src/sna/sna_render_inline.h +++ b/src/sna/sna_render_inline.h @@ -85,10 +85,9 @@ static inline bool is_cpu(DrawablePtr drawable) { struct sna_pixmap *priv = sna_pixmap_from_drawable(drawable); - if (priv == NULL || priv->gpu_bo == NULL || priv->clear || DAMAGE_IS_ALL(priv->cpu_damage)) + if (priv == NULL || priv->gpu_bo == NULL || priv->clear) return true; - assert(!priv->gpu_bo->proxy); /* should be marked as cpu damaged */ if (priv->gpu_damage && kgem_bo_is_busy(priv->gpu_bo)) return false; commit 0e397e4a1dc23ed07089c967612d705584f3b376 Author: Chris Wilson <ch...@chris-wilson.co.uk> Date: Sat Jul 14 21:35:23 2012 +0100 sna/glyphs: Perform the fallback mask reduce before moving the glyph pointers Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk> diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c index 80c0b74..2822368 100644 --- a/src/sna/sna_glyphs.c +++ b/src/sna/sna_glyphs.c @@ -1316,6 +1316,11 @@ glyphs_fallback(CARD8 op, } RegionTranslate(®ion, -dst->pDrawable->x, -dst->pDrawable->y); + if (mask_format && + (op_is_bounded(op) || (nlist == 1 && list->len == 1)) && + mask_format == glyphs_format(nlist, list, glyphs)) + mask_format = NULL; + cache = sna->render.glyph_cache; pixman_glyph_cache_freeze(cache); @@ -1377,11 +1382,6 @@ next: if (dst_image == NULL) goto out_free_src; - if (mask_format && - (op_is_bounded(op) || (nlist == 1 && list->len == 1)) && - mask_format == glyphs_format(nlist, list, glyphs)) - mask_format = NULL; - if (mask_format) { pixman_composite_glyphs(op, src_image, dst_image, mask_format->format | (mask_format->depth << 24), commit db1ee13a53b0c1348b7566ee60ee1b7b384ef59a Author: Chris Wilson <ch...@chris-wilson.co.uk> Date: Sat Jul 14 21:26:01 2012 +0100 sna/gen7: Check for gradient allocation failure within spans Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk> diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c index c06980d..1e10cb0 100644 --- a/src/sna/gen7_render.c +++ b/src/sna/gen7_render.c @@ -3185,13 +3185,12 @@ gen7_render_composite_spans(struct sna *sna, break; } - tmp->base.mask.bo = NULL; - tmp->base.is_affine = tmp->base.src.is_affine; tmp->base.has_component_alpha = false; tmp->base.need_magic_ca_pass = false; - gen7_composite_alpha_gradient_init(sna, &tmp->base.mask); + if (!gen7_composite_alpha_gradient_init(sna, &tmp->base.mask)) + goto cleanup_src; tmp->prim_emit = gen7_emit_composite_spans_primitive; if (tmp->base.src.is_solid) { commit 86479e97460da798a3804cbb4ae39e62de881af1 Author: Chris Wilson <ch...@chris-wilson.co.uk> Date: Sat Jul 14 21:24:04 2012 +0100 sna/gen7: Uses EXTEND_PAD for its alpha-gradient with spans Fixes regression from 2b94f9a043. Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk> diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c index 589c594..c06980d 100644 --- a/src/sna/gen7_render.c +++ b/src/sna/gen7_render.c @@ -2874,8 +2874,6 @@ gen7_composite_alpha_gradient_init(struct sna *sna, { DBG(("%s\n", __FUNCTION__)); - channel->filter = PictFilterNearest; - channel->repeat = RepeatPad; channel->is_affine = true; channel->is_solid = false; channel->transform = NULL; @@ -3222,7 +3220,7 @@ gen7_render_composite_spans(struct sna *sna, tmp->base.u.gen7.sampler = SAMPLER_OFFSET(tmp->base.src.filter, tmp->base.src.repeat, SAMPLER_FILTER_NEAREST, - SAMPLER_EXTEND_NONE); + SAMPLER_EXTEND_PAD); tmp->box = gen7_render_composite_spans_box; tmp->boxes = gen7_render_composite_spans_boxes; commit f17037275c05198c3c3f456964fd42032f9085b6 Author: Chris Wilson <ch...@chris-wilson.co.uk> Date: Sat Jul 14 20:11:17 2012 +0100 sna: Reorder overlapping boxes for CopyArea/Window Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk> diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 4257e07..d3787c1 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -3692,6 +3692,54 @@ move_to_gpu(PixmapPtr pixmap, struct sna_pixmap *priv, } } +static BoxPtr +reorder_boxes(BoxPtr box, int n, int dx, int dy) +{ + BoxPtr new, base, next, tmp; + + DBG(("%s x %d dx=%d, dy=%d\n", __FUNCTION__, n, dx, dy)); + + if (dy < 0) { + new = malloc(sizeof(BoxRec) * n); + if (new == NULL) + return NULL; + + base = next = box + n - 1; + while (base >= box) { + while (next >= box && base->y1 == next->y1) + next--; + tmp = next + 1; + while (tmp <= base) + *new++ = *tmp++; + base = next; + } + new -= n; + box = new; + } + + if (dx < 0) { + new = malloc(sizeof(BoxRec) * n); + if (!new) { + if (dy < 0) + free(box); + return NULL; + } + base = next = box; + while (base < box + n) { + while (next < box + n && next->y1 == base->y1) + next++; + tmp = next; + while (tmp != base) + *new++ = *--tmp; + base = next; + } + new -= n; + box = new; + } + + return box; +} + static void sna_self_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, RegionPtr region,int dx, int dy, @@ -3700,6 +3748,8 @@ sna_self_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, PixmapPtr pixmap = get_drawable_pixmap(src); struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv = sna_pixmap(pixmap); + BoxPtr box = RegionRects(region); + int n = RegionNumRects(region); int alu = gc ? gc->alu : GXcopy; int16_t tx, ty; @@ -3707,8 +3757,14 @@ sna_self_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, if (((dx | dy) == 0 && alu == GXcopy)) return; + if (n > 1 && (dx | dy) < 0) { + box = reorder_boxes(box, n, dx, dy); + if (box == NULL) + return; + } + DBG(("%s (boxes=%dx[(%d, %d), (%d, %d)...], src=+(%d, %d), alu=%d, pix.size=%dx%d)\n", - __FUNCTION__, RegionNumRects(region), + __FUNCTION__, n, region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2, dx, dy, alu, @@ -3725,7 +3781,7 @@ sna_self_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, if (priv->gpu_bo) { if (alu == GXcopy && priv->clear) - return; + goto out; assert(priv->gpu_bo->proxy == NULL); if (!sna_pixmap_move_to_gpu(pixmap, MOVE_WRITE | MOVE_READ)) { @@ -3737,9 +3793,7 @@ 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, - RegionRects(region), - RegionNumRects(region), - 0)) { + box, n, 0)) { DBG(("%s: fallback - accelerated copy boxes failed\n", __FUNCTION__)); goto fallback; @@ -3754,11 +3808,9 @@ sna_self_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, fallback: DBG(("%s: fallback", __FUNCTION__)); if (!sna_pixmap_move_to_cpu(pixmap, MOVE_READ | MOVE_WRITE)) - return; + goto out; 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; @@ -3778,7 +3830,7 @@ fallback: } while (--n); } else { if (gc && !sna_gc_move_to_cpu(gc, dst, region)) - return; + goto out; get_drawable_deltas(src, pixmap, &tx, &ty); miCopyRegion(src, dst, gc, @@ -3789,6 +3841,10 @@ fallback: sna_gc_move_to_gpu(gc); } } + +out: + if (box != RegionRects(region)) + free(box); } static int commit 86e09d14bd00344d378b86a19ebb44f7d946926c Author: Chris Wilson <ch...@chris-wilson.co.uk> Date: Sat Jul 14 17:51:31 2012 +0100 sna: Tidy sna_copy_boxes So there appears to be a bug hidden here. But only when we scroll upwards in a GTK+ application. Hmm. Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk> diff --git a/src/sna/kgem.c b/src/sna/kgem.c index 5880c78..f85b5af 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -800,7 +800,7 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen) kgem->half_cpu_cache_pages = cpu_cache_size() >> 13; DBG(("%s: half cpu cache %d pages\n", __FUNCTION__, - kgem->half_cpu_cace_pages)); + kgem->half_cpu_cache_pages)); list_init(&kgem->batch_partials); list_init(&kgem->active_partials); diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 9627a06..4257e07 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -69,6 +69,7 @@ #define ACCEL_PUT_IMAGE 1 #define ACCEL_COPY_AREA 1 #define ACCEL_COPY_PLANE 1 +#define ACCEL_COPY_WINDOW 1 #define ACCEL_POLY_POINT 1 #define ACCEL_POLY_LINE 1 #define ACCEL_POLY_SEGMENT 1 @@ -3723,6 +3724,9 @@ sna_self_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, goto fallback; if (priv->gpu_bo) { + if (alu == GXcopy && priv->clear) + return; + assert(priv->gpu_bo->proxy == NULL); if (!sna_pixmap_move_to_gpu(pixmap, MOVE_WRITE | MOVE_READ)) { DBG(("%s: fallback - not a pure copy and failed to move dst to GPU\n", @@ -3773,7 +3777,7 @@ fallback: box++; } while (--n); } else { - if (!sna_gc_move_to_cpu(gc, dst, region)) + if (gc && !sna_gc_move_to_cpu(gc, dst, region)) return; get_drawable_deltas(src, pixmap, &tx, &ty); @@ -3781,7 +3785,8 @@ fallback: region, dx - tx, dy - ty, fbCopyNtoN, 0, NULL); - sna_gc_move_to_gpu(gc); + if (gc) + sna_gc_move_to_gpu(gc); } } } @@ -3821,17 +3826,17 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, struct sna *sna = to_sna_from_pixmap(src_pixmap); struct sna_damage **damage; struct kgem_bo *bo; - 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 alu = gc->alu; int stride, bpp; char *bits; bool replaces; - if (n == 0) - return; + assert(RegionNumRects(region)); + assert_pixmap_contains_box(dst_pixmap, RegionExtents(region)); if (src_pixmap == dst_pixmap) return sna_self_copy_boxes(src, dst, gc, @@ -3851,13 +3856,10 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, bpp = dst_pixmap->drawable.bitsPerPixel; get_drawable_deltas(dst, dst_pixmap, &dst_dx, &dst_dy); - get_drawable_deltas(src, src_pixmap, &src_dx, &src_dy); - src_dx += dx; - src_dy += dy; - RegionTranslate(region, dst_dx, dst_dy); - src_dx -= dst_dx; - src_dy -= dst_dy; + get_drawable_deltas(src, src_pixmap, &src_dx, &src_dy); + src_dx += dx - dst_dx; + src_dy += dy - dst_dy; replaces = n == 1 && box->x1 <= 0 && @@ -3897,8 +3899,6 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, 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(region)); if (n == 1) { if (!sna->render.fill_one(sna, dst_pixmap, bo, @@ -3927,7 +3927,6 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, if (damage) sna_damage_add(damage, region); - return; } @@ -3945,11 +3944,8 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, goto fallback; } - if (damage) { - assert_pixmap_contains_box(dst_pixmap, - RegionExtents(region)); + if (damage) sna_damage_add(damage, region); - } return; } @@ -3980,11 +3976,8 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, goto fallback; } - if (damage) { - assert_pixmap_contains_box(dst_pixmap, - RegionExtents(region)); + if (damage) sna_damage_add(damage, region); - } return; } @@ -4016,11 +4009,8 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, goto fallback; } - if (damage) { - assert_pixmap_contains_box(dst_pixmap, - RegionExtents(region)); + if (damage) sna_damage_add(damage, region); - } return; } @@ -4028,7 +4018,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, PixmapPtr tmp; int i; - assert (src_pixmap->drawable.depth != 1); + assert(src_pixmap->drawable.depth != 1); DBG(("%s: creating temporary source upload for non-copy alu [%d]\n", __FUNCTION__, alu)); @@ -4078,11 +4068,8 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, } tmp->drawable.pScreen->DestroyPixmap(tmp); - if (damage) { - assert_pixmap_contains_box(dst_pixmap, - RegionExtents(region)); + if (damage) sna_damage_add(damage, region); - } return; } else { DBG(("%s: dst is on the GPU, src is on the CPU, uploading into dst\n", @@ -4132,12 +4119,9 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, dst_pixmap->drawable.height); list_del(&dst_priv->list); dst_priv->undamaged = false; - } else { - assert_pixmap_contains_box(dst_pixmap, - RegionExtents(region)); + } else sna_damage_add(&dst_priv->gpu_damage, region); - } assert_pixmap_damage(dst_pixmap); } } @@ -4151,9 +4135,6 @@ fallback: __FUNCTION__, src_priv->clear_color)); if (dst_priv) { - assert_pixmap_contains_box(dst_pixmap, - RegionExtents(region)); - if (!sna_drawable_move_region_to_cpu(&dst_pixmap->drawable, region, MOVE_WRITE | MOVE_INPLACE_HINT)) @@ -4198,9 +4179,6 @@ fallback: if (dst_priv) { unsigned mode; - assert_pixmap_contains_box(dst_pixmap, - RegionExtents(region)); - if (alu_overwrites(alu)) mode = MOVE_WRITE | MOVE_INPLACE_HINT; else @@ -4267,6 +4245,21 @@ typedef void (*sna_copy_func)(DrawablePtr src, DrawablePtr dst, GCPtr gc, RegionPtr region, int dx, int dy, Pixel bitPlane, void *closure); +inline static bool +box_intersect(BoxPtr a, const BoxRec *b) +{ + if (a->x1 < b->x1) + a->x1 = b->x1; + if (a->x2 > b->x2) + a->x2 = b->x2; + if (a->y1 < b->y1) + a->y1 = b->y1; + if (a->y2 > b->y2) + a->y2 = b->y2; + + return a->x1 < a->x2 && a->y1 < a->y2; +} + static RegionPtr sna_do_copy(DrawablePtr src, DrawablePtr dst, GCPtr gc, int sx, int sy, @@ -4274,13 +4267,18 @@ sna_do_copy(DrawablePtr src, DrawablePtr dst, GCPtr gc, int dx, int dy, sna_copy_func copy, Pixel bitPlane, void *closure) { - RegionPtr clip = NULL, free_clip = NULL; + RegionPtr clip, free_clip = NULL; RegionRec region; - bool expose = false; + bool expose; + + DBG(("%s: src=(%d, %d), dst=(%d, %d), size=(%dx%d)\n", + __FUNCTION__, sx, sy, dx, dy, width, height)); /* Short cut for unmapped windows */ - if (dst->type == DRAWABLE_WINDOW && !((WindowPtr)dst)->realized) + if (dst->type == DRAWABLE_WINDOW && !((WindowPtr)dst)->realized) { + DBG(("%s: unmapped\n", __FUNCTION__)); return NULL; + } if (src->pScreen->SourceValidate) src->pScreen->SourceValidate(src, sx, sy, @@ -4293,25 +4291,23 @@ sna_do_copy(DrawablePtr src, DrawablePtr dst, GCPtr gc, dx += dst->x; dy += dst->y; + DBG(("%s: after drawable: src=(%d, %d), dst=(%d, %d), size=(%dx%d)\n", + __FUNCTION__, sx, sy, dx, dy, width, height)); + 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)) + DBG(("%s: dst extents (%d, %d), (%d, %d)\n", __FUNCTION__, + region.extents.x1, region.extents.y1, + region.extents.x2, region.extents.y2)); + + if (!box_intersect(®ion.extents, &gc->pCompositeClip->extents)) { + DBG(("%s: dst clipped out\n", __FUNCTION__)); return NULL; + } region.extents.x1 += sx - dx; region.extents.x2 += sx - dx; @@ -4319,31 +4315,28 @@ sna_do_copy(DrawablePtr src, DrawablePtr dst, GCPtr gc, region.extents.y2 += sy - dy; /* Compute source clip region */ - if (src->type == DRAWABLE_PIXMAP) { - if (src == dst && gc->clientClipType == CT_NONE) - clip = gc->pCompositeClip; + clip = NULL; + if (src == dst && gc->clientClipType == CT_NONE) { + DBG(("%s: using gc clip for src\n", __FUNCTION__)); + clip = gc->pCompositeClip; + } else if (src->type == DRAWABLE_PIXMAP) { + DBG(("%s: pixmap -- no source clipping\n", __FUNCTION__)); + } 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)) { + DBG(("%s: include inferiors\n", __FUNCTION__)); + free_clip = clip = NotClippedByChildren((WindowPtr)src); + } } 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); -- To UNSUBSCRIBE, email to debian-x-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org Archive: http://lists.debian.org/e1sqmet-00068e...@vasks.debian.org