summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King <rmk@arm.linux.org.uk>2017-11-03 16:56:24 +0000
committerRussell King <rmk@arm.linux.org.uk>2017-11-03 16:56:24 +0000
commit04748ff4fb30370086cc97b9487a32951c5600ba (patch)
tree60f7a9385d517be12e80b0c2cc0c8409830e5c22
parente907c63249dbd3c2e4621db64c61d47c8a252384 (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.c31
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;