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

Huang, FrankR FrankR.Huang at amd.com
Wed Aug 4 23:32:48 PDT 2010


This is still a temp version of patch 4
This one has fixed several bugs below:
1)google chrome hang
2)Some website using repeat for source picture with PictOpSrc
To sum up, right now this patch has gracefully solved the Nautilus bug and some special rendering under PictOpSrc and PictOpOver
I will describe all special conditions I met 

To do:
Add the negative srcX and srcY support


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

*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 |  207 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 188 insertions(+), 19 deletions(-)

diff --git a/src/lx_exa.c b/src/lx_exa.c
index e8a001a..44d1f36 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,87 @@ 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, 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;
+    unsigned int dstOffset, srcOffset = 0;
+    
+    optempX = opX;
+    optempY = opY;
+
+    opWidth = exaScratch.srcWidth - srcX % exaScratch.srcWidth;
+    opHeight = exaScratch.srcHeight -  srcY % exaScratch.srcHeight;
+
+    srcOffset = GetSrcOffset(srcX % exaScratch.srcWidth,
+	srcY % exaScratch.srcHeight);
+
+    if (width < opWidth)
+	opWidth = width;
+    if (height < opHeight)
+	opHeight = height;
+
+    while (1) {
+        gp_wait_until_idle();
+
+	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, 0);
+	    opWidth = ((opX + width) - optempX) > (exaScratch.srcWidth - srcX
+		% exaScratch.srcWidth) ? (exaScratch.srcWidth - srcX %
+		exaScratch.srcWidth) : ((opX + width) - optempX);
+	    opHeight = ((opY + height) - optempY) > exaScratch.srcHeight
+		? exaScratch.srcHeight : ((opY + height) - optempY);
+	} else if (optempY == opY) {
+	    srcOffset = GetSrcOffset(0, srcY % exaScratch.srcHeight);
+	    opWidth = ((opX + width) - optempX) > exaScratch.srcWidth
+		? exaScratch.srcWidth : ((opX + width) - optempX);
+	    opHeight = ((opY + height) - optempY) > (exaScratch.srcHeight -
+		srcY % exaScratch.srcHeight) ? (exaScratch.srcHeight - srcY %
+		exaScratch.srcHeight) : ((opY + height) - optempY);
+	} 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 +1021,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,
@@ -1122,6 +1203,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,10 +1213,62 @@ 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 (((srcX >= 0 && srcY >= exaScratch.srcHeight)
+		    || (srcX >= exaScratch.srcWidth  && srcY >= 0)) &&
+		    (exaScratch.op == PictOpOver || exaScratch.op == PictOpSrc)) {
+		    if (exaScratch.repeat == 1) {
+			opWidth = width;
+			opHeight = height;
+		    } else {
+			if (exaScratch.op == PictOpOver)
+			    return ;
+			else {
+			    exaScratch.op = PictOpClear;
+			    opWidth = width;
+			    opHeight = height;
+			}
+		    }
+		} else if (srcX >= 0 && srcY >= 0 &&
+		    (exaScratch.op == PictOpOver || exaScratch.op == PictOpSrc)) {
+		    if (exaScratch.repeat == 1) {
+			opWidth = width;
+			opHeight = height;
+		    } else {
+			if ((exaScratch.srcWidth - srcX) < opWidth)
+			    opWidth = exaScratch.srcWidth - srcX;
+			if ((exaScratch.srcHeight - srcY) < opHeight)
+			    opHeight = exaScratch.srcHeight - srcY;
+		    }
+
+		} else {
+		    if (exaScratch.srcWidth < opWidth)
+			opWidth = exaScratch.srcWidth;
+		    if (exaScratch.srcHeight < opHeight)
+			opHeight = exaScratch.srcHeight;
+		}
+
+		/* Test use only */
+
+/*		if (srcX != 0 || srcY != 0 || exaScratch.srcWidth <= srcX ||
+		    exaScratch.srcHeight <= srcY) {
+		    ErrorF("exaScratch.op = %d, exaScratch.srcWidth = %d, exaScratch.srcHeight = %d, srcX = %d, srcY = %d, width = %d , height = %d ",
+			exaScratch.op, exaScratch.srcWidth, exaScratch.srcHeight, srcX, srcY, width, height);
+		    ErrorF("exaScratch.repeat = %d, opWidth = %d, opHeight = %d\n",
+			exaScratch.repeat, opWidth, opHeight);
+		}
+*/
+
+	    } 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) {
@@ -1168,8 +1304,16 @@ 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 ((srcX >= 0 && srcY >= 0) &&
+		(exaScratch.op == PictOpOver || exaScratch.op == PictOpSrc)
+		&& (exaScratch.repeat == 1)) {
+		lx_composite_onepass_special(pxDst, opWidth, opHeight, opX, opY,
+		    srcX, srcY);
+		return ;
+	    }
+	    else 
+		lx_composite_onepass(pxDst, dstOffset, srcOffset, opWidth,
+		    opHeight);
 	    break;
 
 	case COMP_TYPE_TWOPASS:
@@ -1204,27 +1348,52 @@ 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) {
+		if (srcX >= 0 && srcY >= 0 && (exaScratch.op == PictOpOver || exaScratch.op == PictOpSrc || exaScratch.op == PictOpClear)) {
+		    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 ?
+		    exaScratch.srcWidth : (dstX + width) - opX;
+		opHeight = ((dstY + height) - opY) > exaScratch.srcHeight ?
+		    exaScratch.srcHeight : (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