diff options
Diffstat (limited to 'src/lx_exa.c')
-rw-r--r-- | src/lx_exa.c | 88 |
1 files changed, 48 insertions, 40 deletions
diff --git a/src/lx_exa.c b/src/lx_exa.c index bcff23e..8f3cb68 100644 --- a/src/lx_exa.c +++ b/src/lx_exa.c @@ -95,7 +95,6 @@ static struct { unsigned int srcPitch; unsigned int srcBpp; unsigned int srcWidth, srcHeight; - PixmapPtr srcPixmap; unsigned int srcColor; int op; @@ -285,6 +284,7 @@ lx_get_source_color(PixmapPtr pSrc, int srcFormat, int dstFormat) * exaGetPixmapFirstPixel, so this should be adjusted so * the stall isn't run needlessly */ + /* FIXME: xserver-1.4 with a supposed fix for this is really old, so kill the stall? */ gp_wait_until_idle(); in = exaGetPixmapFirstPixel(pSrc); @@ -547,28 +547,36 @@ lx_check_composite(int op, PicturePtr pSrc, PicturePtr pMsk, PicturePtr pDst) if (op > PictOpAdd) GEODE_FALLBACK(("Operation %d is not supported\n", op)); + /* XXX - don't know if we can do any hwaccel on solid fills or gradient types in generic cases */ + if (pMsk && pMsk->pSourcePict) + GEODE_FALLBACK(("%s are not supported as a mask\n", pMsk->pSourcePict->type == SourcePictTypeSolidFill ? "Solid pictures" : "Gradients")); + + if (pSrc->pSourcePict && pSrc->pSourcePict->type != SourcePictTypeSolidFill) + GEODE_FALLBACK(("Gradients are not supported as the source\n")); + + if (pMsk && op == PictOpAdd) + GEODE_FALLBACK(("PictOpAdd with mask is not supported\n")); + /* FIXME: Meet this conditions from the debug for PictOpAdd. * Any Other possibilities? Add a judge for the future supplement */ if (op == PictOpAdd && pSrc->format == PICT_a8r8g8b8 && - pDst->format == PICT_a8 && !pMsk) + pDst->format == PICT_a8) return TRUE; if (op == PictOpAdd && pSrc->format == PICT_x8r8g8b8 && - pDst->format == PICT_a8 && !pMsk) + pDst->format == PICT_a8) return TRUE; if (op == PictOpAdd && pSrc->format == PICT_r5g6b5 && - pDst->format == PICT_a8 && !pMsk) + pDst->format == PICT_a8) return TRUE; if (usesPasses(op)) { + /* FIXME: Slightly misleading fallback msg when !pMsk */ if (pGeode->exaBfrOffset == 0 || !pMsk) GEODE_FALLBACK(("Multipass operation requires off-screen buffer\n")); } - if (pMsk && op == PictOpAdd) - GEODE_FALLBACK(("PictOpAdd with mask is not supported\n")); - /* Check that the filter matches what we support */ switch (pSrc->filter) { @@ -585,10 +593,6 @@ lx_check_composite(int op, PicturePtr pSrc, PicturePtr pMsk, PicturePtr pDst) if (pMsk && pMsk->transform) GEODE_FALLBACK(("Mask transforms are not supported\n")); - /* XXX - don't know if we can do any hwaccel on solid fills or gradient types */ - if (pSrc->pSourcePict || (pMsk && pMsk->pSourcePict)) - GEODE_FALLBACK(("Solid fills or gradient types are not supported\n")); - /* Keep an eye out for source rotation transforms - those we can * do something about */ @@ -607,8 +611,8 @@ lx_check_composite(int op, PicturePtr pSrc, PicturePtr pMsk, PicturePtr pDst) struct blend_ops_t *opPtr = &lx_alpha_ops[op * 2]; int direction = (opPtr->channel == CIMGP_CHANNEL_A_SOURCE) ? 0 : 1; - /* Direction 0 indicates src->dst, 1 indiates dst->src */ - if (((direction == 0) && (pSrc->pDrawable->bitsPerPixel < 16)) || + /* Direction 0 indicates src->dst, 1 indicates dst->src */ + if (((direction == 0) && (pSrc->pDrawable && pSrc->pDrawable->bitsPerPixel < 16)) || ((direction == 1) && (pDst->pDrawable->bitsPerPixel < 16))) { ErrorF("Mask blending unsupported with <16bpp\n"); return FALSE; @@ -617,27 +621,28 @@ lx_check_composite(int op, PicturePtr pSrc, PicturePtr pMsk, PicturePtr pDst) GEODE_FALLBACK(("Masks can be only done with a 8bpp or 4bpp depth\n")); /* The pSrc should be 1x1 pixel if the pMsk is not zero */ - if (pSrc->pDrawable->width != 1 || pSrc->pDrawable->height != 1) + if (pSrc->pDrawable && (pSrc->pDrawable->width != 1 || pSrc->pDrawable->height != 1)) GEODE_FALLBACK(("pSrc should be 1x1 pixel if pMsk is not zero\n")); /* FIXME: In lx_prepare_composite, there are no variables to record the * one pixel source's width and height when the mask is not zero. * That will lead to bigger region to render instead of one pixel in lx * _do_composite, so we should fallback currently to avoid this */ - if (!pSrc->repeat) + /* Not an issue for solid pictures, because we'll treat it as 1x1R too */ + if (!pSrc->repeat && !(pSrc->pSourcePict && pSrc->pSourcePict->type == SourcePictTypeSolidFill)) { GEODE_FALLBACK(("FIXME: unzero mask might lead to bigger rendering region than 1x1 pixels\n")); + } + } else { + if (pSrc->pSourcePict) + GEODE_FALLBACK(("Solid source pictures without a mask are not supported\n")); } /* Get the formats for the source and destination */ - if ((srcFmt = lx_get_format(pSrc)) == NULL) { - ErrorF("EXA: Invalid source format %x\n", pSrc->format); - return FALSE; - } + if ((srcFmt = lx_get_format(pSrc)) == NULL) + GEODE_FALLBACK(("Unsupported source format %x\n", pSrc->format)); - if ((dstFmt = lx_get_format(pDst)) == NULL) { - ErrorF("EXA: Invalid destination format %x\n", pDst->format); - return FALSE; - } + if ((dstFmt = lx_get_format(pDst)) == NULL) + GEODE_FALLBACK(("Unsupported destination format %x\n", pDst->format)); /* Make sure operations that need alpha bits have them */ /* If a mask is enabled, the alpha will come from there */ @@ -684,25 +689,28 @@ lx_prepare_composite(int op, PicturePtr pSrc, PicturePtr pMsk, if (pMsk && op != PictOpClear) { /* Get the source color */ - /* If the op is PictOpOver(or PictOpOutReverse, PictOpInReverse, - * PictOpIn, PictOpOut, PictOpOverReverse), we should get the - * ARGB32 source format */ - - if ((op == PictOpOver || op == PictOpOutReverse || op == - PictOpInReverse || op == PictOpIn || op == PictOpOut || - op == PictOpOverReverse) && (srcFmt->alphabits != 0)) - exaScratch.srcColor = exaGetPixmapFirstPixel(pxSrc); - else if ((op == PictOpOver || op == PictOpOutReverse || op == - PictOpInReverse || op == PictOpIn || op == PictOpOut || - op == PictOpOverReverse) && (srcFmt->alphabits == 0)) - exaScratch.srcColor = lx_get_source_color(pxSrc, pSrc->format, - PICT_a8r8g8b8); - else - exaScratch.srcColor = lx_get_source_color(pxSrc, pSrc->format, - pDst->format); + if (pSrc->pSourcePict) { + exaScratch.srcColor = pSrc->pSourcePict->solidFill.color; + } else { + /* If the op is PictOpOver(or PictOpOutReverse, PictOpInReverse, + * PictOpIn, PictOpOut, PictOpOverReverse), we should get the + * ARGB32 source format */ + + if ((op == PictOpOver || op == PictOpOutReverse || op == + PictOpInReverse || op == PictOpIn || op == PictOpOut || + op == PictOpOverReverse) && (srcFmt->alphabits != 0)) + exaScratch.srcColor = exaGetPixmapFirstPixel(pxSrc); + else if ((op == PictOpOver || op == PictOpOutReverse || op == + PictOpInReverse || op == PictOpIn || op == PictOpOut || + op == PictOpOverReverse) && (srcFmt->alphabits == 0)) + exaScratch.srcColor = lx_get_source_color(pxSrc, pSrc->format, + PICT_a8r8g8b8); + else + exaScratch.srcColor = lx_get_source_color(pxSrc, pSrc->format, + pDst->format); + } /* Save off the info we need (reuse the source values to save space) */ - exaScratch.type = COMP_TYPE_MASK; exaScratch.maskrepeat = pMsk->repeat; |