On 05/27/2010 04:13 AM, Daniel Stone wrote:
* PGP Signed by an unknown key

On Wed, May 26, 2010 at 04:57:02PM -0700, Pierre-Loup A. Griffais wrote:
ValidateTree can be pretty expensive; gnome-shell floods the server with
input shape requests when animating windows, so that change makes it
perform a lot better.

Aaron suggested Keith and Adam as reviewers; are the SetWinSize,
SetBorderSize, ResizeChildrenWinSize also unneeded when changing the
input shape? The only thing that looks needed for sure is
CheckCursorConfinement(), but I have my doubts about the rest.

You don't need to call any of SetWinSize, SetBorderSize, or
ResizeChildrenWinSize, which are also moderately hostile.  So if you
skipped those three for changes only to the input shape:
Reviewed-by: Daniel Stone<[email protected]>

Great, thanks a lot. New patch attached that explicitly conditionalizes most of the function depending on the shape kind at Keith's suggestion. Indenting the new block caused my editor to destroy all the tabs, so I had to touch up the style of most of the function; sorry that makes the patch hard to read. Also updated the commit message to reflect the more general approach of the change.

Thanks!
 - Pierre-Loup


Cheers,
Daniel

* Unknown Key
* 0xB2808094
>From 753dba594a3ee08ec924c89b5dfea294c6169e18 Mon Sep 17 00:00:00 2001
From: Pierre-Loup A. Griffais <[email protected]>
Date: Wed, 26 May 2010 15:30:28 -0700
Subject: [PATCH] Only deal with input code when changing the input shape.

Propagate the shape kind all the way to SetShape to avoid performing non-input
operations such as revalidating the tree and generating exposures when only
changing a window's input shape.

Signed-off-by: Pierre-Loup A. Griffais <[email protected]>
Acked-by: Aaron Plattner<[email protected]>
---
 Xext/shape.c                  |    4 +-
 hw/dmx/dmxwindow.c            |    4 +-
 hw/dmx/dmxwindow.h            |    2 +-
 hw/xnest/Window.c             |    4 +-
 hw/xnest/XNWindow.h           |    2 +-
 hw/xwin/win.h                 |    4 +-
 hw/xwin/winmultiwindowshape.c |    6 +-
 hw/xwin/winwindow.c           |    6 +-
 include/scrnintstr.h          |    3 +-
 mi/mi.h                       |    3 +-
 mi/mioverlay.c                |   81 ++++++++++++++++++-----------------
 mi/miwindow.c                 |   94 +++++++++++++++++++++-------------------
 xfixes/region.c               |    2 +-
 13 files changed, 112 insertions(+), 103 deletions(-)

diff --git a/Xext/shape.c b/Xext/shape.c
index 93e4703..86b0bc0 100644
--- a/Xext/shape.c
+++ b/Xext/shape.c
@@ -220,7 +220,7 @@ RegionOperate (
     }
     if (srcRgn)
 	REGION_DESTROY(pScreen, srcRgn);
-    (*pScreen->SetShape) (pWin);
+    (*pScreen->SetShape) (pWin, kind);
     SendShapeNotify (pWin, kind);
     return Success;
 }
@@ -642,7 +642,7 @@ ProcShapeOffset (ClientPtr client)
     if (srcRgn)
     {
         REGION_TRANSLATE(pScreen, srcRgn, stuff->xOff, stuff->yOff);
-        (*pScreen->SetShape) (pWin);
+        (*pScreen->SetShape) (pWin, stuff->destKind);
     }
     SendShapeNotify (pWin, (int)stuff->destKind);
     return Success;
diff --git a/hw/dmx/dmxwindow.c b/hw/dmx/dmxwindow.c
index 39af510..5b0baff 100644
--- a/hw/dmx/dmxwindow.c
+++ b/hw/dmx/dmxwindow.c
@@ -991,7 +991,7 @@ static void dmxDoSetShape(WindowPtr pWindow)
 }
 
 /** Set shape of \a pWindow on the back-end server. */
