Mir

Merge lp:~afrantzis/mir/fix-1169186 into lp:~mir-team/mir/trunk

Proposed by Alexandros Frantzis
Status: Merged
Approved by: Alexandros Frantzis
Approved revision: no longer in the source branch.
Merged at revision: 594
Proposed branch: lp:~afrantzis/mir/fix-1169186
Merge into: lp:~mir-team/mir/trunk
Diff against target: 194 lines (+81/-0)
9 files modified
include/server/mir/graphics/display_buffer.h (+1/-0)
include/test/mir_test_doubles/mock_display_buffer.h (+1/-0)
include/test/mir_test_doubles/null_display_buffer.h (+1/-0)
src/server/compositor/multi_threaded_compositor.cpp (+6/-0)
src/server/graphics/android/android_display.cpp (+5/-0)
src/server/graphics/android/android_display.h (+2/-0)
src/server/graphics/gbm/gbm_display_buffer.cpp (+5/-0)
src/server/graphics/gbm/gbm_display_buffer.h (+1/-0)
tests/unit-tests/compositor/test_multi_threaded_compositor.cpp (+59/-0)
To merge this branch: bzr merge lp:~afrantzis/mir/fix-1169186
Reviewer Review Type Date Requested Status
Alan Griffiths Approve
Robert Ancell Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+158934@code.launchpad.net

Commit message

compositor: Release the display buffers' contexts when stopping the compositor

Release the display buffers' contexts when stopping the compositor, so that
the contexts can be made current to potentially different threads if the
compositor is restarted.

Description of the change

compositor: Release the display buffers' contexts when stopping the compositor

Release the display buffers' contexts when stopping the compositor, so that
the contexts can be made current to potentially different threads if the
compositor is restarted.

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 :

The functionality looks OK, but I don't think the name is right.

Essentially we've a pair "make_current()/release_current()" - I don't have a good antonym for "current" so I'll suggest "make_not_current()" as an improvement on release_current().

Actually, I suspect "make_current()" of being a bad name too - but am struggling for improvements. "become_current()"? "set_as_current()"?

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

> The functionality looks OK, but I don't think the name is right.
>
> Essentially we've a pair "make_current()/release_current()" - I don't have a
> good antonym for "current" so I'll suggest "make_not_current()" as an
> improvement on release_current().
>
> Actually, I suspect "make_current()" of being a bad name too - but am
> struggling for improvements. "become_current()"? "set_as_current()"?

I'd rather keep make_current since it's based on egl/glxMakeCurrent, i.e., it's a well known term in the world of graphics. The term "release" is also widely used in this context, e.g. from the EGL spec: "To release the current context without assigning a new one...", although I am more amenable to changing the "release_current" name.

I agree they are not the most intuitive names, but the big win is that someone familiar with the GL concepts and terminology can instantly recognize them and get a very good idea of what to expect (because they essentially are wrappers around the respective GL functionality).

Revision history for this message
Robert Ancell (robert-ancell) wrote :

The naming sounds a little weird to me to, but the functionality looks correct.

The eglMakeCurrent man page describes it as "attach an EGL rendering context to EGL surfaces". So attach () and detach () could be useful method names.

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

> I agree they are not the most intuitive names, but the big win is that someone
> familiar with the GL concepts and terminology can instantly recognize them and
> get a very good idea of what to expect (because they essentially are wrappers
> around the respective GL functionality).

