[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(®);
+ RegionCopy(®, prgnDst);
+ RegionTranslate(®, xoff + dx, yoff + dy);
+ pExaScr->prepare_access_reg(pPix, EXA_PREPARE_SRC, ®);
+ RegionUninit(®);
+ } else
+ exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);
+
+ if (pExaScr->prepare_access_reg) {
+ RegionNull(®);
+ RegionCopy(®, prgnDst);
+ RegionTranslate(®, xoff, yoff);
+ pExaScr->prepare_access_reg(pPix, EXA_PREPARE_SRC, ®);
+ RegionUninit(®);
+ } 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