[Xorg-driver-geode] [PATCH 4/5] Fix the Nautilus file broswer misrendering issue

Huang, FrankR FrankR.Huang at amd.com
Fri Jul 23 02:18:02 PDT 2010


Fix the Nautilus file broswer misrendering issue

*When the srcX or srcY is greater than source width or source height,
the driver should do the correct region to render. Add a function
lx_composite_onepass_special to handle this. The source start point should
be calculated by a modulus operation.
*If the opeartion is with a shifted position src, then adjust the
operation region based on the operations src width and height
parameters. The rotation condition should be excluded. This part still
need investigation

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

diff --git a/src/lx_exa.c b/src/lx_exa.c
index e8a001a..74327ef 100644
--- a/src/lx_exa.c
+++ b/src/lx_exa.c
@@ -787,6 +787,13 @@ get_op_type(struct exa_format_t *src, struct exa_format_t *dst, int type)
  * ifdefed out until such time that we are sure its not needed
  */
 
+#define GetPixmapOffset(px, x, y) ( exaGetPixmapOffset((px)) + \
+  (exaGetPixmapPitch((px)) * (y)) + \
+  ((((px)->drawable.bitsPerPixel + 7) / 8) * (x)) )
+
+#define GetSrcOffset(_x, _y) (exaScratch.srcOffset + ((_y) * exaScratch.srcPitch) + \
+			      ((_x) * exaScratch.srcBpp))
+
 static void
 lx_composite_onepass(PixmapPtr pxDst, unsigned long dstOffset,
     unsigned long srcOffset, int width, int height)
@@ -815,6 +822,73 @@ lx_composite_onepass(PixmapPtr pxDst, unsigned long dstOffset,
     gp_screen_to_screen_convert(dstOffset, srcOffset, width, height, 0);
 }
 
+static void
+lx_composite_onepass_special(PixmapPtr pxDst, unsigned long dstOffset,
+    unsigned long srcOffset, int width, int height, int opX, int opY,
+    int srcX, int srcY)
+{
+    struct blend_ops_t *opPtr;
+    int apply, type;
+    int opWidth, opHeight;
+    int optempX, optempY;
+
+    optempX = opX;
+    optempY = opY;
+
+    opWidth = exaScratch.srcWidth - srcX % exaScratch.srcWidth;
+    opHeight = exaScratch.srcHeight -  srcY % exaScratch.srcHeight;
+
+    if (width < opWidth)
+	opWidth = width;
+    if (height < opHeight)
+	opHeight = height;
+
+    while (1) {
+	dstOffset = GetPixmapOffset(pxDst, optempX, optempY);
+
+	opPtr = &lx_alpha_ops[exaScratch.op * 2];
+
+	apply = (exaScratch.dstFormat->alphabits != 0 &&
+	    exaScratch.srcFormat->alphabits != 0) ?
+	    CIMGP_APPLY_BLEND_TO_ALL : CIMGP_APPLY_BLEND_TO_RGB;
+
+	gp_declare_blt(0);
+	gp_set_bpp(lx_get_bpp_from_format(exaScratch.dstFormat->fmt));
+	gp_set_strides(exaGetPixmapPitch(pxDst), exaScratch.srcPitch);
+
+	lx_set_source_format(exaScratch.srcFormat->fmt,
+	    exaScratch.dstFormat->fmt);
+
+	type = get_op_type(exaScratch.srcFormat, exaScratch.dstFormat,
+	    opPtr->type);
+
+	gp_set_alpha_operation(opPtr->operation, type, opPtr->channel,
+	    apply, 0);
+
+	gp_screen_to_screen_convert(dstOffset, srcOffset, opWidth, opHeight, 0);
+
+	optempX += opWidth;
+	if (optempX >= opX + width) {
+	    optempX = opX;
+	    optempY += opHeight;
+	    if (optempY >= opY + height)
+		break;
+	}
+	if (optempX == opX) {
+	    srcOffset = GetSrcOffset(srcX % exaScratch.srcWidth, srcY %
+		exaScratch.srcHeight);
+	    opWidth = exaScratch.srcWidth - srcX % exaScratch.srcWidth;
+	    opHeight = exaScratch.srcHeight -  srcY % exaScratch.srcHeight;
+	} else {
+	    srcOffset = GetSrcOffset(0, 0);
+	    opWidth = ((opX + width) - optempX) > exaScratch.srcWidth
+		? exaScratch.srcWidth : ((opX + width) - optempX);
+	    opHeight = ((opY + height) - optempY) > exaScratch.srcHeight
+		? exaScratch.srcHeight : ((opY + height) - optempY);
+	}
+    }
+}
+
 /* This function handles the multipass blend functions */
 
 static void
