[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