[Xorg-driver-geode] [PATCH 4/4] Fix the Nautilus file broswer misrendering issue
Huang, FrankR
FrankR.Huang at amd.com
Wed Jul 14 23:49:47 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 | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 135 insertions(+), 19 deletions(-)
NOTE:***************
Based on the Jonathan's suggestion, the source start point should be calculated by a modulus operation. So resend the patch.
********************
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
More information about the Xorg-driver-geode
mailing list