Mir

Merge lp:~afrantzis/mir/fix-1234563 into lp:mir

Proposed by Alexandros Frantzis
Status: Merged
Approved by: Daniel van Vugt
Approved revision: no longer in the source branch.
Merged at revision: 1173
Proposed branch: lp:~afrantzis/mir/fix-1234563
Merge into: lp:mir
Diff against target: 103 lines (+59/-5)
1 file modified
examples/image_renderer.cpp (+59/-5)
To merge this branch: bzr merge lp:~afrantzis/mir/fix-1234563
Reviewer Review Type Date Requested Status
Daniel van Vugt Approve
Alan Griffiths Needs Fixing
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+192509@code.launchpad.net

Commit message

examples: Restore GL state after initializing buffers, fixing crashes
observed in render_surfaces (LP: #1234563)

Due to the lazy allocation of buffers on the server, buffer
allocation and initialization may occur while the renderer
has already set up its GL state. Ensure that we don't
change the renderer's state when initializing buffers.

Description of the change

examples: Restore GL state after initializing buffers

Due to the lazy allocation of buffers on the server, buffer allocation and initialization may occur while the renderer has already set up its GL state. Ensure that we don't change the renderer's state when initializing buffers.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Could this fix bug 1211699 too?

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

I feel the new GLState class is acting by side-effect in restoring state on destruction. The GL state is a very important and far-reaching set of globals, effectively. So rather than implicitly modify globals by RAII, it should be explicit. I think GLState should use methods: save(), restore()

If only OpenGL|ES didn't drop push/pop operations we could use with OpenGL :/

review: Needs Fixing
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

The copy semantics of GLState are probably inappropriate and unnecessary while the name doesn't really suggest the preserving role. Maybe "StoreGLState"?

Also, I think the use of forwarding constructors would be simpler the other way around. Vis:

GLState()
{
    glGetIntegerv(GL_CURRENT_PROGRAM, &program);
    glGetIntegerv(GL_TEXTURE_BINDING_2D, &texture);
    glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &buffer);
    glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture_unit);
}

GLState(GLint attrib_loc) : GLState()
{
    this->attrib_loc = attrib_loc

    if (attrib_loc >= 0)
    {
        glGetVertexAttribiv(attrib_loc, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &attrib_enabled);
        glGetVertexAttribiv(attrib_loc, GL_VERTEX_ATTRIB_ARRAY_SIZE, &attrib_size);
        glGetVertexAttribiv(attrib_loc, GL_VERTEX_ATTRIB_ARRAY_TYPE, &attrib_type);
        glGetVertexAttribiv(attrib_loc, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &attrib_normalized);
        glGetVertexAttribiv(attrib_loc, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &attrib_stride);
        glGetVertexAttribPointerv(attrib_loc, GL_VERTEX_ATTRIB_ARRAY_POINTER, &attrib_pointer);
    }
}

BTW I think that using scoped objects to save and restore state is entirely appropriate: embedding paired operations in construction and destruction is a normal C++ idiom.

review: Needs Fixing
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

> The copy semantics of GLState are probably inappropriate and unnecessary while the name doesn't
> really suggest the preserving role. Maybe "StoreGLState"?

The idea was to avoid stressing the store/restore implementation of the class, and provide another abstraction: when that object is in scope, it is the new target GL state for all state changes (which is just an illusion, of course). Perhaps "TargetGLState", "CurrentGLState", "TemporaryGLState", "ScopedGLState", "LocalGLState" ?

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> > The copy semantics of GLState are probably inappropriate and unnecessary
> while the name doesn't
> > really suggest the preserving role. Maybe "StoreGLState"?
>
> The idea was to avoid stressing the store/restore implementation of the class,
> and provide another abstraction: when that object is in scope, it is the new
> target GL state for all state changes (which is just an illusion, of course).
> Perhaps "TargetGLState", "CurrentGLState", "TemporaryGLState",
> "ScopedGLState", "LocalGLState" ?

GLScope perhaps?

Revision history for this message
Robert Carr (robertcarr) wrote :

I think GLScope or GLStateScope is a telling name in this case.

Daniel: I wish we weren't having the same argument on RAII over and over. I think it confuses the argument and makes it more difficult for discussion to proceed:

A little word-swapping excercise ;)
===
"I feel the new GLState class is acting by side-effect in restoring state on destruction. The GL state is a very important and far-reaching set of globals, effectively. So rather than implicitly modify globals by RAII, it should be explicit. I think GLState should use methods: save(), restore()"
===

vs.

===
""I feel the new GLState class is acting putting burden on the user with save/restore method. The GL state is a very important and far-reaching set of globals, effectively. So rather than explicitly modify globals, it should be implicit via RAII. I think GLState should use c'tor/d'tor""
====

