[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xserver-xorg-video-intel: Changes to 'upstream-experimental'



 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 <chris@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 <chris@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 <chris@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 <chris@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 <chris@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 <chris@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 <chris@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 <chris@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 <chris@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 <chris@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 <chris@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 <chris@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 <chris@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 <chris@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(&region, -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 <chris@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 <chris@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 <chris@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 <chris@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 <chris@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 <chris@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 <chris@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 <chris@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(&region.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(&region.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);


Reply to: