Merge lp:~afrantzis/unity-system-compositor/fix-1463855-usc-spinner into lp:unity-system-compositor

Proposed by Alexandros Frantzis
Status: Merged
Approved by: Alexandros Frantzis
Approved revision: 220
Merged at revision: 219
Proposed branch: lp:~afrantzis/unity-system-compositor/fix-1463855-usc-spinner
Merge into: lp:unity-system-compositor
Diff against target: 252 lines (+86/-23)
3 files modified
spinner/eglapp.cpp (+15/-4)
spinner/miregl.cpp (+64/-15)
spinner/miregl.h (+7/-4)
To merge this branch: bzr merge lp:~afrantzis/unity-system-compositor/fix-1463855-usc-spinner
Reviewer Review Type Date Requested Status
Chris Halse Rogers Approve
Alan Griffiths Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+261635@code.launchpad.net

Commit message

spinner: Fix failure to run on Android

This MP:

1. Passes surface dimensions in addition to the output_id when placing on a specific output. This is needed as a workaround for our Android backend, which unfortunately uses the value of mir_display_output_invalid_id (0) as a valid output id!

2. Sets swapinterval correctly per surface.

3. Uses eglQuerySurface to get the surface size (instead of mir_buffer_stream_get_current_buffer() which returns a platform dependent structure).

4. Uses a dummy pbuffer surface to emulate a surfaceless context on platforms that don't support it (e.g. Android).

Description of the change

spinner: Fix failure to run on Android

This MP:

1. Passes surface dimensions in addition to the output_id when placing on a specific output. This is needed as a workaround for our Android backend, which unfortunately uses the value of mir_display_output_invalid_id (0) as an output id ([1])!

2. Sets swapinterval correctly per surface.

3. Uses eglQuerySurface to get the surface size (instead of mir_buffer_stream_get_current_buffer() which returns a platform dependent structure).

4. Uses a dummy pbuffer surface to emulate a surfaceless context on platforms that don't support it (e.g. Android).

[1] https://bugs.launchpad.net/mir/+bug/1463873

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

LGTM

review: Approve
Revision history for this message
Chris Halse Rogers (raof) wrote :