@@ -933,13 +1007,6 @@ lx_do_composite_mask(PixmapPtr pxDst, unsigned long dstOffset,
 	exaScratch.srcPitch, opPtr->operation, exaScratch.fourBpp);
 }
 
-#define GetPixmapOffset(px, x, y) ( exaGetPixmapOffset((px)) + \
-  (exaGetPixmapPitch((px)) * (y)) + \
-  ((((px)->drawable.bitsPerPixel + 7) / 8) * (x)) )
-
-#define GetSrcOffset(_x, _y) (exaScratch.srcOffset + ((_y) * exaScratch.srcPitch) + \
-			      ((_x) * exaScratch.srcBpp))
-
 static void
 lx_do_composite_mask_opover(PixmapPtr pxDst, unsigned long dstOffset,
     unsigned int maskOffset, int width, int height, int opX, int opY,
@@ -1045,6 +1112,7 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX,
     /* Use maskflag to record the exaScratch.type when it is COMP_TYPE_MASK.
      * This is useful for PictOpSrc operation when exaScratch.type is changed */
     int maskflag = 0;
+    int nothing = 0;
 
     xPointFixed srcPoint;
 
@@ -1122,6 +1190,9 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX,
      * and maskY coordinate are negative or greater than
      * exaScratch.srcWidth and exaScratch.srcHeight */
 
+    /* FIXME:  Please add the code to handle the condition when the srcX
+     * and srcY coordinate are negative or greater than
+     * exaScratch.srcWidth and exaScratch.srcHeight */
 
     if (exaScratch.type == COMP_TYPE_MASK) {
 	if ((exaScratch.srcWidth - maskX) < opWidth)
@@ -1129,14 +1200,38 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX,
 	if ((exaScratch.srcHeight - maskY) < opHeight)
 	    opHeight = exaScratch.srcHeight - maskY;
     } else {
-	if (exaScratch.srcWidth < opWidth)
-	    opWidth = exaScratch.srcWidth;
-	if (exaScratch.srcHeight < opHeight)
-	    opHeight = exaScratch.srcHeight;
+	    if (exaScratch.type == COMP_TYPE_ONEPASS) {
+		if (((exaScratch.srcWidth < srcX) || (exaScratch.srcHeight <
+		    srcY)) && (exaScratch.op == PictOpOver)) {
+		    if (exaScratch.repeat == 1) {
+			opWidth = width;
+			opHeight = height;
+			srcOffset = GetSrcOffset(srcX % exaScratch.srcWidth,
+			    srcY % exaScratch.srcHeight);
+		    } else
+			nothing = 1;
+		} else {
+		    if ((exaScratch.srcWidth - srcX) < opWidth)
+			opWidth = exaScratch.srcWidth - srcX;
+		    if ((exaScratch.srcHeight - srcY) < opHeight)
+			opHeight = exaScratch.srcHeight - srcY;
+		}
+	    } else {
+		if (exaScratch.rotate == RR_Rotate_180) {
+		} else {
+		    if ((exaScratch.srcWidth - srcY) < opWidth)
+			opWidth = exaScratch.srcWidth - srcY;
+		    if ((exaScratch.srcHeight - srcX) < opHeight)
+			opHeight = exaScratch.srcHeight - srcX;
+		}
+	    }
     }
 
     while (1) {
 
+	if (nothing == 1)
+	    break;
+
 	dstOffset = GetPixmapOffset(pxDst, opX, opY);
 
 	switch (exaScratch.type) {
@@ -1168,8 +1263,14 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX,
 	    break;
 
 	case COMP_TYPE_ONEPASS:
-	    lx_composite_onepass(pxDst, dstOffset, srcOffset, opWidth,
-		opHeight);
+	    if (((exaScratch.srcWidth < srcX) || (exaScratch.srcHeight <
+		srcY)) && (exaScratch.op == PictOpOver) && (exaScratch.repeat
+		== 1))
+		lx_composite_onepass_special(pxDst, dstOffset, srcOffset,
+		    opWidth, opHeight, opX, opY, srcX, srcY);
+	    else
+		lx_composite_onepass(pxDst, dstOffset, srcOffset, opWidth,
+		    opHeight);
 	    break;
 
 	case COMP_TYPE_TWOPASS:
@@ -1204,27 +1305,42 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX,
 	    /* Use the PictOpClear to make other non-blending region(out of
 	     * mask region) to be black if the op is PictOpSrc or
 	     * PictOpClear */
-	    if (!exaScratch.maskrepeat)
+	    if (!exaScratch.maskrepeat) {
 		if ((exaScratch.op == PictOpClear) ||
 		    (exaScratch.op == PictOpSrc)) {
 		    exaScratch.op = PictOpClear;
 		    exaScratch.type = COMP_TYPE_ONEPASS;
 		} else if (exaScratch.op == PictOpOver)
 		    break;
+	    }
 	} else {
-	    opWidth = ((dstX + width) - opX) > exaScratch.srcWidth ?
-		exaScratch.srcWidth : (dstX + width) - opX;
-	    opHeight = ((dstY + height) - opY) > exaScratch.srcHeight ?
-		exaScratch.srcHeight : (dstY + height) - opY;
+
+	    /* FIXME:  Please add the code to handle the condition when the
+	     * srcX and srcY coordinate are negative or greater than
+	     * exaScratch.srcWidth and exaScratch.srcHeight */
+
+	    if (exaScratch.type == COMP_TYPE_ONEPASS) {
+		opWidth = ((dstX + width) - opX) > (exaScratch.srcWidth - srcX)
+		    ? (exaScratch.srcWidth - srcX) : (dstX + width) - opX;
+		opHeight = ((dstY + height) - opY) >
+		    (exaScratch.srcHeight - srcY) ?
+		    (exaScratch.srcHeight - srcY) : (dstY + height) - opY;
+	    } else {
+		opWidth = ((dstX + width) - opX) > (exaScratch.srcWidth - srcY)
+		    ? (exaScratch.srcWidth - srcY) : (dstX + width) - opX;
+		opHeight = ((dstY + height) - opY) > (exaScratch.srcHeight - srcX
+		    ) ? (exaScratch.srcHeight - srcX) : (dstY + height) - opY;
+	    }
 	    /* Use the PictOpClear to make other non-blending region(out of
 	     * source region) to be black if the op is PictOpSrc or
 	     * PictOpClear. Special attention to rotation condition */
-	    if (!exaScratch.repeat && (exaScratch.type == COMP_TYPE_ONEPASS))
+	    if (!exaScratch.repeat && (exaScratch.type == COMP_TYPE_ONEPASS)) {
 		if ((exaScratch.op == PictOpClear) ||
 		    (exaScratch.op == PictOpSrc))
 		    exaScratch.op = PictOpClear;
 		else
 		    break;
+	    }
 	    if (!exaScratch.repeat && (exaScratch.type == COMP_TYPE_ROTATE))
 		    break;
 	}
-- 
1.7.1




More information about the Xorg-driver-geode mailing list