-void dmxSetShape(WindowPtr pWindow)
+void dmxSetShape(WindowPtr pWindow, int kind)
 {
     ScreenPtr       pScreen = pWindow->drawable.pScreen;
     DMXScreenInfo  *dmxScreen = &dmxScreens[pScreen->myNum];
@@ -1000,7 +1000,7 @@ void dmxSetShape(WindowPtr pWindow)
     DMX_UNWRAP(SetShape, dmxScreen, pScreen);
 #if 1
     if (pScreen->SetShape)
-	pScreen->SetShape(pWindow);
+	pScreen->SetShape(pWindow, kind);
 #endif
 
     if (pWinPriv->window) {
diff --git a/hw/dmx/dmxwindow.h b/hw/dmx/dmxwindow.h
index 740a21f..8bd1f74 100644
--- a/hw/dmx/dmxwindow.h
+++ b/hw/dmx/dmxwindow.h
@@ -94,7 +94,7 @@ extern void dmxResizeRootWindow(WindowPtr pRoot,
 extern Bool dmxBEDestroyWindow(WindowPtr pWindow);
 
 /* Support for shape extension */
-extern void dmxSetShape(WindowPtr pWindow);
+extern void dmxSetShape(WindowPtr pWindow, int kind);
 
 /** Private index.  \see dmxwindow.c \see dmxscrinit.c */
 extern DevPrivateKey dmxWinPrivateKey;
diff --git a/hw/xnest/Window.c b/hw/xnest/Window.c
index 48c870f..11d5369 100644
--- a/hw/xnest/Window.c
+++ b/hw/xnest/Window.c
@@ -423,10 +423,10 @@ xnestWindowExposures(WindowPtr pWin, RegionPtr pRgn, RegionPtr other_exposed)
 }
 
 void
-xnestSetShape(WindowPtr pWin)
+xnestSetShape(WindowPtr pWin, int kind)
 {
   xnestShapeWindow(pWin);
-  miSetShape(pWin);
+  miSetShape(pWin, kind);
 }
 
 static Bool
diff --git a/hw/xnest/XNWindow.h b/hw/xnest/XNWindow.h
index b59d86a..92a1902 100644
--- a/hw/xnest/XNWindow.h
+++ b/hw/xnest/XNWindow.h
@@ -66,7 +66,7 @@ void xnestCopyWindow(WindowPtr pWin, xPoint oldOrigin, RegionPtr oldRegion);
 void xnestClipNotify(WindowPtr pWin, int dx, int dy);
 void xnestWindowExposures(WindowPtr pWin, RegionPtr pRgn,
 			  RegionPtr other_exposed);
-void xnestSetShape(WindowPtr pWin);
+void xnestSetShape(WindowPtr pWin, int kind);
 void xnestShapeWindow(WindowPtr pWin);
 
 #endif /* XNESTWINDOW_H */
diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index 26bb856..49b73d7 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -1204,7 +1204,7 @@ Bool
 winMapWindowRootless (WindowPtr pWindow);
 
 void
-winSetShapeRootless (WindowPtr pWindow);
+winSetShapeRootless (WindowPtr pWindow, int kind);
 
 
 /*
@@ -1226,7 +1226,7 @@ void
 winReshapeMultiWindow (WindowPtr pWin);
 
 void
-winSetShapeMultiWindow (WindowPtr pWindow);
+winSetShapeMultiWindow (WindowPtr pWindow, int kind);
 
 void
 winUpdateRgnMultiWindow (WindowPtr pWindow);
diff --git a/hw/xwin/winmultiwindowshape.c b/hw/xwin/winmultiwindowshape.c
index 3532357..597eab6 100644
--- a/hw/xwin/winmultiwindowshape.c
+++ b/hw/xwin/winmultiwindowshape.c
@@ -41,17 +41,17 @@
  */
 
 void
-winSetShapeMultiWindow (WindowPtr pWin)
+winSetShapeMultiWindow (WindowPtr pWin, int kind)
 {
   ScreenPtr		pScreen = pWin->drawable.pScreen;
   winScreenPriv(pScreen);
 
 #if CYGMULTIWINDOW_DEBUG
-  ErrorF ("winSetShapeMultiWindow - pWin: %08x\n", pWin);
+  ErrorF ("winSetShapeMultiWindow - pWin: %08x kind: %i\n", pWin, kind);
 #endif
   
   WIN_UNWRAP(SetShape); 
-  (*pScreen->SetShape)(pWin);
+  (*pScreen->SetShape)(pWin, kind);
   WIN_WRAP(SetShape, winSetShapeMultiWindow);
   
   /* Update the Windows window's shape */
diff --git a/hw/xwin/winwindow.c b/hw/xwin/winwindow.c
index 30b6729..d0c360f 100644
--- a/hw/xwin/winwindow.c
+++ b/hw/xwin/winwindow.c
@@ -451,17 +451,17 @@ winMapWindowRootless (WindowPtr pWin)
 
 
 void
-winSetShapeRootless (WindowPtr pWin)
+winSetShapeRootless (WindowPtr pWin, int kind)
 {
   ScreenPtr		pScreen = pWin->drawable.pScreen;
   winScreenPriv(pScreen);
 
 #if CYGDEBUG
-  winTrace ("winSetShapeRootless (%p)\n", pWin);
+  winTrace ("winSetShapeRootless (%p, %i)\n", pWin, kind);
 #endif
 
   WIN_UNWRAP(SetShape); 
-  (*pScreen->SetShape)(pWin);
+  (*pScreen->SetShape)(pWin, kind);
   WIN_WRAP(SetShape, winSetShapeRootless);
   
   winReshapeRootless (pWin);
diff --git a/include/scrnintstr.h b/include/scrnintstr.h
index 6f1936c..21b4a16 100644
--- a/include/scrnintstr.h
+++ b/include/scrnintstr.h
@@ -423,7 +423,8 @@ typedef    void (* ReparentWindowProcPtr)(
     WindowPtr /*pPriorParent*/);
 
 typedef    void (* SetShapeProcPtr)(
-	WindowPtr /*pWin*/);
+        WindowPtr /*pWin*/,
+        int /* kind */);
 
 typedef    void (* ChangeBorderWidthProcPtr)(
 	WindowPtr /*pWin*/,
diff --git a/mi/mi.h b/mi/mi.h
index 812edce..321523b 100644
--- a/mi/mi.h
+++ b/mi/mi.h
@@ -567,7 +567,8 @@ extern _X_EXPORT WindowPtr miGetLayerWindow(
 );
 
 extern _X_EXPORT void miSetShape(
-    WindowPtr /*pWin*/
+    WindowPtr /*pWin*/,
+    int /*kind*/
 );
 
 extern _X_EXPORT void miChangeBorderWidth(
diff --git a/mi/mioverlay.c b/mi/mioverlay.c
index 2de7682..df43196 100644
--- a/mi/mioverlay.c
+++ b/mi/mioverlay.c
@@ -5,6 +5,7 @@
 
 #include <X11/X.h>
 #include "scrnintstr.h"
+#include <X11/extensions/shapeproto.h>
 #include "validate.h"
 #include "windowstr.h"
 #include "mi.h"
@@ -82,7 +83,7 @@ static void miOverlayResizeWindow(WindowPtr, int, int, unsigned int,
 					unsigned int, WindowPtr);
 static void miOverlayClearToBackground(WindowPtr, int, int, int, int, Bool);
 
-static void miOverlaySetShape(WindowPtr);
+static void miOverlaySetShape(WindowPtr, int);
 static void miOverlayChangeBorderWidth(WindowPtr, unsigned int);
 
 #define MIOVERLAY_GET_SCREEN_PRIVATE(pScreen) ((miOverlayScreenPtr) \
@@ -1497,53 +1498,55 @@ miOverlayResizeWindow(
 
 
 static void
-miOverlaySetShape(WindowPtr pWin)
+miOverlaySetShape(WindowPtr pWin, int kind)
 {
-    Bool	WasViewable = (Bool)(pWin->viewable);
-    ScreenPtr 	pScreen = pWin->drawable.pScreen;
-
-    if (WasViewable) {
-	(*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL);
-
-	if (HasBorder (pWin)) {
-	    RegionPtr borderVisible;
-
-	    borderVisible = REGION_CREATE(pScreen, NullBox, 1);
-	    REGION_SUBTRACT(pScreen, borderVisible,
-				      &pWin->borderClip, &pWin->winSize);
-	    pWin->valdata->before.borderVisible = borderVisible;
-	    pWin->valdata->before.resized = TRUE;
-	    if(IN_UNDERLAY(pWin)) {
-		miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
-		RegionPtr borderVisible2;
-
-		borderVisible2 = REGION_CREATE(pScreen, NULL, 1);
-		REGION_SUBTRACT(pScreen, borderVisible2,
-				      &pTree->borderClip, &pWin->winSize);
-		pTree->valdata->borderVisible = borderVisible2;
-	    }
-	}
-    }
+    Bool        WasViewable = (Bool)(pWin->viewable);
+    ScreenPtr   pScreen = pWin->drawable.pScreen;
+
+    if (kind != ShapeInput) {
+        if (WasViewable) {
+            (*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL);
+
+            if (HasBorder (pWin)) {
+                RegionPtr borderVisible;
+
+                borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+                REGION_SUBTRACT(pScreen, borderVisible,
+                                        &pWin->borderClip, &pWin->winSize);
+                pWin->valdata->before.borderVisible = borderVisible;
+                pWin->valdata->before.resized = TRUE;
+                if(IN_UNDERLAY(pWin)) {
+                    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+                    RegionPtr borderVisible2;
+
+                    borderVisible2 = REGION_CREATE(pScreen, NULL, 1);
+                    REGION_SUBTRACT(pScreen, borderVisible2,
+                                        &pTree->borderClip, &pWin->winSize);
+                    pTree->valdata->borderVisible = borderVisible2;
+                }
+            }
+        }
 
-    SetWinSize (pWin);
-    SetBorderSize (pWin);
+        SetWinSize (pWin);
+        SetBorderSize (pWin);
 
-    ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+        ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
 
-    if (WasViewable) {
-	(*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL);
+        if (WasViewable) {
+            (*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL);
 
 
-	(*pScreen->ValidateTree)(pWin->parent, NullWindow, VTOther);
-    }
+            (*pScreen->ValidateTree)(pWin->parent, NullWindow, VTOther);
+        }
 
-    if (WasViewable) {
-	(*pScreen->HandleExposures)(pWin->parent);
-	if (pScreen->PostValidateTree)
-	    (*pScreen->PostValidateTree)(pWin->parent, NullWindow, VTOther);
+        if (WasViewable) {
+            (*pScreen->HandleExposures)(pWin->parent);
+            if (pScreen->PostValidateTree)
+                (*pScreen->PostValidateTree)(pWin->parent, NullWindow, VTOther);
+        }
     }
     if (pWin->realized)
-	WindowsRestructured ();
+        WindowsRestructured ();
     CheckCursorConfinement(pWin);
 }
 
diff --git a/mi/miwindow.c b/mi/miwindow.c
index 2550ca2..ce35974 100644
--- a/mi/miwindow.c
+++ b/mi/miwindow.c
@@ -50,6 +50,7 @@ SOFTWARE.
 #endif
 
 #include <X11/X.h>
+#include <X11/extensions/shape.h>
 #include "regionstr.h"
 #include "region.h"
 #include "mi.h"
@@ -696,56 +697,59 @@ miGetLayerWindow(WindowPtr pWin)
  */
 
 void
-miSetShape(WindowPtr pWin)
+miSetShape(WindowPtr pWin, int kind)
 {
-    Bool	WasViewable = (Bool)(pWin->viewable);
-    ScreenPtr 	pScreen = pWin->drawable.pScreen;
-    Bool	anyMarked = FALSE;
+    Bool        WasViewable = (Bool)(pWin->viewable);
+    ScreenPtr   pScreen = pWin->drawable.pScreen;
+    Bool        anyMarked = FALSE;
     WindowPtr   pLayerWin;
 
-    if (WasViewable)
-    {
-	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
-						      &pLayerWin);
-	if (pWin->valdata)
-	{
-	    if (HasBorder (pWin))
-	    {
-		RegionPtr	borderVisible;
-
-		borderVisible = REGION_CREATE(pScreen, NullBox, 1);
-		REGION_SUBTRACT(pScreen, borderVisible,
-				      &pWin->borderClip, &pWin->winSize);
-		pWin->valdata->before.borderVisible = borderVisible;
-	    }
-	    pWin->valdata->before.resized = TRUE;
-	}
-    }
-
-    SetWinSize (pWin);
-    SetBorderSize (pWin);
-
-    ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
-
-    if (WasViewable)
-    {
-	anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
-						NULL);
-
-
-	if (anyMarked)
-	    (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, VTOther);
-    }
-
-    if (WasViewable)
-    {
-	if (anyMarked)
-	    (*pScreen->HandleExposures)(pLayerWin->parent);
-	if (anyMarked && pScreen->PostValidateTree)
-	    (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, VTOther);
+    if (kind != ShapeInput) {
+        if (WasViewable)
+        {
+            anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+                                                          &pLayerWin);
+            if (pWin->valdata)
+            {
+                if (HasBorder (pWin))
+                {
+                    RegionPtr borderVisible;
+
+                    borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+                    REGION_SUBTRACT(pScreen, borderVisible,
+                                    &pWin->borderClip, &pWin->winSize);
+                    pWin->valdata->before.borderVisible = borderVisible;
+                }
+                pWin->valdata->before.resized = TRUE;
+            }
+        }
+
+        SetWinSize (pWin);
+        SetBorderSize (pWin);
+
+        ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+        if (WasViewable)
+        {
+            anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+                                                           NULL);
+
+            if (anyMarked)
+                (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow,
+                                         VTOther);
+        }
+
+        if (WasViewable)
+        {
+            if (anyMarked)
+                (*pScreen->HandleExposures)(pLayerWin->parent);
+            if (anyMarked && pScreen->PostValidateTree)
+                (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow,
+                                             VTOther);
+        }
     }
     if (pWin->realized)
-	WindowsRestructured ();
+        WindowsRestructured ();
     CheckCursorConfinement(pWin);
 }
 
diff --git a/xfixes/region.c b/xfixes/region.c
index 7a71c78..b034ad0 100644
--- a/xfixes/region.c
+++ b/xfixes/region.c
@@ -733,7 +733,7 @@ ProcXFixesSetWindowShapeRegion (ClientPtr client)
     if (*pDestRegion)
 	REGION_DESTROY(pScreen, *pDestRegion);
     *pDestRegion = pRegion;
-    (*pScreen->SetShape) (pWin);
+    (*pScreen->SetShape) (pWin, stuff->destKind);
     SendShapeNotify (pWin, stuff->destKind);
     return Success;
 }
-- 
1.7.0.4

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to