---
 exa/exa_accel.c   |   43 ++++++++++++++++++++++++++++---------------
 exa/exa_priv.h    |   16 ++++++++++++++++
 exa/exa_render.c  |   17 +++++++++++++----
 exa/exa_unaccel.c |   27 +++++++++++++++++++++++++++
 4 files changed, 84 insertions(+), 19 deletions(-)

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index cc5dd18..b66b1da 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -359,8 +359,8 @@ exaCopyNtoNTwoDir (DrawablePtr pSrcDrawable, DrawablePtr 
pDstDrawable,
     return TRUE;
 }
 
-void
-exaCopyNtoN (DrawablePtr    pSrcDrawable,
+Bool
+exaHWCopyNtoN (DrawablePtr    pSrcDrawable,
             DrawablePtr    pDstDrawable,
             GCPtr          pGC,
             BoxPtr         pbox,
@@ -368,9 +368,7 @@ exaCopyNtoN (DrawablePtr    pSrcDrawable,
             int            dx,
             int            dy,
             Bool           reverse,
-            Bool           upsidedown,
-            Pixel          bitplane,
-            void           *closure)
+            Bool           upsidedown)
 {
     ExaScreenPriv (pDstDrawable->pScreen);
     PixmapPtr pSrcPixmap, pDstPixmap;
@@ -380,10 +378,11 @@ exaCopyNtoN (DrawablePtr    pSrcDrawable,
     ExaMigrationRec pixmaps[2];
     RegionPtr srcregion = NULL, dstregion = NULL;
     xRectangle *rects;
+    Bool ret = TRUE;
 
     /* avoid doing copy operations if no boxes */
     if (nbox == 0)
-       return;
+       return TRUE;
 
     pSrcPixmap = exaGetDrawablePixmap (pSrcDrawable);
     pDstPixmap = exaGetDrawablePixmap (pDstDrawable);
@@ -492,15 +491,7 @@ exaCopyNtoN (DrawablePtr    pSrcDrawable,
     goto out;
 
 fallback:
-    EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrcDrawable, pDstDrawable,
-                 exaDrawableLocation(pSrcDrawable),
-                 exaDrawableLocation(pDstDrawable)));
-    exaPrepareAccessReg (pDstDrawable, EXA_PREPARE_DEST, dstregion);
-    exaPrepareAccessReg (pSrcDrawable, EXA_PREPARE_SRC, srcregion);
-    fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse,
-               upsidedown, bitplane, closure);
-    exaFinishAccess (pSrcDrawable, EXA_PREPARE_SRC);
-    exaFinishAccess (pDstDrawable, EXA_PREPARE_DEST);
+    ret = FALSE;
 
 out:
     if (dstregion) {
@@ -511,6 +502,28 @@ out:
        REGION_UNINIT(pScreen, srcregion);
        REGION_DESTROY(pScreen, srcregion);
     }
+
+    return ret;
+}
+
+void
+exaCopyNtoN (DrawablePtr    pSrcDrawable,
+            DrawablePtr    pDstDrawable,
+            GCPtr          pGC,
+            BoxPtr         pbox,
+            int            nbox,
+            int            dx,
+            int            dy,
+            Bool           reverse,
+            Bool           upsidedown,
+            Pixel          bitplane,
+            void           *closure)
+{
+    if (exaHWCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, 
reverse, upsidedown))
+       return;
+
+    /* fallback */
+    ExaCheckCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, 
reverse, upsidedown, bitplane, closure);
 }
 
 RegionPtr
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 6d7c1dd..13de499 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -316,6 +316,11 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int 
depth,
                 int x, int y, int w, int h, int leftPad, int format,
                 char *bits);
 
+void
+ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst,  GCPtr pGC,
+            BoxPtr     pbox, int nbox, int dx, int dy, Bool    reverse, 
+            Bool upsidedown, Pixel bitplane, void *closure);
+
 RegionPtr
 ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
                 int srcx, int srcy, int w, int h, int dstx, int dsty);
@@ -465,6 +470,17 @@ RegionPtr
 exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
            int srcx, int srcy, int width, int height, int dstx, int dsty);
 
+Bool
+exaHWCopyNtoN (DrawablePtr    pSrcDrawable,
+            DrawablePtr    pDstDrawable,
+            GCPtr          pGC,
+            BoxPtr         pbox,
+            int            nbox,
+            int            dx,
+            int            dy,
+            Bool           reverse,
+            Bool           upsidedown);
+
 void
 exaCopyNtoN (DrawablePtr    pSrcDrawable,
             DrawablePtr    pDstDrawable,
diff --git a/exa/exa_render.c b/exa/exa_render.c
index 63ea5c1..1788531 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -851,6 +851,7 @@ exaComposite(CARD8  op,
                     !pSrc->repeat &&
                     !pSrc->transform)
            {
+               Bool ret;
                xDst += pDst->pDrawable->x;
                yDst += pDst->pDrawable->y;
                xSrc += pSrc->pDrawable->x;
@@ -861,12 +862,20 @@ exaComposite(CARD8        op,
                                               yDst, width, height))
                    goto done;
 
-
-               exaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, NULL,
+               ret = exaHWCopyNtoN(pSrc->pDrawable, pDst->pDrawable, NULL,
                             REGION_RECTS(&region), REGION_NUM_RECTS(&region),
-                            xSrc - xDst, ySrc - yDst,
-                            FALSE, FALSE, 0, NULL);
+                            xSrc - xDst, ySrc - yDst, FALSE, FALSE);
                REGION_UNINIT(pDst->pDrawable->pScreen, &region);
+
+               /* Reset values to their original values. */
+               xDst -= pDst->pDrawable->x;
+               yDst -= pDst->pDrawable->y;
+               xSrc -= pSrc->pDrawable->x;
+               ySrc -= pSrc->pDrawable->y;
+
+               if (!ret)
+                   goto fallback;
+
                goto done;
            }
            else if (pSrc->pDrawable != NULL &&
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index e0f2ae9..c9423d4 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -116,6 +116,33 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int 
depth,
     EXA_GC_EPILOGUE(pGC);
 }
 
+void
+ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst,  GCPtr pGC,
+            BoxPtr     pbox, int nbox, int dx, int dy, Bool    reverse, 
+            Bool upsidedown, Pixel bitplane, void *closure)
+{
+    /* This needs to be between brackets. */
+    if (pGC) {
+       EXA_GC_PROLOGUE(pGC);
+    }
+    EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
+                 exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
+    exaPrepareAccess (pDst, EXA_PREPARE_DEST);
+    exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
+    /* This will eventually call fbCopyNtoN, with some calculation overhead. */
+    while (nbox--) {
+       pGC->ops->CopyArea (pSrc, pDst, pGC, pbox->x1 - pSrc->x + dx, pbox->y1 
- pSrc->y + dy, 
+                       pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, pbox->x1 - 
pDst->x, pbox->y1 - pDst->y);
+       pbox++;
+    }
+    exaFinishAccess (pSrc, EXA_PREPARE_SRC);
+    exaFinishAccess (pDst, EXA_PREPARE_DEST);
+    if (pGC) {
+       ExaGCPriv(pGC);
+       EXA_GC_EPILOGUE(pGC);
+    }
+}
+
 RegionPtr
 ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
                 int srcx, int srcy, int w, int h, int dstx, int dsty)
-- 
1.6.1.1

_______________________________________________
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg

Reply via email to