Merge lp:~compiz-team/compiz/gles2.scope_of_empty_vb_check into lp:~compiz-linaro-team/compiz/gles2

Proposed by Sam Spilsbury
Status: Superseded
Proposed branch: lp:~compiz-team/compiz/gles2.scope_of_empty_vb_check
Merge into: lp:~compiz-linaro-team/compiz/gles2
Diff against target: 261 lines (+80/-95)
6 files modified
plugins/compiztoolbox/src/compiztoolbox.cpp (+9/-12)
plugins/decor/src/decor.cpp (+8/-13)
plugins/opengl/src/paint.cpp (+4/-2)
plugins/ring/src/ring.cpp (+17/-20)
plugins/scale/src/scale.cpp (+6/-9)
plugins/shift/src/shift.cpp (+36/-39)
To merge this branch: bzr merge lp:~compiz-team/compiz/gles2.scope_of_empty_vb_check
Reviewer Review Type Date Requested Status
Daniel van Vugt Needs Fixing
Review via email: mp+117058@code.launchpad.net

This proposal has been superseded by a proposal from 2012-08-08.

Commit message

Make checking to see if the vertex buffer is empty the responsibility of
GLWindow::glDraw and not the clients of that function.

While this is technically slower (incurred wrapped function overhead), it
is better encapsulation, since clients of glDraw less are coupled with the
implementation of glDraw.

Description of the change

Put the check for an empty vertex buffer inside of glDraw.

The more expensive part of calling glDraw so much is the associated calls to glDrawArrays with an empty buffer - we can effectively cull out this part by putting the check for an empty buffer inside of glDrawTexture. This decouples the "necessary optimization" from the clients of glDrawTexture.

While this is technically more expensive due to the extra wrapped function call overhead, most of that is mitigated by plugins doing the Right Thing [tm] and not registering a wrapped function for glDrawTexture.

I compared benchmarks through manual testing and there wasn't any noticable impact.

To post a comment you must log in.
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

There are still a lot of calculations we wish to avoid if number of vertices is zero. So I'd like to keep the if statements:
  if (gWindow->vertexBuffer ()->countVertices ()) { /* stuff to avoid */ }

I think we just want the 2-line check added to glDrawTexture. It's redundant but an extra layer of performance-safety.

So keep lines 86-87 and drop everything else?

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

I feel like in that case this abstraction is totally wrong. The clients shouldn't be dependent upon the implementation detail of GLVertexBuffer. Perhaps GLVertexBuffer::end should return the number of vertices added?

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

I was thinking along the same lines recently. Maybe end() should return a bool indicating whether you can or should render().

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

On Wed, 8 Aug 2012, Daniel van Vugt wrote:

> I was thinking along the same lines recently. Maybe end() should return a bool indicating whether you can or should render().

Okay, how about this:

1) end () returns a bool which is essentially just countVertices () > 0
2) We add a new method to GLWindow called regenerateVertices (same
signature as glAddGeometry)) which
returns bool. This calls its internal GLVertexBuffer::begin (),
glAddGeometry () and GLVertexBuffer::end () and returns the result.

This would put the current code in line with the law-of-demeter.

Thoughts?

> --
> https://code.launchpad.net/~compiz-team/compiz/gles2.scope_of_empty_vb_check/+merge/117058
> Your team Compiz Maintainers is subscribed to branch lp:~compiz-team/compiz/gles2.scope_of_empty_vb_check.
>

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

I don't understand #2. What's regenerateVertices for?

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

The problem is that the clients know too much about GLWindow (eg, that it has a vertex buffer) and furthermore, they are free to manipulate this internal state. It would be far simpler, and far less repetitious if we just had this:

void
GLWindow::clearVertices ()
{
    priv->vertexBuffer->begin ();
}

bool
GLWindow::saveVertices ()
{
    return priv->vertexBuffer->end ();
}

(in usage)