Looks sensible.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'spinner/eglapp.cpp'
2--- spinner/eglapp.cpp 2015-05-28 15:25:28 +0000
3+++ spinner/eglapp.cpp 2015-06-10 15:00:47 +0000
4@@ -205,21 +205,30 @@
5 auto const pixel_format = select_pixel_format(connection);
6 surfaceparm.pixel_format = pixel_format;
7
8- auto const mir_egl_app = make_mir_eglapp(connection, pixel_format, swapinterval);
9+ auto const mir_egl_app = make_mir_eglapp(connection, pixel_format);
10
11 std::vector<std::shared_ptr<MirEglSurface>> result;
12
13 // If a size has been specified just do that
14 if (surfaceparm.width && surfaceparm.height)
15 {
16- result.push_back(std::make_shared<MirEglSurface>(mir_egl_app, surfaceparm));
17+ result.push_back(std::make_shared<MirEglSurface>(mir_egl_app, surfaceparm, swapinterval));
18 return result;
19 }
20
21 // If an output has been specified just do that
22 if (surfaceparm.output_id != mir_display_output_id_invalid)
23 {
24- result.push_back(std::make_shared<MirEglSurface>(mir_egl_app, surfaceparm));
25+ for_each_active_output(connection, [&](MirDisplayOutput const* output)
26+ {
27+ if (output->output_id == surfaceparm.output_id)
28+ {
29+ auto const& mode = output->modes[output->current_mode];
30+ surfaceparm.width = mode.horizontal_resolution;
31+ surfaceparm.height = mode.vertical_resolution;
32+ }
33+ });
34+ result.push_back(std::make_shared<MirEglSurface>(mir_egl_app, surfaceparm, swapinterval));
35 return result;
36 }
37
38@@ -233,8 +242,10 @@
39 output->position_x, output->position_y,
40 mode.horizontal_resolution, mode.vertical_resolution);
41
42+ surfaceparm.width = mode.horizontal_resolution;
43+ surfaceparm.height = mode.vertical_resolution;
44 surfaceparm.output_id = output->output_id;
45- result.push_back(std::make_shared<MirEglSurface>(mir_egl_app, surfaceparm));
46+ result.push_back(std::make_shared<MirEglSurface>(mir_egl_app, surfaceparm, swapinterval));
47 });
48
49 if (result.empty())
50
51=== modified file 'spinner/miregl.cpp'
52--- spinner/miregl.cpp 2015-05-28 15:29:51 +0000
53+++ spinner/miregl.cpp 2015-06-10 15:00:47 +0000
54@@ -16,12 +16,14 @@
55
56 #include "miregl.h"
57
58+#include <cstring>
59+
60 #include <GLES2/gl2.h>
61
62 class MirEglApp
63 {
64 public:
65- MirEglApp(MirConnection* const connection, MirPixelFormat pixel_format, EGLint swapinterval);
66+ MirEglApp(MirConnection* const connection, MirPixelFormat pixel_format);
67
68 EGLSurface create_surface(MirSurface* surface);
69
70@@ -33,6 +35,12 @@
71
72 void destroy_surface(EGLSurface eglsurface) const;
73
74+ void get_surface_size(EGLSurface eglsurface, int* width, int* height) const;
75+
76+ void set_swap_interval(EGLSurface eglsurface, int interval) const;
77+
78+ bool supports_surfaceless_context();
79+
80 ~MirEglApp();
81
82 MirConnection* const connection;
83@@ -41,12 +49,13 @@
84 EGLContext eglctx;
85 EGLConfig eglconfig;
86 EGLint neglconfigs;
87+ EGLSurface dummy_surface;
88 };
89
90 std::shared_ptr<MirEglApp> make_mir_eglapp(
91- MirConnection* const connection, MirPixelFormat const& pixel_format, EGLint swapinterval)
92+ MirConnection* const connection, MirPixelFormat const& pixel_format)
93 {
94- return std::make_shared<MirEglApp>(connection, pixel_format, swapinterval);
95+ return std::make_shared<MirEglApp>(connection, pixel_format);
96 }
97
98 namespace
99@@ -67,7 +76,7 @@
100 mir_surface_spec_release(spec);
101
102 if (!mir_surface_is_valid(surface))
103- throw std::runtime_error("Can't create a surface");
104+ throw std::runtime_error(std::string("Can't create a surface ") + mir_surface_get_error_message(surface));
105
106 if (surfaceparm.output_id != mir_display_output_id_invalid)
107 mir_surface_set_state(surface, mir_surface_state_fullscreen);
108@@ -76,11 +85,14 @@
109 }
110 }
111
112-MirEglSurface::MirEglSurface(std::shared_ptr<MirEglApp> const& mir_egl_app, MirSurfaceParameters const& surfaceparm) :
113+MirEglSurface::MirEglSurface(std::shared_ptr<MirEglApp> const& mir_egl_app, MirSurfaceParameters const& surfaceparm, int swapinterval) :
114 mir_egl_app{mir_egl_app},
115 surface{create_surface(mir_egl_app->connection, surfaceparm)},
116- eglsurface{mir_egl_app->create_surface(surface)}
117+ eglsurface{mir_egl_app->create_surface(surface)},
118+ width_{0},
119+ height_{0}
120 {
121+ mir_egl_app->set_swap_interval(eglsurface, swapinterval);
122 }
123
124 MirEglSurface::~MirEglSurface()
125@@ -91,8 +103,7 @@
126
127 void MirEglSurface::egl_make_current()
128 {
129- auto const buffer_stream = mir_surface_get_buffer_stream(surface);
130- mir_buffer_stream_get_current_buffer(buffer_stream, &buffer_package);
131+ mir_egl_app->get_surface_size(eglsurface, &width_, &height_);
132 mir_egl_app->make_current(eglsurface);
133 }
134
135@@ -103,16 +114,17 @@
136
137 unsigned int MirEglSurface::width() const
138 {
139- return buffer_package->width;
140+ return width_;
141 }
142
143 unsigned int MirEglSurface::height() const
144 {
145- return buffer_package->height;
146+ return height_;
147 }
148
149-MirEglApp::MirEglApp(MirConnection* const connection, MirPixelFormat pixel_format, EGLint swapinterval) :
150- connection{connection}
151+MirEglApp::MirEglApp(MirConnection* const connection, MirPixelFormat pixel_format) :
152+ connection{connection},
153+ dummy_surface{EGL_NO_SURFACE}
154 {
155 unsigned int bpp = 8*MIR_BYTES_PER_PIXEL(pixel_format);
156
157@@ -153,10 +165,21 @@
158 if (eglctx == EGL_NO_CONTEXT)
159 throw std::runtime_error("eglCreateContext failed");
160
161- if (!eglMakeCurrent(egldisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglctx))
162- throw std::runtime_error("Can't eglMakeCurrent");
163+ if (!supports_surfaceless_context())
164+ {
165+ static EGLint const dummy_pbuffer_attribs[] =
166+ {
167+ EGL_WIDTH, 1,
168+ EGL_HEIGHT, 1,
169+ EGL_NONE
170+ };
171+
172+ dummy_surface = eglCreatePbufferSurface(egldisplay, eglconfig, dummy_pbuffer_attribs);
173+ if (dummy_surface == EGL_NO_SURFACE)
174+ throw std::runtime_error("eglCreatePbufferSurface failed");
175+ }
176
177- eglSwapInterval(egldisplay, swapinterval);
178+ make_current(dummy_surface);
179 }
180
181 EGLSurface MirEglApp::create_surface(MirSurface* surface)
182@@ -188,10 +211,36 @@
183 eglDestroySurface(egldisplay, eglsurface);
184 }
185
186+void MirEglApp::get_surface_size(EGLSurface eglsurface, int* width, int* height) const
187+{
188+ eglQuerySurface(egldisplay, eglsurface, EGL_WIDTH, width);
189+ eglQuerySurface(egldisplay, eglsurface, EGL_HEIGHT, height);
190+}
191+
192+void MirEglApp::set_swap_interval(EGLSurface eglsurface, int interval) const
193+{
194+ auto const previous_surface = eglGetCurrentSurface(EGL_DRAW);
195+
196+ make_current(eglsurface);
197+ eglSwapInterval(egldisplay, interval);
198+
199+ if (previous_surface != EGL_NO_SURFACE)
200+ make_current(previous_surface);
201+}
202+
203+bool MirEglApp::supports_surfaceless_context()
204+{
205+ auto const extensions = eglQueryString(egldisplay, EGL_EXTENSIONS);
206+ if (!extensions)
207+ return false;
208+ return std::strstr(extensions, "EGL_KHR_surfaceless_context") != nullptr;
209+}
210
211 MirEglApp::~MirEglApp()
212 {
213 eglMakeCurrent(egldisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
214+ if (dummy_surface != EGL_NO_SURFACE)
215+ destroy_surface(dummy_surface);
216 eglDestroyContext(egldisplay, eglctx);
217 eglTerminate(egldisplay);
218 mir_connection_release(connection);
219
220=== modified file 'spinner/miregl.h'
221--- spinner/miregl.h 2015-05-28 15:25:28 +0000
222+++ spinner/miregl.h 2015-06-10 15:00:47 +0000
223@@ -30,13 +30,15 @@
224
225 std::shared_ptr<MirEglApp> make_mir_eglapp(
226 MirConnection* const connection,
227- MirPixelFormat const& pixel_format,
228- EGLint swapinterval);
229+ MirPixelFormat const& pixel_format);
230
231 class MirEglSurface
232 {
233 public:
234- MirEglSurface(std::shared_ptr<MirEglApp> const& mir_egl_app, MirSurfaceParameters const& surfaceparm);
235+ MirEglSurface(
236+ std::shared_ptr<MirEglApp> const& mir_egl_app,
237+ MirSurfaceParameters const& surfaceparm,
238+ int swapinterval);
239
240 ~MirEglSurface();
241
242@@ -57,8 +59,9 @@
243
244 std::shared_ptr<MirEglApp> const mir_egl_app;
245 MirSurface* const surface;
246- MirBufferPackage* buffer_package;
247 EGLSurface const eglsurface;
248+ int width_;
249+ int height_;
250 };
251
252 #endif //UNITYSYSTEMCOMPOSITOR_MIREGL_H

Subscribers

People subscribed via source and target branches