[PATCH] [RFC] dix: don't use CopyWindow in driver level interface.

Dave Airlie airlied at gmail.com
Wed Mar 30 22:21:42 PDT 2011


From: Dave Airlie <airlied at redhat.com>

This splits CopyWindow before the exa/fb layers, and uses a
new interface called PixmapCopyRegion to do the actual copy.

The main point of this is a step towards removing WindowPtr's
from the interface that drivers see or use.

I've only lightly tested this with Xephyr in fb and fakexa modes,
but moving a window still moves and goes via the new paths.

Open thoughts:
a) exa should I restore the fallback hook for pixmapcopyregion
instead of copy window? feeling I have is yes.

b) should the hook take Pixmap or Drawable, it probably at least
needs an assert if it takes drawable and gets passed a window.

c) is PixmapCopyRegion a good enough name?

uxa: left as an exercise for the reader.

(not signed off yet).

Dave.
---
 exa/exa.c            |    4 +-
 exa/exa_accel.c      |   55 ++++++++--------------------------------
 exa/exa_priv.h       |   12 ++++----
 exa/exa_unaccel.c    |   67 +++++++++++++++++++++++++++++--------------------
 fb/fb.h              |   10 +++---
 fb/fbscreen.c        |    2 +-
 fb/fbwindow.c        |   33 +++---------------------
 include/scrnintstr.h |    6 ++++
 mi/mi.h              |    1 +
 mi/miscrinit.c       |    1 +
 mi/miwindow.c        |   29 +++++++++++++++++++++
 11 files changed, 107 insertions(+), 113 deletions(-)

diff --git a/exa/exa.c b/exa/exa.c
index a4e294a..604b657 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -792,7 +792,7 @@ exaCloseScreen(int i, ScreenPtr pScreen)
 	unwrap(pExaScr, pScreen, DestroyPixmap);
     if (pExaScr->SavedModifyPixmapHeader)
 	unwrap(pExaScr, pScreen, ModifyPixmapHeader);
-    unwrap(pExaScr, pScreen, CopyWindow);
+    unwrap(pExaScr, pScreen, PixmapCopyRegion);
     unwrap(pExaScr, pScreen, ChangeWindowAttributes);
     unwrap(pExaScr, pScreen, BitmapToRegion);
     unwrap(pExaScr, pScreen, CreateScreenResources);
@@ -951,7 +951,7 @@ exaDriverInit (ScreenPtr		pScreen,
     wrap(pExaScr, pScreen, CloseScreen, exaCloseScreen);
     wrap(pExaScr, pScreen, GetImage, exaGetImage);
     wrap(pExaScr, pScreen, GetSpans, ExaCheckGetSpans);
-    wrap(pExaScr, pScreen, CopyWindow, exaCopyWindow);
+    wrap(pExaScr, pScreen, PixmapCopyRegion, exaPixmapCopyRegion);
     wrap(pExaScr, pScreen, ChangeWindowAttributes, exaChangeWindowAttributes);
     wrap(pExaScr, pScreen, BitmapToRegion, exaBitmapToRegion);
     wrap(pExaScr, pScreen, CreateScreenResources, exaCreateScreenResources);
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index b4c0f83..fe5856f 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -577,19 +577,12 @@ exaCopyNtoN (DrawablePtr    pSrcDrawable,
 {
     ExaScreenPriv(pDstDrawable->pScreen);
 
-    if (pExaScr->fallback_counter ||
-	    (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW))
+    if (pExaScr->fallback_counter)
 	return;
 
     if (exaHWCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse, upsidedown))
 	return;
 
-    /* This is a CopyWindow, it's cleaner to fallback at the original call. */
-    if (pExaScr->fallback_flags & EXA_ACCEL_COPYWINDOW) {
-	pExaScr->fallback_flags |= EXA_FALLBACK_COPYWINDOW;
-	return;
-    }
-
     /* fallback */
     ExaCheckCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse, upsidedown, bitplane, closure);
 }
@@ -955,45 +948,19 @@ const GCOps exaOps = {
 };
 
 void
-exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+exaPixmapCopyRegion(PixmapPtr pPixmap,
+		    RegionPtr prgnDst,
+		    int dx, int dy)
 {
-    RegionRec	rgnDst;
-    int		dx, dy;
-    PixmapPtr	pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
-    ExaScreenPriv(pWin->drawable.pScreen);
-
-    dx = ptOldOrg.x - pWin->drawable.x;
-    dy = ptOldOrg.y - pWin->drawable.y;
-    RegionTranslate(prgnSrc, -dx, -dy);
-
-    RegionInit(&rgnDst, NullBox, 0);
-
-    RegionIntersect(&rgnDst, &pWin->borderClip, prgnSrc);
-#ifdef COMPOSITE
-    if (pPixmap->screen_x || pPixmap->screen_y)
-	RegionTranslate(&rgnDst,
-			  -pPixmap->screen_x, -pPixmap->screen_y);
-#endif
-
-    if (pExaScr->fallback_counter) {
-	pExaScr->fallback_flags |= EXA_FALLBACK_COPYWINDOW;
-	goto fallback;
+    ExaScreenPriv(pPixmap->drawable.pScreen);
+    if (pExaScr->fallback_counter || pExaScr->swappedOut) {
+	ExaCheckPixmapCopyRegion(pPixmap, prgnDst,
+				 dx, dy);
+	return;
     }
 
-    pExaScr->fallback_flags |= EXA_ACCEL_COPYWINDOW;
-    miCopyRegion (&pPixmap->drawable, &pPixmap->drawable,
-		  NULL,
-		  &rgnDst, dx, dy, exaCopyNtoN, 0, NULL);
-    pExaScr->fallback_flags &= ~EXA_ACCEL_COPYWINDOW;
-
-fallback:
-    RegionUninit(&rgnDst);
-
-    if (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW) {
-	pExaScr->fallback_flags &= ~EXA_FALLBACK_COPYWINDOW;
-	RegionTranslate(prgnSrc, dx, dy);
-	ExaCheckCopyWindow(pWin, ptOldOrg, prgnSrc);
-    }
+    miCopyRegion(&pPixmap->drawable, &pPixmap->drawable, NULL,
+		 prgnDst, dx, dy, exaCopyNtoN, 0, 0);
 }
 
 static Bool
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index e5d90d4..37906ba 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -137,9 +137,6 @@ typedef struct {
 
 #define EXA_NUM_GLYPH_CACHES 4
 
-#define EXA_FALLBACK_COPYWINDOW (1 << 0)
-#define EXA_ACCEL_COPYWINDOW (1 << 1)
-
 typedef struct _ExaMigrationRec {
     Bool as_dst;
     Bool as_src;
@@ -158,7 +155,7 @@ typedef struct {
     GetSpansProcPtr 		 SavedGetSpans;
     CreatePixmapProcPtr 	 SavedCreatePixmap;
     DestroyPixmapProcPtr 	 SavedDestroyPixmap;
-    CopyWindowProcPtr 		 SavedCopyWindow;
+    PixmapCopyRegionProcPtr 	 SavedPixmapCopyRegion;
     ChangeWindowAttributesProcPtr SavedChangeWindowAttributes;
     BitmapToRegionProcPtr        SavedBitmapToRegion;
     CreateScreenResourcesProcPtr SavedCreateScreenResources;
@@ -424,7 +421,8 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
 		   int w, int h, int x, int y);
 
 void
-ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
+ExaCheckPixmapCopyRegion(PixmapPtr pPix, RegionPtr prgnDst,
+			 int dx, int dy);
 
 void
 ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
@@ -458,7 +456,9 @@ exaGCReadsDestination(DrawablePtr pDrawable, unsigned long planemask,
 }
 
 void
-exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
+exaPixmapCopyRegion(PixmapPtr pPixmap,
+		    RegionPtr pRgnDst,
+		    int dx, int dy);
 
 Bool
 exaFillRegionTiled (DrawablePtr	pDrawable, RegionPtr pRegion, PixmapPtr pTile,
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index bd533c4..5358acb 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -162,6 +162,46 @@ ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst,  GCPtr pGC,
     EXA_POST_FALLBACK_GC(pGC);
 }
 
+void
+ExaCheckPixmapCopyRegion(PixmapPtr pPix, RegionPtr prgnDst,
+			 int dx, int dy)
+{
+    ScreenPtr pScreen = pPix->drawable.pScreen;
+    ExaScreenPriv(pScreen);
+    int xoff, yoff;
+    RegionRec reg;
+    DrawablePtr pDrawable = &pPix->drawable;
+
+    EXA_FALLBACK(("from %p\n", pPix, exaDrawableLocation(pDrawable)));
+
+    exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);
+
+    if (pExaScr->prepare_access_reg) {
+	RegionNull(&reg);
+	RegionCopy(&reg, prgnDst);
+	RegionTranslate(&reg, xoff + dx, yoff + dy);
+	pExaScr->prepare_access_reg(pPix, EXA_PREPARE_SRC, &reg);
+	RegionUninit(&reg);
+    } else
+	exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);
+
+    if (pExaScr->prepare_access_reg)  {
+	RegionNull(&reg);
+	RegionCopy(&reg, prgnDst);
+	RegionTranslate(&reg, xoff, yoff);
+	pExaScr->prepare_access_reg(pPix, EXA_PREPARE_SRC, &reg);
+	RegionUninit(&reg);
+    } else
+	exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
+
+    swap(pExaScr, pScreen, PixmapCopyRegion);
+    pScreen->PixmapCopyRegion(pPix, prgnDst, dx, dy);
+    swap(pExaScr, pScreen, PixmapCopyRegion);
+
+    exaFinishAccess(pDrawable, EXA_PREPARE_SRC);
+    exaFinishAccess(pDrawable, EXA_PREPARE_DEST); 
+}
+
 static void
 ExaFallbackPrepareReg(DrawablePtr pDrawable,
 		      GCPtr pGC,
@@ -369,33 +409,6 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
 }
 
 void
-ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
-{
-    DrawablePtr pDrawable = &pWin->drawable;
-    ScreenPtr pScreen = pDrawable->pScreen;
-    EXA_PRE_FALLBACK(pScreen);
-    EXA_FALLBACK(("from %p\n", pWin));
-
-    /* Only need the source bits, the destination region will be overwritten */
-    if (pExaScr->prepare_access_reg) {
-	PixmapPtr pPixmap = pScreen->GetWindowPixmap(pWin);
-	int xoff, yoff;
-
-	exaGetDrawableDeltas(&pWin->drawable, pPixmap, &xoff, &yoff);
-	RegionTranslate(prgnSrc, xoff, yoff);
-	pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, prgnSrc);
-	RegionTranslate(prgnSrc, -xoff, -yoff);
-    } else
-	exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);
-
-    swap(pExaScr, pScreen, CopyWindow);
-    pScreen->CopyWindow (pWin, ptOldOrg, prgnSrc);
-    swap(pExaScr, pScreen, CopyWindow);
-    exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
-    EXA_POST_FALLBACK(pScreen);
-}
-
-void
 ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
 		unsigned int format, unsigned long planeMask, char *d)
 {
diff --git a/fb/fb.h b/fb/fb.h
index bab1010..dd1f533 100644
--- a/fb/fb.h
+++ b/fb/fb.h
@@ -1315,6 +1315,11 @@ typedef void   (*fbCopyProc) (DrawablePtr  pSrcDrawable,
                               void         *closure);
 
 extern _X_EXPORT void
+fbPixmapCopyRegion(PixmapPtr pPixmap,
+		   RegionPtr prgnDst,
+		   int dx, int dy);
+
+extern _X_EXPORT void
 fbCopyNtoN (DrawablePtr	pSrcDrawable,
 	    DrawablePtr	pDstDrawable,
 	    GCPtr	pGC,
@@ -2005,11 +2010,6 @@ fbPositionWindow(WindowPtr pWin, int x, int y);
 extern _X_EXPORT Bool
 fbUnmapWindow(WindowPtr pWindow);
     
-extern _X_EXPORT void
-fbCopyWindow(WindowPtr	    pWin, 
-	     DDXPointRec    ptOldOrg, 
-	     RegionPtr	    prgnSrc);
-
 extern _X_EXPORT Bool
 fbChangeWindowAttributes(WindowPtr pWin, unsigned long mask);
 
diff --git a/fb/fbscreen.c b/fb/fbscreen.c
index fa518f6..5b5c583 100644
--- a/fb/fbscreen.c
+++ b/fb/fbscreen.c
@@ -115,7 +115,7 @@ fbSetupScreen(ScreenPtr	pScreen,
     pScreen->ChangeWindowAttributes = fbChangeWindowAttributes;
     pScreen->RealizeWindow = fbMapWindow;
     pScreen->UnrealizeWindow = fbUnmapWindow;
-    pScreen->CopyWindow = fbCopyWindow;
+    pScreen->PixmapCopyRegion = fbPixmapCopyRegion;
     pScreen->CreatePixmap = fbCreatePixmap;
     pScreen->DestroyPixmap = fbDestroyPixmap;
     pScreen->RealizeFont = fbRealizeFont;
diff --git a/fb/fbwindow.c b/fb/fbwindow.c
index d41b783..5cad00c 100644
--- a/fb/fbwindow.c
+++ b/fb/fbwindow.c
@@ -63,36 +63,13 @@ fbUnmapWindow(WindowPtr pWindow)
 }
 
 void
-fbCopyWindow(WindowPtr	    pWin, 
-	     DDXPointRec    ptOldOrg, 
-	     RegionPtr	    prgnSrc)
+fbPixmapCopyRegion(PixmapPtr pPixmap,
+		   RegionPtr prgnDst,
+		   int dx, int dy)
 {
-    RegionRec	rgnDst;
-    int		dx, dy;
-
-    PixmapPtr	pPixmap = fbGetWindowPixmap (pWin);
     DrawablePtr	pDrawable = &pPixmap->drawable;
-
-    dx = ptOldOrg.x - pWin->drawable.x;
-    dy = ptOldOrg.y - pWin->drawable.y;
-    RegionTranslate(prgnSrc, -dx, -dy);
-
-    RegionNull(&rgnDst);
-    
-    RegionIntersect(&rgnDst, &pWin->borderClip, prgnSrc);
-
-#ifdef COMPOSITE
-    if (pPixmap->screen_x || pPixmap->screen_y)
-	RegionTranslate(&rgnDst,
-			  -pPixmap->screen_x, -pPixmap->screen_y);
-#endif
-
-    miCopyRegion (pDrawable, pDrawable,
-		  NULL,
-		  &rgnDst, dx, dy, fbCopyNtoN, 0, 0);
-    
-    RegionUninit(&rgnDst);
-    fbValidateDrawable (&pWin->drawable);
+    miCopyRegion(pDrawable, pDrawable, NULL,
+		 prgnDst, dx, dy, fbCopyNtoN, 0, 0);
 }
 
 Bool
diff --git a/include/scrnintstr.h b/include/scrnintstr.h
index 83afa83..1c4f286 100644
--- a/include/scrnintstr.h
+++ b/include/scrnintstr.h
@@ -196,6 +196,11 @@ typedef    void (* ClipNotifyProcPtr)(
 	int /*dx*/,
 	int /*dy*/);
 
+typedef   void (* PixmapCopyRegionProcPtr)(
+	PixmapPtr pPixmap,
+	RegionPtr dstregion,
+	int dx, int dy);
+
 /* pixmap will exist only for the duration of the current rendering operation */
 #define CREATE_PIXMAP_USAGE_SCRATCH                     1
 /* pixmap will be the backing pixmap for a redirected window */
@@ -540,6 +545,7 @@ typedef struct _Screen {
     DeviceCursorInitializeProcPtr DeviceCursorInitialize;
     DeviceCursorCleanupProcPtr    DeviceCursorCleanup;
 
+    PixmapCopyRegionProcPtr PixmapCopyRegion;
     /* set it in driver side if X server can copy the framebuffer content.
      * Meant to be used together with '-background none' option, avoiding
      * malicious users to steal framebuffer's content if that would be the
diff --git a/mi/mi.h b/mi/mi.h
index fddf27f..1fb9dde 100644
--- a/mi/mi.h
+++ b/mi/mi.h
@@ -596,4 +596,5 @@ extern _X_EXPORT void miPolyFillArc(
     xArc * /*parcs*/
 );
 
+extern _X_EXPORT void miCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
 #endif /* MI_H */
diff --git a/mi/miscrinit.c b/mi/miscrinit.c
index fb01c68..348309e 100644
--- a/mi/miscrinit.c
+++ b/mi/miscrinit.c
@@ -252,6 +252,7 @@ miScreenInit(
     pScreen->ValidateTree = miValidateTree;
     pScreen->PostValidateTree = (PostValidateTreeProcPtr) 0;
     pScreen->WindowExposures = miWindowExposures;
+    pScreen->CopyWindow = miCopyWindow;
     /* CopyWindow */
     pScreen->ClearToBackground = miClearToBackground;
     pScreen->ClipNotify = (ClipNotifyProcPtr) 0;
diff --git a/mi/miwindow.c b/mi/miwindow.c
index dc5d21a..c74357d 100644
--- a/mi/miwindow.c
+++ b/mi/miwindow.c
@@ -822,3 +822,32 @@ miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth)
 	    miSegregateChildren(pChild, pReg, depth);
     }
 }
+
+void
+miCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+    /* get the pixmaps */
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    PixmapPtr pPixmap = pScreen->GetWindowPixmap(pWin);
+    RegionRec	rgnDst;
+    int xoff = 0, yoff = 0;
+    int dx, dy;
+
+
+    dx = ptOldOrg.x - pWin->drawable.x;
+    dy = ptOldOrg.y - pWin->drawable.y;
+    RegionTranslate(prgnSrc, -dx, -dy);
+    RegionNull(&rgnDst);
+    RegionIntersect(&rgnDst, &pWin->borderClip, prgnSrc);
+#ifdef COMPOSITE
+    if (pPixmap->screen_x || pPixmap->screen_y) {
+	xoff = -pPixmap->screen_x;
+	yoff = -pPixmap->screen_y;
+    }
+#endif
+    RegionTranslate(&rgnDst, xoff, yoff);
+
+    (*pScreen->PixmapCopyRegion)(pPixmap, &rgnDst, dx, dy);
+
+    RegionUninit(&rgnDst);    
+}
-- 
1.7.1



More information about the xorg-devel mailing list