summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-01-14 23:21:29 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2012-01-15 09:48:52 +0000
commit1d6030322e2c3bae87a0173a32fb8d341dea560c (patch)
treeacf375ed0237c22fc65aa4c38db96569b78c4aa8
parent0e4a24ef6c186909c99a501cb606994b5c10a813 (diff)
sna/gen5: Check reused source for validity
Be sure the mask picture has a valid format even though it points to the same pixels as the valid source. And also be wary if the source was converted to a solid, but the mask is not. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/gen5_render.c68
1 files changed, 60 insertions, 8 deletions
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index 560830e1..f8d8d105 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -557,8 +557,33 @@ static Bool gen5_check_dst_format(PictFormat format)
case PICT_a4r4g4b4:
case PICT_x4r4g4b4:
return TRUE;
+ default:
+ DBG(("%s: unhandled format: %x\n", __FUNCTION__, format));
+ return FALSE;
+ }
+}
+
+static bool gen5_check_format(PicturePtr p)
+{
+ switch (p->format) {
+ case PICT_a8r8g8b8:
+ case PICT_x8r8g8b8:
+ case PICT_a8b8g8r8:
+ case PICT_x8b8g8r8:
+ case PICT_a2r10g10b10:
+ case PICT_x2r10g10b10:
+ case PICT_r8g8b8:
+ case PICT_r5g6b5:
+ case PICT_x1r5g5b5:
+ case PICT_a1r5g5b5:
+ case PICT_a8:
+ case PICT_a4r4g4b4:
+ case PICT_x4r4g4b4:
+ return true;
+ default:
+ DBG(("%s: unhandled format: %x\n", __FUNCTION__, p->format));
+ return false;
}
- return FALSE;
}
static uint32_t gen5_get_dest_format_for_depth(int depth)
@@ -654,6 +679,7 @@ static uint32_t gen5_get_card_format(PictFormat format)
if (gen5_tex_formats[i].pict_fmt == format)
return gen5_tex_formats[i].card_fmt;
}
+ assert(0);
return -1;
}
@@ -676,6 +702,7 @@ static uint32_t gen5_check_filter(PicturePtr picture)
case PictFilterBilinear:
return TRUE;
default:
+ DBG(("%s: unknown filter: %x\n", __FUNCTION__, picture->filter));
return FALSE;
}
}
@@ -708,6 +735,8 @@ static bool gen5_check_repeat(PicturePtr picture)
case RepeatReflect:
return TRUE;
default:
+ DBG(("%s: unknown repeat: %x\n",
+ __FUNCTION__, picture->repeatType));
return FALSE;
}
}
@@ -1868,6 +1897,10 @@ gen5_composite_picture(struct sna *sna,
x, y, w, h, dst_x, dst_y);
}
+ if (!gen5_check_format(picture))
+ return sna_render_picture_fixup(sna, picture, channel,
+ x, y, w, h, dst_x, dst_y);
+
if (!gen5_check_repeat(picture))
return sna_render_picture_fixup(sna, picture, channel,
x, y, w, h, dst_x, dst_y);
@@ -1897,9 +1930,6 @@ gen5_composite_picture(struct sna *sna,
channel->transform = picture->transform;
channel->card_format = gen5_get_card_format(picture->format);
- if (channel->card_format == (unsigned)-1)
- return sna_render_picture_convert(sna, picture, channel, pixmap,
- x, y, w, h, dst_x, dst_y);
if (too_large(pixmap->drawable.width, pixmap->drawable.height))
return sna_render_picture_extract(sna, picture, channel,
@@ -2045,7 +2075,11 @@ has_alphamap(PicturePtr p)
static bool
source_fallback(PicturePtr p)
{
- return has_alphamap(p) || is_gradient(p) || !gen5_check_filter(p) || !gen5_check_repeat(p);
+ return (has_alphamap(p) ||
+ is_gradient(p) ||
+ !gen5_check_filter(p) ||
+ !gen5_check_repeat(p) ||
+ !gen5_check_format(p));
}
static bool
@@ -2133,14 +2167,29 @@ reuse_source(struct sna *sna,
PicturePtr src, struct sna_composite_channel *sc, int src_x, int src_y,
PicturePtr mask, struct sna_composite_channel *mc, int msk_x, int msk_y)
{
- if (src->pDrawable == NULL || mask->pDrawable != src->pDrawable)
+ uint32_t color;
+
+ if (src_x != msk_x || src_y != msk_y)
return FALSE;
- DBG(("%s: mask reuses source drawable\n", __FUNCTION__));
+ if (src == mask) {
+ DBG(("%s: mask is source\n", __FUNCTION__));
+ *mc = *sc;
+ mc->bo = kgem_bo_reference(mc->bo);
+ return TRUE;
+ }
- if (src_x != msk_x || src_y != msk_y)
+ if (sna_picture_is_solid(mask, &color))
+ return gen5_composite_solid_init(sna, mc, color);
+
+ if (sc->is_solid)
+ return FALSE;
+
+ if (src->pDrawable == NULL || mask->pDrawable != src->pDrawable)
return FALSE;
+ DBG(("%s: mask reuses source drawable\n", __FUNCTION__));
+
if (!sna_transform_equal(src->transform, mask->transform))
return FALSE;
@@ -2153,6 +2202,9 @@ reuse_source(struct sna *sna,
if (!gen5_check_filter(mask))
return FALSE;
+ if (!gen5_check_format(mask))
+ return FALSE;
+
DBG(("%s: reusing source channel for mask with a twist\n",
__FUNCTION__));