Mir

Merge lp:~afrantzis/mir/report-egl-errors-in-exceptions into lp:mir

Proposed by Alexandros Frantzis
Status: Merged
Approved by: Alan Griffiths
Approved revision: no longer in the source branch.
Merged at revision: 2497
Proposed branch: lp:~afrantzis/mir/report-egl-errors-in-exceptions
Merge into: lp:mir
Diff against target: 625 lines (+267/-32)
15 files modified
src/include/platform/mir/graphics/egl_error.h (+40/-0)
src/platform/graphics/CMakeLists.txt (+1/-0)
src/platform/graphics/egl_error.cpp (+72/-0)
src/platform/graphics/egl_resources.cpp (+3/-2)
src/platform/symbols.map (+1/-0)
src/platforms/android/server/buffer.cpp (+3/-2)
src/platforms/android/server/gl_context.cpp (+6/-10)
src/platforms/mesa/server/buffer_allocator.cpp (+2/-1)
src/platforms/mesa/server/display_helpers.cpp (+9/-7)
src/server/graphics/nested/display.cpp (+6/-5)
src/server/graphics/nested/display_buffer.cpp (+2/-1)
src/server/graphics/offscreen/display.cpp (+3/-2)
src/server/graphics/surfaceless_egl_context.cpp (+3/-2)
tests/unit-tests/graphics/CMakeLists.txt (+1/-0)
tests/unit-tests/graphics/test_egl_error.cpp (+115/-0)
To merge this branch: bzr merge lp:~afrantzis/mir/report-egl-errors-in-exceptions
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Kevin DuBois (community) Approve
Alan Griffiths Approve
Robert Carr (community) Approve
Review via email: mp+256534@code.launchpad.net

Commit message

server,platform: Report the EGL error code when throwing exceptions for EGL errors

Description of the change

server,platform: Report the EGL error code when throwing exceptions for EGL errors

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
Robert Carr (robertcarr) wrote :

LGTM! A few preexisting \n in exception strings that I guess shouldn't be there?

Revision history for this message
Robert Carr (robertcarr) :
review: Approve
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

> A few preexisting \n in exception strings that I guess shouldn't be there?

Fixed!

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 :

38+ egl_error(std::string const& msg)
39+ : std::system_error(eglGetError(), egl_category(), msg)
40+ {
41+ }

I'm not sure why this code is inline (which requires egl_category() to be published)

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

could the code in src/platforms/android/server/gl_context.cpp use this too?

review: Approve
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

I think it would be better to expose egl_error and its typeinfo since it gets thrown around? But I might be wrong, and boost::exception already deals with that.

Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

I was thinking about cases in which somebody wants to catch egl_error outside of libmirserver.so

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

@Kevin
> could the code in src/platforms/android/server/gl_context.cpp use this too?

12 +++ src/platforms/android/server/gl_context.cpp 2015-04-17 07:34:44 +0000

:)

@Andreas
> I think it would be better to expose egl_error and its typeinfo since it gets thrown around?

mg::egl_error is a convenience class. For all intents the purpose, the exception we are throwing is a std::system_error with an egl_category.

@Alan
> I'm not sure why this code is inline (which requires egl_category() to be published)

See above, and also, in some cases this convenience class may not be usable, since it calls eglGetError() itself.

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

> mg::egl_error is a convenience class. For all intents the purpose, the
> exception we are throwing is a std::system_error with an egl_category.

a convenience class that could be replaced by a convenience function?

inline auto egl_error(std::string const& msg) -> std::system_error
{
    return std::system_error(eglGetError(), egl_category(), msg);
}

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

> a convenience class that could be replaced by a convenience function?

