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(®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 <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(®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);
Reply to: