diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-03-22 09:22:52 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-03-22 09:22:52 +0000 |
commit | a6b48dd7f1eeb1a8e3841b8f3326c60b300ee9e9 (patch) | |
tree | be6713381ed261e411cd2c51ac564e699d851aa2 /src/sna | |
parent | 52f39ae1697bef86471b7c5eef8553661f255b67 (diff) |
sna: Force fallbacks if the destination is unattached
Since the removal of the ability to create a backing pixmap after the
creation of its parent, it no longer becomes practical to attempt
rendering with the GPU to unattached pixmaps. So having made the
decision never to render to that pixmap, perform the test explicitly
along the render paths.
This fixes a segmentation fault introduced in 8a303f195 (sna: Remove
existing damage before overwriting with a composite op) which assumed
the existence of a backing pixmap along a render path.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=47700
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna')
-rw-r--r-- | src/sna/sna_composite.c | 28 | ||||
-rw-r--r-- | src/sna/sna_glyphs.c | 20 | ||||
-rw-r--r-- | src/sna/sna_render_inline.h | 9 | ||||
-rw-r--r-- | src/sna/sna_trapezoids.c | 12 |
4 files changed, 44 insertions, 25 deletions
diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c index b098fcc9..e5031c0d 100644 --- a/src/sna/sna_composite.c +++ b/src/sna/sna_composite.c @@ -413,7 +413,9 @@ sna_composite(CARD8 op, INT16 dst_x, INT16 dst_y, CARD16 width, CARD16 height) { - struct sna *sna = to_sna_from_drawable(dst->pDrawable); + PixmapPtr pixmap = get_drawable_pixmap(dst->pDrawable); + struct sna *sna = to_sna_from_pixmap(pixmap); + struct sna_pixmap *priv; struct sna_composite_op tmp; unsigned flags; RegionRec region; @@ -462,8 +464,14 @@ sna_composite(CARD8 op, goto fallback; } - if (too_small(dst->pDrawable) && - !picture_is_gpu(src) && !picture_is_gpu(mask)) { + priv = sna_pixmap(pixmap); + if (priv == NULL) { + DBG(("%s: fallback as destination is unattached\n", + __FUNCTION__)); + goto fallback; + } + + if (too_small(priv) && !picture_is_gpu(src) && !picture_is_gpu(mask)) { DBG(("%s: fallback due to too small\n", __FUNCTION__)); goto fallback; } @@ -479,10 +487,8 @@ sna_composite(CARD8 op, get_drawable_dx(dst->pDrawable), get_drawable_dy(dst->pDrawable))); - if (op <= PictOpSrc) { - struct sna_pixmap *priv = sna_pixmap_from_drawable(dst->pDrawable); + if (op <= PictOpSrc) sna_damage_subtract(&priv->cpu_damage, ®ion); - } memset(&tmp, 0, sizeof(tmp)); if (!sna->render.composite(sna, @@ -752,17 +758,17 @@ sna_composite_rectangles(CARD8 op, boxes = pixman_region_rectangles(®ion, &num_boxes); - if (too_small(dst->pDrawable)) { - DBG(("%s: fallback, dst is too small\n", __FUNCTION__)); - goto fallback; - } - priv = sna_pixmap(pixmap); if (priv == NULL) { DBG(("%s: fallback, not attached\n", __FUNCTION__)); goto fallback; } + if (too_small(priv)) { + DBG(("%s: fallback, dst is too small\n", __FUNCTION__)); + goto fallback; + } + /* If we going to be overwriting any CPU damage with a subsequent * operation, then we may as well delete it without moving it * first to the GPU. diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c index 1c536c82..235528cb 100644 --- a/src/sna/sna_glyphs.c +++ b/src/sna/sna_glyphs.c @@ -1217,7 +1217,9 @@ sna_glyphs(CARD8 op, INT16 src_x, INT16 src_y, int nlist, GlyphListPtr list, GlyphPtr *glyphs) { - struct sna *sna = to_sna_from_drawable(dst->pDrawable); + PixmapPtr pixmap = get_drawable_pixmap(dst->pDrawable); + struct sna *sna = to_sna_from_pixmap(pixmap); + struct sna_pixmap *priv; PictFormatPtr _mask; DBG(("%s(op=%d, nlist=%d, src=(%d, %d))\n", @@ -1234,14 +1236,20 @@ sna_glyphs(CARD8 op, goto fallback; } - if (too_small(dst->pDrawable) && !picture_is_gpu(src)) { - DBG(("%s: fallback -- too small (%dx%d)\n", - __FUNCTION__, dst->pDrawable->width, dst->pDrawable->height)); + if (dst->alphaMap) { + DBG(("%s: fallback -- dst alpha map\n", __FUNCTION__)); goto fallback; } - if (dst->alphaMap) { - DBG(("%s: fallback -- dst alpha map\n", __FUNCTION__)); + priv = sna_pixmap(pixmap); + if (priv == NULL) { + DBG(("%s: fallback -- destination unattached\n", __FUNCTION__)); + goto fallback; + } + + if (too_small(priv) && !picture_is_gpu(src)) { + DBG(("%s: fallback -- too small (%dx%d)\n", + __FUNCTION__, dst->pDrawable->width, dst->pDrawable->height)); goto fallback; } diff --git a/src/sna/sna_render_inline.h b/src/sna/sna_render_inline.h index 88d0130a..956e2aa2 100644 --- a/src/sna/sna_render_inline.h +++ b/src/sna/sna_render_inline.h @@ -101,13 +101,10 @@ is_dirty(DrawablePtr drawable) return priv == NULL || kgem_bo_is_dirty(priv->gpu_bo); } -static inline Bool -too_small(DrawablePtr drawable) +static inline bool +too_small(struct sna_pixmap *priv) { - struct sna_pixmap *priv = sna_pixmap_from_drawable(drawable); - - if (priv == NULL) - return true; + assert(priv); if (priv->gpu_damage) return false; diff --git a/src/sna/sna_trapezoids.c b/src/sna/sna_trapezoids.c index 7048cae9..9ab5ae25 100644 --- a/src/sna/sna_trapezoids.c +++ b/src/sna/sna_trapezoids.c @@ -4435,7 +4435,9 @@ sna_composite_trapezoids(CARD8 op, INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid *traps) { - struct sna *sna = to_sna_from_drawable(dst->pDrawable); + PixmapPtr pixmap = get_drawable_pixmap(dst->pDrawable); + struct sna *sna = to_sna_from_pixmap(pixmap); + struct sna_pixmap *priv; bool rectilinear, pixel_aligned; unsigned flags; int n; @@ -4461,7 +4463,13 @@ sna_composite_trapezoids(CARD8 op, goto fallback; } - if (too_small(dst->pDrawable) && !picture_is_gpu(src)) { + priv = sna_pixmap(pixmap); + if (priv == NULL) { + DBG(("%s: fallback -- dst is unattached\n", __FUNCTION__)); + goto fallback; + } + + if (too_small(priv) && !picture_is_gpu(src)) { DBG(("%s: fallback -- dst is too small, %dx%d\n", __FUNCTION__, dst->pDrawable->width, |