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

Proposed by Sam Spilsbury
Status: Superseded
Proposed branch: lp:~smspillaz/compiz/compiz.static_vertex_buffers
Merge into: lp:compiz/0.9.8
Diff against target: 1088 lines (+759/-23)
13 files modified
plugins/decor/src/decor.cpp (+8/-1)
plugins/decor/src/decor.h (+2/-0)
plugins/opengl/CMakeLists.txt (+7/-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)
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 (community) continuous-integration Approve
Review via email: mp+123447@code.launchpad.net

This proposal has been superseded by a proposal from 2012-09-28.

Commit message

Avoid doing so many vertex buffer object binds.

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 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

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 :
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

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 :

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 :

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 :

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 :

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 :

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

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
=== modified file 'plugins/decor/src/decor.cpp'
--- plugins/decor/src/decor.cpp 2012-08-14 06:33:22 +0000
+++ plugins/decor/src/decor.cpp 2012-09-09 16:26:19 +0000
@@ -42,6 +42,8 @@
4242
43COMPIZ_PLUGIN_20090315 (decor, DecorPluginVTable)43COMPIZ_PLUGIN_20090315 (decor, DecorPluginVTable)
4444
45namespace cgl = compiz::opengl;
46
45MatchedDecorClipGroup::MatchedDecorClipGroup (const CompMatch &match) :47MatchedDecorClipGroup::MatchedDecorClipGroup (const CompMatch &match) :
46 mMatch (match)48 mMatch (match)
47{49{
@@ -209,6 +211,9 @@
209 const CompRegion &region,211 const CompRegion &region,
210 unsigned int mask)212 unsigned int mask)
211{213{
214 cgl::VertexBufferPush vertexBufferPush (gWindow->vertexBufferStack (),
215 mDecorationVertexBuffer);
216
212 if (wd &&217 if (wd &&
213 wd->decor->type == WINDOW_DECORATION_TYPE_PIXMAP)218 wd->decor->type == WINDOW_DECORATION_TYPE_PIXMAP)
214 {219 {
@@ -3091,8 +3096,10 @@
3091 mClipGroup (NULL),3096 mClipGroup (NULL),
3092 mOutputRegion (window->outputRect ()),3097 mOutputRegion (window->outputRect ()),
3093 mInputRegion (window->inputRect ()),3098 mInputRegion (window->inputRect ()),
3094 mRequestor (screen->dpy (), w->id (), &decor)3099 mRequestor (screen->dpy (), w->id (), &decor),
3100 mDecorationVertexBuffer (new GLVertexBuffer (GL_STATIC_DRAW))
3095{3101{
3102 mDecorationVertexBuffer->setAutoProgram (gWindow->autoProgram ());
3096 WindowInterface::setHandler (window);3103 WindowInterface::setHandler (window);
30973104
3098 /* FIXME :DecorWindow::update can call updateWindowOutputExtents3105 /* FIXME :DecorWindow::update can call updateWindowOutputExtents
30993106
=== modified file 'plugins/decor/src/decor.h'
--- plugins/decor/src/decor.h 2012-07-30 07:10:52 +0000
+++ plugins/decor/src/decor.h 2012-09-09 16:26:19 +0000
@@ -31,6 +31,7 @@
3131
32#include <composite/composite.h>32#include <composite/composite.h>
33#include <opengl/opengl.h>33#include <opengl/opengl.h>
34#include <opengl/vertexbufferstack.h>
34#include <core/atoms.h>35#include <core/atoms.h>
35#include <core/windowextents.h>36#include <core/windowextents.h>
3637
@@ -362,6 +363,7 @@
362 CompRegion mInputRegion;363 CompRegion mInputRegion;
363364
364 X11DecorPixmapRequestor mRequestor;365 X11DecorPixmapRequestor mRequestor;
366 compiz::opengl::GLVertexBufferPtr mDecorationVertexBuffer;
365};367};
366368
367class DecorPluginVTable :369class DecorPluginVTable :
368370
=== modified file 'plugins/opengl/CMakeLists.txt'
--- plugins/opengl/CMakeLists.txt 2012-09-04 10:19:19 +0000
+++ plugins/opengl/CMakeLists.txt 2012-09-09 16:26:19 +0000
@@ -5,10 +5,17 @@
5set (INTERNAL_LIBRARIES5set (INTERNAL_LIBRARIES
6 compiz_opengl_double_buffer6 compiz_opengl_double_buffer
7 compiz_opengl_fsregion7 compiz_opengl_fsregion
8 compiz_opengl_vertex_buffer_stack
8)9)
910
11set (COMPIZ_OPENGL_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
12set (COMPIZ_OPENGL_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
13
10add_subdirectory (src/doublebuffer)14add_subdirectory (src/doublebuffer)
11add_subdirectory (src/fsregion)15add_subdirectory (src/fsregion)
16add_subdirectory (src/vertexbufferstack)
17
18include_directories (src/vertexbufferstack/include)
1219
13if (USE_GLES)20if (USE_GLES)
14 compiz_plugin(opengl PLUGINDEPS composite CFLAGSADD "-DUSE_GLES -std=c++0x" LIBRARIES ${OPENGLES2_LIBRARIES} ${INTERNAL_LIBRARIES} dl INCDIRS ${OPENGLES2_INCLUDE_DIR})21 compiz_plugin(opengl PLUGINDEPS composite CFLAGSADD "-DUSE_GLES -std=c++0x" LIBRARIES ${OPENGLES2_LIBRARIES} ${INTERNAL_LIBRARIES} dl INCDIRS ${OPENGLES2_INCLUDE_DIR})
1522
=== modified file 'plugins/opengl/include/opengl/opengl.h'
--- plugins/opengl/include/opengl/opengl.h 2012-08-14 08:42:15 +0000
+++ plugins/opengl/include/opengl/opengl.h 2012-09-09 16:26:19 +0000
@@ -39,6 +39,9 @@
39#include <GL/glx.h>39#include <GL/glx.h>
40#endif40#endif
4141
42#include <boost/shared_ptr.hpp>
43#include <boost/weak_ptr.hpp>
44
42#include <core/size.h>45#include <core/size.h>
43#include <core/pluginclasshandler.h>46#include <core/pluginclasshandler.h>
4447
@@ -871,6 +874,16 @@
871 const GLWindowPaintAttrib &, unsigned int);874 const GLWindowPaintAttrib &, unsigned int);
872};875};
873876
877namespace compiz
878{
879 namespace opengl
880 {
881 typedef boost::shared_ptr <GLVertexBuffer> GLVertexBufferPtr;
882 typedef boost::weak_ptr <GLVertexBuffer> GLVertexBufferWeak;
883 class VertexBufferStack;
884 }
885}
886
874class GLWindow :887class GLWindow :
875 public WrapableHandler<GLWindowInterface, 4>,888 public WrapableHandler<GLWindowInterface, 4>,
876 public PluginClassHandler<GLWindow, CompWindow, COMPIZ_OPENGL_ABI>889 public PluginClassHandler<GLWindow, CompWindow, COMPIZ_OPENGL_ABI>
@@ -926,6 +939,23 @@
926 GLVertexBuffer * vertexBuffer ();939 GLVertexBuffer * vertexBuffer ();
927940
928 /**941 /**
942 * Returns the current vertex buffer stack
943 */
944 compiz::opengl::VertexBufferStack &
945 vertexBufferStack ();
946
947 /**
948 * Returns the AutoProgram used for this window's
949 * GLVertexBuffer objects. The returned object
950 * is internal to GLWindow and should not be
951 * deleted
952 *
953 * TODO ABI: Return weak pointer
954 */
955 compiz::gl::AutoProgram *
956 autoProgram ();
957
958 /**
929 * Add a vertex and/or fragment shader function to the pipeline.959 * Add a vertex and/or fragment shader function to the pipeline.
930 *960 *
931 * @param name Name of the plugin adding the functions961 * @param name Name of the plugin adding the functions
932962
=== added file 'plugins/opengl/include/opengl/vertexbufferstack.h'
--- plugins/opengl/include/opengl/vertexbufferstack.h 1970-01-01 00:00:00 +0000
+++ plugins/opengl/include/opengl/vertexbufferstack.h 2012-09-09 16:26:19 +0000
@@ -0,0 +1,69 @@
1/*
2 * Compiz opengl plugin, VertexBufferStack interface
3 *
4 * Copyright (c) 2012 Canonical Ltd.
5 * Author: Sam Spilsbury <sam.spilsbury@canonical.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25#ifndef __COMPIZ_OPENGL_VERTEXBUFFERSTACK_H
26#define __COMPIZ_OPENGL_VERTEXBUFFERSTACK_H
27
28#include <boost/shared_ptr.hpp>
29#include <boost/weak_ptr.hpp>
30
31class GLVertexBuffer;
32
33namespace compiz
34{
35 namespace opengl
36 {
37 typedef boost::shared_ptr <GLVertexBuffer> GLVertexBufferPtr;
38 typedef boost::weak_ptr <GLVertexBuffer> GLVertexBufferWeak;
39
40 class VertexBufferStack
41 {
42 public:
43
44 virtual ~VertexBufferStack () {}
45
46 virtual void pushVertexBuffer (const GLVertexBufferPtr &) = 0;
47 virtual bool removeVertexBuffer (const GLVertexBufferPtr &) = 0;
48 virtual bool removeLastVertexBuffer (const GLVertexBufferPtr &) = 0;
49 virtual void popVertexBufferFromTop () = 0;
50 virtual const GLVertexBufferWeak & activeVertexBuffer () const = 0;
51 };
52
53 class VertexBufferPush
54 {
55 public:
56
57 VertexBufferPush (VertexBufferStack &vbStack,
58 const GLVertexBufferPtr &vertexBuffer);
59 ~VertexBufferPush ();
60
61 private:
62
63 VertexBufferStack &mVBStack;
64 const GLVertexBufferPtr &mVertexBuffer;
65 };
66 }
67}
68
69#endif
070
=== modified file 'plugins/opengl/src/paint.cpp'
--- plugins/opengl/src/paint.cpp 2012-09-06 09:55:05 +0000
+++ plugins/opengl/src/paint.cpp 2012-09-09 16:26:19 +0000
@@ -36,13 +36,14 @@
36#define foreach BOOST_FOREACH36#define foreach BOOST_FOREACH
3737
38#include <opengl/opengl.h>38#include <opengl/opengl.h>
39#include <opengl/vertexbufferstack.h>
3940
40#include "privates.h"41#include "privates.h"
41#include "fsregion/fsregion.h"42#include "fsregion/fsregion.h"
4243
43#define DEG2RAD (M_PI / 180.0f)44#define DEG2RAD (M_PI / 180.0f)
4445
45using namespace compiz::opengl;46namespace cgl = compiz::opengl;
4647
47GLScreenPaintAttrib defaultScreenPaintAttrib = {48GLScreenPaintAttrib defaultScreenPaintAttrib = {
48 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -DEFAULT_Z_CAMERA49 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -DEFAULT_Z_CAMERA
@@ -275,7 +276,7 @@
275276
276 if (!(mask & PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK))277 if (!(mask & PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK))
277 {278 {
278 FullscreenRegion fs (*output);279 cgl::FullscreenRegion fs (*output);
279280
280 /* detect occlusions */281 /* detect occlusions */
281 for (rit = pl.rbegin (); rit != pl.rend (); ++rit)282 for (rit = pl.rbegin (); rit != pl.rend (); ++rit)
@@ -339,11 +340,11 @@
339 tmpRegion -= w->region ();340 tmpRegion -= w->region ();
340 }341 }
341342
342 FullscreenRegion::WinFlags flags = 0;343 cgl::FullscreenRegion::WinFlags flags = 0;
343 if (w->type () & CompWindowTypeDesktopMask)344 if (w->type () & CompWindowTypeDesktopMask)
344 flags |= FullscreenRegion::Desktop;345 flags |= cgl::FullscreenRegion::Desktop;
345 if (w->alpha ())346 if (w->alpha ())
346 flags |= FullscreenRegion::Alpha;347 flags |= cgl::FullscreenRegion::Alpha;
347 348
348 /*349 /*
349 * Windows with alpha channels can partially occlude windows350 * Windows with alpha channels can partially occlude windows
@@ -895,9 +896,16 @@
895{896{
896 WRAPABLE_HND_FUNCTN (glAddGeometry, matrix, region, clip)897 WRAPABLE_HND_FUNCTN (glAddGeometry, matrix, region, clip)
897898
899 boost::shared_ptr <GLVertexBuffer> activeVertexBuffer = priv->vertexBufferStack.activeVertexBuffer ().lock ();
900
898 BoxRec full;901 BoxRec full;
899 int nMatrix = matrix.size ();902 int nMatrix = matrix.size ();
900903
904 /* Someone is modifying our internal vertex buffer */
905 if (!priv->inGLDraw &&
906 activeVertexBuffer == priv->windowVertexBuffer)
907 priv->vertexBufferDirty = true;
908
901 full = clip.handle ()->extents;909 full = clip.handle ()->extents;
902 if (region.handle ()->extents.x1 > full.x1)910 if (region.handle ()->extents.x1 > full.x1)
903 full.x1 = region.handle ()->extents.x1;911 full.x1 = region.handle ()->extents.x1;
@@ -954,7 +962,7 @@
954962
955 if (nClip == 1)963 if (nClip == 1)
956 {964 {
957 addQuads (priv->vertexBuffer, matrix, nMatrix,965 addQuads (activeVertexBuffer.get (), matrix, nMatrix,
958 x1, y1, x2, y2,966 x1, y1, x2, y2,
959 rect,967 rect,
960 maxGridWidth, maxGridHeight);968 maxGridWidth, maxGridHeight);
@@ -980,7 +988,7 @@
980988
981 if (cbox.x1 < cbox.x2 && cbox.y1 < cbox.y2)989 if (cbox.x1 < cbox.x2 && cbox.y1 < cbox.y2)
982 {990 {
983 addQuads (priv->vertexBuffer, matrix, nMatrix,991 addQuads (activeVertexBuffer.get (), matrix, nMatrix,
984 cbox.x1, cbox.y1, cbox.x2, cbox.y2,992 cbox.x1, cbox.y1, cbox.x2, cbox.y2,
985 rect,993 rect,
986 maxGridWidth, maxGridHeight);994 maxGridWidth, maxGridHeight);
@@ -1222,14 +1230,14 @@
1222 texture->enable (filter);1230 texture->enable (filter);
12231231
1224 #ifdef USE_GLES1232 #ifdef USE_GLES
1225 priv->vertexBuffer->render (transform, attrib);1233 priv->vertexBufferStack.activeVertexBuffer ().lock ()->render (transform, attrib);
1226 #else1234 #else
12271235
1228 if (!GLVertexBuffer::enabled ())1236 if (!GLVertexBuffer::enabled ())
1229 enableLegacyOBSAndRender (priv->gScreen, this, texture, transform,1237 enableLegacyOBSAndRender (priv->gScreen, this, texture, transform,
1230 attrib, filter, mask);1238 attrib, filter, mask);
1231 else1239 else
1232 priv->vertexBuffer->render (transform, attrib);1240 priv->vertexBufferStack.activeVertexBuffer ().lock ()->render (transform, attrib);
1233 #endif1241 #endif
12341242
1235 priv->shaders.clear ();1243 priv->shaders.clear ();
@@ -1248,9 +1256,22 @@
1248 WRAPABLE_HND_FUNCTN_RETURN (bool, glDraw, transform,1256 WRAPABLE_HND_FUNCTN_RETURN (bool, glDraw, transform,
1249 attrib, region, mask)1257 attrib, region, mask)
12501258
1259 const bool transformedWindow = mask & (PAINT_WINDOW_WITH_OFFSET_MASK |
1260 PAINT_WINDOW_TRANSFORMED_MASK);
1261 const bool damageRegionChanged = priv->lastDamageRegion != region;
1262 const bool internalMatricesChanged = priv->updateState & (PrivateGLWindow::UpdateMatrix |
1263 PrivateGLWindow::UpdateRegion);
1264 const bool readdGeometry = priv->vertexBufferDirty ||
1265 transformedWindow ||
1266 internalMatricesChanged ||
1267 damageRegionChanged;
1268
1251 const CompRegion &reg = (mask & PAINT_WINDOW_TRANSFORMED_MASK) ?1269 const CompRegion &reg = (mask & PAINT_WINDOW_TRANSFORMED_MASK) ?
1252 infiniteRegion : region;1270 infiniteRegion : region;
12531271
1272 if (readdGeometry)
1273 priv->lastDamageRegion = region;
1274
1254 if (reg.isEmpty ())1275 if (reg.isEmpty ())
1255 return true;1276 return true;
12561277
@@ -1282,10 +1303,23 @@
12821303
1283 for (unsigned int i = 0; i < priv->textures.size (); i++)1304 for (unsigned int i = 0; i < priv->textures.size (); i++)
1284 {1305 {
1285 ml[0] = priv->matrices[i];1306 cgl::VertexBufferStack &vbStack (priv->vertexBufferStack);
1286 priv->vertexBuffer->begin ();1307 cgl::VertexBufferPush push (vbStack,
1287 glAddGeometry (ml, priv->regions[i], reg);1308 priv->windowVertexBuffer);
1288 if (priv->vertexBuffer->end ())1309 cgl::GLVertexBufferPtr activeVertexBuffer = vbStack.activeVertexBuffer ().lock ();
1310
1311 if (readdGeometry || true)
1312 {
1313 priv->inGLDraw = true;
1314 ml[0] = priv->matrices[i];
1315 activeVertexBuffer->begin ();
1316 glAddGeometry (ml, priv->regions[i], reg);
1317 activeVertexBuffer->end ();
1318 priv->inGLDraw = false;
1319 priv->vertexBufferDirty = false;
1320 }
1321
1322 if (activeVertexBuffer->countVertices ())
1289 glDrawTexture (priv->textures[i], transform, attrib, mask);1323 glDrawTexture (priv->textures[i], transform, attrib, mask);
1290 }1324 }
12911325
12921326
=== modified file 'plugins/opengl/src/privates.h'
--- plugins/opengl/src/privates.h 2012-07-30 07:10:52 +0000
+++ plugins/opengl/src/privates.h 2012-09-09 16:26:19 +0000
@@ -28,6 +28,9 @@
28#ifndef _OPENGL_PRIVATES_H28#ifndef _OPENGL_PRIVATES_H
29#define _OPENGL_PRIVATES_H29#define _OPENGL_PRIVATES_H
3030
31#include <boost/shared_ptr.hpp>
32#include <boost/weak_ptr.hpp>
33
31#include <composite/composite.h>34#include <composite/composite.h>
32#include <opengl/opengl.h>35#include <opengl/opengl.h>
33#include <core/atoms.h>36#include <core/atoms.h>
@@ -40,6 +43,7 @@
4043
41#include "privatetexture.h"44#include "privatetexture.h"
42#include "privatevertexbuffer.h"45#include "privatevertexbuffer.h"
46#include "vertexbufferstack-internal.h"
43#include "opengl_options.h"47#include "opengl_options.h"
4448
45extern CompOutput *targetOutput;49extern CompOutput *targetOutput;
@@ -213,7 +217,8 @@
213217
214class PrivateGLWindow :218class PrivateGLWindow :
215 public WindowInterface,219 public WindowInterface,
216 public CompositeWindowInterface220 public CompositeWindowInterface,
221 public compiz::opengl::VertexBufferStack
217{222{
218 public:223 public:
219224
@@ -246,6 +251,9 @@
246 bool needsRebind;251 bool needsRebind;
247252
248 CompRegion clip;253 CompRegion clip;
254 CompRegion lastDamageRegion;
255 bool vertexBufferDirty;
256 bool inGLDraw;
249257
250 bool bindFailed;258 bool bindFailed;
251 bool overlayWindow;259 bool overlayWindow;
@@ -259,7 +267,8 @@
259267
260 unsigned int lastMask;268 unsigned int lastMask;
261269
262 GLVertexBuffer *vertexBuffer;270 compiz::opengl::impl::VertexBufferStack vertexBufferStack;
271 compiz::opengl::GLVertexBufferPtr windowVertexBuffer;
263272
264 // map of shaders, plugin name is key, pair of vertex and fragment273 // map of shaders, plugin name is key, pair of vertex and fragment
265 // shader source code is value274 // shader source code is value
@@ -267,6 +276,15 @@
267 GLVertexBuffer::AutoProgram *autoProgram;276 GLVertexBuffer::AutoProgram *autoProgram;
268277
269 std::list<GLIcon> icons;278 std::list<GLIcon> icons;
279
280 private:
281
282 /* Implementation of compiz::opengl::VertexBufferStack */
283 void pushVertexBuffer (const compiz::opengl::GLVertexBufferPtr &);
284 void popVertexBufferFromTop ();
285 bool removeVertexBuffer (const compiz::opengl::GLVertexBufferPtr &);
286 bool removeLastVertexBuffer (const compiz::opengl::GLVertexBufferPtr &);
287 const compiz::opengl::GLVertexBufferWeak & activeVertexBuffer () const;
270};288};
271289
272#endif290#endif
273291
=== added directory 'plugins/opengl/src/vertexbufferstack'
=== added file 'plugins/opengl/src/vertexbufferstack/CMakeLists.txt'
--- plugins/opengl/src/vertexbufferstack/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ plugins/opengl/src/vertexbufferstack/CMakeLists.txt 2012-09-09 16:26:19 +0000
@@ -0,0 +1,25 @@
1INCLUDE_DIRECTORIES (
2 ${COMPIZ_OPENGL_SOURCE_DIR}
3 ${COMPIZ_OPENGL_INCLUDE_DIR}
4 ${CMAKE_CURRENT_SOURCE_DIR}/include
5 ${CMAKE_CURRENT_SOURCE_DIR}/src
6
7 ${Boost_INCLUDE_DIRS}
8)
9
10LINK_DIRECTORIES (${COMPIZ_LIBRARY_DIRS})
11
12SET(
13 SRCS
14 ${CMAKE_CURRENT_SOURCE_DIR}/src/vertex-buffer-stack.cpp
15)
16
17ADD_LIBRARY(
18 compiz_opengl_vertex_buffer_stack STATIC
19
20 ${SRCS}
21)
22
23if (COMPIZ_BUILD_TESTING)
24ADD_SUBDIRECTORY( ${CMAKE_CURRENT_SOURCE_DIR}/tests )
25endif (COMPIZ_BUILD_TESTING)
026
=== added directory 'plugins/opengl/src/vertexbufferstack/include'
=== added file 'plugins/opengl/src/vertexbufferstack/include/vertexbufferstack-internal.h'
--- plugins/opengl/src/vertexbufferstack/include/vertexbufferstack-internal.h 1970-01-01 00:00:00 +0000
+++ plugins/opengl/src/vertexbufferstack/include/vertexbufferstack-internal.h 2012-09-09 16:26:19 +0000
@@ -0,0 +1,67 @@
1/*
2 * Compiz opengl plugin, VertexBufferStack interface
3 *
4 * Copyright (c) 2012 Canonical Ltd.
5 * Author: Sam Spilsbury <sam.spilsbury@canonical.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25#ifndef __COMPIZ_OPENGL_VERTEXBUFFERSTACKINTERNAL_H
26#define __COMPIZ_OPENGL_VERTEXBUFFERSTACKINTERNAL_H
27
28#include <opengl/vertexbufferstack.h>
29
30namespace compiz
31{
32 namespace opengl
33 {
34 namespace impl
35 {
36 namespace cgl = compiz::opengl;
37
38 class PrivateVertexBufferStack;
39
40 class VertexBufferStack :
41 public cgl::VertexBufferStack
42 {
43 public:
44
45 VertexBufferStack ();
46 ~VertexBufferStack ();
47
48 void pushVertexBuffer (const GLVertexBufferPtr &);
49 bool removeLastVertexBuffer (const GLVertexBufferPtr &);
50 bool removeVertexBuffer (const GLVertexBufferPtr &);
51 void popVertexBufferFromTop ();
52 const GLVertexBufferWeak & activeVertexBuffer () const;
53
54 private:
55
56 PrivateVertexBufferStack *priv;
57 };
58 }
59 }
60}
61
62bool operator== (const compiz::opengl::GLVertexBufferWeak &lhs,
63 const compiz::opengl::GLVertexBufferWeak &rhs);
64bool operator!= (const compiz::opengl::GLVertexBufferWeak &lhs,
65 const compiz::opengl::GLVertexBufferWeak &rhs);
66
67#endif
068
=== added directory 'plugins/opengl/src/vertexbufferstack/src'
=== added file 'plugins/opengl/src/vertexbufferstack/src/vertex-buffer-stack.cpp'
--- plugins/opengl/src/vertexbufferstack/src/vertex-buffer-stack.cpp 1970-01-01 00:00:00 +0000
+++ plugins/opengl/src/vertexbufferstack/src/vertex-buffer-stack.cpp 2012-09-09 16:26:19 +0000
@@ -0,0 +1,145 @@
1/*
2 * Compiz, opengl plugin, VertexBufferStack class
3 *
4 * Copyright (c) 2012 Canonical Ltd.
5 * Authors: Sam Spilsbury <sam.spilsbury@canonical.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25#include <algorithm>
26#include <vector>
27#include "vertexbufferstack-internal.h"
28
29namespace cgl = compiz::opengl;
30namespace cgli = compiz::opengl::impl;
31
32class GLVertexBuffer;
33
34namespace compiz
35{
36 namespace opengl
37 {
38 namespace impl
39 {
40 class PrivateVertexBufferStack
41 {
42 public:
43
44 std::vector <cgl::GLVertexBufferWeak> savedVertexBuffers;
45 cgl::GLVertexBufferWeak activeVertexBuffer;
46 };
47 }
48 }
49}
50
51bool operator== (const compiz::opengl::GLVertexBufferWeak &lhs,
52 const compiz::opengl::GLVertexBufferWeak &rhs)
53{
54 return lhs.lock () == rhs.lock ();
55}
56
57bool operator!= (const compiz::opengl::GLVertexBufferWeak &lhs,
58 const compiz::opengl::GLVertexBufferWeak &rhs)
59{
60 return !(lhs == rhs);
61}
62
63cgli::VertexBufferStack::VertexBufferStack () :
64 priv (new PrivateVertexBufferStack)
65{
66}
67
68cgli::VertexBufferStack::~VertexBufferStack ()
69{
70 delete priv;
71}
72
73void
74cgli::VertexBufferStack::pushVertexBuffer (const cgl::GLVertexBufferPtr &vb)
75{
76 priv->savedVertexBuffers.push_back (priv->activeVertexBuffer);
77 priv->activeVertexBuffer = vb;
78}
79
80void
81cgli::VertexBufferStack::popVertexBufferFromTop ()
82{
83 if (!priv->savedVertexBuffers.empty ())
84 priv->activeVertexBuffer = priv->savedVertexBuffers.back ();
85 else
86 priv->activeVertexBuffer.reset ();
87
88 priv->savedVertexBuffers.pop_back ();
89}
90
91bool
92cgli::VertexBufferStack::removeLastVertexBuffer (const GLVertexBufferPtr &vb)
93{
94 cgl::GLVertexBufferWeak weak (vb);
95 std::vector <cgl::GLVertexBufferWeak>::reverse_iterator rit = priv->savedVertexBuffers.rbegin ();
96
97 if (weak == priv->activeVertexBuffer)
98 {
99 popVertexBufferFromTop ();
100 return true;
101 }
102
103 while (rit != priv->savedVertexBuffers.rend ())
104 {
105 if (*rit == weak)
106 {
107 priv->savedVertexBuffers.erase (rit.base () - 1);
108 return true;
109 }
110
111 ++rit;
112 };
113
114 return false;
115}
116
117bool
118cgli::VertexBufferStack::removeVertexBuffer (const cgl::GLVertexBufferPtr &vb)
119{
120 bool found = false;
121
122 while (removeLastVertexBuffer (vb))
123 found = true;
124
125 return found;
126}
127
128const cgl::GLVertexBufferWeak &
129cgli::VertexBufferStack::activeVertexBuffer () const
130{
131 return priv->activeVertexBuffer;
132}
133
134cgl::VertexBufferPush::VertexBufferPush (cgl::VertexBufferStack &vbStack,
135 const cgl::GLVertexBufferPtr &vertexBuffer) :
136 mVBStack (vbStack),
137 mVertexBuffer (vertexBuffer)
138{
139 vbStack.pushVertexBuffer (vertexBuffer);
140}
141
142cgl::VertexBufferPush::~VertexBufferPush ()
143{
144 mVBStack.removeLastVertexBuffer (mVertexBuffer);
145}
0146
=== added directory 'plugins/opengl/src/vertexbufferstack/tests'
=== added file 'plugins/opengl/src/vertexbufferstack/tests/CMakeLists.txt'
--- plugins/opengl/src/vertexbufferstack/tests/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ plugins/opengl/src/vertexbufferstack/tests/CMakeLists.txt 2012-09-09 16:26:19 +0000
@@ -0,0 +1,24 @@
1find_library (GMOCK_LIBRARY gmock)
2find_library (GMOCK_MAIN_LIBRARY gmock_main)
3
4if (NOT GMOCK_LIBRARY OR NOT GMOCK_MAIN_LIBRARY OR NOT GTEST_FOUND)
5 message ("Google Mock and Google Test not found - cannot build tests!")
6 set (COMPIZ_BUILD_TESTING OFF)
7endif (NOT GMOCK_LIBRARY OR NOT GMOCK_MAIN_LIBRARY OR NOT GTEST_FOUND)
8
9include_directories (${GTEST_INCLUDE_DIRS})
10
11link_directories (${COMPIZ_LIBRARY_DIRS})
12
13add_executable (compiz_test_opengl_vertex_buffer_stack
14 ${CMAKE_CURRENT_SOURCE_DIR}/test-opengl-vertex-buffer-stack.cpp)
15
16target_link_libraries (compiz_test_opengl_vertex_buffer_stack
17 compiz_opengl_vertex_buffer_stack
18 ${GTEST_BOTH_LIBRARIES}
19 ${GMOCK_LIBRARY}
20 ${GMOCK_MAIN_LIBRARY}
21 ${CMAKE_THREAD_LIBS_INIT} # Link in pthread.
22 )
23
24compiz_discover_tests (compiz_test_opengl_vertex_buffer_stack COVERAGE compiz_opengl_vertex_buffer_stack)
025
=== added file 'plugins/opengl/src/vertexbufferstack/tests/test-opengl-vertex-buffer-stack.cpp'
--- plugins/opengl/src/vertexbufferstack/tests/test-opengl-vertex-buffer-stack.cpp 1970-01-01 00:00:00 +0000
+++ plugins/opengl/src/vertexbufferstack/tests/test-opengl-vertex-buffer-stack.cpp 2012-09-09 16:26:19 +0000
@@ -0,0 +1,256 @@
1/*
2 * Compiz, opengl plugin, VertexBufferStack class
3 *
4 * Copyright (c) 2012 Canonical Ltd.
5 * Authors: Sam Spilsbury <sam.spilsbury@canonical.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25#include <boost/make_shared.hpp>
26#include <gtest/gtest.h>
27#include <gmock/gmock.h>
28#include "vertexbufferstack-internal.h"
29
30using ::testing::MatcherInterface;
31using ::testing::MakeMatcher;
32using ::testing::MatchResultListener;
33using ::testing::Matcher;
34
35template <class P>
36class ExpiredPtrMatcher :
37 public ::testing::MatcherInterface <const boost::weak_ptr <P> &>
38{
39 public:
40
41 bool MatchAndExplain (const boost::weak_ptr <P> &x, MatchResultListener *listener) const
42 {
43 return x.expired ();
44 }
45
46 void DescribeTo (std::ostream *os) const
47 {
48 *os << "is expired";
49 }
50
51 void DescribeNegationTo (std::ostream *os) const
52 {
53 *os << "is not expired";
54 }
55};
56
57template <class P>
58inline Matcher<const boost::weak_ptr <P> &> IsExpired ()
59{
60 return MakeMatcher (new ExpiredPtrMatcher<P> ());
61}
62
63namespace cgl = compiz::opengl;
64namespace cgli = compiz::opengl::impl;
65
66class OpenGLVertexBufferStackTest :
67 public ::testing::Test
68{
69 public:
70
71 cgli::VertexBufferStack vbStack;
72};
73
74/* Provide a dummy definition of GLVertexBuffer for our purposes,
75 * as we are only managing the pointer */
76class GLVertexBuffer
77{
78};
79
80TEST_F (OpenGLVertexBufferStackTest, TestPushIsActive)
81{
82 cgl::GLVertexBufferPtr vb (boost::make_shared <GLVertexBuffer> ());
83 cgl::GLVertexBufferWeak weak (vb);
84
85 vbStack.pushVertexBuffer (vb);
86 EXPECT_EQ (weak, vbStack.activeVertexBuffer ());
87}
88
89TEST_F (OpenGLVertexBufferStackTest, TestPushTwoPopFirstActive)
90{
91 cgl::GLVertexBufferPtr vbFirst (boost::make_shared <GLVertexBuffer> ());
92 cgl::GLVertexBufferPtr vbSecond (boost::make_shared <GLVertexBuffer> ());
93
94 cgl::GLVertexBufferWeak weakFirst (vbFirst);
95 cgl::GLVertexBufferWeak weakSecond (vbSecond);
96
97 vbStack.pushVertexBuffer (vbFirst);
98 vbStack.pushVertexBuffer (vbSecond);
99
100 EXPECT_EQ (weakSecond, vbStack.activeVertexBuffer ());
101
102 vbStack.popVertexBufferFromTop ();
103
104 EXPECT_EQ (weakFirst, vbStack.activeVertexBuffer ());
105}
106
107TEST_F (OpenGLVertexBufferStackTest, TestPushThreeRemoveSecondThirdIsActive)
108{
109 cgl::GLVertexBufferPtr vbFirst (boost::make_shared <GLVertexBuffer> ());
110 cgl::GLVertexBufferPtr vbSecond (boost::make_shared <GLVertexBuffer> ());
111 cgl::GLVertexBufferPtr vbThird (boost::make_shared <GLVertexBuffer> ());
112
113 cgl::GLVertexBufferWeak weakFirst (vbFirst);
114 cgl::GLVertexBufferWeak weakSecond (vbSecond);
115 cgl::GLVertexBufferWeak weakThird (vbThird);
116
117 vbStack.pushVertexBuffer (vbFirst);
118 vbStack.pushVertexBuffer (vbSecond);
119 vbStack.pushVertexBuffer (vbThird);
120
121 EXPECT_EQ (weakThird, vbStack.activeVertexBuffer ());
122
123 vbStack.removeVertexBuffer (vbSecond);
124
125 EXPECT_EQ (weakThird, vbStack.activeVertexBuffer ());
126
127 vbStack.popVertexBufferFromTop ();
128
129 EXPECT_EQ (weakFirst, vbStack.activeVertexBuffer ());
130}
131
132TEST_F (OpenGLVertexBufferStackTest, TestOneAndTwoOfTheSameRemovesLast)
133{
134 cgl::GLVertexBufferPtr vbFirst (boost::make_shared <GLVertexBuffer> ());
135 cgl::GLVertexBufferPtr vbSecond (boost::make_shared <GLVertexBuffer> ());
136 cgl::GLVertexBufferPtr vbThird (vbSecond);
137 cgl::GLVertexBufferPtr vbFourth (boost::make_shared <GLVertexBuffer> ());
138
139 cgl::GLVertexBufferWeak weakFirst (vbFirst);
140 cgl::GLVertexBufferWeak weakSecond (vbSecond);
141 cgl::GLVertexBufferWeak weakThird (vbThird);
142 cgl::GLVertexBufferWeak weakFourth (vbFourth);
143
144 vbStack.pushVertexBuffer (vbFirst);
145 vbStack.pushVertexBuffer (vbSecond);
146 vbStack.pushVertexBuffer (vbThird);
147 vbStack.pushVertexBuffer (vbFourth);
148
149 EXPECT_EQ (weakFourth, vbStack.activeVertexBuffer ());
150
151 vbStack.removeLastVertexBuffer (vbThird);
152
153 EXPECT_EQ (weakFourth, vbStack.activeVertexBuffer ());
154
155 vbStack.popVertexBufferFromTop ();
156
157 EXPECT_EQ (weakSecond, vbStack.activeVertexBuffer ());
158
159 vbStack.popVertexBufferFromTop ();
160
161 EXPECT_EQ (weakFirst, vbStack.activeVertexBuffer ());
162}
163
164TEST_F (OpenGLVertexBufferStackTest, TestPushTwoRemoveLastFirstIsActive)
165{
166 cgl::GLVertexBufferPtr vbFirst (boost::make_shared <GLVertexBuffer> ());
167 cgl::GLVertexBufferPtr vbSecond (boost::make_shared <GLVertexBuffer> ());
168
169 cgl::GLVertexBufferWeak weakFirst (vbFirst);
170 cgl::GLVertexBufferWeak weakSecond (vbSecond);
171
172 vbStack.pushVertexBuffer (vbFirst);
173 vbStack.pushVertexBuffer (vbSecond);
174
175 EXPECT_EQ (weakSecond, vbStack.activeVertexBuffer ());
176
177 vbStack.removeVertexBuffer (vbSecond);
178
179 EXPECT_EQ (weakFirst, vbStack.activeVertexBuffer ());
180
181 vbStack.popVertexBufferFromTop ();
182
183 EXPECT_THAT (vbStack.activeVertexBuffer (), IsExpired <GLVertexBuffer> ());
184}
185
186TEST_F (OpenGLVertexBufferStackTest, TestPushAndRemoveNoneActive)
187{
188 cgl::GLVertexBufferPtr vb (boost::make_shared <GLVertexBuffer> ());
189 cgl::GLVertexBufferWeak weak (vb);
190
191 vbStack.pushVertexBuffer (vb);
192 EXPECT_EQ (weak, vbStack.activeVertexBuffer ());
193 vbStack.removeVertexBuffer (vb);
194 EXPECT_THAT (vbStack.activeVertexBuffer (), IsExpired <GLVertexBuffer> ());
195}
196
197TEST_F (OpenGLVertexBufferStackTest, TestPushAndRemoveBothTheSameNoneActive)
198{
199 cgl::GLVertexBufferPtr vb (boost::make_shared <GLVertexBuffer> ());
200 cgl::GLVertexBufferPtr vbIdentical (vb);
201 cgl::GLVertexBufferWeak weak (vb);
202 cgl::GLVertexBufferWeak weakIdentical (weak);
203
204 vbStack.pushVertexBuffer (vb);
205 vbStack.pushVertexBuffer (vbIdentical);
206 EXPECT_EQ (weak, vbStack.activeVertexBuffer ());
207 vbStack.removeVertexBuffer (vb);
208 EXPECT_THAT (vbStack.activeVertexBuffer (), IsExpired <GLVertexBuffer> ());
209}
210
211TEST_F (OpenGLVertexBufferStackTest, TestPushAndRemoveNonPushedDoesNothing)
212{
213 cgl::GLVertexBufferPtr vb (boost::make_shared <GLVertexBuffer> ());
214 cgl::GLVertexBufferWeak weak (vb);
215 cgl::GLVertexBufferPtr nonExistant;
216
217 vbStack.pushVertexBuffer (vb);
218 EXPECT_EQ (weak, vbStack.activeVertexBuffer ());
219 vbStack.removeVertexBuffer (nonExistant);
220 EXPECT_EQ (weak, vbStack.activeVertexBuffer ());
221}
222
223TEST_F (OpenGLVertexBufferStackTest, TestVertexBufferPushObject)
224{
225 cgl::GLVertexBufferPtr vb (boost::make_shared <GLVertexBuffer> ());
226 cgl::GLVertexBufferWeak weak (vb);
227
228 {
229 cgl::VertexBufferPush pushedVertexBuffer (vbStack, vb);
230
231 EXPECT_EQ (vbStack.activeVertexBuffer (), weak);
232 }
233
234 EXPECT_THAT (vbStack.activeVertexBuffer (), IsExpired <GLVertexBuffer> ());
235}
236
237TEST_F (OpenGLVertexBufferStackTest, TestVertexBufferPushTwoIdenticalObjectOnlyRemovesOneEach)
238{
239 cgl::GLVertexBufferPtr vb (boost::make_shared <GLVertexBuffer> ());
240 cgl::GLVertexBufferPtr vbIdentical (vb);
241 cgl::GLVertexBufferWeak weak (vb);
242
243 {
244 cgl::VertexBufferPush pushedVertexBuffer (vbStack, vb);
245
246 {
247 cgl::VertexBufferPush pushedVertexBuffer (vbStack, vbIdentical);
248
249 EXPECT_EQ (vbStack.activeVertexBuffer (), weak);
250 }
251
252 EXPECT_EQ (vbStack.activeVertexBuffer (), weak);
253 }
254
255 EXPECT_THAT (vbStack.activeVertexBuffer (), IsExpired <GLVertexBuffer> ());
256}
0257
=== modified file 'plugins/opengl/src/window.cpp'
--- plugins/opengl/src/window.cpp 2012-08-14 06:33:22 +0000
+++ plugins/opengl/src/window.cpp 2012-09-09 16:26:19 +0000
@@ -24,9 +24,12 @@
24 * Authors: Dennis Kasprzyk <onestone@compiz-fusion.org>24 * Authors: Dennis Kasprzyk <onestone@compiz-fusion.org>
25 * David Reveman <davidr@novell.com>25 * David Reveman <davidr@novell.com>
26 */26 */
2727#include <boost/make_shared.hpp>
28#include "privates.h"28#include "privates.h"
2929
30namespace cgl = compiz::opengl;
31namespace cgli = compiz::opengl::impl;
32
30GLWindow::GLWindow (CompWindow *w) :33GLWindow::GLWindow (CompWindow *w) :
31 PluginClassHandler<GLWindow, CompWindow, COMPIZ_OPENGL_ABI> (w),34 PluginClassHandler<GLWindow, CompWindow, COMPIZ_OPENGL_ABI> (w),
32 priv (new PrivateGLWindow (w, this))35 priv (new PrivateGLWindow (w, this))
@@ -68,6 +71,36 @@
6871
69};72};
7073
74const cgl::GLVertexBufferWeak &
75PrivateGLWindow::activeVertexBuffer () const
76{
77 return vertexBufferStack.activeVertexBuffer ();
78}
79
80void
81PrivateGLWindow::pushVertexBuffer (const cgl::GLVertexBufferPtr &vertexBuffer)
82{
83 vertexBufferStack.pushVertexBuffer (vertexBuffer);
84}
85
86void
87PrivateGLWindow::popVertexBufferFromTop ()
88{
89 vertexBufferStack.popVertexBufferFromTop ();
90}
91
92bool
93PrivateGLWindow::removeVertexBuffer (const cgl::GLVertexBufferPtr &vertexBuffer)
94{
95 return vertexBufferStack.removeVertexBuffer (vertexBuffer);
96}
97
98bool
99PrivateGLWindow::removeLastVertexBuffer (const cgl::GLVertexBufferPtr &vertexBuffer)
100{
101 return vertexBufferStack.removeLastVertexBuffer (vertexBuffer);
102}
103
71PrivateGLWindow::PrivateGLWindow (CompWindow *w,104PrivateGLWindow::PrivateGLWindow (CompWindow *w,
72 GLWindow *gw) :105 GLWindow *gw) :
73 window (w),106 window (w),
@@ -79,11 +112,21 @@
79 updateState (UpdateRegion | UpdateMatrix),112 updateState (UpdateRegion | UpdateMatrix),
80 needsRebind (true),113 needsRebind (true),
81 clip (),114 clip (),
115 lastDamageRegion (),
116 vertexBufferDirty (false),
117 inGLDraw (false),
82 bindFailed (false),118 bindFailed (false),
83 vertexBuffer (new GLVertexBuffer ()),119 /* We are using GL_DYNAMIC_DRAW here as the vertex buffer contents
84 autoProgram(new GLWindowAutoProgram(this)),120 * will change across different regions of the screen being damaged,
121 * however if the same region of the screen is being damaged (video)
122 * this will yeild the best performance in that case */
123 windowVertexBuffer (new GLVertexBuffer (GL::DYNAMIC_DRAW)),
124 autoProgram (new GLWindowAutoProgram(this)),
85 icons ()125 icons ()
86{126{
127 windowVertexBuffer->setAutoProgram (autoProgram);
128 vertexBufferStack.pushVertexBuffer (windowVertexBuffer);
129
87 paint.xScale = 1.0f;130 paint.xScale = 1.0f;
88 paint.yScale = 1.0f;131 paint.yScale = 1.0f;
89 paint.xTranslate = 0.0f;132 paint.xTranslate = 0.0f;
@@ -92,14 +135,11 @@
92 WindowInterface::setHandler (w);135 WindowInterface::setHandler (w);
93 CompositeWindowInterface::setHandler (cWindow);136 CompositeWindowInterface::setHandler (cWindow);
94137
95 vertexBuffer->setAutoProgram(autoProgram);
96
97 cWindow->setNewPixmapReadyCallback (boost::bind (&PrivateGLWindow::clearTextures, this));138 cWindow->setNewPixmapReadyCallback (boost::bind (&PrivateGLWindow::clearTextures, this));
98}139}
99140
100PrivateGLWindow::~PrivateGLWindow ()141PrivateGLWindow::~PrivateGLWindow ()
101{142{
102 delete vertexBuffer;
103 delete autoProgram;143 delete autoProgram;
104 cWindow->setNewPixmapReadyCallback (boost::function <void ()> ());144 cWindow->setNewPixmapReadyCallback (boost::function <void ()> ());
105}145}
@@ -128,6 +168,18 @@
128 textures.clear ();168 textures.clear ();
129}169}
130170
171compiz::opengl::VertexBufferStack &
172GLWindow::vertexBufferStack ()
173{
174 return *priv;
175}
176
177compiz::gl::AutoProgram *
178GLWindow::autoProgram ()
179{
180 return priv->autoProgram;
181}
182
131bool183bool
132GLWindow::bind ()184GLWindow::bind ()
133{185{
@@ -287,7 +339,7 @@
287GLVertexBuffer *339GLVertexBuffer *
288GLWindow::vertexBuffer ()340GLWindow::vertexBuffer ()
289{341{
290 return priv->vertexBuffer;342 return priv->vertexBufferStack.activeVertexBuffer ().lock ().get ();
291}343}
292344
293const GLTexture::List &345const GLTexture::List &

Subscribers

People subscribed via source and target branches