summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk@arm.linux.org.uk>2014-03-21 15:00:14 +0000
committerRussell King <rmk@arm.linux.org.uk>2014-03-21 15:04:44 +0000
commit7524499908d316c2d5a94539edc4a919699d0008 (patch)
treea11b49e751c2a3cb372755a9ec2e92c79bb1c1bf
parent33d72046d6ec7a2ee1279d7d7751dde816a329ec (diff)
downloadxf86-video-armada-7524499908d316c2d5a94539edc4a919699d0008.tar.gz
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 <rmk@arm.linux.org.uk>
-rw-r--r--src/vivante_accel.c72
1 files 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
@@ -1181,6 +1181,34 @@ static Bool vivante_blend(struct vivante *vivante, gcsRECT_PTR clip,
}
/*
+ * 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
* with a mask. Otherwise, we ask for the plain source format,
@@ -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);