Mir

Merge lp:~vanvugt/mir/neg into lp:mir

Proposed by Daniel van Vugt
Status: Merged
Approved by: Daniel van Vugt
Approved revision: no longer in the source branch.
Merged at revision: 2226
Proposed branch: lp:~vanvugt/mir/neg
Merge into: lp:mir
Diff against target: 530 lines (+163/-75)
10 files modified
doc/demo_shell_controls.md (+2/-0)
playground/demo-shell/demo_compositor.cpp (+5/-0)
playground/demo-shell/demo_compositor.h (+2/-0)
playground/demo-shell/demo_renderer.cpp (+48/-1)
playground/demo-shell/demo_renderer.h (+25/-7)
playground/demo-shell/window_manager.cpp (+21/-0)
playground/demo-shell/window_manager.h (+4/-0)
src/include/server/mir/compositor/gl_renderer.h (+12/-3)
src/server/compositor/gl_renderer.cpp (+34/-63)
src/server/symbols.map (+10/-1)
To merge this branch: bzr merge lp:~vanvugt/mir/neg
Reviewer Review Type Date Requested Status
Cemil Azizoglu (community) Approve
Andreas Pokorny (community) Abstain
PS Jenkins bot (community) continuous-integration Approve
Kevin DuBois (community) Needs Information
Review via email: mp+246057@code.launchpad.net

Commit message

