[PATCH 9/9] exa: fix exaCopyArea and friends.

Maarten Maathuis madman2003 at gmail.com
Tue Feb 3 15:25:33 PST 2009


---
 exa/Makefile.am     |    3 ++-
 exa/exa_accel.c     |   44 ++++++++++++++++++++++++++++++--------------
 exa/exa_priv.h      |    6 +++++-
 exa/exa_render.c    |   14 ++++++++++++--
 exa/exa_unaccel.c   |   15 +++++++++++++++
 fb/fbcopy_helpers.h |    5 +++++
 6 files changed, 69 insertions(+), 18 deletions(-)

diff --git a/exa/Makefile.am b/exa/Makefile.am
index 2b3f1e4..f344a05 100644
--- a/exa/Makefile.am
+++ b/exa/Makefile.am
@@ -12,11 +12,12 @@ INCLUDES = \
 	$(XORG_INCS) \
 	-I$(srcdir)/../miext/cw
 
-AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS)
+AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) -DEXA_WRAPPER
 
 libexa_la_SOURCES = \
 	exa.c \
 	exa.h \
+	../fb/fbcopy_helpers.c \
 	exa_accel.c \
 	exa_glyphs.c \
 	exa_migration.c \
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 02858f1..db79cee 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -359,7 +359,7 @@ exaCopyNtoNTwoDir (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
     return TRUE;
 }
 
-void
+Bool
 exaCopyNtoN (DrawablePtr    pSrcDrawable,
 	     DrawablePtr    pDstDrawable,
 	     GCPtr	    pGC,
@@ -383,7 +383,7 @@ exaCopyNtoN (DrawablePtr    pSrcDrawable,
 
     /* avoid doing copy operations if no boxes */
     if (nbox == 0)
-	return;
+	return TRUE;
 
     pSrcPixmap = exaGetDrawablePixmap (pSrcDrawable);
     pDstPixmap = exaGetDrawablePixmap (pDstDrawable);
@@ -492,15 +492,15 @@ 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);
+    if (dstregion) {
+	REGION_UNINIT(pScreen, dstregion);
+	REGION_DESTROY(pScreen, dstregion);
+    }
+    if (srcregion) {
+	REGION_UNINIT(pScreen, srcregion);
+	REGION_DESTROY(pScreen, srcregion);
+    }
+    return FALSE;
 
 out:
     if (dstregion) {
@@ -511,6 +511,8 @@ out:
 	REGION_UNINIT(pScreen, srcregion);
 	REGION_DESTROY(pScreen, srcregion);
     }
+
+    return TRUE;
 }
 
 RegionPtr
@@ -518,15 +520,25 @@ exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
 	    int srcx, int srcy, int width, int height, int dstx, int dsty)
 {
     ExaScreenPriv (pDstDrawable->pScreen);
+    RegionPtr ret;
+    Bool success;
 
     if (pExaScr->swappedOut) {
         return  ExaCheckCopyArea(pSrcDrawable, pDstDrawable, pGC,
                                  srcx, srcy, width, height, dstx, dsty);
     }
 
-    return  fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
+    ret = exaDoCopy (pSrcDrawable, pDstDrawable, pGC,
                       srcx, srcy, width, height,
-                      dstx, dsty, exaCopyNtoN, 0, NULL);
+                      dstx, dsty, exaCopyNtoN, 0, NULL, &success);
+
+    if (!success) {
+	xfree(ret);
+	return ExaCheckCopyArea(pSrcDrawable, pDstDrawable, pGC,
+                                 srcx, srcy, width, height, dstx, dsty);
+    }
+
+    return ret;
 }
 
 static void
@@ -865,6 +877,7 @@ exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
     RegionRec	rgnDst;
     int		dx, dy;
     PixmapPtr	pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
+    Bool ret;
 
     dx = ptOldOrg.x - pWin->drawable.x;
     dy = ptOldOrg.y - pWin->drawable.y;
@@ -879,11 +892,14 @@ exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
 			  -pPixmap->screen_x, -pPixmap->screen_y);
 #endif
 
