diff options
author | Russell King <rmk@arm.linux.org.uk> | 2017-11-03 16:56:24 +0000 |
---|---|---|
committer | Russell King <rmk@arm.linux.org.uk> | 2017-11-03 16:56:24 +0000 |
commit | 04748ff4fb30370086cc97b9487a32951c5600ba (patch) | |
tree | 60f7a9385d517be12e80b0c2cc0c8409830e5c22 | |
parent | e907c63249dbd3c2e4621db64c61d47c8a252384 (diff) |
etnaviv: avoid out of bounds accelerated picture accesses
The GPU can't handle repeats or accesses outside of the source pictures
so we need to be careful to handle these correctly. If the source
coordinates fall entirely within the source picture, we're fine.
Replace picture_needs_repeat() with picture_has_pixels() which validates
that the region we're going to fetch is covered by the underlying
drawable.
Signed-off-by: Russell King <rmk@arm.linux.org.uk>
-rw-r--r-- | etnaviv/etnaviv_render.c | 31 |
1 files changed, 12 insertions, 19 deletions
diff --git a/etnaviv/etnaviv_render.c b/etnaviv/etnaviv_render.c index 8667a23..3d125c0 100644 --- a/etnaviv/etnaviv_render.c +++ b/etnaviv/etnaviv_render.c @@ -120,29 +120,22 @@ static void etnaviv_debug_blend_op(const char *func, } #endif -/* - * For a rectangle described by (wxh+x+y) on the picture's drawable, - * determine whether the picture repeat flag is meaningful. The - * rectangle must have had the transformation applied. - */ -static Bool picture_needs_repeat(PicturePtr pPict, int x, int y, - unsigned w, unsigned h) +static Bool picture_has_pixels(PicturePtr pPict, int x, int y, + const BoxRec *box) { DrawablePtr pDrawable; - if (!pPict->repeat) - return FALSE; - + /* If there is no drawable, there are no pixels that can be fetched */ pDrawable = pPict->pDrawable; if (!pDrawable) - return TRUE; + return FALSE; + /* Does the drawable contain all the pixels we want? */ if (pPict->filter != PictFilterConvolution && - (pDrawable->width > 1 || pDrawable->height > 1) && - drawable_contains(pDrawable, x, y, w, h)) - return FALSE; + drawable_contains(pDrawable, x, y, box->x2, box->y2)) + return TRUE; - return TRUE; + return FALSE; } static const struct etnaviv_blend_op etnaviv_composite_op[] = { @@ -425,8 +418,8 @@ static struct etnaviv_pixmap *etnaviv_acquire_src(ScreenPtr pScreen, if (!transform_is_integer_translation(pict->transform, &tx, &ty)) goto fallback; - if (picture_needs_repeat(pict, src_topleft->x + tx, src_topleft->y + ty, - clip->x2, clip->y2)) + if (!picture_has_pixels(pict, src_topleft->x + tx, src_topleft->y + ty, + clip)) goto fallback; src_topleft->x += drawable->x + src_offset.x + tx; @@ -661,8 +654,8 @@ static int etnaviv_accel_composite_masked(PicturePtr pSrc, PicturePtr pMask, mask_offset.y += ty; /* We don't handle mask repeats (yet) */ - if (picture_needs_repeat(pMask, mask_offset.x, mask_offset.y, - clip_temp.x2, clip_temp.y2)) + if (!picture_has_pixels(pMask, mask_offset.x, mask_offset.y, + &clip_temp)) goto fallback; mask_offset.x += pMask->pDrawable->x; |