summaryrefslogtreecommitdiff
path: root/src/lx_exa.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lx_exa.c')
-rw-r--r--src/lx_exa.c88
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;