[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