[prev in list] [next in list] [prev in thread] [next in thread] 

List:       freedesktop-xorg
Subject:    Faster window resize in a composite manager
From:       Dennis Kasprzyk <onestone () opencompositing ! org>
Date:       2007-10-16 12:54:29
Message-ID: 200710161454.29558.onestone () opencompositing ! org
[Download RAW message or body]

Hi,

I've implemented my idea from my "Idea how to fix slow window resize in a 
composited desktop" post. My patches add a new function 
XCompositeSetWindowPixmapSize to Xcomposite. The compositing manager can use 
this function to set the window pixmap to the desired size, and the xserver 
will not change the pixmap and it's size during a resize. If 
XCompositeSetWindowPixmapSize is called with 0/0 as size, the xserver 
switches back to it's current pixmap handling and resizes the current pixmap 
back to the window size.

The compiz patches add the functionality to compiz to use the new function. 
Theses patches to compiz are only a prove of concept and are there a some 
things that need to be optimized in compiz with this new function.

I've seen a great resize speed improvement (still not as fast as without 
compiz) with the nvidia binary driver and got also positive feedback from 
tests with the intel driver.

Dennis Kasprzyk

["compiz-resize-with-composite-0.5.patch" (text/x-diff)]

diff --git a/metadata/resize.xml.in b/metadata/resize.xml.in
index 274f796..004810c 100644
--- a/metadata/resize.xml.in
+++ b/metadata/resize.xml.in
@@ -96,6 +96,11 @@
 		<_long>Windows that stretch resize should be used for</_long>
 		<default/>
 	    </option>
+	    <option name="big_pixmap" type="bool">
+		<_short>Use composite 0.5</_short>
+		<_long>Use composite 0.5 big pixmap resize</_long>
+		<default>true</default>
+	    </option>
 	</display>
     </plugin>
 </compiz>
diff --git a/plugins/resize.c b/plugins/resize.c
index c514ad2..47a2e09 100644
--- a/plugins/resize.c
+++ b/plugins/resize.c
@@ -32,6 +32,10 @@
 
 #include <compiz-core.h>
 
+#if COMPOSITE_MAJOR > 0 || COMPOSITE_MINOR > 2
+#define USE_CUSTOM_PIXMAP
+#endif
+
 static CompMetadata resizeMetadata;
 
 #define ResizeUpMask    (1L << 0)
