[PATCH] composite: fix freeing of old pixmap until after move/resize/cbw

Dave Airlie airlied at gmail.com
Sun Jun 20 23:33:55 PDT 2010


From: Dave Airlie <airlied at redhat.com>

The fixes for the composite reallocation failure, were freeing the oldpixmap
straight after reallocating the new one, however this led to some wierd
effects in e16 compositing, and I think in a few other places. This patch
moves the freeing of the pixmap into the post wrapped stage. I'm not sure if
we are actually better off breaking ABI and adding another callback from the
ConfigureWindow to composite to make sure the old pixmap is always freed,
but this should be satisfactory as we should always hit one of the freeing
paths or else its a bug in the DIX.

bug: https://bugs.freedesktop.org/show_bug.cgi?id=28435
Reported-by: Andrew Randrianasulu <randrik at mail.ru>
Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 composite/compinit.c   |   12 ++++++++
 composite/compint.h    |   17 +++++++++++-
 composite/compwindow.c |   68 +++++++++++++++++++++++++++++++++++++++++------
 3 files changed, 87 insertions(+), 10 deletions(-)

diff --git a/composite/compinit.c b/composite/compinit.c
index 1b2cd8f..5db9f02 100644
--- a/composite/compinit.c
+++ b/composite/compinit.c
@@ -66,6 +66,9 @@ compCloseScreen (int index, ScreenPtr pScreen)
     pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes;
     pScreen->ReparentWindow = cs->ReparentWindow;
     pScreen->ConfigNotify = cs->ConfigNotify;
+    pScreen->MoveWindow = cs->MoveWindow;
+    pScreen->ResizeWindow = cs->ResizeWindow;
+    pScreen->ChangeBorderWidth = cs->ChangeBorderWidth;
     
     pScreen->ClipNotify = cs->ClipNotify;
     pScreen->UnrealizeWindow = cs->UnrealizeWindow;
@@ -366,6 +369,15 @@ compScreenInit (ScreenPtr pScreen)
     cs->ConfigNotify = pScreen->ConfigNotify;
     pScreen->ConfigNotify = compConfigNotify;
 
+    cs->MoveWindow = pScreen->MoveWindow;
+    pScreen->MoveWindow = compMoveWindow;
+
+    cs->ResizeWindow = pScreen->ResizeWindow;
+    pScreen->ResizeWindow = compResizeWindow;
+
+    cs->ChangeBorderWidth = pScreen->ChangeBorderWidth;
+    pScreen->ChangeBorderWidth = compChangeBorderWidth;
+
     cs->ReparentWindow = pScreen->ReparentWindow;
     pScreen->ReparentWindow = compReparentWindow;
 
diff --git a/composite/compint.h b/composite/compint.h
index 9c1ffd5..80083b0 100644
--- a/composite/compint.h
+++ b/composite/compint.h
@@ -127,9 +127,14 @@ typedef struct _CompScreen {
     UnrealizeWindowProcPtr	UnrealizeWindow;
     ClipNotifyProcPtr		ClipNotify;
     /*
-     * Called from ConfigureWindow.
+     * Called from ConfigureWindow, these
+     * three track changes to the offscreen storage
+     * geometry
      */
     ConfigNotifyProcPtr         ConfigNotify;
+    MoveWindowProcPtr		MoveWindow;
+    ResizeWindowProcPtr		ResizeWindow;
+    ChangeBorderWidthProcPtr	ChangeBorderWidth;
     /*
      * Reparenting has an effect on Subwindows redirect
      */
@@ -281,6 +286,16 @@ void
 compClipNotify (WindowPtr pWin, int dx, int dy);
 
 void
+compMoveWindow (WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind);
+
+void
+compResizeWindow (WindowPtr pWin, int x, int y,
+		  unsigned int w, unsigned int h, WindowPtr pSib);
+
+void
+compChangeBorderWidth (WindowPtr pWin, unsigned int border_width);
+
+void
 compReparentWindow (WindowPtr pWin, WindowPtr pPriorParent);
 
 Bool
diff --git a/composite/compwindow.c b/composite/compwindow.c
index 7d877b1..160b764 100644
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -334,6 +334,65 @@ compImplicitRedirect (WindowPtr pWin, WindowPtr pParent)
     return FALSE;
 }
 
