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
=== modified file 'plugins/decor/src/decor.cpp'
--- plugins/decor/src/decor.cpp 2012-09-17 15:25:00 +0000
+++ plugins/decor/src/decor.cpp 2012-09-28 07:48:55 +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 {
@@ -3093,8 +3098,10 @@
3093 mClipGroup (NULL),3098 mClipGroup (NULL),
3094 mOutputRegion (window->outputRect ()),3099 mOutputRegion (window->outputRect ()),
3095 mInputRegion (window->inputRect ()),3100 mInputRegion (window->inputRect ()),
3096 mRequestor (screen->dpy (), w->id (), &decor)3101 mRequestor (screen->dpy (), w->id (), &decor),
3102 mDecorationVertexBuffer (new GLVertexBuffer (GL_STATIC_DRAW))
3097{3103{
3104 mDecorationVertexBuffer->setAutoProgram (gWindow->autoProgram ());
3098 WindowInterface::setHandler (window);3105 WindowInterface::setHandler (window);
30993106
3100 /* FIXME :DecorWindow::update can call updateWindowOutputExtents3107 /* FIXME :DecorWindow::update can call updateWindowOutputExtents
31013108
=== modified file 'plugins/decor/src/decor.h'
--- plugins/decor/src/decor.h 2012-09-07 22:37:20 +0000
+++ plugins/decor/src/decor.h 2012-09-28 07:48:55 +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-22 04:00:52 +0000
+++ plugins/opengl/CMakeLists.txt 2012-09-28 07:48:55 +0000
@@ -5,14 +5,27 @@
5set (INTERNAL_LIBRARIES5set (INTERNAL_LIBRARIES
6 compiz_opengl_double_buffer6 compiz_opengl_double_buffer
7 compiz_opengl_fsregion7 compiz_opengl_fsregion
8<<<<<<< TREE
8 compiz_opengl_glx_tfp_bind9 compiz_opengl_glx_tfp_bind
10=======
11 compiz_opengl_vertex_buffer_stack
12>>>>>>> MERGE-SOURCE
9)13)
1014
15set (COMPIZ_OPENGL_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
16set (COMPIZ_OPENGL_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
17
11add_subdirectory (src/doublebuffer)18add_subdirectory (src/doublebuffer)
12add_subdirectory (src/fsregion)19add_subdirectory (src/fsregion)
20<<<<<<< TREE
13add_subdirectory (src/glxtfpbind)21add_subdirectory (src/glxtfpbind)
1422
15include_directories (src/glxtfpbind/include)23include_directories (src/glxtfpbind/include)
24=======
25add_subdirectory (src/vertexbufferstack)
26
27include_directories (src/vertexbufferstack/include)
28>>>>>>> MERGE-SOURCE
1629
17if (USE_GLES)30if (USE_GLES)
18 compiz_plugin(opengl PLUGINDEPS composite CFLAGSADD "-DUSE_GLES -std=c++0x" LIBRARIES ${OPENGLES2_LIBRARIES} ${INTERNAL_LIBRARIES} dl INCDIRS ${OPENGLES2_INCLUDE_DIR})31 compiz_plugin(opengl PLUGINDEPS composite CFLAGSADD "-DUSE_GLES -std=c++0x" LIBRARIES ${OPENGLES2_LIBRARIES} ${INTERNAL_LIBRARIES} dl INCDIRS ${OPENGLES2_INCLUDE_DIR})
1932
=== modified file 'plugins/opengl/include/opengl/opengl.h'
--- plugins/opengl/include/opengl/opengl.h 2012-09-17 14:36:00 +0000
+++ plugins/opengl/include/opengl/opengl.h 2012-09-28 07:48:55 +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-28 07:48:55 +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-21 06:05:27 +0000
+++ plugins/opengl/src/paint.cpp 2012-09-28 07:48:55 +0000
@@ -37,13 +37,14 @@
37#define foreach BOOST_FOREACH37#define foreach BOOST_FOREACH
3838
39#include <opengl/opengl.h>39#include <opengl/opengl.h>
40#include <opengl/vertexbufferstack.h>
4041
41#include "privates.h"42#include "privates.h"
42#include "fsregion/fsregion.h"43#include "fsregion/fsregion.h"
4344
44#define DEG2RAD (M_PI / 180.0f)45#define DEG2RAD (M_PI / 180.0f)
4546
46using namespace compiz::opengl;47namespace cgl = compiz::opengl;
4748
48GLScreenPaintAttrib defaultScreenPaintAttrib = {49GLScreenPaintAttrib defaultScreenPaintAttrib = {
49 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -DEFAULT_Z_CAMERA50 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -DEFAULT_Z_CAMERA
@@ -276,7 +277,7 @@
276277
277 if (!(mask & PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK))278 if (!(mask & PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK))
278 {279 {
279 FullscreenRegion fs (*output);280 cgl::FullscreenRegion fs (*output);
280281
281 /* detect occlusions */282 /* detect occlusions */
282 for (rit = pl.rbegin (); rit != pl.rend (); ++rit)283 for (rit = pl.rbegin (); rit != pl.rend (); ++rit)
@@ -340,11 +341,11 @@
340 tmpRegion -= w->region ();341 tmpRegion -= w->region ();
341 }342 }
342343
343 FullscreenRegion::WinFlags flags = 0;344 cgl::FullscreenRegion::WinFlags flags = 0;
344 if (w->type () & CompWindowTypeDesktopMask)345 if (w->type () & CompWindowTypeDesktopMask)
345 flags |= FullscreenRegion::Desktop;346 flags |= cgl::FullscreenRegion::Desktop;
346 if (w->alpha ())347 if (w->alpha ())
347 flags |= FullscreenRegion::Alpha;348 flags |= cgl::FullscreenRegion::Alpha;
348 349
349 /*350 /*
350 * Windows with alpha channels can partially occlude windows351 * Windows with alpha channels can partially occlude windows
@@ -917,9 +918,16 @@
917{918{
918 WRAPABLE_HND_FUNCTN (glAddGeometry, matrix, region, clip)919 WRAPABLE_HND_FUNCTN (glAddGeometry, matrix, region, clip)
919920
921 boost::shared_ptr <GLVertexBuffer> activeVertexBuffer = priv->vertexBufferStack.activeVertexBuffer ().lock ();
922
920 BoxRec full;923 BoxRec full;
921 int nMatrix = matrix.size ();924 int nMatrix = matrix.size ();
922925
926 /* Someone is modifying our internal vertex buffer */
927 if (!priv->inGLDraw &&
928 activeVertexBuffer == priv->windowVertexBuffer)
929 priv->vertexBufferDirty = true;
930
923 full = clip.handle ()->extents;931 full = clip.handle ()->extents;
924 if (region.handle ()->extents.x1 > full.x1)932 if (region.handle ()->extents.x1 > full.x1)
925 full.x1 = region.handle ()->extents.x1;933 full.x1 = region.handle ()->extents.x1;
@@ -976,7 +984,7 @@
976984
977 if (nClip == 1)985 if (nClip == 1)
978 {986 {
979 addQuads (priv->vertexBuffer, matrix, nMatrix,987 addQuads (activeVertexBuffer.get (), matrix, nMatrix,
980 x1, y1, x2, y2,988 x1, y1, x2, y2,
981 rect,989 rect,
982 maxGridWidth, maxGridHeight);990 maxGridWidth, maxGridHeight);
@@ -1002,7 +1010,7 @@
10021010
1003 if (cbox.x1 < cbox.x2 && cbox.y1 < cbox.y2)1011 if (cbox.x1 < cbox.x2 && cbox.y1 < cbox.y2)
1004 {1012 {
1005 addQuads (priv->vertexBuffer, matrix, nMatrix,1013 addQuads (activeVertexBuffer.get (), matrix, nMatrix,
1006 cbox.x1, cbox.y1, cbox.x2, cbox.y2,1014 cbox.x1, cbox.y1, cbox.x2, cbox.y2,
1007 rect,1015 rect,
1008 maxGridWidth, maxGridHeight);1016 maxGridWidth, maxGridHeight);
@@ -1244,14 +1252,14 @@
1244 texture->enable (filter);1252 texture->enable (filter);
12451253
1246 #ifdef USE_GLES1254 #ifdef USE_GLES
1247 priv->vertexBuffer->render (transform, attrib);1255 priv->vertexBufferStack.activeVertexBuffer ().lock ()->render (transform, attrib);
1248 #else1256 #else
12491257
1250 if (!GLVertexBuffer::enabled ())1258 if (!GLVertexBuffer::enabled ())
1251 enableLegacyOBSAndRender (priv->gScreen, this, texture, transform,1259 enableLegacyOBSAndRender (priv->gScreen, this, texture, transform,
1252 attrib, filter, mask);1260 attrib, filter, mask);
1253 else1261 else
1254 priv->vertexBuffer->render (transform, attrib);1262 priv->vertexBufferStack.activeVertexBuffer ().lock ()->render (transform, attrib);
1255 #endif1263 #endif
12561264
1257 priv->shaders.clear ();1265 priv->shaders.clear ();
@@ -1270,9 +1278,22 @@
1270 WRAPABLE_HND_FUNCTN_RETURN (bool, glDraw, transform,1278 WRAPABLE_HND_FUNCTN_RETURN (bool, glDraw, transform,
1271 attrib, region, mask)1279 attrib, region, mask)
12721280
1281 const bool transformedWindow = mask & (PAINT_WINDOW_WITH_OFFSET_MASK |
1282 PAINT_WINDOW_TRANSFORMED_MASK);
1283 const bool damageRegionChanged = priv->lastDamageRegion != region;
1284 const bool internalMatricesChanged = priv->updateState & (PrivateGLWindow::UpdateMatrix |
1285 PrivateGLWindow::UpdateRegion);
1286 const bool readdGeometry = priv->vertexBufferDirty ||
1287 transformedWindow ||
1288 internalMatricesChanged ||
1289 damageRegionChanged;
1290
1273 const CompRegion &reg = (mask & PAINT_WINDOW_TRANSFORMED_MASK) ?1291 const CompRegion &reg = (mask & PAINT_WINDOW_TRANSFORMED_MASK) ?
1274 infiniteRegion : region;1292 infiniteRegion : region;
12751293
1294 if (readdGeometry)
1295 priv->lastDamageRegion = region;
1296
1276 if (reg.isEmpty ())1297 if (reg.isEmpty ())
1277 return true;1298 return true;
12781299
@@ -1304,10 +1325,23 @@
13041325
1305 for (unsigned int i = 0; i < priv->textures.size (); i++)1326 for (unsigned int i = 0; i < priv->textures.size (); i++)
1306 {1327 {
1307 ml[0] = priv->matrices[i];1328 cgl::VertexBufferStack &vbStack (priv->vertexBufferStack);
1308 priv->vertexBuffer->begin ();1329 cgl::VertexBufferPush push (vbStack,
1309 glAddGeometry (ml, priv->regions[i], reg);1330 priv->windowVertexBuffer);
1310 if (priv->vertexBuffer->end ())1331 cgl::GLVertexBufferPtr activeVertexBuffer = vbStack.activeVertexBuffer ().lock ();
1332
1333 if (readdGeometry || true)
1334 {
1335 priv->inGLDraw = true;
1336 ml[0] = priv->matrices[i];
1337 activeVertexBuffer->begin ();
1338 glAddGeometry (ml, priv->regions[i], reg);
1339 activeVertexBuffer->end ();
1340 priv->inGLDraw = false;
1341 priv->vertexBufferDirty = false;
1342 }
1343
1344 if (activeVertexBuffer->countVertices ())
1311 glDrawTexture (priv->textures[i], transform, attrib, mask);1345 glDrawTexture (priv->textures[i], transform, attrib, mask);
1312 }1346 }
13131347
13141348
=== modified file 'plugins/opengl/src/privates.h'
--- plugins/opengl/src/privates.h 2012-09-25 10:47:39 +0000
+++ plugins/opengl/src/privates.h 2012-09-28 07:48:55 +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;
@@ -218,7 +222,8 @@
218222
219class PrivateGLWindow :223class PrivateGLWindow :
220 public WindowInterface,224 public WindowInterface,
221 public CompositeWindowInterface225 public CompositeWindowInterface,
226 public compiz::opengl::VertexBufferStack
222{227{
223 public:228 public:
224229
@@ -251,6 +256,9 @@
251 bool needsRebind;256 bool needsRebind;
252257
253 CompRegion clip;258 CompRegion clip;
259 CompRegion lastDamageRegion;
260 bool vertexBufferDirty;
261 bool inGLDraw;
254262
255 bool bindFailed;263 bool bindFailed;
256 bool overlayWindow;264 bool overlayWindow;
@@ -264,7 +272,8 @@
264272
265 unsigned int lastMask;273 unsigned int lastMask;
266274
267 GLVertexBuffer *vertexBuffer;275 compiz::opengl::impl::VertexBufferStack vertexBufferStack;
276 compiz::opengl::GLVertexBufferPtr windowVertexBuffer;
268277
269 // map of shaders, plugin name is key, pair of vertex and fragment278 // map of shaders, plugin name is key, pair of vertex and fragment
270 // shader source code is value279 // shader source code is value
@@ -272,6 +281,15 @@
272 GLVertexBuffer::AutoProgram *autoProgram;281 GLVertexBuffer::AutoProgram *autoProgram;
273282
274 std::list<GLIcon> icons;283 std::list<GLIcon> icons;
284
285 private:
286
287 /* Implementation of compiz::opengl::VertexBufferStack */
288 void pushVertexBuffer (const compiz::opengl::GLVertexBufferPtr &);
289 void popVertexBufferFromTop ();
290 bool removeVertexBuffer (const compiz::opengl::GLVertexBufferPtr &);
291 bool removeLastVertexBuffer (const compiz::opengl::GLVertexBufferPtr &);
292 const compiz::opengl::GLVertexBufferWeak & activeVertexBuffer () const;
275};293};
276294
277#endif295#endif
278296
=== 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-28 07:48:55 +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-28 07:48:55 +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-28 07:48:55 +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-28 07:48:55 +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-28 07:48:55 +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-28 07:48:55 +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