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

Huang, FrankR FrankR.Huang at amd.com
Tue Aug 3 18:50:19 PDT 2010


Thanks for daduke's test on it.
This patch will cause some side effect. From what I get:
	1)It will cause Google chrome hang
	2)It will cause some Chinese webpages to be misrendered.

For the 1), it is because srcX is equal to source width. So it is a special condtion this patch omit. Fixed.
For the 2), it is because the negative coordinate of srcX and srcY. Still investigated.
Any update, I'll let you know.


Thanks,
Frank

> -----Original Message-----
> From: xorg-driver-geode-bounces+frankr.huang=amd.com at lists.x.org
> [mailto:xorg-driver-geode-bounces+frankr.huang=amd.com at lists.x.org] On
> Behalf Of Huang, FrankR
> Sent: 2010?7?23? 17:18
> To: xorg-driver-geode at lists.x.org
> Subject: [Xorg-driver-geode] [PATCH 4/5] Fix the Nautilus file
> broswermisrendering issue
> 
> 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
> 
> 
> _______________________________________________
> Xorg-driver-geode mailing list
> Xorg-driver-geode at lists.x.org
> http://lists.x.org/mailman/listinfo/xorg-driver-geode




More information about the Xorg-driver-geode mailing list