Mir

Merge lp:~mterry/mir/fix-nested-crash into lp:mir

Proposed by Michael Terry
Status: Merged
Approved by: Daniel van Vugt
Approved revision: no longer in the source branch.
Merged at revision: 1225
Proposed branch: lp:~mterry/mir/fix-nested-crash
Merge into: lp:mir
Diff against target: 57 lines (+25/-3)
1 file modified
src/server/graphics/nested/nested_display.cpp (+25/-3)
To merge this branch: bzr merge lp:~mterry/mir/fix-nested-crash
Reviewer Review Type Date Requested Status
Daniel van Vugt Approve
Kevin DuBois (community) Approve
Review via email: mp+195320@code.launchpad.net

Commit message

Fix a crash due to a failed eglMakeCurrent() call when in nested mode.

Description of the change

Fix a crash due to a failed eglMakeCurrent() call when in nested mode.

I'm not sure how to give reproduction steps that don't involve all of unity8. But if you happen to have set up unity8 in nested mode, you can see this by doing:
1) Open an app
2) Swipe from left (launcher) or right (switch app)

Either swipe will crash unity8, due to a "cannot bind buffer to texture without EGL context" error. kdub helped me trace it down. Apparently NestedGLContext should act a little more like AndroidGLContext and use a dummy pbuffer surface instead of EGL_NO_SURFACE. It's eglMakeCurrent() call was silently failing, and this caused crashes later.

So I've made NestedGLContext do some of the things AndroidGLContext does:
1) Release in destructor
2) Use a dummy pbuffer surface
3) Throw an exception if eglMakeCurrent fails.

I've tested and it fixes the crash for me.

To post a comment you must log in.
Revision history for this message
Chris Halse Rogers (raof) wrote :

Hm. This should be necessary only if the underlying EGL doesn't support EGL_KHR_surfaceless_context, and the Mesa stack (should!) supports that.

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

> Hm. This should be necessary only if the underlying EGL doesn't support
> EGL_KHR_surfaceless_context, and the Mesa stack (should!) supports that.

Yes. all the implementations of mg::GLContext needs to be de-duped. I think we should wait for 1 branch I have that dedupes 3 android glcontext implementations and for alf's offscreen display work to land before we go and consolidate this.

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

looks okay to me... we should have a test though. :/
I think we could get this under test when we do the aforementioned consolidation, so i'll +1

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

namespace { static ... is redundant. You only need one or the other :)

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

OK, only minor style complaints:

1. Please don't overload the initializer list with function calls. It would be clearer to call the functions in the constructor.
27 + egl_context{egl_display, eglCreateContext(egl_display, egl_config, EGL_NO_CONTEXT, detail::nested_egl_context_attribs)},
28 + egl_surface{egl_display, eglCreatePbufferSurface(egl_display, egl_config, dummy_pbuffer_attribs)}

2. "namespace { static" is redundant. You only need one or the other.

review: Needs Fixing
Revision history for this message
Michael Terry (mterry) wrote :

> 1. Please don't overload the initializer list with function calls. It would be clearer to call the functions in the constructor.

Er, the function-in-initializer-list pattern is all over the place in mir, right? Especially in surrounding code and nearby android_display.cpp. Also, EGLSurfaceStore doesn't define a public operator= nor the ability to set the surface pointer after the fact. So I'm not sure how to move the function to the constructor?

> 2. "namespace { static" is redundant. You only need one or the other.

Fixed. If you're on a cleaning rampage, note that mine was just copied code from android_display.cpp.

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

Oh, I was confused by the braces. I thought even in C++11 that a constructor call still had to use parentheses:
  egl_context(...)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/rules' (properties changed: -x to +x)
2=== modified file 'src/server/graphics/nested/nested_display.cpp'
3--- src/server/graphics/nested/nested_display.cpp 2013-10-25 09:40:26 +0000
4+++ src/server/graphics/nested/nested_display.cpp 2013-11-15 04:26:53 +0000
5@@ -273,6 +273,16 @@
6 return std::weak_ptr<Cursor>();
7 }
8
9+namespace
10+{
11+EGLint const dummy_pbuffer_attribs[] =
12+{
13+ EGL_WIDTH, 1,
14+ EGL_HEIGHT, 1,
15+ EGL_NONE
16+};
17+}
18+
19 std::unique_ptr<mg::GLContext> mgn::NestedDisplay::create_gl_context()
20 {
21 class NestedGLContext : public mg::GLContext
22@@ -281,13 +291,24 @@
23 NestedGLContext(detail::EGLDisplayHandle const& egl_display) :
24 egl_display{egl_display},
25 egl_config{egl_display.choose_config(detail::nested_egl_config_attribs)},
26- egl_context{egl_display, eglCreateContext(egl_display, egl_config, EGL_NO_CONTEXT, detail::nested_egl_context_attribs)}
27- {
28+ egl_context{egl_display, eglCreateContext(egl_display, egl_config, EGL_NO_CONTEXT, detail::nested_egl_context_attribs)},
29+ egl_surface{egl_display, eglCreatePbufferSurface(egl_display, egl_config, dummy_pbuffer_attribs)}
30+ {
31+ }
32+
33+ ~NestedGLContext() noexcept
34+ {
35+ if (eglGetCurrentContext() == egl_context)
36+ release_current();
37 }
38
39 void make_current() override
40 {
41- eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, egl_context);
42+ if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context) == EGL_FALSE)
43+ {
44+ BOOST_THROW_EXCEPTION(
45+ std::runtime_error("could not activate dummy surface with eglMakeCurrent\n"));
46+ }
47 }
48
49 void release_current() override
50@@ -299,6 +320,7 @@
51 EGLDisplay const egl_display;
52 EGLConfig const egl_config;
53 EGLContextStore const egl_context;
54+ EGLSurfaceStore const egl_surface;
55 };
56
57 return std::unique_ptr<mg::GLContext>{new NestedGLContext(egl_display)};

Subscribers

People subscribed via source and target branches