[PATCH 9/9] exa: fix exaCopyArea and friends.
Maarten Maathuis
madman2003 at gmail.com
Wed Feb 4 05:33:02 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.c | 6 +++---
fb/fbcopy_helpers.h | 12 ++++++++++--
7 files changed, 77 insertions(+), 23 deletions(-)
diff --git a/exa/Makefile.am b/exa/Makefile.am
index 2b3f1e4..409dd09 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) -DFB_WRAP_PREFIX=exa
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(®ion), REGION_NUM_RECTS(®ion),
xSrc - xDst, ySrc - yDst,
- FALSE, FALSE, 0, NULL);
+ FALSE, FALSE, 0, NULL)) {
+ REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
+
+ /* 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, ®ion);
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.c b/fb/fbcopy_helpers.c
index b51b0ad..1611e7a 100644
--- a/fb/fbcopy_helpers.c
+++ b/fb/fbcopy_helpers.c
@@ -30,7 +30,7 @@
#include "fbcopy_helpers.h"
Bool
-fbCopyRegion (DrawablePtr pSrcDrawable,
+FB_WRAPPED_NAME(CopyRegion) (DrawablePtr pSrcDrawable,
DrawablePtr pDstDrawable,
GCPtr pGC,
RegionPtr pDstRegion,
@@ -151,7 +151,7 @@ fbCopyRegion (DrawablePtr pSrcDrawable,
}
RegionPtr
-fbDoCopy (DrawablePtr pSrcDrawable,
+FB_WRAPPED_NAME(DoCopy) (DrawablePtr pSrcDrawable,
DrawablePtr pDstDrawable,
GCPtr pGC,
int xIn,
@@ -340,7 +340,7 @@ fbDoCopy (DrawablePtr pSrcDrawable,
/* Do bit blitting */
numRects = REGION_NUM_RECTS(&rgnDst);
if (numRects && widthSrc && heightSrc)
- ret = fbCopyRegion (pSrcDrawable, pDstDrawable, pGC,
+ ret = FB_WRAPPED_NAME(CopyRegion) (pSrcDrawable, pDstDrawable, pGC,
&rgnDst, dx, dy, copyProc, bitPlane, closure);
else
ret = TRUE;
diff --git a/fb/fbcopy_helpers.h b/fb/fbcopy_helpers.h
index d523e92..9636ce9 100644
--- a/fb/fbcopy_helpers.h
+++ b/fb/fbcopy_helpers.h
@@ -23,8 +23,16 @@
#ifndef _FBCOPY_HELPERS_H_
#define _FBCOPY_HELPERS_H_
+#ifdef FB_WRAP_PREFIX
+#define FB_TEMP(prefix, name) prefix##name /* concentrate the two strings */
+#define FB_TEMP2(prefix, name) FB_TEMP(prefix, name) /* expand FB_WRAP_PREFIX to it's value */
+#define FB_WRAPPED_NAME(name) FB_TEMP2(FB_WRAP_PREFIX, name)
+#else
+#define FB_WRAPPED_NAME(name) fb##name
+#endif
+
extern _X_EXPORT Bool
-fbCopyRegion (DrawablePtr pSrcDrawable,
+FB_WRAPPED_NAME(CopyRegion) (DrawablePtr pSrcDrawable,
DrawablePtr pDstDrawable,
GCPtr pGC,
RegionPtr pDstRegion,
@@ -35,7 +43,7 @@ fbCopyRegion (DrawablePtr pSrcDrawable,
void *closure);
extern _X_EXPORT RegionPtr
-fbDoCopy (DrawablePtr pSrcDrawable,
+FB_WRAPPED_NAME(DoCopy) (DrawablePtr pSrcDrawable,
DrawablePtr pDstDrawable,
GCPtr pGC,
int xIn,
--
1.6.1.1
More information about the xorg
mailing list