summaryrefslogtreecommitdiff
path: root/src/sna
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-03-22 09:22:52 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2012-03-22 09:22:52 +0000
commita6b48dd7f1eeb1a8e3841b8f3326c60b300ee9e9 (patch)
treebe6713381ed261e411cd2c51ac564e699d851aa2 /src/sna
parent52f39ae1697bef86471b7c5eef8553661f255b67 (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.c28
-rw-r--r--src/sna/sna_glyphs.c20
-rw-r--r--src/sna/sna_render_inline.h9
-rw-r--r--src/sna/sna_trapezoids.c12
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, &region);
- }
memset(&tmp, 0, sizeof(tmp));
if (!sna->render.composite(sna,
@@ -752,17 +758,17 @@ sna_composite_rectangles(CARD8 op,
boxes = pixman_region_rectangles(&region, &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,