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

Reply via email to