From: Dave Airlie <airl...@gmail.com>

This makes X -retro actually render fast, as opposed to glacially slow.

Signed-off-by: Dave Airlie <airl...@redhat.com>
---
 src/uxa/uxa-accel.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 68 insertions(+), 10 deletions(-)

diff --git a/src/uxa/uxa-accel.c b/src/uxa/uxa-accel.c
index e456e6c..f7c32b7 100644
--- a/src/uxa/uxa-accel.c
+++ b/src/uxa/uxa-accel.c
@@ -1137,7 +1137,7 @@ uxa_fill_region_tiled(DrawablePtr pDrawable,
        int nbox = REGION_NUM_RECTS(pRegion);
        BoxPtr pBox = REGION_RECTS(pRegion);
        Bool ret = FALSE;
-
+       int i;
        tileWidth = pTile->drawable.width;
        tileHeight = pTile->drawable.height;
 
@@ -1157,24 +1157,31 @@ uxa_fill_region_tiled(DrawablePtr pDrawable,
            !uxa_screen->info->check_copy(pTile, pPixmap, alu, planemask))
                return FALSE;
 
-       REGION_TRANSLATE(pScreen, pRegion, xoff, yoff);
 
        if ((*uxa_screen->info->prepare_copy) (pTile, pPixmap, 1, 1, alu,
                                               planemask)) {
-               while (nbox--) {
-                       int height = pBox->y2 - pBox->y1;
-                       int dstY = pBox->y1;
+               if (xoff || yoff)
+                       REGION_TRANSLATE(pScreen, pRegion, xoff, yoff);
+
+                 for (i = 0; i < nbox; i++) {
+                       int height = pBox[i].y2 - pBox[i].y1;
+                       int dstY = pBox[i].y1;
                        int tileY;
 
+                       if (alu == GXcopy)
+                           height = min(height, tileHeight);
+
                        modulus(dstY - yoff - pDrawable->y - pPatOrg->y,
                                tileHeight, tileY);
 
                        while (height > 0) {
-                               int width = pBox->x2 - pBox->x1;
-                               int dstX = pBox->x1;
+                               int width = pBox[i].x2 - pBox[i].x1;
+                               int dstX = pBox[i].x1;
                                int tileX;
                                int h = tileHeight - tileY;
 
+                               if (alu == GXcopy)
+                                   width = min(width, tileWidth);
                                if (h > height)
                                        h = height;
                                height -= h;
@@ -1198,15 +1205,66 @@ uxa_fill_region_tiled(DrawablePtr pDrawable,
                                dstY += h;
                                tileY = 0;
                        }
-                       pBox++;
                }
                (*uxa_screen->info->done_copy) (pPixmap);
 
-               ret = TRUE;
+               if (alu != GXcopy)
+                       ret = TRUE;
+               else {
+                       Bool more_copy = FALSE;
+
+                       for (i = 0; i < nbox; i++) {
+                               int dstX = pBox[i].x1 + tileWidth;
+                               int dstY = pBox[i].y1 + tileHeight;
+
+                               if ((dstX < pBox[i].x2) || (dstY < pBox[i].y2)) 
{
+                                       more_copy = TRUE;
+                                       break;
+                               }
+                       }
+
+                       if (more_copy == FALSE)
+                               ret = TRUE;
+
+                       if (more_copy && (*uxa_screen->info->prepare_copy) 
(pPixmap, pPixmap, 1, 1, alu, planemask)) {
+                               for (i = 0; i < nbox; i++) {
+                                       int dstX = pBox[i].x1 + tileWidth;
+                                       int dstY = pBox[i].y1 + tileHeight;
+                                       int width = min(pBox[i].x2 - dstX, 
tileWidth);
+                                       int height = min(pBox[i].y2 - 
pBox[i].y1, tileHeight);
+
+                                       while (dstX < pBox[i].x2) {
+                                               (*uxa_screen->info->copy) 
(pPixmap,
+                                                                          
pBox[i].x1, pBox[i].y1,
+                                                                          
dstX, pBox[i].y1, 
+                                                                          
width, height);
+                                               dstX += width;
+                                               width = min(pBox[i].x2 - dstX, 
width * 2);
+                                       }
+
+                                       width = pBox[i].x2 - pBox[i].x1;
+                                       height = min(pBox[i].y2 - dstY, 
tileHeight);
+
+                                       while (dstY < pBox[i].y2) {
+                                               (*uxa_screen->info->copy) 
(pPixmap,
+                                                                          
pBox[i].x1, pBox[i].y1,
+                                                                          
pBox[i].x1, dstY, 
+                                                                          
width, height);
+                                               dstY += height;
+                                               height = min(pBox[i].y2 - dstY, 
height * 2);
+                                       }
+                               }
+                               (*uxa_screen->info->done_copy) (pPixmap);
+                               ret = TRUE;
+                       }
+               }
+
+               if (xoff || yoff)
+                       REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
+
        }
 
 out:
-       REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
 
        return ret;
 }
-- 
1.8.1.2

_______________________________________________
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel

Reply via email to