+static void compFreeOldPixmap(WindowPtr pWin)
+{
+    ScreenPtr		pScreen = pWin->drawable.pScreen;
+    if (pWin->redirectDraw != RedirectDrawNone)
+    {
+	CompWindowPtr	cw = GetCompWindow (pWin);
+	if (cw->pOldPixmap)
+	{
+	    (*pScreen->DestroyPixmap) (cw->pOldPixmap);
+	    cw->pOldPixmap = NullPixmap;
+	}
+    }
+}
+void
+compMoveWindow (WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind)
+{
+    ScreenPtr		pScreen = pWin->drawable.pScreen;
+    CompScreenPtr	cs = GetCompScreen (pScreen);
+
+    pScreen->MoveWindow = cs->MoveWindow;
+    (*pScreen->MoveWindow) (pWin, x, y, pSib, kind);
+    cs->MoveWindow = pScreen->MoveWindow;
+    pScreen->MoveWindow = compMoveWindow;
+
+    compFreeOldPixmap(pWin);
+    compCheckTree (pScreen);
+}
+
+void
+compResizeWindow (WindowPtr pWin, int x, int y,
+		  unsigned int w, unsigned int h, WindowPtr pSib)
+{
+    ScreenPtr		pScreen = pWin->drawable.pScreen;
+    CompScreenPtr	cs = GetCompScreen (pScreen);
+
+    pScreen->ResizeWindow = cs->ResizeWindow;
+    (*pScreen->ResizeWindow) (pWin, x, y, w, h, pSib);
+    cs->ResizeWindow = pScreen->ResizeWindow;
+    pScreen->ResizeWindow = compResizeWindow;
+
+    compFreeOldPixmap(pWin);
+    compCheckTree (pWin->drawable.pScreen);
+}
+
+void
+compChangeBorderWidth (WindowPtr pWin, unsigned int bw)
+{
+    ScreenPtr		pScreen = pWin->drawable.pScreen;
+    CompScreenPtr	cs = GetCompScreen (pScreen);
+
+    pScreen->ChangeBorderWidth = cs->ChangeBorderWidth;
+    (*pScreen->ChangeBorderWidth) (pWin, bw);
+    cs->ChangeBorderWidth = pScreen->ChangeBorderWidth;
+    pScreen->ChangeBorderWidth = compChangeBorderWidth;
+
+    compFreeOldPixmap(pWin);
+    compCheckTree (pWin->drawable.pScreen);
+}
+
 void
 compReparentWindow (WindowPtr pWin, WindowPtr pPriorParent)
 {
@@ -705,7 +764,6 @@ compConfigNotify(WindowPtr pWin, int x, int y, int w, int h,
     CompScreenPtr	cs = GetCompScreen (pScreen);
     Bool                ret = 0;
     WindowPtr		pParent = pWin->parent;
-    CompWindowPtr       cw;
     int			draw_x, draw_y;
     Bool alloc_ret;
 
@@ -728,14 +786,6 @@ compConfigNotify(WindowPtr pWin, int x, int y, int w, int h,
     draw_x = pParent->drawable.x + x + bw;
     draw_y = pParent->drawable.y + y + bw;
     alloc_ret = compReallocPixmap (pWin, draw_x, draw_y, w, h, bw);
-    
-    cw = GetCompWindow (pWin);
-    if (cw->pOldPixmap)
-    {
-	(*pScreen->DestroyPixmap) (cw->pOldPixmap);
-	cw->pOldPixmap = NullPixmap;
-    }
-    compCheckTree (pScreen);
 
     if (alloc_ret == FALSE)
 	return BadAlloc;
-- 
1.7.0.1



More information about the xorg-devel mailing list