summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMart Raudsepp <leio@gentoo.org>2012-10-23 11:40:11 +0300
committerMart Raudsepp <leio@gentoo.org>2012-10-23 12:47:04 +0300
commita46486b05f4674fc17f36947c97bc281c1d00d26 (patch)
tree5f89113dcf5980256611cc570555abdaa5264856
parent85f25321661b24324d9e8fb6415abc0fda12436d (diff)
lx_exa: Implement solid pictures support as source with a mask
cairo-1.12 uses solid pictures instead of 1x1R pixmaps in glyph rendering paths, so accelerate it. In addition to acceleration, it avoids a bug in xserver-1.13.0 and earlier which causes visible misrendering for fallback path, making cairo-1.12 a viable and desired choice on GeodeLX systems. Quick benchmarking suggests a 4-12% win in cairo-traces.
-rw-r--r--src/lx_exa.c59
1 files changed, 35 insertions, 24 deletions
diff --git a/src/lx_exa.c b/src/lx_exa.c
index 430ae0d..8f3cb68 100644
--- a/src/lx_exa.c
+++ b/src/lx_exa.c
@@ -547,9 +547,12 @@ 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 */
- if (pSrc->pSourcePict || (pMsk && pMsk->pSourcePict))
- GEODE_FALLBACK(("Solid fills or gradient types are not supported\n"));
+ /* 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"));
@@ -608,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;
@@ -618,14 +621,19 @@ 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 */
@@ -681,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;