First attempts at adding custom shaders in shells. As an example, this
introduces negative (Super+N) and high contrast (Super+C) modes to the
demo shell (mir_proving_server). (LP: #1400580)

I also took the opportunity to clean up and eliminate the ugly vector
of programs approach.

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
Andreas Pokorny (andreas-pokorny) wrote :

Looking at multiwin, I believe you need to apply contrast only on .rgb and leave alpha as is .. or maybe apply it to .rgb/.alpha and *.alpha afterwards, but not sure about the constrast computation.

+ 133 neffects - because of negative inside that MP I stumbled over that term.

Havent thought about the changes to GLRenderer yet.

review: Needs Fixing
Revision history for this message
Kevin DuBois (kdub) wrote :

Unity8 reimplements GLRenderer, so they wouldn't want to pick up our GLRenderer just to have the inverted color rendering. USC doesn't reimplement GLRenderer, but if we're not publishing the header, then this wouldn't help USC either. I'm okay with this change to the proving shell (although, why not try to drive through the public api?), but how does this help USC/U8 implement the feature?

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

This proposal is not intended to help USC or U8 in their current forms. It's foundational work to demo and support future custom shaders in custom shells that utilize GLRenderer. Which is why I did it on the weekend.

There are many such enhancements I want to see in Mir. And any that are not business driven will be done in my own time. Just as you would see from any community contributor.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

yes looks better.. abstain for now until I get look at the GLRenderer solution again

review: Abstain
Revision history for this message
Kevin DuBois (kdub) wrote :

I don't have a problem with adding the feature, but I guess I still don't see how adding a feature that USC/U8 cannot use helps with the bug. To rephrase, I don't see this addressing the bug. Is this just proving that a shader can be written to achieve the effect that is requested? (making this a somewhat-related branch, but not a fix to the wishlist request)

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

For me this branch has a more important purpose than the attached bug; It provides a simple demo for custom shaders in custom shells. It showed me what still needed improving in GLRenderer, so that I may get to my own goal of demonstrating more fancy decoration ideas in the demo shell. I then plan to use those demonstrations to argue for similar ideas in future for Unity8.

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

So the purpose of our demos should come full circle, from appearing to be toys, but eventually helping to motivate positive change in real projects.

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

Should at least be unlinked from bug.

Revision history for this message
Kevin DuBois (kdub) wrote :

> Should at least be unlinked from bug.
Well, it shouldn't resolve the bug at least (could be in the comments)

Revision history for this message
Kevin DuBois (kdub) wrote :

> So the purpose of our demos should come full circle, from appearing to be
> toys, but eventually helping to motivate positive change in real projects.

I agree, but we're changing mg::Renderer (a non-public interface, because its too strange of an interface to support publicly) So, I guess I'm on-board with the feature, but would rather start driving the public interfaces, as opposed to the privileged internal access that the playground/ servers have.

Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

+1 on not resolving the bug.

Otherwise, it looks fine.

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

This branch doesn't resolve the bug for Unity8. That's why it's a separate task already.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'doc/demo_shell_controls.md'
2--- doc/demo_shell_controls.md 2014-12-19 02:31:34 +0000
3+++ doc/demo_shell_controls.md 2015-01-13 03:37:28 +0000
4@@ -36,6 +36,8 @@
5 - Switch apps: *Alt-Tab* or *4-finger swipe left/right*
6 - Move window: *Alt-leftmousebutton* or *3-finger drag*
7 - Resize window: *Alt-middlemousebutton* or *3-finger pinch/zoom*
8+ - Toggle negative rendering: *Super-N*
9+ - Toggle high-contrast rendering: *Super-C*
10 - Sleep/wake all displays: *Alt-P* or *Android power button*
11 - Rotate the focussed monitor: *Ctrl-Alt-(Left/Right/Up/Down)* or
12 *Volume up/down while touching the screen*
13
14=== modified file 'playground/demo-shell/demo_compositor.cpp'
15--- playground/demo-shell/demo_compositor.cpp 2015-01-03 10:01:42 +0000
16+++ playground/demo-shell/demo_compositor.cpp 2015-01-13 03:37:28 +0000
17@@ -161,6 +161,11 @@
18 update_viewport();
19 }
20
21+void me::DemoCompositor::set_colour_effect(me::ColourEffect e)
22+{
23+ renderer.set_colour_effect(e);
24+}
25+
26 void me::DemoCompositor::update_viewport()
27 {
28 auto const& view_area = display_buffer.view_area();
29
30=== modified file 'playground/demo-shell/demo_compositor.h'
31--- playground/demo-shell/demo_compositor.h 2015-01-03 10:01:42 +0000
32+++ playground/demo-shell/demo_compositor.h 2015-01-13 03:37:28 +0000
33@@ -55,6 +55,8 @@
34 void zoom(float mag);
35 void on_cursor_movement(geometry::Point const& p);
36
37+ void set_colour_effect(ColourEffect);
38+
39 static void for_each(std::function<void(DemoCompositor&)> f);
40
41 private:
42
43=== modified file 'playground/demo-shell/demo_renderer.cpp'
44--- playground/demo-shell/demo_renderer.cpp 2015-01-03 10:01:42 +0000
45+++ playground/demo-shell/demo_renderer.cpp 2015-01-13 03:37:28 +0000
46@@ -25,6 +25,7 @@
47 using namespace mir;
48 using namespace mir::examples;
49 using namespace mir::geometry;
50+using namespace mir::compositor;
51
52 namespace
53 {
54@@ -143,6 +144,31 @@
55 return corner;
56 }
57
58+static const GLchar inverse_fshader[] =
59+{
60+ "precision mediump float;\n"
61+ "uniform sampler2D tex;\n"
62+ "uniform float alpha;\n"
63+ "varying vec2 v_texcoord;\n"
64+ "void main() {\n"
65+ " vec4 f = texture2D(tex, v_texcoord);\n"
66+ " vec3 inverted = (vec3(1.0) - (f.rgb / f.a)) * f.a;\n"
67+ " gl_FragColor = alpha*vec4(inverted, f.a);\n"
68+ "}\n"
69+};
70+static const GLchar contrast_fshader[] =
71+{
72+ "precision mediump float;\n"
73+ "uniform sampler2D tex;\n"
74+ "uniform float alpha;\n"
75+ "varying vec2 v_texcoord;\n"
76+ "void main() {\n"
77+ " vec4 raw = texture2D(tex, v_texcoord);\n"
78+ " vec3 bent = (1.0 - cos(raw.rgb * 3.141592654)) / 2.0;\n"
79+ " gl_FragColor = alpha * vec4(bent, raw.a);\n"
80+ "}\n"
81+};
82+
83 } // namespace
84
85 DemoRenderer::DemoRenderer(
86@@ -156,7 +182,10 @@
87 dest_alpha),
88 titlebar_height{titlebar_height},
89 shadow_radius{shadow_radius},
90- corner_radius{0.5f}
91+ corner_radius{0.5f},
92+ colour_effect{none},
93+ inverse_program(family.add_program(vshader, inverse_fshader)),
94+ contrast_program(family.add_program(vshader, contrast_fshader))
95 {
96 shadow_corner_tex = generate_shadow_corner_texture(0.4f);
97 titlebar_corner_tex = generate_frame_corner_texture(corner_radius,
98@@ -338,3 +367,21 @@
99 display_area.overlaps(top) ||
100 display_area.overlaps(bottom));
101 }
102+
103+void DemoRenderer::set_colour_effect(ColourEffect e)
104+{
105+ colour_effect = e;
106+}
107+
108+void DemoRenderer::draw(graphics::Renderable const& renderable,
109+ GLRenderer::Program const& current_program) const
110+{
111+ const GLRenderer::Program* const programs[ColourEffect::neffects] =
112+ {
113+ &current_program,
114+ &inverse_program,
115+ &contrast_program
116+ };
117+
118+ GLRenderer::draw(renderable, *programs[colour_effect]);
119+}
120
121=== modified file 'playground/demo-shell/demo_renderer.h'
122--- playground/demo-shell/demo_renderer.h 2015-01-03 10:01:42 +0000
123+++ playground/demo-shell/demo_renderer.h 2015-01-13 03:37:28 +0000
124@@ -28,6 +28,14 @@
125 namespace examples
126 {
127
128+enum ColourEffect
129+{
130+ none,
131+ inverse,
132+ contrast,
133+ neffects
134+};
135+
136 class DemoRenderer : public compositor::GLRenderer
137 {
138 public:
139@@ -40,9 +48,20 @@
140
141 void begin(std::unordered_set<graphics::Renderable::ID> renderables_not_to_decorate) const;
142
143- void tessellate(
144- std::vector<graphics::GLPrimitive>& primitives,
145- graphics::Renderable const& renderable) const override;
146+ bool would_embellish(
147+ graphics::Renderable const& renderable,
148+ geometry::Rectangle const&) const;
149+
150+ void set_colour_effect(ColourEffect);
151+
152+protected:
153+ void tessellate(std::vector<graphics::GLPrimitive>& primitives,
154+ graphics::Renderable const& renderable) const override;
155+
156+ void draw(graphics::Renderable const& renderable,
157+ GLRenderer::Program const& prog) const override;
158+
159+private:
160 void tessellate_shadow(
161 std::vector<graphics::GLPrimitive>& primitives,
162 graphics::Renderable const& renderable,
163@@ -51,16 +70,15 @@
164 std::vector<graphics::GLPrimitive>& primitives,
165 graphics::Renderable const& renderable,
166 float titlebar_height) const;
167- bool would_embellish(
168- graphics::Renderable const& renderable,
169- geometry::Rectangle const&) const;
170
171-private:
172 float const titlebar_height;
173 float const shadow_radius;
174 float const corner_radius;
175 GLuint shadow_corner_tex;
176 GLuint titlebar_corner_tex;
177+
178+ ColourEffect colour_effect;
179+ Program inverse_program, contrast_program;
180
181 mutable std::unordered_set<graphics::Renderable::ID> decoration_skip_list;
182 };
183
184=== modified file 'playground/demo-shell/window_manager.cpp'
185--- playground/demo-shell/window_manager.cpp 2014-12-19 02:31:34 +0000
186+++ playground/demo-shell/window_manager.cpp 2015-01-13 03:37:28 +0000
187@@ -128,6 +128,17 @@
188
189 } // namespace
190
191+
192+void me::WindowManager::toggle(ColourEffect which)
193+{
194+ colour_effect = (colour_effect == which) ? none : which;
195+ me::DemoCompositor::for_each([this](me::DemoCompositor& c)
196+ {
197+ c.set_colour_effect(colour_effect);
198+ });
199+ force_redraw();
200+}
201+
202 bool me::WindowManager::handle(MirEvent const& event)
203 {
204 // TODO: Fix android configuration and remove static hack ~racarr
205@@ -276,6 +287,16 @@
206 compositor->start();
207 return true;
208 }
209+ else if (event.key.modifiers & mir_key_modifier_meta &&
210+ event.key.scan_code == KEY_N)
211+ {
212+ toggle(inverse);
213+ }
214+ else if (event.key.modifiers & mir_key_modifier_meta &&
215+ event.key.scan_code == KEY_C)
216+ {
217+ toggle(contrast);
218+ }
219 }
220 else if (event.type == mir_event_type_motion &&
221 focus_controller)
222
223=== modified file 'playground/demo-shell/window_manager.h'
224--- playground/demo-shell/window_manager.h 2014-12-19 02:31:34 +0000
225+++ playground/demo-shell/window_manager.h 2015-01-13 03:37:28 +0000
226@@ -23,6 +23,7 @@
227 #include "mir/input/scene.h"
228 #include "mir/geometry/displacement.h"
229 #include "mir/geometry/size.h"
230+#include "demo_renderer.h"
231
232 #include <memory>
233
234@@ -74,6 +75,9 @@
235 float old_pinch_diam;
236 int max_fingers; // Maximum number of fingers touched during gesture
237 int zoom_exponent = 0;
238+ ColourEffect colour_effect = none;
239+
240+ void toggle(ColourEffect);
241 };
242
243 }
244
245=== modified file 'src/include/server/mir/compositor/gl_renderer.h'
246--- src/include/server/mir/compositor/gl_renderer.h 2015-01-05 03:23:16 +0000
247+++ src/include/server/mir/compositor/gl_renderer.h 2015-01-13 03:37:28 +0000
248@@ -74,12 +74,12 @@
249 virtual void tessellate(std::vector<graphics::GLPrimitive>& primitives,
250 graphics::Renderable const& renderable) const;
251
252- virtual void render(graphics::Renderable const& renderable) const;
253-
254 DestinationAlpha destination_alpha() const;
255
256 GLfloat clear_color[4];
257
258+ mutable long long frameno = 0;
259+
260 GLProgramFamily family;
261 struct Program
262 {
263@@ -92,16 +92,25 @@
264 GLint transform_uniform = -1;
265 GLint screen_to_gl_coords_uniform = -1;
266 GLint alpha_uniform = -1;
267+ mutable long long last_used_frameno = 0;
268
269 Program(GLuint program_id);
270 };
271- std::vector<Program> programs;
272+ Program default_program, alpha_program;
273+
274+ static const GLchar* const vshader;
275+ static const GLchar* const default_fshader;
276+ static const GLchar* const alpha_fshader;
277+
278+ virtual void draw(graphics::Renderable const& renderable,
279+ GLRenderer::Program const& prog) const;
280
281 private:
282 std::unique_ptr<graphics::GLTextureCache> mutable texture_cache;
283 float rotation;
284 DestinationAlpha const dest_alpha;
285 geometry::Rectangle viewport;
286+ glm::mat4 screen_to_gl_coords, screen_rotation;
287
288 std::vector<graphics::GLPrimitive> mutable primitives;
289 };
290
291=== modified file 'src/server/compositor/gl_renderer.cpp'
292--- src/server/compositor/gl_renderer.cpp 2015-01-05 03:23:16 +0000
293+++ src/server/compositor/gl_renderer.cpp 2015-01-13 03:37:28 +0000
294@@ -38,16 +38,7 @@
295 namespace mc = mir::compositor;
296 namespace geom = mir::geometry;
297
298-namespace
299-{
300-
301-enum
302-{
303- default_program_index = 0,
304- alpha_program_index = 1
305-};
306-
307-const GLchar vshader[] =
308+const GLchar* const mc::GLRenderer::vshader =
309 {
310 "attribute vec3 position;\n"
311 "attribute vec2 texcoord;\n"
312@@ -64,7 +55,7 @@
313 "}\n"
314 };
315
316-const GLchar alpha_fshader[] =
317+const GLchar* const mc::GLRenderer::alpha_fshader =
318 {
319 "precision mediump float;\n"
320 "uniform sampler2D tex;\n"
321@@ -76,8 +67,8 @@
322 "}\n"
323 };
324
325-const GLchar default_fshader[] = // Should be faster than blending in theory
326-{
327+const GLchar* const mc::GLRenderer::default_fshader =
328+{ // This is the fastest fragment shader. Use it when you can.
329 "precision mediump float;\n"
330 "uniform sampler2D tex;\n"
331 "varying vec2 v_texcoord;\n"
332@@ -86,8 +77,6 @@
333 "}\n"
334 };
335
336-}
337-
338 mc::GLRenderer::Program::Program(GLuint program_id)
339 {
340 id = program_id;
341@@ -106,8 +95,8 @@
342 geom::Rectangle const& display_area,
343 DestinationAlpha dest_alpha)
344 : clear_color{0.0f, 0.0f, 0.0f, 1.0f},
345- programs{family.add_program(vshader, default_fshader),
346- family.add_program(vshader, alpha_fshader)},
347+ default_program(family.add_program(vshader, default_fshader)),
348+ alpha_program(family.add_program(vshader, alpha_fshader)),
349 texture_cache(std::move(texture_cache)),
350 rotation(NAN), // ensure the first set_rotation succeeds
351 dest_alpha(dest_alpha)
352@@ -127,14 +116,7 @@
353 mir::log_info("%s: %s", s.label, val);
354 }
355
356- for (auto& p : programs)
357- {
358- glUseProgram(p.id);
359- glUniform1i(p.tex_uniform, 0);
360- }
361-
362 glBindBuffer(GL_ARRAY_BUFFER, 0);
363- glUseProgram(0);
364
365 set_viewport(display_area);
366 set_rotation(0.0f);
367@@ -159,23 +141,17 @@
368 if (dest_alpha == DestinationAlpha::opaque)
369 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
370
371+ ++frameno;
372 for (auto const& r : renderables)
373- render(*r);
374+ draw(*r, r->alpha() < 1.0f ? alpha_program : default_program);
375
376 texture_cache->drop_unused();
377 }
378
379-void mc::GLRenderer::render(mg::Renderable const& renderable) const
380+void mc::GLRenderer::draw(mg::Renderable const& renderable,
381+ GLRenderer::Program const& prog) const
382 {
383- const Program* prog = &programs[default_program_index];
384-
385- if (renderable.alpha() < 1.0f)
386- {
387- prog = &programs[alpha_program_index];
388- glEnable(GL_BLEND);
389- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
390- }
391- else if (renderable.shaped())
392+ if (renderable.alpha() < 1.0f || renderable.shaped())
393 {
394 glEnable(GL_BLEND);
395 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
396@@ -185,7 +161,17 @@
397 glDisable(GL_BLEND);
398 }
399
400- glUseProgram(prog->id);
401+ glUseProgram(prog.id);
402+ if (prog.last_used_frameno != frameno)
403+ { // Avoid reloading the screen-global uniforms on every renderable
404+ prog.last_used_frameno = frameno;
405+ glUniform1i(prog.tex_uniform, 0);
406+ glUniformMatrix4fv(prog.display_transform_uniform, 1, GL_FALSE,
407+ glm::value_ptr(screen_rotation));
408+ glUniformMatrix4fv(prog.screen_to_gl_coords_uniform, 1, GL_FALSE,
409+ glm::value_ptr(screen_to_gl_coords));
410+ }
411+
412 glActiveTexture(GL_TEXTURE0);
413
414 auto const& rect = renderable.screen_position();
415@@ -193,17 +179,17 @@
416 rect.size.width.as_int() / 2.0f;
417 GLfloat centrey = rect.top_left.y.as_int() +
418 rect.size.height.as_int() / 2.0f;
419- glUniform2f(prog->centre_uniform, centrex, centrey);
420+ glUniform2f(prog.centre_uniform, centrex, centrey);
421
422- glUniformMatrix4fv(prog->transform_uniform, 1, GL_FALSE,
423+ glUniformMatrix4fv(prog.transform_uniform, 1, GL_FALSE,
424 glm::value_ptr(renderable.transformation()));
425
426- if (prog->alpha_uniform >= 0)
427- glUniform1f(prog->alpha_uniform, renderable.alpha());
428+ if (prog.alpha_uniform >= 0)
429+ glUniform1f(prog.alpha_uniform, renderable.alpha());
430
431 /* Draw */
432- glEnableVertexAttribArray(prog->position_attr);
433- glEnableVertexAttribArray(prog->texcoord_attr);
434+ glEnableVertexAttribArray(prog.position_attr);
435+ glEnableVertexAttribArray(prog.texcoord_attr);
436
437 primitives.clear();
438 tessellate(primitives, renderable);
439@@ -220,18 +206,18 @@
440 else
441 surface_tex->bind();
442
443- glVertexAttribPointer(prog->position_attr, 3, GL_FLOAT,
444+ glVertexAttribPointer(prog.position_attr, 3, GL_FLOAT,
445 GL_FALSE, sizeof(mg::GLVertex),
446 &p.vertices[0].position);
447- glVertexAttribPointer(prog->texcoord_attr, 2, GL_FLOAT,
448+ glVertexAttribPointer(prog.texcoord_attr, 2, GL_FLOAT,
449 GL_FALSE, sizeof(mg::GLVertex),
450 &p.vertices[0].texcoord);
451
452 glDrawArrays(p.type, 0, p.nvertices);
453 }
454
455- glDisableVertexAttribArray(prog->texcoord_attr);
456- glDisableVertexAttribArray(prog->position_attr);
457+ glDisableVertexAttribArray(prog.texcoord_attr);
458+ glDisableVertexAttribArray(prog.position_attr);
459 }
460
461 void mc::GLRenderer::set_viewport(geometry::Rectangle const& rect)
462@@ -245,7 +231,7 @@
463 * (top-left is (0,0), bottom-right is (W,H)) to the normalized GL coordinate system
464 * (top-left is (-1,1), bottom-right is (1,-1))
465 */
466- glm::mat4 screen_to_gl_coords = glm::translate(glm::mat4(1.0f), glm::vec3{-1.0f, 1.0f, 0.0f});
467+ screen_to_gl_coords = glm::translate(glm::mat4(1.0f), glm::vec3{-1.0f, 1.0f, 0.0f});
468
469 /*
470 * Perspective division is one thing that can't be done in a matrix
471@@ -270,14 +256,6 @@
472 -rect.top_left.y.as_float(),
473 0.0f});
474
475- for (auto& p : programs)
476- {
477- glUseProgram(p.id);
478- glUniformMatrix4fv(p.screen_to_gl_coords_uniform, 1, GL_FALSE,
479- glm::value_ptr(screen_to_gl_coords));
480- }
481- glUseProgram(0);
482-
483 viewport = rect;
484 }
485
486@@ -289,18 +267,11 @@
487 float rad = degrees * M_PI / 180.0f;
488 GLfloat cos = cosf(rad);
489 GLfloat sin = sinf(rad);
490- GLfloat rot[16] = {cos, sin, 0.0f, 0.0f,
491+ screen_rotation = {cos, sin, 0.0f, 0.0f,
492 -sin, cos, 0.0f, 0.0f,
493 0.0f, 0.0f, 1.0f, 0.0f,
494 0.0f, 0.0f, 0.0f, 1.0f};
495
496- for (auto& p : programs)
497- {
498- glUseProgram(p.id);
499- glUniformMatrix4fv(p.display_transform_uniform, 1, GL_FALSE, rot);
500- }
501- glUseProgram(0);
502-
503 rotation = degrees;
504 }
505
506
507=== modified file 'src/server/symbols.map'
508--- src/server/symbols.map 2015-01-03 09:28:20 +0000
509+++ src/server/symbols.map 2015-01-13 03:37:28 +0000
510@@ -787,10 +787,19 @@
511 mir::compositor::GLRenderer::set_viewport*;
512 mir::compositor::GLRenderer::suspend*;
513 mir::compositor::GLRenderer::tessellate*;
514- mir::compositor::GLProgramFamily::*;
515 typeinfo?for?mir::compositor::GLRenderer;
516 vtable?for?mir::compositor::GLRenderer;
517 vtable?for?mir::compositor::RecentlyUsedCache;
518 };
519 local: *;
520 };
521+
522+MIR_SERVER_28.1 {
523+ global:
524+ extern "C++" {
525+ mir::compositor::GLRenderer::draw*;
526+ mir::compositor::GLRenderer::vshader;
527+ mir::compositor::GLRenderer::Program::Program*;
528+ mir::compositor::GLProgramFamily::*;
529+ };
530+} MIR_SERVER_28;

Subscribers

People subscribed via source and target branches