gWindow->clearVertices ();
gWindow->glAddGeometry (...);
if (gWindow->saveVertices ())
    gWindow->glDrawTexture (...);

Turns out we can't have a single wrapper method like I first thought, as multiple calls to glAddGeometry are permissible.

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

Nice idea, but you'd still end up with lots of ugly plugin code which does:

gWindow->clearVertices();
gWindow->vertexBuffer()->blah();
gWindow->vertexBuffer()->blah2();
gWindow->vertexBuffer()->blah3();
gWindow->saveVertices();

We cannot get away from the fact that plugins need direct access to a GLVertexBuffer; GLWindow::vertexBuffer(). In the same way that they use GLWindow::Geometry on trunk; GLWindow::geometry().

However this is not really an issue at all. If you want the plugin code to be nicer, just write it nicer:

GLVertexBuffer *vb = gWindow->vertexBuffer();
vb->begin();
vb->blah();
vb->blah2();
vb->blah3();
vb->end();

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

On Wed, 8 Aug 2012, Daniel van Vugt wrote:

> Nice idea, but you'd still end up with lots of ugly plugin code which does:
>
> gWindow->clearVertices();
> gWindow->vertexBuffer()->blah();
> gWindow->vertexBuffer()->blah2();
> gWindow->vertexBuffer()->blah3();
> gWindow->saveVertices();
>
> We cannot get away from the fact that plugins need direct access to a GLVertexBuffer; GLWindow::vertexBuffer(). In the same way that they use GLWindow::Geometry on trunk; GLWindow::geometry().
>
> However this is not really an issue at all. If you want the plugin code to be nicer, just write it nicer:
>
> GLVertexBuffer *vb = gWindow->vertexBuffer();
> vb->begin();
> vb->blah();
> vb->blah2();
> vb->blah3();
> vb->end();
>

In fact, I checked the code and the main reason why the plugins are using
gWindow->vertexBuffer () are to call begin () and end (). The only other
place where it is used otherwise are in the plugin glAddGeometry calls.

I'd like to remove it entirely, so I think what might be better is is
plugins call this:

void
GLWindow::addNewGeometry (... (same as glAddGeometry))
{
     glAddGeometry (priv->vertexBuffer, ...);
}

That way, the plugins that do need to add stuff to the vertex buffer get a
pointer to it when they need to do it. In all other instances the vertex
buffer is effectively protected (as it should be).

Thoughts?

> --
> https://code.launchpad.net/~compiz-team/compiz/gles2.scope_of_empty_vb_check/+merge/117058
> Your team Compiz Maintainers is subscribed to branch lp:~compiz-team/compiz/gles2.scope_of_empty_vb_check.
>

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

I like information hiding, but still suspect you will encounter lots of plugins where it won't work. Unless you expose the whole GLVertexBuffer interface through GLWindow, but that's just nasty.

If you have an idea for improving information hiding, test that it works and then propose it. So long as we don't have to touch vast amounts of plugin code...

As for now, I'll just do the "end() returns bool" thing.

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

On Wed, 8 Aug 2012, Daniel van Vugt wrote:

> I like information hiding, but still suspect you will encounter lots of plugins where it won't work. Unless you expose the whole GLVertexBuffer interface through GLWindow, but that's just nasty.
>
> If you have an idea for improving information hiding, test that it works and then propose it. So long as we don't have to touch vast amounts of plugin code...
>
> As for now, I'll just do the "end() returns bool" thing.

Okay, I only have to touch two plugins and its very noninvasive. I will
propose it in the next few minutes

> --
> https://code.launchpad.net/~compiz-team/compiz/gles2.scope_of_empty_vb_check/+merge/117058
> Your team Compiz Maintainers is subscribed to branch lp:~compiz-team/compiz/gles2.scope_of_empty_vb_check.
>

Unmerged revisions

3300. By Sam Spilsbury