I don't think there is an 'argument' here, it's just an authoritative way to say "RAII should not be used". Of course, I respect your opinions on the matter, and more than that respect that you consistently express them. I think though that merge proposals are typically not the right place to express strong opinions on controversial topics. At the risk of violating the tenant I've just put forth, I'll say: I think it polarizes the conversation and detracts from the rigor/integrity of the discussion. I know if nothing else it makes it feel difficult for me to engage on merge proposals once they have been brought to such a level.

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

I understand RAII and accept that people will use it in the context of the local object.

However RAII should not be used to modify global variables/state. That's a side effect, and side effects are widely recognised in software engineering as being a danger to maintainability.

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

Hmm, OK I give in. This actually isn't much different or worse to other RAII use. And the GL state machine has the same dangers even without C++.

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

It occurs to me we don't really have time to argue over example code. Especially example code that is neither a client or server that people can learn from.

Verified the fix works. All good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'examples/image_renderer.cpp'
2--- examples/image_renderer.cpp 2013-03-21 03:32:59 +0000
3+++ examples/image_renderer.cpp 2013-10-24 13:41:26 +0000
4@@ -87,11 +87,68 @@
5 BOOST_THROW_EXCEPTION(std::runtime_error(object_info_err));
6 }
7
8+class GLState
9+{
10+public:
11+ GLState(GLint attrib_loc)
12+ : attrib_loc{attrib_loc}
13+ {
14+ glGetIntegerv(GL_CURRENT_PROGRAM, &program);
15+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &texture);
16+ glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &buffer);
17+ glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture_unit);
18+ if (attrib_loc >= 0)
19+ {
20+ glGetVertexAttribiv(attrib_loc, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &attrib_enabled);
21+ glGetVertexAttribiv(attrib_loc, GL_VERTEX_ATTRIB_ARRAY_SIZE, &attrib_size);
22+ glGetVertexAttribiv(attrib_loc, GL_VERTEX_ATTRIB_ARRAY_TYPE, &attrib_type);
23+ glGetVertexAttribiv(attrib_loc, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &attrib_normalized);
24+ glGetVertexAttribiv(attrib_loc, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &attrib_stride);
25+ glGetVertexAttribPointerv(attrib_loc, GL_VERTEX_ATTRIB_ARRAY_POINTER, &attrib_pointer);
26+ }
27+ }
28+
29+ GLState() : GLState{invalid_attrib_loc} {}
30+
31+ ~GLState()
32+ {
33+ glUseProgram(program);
34+ glBindTexture(GL_TEXTURE_2D, texture);
35+ glBindBuffer(GL_ARRAY_BUFFER, buffer);
36+ glActiveTexture(active_texture_unit);
37+ if (attrib_loc >= 0)
38+ {
39+ glVertexAttribPointer(attrib_loc, attrib_size, attrib_type,
40+ attrib_normalized, attrib_stride, attrib_pointer);
41+ if (attrib_enabled)
42+ glEnableVertexAttribArray(attrib_loc);
43+ else
44+ glDisableVertexAttribArray(attrib_loc);
45+ }
46+ }
47+
48+private:
49+ static GLint const invalid_attrib_loc = -1;
50+ GLint program = 0;
51+ GLint texture = 0;
52+ GLint buffer = 0;
53+ GLint active_texture_unit = 0;
54+ GLint attrib_loc = invalid_attrib_loc;
55+ GLint attrib_enabled = 0;
56+ GLint attrib_size = 0;
57+ GLint attrib_type = 0;
58+ GLint attrib_normalized = 0;
59+ GLint attrib_stride = 0;
60+ GLvoid* attrib_pointer = nullptr;
61+};
62+
63 }
64
65 mt::ImageRenderer::ImageRenderer(const uint8_t* pixel_data, mir::geometry::Size size,
66 uint32_t bytes_per_pixel)
67 {
68+ GLState gl_state;
69+
70 resources.setup();
71
72 /* Upload the texture */
73@@ -173,7 +230,6 @@
74 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
75
76 glUniform1i(tex_loc, 0);
77- glBindTexture(GL_TEXTURE_2D, 0);
78
79 /* Create VBO */
80 glGenBuffers(1, &vertex_attribs_vbo);
81@@ -181,14 +237,13 @@
82 glBindBuffer(GL_ARRAY_BUFFER, vertex_attribs_vbo);
83 glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_attribs),
84 glm::value_ptr(vertex_attribs[0]), GL_STATIC_DRAW);
85-
86- glBindBuffer(GL_ARRAY_BUFFER, 0);
87- glUseProgram(0);
88 }
89
90
91 void mt::ImageRenderer::render()
92 {
93+ GLState gl_state(resources.position_attr_loc);
94+
95 glUseProgram(resources.program);
96
97 glActiveTexture(GL_TEXTURE0);
98@@ -202,5 +257,4 @@
99 /* Draw */
100 glEnableVertexAttribArray(resources.position_attr_loc);
101 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
102- glDisableVertexAttribArray(resources.position_attr_loc);
103 }

Subscribers

People subscribed via source and target branches