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
1=== modified file 'plugins/compiztoolbox/src/compiztoolbox.cpp'
2--- plugins/compiztoolbox/src/compiztoolbox.cpp 2012-07-27 09:57:26 +0000
3+++ plugins/compiztoolbox/src/compiztoolbox.cpp 2012-07-27 13:25:23 +0000
4@@ -536,18 +536,15 @@
5
6 gWindow->vertexBuffer ()->end ();
7
8- if (gWindow->vertexBuffer ()->countVertices ())
9- {
10- GLMatrix wTransform (transform);
11-
12- wTransform.translate (g.x (), g.y (), 0.0f);
13- wTransform.scale (sAttrib.xScale, sAttrib.yScale, 1.0f);
14- wTransform.translate (sAttrib.xTranslate / sAttrib.xScale - g.x (),
15- sAttrib.yTranslate / sAttrib.yScale - g.y (),
16- 0.0f);
17-
18- gWindow->glDrawTexture (icon, wTransform, sAttrib, mask);
19- }
20+ GLMatrix wTransform (transform);
21+
22+ wTransform.translate (g.x (), g.y (), 0.0f);
23+ wTransform.scale (sAttrib.xScale, sAttrib.yScale, 1.0f);
24+ wTransform.translate (sAttrib.xTranslate / sAttrib.xScale - g.x (),
25+ sAttrib.yTranslate / sAttrib.yScale - g.y (),
26+ 0.0f);
27+
28+ gWindow->glDrawTexture (icon, wTransform, sAttrib, mask);
29 }
30 }
31
32
33=== modified file 'plugins/decor/src/decor.cpp'
34--- plugins/decor/src/decor.cpp 2012-07-27 09:57:26 +0000
35+++ plugins/decor/src/decor.cpp 2012-07-27 13:25:23 +0000
36@@ -264,13 +264,10 @@
37
38 gWindow->vertexBuffer ()->end ();
39
40- if (gWindow->vertexBuffer ()->countVertices ())
41- {
42- glEnable (GL_BLEND);
43- gWindow->glDrawTexture (wd->decor->texture->textures[0], transform,
44- attrib, mask);
45- glDisable (GL_BLEND);
46- }
47+ glEnable (GL_BLEND);
48+ gWindow->glDrawTexture (wd->decor->texture->textures[0], transform,
49+ attrib, mask);
50+ glDisable (GL_BLEND);
51 }
52 else if (wd && wd->decor->type == WINDOW_DECORATION_TYPE_WINDOW)
53 {
54@@ -293,9 +290,8 @@
55 gWindow->glAddGeometry (ml, window->frameRegion (), region);
56 gWindow->vertexBuffer ()->end ();
57
58- if (gWindow->vertexBuffer ()->countVertices ())
59- gWindow->glDrawTexture (gWindow->textures ()[0], transform,
60- attrib, mask);
61+ gWindow->glDrawTexture (gWindow->textures ()[0], transform,
62+ attrib, mask);
63 }
64 else
65 {
66@@ -308,9 +304,8 @@
67 gWindow->glAddGeometry (ml, regions[i], region);
68 gWindow->vertexBuffer ()->end ();
69
70- if (gWindow->vertexBuffer ()->countVertices ())
71- gWindow->glDrawTexture (gWindow->textures ()[i], transform,
72- attrib, mask);
73+ gWindow->glDrawTexture (gWindow->textures ()[i], transform,
74+ attrib, mask);
75 }
76 }
77
78
79=== modified file 'plugins/opengl/src/paint.cpp'
80--- plugins/opengl/src/paint.cpp 2012-07-27 11:06:51 +0000
81+++ plugins/opengl/src/paint.cpp 2012-07-27 13:25:23 +0000
82@@ -1217,6 +1217,9 @@
83
84 GLTexture::Filter filter;
85
86+ if (!priv->vertexBuffer->countVertices ())
87+ return;
88+
89 if (mask & PAINT_WINDOW_BLEND_MASK)
90 glEnable (GL_BLEND);
91
92@@ -1295,8 +1298,7 @@
93 glAddGeometry (ml, priv->regions[i], reg);
94 priv->vertexBuffer->end ();
95
96- if (priv->vertexBuffer->countVertices())
97- glDrawTexture (priv->textures[i], transform, attrib, mask);
98+ glDrawTexture (priv->textures[i], transform, attrib, mask);
99 }
100
101 return true;
102
103=== modified file 'plugins/ring/src/ring.cpp'
104--- plugins/ring/src/ring.cpp 2012-07-27 09:57:26 +0000
105+++ plugins/ring/src/ring.cpp 2012-07-27 13:25:23 +0000
106@@ -375,26 +375,23 @@
107 gWindow->glAddGeometry (matricies, iconReg, iconReg);
108 gWindow->vertexBuffer ()->end ();
109
110- if (gWindow->vertexBuffer ()->countVertices ())
111- {
112- GLWindowPaintAttrib wAttrib (sAttrib);
113- GLMatrix wTransform = transform;
114-
115- if (!pixmap)
116- sAttrib.opacity = gWindow->paintAttrib ().opacity;
117-
118- if (mSlot)
119- wAttrib.brightness = (float)wAttrib.brightness *
120- mSlot->depthBrightness;
121-
122- wTransform.translate (window->x (), window->y (), 0.0f);
123- wTransform.scale (scale, scale, 1.0f);
124- wTransform.translate ((x - window->x ()) / scale - window->x (),
125- (y - window->y ()) / scale - window->y (),
126- 0.0f);
127-
128- gWindow->glDrawTexture (icon, wTransform, wAttrib, mask);
129- }
130+ GLWindowPaintAttrib wAttrib (sAttrib);
131+ GLMatrix wTransform = transform;
132+
133+ if (!pixmap)
134+ sAttrib.opacity = gWindow->paintAttrib ().opacity;
135+
136+ if (mSlot)
137+ wAttrib.brightness = (float)wAttrib.brightness *
138+ mSlot->depthBrightness;
139+
140+ wTransform.translate (window->x (), window->y (), 0.0f);
141+ wTransform.scale (scale, scale, 1.0f);
142+ wTransform.translate ((x - window->x ()) / scale - window->x (),
143+ (y - window->y ()) / scale - window->y (),
144+ 0.0f);
145+
146+ gWindow->glDrawTexture (icon, wTransform, wAttrib, mask);
147 }
148 }
149 }
150
151=== modified file 'plugins/scale/src/scale.cpp'
152--- plugins/scale/src/scale.cpp 2012-07-27 09:57:26 +0000
153+++ plugins/scale/src/scale.cpp 2012-07-27 13:25:23 +0000
154@@ -233,15 +233,12 @@
155
156 priv->gWindow->vertexBuffer ()->end ();
157
158- if (priv->gWindow->vertexBuffer ()->countVertices ())
159- {
160- GLMatrix wTransform (transform);
161-
162- wTransform.scale (scale, scale, 1.0f);
163- wTransform.translate (x / scale, y / scale, 0.0f);
164-
165- priv->gWindow->glDrawTexture (icon, wTransform, sAttrib, mask);
166- }
167+ GLMatrix wTransform (transform);
168+
169+ wTransform.scale (scale, scale, 1.0f);
170+ wTransform.translate (x / scale, y / scale, 0.0f);
171+
172+ priv->gWindow->glDrawTexture (icon, wTransform, sAttrib, mask);
173 }
174 }
175 }
176
177=== modified file 'plugins/shift/src/shift.cpp'
178--- plugins/shift/src/shift.cpp 2012-07-27 09:57:26 +0000
179+++ plugins/shift/src/shift.cpp 2012-07-27 13:25:23 +0000
180@@ -421,45 +421,42 @@
181
182 gWindow->vertexBuffer ()->end ();
183
184- if (gWindow->vertexBuffer ()->countVertices ())
185- {
186- GLWindowPaintAttrib wAttrib (sAttrib);
187- GLMatrix wTransform (transform);
188-
189- if (gWindow->textures ().empty ())
190- sAttrib.opacity = gWindow->paintAttrib ().opacity;
191-
192- wAttrib = GLWindowPaintAttrib (sAttrib);
193-
194- wAttrib.opacity = (float)wAttrib.opacity * sopacity;
195- wAttrib.brightness = (float)wAttrib.brightness *
196- ss->mReflectBrightness;
197-
198- wTransform.translate (sx, sy, sz);
199-
200- wTransform.translate (window->x () +
201- (window->width () * sscale / 2),
202- window->y () +
203- (window->height () * sscale / 2.0),
204- 0.0f);
205-
206- wTransform.scale (ss->mOutput->width (),
207- -ss->mOutput->height (),
208- 1.0f);
209-
210- wTransform.rotate (srot, 0.0, 1.0, 0.0);
211-
212- wTransform.scale (1.0f / ss->mOutput->width (),
213- -1.0f / ss->mOutput->height (),
214- 1.0f);
215-
216- wTransform.translate (x - (window->width () * sscale / 2),
217- y - (window->height () * sscale / 2.0),
218- 0.0f);
219- wTransform.scale (scale, scale, 1.0f);
220-
221- gWindow->glDrawTexture (icon, wTransform, wAttrib, mask);
222- }
223+ GLWindowPaintAttrib wAttrib (sAttrib);
224+ GLMatrix wTransform (transform);
225+
226+ if (gWindow->textures ().empty ())
227+ sAttrib.opacity = gWindow->paintAttrib ().opacity;
228+
229+ wAttrib = GLWindowPaintAttrib (sAttrib);
230+
231+ wAttrib.opacity = (float)wAttrib.opacity * sopacity;
232+ wAttrib.brightness = (float)wAttrib.brightness *
233+ ss->mReflectBrightness;
234+
235+ wTransform.translate (sx, sy, sz);
236+
237+ wTransform.translate (window->x () +
238+ (window->width () * sscale / 2),
239+ window->y () +
240+ (window->height () * sscale / 2.0),
241+ 0.0f);
242+
243+ wTransform.scale (ss->mOutput->width (),
244+ -ss->mOutput->height (),
245+ 1.0f);
246+
247+ wTransform.rotate (srot, 0.0, 1.0, 0.0);
248+
249+ wTransform.scale (1.0f / ss->mOutput->width (),
250+ -1.0f / ss->mOutput->height (),
251+ 1.0f);
252+
253+ wTransform.translate (x - (window->width () * sscale / 2),
254+ y - (window->height () * sscale / 2.0),
255+ 0.0f);
256+ wTransform.scale (scale, scale, 1.0f);
257+
258+ gWindow->glDrawTexture (icon, wTransform, wAttrib, mask);
259 }
260 }
261 }

Subscribers

People subscribed via source and target branches