I'll accept the "prior art" argument.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/server/mir/graphics/display_buffer.h'
2--- include/server/mir/graphics/display_buffer.h 2013-04-12 04:55:11 +0000
3+++ include/server/mir/graphics/display_buffer.h 2013-04-15 14:22:45 +0000
4@@ -33,6 +33,7 @@
5
6 virtual geometry::Rectangle view_area() const = 0;
7 virtual void make_current() = 0;
8+ virtual void release_current() = 0;
9 virtual void clear() = 0;
10 virtual bool post_update() = 0;
11
12
13=== modified file 'include/test/mir_test_doubles/mock_display_buffer.h'
14--- include/test/mir_test_doubles/mock_display_buffer.h 2013-04-12 04:55:11 +0000
15+++ include/test/mir_test_doubles/mock_display_buffer.h 2013-04-15 14:22:45 +0000
16@@ -35,6 +35,7 @@
17 public:
18 MOCK_CONST_METHOD0(view_area, geometry::Rectangle());
19 MOCK_METHOD0(make_current, void());
20+ MOCK_METHOD0(release_current, void());
21 MOCK_METHOD0(clear, void());
22 MOCK_METHOD0(post_update, bool());
23 };
24
25=== modified file 'include/test/mir_test_doubles/null_display_buffer.h'
26--- include/test/mir_test_doubles/null_display_buffer.h 2013-04-12 04:55:11 +0000
27+++ include/test/mir_test_doubles/null_display_buffer.h 2013-04-15 14:22:45 +0000
28@@ -33,6 +33,7 @@
29 public:
30 geometry::Rectangle view_area() const { return geometry::Rectangle(); }
31 void make_current() {}
32+ void release_current() {}
33 void clear() {}
34 bool post_update() { return true; }
35 };
36
37=== modified file 'src/server/compositor/multi_threaded_compositor.cpp'
38--- src/server/compositor/multi_threaded_compositor.cpp 2013-04-12 04:55:11 +0000
39+++ src/server/compositor/multi_threaded_compositor.cpp 2013-04-15 14:22:45 +0000
40@@ -68,6 +68,12 @@
41 lock.lock();
42 }
43 }
44+
45+ /*
46+ * Release the display buffer from this thread, so that it can be
47+ * made current in another thread.
48+ */
49+ buffer.release_current();
50 }
51
52 void schedule_compositing()
53
54=== modified file 'src/server/graphics/android/android_display.cpp'
55--- src/server/graphics/android/android_display.cpp 2013-04-15 08:48:37 +0000
56+++ src/server/graphics/android/android_display.cpp 2013-04-15 14:22:45 +0000
57@@ -162,3 +162,8 @@
58 if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context) == EGL_FALSE)
59 BOOST_THROW_EXCEPTION(std::runtime_error("could not activate surface with eglMakeCurrent\n"));
60 }
61+
62+void mga::AndroidDisplay::release_current()
63+{
64+ eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
65+}
66
67=== modified file 'src/server/graphics/android/android_display.h'
68--- src/server/graphics/android/android_display.h 2013-04-15 08:48:37 +0000
69+++ src/server/graphics/android/android_display.h 2013-04-15 14:22:45 +0000
70@@ -59,6 +59,8 @@
71 void resume();
72
73 void make_current();
74+ void release_current();
75+
76 private:
77 std::shared_ptr<AndroidFramebufferWindowQuery> native_window;
78 EGLDisplay egl_display;
79
80=== modified file 'src/server/graphics/gbm/gbm_display_buffer.cpp'
81--- src/server/graphics/gbm/gbm_display_buffer.cpp 2013-04-15 08:48:37 +0000
82+++ src/server/graphics/gbm/gbm_display_buffer.cpp 2013-04-15 14:22:45 +0000
83@@ -276,6 +276,11 @@
84 }
85 }
86
87+void mgg::GBMDisplayBuffer::release_current()
88+{
89+ egl.release_current();
90+}
91+
92 void mgg::GBMDisplayBuffer::schedule_set_crtc()
93 {
94 needs_set_crtc = true;
95
96=== modified file 'src/server/graphics/gbm/gbm_display_buffer.h'
97--- src/server/graphics/gbm/gbm_display_buffer.h 2013-04-15 08:48:37 +0000
98+++ src/server/graphics/gbm/gbm_display_buffer.h 2013-04-15 14:22:45 +0000
99@@ -53,6 +53,7 @@
100
101 geometry::Rectangle view_area() const;
102 void make_current();
103+ void release_current();
104 void clear();
105 bool post_update();
106
107
108=== modified file 'tests/unit-tests/compositor/test_multi_threaded_compositor.cpp'
109--- tests/unit-tests/compositor/test_multi_threaded_compositor.cpp 2013-04-11 10:56:45 +0000
110+++ tests/unit-tests/compositor/test_multi_threaded_compositor.cpp 2013-04-15 14:22:45 +0000
111@@ -21,6 +21,7 @@
112 #include "mir/compositor/renderables.h"
113 #include "mir/graphics/display.h"
114 #include "mir_test_doubles/null_display_buffer.h"
115+#include "mir_test_doubles/mock_display_buffer.h"
116
117 #include <unordered_map>
118 #include <unordered_set>
119@@ -65,6 +66,38 @@
120 std::vector<mtd::NullDisplayBuffer> buffers;
121 };
122
123+class StubDisplayWithMockBuffers : public mg::Display
124+{
125+ public:
126+ StubDisplayWithMockBuffers(unsigned int nbuffers) : buffers{nbuffers} {}
127+ geom::Rectangle view_area() const { return geom::Rectangle(); }
128+ void for_each_display_buffer(std::function<void(mg::DisplayBuffer&)> const& f)
129+ {
130+ for (auto& db : buffers)
131+ f(db);
132+ }
133+ std::shared_ptr<mg::DisplayConfiguration> configuration()
134+ {
135+ return std::shared_ptr<mg::DisplayConfiguration>();
136+ }
137+ void register_pause_resume_handlers(mir::MainLoop&,
138+ std::function<void()> const&,
139+ std::function<void()> const&)
140+ {
141+ }
142+ void pause() {}
143+ void resume() {}
144+
145+ void for_each_mock_buffer(std::function<void(mtd::MockDisplayBuffer&)> const& f)
146+ {
147+ for (auto& db : buffers)
148+ f(db);
149+ }
150+
151+private:
152+ std::vector<mtd::MockDisplayBuffer> buffers;
153+};
154+
155 class StubRenderables : public mc::Renderables
156 {
157 public:
158@@ -216,6 +249,12 @@
159 unsigned int render_count;
160 };
161
162+class NullCompositingStrategy : public mc::CompositingStrategy
163+{
164+public:
165+ void render(mg::DisplayBuffer&) {}
166+};
167+
168 }
169
170 TEST(MultiThreadedCompositor, compositing_happens_in_different_threads)
171@@ -303,3 +342,23 @@
172
173 compositor.stop();
174 }
175+
176+TEST(MultiThreadedCompositor, releases_display_buffer_context_when_stopping)
177+{
178+ using namespace testing;
179+
180+ unsigned int const nbuffers{3};
181+
182+ auto display = std::make_shared<StubDisplayWithMockBuffers>(nbuffers);
183+ auto renderables = std::make_shared<StubRenderables>();
184+ auto strategy = std::make_shared<NullCompositingStrategy>();
185+ mc::MultiThreadedCompositor compositor{display, renderables, strategy};
186+
187+ display->for_each_mock_buffer([](mtd::MockDisplayBuffer& mock_buf)
188+ {
189+ EXPECT_CALL(mock_buf, release_current()).Times(1);
190+ });
191+
192+ compositor.start();
193+ compositor.stop();
194+}

Subscribers

People subscribed via source and target branches