Better, thanks.

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'src/include/platform/mir/graphics/egl_error.h'
2--- src/include/platform/mir/graphics/egl_error.h 1970-01-01 00:00:00 +0000
3+++ src/include/platform/mir/graphics/egl_error.h 2015-04-17 15:49:38 +0000
4@@ -0,0 +1,40 @@
5+/*
6+ * Copyright © 2015 Canonical Ltd.
7+ *
8+ * This program is free software: you can redistribute it and/or modify it
9+ * under the terms of the GNU Lesser General Public License version 3,
10+ * as published by the Free Software Foundation.
11+ *
12+ * This program is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ * GNU Lesser General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU Lesser General Public License
18+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19+ *
20+ * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
21+ */
22+
23+#ifndef MIR_GRAPHICS_EGL_ERROR_H_
24+#define MIR_GRAPHICS_EGL_ERROR_H_
25+
26+#include <system_error>
27+#include <EGL/egl.h>
28+
29+namespace mir
30+{
31+namespace graphics
32+{
33+
34+std::error_category const& egl_category();
35+
36+inline auto egl_error(std::string const& msg) -> std::system_error
37+{
38+ return std::system_error{eglGetError(), egl_category(), msg};
39+}
40+
41+}
42+}
43+
44+#endif
45
46=== modified file 'src/platform/graphics/CMakeLists.txt'
47--- src/platform/graphics/CMakeLists.txt 2015-03-31 02:35:42 +0000
48+++ src/platform/graphics/CMakeLists.txt 2015-04-17 15:49:38 +0000
49@@ -5,6 +5,7 @@
50
51 egl_extensions.cpp
52 egl_resources.cpp
53+ egl_error.cpp
54 display_configuration.cpp
55 buffer_basic.cpp
56 pixel_format_utils.cpp
57
58=== added file 'src/platform/graphics/egl_error.cpp'
59--- src/platform/graphics/egl_error.cpp 1970-01-01 00:00:00 +0000
60+++ src/platform/graphics/egl_error.cpp 2015-04-17 15:49:38 +0000
61@@ -0,0 +1,72 @@
62+/*
63+ * Copyright © 2015 Canonical Ltd.
64+ *
65+ * This program is free software: you can redistribute it and/or modify it
66+ * under the terms of the GNU Lesser General Public License version 3,
67+ * as published by the Free Software Foundation.
68+ *
69+ * This program is distributed in the hope that it will be useful,
70+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
71+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
72+ * GNU Lesser General Public License for more details.
73+ *
74+ * You should have received a copy of the GNU Lesser General Public License
75+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
76+ *
77+ * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
78+ */
79+
80+#include "mir/graphics/egl_error.h"
81+#include <sstream>
82+
83+namespace
84+{
85+
86+std::string to_hex_string(int n)
87+{
88+ std::stringstream ss;
89+ ss << std::showbase << std::hex << n;
90+ return ss.str();
91+}
92+
93+struct egl_category : std::error_category
94+{
95+ const char* name() const noexcept override { return "egl"; }
96+
97+ std::string message(int ev) const override
98+ {
99+ #define CASE_FOR_ERROR(error) \
100+ case error: return #error " (" + to_hex_string(error) + ")";
101+ switch (ev)
102+ {
103+ CASE_FOR_ERROR(EGL_SUCCESS)
104+ CASE_FOR_ERROR(EGL_NOT_INITIALIZED)
105+ CASE_FOR_ERROR(EGL_BAD_ACCESS)
106+ CASE_FOR_ERROR(EGL_BAD_ALLOC)
107+ CASE_FOR_ERROR(EGL_BAD_ATTRIBUTE)
108+ CASE_FOR_ERROR(EGL_BAD_CONFIG)
109+ CASE_FOR_ERROR(EGL_BAD_CONTEXT)
110+ CASE_FOR_ERROR(EGL_BAD_CURRENT_SURFACE)
111+ CASE_FOR_ERROR(EGL_BAD_DISPLAY)
112+ CASE_FOR_ERROR(EGL_BAD_MATCH)
113+ CASE_FOR_ERROR(EGL_BAD_NATIVE_PIXMAP)
114+ CASE_FOR_ERROR(EGL_BAD_NATIVE_WINDOW)
115+ CASE_FOR_ERROR(EGL_BAD_PARAMETER)
116+ CASE_FOR_ERROR(EGL_BAD_SURFACE)
117+ CASE_FOR_ERROR(EGL_CONTEXT_LOST)
118+
119+ default:
120+ return "Unknown error (" + to_hex_string(ev) + ")";
121+ }
122+ #undef CASE_ERROR
123+ }
124+};
125+
126+}
127+
128+std::error_category const& mir::graphics::egl_category()
129+{
130+ static class egl_category const egl_category_instance{};
131+
132+ return egl_category_instance;
133+}
134
135=== modified file 'src/platform/graphics/egl_resources.cpp'
136--- src/platform/graphics/egl_resources.cpp 2014-03-12 02:46:58 +0000
137+++ src/platform/graphics/egl_resources.cpp 2015-04-17 15:49:38 +0000
138@@ -17,6 +17,7 @@
139 */
140
141 #include "mir/graphics/egl_resources.h"
142+#include "mir/graphics/egl_error.h"
143
144 #include <boost/throw_exception.hpp>
145 #include <stdexcept>
146@@ -31,7 +32,7 @@
147 : egl_display_{egl_display}, egl_context_{egl_context}
148 {
149 if (egl_context_ == EGL_NO_CONTEXT)
150- BOOST_THROW_EXCEPTION(std::runtime_error("Could not create egl context\n"));
151+ BOOST_THROW_EXCEPTION(mg::egl_error("Could not create egl context"));
152 }
153
154 mg::EGLContextStore::~EGLContextStore() noexcept
155@@ -62,7 +63,7 @@
156 : egl_display_{egl_display}, egl_surface_{egl_surface}
157 {
158 if (egl_surface_ == EGL_NO_SURFACE && !allow_no_surface)
159- BOOST_THROW_EXCEPTION(std::runtime_error("Could not create egl surface\n"));
160+ BOOST_THROW_EXCEPTION(mg::egl_error("Could not create egl surface"));
161 }
162
163 mg::EGLSurfaceStore::EGLSurfaceStore(EGLDisplay egl_display, EGLSurface egl_surface)
164
165=== modified file 'src/platform/symbols.map'
166--- src/platform/symbols.map 2015-04-09 06:20:31 +0000
167+++ src/platform/symbols.map 2015-04-17 15:49:38 +0000
168@@ -246,6 +246,7 @@
169 mir::graphics::EGLSurfaceStore::EGLSurfaceStore*;
170 mir::graphics::EGLSurfaceStore::EGLSurfaceStore*;
171 mir::graphics::EGLSurfaceStore::operator*;
172+ mir::graphics::egl_category*;
173 mir::graphics::GLTexture::bind*;
174 mir::graphics::GLTexture::?GLTexture*;
175 mir::graphics::GLTexture::GLTexture*;
176
177=== modified file 'src/platforms/android/server/buffer.cpp'
178--- src/platforms/android/server/buffer.cpp 2015-04-09 17:37:55 +0000
179+++ src/platforms/android/server/buffer.cpp 2015-04-17 15:49:38 +0000
180@@ -18,6 +18,7 @@
181 */
182
183 #include "mir/graphics/egl_extensions.h"
184+#include "mir/graphics/egl_error.h"
185 #include "mir/graphics/android/native_buffer.h"
186 #include "mir/graphics/android/sync_fence.h"
187 #include "android_format_conversion-inl.h"
188@@ -83,7 +84,7 @@
189
190 if (current.first == EGL_NO_DISPLAY)
191 {
192- BOOST_THROW_EXCEPTION(std::runtime_error("cannot bind buffer to texture without EGL context\n"));
193+ BOOST_THROW_EXCEPTION(std::runtime_error("cannot bind buffer to texture without EGL context"));
194 }
195
196 static const EGLint image_attrs[] =
197@@ -102,7 +103,7 @@
198
199 if (image == EGL_NO_IMAGE_KHR)
200 {
201- BOOST_THROW_EXCEPTION(std::runtime_error("error binding buffer to texture\n"));
202+ BOOST_THROW_EXCEPTION(mg::egl_error("error binding buffer to texture"));
203 }
204 egl_image_map[current] = image;
205 }
206
207=== modified file 'src/platforms/android/server/gl_context.cpp'
208--- src/platforms/android/server/gl_context.cpp 2015-01-22 09:00:14 +0000
209+++ src/platforms/android/server/gl_context.cpp 2015-04-17 15:49:38 +0000
210@@ -21,6 +21,7 @@
211 #include "android_format_conversion-inl.h"
212 #include "mir/graphics/display_report.h"
213 #include "mir/graphics/gl_config.h"
214+#include "mir/graphics/egl_error.h"
215
216 #include <algorithm>
217 #include <boost/throw_exception.hpp>
218@@ -52,13 +53,13 @@
219
220 auto egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
221 if (egl_display == EGL_NO_DISPLAY)
222- BOOST_THROW_EXCEPTION(std::runtime_error("eglGetDisplay failed\n"));
223+ BOOST_THROW_EXCEPTION(mg::egl_error("eglGetDisplay failed"));
224
225 if (eglInitialize(egl_display, &major, &minor) == EGL_FALSE)
226- BOOST_THROW_EXCEPTION(std::runtime_error("eglInitialize failure\n"));
227+ BOOST_THROW_EXCEPTION(mg::egl_error("eglInitialize failure"));
228
229 if ((major != 1) || (minor != 4))
230- BOOST_THROW_EXCEPTION(std::runtime_error("must have EGL 1.4\n"));
231+ BOOST_THROW_EXCEPTION(std::runtime_error("must have EGL 1.4"));
232 return egl_display;
233 }
234
235@@ -108,7 +109,7 @@
236 if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context) == EGL_FALSE)
237 {
238 BOOST_THROW_EXCEPTION(
239- std::runtime_error("could not activate surface with eglMakeCurrent\n"));
240+ mg::egl_error("could not activate surface with eglMakeCurrent"));
241 }
242 }
243
244@@ -186,13 +187,8 @@
245
246 void mga::FramebufferGLContext::swap_buffers() const
247 {
248- eglGetError();
249 if (eglSwapBuffers(egl_display, egl_surface) == EGL_FALSE)
250- {
251- std::stringstream sstream;
252- sstream << "eglSwapBuffers failure: EGL error code " << std::hex << eglGetError();
253- BOOST_THROW_EXCEPTION(std::runtime_error(sstream.str()));
254- }
255+ BOOST_THROW_EXCEPTION(mg::egl_error("eglSwapBuffers failure"));
256 }
257
258 std::shared_ptr<mg::Buffer> mga::FramebufferGLContext::last_rendered_buffer() const
259
260=== modified file 'src/platforms/mesa/server/buffer_allocator.cpp'
261--- src/platforms/mesa/server/buffer_allocator.cpp 2015-04-14 12:22:18 +0000
262+++ src/platforms/mesa/server/buffer_allocator.cpp 2015-04-17 15:49:38 +0000
263@@ -23,6 +23,7 @@
264 #include "anonymous_shm_file.h"
265 #include "shm_buffer.h"
266 #include "mir/graphics/egl_extensions.h"
267+#include "mir/graphics/egl_error.h"
268 #include "mir/graphics/buffer_properties.h"
269 #include <boost/throw_exception.hpp>
270
271@@ -86,7 +87,7 @@
272 reinterpret_cast<void*>(bo_raw),
273 image_attrs);
274 if (egl_image == EGL_NO_IMAGE_KHR)
275- BOOST_THROW_EXCEPTION(std::runtime_error("Failed to create EGLImage from GBM bo"));
276+ BOOST_THROW_EXCEPTION(mg::egl_error("Failed to create EGLImage from GBM bo"));
277 }
278 }
279
280
281=== modified file 'src/platforms/mesa/server/display_helpers.cpp'
282--- src/platforms/mesa/server/display_helpers.cpp 2015-01-22 09:00:14 +0000
283+++ src/platforms/mesa/server/display_helpers.cpp 2015-04-17 15:49:38 +0000
284@@ -20,6 +20,7 @@
285 #include "drm_close_threadsafe.h"
286
287 #include "mir/graphics/gl_config.h"
288+#include "mir/graphics/egl_error.h"
289 #include "mir/udev/wrapper.h"
290
291 #include <boost/exception/errinfo_errno.hpp>
292@@ -31,6 +32,7 @@
293 #include <xf86drm.h>
294 #include <fcntl.h>
295
296+namespace mg = mir::graphics;
297 namespace mgm = mir::graphics::mesa;
298 namespace mgmh = mir::graphics::mesa::helpers;
299
300@@ -317,7 +319,7 @@
301
302 egl_context = eglCreateContext(egl_display, egl_config, EGL_NO_CONTEXT, context_attr);
303 if (egl_context == EGL_NO_CONTEXT)
304- BOOST_THROW_EXCEPTION(std::runtime_error("Failed to create EGL context"));
305+ BOOST_THROW_EXCEPTION(mg::egl_error("Failed to create EGL context"));
306 }
307
308 void mgmh::EGLHelper::setup(GBMHelper const& gbm, EGLContext shared_context)
309@@ -331,7 +333,7 @@
310
311 egl_context = eglCreateContext(egl_display, egl_config, shared_context, context_attr);
312 if (egl_context == EGL_NO_CONTEXT)
313- BOOST_THROW_EXCEPTION(std::runtime_error("Failed to create EGL context"));
314+ BOOST_THROW_EXCEPTION(mg::egl_error("Failed to create EGL context"));
315 }
316
317 void mgmh::EGLHelper::setup(GBMHelper const& gbm, gbm_surface* surface_gbm,
318@@ -346,11 +348,11 @@
319
320 egl_surface = eglCreateWindowSurface(egl_display, egl_config, surface_gbm, nullptr);
321 if(egl_surface == EGL_NO_SURFACE)
322- BOOST_THROW_EXCEPTION(std::runtime_error("Failed to create EGL window surface"));
323+ BOOST_THROW_EXCEPTION(mg::egl_error("Failed to create EGL window surface"));
324
325 egl_context = eglCreateContext(egl_display, egl_config, shared_context, context_attr);
326 if (egl_context == EGL_NO_CONTEXT)
327- BOOST_THROW_EXCEPTION(std::runtime_error("Failed to create EGL context"));
328+ BOOST_THROW_EXCEPTION(mg::egl_error("Failed to create EGL context"));
329 }
330
331 mgmh::EGLHelper::~EGLHelper() noexcept
332@@ -408,14 +410,14 @@
333
334 egl_display = eglGetDisplay(static_cast<EGLNativeDisplayType>(gbm.device));
335 if (egl_display == EGL_NO_DISPLAY)
336- BOOST_THROW_EXCEPTION(std::runtime_error("Failed to get EGL display"));
337+ BOOST_THROW_EXCEPTION(mg::egl_error("Failed to get EGL display"));
338
339 if (initialize)
340 {
341 EGLint major, minor;
342
343 if (eglInitialize(egl_display, &major, &minor) == EGL_FALSE)
344- BOOST_THROW_EXCEPTION(std::runtime_error("Failed to initialize EGL display"));
345+ BOOST_THROW_EXCEPTION(mg::egl_error("Failed to initialize EGL display"));
346
347 if ((major != required_egl_version_major) || (minor != required_egl_version_minor))
348 {
349@@ -432,7 +434,7 @@
350 if (eglChooseConfig(egl_display, config_attr, &egl_config, 1, &num_egl_configs) == EGL_FALSE ||
351 num_egl_configs != 1)
352 {
353- BOOST_THROW_EXCEPTION(std::runtime_error("Failed to choose ARGB EGL config"));
354+ BOOST_THROW_EXCEPTION(mg::egl_error("Failed to choose ARGB EGL config"));
355 }
356 }
357
358
359=== modified file 'src/server/graphics/nested/display.cpp'
360--- src/server/graphics/nested/display.cpp 2015-04-08 03:02:37 +0000
361+++ src/server/graphics/nested/display.cpp 2015-04-17 15:49:38 +0000
362@@ -28,6 +28,7 @@
363 #include "mir/graphics/display_configuration_policy.h"
364 #include "mir/graphics/overlapping_output_grouping.h"
365 #include "mir/graphics/gl_config.h"
366+#include "mir/graphics/egl_error.h"
367
368 #include <boost/throw_exception.hpp>
369 #include <stdexcept>
370@@ -48,7 +49,7 @@
371 {
372 if (egl_surface == EGL_NO_SURFACE)
373 {
374- BOOST_THROW_EXCEPTION(std::runtime_error("Nested Mir Display Error: Failed to create EGL surface."));
375+ BOOST_THROW_EXCEPTION(mg::egl_error("Nested Mir Display Error: Failed to create EGL surface."));
376 }
377 }
378
379@@ -66,7 +67,7 @@
380 {
381 egl_display = eglGetDisplay(native_display);
382 if (egl_display == EGL_NO_DISPLAY)
383- BOOST_THROW_EXCEPTION(std::runtime_error("Nested Mir Display Error: Failed to fetch EGL display."));
384+ BOOST_THROW_EXCEPTION(mg::egl_error("Nested Mir Display Error: Failed to fetch EGL display."));
385 }
386
387 void mgn::detail::EGLDisplayHandle::initialize(MirPixelFormat format)
388@@ -76,13 +77,13 @@
389
390 if (eglInitialize(egl_display, &major, &minor) != EGL_TRUE)
391 {
392- BOOST_THROW_EXCEPTION(std::runtime_error("Nested Mir Display Error: Failed to initialize EGL."));
393+ BOOST_THROW_EXCEPTION(mg::egl_error("Nested Mir Display Error: Failed to initialize EGL."));
394 }
395
396 egl_context_ = eglCreateContext(egl_display, choose_windowed_es_config(format), EGL_NO_CONTEXT, detail::nested_egl_context_attribs);
397
398 if (egl_context_ == EGL_NO_CONTEXT)
399- BOOST_THROW_EXCEPTION(std::runtime_error("Failed to create shared EGL context"));
400+ BOOST_THROW_EXCEPTION(mg::egl_error("Failed to create shared EGL context"));
401 }
402
403 EGLConfig mgn::detail::EGLDisplayHandle::choose_windowed_es_config(MirPixelFormat format) const
404@@ -104,7 +105,7 @@
405
406 int res = eglChooseConfig(egl_display, nested_egl_config_attribs, &result, 1, &n);
407 if ((res != EGL_TRUE) || (n != 1))
408- BOOST_THROW_EXCEPTION(std::runtime_error("Nested Mir Display Error: Failed to choose EGL configuration."));
409+ BOOST_THROW_EXCEPTION(mg::egl_error("Nested Mir Display Error: Failed to choose EGL configuration."));
410
411 return result;
412 }
413
414=== modified file 'src/server/graphics/nested/display_buffer.cpp'
415--- src/server/graphics/nested/display_buffer.cpp 2015-04-10 01:59:08 +0000
416+++ src/server/graphics/nested/display_buffer.cpp 2015-04-17 15:49:38 +0000
417@@ -21,6 +21,7 @@
418 #include "host_connection.h"
419 #include "mir/input/input_dispatcher.h"
420 #include "mir/graphics/pixel_format_utils.h"
421+#include "mir/graphics/egl_error.h"
422 #include "mir/events/event_private.h"
423
424 #include <boost/throw_exception.hpp>
425@@ -56,7 +57,7 @@
426 void mgn::detail::DisplayBuffer::make_current()
427 {
428 if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context) != EGL_TRUE)
429- BOOST_THROW_EXCEPTION(std::runtime_error("Nested Mir Display Error: Failed to update EGL surface.\n"));
430+ BOOST_THROW_EXCEPTION(mg::egl_error("Nested Mir Display Error: Failed to update EGL surface"));
431 }
432
433 void mgn::detail::DisplayBuffer::release_current()
434
435=== modified file 'src/server/graphics/offscreen/display.cpp'
436--- src/server/graphics/offscreen/display.cpp 2015-03-31 02:35:42 +0000
437+++ src/server/graphics/offscreen/display.cpp 2015-04-17 15:49:38 +0000
438@@ -19,6 +19,7 @@
439 #include "display.h"
440 #include "display_buffer.h"
441 #include "mir/graphics/display_configuration_policy.h"
442+#include "mir/graphics/egl_error.h"
443 #include "mir/geometry/size.h"
444
445 #include <boost/throw_exception.hpp>
446@@ -45,7 +46,7 @@
447 : egl_display{eglGetDisplay(native_display)}
448 {
449 if (egl_display == EGL_NO_DISPLAY)
450- BOOST_THROW_EXCEPTION(std::runtime_error("Failed to get EGL display"));
451+ BOOST_THROW_EXCEPTION(mg::egl_error("Failed to get EGL display"));
452 }
453
454 mgo::detail::EGLDisplayHandle::EGLDisplayHandle(EGLDisplayHandle&& other)
455@@ -59,7 +60,7 @@
456 int major, minor;
457
458 if (eglInitialize(egl_display, &major, &minor) == EGL_FALSE)
459- BOOST_THROW_EXCEPTION(std::runtime_error("Failed to initialize EGL"));
460+ BOOST_THROW_EXCEPTION(mg::egl_error("Failed to initialize EGL"));
461
462 if ((major != 1) || (minor != 4))
463 BOOST_THROW_EXCEPTION(std::runtime_error("EGL version 1.4 needed"));
464
465=== modified file 'src/server/graphics/surfaceless_egl_context.cpp'
466--- src/server/graphics/surfaceless_egl_context.cpp 2015-04-13 14:26:52 +0000
467+++ src/server/graphics/surfaceless_egl_context.cpp 2015-04-17 15:49:38 +0000
468@@ -18,6 +18,7 @@
469
470 #include "mir/graphics/surfaceless_egl_context.h"
471 #include "mir/graphics/gl_extensions_base.h"
472+#include "mir/graphics/egl_error.h"
473
474 #include <boost/throw_exception.hpp>
475 #include <stdexcept>
476@@ -99,7 +100,7 @@
477 if (eglChooseConfig(egl_display, attribs, &egl_config, 1, &num_egl_configs) == EGL_FALSE ||
478 num_egl_configs != 1)
479 {
480- BOOST_THROW_EXCEPTION(std::runtime_error("Failed to choose EGL config"));
481+ BOOST_THROW_EXCEPTION(mg::egl_error("Failed to choose EGL config"));
482 }
483
484 return egl_config;
485@@ -186,7 +187,7 @@
486 egl_context) == EGL_FALSE)
487 {
488 BOOST_THROW_EXCEPTION(
489- std::runtime_error("could not make context current\n"));
490+ mg::egl_error("could not make context current"));
491 }
492 }
493
494
495=== modified file 'tests/unit-tests/graphics/CMakeLists.txt'
496--- tests/unit-tests/graphics/CMakeLists.txt 2015-04-09 06:20:31 +0000
497+++ tests/unit-tests/graphics/CMakeLists.txt 2015-04-17 15:49:38 +0000
498@@ -2,6 +2,7 @@
499 ${CMAKE_CURRENT_SOURCE_DIR}/test_graphics_platform.cpp
500 ${CMAKE_CURRENT_SOURCE_DIR}/test_display_configuration.cpp
501 ${CMAKE_CURRENT_SOURCE_DIR}/test_egl_extensions.cpp
502+ ${CMAKE_CURRENT_SOURCE_DIR}/test_egl_error.cpp
503 ${CMAKE_CURRENT_SOURCE_DIR}/test_display.cpp
504 ${CMAKE_CURRENT_SOURCE_DIR}/test_default_display_configuration_policy.cpp
505 ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer_id.cpp
506
507=== added file 'tests/unit-tests/graphics/test_egl_error.cpp'
508--- tests/unit-tests/graphics/test_egl_error.cpp 1970-01-01 00:00:00 +0000
509+++ tests/unit-tests/graphics/test_egl_error.cpp 2015-04-17 15:49:38 +0000
510@@ -0,0 +1,115 @@
511+/*
512+ * Copyright © 2015 Canonical Ltd.
513+ *
514+ * This program is free software: you can redistribute it and/or modify it
515+ * under the terms of the GNU General Public License version 3,
516+ * as published by the Free Software Foundation.
517+ *
518+ * This program is distributed in the hope that it will be useful,
519+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
520+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
521+ * GNU General Public License for more details.
522+ *
523+ * You should have received a copy of the GNU General Public License
524+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
525+ *
526+ * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
527+ */
528+
529+#include "mir/graphics/egl_error.h"
530+#include "mir_test_doubles/mock_egl.h"
531+
532+#include <gtest/gtest.h>
533+#include <gmock/gmock.h>
534+
535+namespace mg = mir::graphics;
536+namespace mtd = mir::test::doubles;
537+
538+namespace
539+{
540+
541+std::string to_hex_string(int n)
542+{
543+ std::stringstream ss;
544+ ss << std::showbase << std::hex << n;
545+ return ss.str();
546+}
547+
548+struct EGLErrorTest : ::testing::Test
549+{
550+ testing::NiceMock<mtd::MockEGL> mock_egl;
551+
552+ std::string const user_message{"Something failed"};
553+ std::string const egl_error_code_str{"EGL_BAD_MATCH"};
554+ int const egl_error_code{EGL_BAD_MATCH};
555+};
556+
557+}
558+
559+TEST_F(EGLErrorTest, produces_correct_error_code)
560+{
561+ using namespace testing;
562+
563+ EXPECT_CALL(mock_egl, eglGetError())
564+ .WillOnce(Return(egl_error_code));
565+
566+ std::error_code ec;
567+
568+ try
569+ {
570+ throw mg::egl_error("");
571+ }
572+ catch (std::system_error const& error)
573+ {
574+ ec = error.code();
575+ }
576+
577+ EXPECT_THAT(ec.value(), Eq(egl_error_code));
578+}
579+
580+TEST_F(EGLErrorTest, produces_message_with_user_string_and_error_code_for_known_error)
581+{
582+ using namespace testing;
583+
584+ EXPECT_CALL(mock_egl, eglGetError())
585+ .WillOnce(Return(egl_error_code));
586+
587+ std::string error_message;
588+
589+ try
590+ {
591+ throw mg::egl_error(user_message);
592+ }
593+ catch (std::system_error const& error)
594+ {
595+ error_message = error.what();
596+ }
597+
598+ EXPECT_THAT(error_message, HasSubstr(user_message));
599+ EXPECT_THAT(error_message, HasSubstr(egl_error_code_str));
600+ EXPECT_THAT(error_message, HasSubstr(to_hex_string(egl_error_code)));
601+}
602+
603+TEST_F(EGLErrorTest, produces_message_with_user_string_and_error_code_for_unknown_error)
604+{
605+ using namespace testing;
606+
607+ int const unknown_egl_error_code{0x131313};
608+
609+ EXPECT_CALL(mock_egl, eglGetError())
610+ .WillOnce(Return(unknown_egl_error_code));
611+
612+ std::string error_message;
613+
614+ try
615+ {
616+ throw mg::egl_error(user_message);
617+ }
618+ catch (std::system_error const& error)
619+ {
620+ error_message = error.what();
621+ }
622+
623+ EXPECT_THAT(error_message, HasSubstr(user_message));
624+ EXPECT_THAT(error_message, HasSubstr(to_hex_string(unknown_egl_error_code)));
625+}

Subscribers

People subscribed via source and target branches