@@ -76,7 +80,8 @@ struct _ResizeKeys {
 #define RESIZE_DISPLAY_OPTION_OUTLINE_MATCH	     10
 #define RESIZE_DISPLAY_OPTION_RECTANGLE_MATCH	     11
 #define RESIZE_DISPLAY_OPTION_STRETCH_MATCH	     12
-#define RESIZE_DISPLAY_OPTION_NUM		     13
+#define RESIZE_DISPLAY_OPTION_BIG_PIXMAP	     13
+#define RESIZE_DISPLAY_OPTION_NUM		     14
 
 static int displayPrivateIndex;
 
@@ -446,6 +451,18 @@ resizeInitiate (CompDisplay     *d,
 	{
 	    BoxRec box;
 
+#ifdef USE_CUSTOM_PIXMAP
+	    if (rd->opt[RESIZE_DISPLAY_OPTION_BIG_PIXMAP].value.b)
+	    {
+		CompScreen *s = w->screen;
+
+		releaseWindow (w);
+		XCompositeSetWindowPixmapSize (s->display->display,
+					       w->id, s->width, s->height);
+		bindWindow (w);
+	    }
+#endif
+
 	    rd->releaseButton = button;
 
 	    (w->screen->windowGrabNotify) (w, x, y, state,
@@ -551,6 +568,15 @@ resizeTerminate (CompDisplay	 *d,
 
 	if (rs->grabIndex)
 	{
+#ifdef USE_CUSTOM_PIXMAP
+	    if (rd->opt[RESIZE_DISPLAY_OPTION_BIG_PIXMAP].value.b)
+	    {
+		releaseWindow (w);
+		XCompositeSetWindowPixmapSize (w->screen->display->display,
+					       w->id, 0, 0);
+		bindWindow (w);
+	    }
+#endif
 	    removeScreenGrab (w->screen, rs->grabIndex, NULL);
 	    rs->grabIndex = 0;
 	}
@@ -1213,7 +1239,8 @@ static const CompMetadataOptionInfo resizeDisplayOptionInfo[] = {
     { "normal_match", "match", 0, 0, 0 },
     { "outline_match", "match", 0, 0, 0 },
     { "rectangle_match", "match", 0, 0, 0 },
-    { "stretch_match", "match", 0, 0, 0 }
+    { "stretch_match", "match", 0, 0, 0 },
+    { "big_pixmap", "bool", 0, 0, 0 }
 };
 
 static Bool

["xserver-composite-0.5.patch" (text/x-diff)]

diff --git a/composite/compalloc.c b/composite/compalloc.c
index 006e808..8a70ac5 100644
--- a/composite/compalloc.c
+++ b/composite/compalloc.c
@@ -137,6 +137,7 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
 	cw->oldy = COMP_ORIGIN_INVALID;
 	cw->damageRegistered = FALSE;
 	cw->damaged = FALSE;
+	cw->hasCustomPixmap = FALSE;
 	pWin->devPrivates[CompWindowPrivateIndex].ptr = cw;
     }
     ccw->next = cw->clients;
@@ -611,7 +612,8 @@ compReallocPixmap (WindowPtr pWin, int draw_x, int draw_y,
     pix_y = draw_y - bw;
     pix_w = w + (bw << 1);
     pix_h = h + (bw << 1);
-    if (pix_w != pOld->drawable.width || pix_h != pOld->drawable.height)
+    if ((pix_w != pOld->drawable.width || pix_h != pOld->drawable.height) &&
+	!cw->hasCustomPixmap)
     {
 	pNew = compNewPixmap (pWin, pix_x, pix_y, pix_w, pix_h);
 	if (!pNew)
diff --git a/composite/compext.c b/composite/compext.c
index ece51d0..b1e58c7 100644
--- a/composite/compext.c
+++ b/composite/compext.c
@@ -511,6 +511,36 @@ ProcCompositeReleaseOverlayWindow (ClientPtr client)
     return client->noClientException;
 }
 
+static int
+ProcCompositeSetWindowPixmapSize (ClientPtr client)
+{
+    WindowPtr	    pWin;
+    CompWindowPtr   cw;
+
+    REQUEST(xCompositeSetWindowPixmapSizeReq);
+
+    REQUEST_SIZE_MATCH(xCompositeSetWindowPixmapSizeReq);
+
+    pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
+    if (!pWin)
+    {
+	client->errorValue = stuff->window;
+	return BadWindow;
+    }
+
+    if (!pWin->viewable)
+	return BadMatch;
+
+    cw = GetCompWindow (pWin);
+    if (!cw)
+	return BadMatch;
+
+    if (!compSetWindowPixmapSize (pWin, stuff->width, stuff->height))
+	return BadMatch;
+
+    return(client->noClientException);
+}
+
 static int (*ProcCompositeVector[CompositeNumberRequests])(ClientPtr) = {
     ProcCompositeQueryVersion,
     ProcCompositeRedirectWindow,
@@ -521,6 +551,7 @@ static int (*ProcCompositeVector[CompositeNumberRequests])(ClientPtr) = {
     ProcCompositeNameWindowPixmap,
     ProcCompositeGetOverlayWindow,
     ProcCompositeReleaseOverlayWindow,
+    ProcCompositeSetWindowPixmapSize,
 };
 
 static int
@@ -645,6 +676,19 @@ SProcCompositeReleaseOverlayWindow (ClientPtr client)
     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
 }
 
+static int
+SProcCompositeSetWindowPixmapSize (ClientPtr client)
+{
+    int n;
+    REQUEST(xCompositeSetWindowPixmapSizeReq);
+    swaps (&stuff->length, n);
+    REQUEST_SIZE_MATCH(xCompositeSetWindowPixmapSizeReq);
+    swapl(&stuff->window, n);
+    swaps (&stuff->width, n);
+    swaps (&stuff->height, n);
+    return (*ProcCompositeVector[stuff->compositeReqType]) (client);
+}
+
 static int (*SProcCompositeVector[CompositeNumberRequests])(ClientPtr) = {
     SProcCompositeQueryVersion,
     SProcCompositeRedirectWindow,
@@ -655,6 +699,7 @@ static int (*SProcCompositeVector[CompositeNumberRequests])(ClientPtr) = {
     SProcCompositeNameWindowPixmap,
     SProcCompositeGetOverlayWindow,
     SProcCompositeReleaseOverlayWindow,
+    SProcCompositeSetWindowPixmapSize,
 };
 
 static int
diff --git a/composite/compint.h b/composite/compint.h
index 535e1a4..2f9f004 100644
--- a/composite/compint.h
+++ b/composite/compint.h
@@ -94,6 +94,7 @@ typedef struct _CompWindow {
     int			    oldy;
     PixmapPtr		    pOldPixmap;
     int			    borderClipX, borderClipY;
+    Bool		    hasCustomPixmap;
 } CompWindowRec, *CompWindowPtr;
 
 #define COMP_ORIGIN_INVALID	    0x80000000
@@ -297,4 +298,7 @@ CompositeRealChildHead (WindowPtr pWin);
 int
 DeleteWindowNoInputDevices(pointer value, XID wid);
 
+int
+compSetWindowPixmapSize (WindowPtr pWin, unsigned width, unsigned height);
+
 #endif /* _COMPINT_H_ */
diff --git a/composite/compwindow.c b/composite/compwindow.c
index 5792367..292b1af 100644
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -796,3 +796,44 @@ CompositeRealChildHead (WindowPtr pWin)
 	return pChildBefore;
     }
 }
+
+int
+compSetWindowPixmapSize (WindowPtr pWin, unsigned width, unsigned height)
+{
+    ScreenPtr       pScreen = pWin->drawable.pScreen;
+    CompWindowPtr   cw = GetCompWindow (pWin);
+    int             draw_x, draw_y, draw_w, draw_h;
+    unsigned int    bw;
+
+    compCheckTree (pScreen);
+    if (!pWin->redirectDraw)
+	return FALSE;
+
+    bw = wBorderWidth (pWin);
+    draw_x = pWin->drawable.x;
+    draw_y = pWin->drawable.y;
+    draw_w = pWin->drawable.width;
+    draw_h = pWin->drawable.height;
+
+    if (height > 0 && width > 0)
+    {
+	cw->hasCustomPixmap = FALSE;
+	compReallocPixmap (pWin, draw_x, draw_y, width, height, 0);
+	cw->hasCustomPixmap = TRUE;
+    }
+    else
+    {
+	cw->hasCustomPixmap = FALSE;
+	compReallocPixmap (pWin, draw_x, draw_y, draw_w, draw_h, bw);
+    }
+ 
+    if (cw->pOldPixmap)
+    {
+	(*pScreen->DestroyPixmap) (cw->pOldPixmap);
+	cw->pOldPixmap = NullPixmap;
+    }
+
+    compCheckTree (pScreen);
+
+    return TRUE;
+}

["libXcomposite-0.5.patch" (text/x-diff)]

diff --git a/configure.ac b/configure.ac
index 19ee08b..10c0961 100644
--- a/configure.ac
+++ b/configure.ac
@@ -34,7 +34,7 @@ dnl protocol, so Xcomposite version l.n.m corresponds to protocol version l.n
 dnl that 'revision' number appears in Xcomposite.h and has to be manually
 dnl synchronized.
 dnl
-AC_INIT(libXcomposite, 0.4.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], libXcomposite)
+AC_INIT(libXcomposite, 0.5.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], libXcomposite)
 AM_INIT_AUTOMAKE([dist-bzip2])
 AM_MAINTAINER_MODE
 
diff --git a/include/X11/extensions/Xcomposite.h b/include/X11/extensions/Xcomposite.h
index d37a691..0ace552 100644
--- a/include/X11/extensions/Xcomposite.h
+++ b/include/X11/extensions/Xcomposite.h
@@ -92,6 +92,9 @@ XCompositeGetOverlayWindow (Display *dpy, Window window);
 void
 XCompositeReleaseOverlayWindow (Display *dpy, Window window);
 
+void
+XCompositeSetWindowPixmapSize (Display *dpy, Window window, unsigned width, unsigned height);
+
 _XFUNCPROTOEND
 
 #endif /* _XCOMPOSITE_H_ */
diff --git a/src/Xcomposite.c b/src/Xcomposite.c
index e7d576a..ee34b7d 100644
--- a/src/Xcomposite.c
+++ b/src/Xcomposite.c
@@ -391,3 +391,21 @@ XCompositeReleaseOverlayWindow (Display *dpy, Window window)
     UnlockDisplay (dpy);
     SyncHandle ();
 }
+
+void
+XCompositeSetWindowPixmapSize (Display *dpy, Window window, unsigned width, unsigned height)
+{
+    XCompositeExtDisplayInfo	     *info = XCompositeFindDisplay (dpy);
+    xCompositeSetWindowPixmapSizeReq *req;
+
+    XCompositeSimpleCheckExtension (dpy, info);
+    LockDisplay (dpy);
+    GetReq (CompositeSetWindowPixmapSize, req);
+    req->reqType = info->codes->major_opcode;
+    req->compositeReqType = X_CompositeSetWindowPixmapSize;
+    req->window = window;
+    req->width = width;
+    req->height = height;
+    UnlockDisplay (dpy);
+    SyncHandle ();
+}

["compositeproto-0.5.patch" (text/x-diff)]

diff --git a/composite.h b/composite.h
index 30b190f..dcea72a 100644
--- a/composite.h
+++ b/composite.h
@@ -49,7 +49,7 @@
 
 #define COMPOSITE_NAME				"Composite"
 #define COMPOSITE_MAJOR				0
-#define COMPOSITE_MINOR				4
+#define COMPOSITE_MINOR				5
 
 #define CompositeRedirectAutomatic		0
 #define CompositeRedirectManual			1
@@ -63,8 +63,9 @@
 #define X_CompositeNameWindowPixmap		6
 #define X_CompositeGetOverlayWindow             7
 #define X_CompositeReleaseOverlayWindow         8
+#define X_CompositeSetWindowPixmapSize          9
 
-#define CompositeNumberRequests	    (X_CompositeReleaseOverlayWindow + 1)
+#define CompositeNumberRequests	    (X_CompositeSetWindowPixmapSize + 1)
 
 #define CompositeNumberEvents			0
 
diff --git a/compositeproto.h b/compositeproto.h
index 2e392e2..ea108cc 100644
--- a/compositeproto.h
+++ b/compositeproto.h
@@ -186,6 +186,21 @@ typedef struct {
 
 #define sz_xCompositeReleaseOverlayWindowReq sizeof(xCompositeReleaseOverlayWindowReq)
 
+/* Version 0.5 additions */
+
+typedef struct {
+    CARD8   reqType;
+    CARD8   compositeReqType;
+    CARD16  length B16;
+    Window  window B32;
+    CARD16  width B16;
+    CARD16  height B16;
+} xCompositeSetWindowPixmapSizeReq;
+
+#define sz_xCompositeSetWindowPixmapSizeReq 12
+
+
+
 #undef Window
 #undef Region
 #undef Pixmap
diff --git a/compositeproto.txt b/compositeproto.txt
index 4b86621..35bfc2b 100644
--- a/compositeproto.txt
+++ b/compositeproto.txt
@@ -1,5 +1,5 @@
 		         Composite Extension
-			     Version 0.4
+			     Version 0.5
 			      2007-7-3
 			    Keith Packard
 			  keithp@keithp.com
@@ -143,6 +143,10 @@ IncludeInferiors mode, and (perhaps more importantly), it will receive
 expose events in those regions caused by other actions. This new behaviour
 is not selectable.
 
+3.4 Changing window pixmap size
+
+Version 0.5 TODO
+
 4. Errors
 
 The composite extension does not define any new errors.
diff --git a/configure.ac b/configure.ac
index 3a5fc5e..85acb1d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -24,7 +24,7 @@ dnl
 dnl Process this file with autoconf to create configure.
 
 AC_PREREQ([2.57])
-AC_INIT([CompositeProto], [0.4], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg])
+AC_INIT([CompositeProto], [0.5], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 AM_MAINTAINER_MODE
 

["compiz-support-different-pixmap-size.patch" (text/x-diff)]

diff --git a/include/compiz-core.h b/include/compiz-core.h
index 62646e2..1747277 100644
--- a/include/compiz-core.h
+++ b/include/compiz-core.h
@@ -28,7 +28,7 @@
 
 #include <compiz-plugin.h>
 
-#define CORE_ABIVERSION 20070928
+#define CORE_ABIVERSION 20071008
 
 #include <stdio.h>
 #include <sys/time.h>
@@ -2484,6 +2484,8 @@ struct _CompWindow {
     Window	      clientLeader;
     XSizeHints	      sizeHints;
     Pixmap	      pixmap;
+    unsigned int      pixmapWidth;
+    unsigned int      pixmapHeight;
     CompTexture       *texture;
     CompMatrix        matrix;
     Damage	      damage;
diff --git a/src/window.c b/src/window.c
index 647b836..0a86beb 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1313,6 +1313,10 @@ bindWindow (CompWindow *w)
     {
 	XWindowAttributes attr;
 
+	unsigned int ui;
+	Window	     root;
+	int	     i;
+
 	/* don't try to bind window again if it failed previously */
 	if (w->bindFailed)
 	    return FALSE;
@@ -1332,11 +1336,19 @@ bindWindow (CompWindow *w)
 	w->pixmap = XCompositeNameWindowPixmap (w->screen->display->display,
 						w->id);
 
+	if (!XGetGeometry (w->screen->display->display, w->pixmap, &root, &i,
+			   &i, &w->pixmapWidth, &w->pixmapHeight, &ui, &ui))
+	{
+	    XFreePixmap (w->screen->display->display, w->pixmap);
+	    w->pixmap = None;
+	    w->bindFailed = TRUE;
+	    return FALSE;
+	}
 	XUngrabServer (w->screen->display->display);
     }
 
     if (!bindPixmapToTexture (w->screen, w->texture, w->pixmap,
-			      w->width, w->height,
+			      w->pixmapWidth, w->pixmapHeight,
 			      w->attrib.depth))
     {
 	compLogMessage (w->screen->display, "core", CompLogLevelInfo,
@@ -2514,7 +2526,7 @@ resizeWindow (CompWindow *w,
 	w->attrib.height       != height ||
 	w->attrib.border_width != borderWidth)
     {
-	unsigned int pw, ph, actualWidth, actualHeight, ui;
+	unsigned int pw, ph, ui;
 	int	     dx, dy, dwidth, dheight;
 	Pixmap	     pixmap = None;
 	Window	     root;
@@ -2529,10 +2541,10 @@ resizeWindow (CompWindow *w,
 	    pixmap = XCompositeNameWindowPixmap (w->screen->display->display,
 						 w->id);
 	    result = XGetGeometry (w->screen->display->display, pixmap, &root,
-				   &i, &i, &actualWidth, &actualHeight,
+				   &i, &i, &w->pixmapWidth, &w->pixmapHeight,
 				   &ui, &ui);
 
-	    if (!result || actualWidth != pw || actualHeight != ph)
+	    if (!result || w->pixmapWidth < pw || w->pixmapHeight < ph)
 	    {
 		XFreePixmap (w->screen->display->display, pixmap);
 


_______________________________________________
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic