Merge lp:~compiz-team/compiz/compiz.fix_1002602 into lp:compiz/0.9.8

Proposed by Sam Spilsbury
Status: Merged
Merged at revision: 3223
Proposed branch: lp:~compiz-team/compiz/compiz.fix_1002602
Merge into: lp:compiz/0.9.8
Diff against target: 213 lines (+65/-18)
5 files modified
plugins/composite/include/composite/composite.h (+8/-0)
plugins/composite/src/privates.h (+2/-0)
plugins/composite/src/window.cpp (+42/-12)
plugins/opengl/src/privates.h (+2/-0)
plugins/opengl/src/window.cpp (+11/-6)
To merge this branch: bzr merge lp:~compiz-team/compiz/compiz.fix_1002602
Reviewer Review Type Date Requested Status
Daniel van Vugt Approve
Review via email: mp+107325@code.launchpad.net

Description of the change

Delay unbinding of pixmaps until then next rebind (so that they stay bound until we are able to get the next one so you never actually lose the image of the window) and added a callback mechanism to notify renderers just before the pixmap is replaced (so they can do any necessary cleanup such as unbinding textures).

The reason for this is because the nvidia driver seems to require that any textures that are bound to the pixmap are unbound before the pixmap is released. Otherwise it will cause any futher rebind operations to fail silently.

To post a comment you must log in.
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

A small note here - I am writing the tests for this now ... they will come subsequently, some refactoring is required

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Looks good, works well.

