[Xorg-driver-geode] [PATCH 4/5] Fix the Nautilus file broswer misrendering issue
Huang, FrankR
FrankR.Huang at amd.com
Wed Aug 4 01:48:25 PDT 2010
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 | 197 ++++++++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 178 insertions(+), 19 deletions(-)
Temp patch 4
*Fix the google chrome hang
*Fix the PictOpOver srcX>source.width (srcY > source.height) condition
diff --git a/src/lx_exa.c b/src/lx_exa.c
index e8a001a..2f4c937 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,
@@ -1045,6 +1126,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 +1204,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 +1214,55 @@ 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 >= 0 && ((exaScratch.srcWidth <= srcX) ||
+ (exaScratch.srcHeight <= srcY)) &&
+ (exaScratch.op == PictOpOver)) {
+ if (exaScratch.repeat == 1) {
+ opWidth = width;
+ opHeight = height;
+ } else
+ nothing = 1;
+ } else if (srcX >= 0 && srcY >= 0 && exaScratch.op ==
+ PictOpOver) {
+ 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) {
+ if (nothing == 1)
+ break;
+
dstOffset = GetPixmapOffset(pxDst, opX, opY);
switch (exaScratch.type) {
@@ -1168,8 +1294,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.srcWidth <= srcX) ||
+ (exaScratch.srcHeight <= srcY)) && (exaScratch.op == PictOpOver)
+ && (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 +1338,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) {
+ 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