diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-14 23:21:29 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-15 09:48:52 +0000 |
commit | 1d6030322e2c3bae87a0173a32fb8d341dea560c (patch) | |
tree | acf375ed0237c22fc65aa4c38db96569b78c4aa8 | |
parent | 0e4a24ef6c186909c99a501cb606994b5c10a813 (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.c | 68 |
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__)); |