Make checking to see if the vertex buffer is empty the responsibility of
GLWindow::glDraw and not the clients of that function.

While this is technically slower (incurred wrapped function overhead), it
is better encapsulation, since clients of glDraw less coupled with the
implementation of glDraw.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'plugins/compiztoolbox/src/compiztoolbox.cpp'
--- plugins/compiztoolbox/src/compiztoolbox.cpp 2012-07-27 09:57:26 +0000
+++ plugins/compiztoolbox/src/compiztoolbox.cpp 2012-07-27 13:25:23 +0000
@@ -536,18 +536,15 @@
536536
537 gWindow->vertexBuffer ()->end ();537 gWindow->vertexBuffer ()->end ();
538538
539 if (gWindow->vertexBuffer ()->countVertices ())539 GLMatrix wTransform (transform);
540 {540
541 GLMatrix wTransform (transform);541 wTransform.translate (g.x (), g.y (), 0.0f);
542542 wTransform.scale (sAttrib.xScale, sAttrib.yScale, 1.0f);
543 wTransform.translate (g.x (), g.y (), 0.0f);543 wTransform.translate (sAttrib.xTranslate / sAttrib.xScale - g.x (),
544 wTransform.scale (sAttrib.xScale, sAttrib.yScale, 1.0f);544 sAttrib.yTranslate / sAttrib.yScale - g.y (),
545 wTransform.translate (sAttrib.xTranslate / sAttrib.xScale - g.x (),545 0.0f);
546 sAttrib.yTranslate / sAttrib.yScale - g.y (),546
547 0.0f);547 gWindow->glDrawTexture (icon, wTransform, sAttrib, mask);
548
549 gWindow->glDrawTexture (icon, wTransform, sAttrib, mask);
550 }
551 }548 }
552}549}
553550
554551
=== modified file 'plugins/decor/src/decor.cpp'
--- plugins/decor/src/decor.cpp 2012-07-27 09:57:26 +0000
+++ plugins/decor/src/decor.cpp 2012-07-27 13:25:23 +0000
@@ -264,13 +264,10 @@
264264
265 gWindow->vertexBuffer ()->end ();265 gWindow->vertexBuffer ()->end ();
266266
267 if (gWindow->vertexBuffer ()->countVertices ())267 glEnable (GL_BLEND);
268 {268 gWindow->glDrawTexture (wd->decor->texture->textures[0], transform,
269 glEnable (GL_BLEND);269 attrib, mask);
270 gWindow->glDrawTexture (wd->decor->texture->textures[0], transform,270 glDisable (GL_BLEND);
271 attrib, mask);
272 glDisable (GL_BLEND);
273 }
274 }271 }
275 else if (wd && wd->decor->type == WINDOW_DECORATION_TYPE_WINDOW)272 else if (wd && wd->decor->type == WINDOW_DECORATION_TYPE_WINDOW)
276 {273 {
@@ -293,9 +290,8 @@
293 gWindow->glAddGeometry (ml, window->frameRegion (), region);290 gWindow->glAddGeometry (ml, window->frameRegion (), region);
294 gWindow->vertexBuffer ()->end ();291 gWindow->vertexBuffer ()->end ();
295292
296 if (gWindow->vertexBuffer ()->countVertices ())293 gWindow->glDrawTexture (gWindow->textures ()[0], transform,
297 gWindow->glDrawTexture (gWindow->textures ()[0], transform,294 attrib, mask);
298 attrib, mask);
299 }295 }
300 else296 else
301 {297 {
@@ -308,9 +304,8 @@
308 gWindow->glAddGeometry (ml, regions[i], region);304 gWindow->glAddGeometry (ml, regions[i], region);
309 gWindow->vertexBuffer ()->end ();305 gWindow->vertexBuffer ()->end ();
310306
311 if (gWindow->vertexBuffer ()->countVertices ())307 gWindow->glDrawTexture (gWindow->textures ()[i], transform,
312 gWindow->glDrawTexture (gWindow->textures ()[i], transform,308 attrib, mask);
313 attrib, mask);
314 }309 }
315 }310 }
316311
317312
=== modified file 'plugins/opengl/src/paint.cpp'
--- plugins/opengl/src/paint.cpp 2012-07-27 11:06:51 +0000
+++ plugins/opengl/src/paint.cpp 2012-07-27 13:25:23 +0000
@@ -1217,6 +1217,9 @@
12171217
1218 GLTexture::Filter filter;1218 GLTexture::Filter filter;
12191219
1220 if (!priv->vertexBuffer->countVertices ())
1221 return;
1222
1220 if (mask & PAINT_WINDOW_BLEND_MASK)1223 if (mask & PAINT_WINDOW_BLEND_MASK)
1221 glEnable (GL_BLEND);1224 glEnable (GL_BLEND);
12221225
@@ -1295,8 +1298,7 @@
1295 glAddGeometry (ml, priv->regions[i], reg);1298 glAddGeometry (ml, priv->regions[i], reg);
1296 priv->vertexBuffer->end ();1299 priv->vertexBuffer->end ();
12971300
1298 if (priv->vertexBuffer->countVertices())1301 glDrawTexture (priv->textures[i], transform, attrib, mask);
1299 glDrawTexture (priv->textures[i], transform, attrib, mask);
1300 }1302 }
13011303
1302 return true;1304 return true;
13031305
=== modified file 'plugins/ring/src/ring.cpp'
--- plugins/ring/src/ring.cpp 2012-07-27 09:57:26 +0000
+++ plugins/ring/src/ring.cpp 2012-07-27 13:25:23 +0000
@@ -375,26 +375,23 @@
375 gWindow->glAddGeometry (matricies, iconReg, iconReg);375 gWindow->glAddGeometry (matricies, iconReg, iconReg);
376 gWindow->vertexBuffer ()->end ();376 gWindow->vertexBuffer ()->end ();
377377
378 if (gWindow->vertexBuffer ()->countVertices ())378 GLWindowPaintAttrib wAttrib (sAttrib);
379 {379 GLMatrix wTransform = transform;
380 GLWindowPaintAttrib wAttrib (sAttrib);380
381 GLMatrix wTransform = transform;381 if (!pixmap)
382382 sAttrib.opacity = gWindow->paintAttrib ().opacity;
383 if (!pixmap)383
384 sAttrib.opacity = gWindow->paintAttrib ().opacity;384 if (mSlot)
385385 wAttrib.brightness = (float)wAttrib.brightness *
386 if (mSlot)386 mSlot->depthBrightness;
387 wAttrib.brightness = (float)wAttrib.brightness *387
388 mSlot->depthBrightness;388 wTransform.translate (window->x (), window->y (), 0.0f);
389389 wTransform.scale (scale, scale, 1.0f);
390 wTransform.translate (window->x (), window->y (), 0.0f);390 wTransform.translate ((x - window->x ()) / scale - window->x (),
391 wTransform.scale (scale, scale, 1.0f);391 (y - window->y ()) / scale - window->y (),
392 wTransform.translate ((x - window->x ()) / scale - window->x (),392 0.0f);
393 (y - window->y ()) / scale - window->y (),393
394 0.0f);394 gWindow->glDrawTexture (icon, wTransform, wAttrib, mask);
395
396 gWindow->glDrawTexture (icon, wTransform, wAttrib, mask);
397 }
398 }395 }
399 }396 }
400 }397 }
401398
=== modified file 'plugins/scale/src/scale.cpp'
--- plugins/scale/src/scale.cpp 2012-07-27 09:57:26 +0000
+++ plugins/scale/src/scale.cpp 2012-07-27 13:25:23 +0000
@@ -233,15 +233,12 @@
233233
234 priv->gWindow->vertexBuffer ()->end ();234 priv->gWindow->vertexBuffer ()->end ();
235235
236 if (priv->gWindow->vertexBuffer ()->countVertices ())236 GLMatrix wTransform (transform);
237 {237
238 GLMatrix wTransform (transform);238 wTransform.scale (scale, scale, 1.0f);
239239 wTransform.translate (x / scale, y / scale, 0.0f);
240 wTransform.scale (scale, scale, 1.0f);240
241 wTransform.translate (x / scale, y / scale, 0.0f);241 priv->gWindow->glDrawTexture (icon, wTransform, sAttrib, mask);
242
243 priv->gWindow->glDrawTexture (icon, wTransform, sAttrib, mask);
244 }
245 }242 }
246 }243 }
247}244}
248245
=== modified file 'plugins/shift/src/shift.cpp'
--- plugins/shift/src/shift.cpp 2012-07-27 09:57:26 +0000
+++ plugins/shift/src/shift.cpp 2012-07-27 13:25:23 +0000
@@ -421,45 +421,42 @@
421421
422 gWindow->vertexBuffer ()->end ();422 gWindow->vertexBuffer ()->end ();
423423
424 if (gWindow->vertexBuffer ()->countVertices ())424 GLWindowPaintAttrib wAttrib (sAttrib);
425 {425 GLMatrix wTransform (transform);
426 GLWindowPaintAttrib wAttrib (sAttrib);426
427 GLMatrix wTransform (transform);427 if (gWindow->textures ().empty ())
428428 sAttrib.opacity = gWindow->paintAttrib ().opacity;
429 if (gWindow->textures ().empty ())429
430 sAttrib.opacity = gWindow->paintAttrib ().opacity;430 wAttrib = GLWindowPaintAttrib (sAttrib);
431431
432 wAttrib = GLWindowPaintAttrib (sAttrib);432 wAttrib.opacity = (float)wAttrib.opacity * sopacity;
433433 wAttrib.brightness = (float)wAttrib.brightness *
434 wAttrib.opacity = (float)wAttrib.opacity * sopacity;434 ss->mReflectBrightness;
435 wAttrib.brightness = (float)wAttrib.brightness *435
436 ss->mReflectBrightness;436 wTransform.translate (sx, sy, sz);
437437
438 wTransform.translate (sx, sy, sz);438 wTransform.translate (window->x () +
439439 (window->width () * sscale / 2),
440 wTransform.translate (window->x () +440 window->y () +
441 (window->width () * sscale / 2),441 (window->height () * sscale / 2.0),
442 window->y () +442 0.0f);
443 (window->height () * sscale / 2.0),443
444 0.0f);444 wTransform.scale (ss->mOutput->width (),
445445 -ss->mOutput->height (),
446 wTransform.scale (ss->mOutput->width (),446 1.0f);
447 -ss->mOutput->height (),447
448 1.0f);448 wTransform.rotate (srot, 0.0, 1.0, 0.0);
449449
450 wTransform.rotate (srot, 0.0, 1.0, 0.0);450 wTransform.scale (1.0f / ss->mOutput->width (),
451451 -1.0f / ss->mOutput->height (),
452 wTransform.scale (1.0f / ss->mOutput->width (),452 1.0f);
453 -1.0f / ss->mOutput->height (),453
454 1.0f);454 wTransform.translate (x - (window->width () * sscale / 2),
455455 y - (window->height () * sscale / 2.0),
456 wTransform.translate (x - (window->width () * sscale / 2),456 0.0f);
457 y - (window->height () * sscale / 2.0),457 wTransform.scale (scale, scale, 1.0f);
458 0.0f);458
459 wTransform.scale (scale, scale, 1.0f);459 gWindow->glDrawTexture (icon, wTransform, wAttrib, mask);
460
461 gWindow->glDrawTexture (icon, wTransform, wAttrib, mask);
462 }
463 }460 }
464 }461 }
465 }462 }

Subscribers

People subscribed via source and target branches