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 <[email protected]> --- 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 [email protected] http://lists.x.org/mailman/listinfo/xorg-driver-geode
