[Xorg-driver-geode] [PATCH 7/7] Fix the PictOpOver opearation.

Huang, FrankR FrankR.Huang at amd.com
Thu Jun 10 00:05:39 PDT 2010


From: Frank Huang <frankr.huang at amd.com>

*Convert the source format in lx_prepare_composite if it is not
ARGB32 when doing the first pass
*Add a function lx_do_composite_mask_opover to handle the PictOpOver
operation, the first pass is to do the src * (alpha of mask), the
second pass is to do the src + (1-a) * dest
*Progressbar, scrollbar and button are displayed well
*FreeDesktop Bugzilla #28352

Signed-off-by: Frank Huang <frankr.huang at amd.com>
---
 src/lx_exa.c |   77 ++++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 69 insertions(+), 8 deletions(-)

diff --git a/src/lx_exa.c b/src/lx_exa.c
index 223569f..db73088 100644
--- a/src/lx_exa.c
+++ b/src/lx_exa.c
@@ -669,13 +669,21 @@ lx_prepare_composite(int op, PicturePtr pSrc, PicturePtr pMsk,
 	int direction = (opPtr->channel == CIMGP_CHANNEL_A_SOURCE) ? 0 : 1;
 
 	/* Get the source color */
+	/* If the op is PictOpOver, we should get the ARGB32 source format */
 
-	if (direction == 0)
+	if (op == PictOpOver && (srcFmt->alphabits != 0))
+	    exaScratch.srcColor = exaGetPixmapFirstPixel(pxSrc);
+	else if (op == PictOpOver && (srcFmt->alphabits == 0))
 	    exaScratch.srcColor = lx_get_source_color(pxSrc, pSrc->format,
-		pDst->format);
-	else
-	    exaScratch.srcColor = lx_get_source_color(pxDst, pDst->format,
-		pSrc->format);
+		PICT_a8r8g8b8);
+	else {
+	    if (direction == 0)
+		exaScratch.srcColor = lx_get_source_color(pxSrc, pSrc->format,
+		    pDst->format);
+	    else
+		exaScratch.srcColor = lx_get_source_color(pxDst, pDst->format,
+		    pSrc->format);
+	}
 
 	/* Save off the info we need (reuse the source values to save space) */
 
@@ -920,6 +928,46 @@ lx_do_composite_mask(PixmapPtr pxDst, unsigned long dstOffset,
 	exaScratch.srcPitch, opPtr->operation, exaScratch.fourBpp);
 }
 
+static void
+lx_do_composite_mask_opover(PixmapPtr pxDst, unsigned long dstOffset,
+    unsigned int maskOffset, int width, int height)
+{
+    int apply, type;
+    struct blend_ops_t *opPtr;
+
+    /* Wait until the GP is idle - this will ensure that the scratch buffer
+     * isn't occupied */
+
+    gp_wait_until_idle();
+
+    /* Copy the source to the scratch buffer, and do a src * mask raster
+     * operation */
+
+    gp_declare_blt(0);
+    opPtr = &lx_alpha_ops[(exaScratch.op * 2) + 1];
+    gp_set_source_format(CIMGP_SOURCE_FMT_8_8_8_8);
+    gp_set_strides(exaScratch.srcPitch * 4, exaScratch.srcPitch);
+    gp_set_bpp(lx_get_bpp_from_format(CIMGP_SOURCE_FMT_8_8_8_8));
+    gp_set_solid_source(exaScratch.srcColor);
+    gp_blend_mask_blt(exaScratch.bufferOffset, 0, width, height, maskOffset,
+	exaScratch.srcPitch, opPtr->operation, exaScratch.fourBpp);
+
+    /* Do a PictOpOver operation(src + (1-a) * dst), and copy the operation
+     * result to destination */
+
+    gp_declare_blt(CIMGP_BLTFLAGS_HAZARD);
+    opPtr = &lx_alpha_ops[exaScratch.op * 2];
+    apply = (exaScratch.dstFormat->alphabits == 0) ?
+	CIMGP_APPLY_BLEND_TO_RGB : CIMGP_APPLY_BLEND_TO_ALL;
+    gp_set_source_format(CIMGP_SOURCE_FMT_8_8_8_8);
+    gp_set_strides(exaGetPixmapPitch(pxDst), exaScratch.srcPitch * 4);
+    gp_set_bpp(lx_get_bpp_from_format(exaScratch.dstFormat->fmt));
+    type = CIMGP_CONVERTED_ALPHA;
+    gp_set_alpha_operation(opPtr->operation, type, opPtr->channel, apply, 0);
+    gp_screen_to_screen_convert(dstOffset, exaScratch.bufferOffset, width,
+	height, 0);
+}
+
 #define GetPixmapOffset(px, x, y) ( exaGetPixmapOffset((px)) + \
   (exaGetPixmapPitch((px)) * (y)) + \
   ((((px)->drawable.bitsPerPixel + 7) / 8) * (x)) )
@@ -1051,11 +1099,19 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX,
 		if (direction == 1) {
 		    dstOffset =
 			GetPixmapOffset(exaScratch.srcPixmap, opX, opY);
-		    lx_do_composite_mask(exaScratch.srcPixmap, dstOffset,
+		    if (exaScratch.op == PictOpOver)
+			lx_do_composite_mask_opover(exaScratch.srcPixmap,
+			    dstOffset, srcOffset, opWidth, opHeight);
+		    else
+			lx_do_composite_mask(exaScratch.srcPixmap, dstOffset,
 			srcOffset, opWidth, opHeight);
 		} else {
-		    lx_do_composite_mask(pxDst, dstOffset, srcOffset, opWidth,
-			opHeight);
+		    if (exaScratch.op == PictOpOver)
+			lx_do_composite_mask_opover(pxDst, dstOffset,
+			    srcOffset, opWidth, opHeight);
+		    else
+			lx_do_composite_mask(pxDst, dstOffset, srcOffset,
+			    opWidth, opHeight);
 		}
 	    }
 	    break;
@@ -1097,6 +1153,9 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX,
 		exaScratch.type = COMP_TYPE_ONEPASS;
 		exaScratch.op = PictOpClear;
 	    }
+	    if (exaScratch.repeat && (!exaScratch.maskrepeat) &&
+		(exaScratch.op == PictOpSrc))
+		break;
 	} else {
 	    opWidth = ((dstX + width) - opX) > exaScratch.srcWidth ?
 		exaScratch.srcWidth : (dstX + width) - opX;
@@ -1106,6 +1165,8 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX,
 	       exaScratch.type = COMP_TYPE_ONEPASS;
 	       exaScratch.op = PictOpClear;
 	   }
+	    if ((!exaScratch.repeat) && (exaScratch.op == PictOpOver))
+		break;
 	}
 
     }
-- 
1.7.1




More information about the Xorg-driver-geode mailing list