Merge lp:~smspillaz/compiz/compiz.static_vertex_buffers into lp:compiz/0.9.9

Proposed by Sam Spilsbury
Status: Work in progress
Proposed branch: lp:~smspillaz/compiz/compiz.static_vertex_buffers
Merge into: lp:compiz/0.9.9
Diff against target: 1098 lines (+765/-23) (has conflicts)
13 files modified
plugins/decor/src/decor.cpp (+8/-1)
plugins/decor/src/decor.h (+2/-0)
plugins/opengl/CMakeLists.txt (+13/-0)
plugins/opengl/include/opengl/opengl.h (+30/-0)
plugins/opengl/include/opengl/vertexbufferstack.h (+69/-0)
plugins/opengl/src/paint.cpp (+47/-13)
plugins/opengl/src/privates.h (+20/-2)
plugins/opengl/src/vertexbufferstack/CMakeLists.txt (+25/-0)
plugins/opengl/src/vertexbufferstack/include/vertexbufferstack-internal.h (+67/-0)
plugins/opengl/src/vertexbufferstack/src/vertex-buffer-stack.cpp (+145/-0)
plugins/opengl/src/vertexbufferstack/tests/CMakeLists.txt (+24/-0)
plugins/opengl/src/vertexbufferstack/tests/test-opengl-vertex-buffer-stack.cpp (+256/-0)
plugins/opengl/src/window.cpp (+59/-7)
Text conflict in plugins/opengl/CMakeLists.txt
To merge this branch: bzr merge lp:~smspillaz/compiz/compiz.static_vertex_buffers
Reviewer Review Type Date Requested Status
Daniel van Vugt Needs Resubmitting
jenkins continuous-integration Pending
Review via email: mp+126879@code.launchpad.net

This proposal supersedes a proposal from 2012-09-09.

Description of the change

Avoid doing so many vertex buffer object binds. This is more of an RFC than an actual merge proposal as I don't see it going in this cycle.

At the moment, all of the vertex buffer objects for windows are marked GL_STATIC_DRAW. However according to http://developer.apple.com/library/ios/#documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/TechniquesforWorkingwithVertexData/TechniquesforWorkingwithVertexData.html , this is a bad idea because doing glBindBuffer and glBufferData on those buffers can cause GPU to copy vertex data from system memory to the GPU on for that vertex buffer every time the command queue is processed. If that's an expensive operation, then it could result in a fairly large slowdown on some platforms. Because the content of our vertex buffers can change a fair bit, I've changed the default usage hint to GL_DYNAMIC_DRAW, which appears to mean "dma data into the gpu, cache it where necessary"

In compiz, we do region updates by clipping vertex data to a clip region (and, eg, generating new vertex and tex-coord data where it makes sense to do so) and then paint only the primitives specified by those vertices. This is easier on GPUs where fill rate is a concern. However, it means that we can't have static data in our vertex buffer objects, and they effectively need to be re-uploaded every time they change.

There were two factors causing them to be changed all the time, which meant that they had to be re-uploaded all the time
 1) Plugins "share" the vertex buffer object with opengl, and clear the vertex data to add their own. This means that both sets have to be re-uploaded, and the opengl one has to be re-populated every time a plugin uses it "temporarily"
 2) A typical usage trend appears to be just calling ::begin (), adding vertex data and then calling ::end (), even if the vertex data is unchanged.

As for 1) This would best be served by breaking the API and making a GLVertexBuffer * a mandatory part of glAddGeometry and glDrawTexture, so that plugins can provide their own vertex buffers without clobbering the opengl one. Since we can't do that, I've added an API to manipulate which GLVertexBuffer the opengl plugin is using internally. This code is a separate module and covered by unit tests

As for 2) I've added a simple check to determine if we need to re-add vertex data at all, and if we don't, not to call glAddGeometry again, but to re-use the vertex buffer (where it makes sense to do). This code is untested, as it involves setting and checking flags and manipulating lots of internal state. Its also not the preferred solution either as per my comments above, which is why I haven't designed the code to be testable around this case.

The result is that for playing a simple video, in the old usecase, we called:
  * glAddGeometry 497 times
  * GLVertexBuffer::end () (eg, vertex data upload if there is vertex data, which there will be for every frame) 745 times

And for the new code:
 * glAddGeometry 13 times
 * GLVertexBuffer::end () 262 times

I'm not sure what kind of impact this has on framerates. In both cases I maxed out at 60fps.

Where to go with this?
 * The next place that is calling GLVertexBuffer::end () a lot is PrivateGLScreen::paintOutputs when drawing the fbo to the screen. This can be resolved by actually treating that like a static buffer as well (it really should be), or moving to glBlitFramebuffer (preferred
 * We need to make the decor plugin implement the same logic in 2)
 * Make the other plugins provide their own vertex buffers where they need to "attach" textures to windows rather than piggybacking the one internal to opengl.

tl;dr; This might make compiz faster at watching youtube videos. Need feedback as to whether to continue in this direction.

To post a comment you must log in.
Revision history for this message
jenkins (martin-mrazik+qa) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Argh, so many words.

Initial observation: If a class is called "VertexBufferStack" then its method names should not contain the redundant text "VertexBuffer".

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

This doesn't need review right away. Just seeking feedback as to whether or not this is the right direction to go

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Awesome speedup on intel. This is 15-25% faster than trunk there. And it matches the max performance levels I have ever seen on my my desktop.

I honestly never thought I would see the FBO+VBO codepath perform this well... I'd like to make this enhancement a priority.

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Linked to bug 1024304, because I suspect this might be the answer. It certainly is for Intel Sandy Bridge.

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

This is weird. Suddenly trunk is as fast. Maybe I got prematurely excited but it's still interesting.

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

The speedup I thought I got from this was a false alarm. My whole system is suddenly faster with all branches. It wasn't anything to do with this one.

As far as I can tell, this is not required for quantal. So please repropose it after we've branched for 0.9.9.

review: Needs Resubmitting
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

WIP. We can manipulate the internal vb in a much cleaner way.

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

Please target all fixes to lp:compiz first (0.9.10). And then lp:compiz/0.9.9 (the new raring branch) second.

review: Needs Resubmitting
Revision history for this message
MC Return (mc-return) wrote :

Has this been forgotten ?

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

It was more or less of a proof of concept. I'm not interested in
implementing it now.

On 28/05/2013 2:54 AM, "MC Return" <email address hidden> wrote:
>
> Has this been forgotten ?
> --
>
https://code.launchpad.net/~smspillaz/compiz/compiz.static_vertex_buffers/+merge/126879
> You are the owner of lp:~smspillaz/compiz/compiz.static_vertex_buffers.

Unmerged revisions