-    fbCopyRegion (&pPixmap->drawable, &pPixmap->drawable,
+    ret = exaCopyRegion (&pPixmap->drawable, &pPixmap->drawable,
 		  NULL,
 		  &rgnDst, dx, dy, exaCopyNtoN, 0, NULL);
 
     REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
+
+    if (!ret)
+	ExaCheckCopyWindow(pWin, ptOldOrg, prgnSrc);
 }
 
 static Bool
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 6d7c1dd..c555f85 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -55,6 +55,7 @@
 #include "glyphstr.h"
 #endif
 #include "damage.h"
+#include "fbcopy_helpers.h"
 
 #define DEBUG_TRACE_FALL	0
 #define DEBUG_MIGRATE		0
@@ -379,6 +380,9 @@ ExaCheckAddTraps (PicturePtr	pPicture,
 		  int		ntrap,
 		  xTrap		*traps);
 
+void
+ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
+
 /* exa_accel.c */
 
 static _X_INLINE Bool
@@ -465,7 +469,7 @@ RegionPtr
 exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
 	    int srcx, int srcy, int width, int height, int dstx, int dsty);
 
-void
+Bool
 exaCopyNtoN (DrawablePtr    pSrcDrawable,
 	     DrawablePtr    pDstDrawable,
 	     GCPtr	    pGC,
diff --git a/exa/exa_render.c b/exa/exa_render.c
index 63ea5c1..361c2d2 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -862,10 +862,20 @@ exaComposite(CARD8	op,
 		    goto done;
 
 
-		exaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, NULL,
+		if (!exaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, NULL,
 			     REGION_RECTS(&region), REGION_NUM_RECTS(&region),
 			     xSrc - xDst, ySrc - yDst,
-			     FALSE, FALSE, 0, NULL);
+			     FALSE, FALSE, 0, NULL)) {
+			REGION_UNINIT(pDst->pDrawable->pScreen, &region);
+
+			/* Restore variables for fallback. */
+			xDst -= pDst->pDrawable->x;
+			yDst -= pDst->pDrawable->y;
+			xSrc -= pSrc->pDrawable->x;
+			ySrc -= pSrc->pDrawable->y;
+
+			goto fallback;
+		}
 		REGION_UNINIT(pDst->pDrawable->pScreen, &region);
 		goto done;
 	    }
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index e0f2ae9..93924c6 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -332,6 +332,21 @@ ExaCheckGetSpans (DrawablePtr pDrawable,
 }
 
 void
+ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    ExaScreenPriv(pScreen);
+
+    EXA_FALLBACK(("from %p (%c)\n", pWin->pDrawable, exaDrawableLocation(pWin->pDrawable)));
+    /* Since we're both src and dst, src seems the safest choice. */
+    exaPrepareAccess(&pWin->drawable, EXA_PREPARE_SRC);
+    swap(pExaScr, pScreen, CopyWindow);
+    pScreen->CopyWindow(pWin, ptOldOrg, prgnSrc);
+    swap(pExaScr, pScreen, CopyWindow);
+    exaFinishAccess (&pWin->drawable, EXA_PREPARE_SRC);
+}
+
+void
 ExaCheckComposite (CARD8      op,
                    PicturePtr pSrc,
                    PicturePtr pMask,
diff --git a/fb/fbcopy_helpers.h b/fb/fbcopy_helpers.h
index d523e92..ad8d1eb 100644
--- a/fb/fbcopy_helpers.h
+++ b/fb/fbcopy_helpers.h
@@ -23,6 +23,11 @@
 #ifndef _FBCOPY_HELPERS_H_
 #define _FBCOPY_HELPERS_H_
 
+#ifdef EXA_WRAPPER
+#define fbCopyRegion exaCopyRegion
+#define fbDoCopy exaDoCopy
+#endif
+
 extern _X_EXPORT Bool
 fbCopyRegion (DrawablePtr   pSrcDrawable,
 	      DrawablePtr   pDstDrawable,
-- 
1.6.1.1




More information about the xorg mailing list