summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHuang, FrankR <FrankR.Huang@amd.com>2010-08-06 11:16:02 +0800
committerMartin-√Čric Racine <q-funk@iki.fi>2010-08-06 07:52:30 +0300
commitecb741f27de4ca66555d312a4699efc22f873d0e (patch)
tree750f7e64c0d7434e1d1681cfb2f0dd39056c362e
parent5b93fdd42d7d8af4535fd62ce0749f2c4434f9fe (diff)
Fix the Nautilus file browser misrendering issue
This is patch 4 final this week. 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 Websites for test before and after this patch: 1)http://daduke.org (greater srcX and srcY) 2)http://bjdns2.cncmax.cn (negative srcX and srcY) From: Frank Huang <frankr.huang@amd.com> *When the srcX or srcY is greater than source width or source height (or negative),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@amd.com>
-rw-r--r--src/lx_exa.c195
1 files changed, 174 insertions, 21 deletions
diff --git a/src/lx_exa.c b/src/lx_exa.c
index e8a001a..83187fb 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,82 @@ 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;
+
+ /* Make sure srcX and srcY are in source region */
+ srcX = ((srcX % (int)exaScratch.srcWidth) + (int)exaScratch.srcWidth)
+ % (int)exaScratch.srcWidth;
+ srcY = ((srcY % (int)exaScratch.srcHeight) + (int)exaScratch.srcHeight)
+ % (int)exaScratch.srcHeight;
+
+ opWidth = exaScratch.srcWidth - srcX;
+ opHeight = exaScratch.srcHeight - srcY;
+
+ srcOffset = GetSrcOffset(srcX, srcY);
+
+ 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, 0);
+ opWidth = ((opX + width) - optempX) > (exaScratch.srcWidth - srcX)
+ ? (exaScratch.srcWidth - srcX) : ((opX + width) - optempX);
+ opHeight = ((opY + height) - optempY) > exaScratch.srcHeight
+ ? exaScratch.srcHeight : ((opY + height) - optempY);
+ } else if (optempY == opY) {
+ srcOffset = GetSrcOffset(0, srcY);
+ opWidth = ((opX + width) - optempX) > exaScratch.srcWidth
+ ? exaScratch.srcWidth : ((opX + width) - optempX);
+ opHeight = ((opY + height) - optempY) > (exaScratch.srcHeight -
+ srcY) ? (exaScratch.srcHeight - srcY) : ((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 +1016,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,17 +1198,68 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX,
* and maskY coordinate are negative or greater than
* exaScratch.srcWidth and exaScratch.srcHeight */
-
if (exaScratch.type == COMP_TYPE_MASK) {
if ((exaScratch.srcWidth - maskX) < opWidth)
opWidth = exaScratch.srcWidth - 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) {
+ /* This is the condition srcX or/and srcY is/are out of source
+ * region */
+ 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;
+ }
+ }
+ /* This is the condition srcX or/and srcY is/are in the source
+ * region */
+ } 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;
+ }
+ /* This is the condition srcX or/and srcY is/are negative */
+ } else if ((srcX < 0 || srcY < 0) &&
+ (exaScratch.op == PictOpOver || exaScratch.op == PictOpSrc)) {
+ if (exaScratch.repeat == 1) {
+ opWidth = width;
+ opHeight = height;
+ } else {
+ /* Have not met this condition till now */
+ return ;
+ }
+ } else {
+ if (exaScratch.srcWidth < opWidth)
+ opWidth = exaScratch.srcWidth;
+ if (exaScratch.srcHeight < opHeight)
+ opHeight = exaScratch.srcHeight;
+ }
+ } 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) {
@@ -1144,7 +1271,6 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX,
case COMP_TYPE_MASK:{
int direction =
(opPtr->channel == CIMGP_CHANNEL_A_SOURCE) ? 0 : 1;
-
maskflag = 1;
if (direction == 1) {
dstOffset =
@@ -1168,8 +1294,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.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 +1336,48 @@ 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;
+ 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;
}