I believe the static on line 129 is probably pointless, but don't care.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/composite/include/composite/composite.h'
2--- plugins/composite/include/composite/composite.h 2012-02-08 10:54:35 +0000
3+++ plugins/composite/include/composite/composite.h 2012-05-25 05:56:18 +0000
4@@ -327,6 +327,8 @@
5 {
6 public:
7
8+ typedef boost::function <void ()> NewPixmapReadyCallback;
9+
10 CompositeWindow (CompWindow *w);
11 ~CompositeWindow ();
12
13@@ -424,6 +426,12 @@
14 */
15 unsigned short saturation ();
16
17+ /**
18+ * A function to call when a new pixmap is ready to
19+ * be bound just before the old one is released
20+ */
21+ void setNewPixmapReadyCallback (const NewPixmapReadyCallback &cb);
22+
23 WRAPABLE_HND (0, CompositeWindowInterface, bool, damageRect,
24 bool, const CompRect &);
25
26
27=== modified file 'plugins/composite/src/privates.h'
28--- plugins/composite/src/privates.h 2012-03-27 12:14:56 +0000
29+++ plugins/composite/src/privates.h 2012-05-25 05:56:18 +0000
30@@ -131,6 +131,8 @@
31
32 Pixmap pixmap;
33 CompSize size;
34+ bool needsRebind;
35+ CompositeWindow::NewPixmapReadyCallback newPixmapReadyCallback;
36
37 Damage damage;
38
39
40=== modified file 'plugins/composite/src/window.cpp'
41--- plugins/composite/src/window.cpp 2012-04-19 12:06:05 +0000
42+++ plugins/composite/src/window.cpp 2012-05-25 05:56:18 +0000
43@@ -82,12 +82,20 @@
44 delete priv;
45 }
46
47+void
48+CompositeWindow::setNewPixmapReadyCallback (const NewPixmapReadyCallback &cb)
49+{
50+ priv->newPixmapReadyCallback = cb;
51+}
52+
53 PrivateCompositeWindow::PrivateCompositeWindow (CompWindow *w,
54 CompositeWindow *cw) :
55 window (w),
56 cWindow (cw),
57 cScreen (CompositeScreen::get (screen)),
58 pixmap (None),
59+ needsRebind (true),
60+ newPixmapReadyCallback (),
61 damage (None),
62 damaged (false),
63 redirected (cScreen->compositingActive ()),
64@@ -117,7 +125,7 @@
65 return false;
66
67 redirect ();
68- if (!priv->pixmap)
69+ if (priv->needsRebind)
70 {
71 XWindowAttributes attr;
72
73@@ -141,12 +149,36 @@
74 return false;
75 }
76
77- priv->pixmap = XCompositeNameWindowPixmap
78+ Pixmap newPixmap = XCompositeNameWindowPixmap
79 (screen->dpy (), ROOTPARENT (priv->window));
80- priv->size = CompSize (attr.border_width * 2 + attr.width,
81- attr.border_width * 2 + attr.height);
82+ CompSize newSize = CompSize (attr.border_width * 2 + attr.width,
83+ attr.border_width * 2 + attr.height);
84 XUngrabServer (screen->dpy ());
85 XSync (screen->dpy (), false);
86+
87+ if (newPixmap && newSize.width () && newSize.height ())
88+ {
89+ /* Notify renderer that a new pixmap is about to
90+ * be bound */
91+ if (priv->newPixmapReadyCallback)
92+ priv->newPixmapReadyCallback ();
93+
94+ /* Release old pixmap */
95+ if (priv->pixmap)
96+ XFreePixmap (screen->dpy (), priv->pixmap);
97+
98+ /* Assign new pixmap */
99+ priv->pixmap = newPixmap;
100+ priv->size = newSize;
101+
102+ priv->needsRebind = false;
103+ }
104+ else
105+ {
106+ priv->bindFailed = true;
107+ priv->needsRebind = false;
108+ return false;
109+ }
110 }
111 return true;
112 }
113@@ -154,17 +186,17 @@
114 void
115 CompositeWindow::release ()
116 {
117- if (priv->pixmap)
118- {
119- XFreePixmap (screen->dpy (), priv->pixmap);
120- priv->pixmap = None;
121- priv->size = CompSize ();
122- }
123+ priv->needsRebind = true;
124 }
125
126 Pixmap
127 CompositeWindow::pixmap ()
128 {
129+ static Pixmap nPixmap = None;
130+
131+ if (priv->needsRebind)
132+ return nPixmap;
133+
134 return priv->pixmap;
135 }
136
137@@ -588,8 +620,6 @@
138 else
139 {
140 cWindow->release ();
141- this->pixmap = pixmap;
142- this->size = size;
143 }
144
145 cWindow->addDamage ();
146
147=== modified file 'plugins/opengl/src/privates.h'
148--- plugins/opengl/src/privates.h 2012-04-23 05:36:16 +0000
149+++ plugins/opengl/src/privates.h 2012-05-25 05:56:18 +0000
150@@ -148,6 +148,8 @@
151 void setWindowMatrix ();
152 void updateWindowRegions ();
153
154+ void clearTextures ();
155+
156 CompWindow *window;
157 GLWindow *gWindow;
158 CompositeWindow *cWindow;
159
160=== modified file 'plugins/opengl/src/window.cpp'
161--- plugins/opengl/src/window.cpp 2012-04-18 11:44:01 +0000
162+++ plugins/opengl/src/window.cpp 2012-05-25 05:56:18 +0000
163@@ -68,10 +68,13 @@
164
165 WindowInterface::setHandler (w);
166 CompositeWindowInterface::setHandler (cWindow);
167+
168+ cWindow->setNewPixmapReadyCallback (boost::bind (&PrivateGLWindow::clearTextures, this));
169 }
170
171 PrivateGLWindow::~PrivateGLWindow ()
172 {
173+ cWindow->setNewPixmapReadyCallback (boost::function <void ()> ());
174 }
175
176 void
177@@ -92,10 +95,16 @@
178 updateState &= ~(UpdateMatrix);
179 }
180
181+void
182+PrivateGLWindow::clearTextures ()
183+{
184+ textures.clear ();
185+}
186+
187 bool
188 GLWindow::bind ()
189 {
190- if ((!priv->cWindow->pixmap () && !priv->cWindow->bind ()))
191+ if ((priv->needsRebind && !priv->cWindow->bind ()))
192 {
193 if (!priv->textures.empty ())
194 {
195@@ -115,6 +124,7 @@
196 compLogMessage ("opengl", CompLogLevelInfo,
197 "Couldn't bind redirected window 0x%x to "
198 "texture\n", (int) priv->window->id ());
199+ return false;
200 }
201 else
202 {
203@@ -130,11 +140,6 @@
204 void
205 GLWindow::release ()
206 {
207- /* Release the pixmap but don't release
208- * the texture (yet) */
209- if (priv->cWindow->pixmap ())
210- priv->cWindow->release ();
211-
212 priv->needsRebind = true;
213 }
214

Subscribers

People subscribed via source and target branches