3363. By Sam Spilsbury

Don't call glAddGeometry if the geometry is
going to be exactly the same. Saves a vertex
buffer bind

3362. By Sam Spilsbury

Only remove the last vertex buffer when using the stack

3361. By Sam Spilsbury

Use GL_DYNAMIC_DRAW for the vertex buffer objects

3360. By Sam Spilsbury

Use a foreign vertex buffer to draw the decorations

3359. By Sam Spilsbury

Implement the interface publicly

3358. By Sam Spilsbury

Implement the internal vertex buffer in terms of the vertex buffer stack

3357. By Sam Spilsbury

Added a simple RAII class to manage that

3356. By Sam Spilsbury

Added a new class, VertexBufferStack.

A VertexBufferStack is a stack of saved GLVertexBufferObjects, which can have
items pushed to the back, removed and popped off the top. activeVertexBuffer
always represents the top most vertex buffer on the stack, popVertexBufferOffTop
will restore the last one.

3355. By Sam Spilsbury

Internally added the concepts of multiple vertex buffers per window

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/decor/src/decor.cpp'
2--- plugins/decor/src/decor.cpp 2012-09-17 15:25:00 +0000
3+++ plugins/decor/src/decor.cpp 2012-09-28 07:48:55 +0000
4@@ -42,6 +42,8 @@
5
6 COMPIZ_PLUGIN_20090315 (decor, DecorPluginVTable)
7
8+namespace cgl = compiz::opengl;
9+
10 MatchedDecorClipGroup::MatchedDecorClipGroup (const CompMatch &match) :
11 mMatch (match)
12 {
13@@ -209,6 +211,9 @@
14 const CompRegion &region,
15 unsigned int mask)
16 {
17+ cgl::VertexBufferPush vertexBufferPush (gWindow->vertexBufferStack (),
18+ mDecorationVertexBuffer);
19+
20 if (wd &&
21 wd->decor->type == WINDOW_DECORATION_TYPE_PIXMAP)
22 {
23@@ -3093,8 +3098,10 @@
24 mClipGroup (NULL),
25 mOutputRegion (window->outputRect ()),
26 mInputRegion (window->inputRect ()),
27- mRequestor (screen->dpy (), w->id (), &decor)
28+ mRequestor (screen->dpy (), w->id (), &decor),
29+ mDecorationVertexBuffer (new GLVertexBuffer (GL_STATIC_DRAW))
30 {
31+ mDecorationVertexBuffer->setAutoProgram (gWindow->autoProgram ());
32 WindowInterface::setHandler (window);
33
34 /* FIXME :DecorWindow::update can call updateWindowOutputExtents
35
36=== modified file 'plugins/decor/src/decor.h'
37--- plugins/decor/src/decor.h 2012-09-07 22:37:20 +0000
38+++ plugins/decor/src/decor.h 2012-09-28 07:48:55 +0000
39@@ -31,6 +31,7 @@
40
41 #include <composite/composite.h>
42 #include <opengl/opengl.h>
43+#include <opengl/vertexbufferstack.h>
44 #include <core/atoms.h>
45 #include <core/windowextents.h>
46
47@@ -362,6 +363,7 @@
48 CompRegion mInputRegion;
49
50 X11DecorPixmapRequestor mRequestor;
51+ compiz::opengl::GLVertexBufferPtr mDecorationVertexBuffer;
52 };
53
54 class DecorPluginVTable :
55
56=== modified file 'plugins/opengl/CMakeLists.txt'
57--- plugins/opengl/CMakeLists.txt 2012-09-22 04:00:52 +0000
58+++ plugins/opengl/CMakeLists.txt 2012-09-28 07:48:55 +0000
59@@ -5,14 +5,27 @@
60 set (INTERNAL_LIBRARIES
61 compiz_opengl_double_buffer
62 compiz_opengl_fsregion
63+<<<<<<< TREE
64 compiz_opengl_glx_tfp_bind
65+=======
66+ compiz_opengl_vertex_buffer_stack
67+>>>>>>> MERGE-SOURCE
68 )
69
70+set (COMPIZ_OPENGL_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
71+set (COMPIZ_OPENGL_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
72+
73 add_subdirectory (src/doublebuffer)
74 add_subdirectory (src/fsregion)
75+<<<<<<< TREE
76 add_subdirectory (src/glxtfpbind)
77
78 include_directories (src/glxtfpbind/include)
79+=======
80+add_subdirectory (src/vertexbufferstack)
81+
82+include_directories (src/vertexbufferstack/include)
83+>>>>>>> MERGE-SOURCE
84
85 if (USE_GLES)
86 compiz_plugin(opengl PLUGINDEPS composite CFLAGSADD "-DUSE_GLES -std=c++0x" LIBRARIES ${OPENGLES2_LIBRARIES} ${INTERNAL_LIBRARIES} dl INCDIRS ${OPENGLES2_INCLUDE_DIR})
87
88=== modified file 'plugins/opengl/include/opengl/opengl.h'
89--- plugins/opengl/include/opengl/opengl.h 2012-09-17 14:36:00 +0000
90+++ plugins/opengl/include/opengl/opengl.h 2012-09-28 07:48:55 +0000
91@@ -39,6 +39,9 @@
92 #include <GL/glx.h>
93 #endif
94
95+#include <boost/shared_ptr.hpp>
96+#include <boost/weak_ptr.hpp>
97+
98 #include <core/size.h>
99 #include <core/pluginclasshandler.h>
100
101@@ -871,6 +874,16 @@
102 const GLWindowPaintAttrib &, unsigned int);
103 };
104
105+namespace compiz
106+{
107+ namespace opengl
108+ {
109+ typedef boost::shared_ptr <GLVertexBuffer> GLVertexBufferPtr;
110+ typedef boost::weak_ptr <GLVertexBuffer> GLVertexBufferWeak;
111+ class VertexBufferStack;
112+ }
113+}
114+
115 class GLWindow :
116 public WrapableHandler<GLWindowInterface, 4>,
117 public PluginClassHandler<GLWindow, CompWindow, COMPIZ_OPENGL_ABI>
118@@ -926,6 +939,23 @@
119 GLVertexBuffer * vertexBuffer ();
120
121 /**
122+ * Returns the current vertex buffer stack
123+ */
124+ compiz::opengl::VertexBufferStack &
125+ vertexBufferStack ();
126+
127+ /**
128+ * Returns the AutoProgram used for this window's
129+ * GLVertexBuffer objects. The returned object
130+ * is internal to GLWindow and should not be
131+ * deleted
132+ *
133+ * TODO ABI: Return weak pointer
134+ */
135+ compiz::gl::AutoProgram *
136+ autoProgram ();
137+
138+ /**
139 * Add a vertex and/or fragment shader function to the pipeline.
140 *
141 * @param name Name of the plugin adding the functions
142
143=== added file 'plugins/opengl/include/opengl/vertexbufferstack.h'
144--- plugins/opengl/include/opengl/vertexbufferstack.h 1970-01-01 00:00:00 +0000
145+++ plugins/opengl/include/opengl/vertexbufferstack.h 2012-09-28 07:48:55 +0000
146@@ -0,0 +1,69 @@
147+/*
148+ * Compiz opengl plugin, VertexBufferStack interface
149+ *
150+ * Copyright (c) 2012 Canonical Ltd.
151+ * Author: Sam Spilsbury <sam.spilsbury@canonical.com>
152+ *
153+ * Permission is hereby granted, free of charge, to any person obtaining a
154+ * copy of this software and associated documentation files (the "Software"),
155+ * to deal in the Software without restriction, including without limitation
156+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
157+ * and/or sell copies of the Software, and to permit persons to whom the
158+ * Software is furnished to do so, subject to the following conditions:
159+ *
160+ * The above copyright notice and this permission notice shall be included in
161+ * all copies or substantial portions of the Software.
162+ *
163+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
164+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
165+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
166+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
167+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
168+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
169+ * DEALINGS IN THE SOFTWARE.
170+ */
171+#ifndef __COMPIZ_OPENGL_VERTEXBUFFERSTACK_H
172+#define __COMPIZ_OPENGL_VERTEXBUFFERSTACK_H
173+
174+#include <boost/shared_ptr.hpp>
175+#include <boost/weak_ptr.hpp>
176+
177+class GLVertexBuffer;
178+
179+namespace compiz
180+{
181+ namespace opengl
182+ {
183+ typedef boost::shared_ptr <GLVertexBuffer> GLVertexBufferPtr;
184+ typedef boost::weak_ptr <GLVertexBuffer> GLVertexBufferWeak;
185+
186+ class VertexBufferStack
187+ {
188+ public:
189+
190+ virtual ~VertexBufferStack () {}
191+
192+ virtual void pushVertexBuffer (const GLVertexBufferPtr &) = 0;
193+ virtual bool removeVertexBuffer (const GLVertexBufferPtr &) = 0;
194+ virtual bool removeLastVertexBuffer (const GLVertexBufferPtr &) = 0;
195+ virtual void popVertexBufferFromTop () = 0;
196+ virtual const GLVertexBufferWeak & activeVertexBuffer () const = 0;
197+ };
198+
199+ class VertexBufferPush
200+ {
201+ public:
202+
203+ VertexBufferPush (VertexBufferStack &vbStack,
204+ const GLVertexBufferPtr &vertexBuffer);
205+ ~VertexBufferPush ();
206+
207+ private:
208+
209+ VertexBufferStack &mVBStack;
210+ const GLVertexBufferPtr &mVertexBuffer;
211+ };
212+ }
213+}
214+
215+#endif
216
217=== modified file 'plugins/opengl/src/paint.cpp'
218--- plugins/opengl/src/paint.cpp 2012-09-21 06:05:27 +0000
219+++ plugins/opengl/src/paint.cpp 2012-09-28 07:48:55 +0000
220@@ -37,13 +37,14 @@
221 #define foreach BOOST_FOREACH
222
223 #include <opengl/opengl.h>
224+#include <opengl/vertexbufferstack.h>
225
226 #include "privates.h"
227 #include "fsregion/fsregion.h"
228
229 #define DEG2RAD (M_PI / 180.0f)
230
231-using namespace compiz::opengl;
232+namespace cgl = compiz::opengl;
233
234 GLScreenPaintAttrib defaultScreenPaintAttrib = {
235 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -DEFAULT_Z_CAMERA
236@@ -276,7 +277,7 @@
237
238 if (!(mask & PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK))
239 {
240- FullscreenRegion fs (*output);
241+ cgl::FullscreenRegion fs (*output);
242
243 /* detect occlusions */
244 for (rit = pl.rbegin (); rit != pl.rend (); ++rit)
245@@ -340,11 +341,11 @@
246 tmpRegion -= w->region ();
247 }
248
249- FullscreenRegion::WinFlags flags = 0;
250+ cgl::FullscreenRegion::WinFlags flags = 0;
251 if (w->type () & CompWindowTypeDesktopMask)
252- flags |= FullscreenRegion::Desktop;
253+ flags |= cgl::FullscreenRegion::Desktop;
254 if (w->alpha ())
255- flags |= FullscreenRegion::Alpha;
256+ flags |= cgl::FullscreenRegion::Alpha;
257
258 /*
259 * Windows with alpha channels can partially occlude windows
260@@ -917,9 +918,16 @@
261 {
262 WRAPABLE_HND_FUNCTN (glAddGeometry, matrix, region, clip)
263
264+ boost::shared_ptr <GLVertexBuffer> activeVertexBuffer = priv->vertexBufferStack.activeVertexBuffer ().lock ();
265+
266 BoxRec full;
267 int nMatrix = matrix.size ();
268
269+ /* Someone is modifying our internal vertex buffer */
270+ if (!priv->inGLDraw &&
271+ activeVertexBuffer == priv->windowVertexBuffer)
272+ priv->vertexBufferDirty = true;
273+
274 full = clip.handle ()->extents;
275 if (region.handle ()->extents.x1 > full.x1)
276 full.x1 = region.handle ()->extents.x1;
277@@ -976,7 +984,7 @@
278
279 if (nClip == 1)
280 {
281- addQuads (priv->vertexBuffer, matrix, nMatrix,
282+ addQuads (activeVertexBuffer.get (), matrix, nMatrix,
283 x1, y1, x2, y2,
284 rect,
285 maxGridWidth, maxGridHeight);
286@@ -1002,7 +1010,7 @@
287
288 if (cbox.x1 < cbox.x2 && cbox.y1 < cbox.y2)
289 {
290- addQuads (priv->vertexBuffer, matrix, nMatrix,
291+ addQuads (activeVertexBuffer.get (), matrix, nMatrix,
292 cbox.x1, cbox.y1, cbox.x2, cbox.y2,
293 rect,
294 maxGridWidth, maxGridHeight);
295@@ -1244,14 +1252,14 @@
296 texture->enable (filter);
297
298 #ifdef USE_GLES
299- priv->vertexBuffer->render (transform, attrib);
300+ priv->vertexBufferStack.activeVertexBuffer ().lock ()->render (transform, attrib);
301 #else
302
303 if (!GLVertexBuffer::enabled ())
304 enableLegacyOBSAndRender (priv->gScreen, this, texture, transform,
305 attrib, filter, mask);
306 else
307- priv->vertexBuffer->render (transform, attrib);
308+ priv->vertexBufferStack.activeVertexBuffer ().lock ()->render (transform, attrib);
309 #endif
310
311 priv->shaders.clear ();
312@@ -1270,9 +1278,22 @@
313 WRAPABLE_HND_FUNCTN_RETURN (bool, glDraw, transform,
314 attrib, region, mask)
315
316+ const bool transformedWindow = mask & (PAINT_WINDOW_WITH_OFFSET_MASK |
317+ PAINT_WINDOW_TRANSFORMED_MASK);
318+ const bool damageRegionChanged = priv->lastDamageRegion != region;
319+ const bool internalMatricesChanged = priv->updateState & (PrivateGLWindow::UpdateMatrix |
320+ PrivateGLWindow::UpdateRegion);
321+ const bool readdGeometry = priv->vertexBufferDirty ||
322+ transformedWindow ||
323+ internalMatricesChanged ||
324+ damageRegionChanged;
325+
326 const CompRegion &reg = (mask & PAINT_WINDOW_TRANSFORMED_MASK) ?
327 infiniteRegion : region;
328
329+ if (readdGeometry)
330+ priv->lastDamageRegion = region;
331+
332 if (reg.isEmpty ())
333 return true;
334
335@@ -1304,10 +1325,23 @@
336
337 for (unsigned int i = 0; i < priv->textures.size (); i++)
338 {
339- ml[0] = priv->matrices[i];
340- priv->vertexBuffer->begin ();
341- glAddGeometry (ml, priv->regions[i], reg);
342- if (priv->vertexBuffer->end ())
343+ cgl::VertexBufferStack &vbStack (priv->vertexBufferStack);
344+ cgl::VertexBufferPush push (vbStack,
345+ priv->windowVertexBuffer);
346+ cgl::GLVertexBufferPtr activeVertexBuffer = vbStack.activeVertexBuffer ().lock ();
347+
348+ if (readdGeometry || true)
349+ {
350+ priv->inGLDraw = true;
351+ ml[0] = priv->matrices[i];
352+ activeVertexBuffer->begin ();
353+ glAddGeometry (ml, priv->regions[i], reg);
354+ activeVertexBuffer->end ();
355+ priv->inGLDraw = false;
356+ priv->vertexBufferDirty = false;
357+ }
358+
359+ if (activeVertexBuffer->countVertices ())
360 glDrawTexture (priv->textures[i], transform, attrib, mask);
361 }
362
363
364=== modified file 'plugins/opengl/src/privates.h'
365--- plugins/opengl/src/privates.h 2012-09-25 10:47:39 +0000
366+++ plugins/opengl/src/privates.h 2012-09-28 07:48:55 +0000
367@@ -28,6 +28,9 @@
368 #ifndef _OPENGL_PRIVATES_H
369 #define _OPENGL_PRIVATES_H
370
371+#include <boost/shared_ptr.hpp>
372+#include <boost/weak_ptr.hpp>
373+
374 #include <composite/composite.h>
375 #include <opengl/opengl.h>
376 #include <core/atoms.h>
377@@ -40,6 +43,7 @@
378
379 #include "privatetexture.h"
380 #include "privatevertexbuffer.h"
381+#include "vertexbufferstack-internal.h"
382 #include "opengl_options.h"
383
384 extern CompOutput *targetOutput;
385@@ -218,7 +222,8 @@
386
387 class PrivateGLWindow :
388 public WindowInterface,
389- public CompositeWindowInterface
390+ public CompositeWindowInterface,
391+ public compiz::opengl::VertexBufferStack
392 {
393 public:
394
395@@ -251,6 +256,9 @@
396 bool needsRebind;
397
398 CompRegion clip;
399+ CompRegion lastDamageRegion;
400+ bool vertexBufferDirty;
401+ bool inGLDraw;
402
403 bool bindFailed;
404 bool overlayWindow;
405@@ -264,7 +272,8 @@
406
407 unsigned int lastMask;
408
409- GLVertexBuffer *vertexBuffer;
410+ compiz::opengl::impl::VertexBufferStack vertexBufferStack;
411+ compiz::opengl::GLVertexBufferPtr windowVertexBuffer;
412
413 // map of shaders, plugin name is key, pair of vertex and fragment
414 // shader source code is value
415@@ -272,6 +281,15 @@
416 GLVertexBuffer::AutoProgram *autoProgram;
417
418 std::list<GLIcon> icons;
419+
420+ private:
421+
422+ /* Implementation of compiz::opengl::VertexBufferStack */
423+ void pushVertexBuffer (const compiz::opengl::GLVertexBufferPtr &);
424+ void popVertexBufferFromTop ();
425+ bool removeVertexBuffer (const compiz::opengl::GLVertexBufferPtr &);
426+ bool removeLastVertexBuffer (const compiz::opengl::GLVertexBufferPtr &);
427+ const compiz::opengl::GLVertexBufferWeak & activeVertexBuffer () const;
428 };
429
430 #endif
431
432=== added directory 'plugins/opengl/src/vertexbufferstack'
433=== added file 'plugins/opengl/src/vertexbufferstack/CMakeLists.txt'
434--- plugins/opengl/src/vertexbufferstack/CMakeLists.txt 1970-01-01 00:00:00 +0000
435+++ plugins/opengl/src/vertexbufferstack/CMakeLists.txt 2012-09-28 07:48:55 +0000
436@@ -0,0 +1,25 @@
437+INCLUDE_DIRECTORIES (
438+ ${COMPIZ_OPENGL_SOURCE_DIR}
439+ ${COMPIZ_OPENGL_INCLUDE_DIR}
440+ ${CMAKE_CURRENT_SOURCE_DIR}/include
441+ ${CMAKE_CURRENT_SOURCE_DIR}/src
442+
443+ ${Boost_INCLUDE_DIRS}
444+)
445+
446+LINK_DIRECTORIES (${COMPIZ_LIBRARY_DIRS})
447+
448+SET(
449+ SRCS
450+ ${CMAKE_CURRENT_SOURCE_DIR}/src/vertex-buffer-stack.cpp
451+)
452+
453+ADD_LIBRARY(
454+ compiz_opengl_vertex_buffer_stack STATIC
455+
456+ ${SRCS}
457+)
458+
459+if (COMPIZ_BUILD_TESTING)
460+ADD_SUBDIRECTORY( ${CMAKE_CURRENT_SOURCE_DIR}/tests )
461+endif (COMPIZ_BUILD_TESTING)
462
463=== added directory 'plugins/opengl/src/vertexbufferstack/include'
464=== added file 'plugins/opengl/src/vertexbufferstack/include/vertexbufferstack-internal.h'
465--- plugins/opengl/src/vertexbufferstack/include/vertexbufferstack-internal.h 1970-01-01 00:00:00 +0000
466+++ plugins/opengl/src/vertexbufferstack/include/vertexbufferstack-internal.h 2012-09-28 07:48:55 +0000
467@@ -0,0 +1,67 @@
468+/*
469+ * Compiz opengl plugin, VertexBufferStack interface
470+ *
471+ * Copyright (c) 2012 Canonical Ltd.
472+ * Author: Sam Spilsbury <sam.spilsbury@canonical.com>
473+ *
474+ * Permission is hereby granted, free of charge, to any person obtaining a
475+ * copy of this software and associated documentation files (the "Software"),
476+ * to deal in the Software without restriction, including without limitation
477+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
478+ * and/or sell copies of the Software, and to permit persons to whom the
479+ * Software is furnished to do so, subject to the following conditions:
480+ *
481+ * The above copyright notice and this permission notice shall be included in
482+ * all copies or substantial portions of the Software.
483+ *
484+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
485+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
486+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
487+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
488+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
489+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
490+ * DEALINGS IN THE SOFTWARE.
491+ */
492+#ifndef __COMPIZ_OPENGL_VERTEXBUFFERSTACKINTERNAL_H
493+#define __COMPIZ_OPENGL_VERTEXBUFFERSTACKINTERNAL_H
494+
495+#include <opengl/vertexbufferstack.h>
496+
497+namespace compiz
498+{
499+ namespace opengl
500+ {
501+ namespace impl
502+ {
503+ namespace cgl = compiz::opengl;
504+
505+ class PrivateVertexBufferStack;
506+
507+ class VertexBufferStack :
508+ public cgl::VertexBufferStack
509+ {
510+ public:
511+
512+ VertexBufferStack ();
513+ ~VertexBufferStack ();
514+
515+ void pushVertexBuffer (const GLVertexBufferPtr &);
516+ bool removeLastVertexBuffer (const GLVertexBufferPtr &);
517+ bool removeVertexBuffer (const GLVertexBufferPtr &);
518+ void popVertexBufferFromTop ();
519+ const GLVertexBufferWeak & activeVertexBuffer () const;
520+
521+ private:
522+
523+ PrivateVertexBufferStack *priv;
524+ };
525+ }
526+ }
527+}
528+
529+bool operator== (const compiz::opengl::GLVertexBufferWeak &lhs,
530+ const compiz::opengl::GLVertexBufferWeak &rhs);
531+bool operator!= (const compiz::opengl::GLVertexBufferWeak &lhs,
532+ const compiz::opengl::GLVertexBufferWeak &rhs);
533+
534+#endif
535
536=== added directory 'plugins/opengl/src/vertexbufferstack/src'
537=== added file 'plugins/opengl/src/vertexbufferstack/src/vertex-buffer-stack.cpp'
538--- plugins/opengl/src/vertexbufferstack/src/vertex-buffer-stack.cpp 1970-01-01 00:00:00 +0000
539+++ plugins/opengl/src/vertexbufferstack/src/vertex-buffer-stack.cpp 2012-09-28 07:48:55 +0000
540@@ -0,0 +1,145 @@
541+/*
542+ * Compiz, opengl plugin, VertexBufferStack class
543+ *
544+ * Copyright (c) 2012 Canonical Ltd.
545+ * Authors: Sam Spilsbury <sam.spilsbury@canonical.com>
546+ *
547+ * Permission is hereby granted, free of charge, to any person obtaining a
548+ * copy of this software and associated documentation files (the "Software"),
549+ * to deal in the Software without restriction, including without limitation
550+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
551+ * and/or sell copies of the Software, and to permit persons to whom the
552+ * Software is furnished to do so, subject to the following conditions:
553+ *
554+ * The above copyright notice and this permission notice shall be included in
555+ * all copies or substantial portions of the Software.
556+ *
557+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
558+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
559+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
560+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
561+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
562+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
563+ * DEALINGS IN THE SOFTWARE.
564+ */
565+#include <algorithm>
566+#include <vector>
567+#include "vertexbufferstack-internal.h"
568+
569+namespace cgl = compiz::opengl;
570+namespace cgli = compiz::opengl::impl;
571+
572+class GLVertexBuffer;
573+
574+namespace compiz
575+{
576+ namespace opengl
577+ {
578+ namespace impl
579+ {
580+ class PrivateVertexBufferStack
581+ {
582+ public:
583+
584+ std::vector <cgl::GLVertexBufferWeak> savedVertexBuffers;
585+ cgl::GLVertexBufferWeak activeVertexBuffer;
586+ };
587+ }
588+ }
589+}
590+
591+bool operator== (const compiz::opengl::GLVertexBufferWeak &lhs,
592+ const compiz::opengl::GLVertexBufferWeak &rhs)
593+{
594+ return lhs.lock () == rhs.lock ();
595+}
596+
597+bool operator!= (const compiz::opengl::GLVertexBufferWeak &lhs,
598+ const compiz::opengl::GLVertexBufferWeak &rhs)
599+{
600+ return !(lhs == rhs);
601+}
602+
603+cgli::VertexBufferStack::VertexBufferStack () :
604+ priv (new PrivateVertexBufferStack)
605+{
606+}
607+
608+cgli::VertexBufferStack::~VertexBufferStack ()
609+{
610+ delete priv;
611+}
612+
613+void
614+cgli::VertexBufferStack::pushVertexBuffer (const cgl::GLVertexBufferPtr &vb)
615+{
616+ priv->savedVertexBuffers.push_back (priv->activeVertexBuffer);
617+ priv->activeVertexBuffer = vb;
618+}
619+
620+void
621+cgli::VertexBufferStack::popVertexBufferFromTop ()
622+{
623+ if (!priv->savedVertexBuffers.empty ())
624+ priv->activeVertexBuffer = priv->savedVertexBuffers.back ();
625+ else
626+ priv->activeVertexBuffer.reset ();
627+
628+ priv->savedVertexBuffers.pop_back ();
629+}
630+
631+bool
632+cgli::VertexBufferStack::removeLastVertexBuffer (const GLVertexBufferPtr &vb)
633+{
634+ cgl::GLVertexBufferWeak weak (vb);
635+ std::vector <cgl::GLVertexBufferWeak>::reverse_iterator rit = priv->savedVertexBuffers.rbegin ();
636+
637+ if (weak == priv->activeVertexBuffer)
638+ {
639+ popVertexBufferFromTop ();
640+ return true;
641+ }
642+
643+ while (rit != priv->savedVertexBuffers.rend ())
644+ {
645+ if (*rit == weak)
646+ {
647+ priv->savedVertexBuffers.erase (rit.base () - 1);
648+ return true;
649+ }
650+
651+ ++rit;
652+ };
653+
654+ return false;
655+}
656+
657+bool
658+cgli::VertexBufferStack::removeVertexBuffer (const cgl::GLVertexBufferPtr &vb)
659+{
660+ bool found = false;
661+
662+ while (removeLastVertexBuffer (vb))
663+ found = true;
664+
665+ return found;
666+}
667+
668+const cgl::GLVertexBufferWeak &
669+cgli::VertexBufferStack::activeVertexBuffer () const
670+{
671+ return priv->activeVertexBuffer;
672+}
673+
674+cgl::VertexBufferPush::VertexBufferPush (cgl::VertexBufferStack &vbStack,
675+ const cgl::GLVertexBufferPtr &vertexBuffer) :
676+ mVBStack (vbStack),
677+ mVertexBuffer (vertexBuffer)
678+{
679+ vbStack.pushVertexBuffer (vertexBuffer);
680+}
681+
682+cgl::VertexBufferPush::~VertexBufferPush ()
683+{
684+ mVBStack.removeLastVertexBuffer (mVertexBuffer);
685+}
686
687=== added directory 'plugins/opengl/src/vertexbufferstack/tests'
688=== added file 'plugins/opengl/src/vertexbufferstack/tests/CMakeLists.txt'
689--- plugins/opengl/src/vertexbufferstack/tests/CMakeLists.txt 1970-01-01 00:00:00 +0000
690+++ plugins/opengl/src/vertexbufferstack/tests/CMakeLists.txt 2012-09-28 07:48:55 +0000
691@@ -0,0 +1,24 @@
692+find_library (GMOCK_LIBRARY gmock)
693+find_library (GMOCK_MAIN_LIBRARY gmock_main)
694+
695+if (NOT GMOCK_LIBRARY OR NOT GMOCK_MAIN_LIBRARY OR NOT GTEST_FOUND)
696+ message ("Google Mock and Google Test not found - cannot build tests!")
697+ set (COMPIZ_BUILD_TESTING OFF)
698+endif (NOT GMOCK_LIBRARY OR NOT GMOCK_MAIN_LIBRARY OR NOT GTEST_FOUND)
699+
700+include_directories (${GTEST_INCLUDE_DIRS})
701+
702+link_directories (${COMPIZ_LIBRARY_DIRS})
703+
704+add_executable (compiz_test_opengl_vertex_buffer_stack
705+ ${CMAKE_CURRENT_SOURCE_DIR}/test-opengl-vertex-buffer-stack.cpp)
706+
707+target_link_libraries (compiz_test_opengl_vertex_buffer_stack
708+ compiz_opengl_vertex_buffer_stack
709+ ${GTEST_BOTH_LIBRARIES}
710+ ${GMOCK_LIBRARY}
711+ ${GMOCK_MAIN_LIBRARY}
712+ ${CMAKE_THREAD_LIBS_INIT} # Link in pthread.
713+ )
714+
715+compiz_discover_tests (compiz_test_opengl_vertex_buffer_stack COVERAGE compiz_opengl_vertex_buffer_stack)
716
717=== added file 'plugins/opengl/src/vertexbufferstack/tests/test-opengl-vertex-buffer-stack.cpp'
718--- plugins/opengl/src/vertexbufferstack/tests/test-opengl-vertex-buffer-stack.cpp 1970-01-01 00:00:00 +0000
719+++ plugins/opengl/src/vertexbufferstack/tests/test-opengl-vertex-buffer-stack.cpp 2012-09-28 07:48:55 +0000
720@@ -0,0 +1,256 @@
721+/*
722+ * Compiz, opengl plugin, VertexBufferStack class
723+ *
724+ * Copyright (c) 2012 Canonical Ltd.
725+ * Authors: Sam Spilsbury <sam.spilsbury@canonical.com>
726+ *
727+ * Permission is hereby granted, free of charge, to any person obtaining a
728+ * copy of this software and associated documentation files (the "Software"),
729+ * to deal in the Software without restriction, including without limitation
730+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
731+ * and/or sell copies of the Software, and to permit persons to whom the
732+ * Software is furnished to do so, subject to the following conditions:
733+ *
734+ * The above copyright notice and this permission notice shall be included in
735+ * all copies or substantial portions of the Software.
736+ *
737+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
738+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
739+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
740+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
741+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
742+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
743+ * DEALINGS IN THE SOFTWARE.
744+ */
745+#include <boost/make_shared.hpp>
746+#include <gtest/gtest.h>
747+#include <gmock/gmock.h>
748+#include "vertexbufferstack-internal.h"
749+
750+using ::testing::MatcherInterface;
751+using ::testing::MakeMatcher;
752+using ::testing::MatchResultListener;
753+using ::testing::Matcher;
754+
755+template <class P>
756+class ExpiredPtrMatcher :
757+ public ::testing::MatcherInterface <const boost::weak_ptr <P> &>
758+{
759+ public:
760+
761+ bool MatchAndExplain (const boost::weak_ptr <P> &x, MatchResultListener *listener) const
762+ {
763+ return x.expired ();
764+ }
765+
766+ void DescribeTo (std::ostream *os) const
767+ {
768+ *os << "is expired";
769+ }
770+
771+ void DescribeNegationTo (std::ostream *os) const
772+ {
773+ *os << "is not expired";
774+ }
775+};
776+
777+template <class P>
778+inline Matcher<const boost::weak_ptr <P> &> IsExpired ()
779+{
780+ return MakeMatcher (new ExpiredPtrMatcher<P> ());
781+}
782+
783+namespace cgl = compiz::opengl;
784+namespace cgli = compiz::opengl::impl;
785+
786+class OpenGLVertexBufferStackTest :
787+ public ::testing::Test
788+{
789+ public:
790+
791+ cgli::VertexBufferStack vbStack;
792+};
793+
794+/* Provide a dummy definition of GLVertexBuffer for our purposes,
795+ * as we are only managing the pointer */
796+class GLVertexBuffer
797+{
798+};
799+
800+TEST_F (OpenGLVertexBufferStackTest, TestPushIsActive)
801+{
802+ cgl::GLVertexBufferPtr vb (boost::make_shared <GLVertexBuffer> ());
803+ cgl::GLVertexBufferWeak weak (vb);
804+
805+ vbStack.pushVertexBuffer (vb);
806+ EXPECT_EQ (weak, vbStack.activeVertexBuffer ());
807+}
808+
809+TEST_F (OpenGLVertexBufferStackTest, TestPushTwoPopFirstActive)
810+{
811+ cgl::GLVertexBufferPtr vbFirst (boost::make_shared <GLVertexBuffer> ());
812+ cgl::GLVertexBufferPtr vbSecond (boost::make_shared <GLVertexBuffer> ());
813+
814+ cgl::GLVertexBufferWeak weakFirst (vbFirst);
815+ cgl::GLVertexBufferWeak weakSecond (vbSecond);
816+
817+ vbStack.pushVertexBuffer (vbFirst);
818+ vbStack.pushVertexBuffer (vbSecond);
819+
820+ EXPECT_EQ (weakSecond, vbStack.activeVertexBuffer ());
821+
822+ vbStack.popVertexBufferFromTop ();
823+
824+ EXPECT_EQ (weakFirst, vbStack.activeVertexBuffer ());
825+}
826+
827+TEST_F (OpenGLVertexBufferStackTest, TestPushThreeRemoveSecondThirdIsActive)
828+{
829+ cgl::GLVertexBufferPtr vbFirst (boost::make_shared <GLVertexBuffer> ());
830+ cgl::GLVertexBufferPtr vbSecond (boost::make_shared <GLVertexBuffer> ());
831+ cgl::GLVertexBufferPtr vbThird (boost::make_shared <GLVertexBuffer> ());
832+
833+ cgl::GLVertexBufferWeak weakFirst (vbFirst);
834+ cgl::GLVertexBufferWeak weakSecond (vbSecond);
835+ cgl::GLVertexBufferWeak weakThird (vbThird);
836+
837+ vbStack.pushVertexBuffer (vbFirst);
838+ vbStack.pushVertexBuffer (vbSecond);
839+ vbStack.pushVertexBuffer (vbThird);
840+
841+ EXPECT_EQ (weakThird, vbStack.activeVertexBuffer ());
842+
843+ vbStack.removeVertexBuffer (vbSecond);
844+
845+ EXPECT_EQ (weakThird, vbStack.activeVertexBuffer ());
846+
847+ vbStack.popVertexBufferFromTop ();
848+
849+ EXPECT_EQ (weakFirst, vbStack.activeVertexBuffer ());
850+}
851+
852+TEST_F (OpenGLVertexBufferStackTest, TestOneAndTwoOfTheSameRemovesLast)
853+{
854+ cgl::GLVertexBufferPtr vbFirst (boost::make_shared <GLVertexBuffer> ());
855+ cgl::GLVertexBufferPtr vbSecond (boost::make_shared <GLVertexBuffer> ());
856+ cgl::GLVertexBufferPtr vbThird (vbSecond);
857+ cgl::GLVertexBufferPtr vbFourth (boost::make_shared <GLVertexBuffer> ());
858+
859+ cgl::GLVertexBufferWeak weakFirst (vbFirst);
860+ cgl::GLVertexBufferWeak weakSecond (vbSecond);
861+ cgl::GLVertexBufferWeak weakThird (vbThird);
862+ cgl::GLVertexBufferWeak weakFourth (vbFourth);
863+
864+ vbStack.pushVertexBuffer (vbFirst);
865+ vbStack.pushVertexBuffer (vbSecond);
866+ vbStack.pushVertexBuffer (vbThird);
867+ vbStack.pushVertexBuffer (vbFourth);
868+
869+ EXPECT_EQ (weakFourth, vbStack.activeVertexBuffer ());
870+
871+ vbStack.removeLastVertexBuffer (vbThird);
872+
873+ EXPECT_EQ (weakFourth, vbStack.activeVertexBuffer ());
874+
875+ vbStack.popVertexBufferFromTop ();
876+
877+ EXPECT_EQ (weakSecond, vbStack.activeVertexBuffer ());
878+
879+ vbStack.popVertexBufferFromTop ();
880+
881+ EXPECT_EQ (weakFirst, vbStack.activeVertexBuffer ());
882+}
883+
884+TEST_F (OpenGLVertexBufferStackTest, TestPushTwoRemoveLastFirstIsActive)
885+{
886+ cgl::GLVertexBufferPtr vbFirst (boost::make_shared <GLVertexBuffer> ());
887+ cgl::GLVertexBufferPtr vbSecond (boost::make_shared <GLVertexBuffer> ());
888+
889+ cgl::GLVertexBufferWeak weakFirst (vbFirst);
890+ cgl::GLVertexBufferWeak weakSecond (vbSecond);
891+
892+ vbStack.pushVertexBuffer (vbFirst);
893+ vbStack.pushVertexBuffer (vbSecond);
894+
895+ EXPECT_EQ (weakSecond, vbStack.activeVertexBuffer ());
896+
897+ vbStack.removeVertexBuffer (vbSecond);
898+
899+ EXPECT_EQ (weakFirst, vbStack.activeVertexBuffer ());
900+
901+ vbStack.popVertexBufferFromTop ();
902+
903+ EXPECT_THAT (vbStack.activeVertexBuffer (), IsExpired <GLVertexBuffer> ());
904+}
905+
906+TEST_F (OpenGLVertexBufferStackTest, TestPushAndRemoveNoneActive)
907+{
908+ cgl::GLVertexBufferPtr vb (boost::make_shared <GLVertexBuffer> ());
909+ cgl::GLVertexBufferWeak weak (vb);
910+
911+ vbStack.pushVertexBuffer (vb);
912+ EXPECT_EQ (weak, vbStack.activeVertexBuffer ());
913+ vbStack.removeVertexBuffer (vb);
914+ EXPECT_THAT (vbStack.activeVertexBuffer (), IsExpired <GLVertexBuffer> ());
915+}
916+
917+TEST_F (OpenGLVertexBufferStackTest, TestPushAndRemoveBothTheSameNoneActive)
918+{
919+ cgl::GLVertexBufferPtr vb (boost::make_shared <GLVertexBuffer> ());
920+ cgl::GLVertexBufferPtr vbIdentical (vb);
921+ cgl::GLVertexBufferWeak weak (vb);
922+ cgl::GLVertexBufferWeak weakIdentical (weak);
923+
924+ vbStack.pushVertexBuffer (vb);
925+ vbStack.pushVertexBuffer (vbIdentical);
926+ EXPECT_EQ (weak, vbStack.activeVertexBuffer ());
927+ vbStack.removeVertexBuffer (vb);
928+ EXPECT_THAT (vbStack.activeVertexBuffer (), IsExpired <GLVertexBuffer> ());
929+}
930+
931+TEST_F (OpenGLVertexBufferStackTest, TestPushAndRemoveNonPushedDoesNothing)
932+{
933+ cgl::GLVertexBufferPtr vb (boost::make_shared <GLVertexBuffer> ());
934+ cgl::GLVertexBufferWeak weak (vb);
935+ cgl::GLVertexBufferPtr nonExistant;
936+
937+ vbStack.pushVertexBuffer (vb);
938+ EXPECT_EQ (weak, vbStack.activeVertexBuffer ());
939+ vbStack.removeVertexBuffer (nonExistant);
940+ EXPECT_EQ (weak, vbStack.activeVertexBuffer ());
941+}
942+
943+TEST_F (OpenGLVertexBufferStackTest, TestVertexBufferPushObject)
944+{
945+ cgl::GLVertexBufferPtr vb (boost::make_shared <GLVertexBuffer> ());
946+ cgl::GLVertexBufferWeak weak (vb);
947+
948+ {
949+ cgl::VertexBufferPush pushedVertexBuffer (vbStack, vb);
950+
951+ EXPECT_EQ (vbStack.activeVertexBuffer (), weak);
952+ }
953+
954+ EXPECT_THAT (vbStack.activeVertexBuffer (), IsExpired <GLVertexBuffer> ());
955+}
956+
957+TEST_F (OpenGLVertexBufferStackTest, TestVertexBufferPushTwoIdenticalObjectOnlyRemovesOneEach)
958+{
959+ cgl::GLVertexBufferPtr vb (boost::make_shared <GLVertexBuffer> ());
960+ cgl::GLVertexBufferPtr vbIdentical (vb);
961+ cgl::GLVertexBufferWeak weak (vb);
962+
963+ {
964+ cgl::VertexBufferPush pushedVertexBuffer (vbStack, vb);
965+
966+ {
967+ cgl::VertexBufferPush pushedVertexBuffer (vbStack, vbIdentical);
968+
969+ EXPECT_EQ (vbStack.activeVertexBuffer (), weak);
970+ }
971+
972+ EXPECT_EQ (vbStack.activeVertexBuffer (), weak);
973+ }
974+
975+ EXPECT_THAT (vbStack.activeVertexBuffer (), IsExpired <GLVertexBuffer> ());
976+}
977
978=== modified file 'plugins/opengl/src/window.cpp'
979--- plugins/opengl/src/window.cpp 2012-08-14 06:33:22 +0000
980+++ plugins/opengl/src/window.cpp 2012-09-28 07:48:55 +0000
981@@ -24,9 +24,12 @@
982 * Authors: Dennis Kasprzyk <onestone@compiz-fusion.org>
983 * David Reveman <davidr@novell.com>
984 */
985-
986+#include <boost/make_shared.hpp>
987 #include "privates.h"
988
989+namespace cgl = compiz::opengl;
990+namespace cgli = compiz::opengl::impl;
991+
992 GLWindow::GLWindow (CompWindow *w) :
993 PluginClassHandler<GLWindow, CompWindow, COMPIZ_OPENGL_ABI> (w),
994 priv (new PrivateGLWindow (w, this))
995@@ -68,6 +71,36 @@
996
997 };
998
999+const cgl::GLVertexBufferWeak &
1000+PrivateGLWindow::activeVertexBuffer () const
1001+{
1002+ return vertexBufferStack.activeVertexBuffer ();
1003+}
1004+
1005+void
1006+PrivateGLWindow::pushVertexBuffer (const cgl::GLVertexBufferPtr &vertexBuffer)
1007+{
1008+ vertexBufferStack.pushVertexBuffer (vertexBuffer);
1009+}
1010+
1011+void
1012+PrivateGLWindow::popVertexBufferFromTop ()
1013+{
1014+ vertexBufferStack.popVertexBufferFromTop ();
1015+}
1016+
1017+bool
1018+PrivateGLWindow::removeVertexBuffer (const cgl::GLVertexBufferPtr &vertexBuffer)
1019+{
1020+ return vertexBufferStack.removeVertexBuffer (vertexBuffer);
1021+}
1022+
1023+bool
1024+PrivateGLWindow::removeLastVertexBuffer (const cgl::GLVertexBufferPtr &vertexBuffer)
1025+{
1026+ return vertexBufferStack.removeLastVertexBuffer (vertexBuffer);
1027+}
1028+
1029 PrivateGLWindow::PrivateGLWindow (CompWindow *w,
1030 GLWindow *gw) :
1031 window (w),
1032@@ -79,11 +112,21 @@
1033 updateState (UpdateRegion | UpdateMatrix),
1034 needsRebind (true),
1035 clip (),
1036+ lastDamageRegion (),
1037+ vertexBufferDirty (false),
1038+ inGLDraw (false),
1039 bindFailed (false),
1040- vertexBuffer (new GLVertexBuffer ()),
1041- autoProgram(new GLWindowAutoProgram(this)),
1042+ /* We are using GL_DYNAMIC_DRAW here as the vertex buffer contents
1043+ * will change across different regions of the screen being damaged,
1044+ * however if the same region of the screen is being damaged (video)
1045+ * this will yeild the best performance in that case */
1046+ windowVertexBuffer (new GLVertexBuffer (GL::DYNAMIC_DRAW)),
1047+ autoProgram (new GLWindowAutoProgram(this)),
1048 icons ()
1049 {
1050+ windowVertexBuffer->setAutoProgram (autoProgram);
1051+ vertexBufferStack.pushVertexBuffer (windowVertexBuffer);
1052+
1053 paint.xScale = 1.0f;
1054 paint.yScale = 1.0f;
1055 paint.xTranslate = 0.0f;
1056@@ -92,14 +135,11 @@
1057 WindowInterface::setHandler (w);
1058 CompositeWindowInterface::setHandler (cWindow);
1059
1060- vertexBuffer->setAutoProgram(autoProgram);
1061-
1062 cWindow->setNewPixmapReadyCallback (boost::bind (&PrivateGLWindow::clearTextures, this));
1063 }
1064
1065 PrivateGLWindow::~PrivateGLWindow ()
1066 {
1067- delete vertexBuffer;
1068 delete autoProgram;
1069 cWindow->setNewPixmapReadyCallback (boost::function <void ()> ());
1070 }
1071@@ -128,6 +168,18 @@
1072 textures.clear ();
1073 }
1074
1075+compiz::opengl::VertexBufferStack &
1076+GLWindow::vertexBufferStack ()
1077+{
1078+ return *priv;
1079+}
1080+
1081+compiz::gl::AutoProgram *
1082+GLWindow::autoProgram ()
1083+{
1084+ return priv->autoProgram;
1085+}
1086+
1087 bool
1088 GLWindow::bind ()
1089 {
1090@@ -287,7 +339,7 @@
1091 GLVertexBuffer *
1092 GLWindow::vertexBuffer ()
1093 {
1094- return priv->vertexBuffer;
1095+ return priv->vertexBufferStack.activeVertexBuffer ().lock ().get ();
1096 }
1097
1098 const GLTexture::List &

Subscribers

People subscribed via source and target branches