From 7524499908d316c2d5a94539edc4a919699d0008 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 21 Mar 2014 15:00:14 +0000 Subject: Fix bail out on pictures we don't yet handle in composite method It is better to bail out early on pictures we don't handle than to try to handle them and then fail. We check: - the operation is one we can support - the source and destinations do not have alpha maps - the source has a drawable, or is a solid single coloured surface - the mask does not have an alpha map, and is not component alpha - the mask has a drawable The last case was missed, and this causes Audacious to crash when using the GTK+ theme. Bug reported by Matthew Coburn. Signed-off-by: Russell King --- src/vivante_accel.c | 72 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 26 deletions(-) diff --git a/src/vivante_accel.c b/src/vivante_accel.c index e2314bb..9b1b923 100644 --- a/src/vivante_accel.c +++ b/src/vivante_accel.c @@ -1180,6 +1180,34 @@ static Bool vivante_blend(struct vivante *vivante, gcsRECT_PTR clip, return TRUE; } +/* + * Returns TRUE and the pixel value in COLOUR if the picture + * represents a solid surface of constant colour. + */ +static Bool vivante_picture_is_solid(PicturePtr pict, CARD32 *colour) +{ + if (pict->pDrawable) { + DrawablePtr pDraw = pict->pDrawable; + + if (pDraw->width == 1 && pDraw->height == 1 && + pict->repeat != RepeatNone) { + if (colour) + *colour = get_first_pixel(pDraw); + return TRUE; + } + } else { + SourcePict *sp = pict->pSourcePict; + + if (sp->type == SourcePictTypeSolidFill) { + if (colour) + *colour = sp->solidFill.color; + return TRUE; + } + } + + return FALSE; +} + /* * If we're filling a solid * surface, force it to have alpha; it may be used in combination @@ -1194,25 +1222,10 @@ static struct vivante_pixmap *vivante_acquire_src(struct vivante *vivante, PixmapPtr pPixmap; struct vivante_pixmap *vSrc; DrawablePtr drawable = pict->pDrawable; - uint32_t colour; + CARD32 colour; int tx, ty, ox, oy; - Bool fill = FALSE; - - if (drawable == NULL) { - SourcePict *src = pict->pSourcePict; - if (src && src->type == SourcePictTypeSolidFill) { - colour = src->solidFill.color; - fill = TRUE; - } else { - return NULL; - } - } else if (drawable->width == 1 && drawable->height == 1 && - pict->repeat != RepeatNone) { - colour = get_first_pixel(pict->pDrawable); - fill = TRUE; - } - if (fill) { + if (vivante_picture_is_solid(pict, &colour)) { *xout = 0; *yout = 0; vTemp->pict_format = vivante_pict_format(PICT_a8r8g8b8, FALSE); @@ -1333,19 +1346,26 @@ int vivante_accel_Composite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, gcsRECT clipTemp; int oDst_x, oDst_y, rc; - if (pDst->alphaMap || pSrc->alphaMap || - (pMask && (pMask->alphaMap || pMask->componentAlpha))) { -// fprintf(stderr, "%s: D:%s S:%s M:%s%s\n", __FUNCTION__, -// pDst->alphaMap ? "AM" : "", pSrc->alphaMap ? "AM" : "", -// pMask && pMask->alphaMap ? "AM" : "", -// pMask && pMask->componentAlpha ? "CA" : ""); - return FALSE; - } - /* If we can't do the op, there's no point going any further */ if (op >= ARRAY_SIZE(vivante_composite_op)) return FALSE; + /* If there are alpha maps, fallback for now */ + if (pDst->alphaMap || pSrc->alphaMap) + return FALSE; + + /* If the source has no drawable, and is not solid, fallback */ + if (!pSrc->pDrawable && !vivante_picture_is_solid(pSrc, NULL)) + return FALSE; + + if (pMask) { + if (pMask->alphaMap || pMask->componentAlpha) + return FALSE; + + if (!pMask->pDrawable) + return FALSE; + } + /* The destination pixmap must have a bo */ pPixmap = vivante_drawable_pixmap_deltas(pDst->pDrawable, &oDst_x, &oDst_y); vDst = vivante_get_pixmap_priv(pPixmap); -- cgit v1.2.3