Mir

Merge lp:~alan-griffiths/mir/dlopen-graphicsplatform into lp:~mir-team/mir/trunk

Proposed by Alan Griffiths
Status: Merged
Approved by: Kevin DuBois
Approved revision: no longer in the source branch.
Merged at revision: 767
Proposed branch: lp:~alan-griffiths/mir/dlopen-graphicsplatform
Merge into: lp:~mir-team/mir/trunk
Diff against target: 514 lines (+260/-24)
16 files modified
CMakeLists.txt (+1/-1)
debian/libmirserver0.install (+1/-0)
examples/render_to_fb.cpp (+4/-1)
include/server/mir/graphics/platform.h (+4/-4)
include/server/mir/shared_library.h (+55/-0)
src/server/CMakeLists.txt (+3/-1)
src/server/default_server_configuration.cpp (+5/-7)
src/server/graphics/CMakeLists.txt (+2/-1)
src/server/graphics/android/CMakeLists.txt (+5/-2)
src/server/graphics/android/android_platform.cpp (+3/-3)
src/server/graphics/gbm/CMakeLists.txt (+4/-3)
src/server/graphics/gbm/gbm_platform.cpp (+1/-1)
src/server/shared_library.cpp (+55/-0)
tests/integration-tests/CMakeLists.txt (+1/-0)
tests/unit-tests/CMakeLists.txt (+2/-0)
tests/unit-tests/shared_library_test.cpp (+114/-0)
To merge this branch: bzr merge lp:~alan-griffiths/mir/dlopen-graphicsplatform
Reviewer Review Type Date Requested Status
Kevin DuBois (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Alexandros Frantzis (community) Approve
Review via email: mp+170797@code.launchpad.net

Commit message

graphics, config: Dynamically load the graphics platform

Description of the change

graphics, config: Dynamically load the graphics platform

Will follow up with MP to make the library configurable

To post a comment you must log in.
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Looks good, and works just fine locally.

review: Approve
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: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote :

looks good!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2013-06-19 09:57:32 +0000
3+++ CMakeLists.txt 2013-06-21 15:26:27 +0000
4@@ -42,7 +42,7 @@
5 include (cmake/PrePush.cmake)
6
7 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Werror -Wall -pedantic -Wextra -fPIC")
8-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -std=c++0x -Werror -Wall -fno-strict-aliasing -pedantic -Wnon-virtual-dtor -Wextra -fPIC")
9+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -std=c++0x -Werror -Wall -fno-strict-aliasing -pedantic -Wnon-virtual-dtor -Wextra -fPIC -Wno-return-type-c-linkage")
10 set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
11
12 #####################################################################
13
14=== modified file 'debian/libmirserver0.install'
15--- debian/libmirserver0.install 2013-05-22 10:24:51 +0000
16+++ debian/libmirserver0.install 2013-06-21 15:26:27 +0000
17@@ -1,2 +1,3 @@
18 usr/lib/libmirserver.so.*
19+usr/lib/libmirplatformgraphics.so*
20 usr/lib/libmirserverlttng.so
21
22=== modified file 'examples/render_to_fb.cpp'
23--- examples/render_to_fb.cpp 2013-06-20 02:16:09 +0000
24+++ examples/render_to_fb.cpp 2013-06-21 15:26:27 +0000
25@@ -16,6 +16,7 @@
26 * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
27 */
28
29+#include "mir/shared_library.h"
30 #include "mir/graphics/platform.h"
31 #include "mir/graphics/display.h"
32 #include "mir/graphics/display_buffer.h"
33@@ -56,8 +57,10 @@
34 sigaction(SIGINT, &sa, NULL);
35 sigaction(SIGTERM, &sa, NULL);
36
37+ mir::SharedLibrary libmirplatformgraphics("libmirplatformgraphics.so");
38 auto logger = std::make_shared<ml::DumbConsoleLogger>();
39- auto platform = mg::create_platform(std::make_shared<mo::ProgramOption>(), std::make_shared<ml::DisplayReport>(logger));
40+ auto report = std::make_shared<ml::DisplayReport>(logger);
41+ auto platform = libmirplatformgraphics.load_function<mg::CreatePlatform>("create_platform")(std::make_shared<mo::ProgramOption>(), report);
42 auto display = platform->create_display();
43
44 mir::draw::glAnimationBasic gl_animation;
45
46=== modified file 'include/server/mir/graphics/platform.h'
47--- include/server/mir/graphics/platform.h 2013-06-20 23:34:40 +0000
48+++ include/server/mir/graphics/platform.h 2013-06-21 15:26:27 +0000
49@@ -101,7 +101,7 @@
50 */
51 virtual void fill_ipc_package(std::shared_ptr<compositor::BufferIPCPacker> const& packer,
52 std::shared_ptr<compositor::Buffer> const& buffer) const = 0;
53-
54+
55 /**
56 * Creates the in-process client support object.
57 */
58@@ -109,7 +109,7 @@
59 };
60
61 /**
62- * Creates and returns a new graphics platform.
63+ * Function prototype used to return a new graphics platform.
64 *
65 * \param [in] options options to use for this platform
66 * \param [in] report the object to use to report interesting events from the display subsystem
67@@ -118,8 +118,8 @@
68 *
69 * \ingroup platform_enablement
70 */
71-std::shared_ptr<Platform> create_platform(std::shared_ptr<options::Option> const& options, std::shared_ptr<DisplayReport> const& report);
72-
73+extern "C" typedef std::shared_ptr<Platform>(*CreatePlatform)(std::shared_ptr<options::Option> const& options, std::shared_ptr<DisplayReport> const& report);
74+extern "C" std::shared_ptr<Platform> create_platform (std::shared_ptr<options::Option> const& options, std::shared_ptr<DisplayReport> const& report);
75 }
76 }
77
78
79=== added file 'include/server/mir/shared_library.h'
80--- include/server/mir/shared_library.h 1970-01-01 00:00:00 +0000
81+++ include/server/mir/shared_library.h 2013-06-21 15:26:27 +0000
82@@ -0,0 +1,55 @@
83+/*
84+ * Copyright © 2013 Canonical Ltd.
85+ *
86+ * This program is free software: you can redistribute it and/or modify it
87+ * under the terms of the GNU General Public License version 3,
88+ * as published by the Free Software Foundation.
89+ *
90+ * This program is distributed in the hope that it will be useful,
91+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
92+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
93+ * GNU General Public License for more details.
94+ *
95+ * You should have received a copy of the GNU General Public License
96+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
97+ *
98+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
99+ */
100+
101+#ifndef MIR_SHARED_LIBRARY_H_
102+#define MIR_SHARED_LIBRARY_H_
103+
104+#include <string>
105+
106+namespace mir
107+{
108+class SharedLibrary
109+{
110+public:
111+ explicit SharedLibrary(char const* library_name);
112+ explicit SharedLibrary(std::string const& library_name);
113+ ~SharedLibrary();
114+
115+ template<typename FunctionPtr>
116+ FunctionPtr load_function(char const* function_name) const
117+ {
118+ FunctionPtr result{};
119+ (void*&)result = load_symbol(function_name);
120+ return result;
121+ }
122+
123+ template<typename FunctionPtr>
124+ FunctionPtr load_function(std::string const& function_name) const
125+ {
126+ return load_function<FunctionPtr>(function_name.c_str());
127+ }
128+private:
129+ void* const so;
130+ void* load_symbol(char const* function_name) const;
131+ SharedLibrary(SharedLibrary const&) = delete;
132+ SharedLibrary& operator=(SharedLibrary const&) = delete;
133+};
134+}
135+
136+
137+#endif /* MIR_SHARED_LIBRARY_H_ */
138
139=== modified file 'src/server/CMakeLists.txt'
140--- src/server/CMakeLists.txt 2013-06-03 08:14:01 +0000
141+++ src/server/CMakeLists.txt 2013-06-21 15:26:27 +0000
142@@ -28,6 +28,7 @@
143 display_server.cpp
144 default_server_configuration.cpp
145 asio_main_loop.cpp
146+ shared_library.cpp
147 )
148
149 set(MIRSERVER_LINKAGE SHARED)
150@@ -50,9 +51,10 @@
151 )
152
153 list(APPEND MIRSERVER_LINKS
154- mirplatformgraphics
155 mirprotobuf
156 3rd_party
157+ ${EGL_LDFLAGS} ${EGL_LIBRARIES}
158+ ${GLESv2_LDFLAGS} ${GLESv2_LIBRARIES}
159 )
160
161 if(${MIRSERVER_LINKAGE} STREQUAL SHARED)
162
163=== modified file 'src/server/default_server_configuration.cpp'
164--- src/server/default_server_configuration.cpp 2013-06-20 23:34:12 +0000
165+++ src/server/default_server_configuration.cpp 2013-06-21 15:26:27 +0000
166@@ -19,6 +19,7 @@
167 #include "mir/default_server_configuration.h"
168 #include "mir/abnormal_exit.h"
169 #include "mir/asio_main_loop.h"
170+#include "mir/shared_library.h"
171
172 #include "mir/options/program_option.h"
173 #include "mir/compositor/buffer_allocation_strategy.h"
174@@ -290,18 +291,15 @@
175 });
176 }
177
178+
179 std::shared_ptr<mg::Platform> mir::DefaultServerConfiguration::the_graphics_platform()
180 {
181 return graphics_platform(
182 [this]()
183 {
184- // TODO I doubt we need the extra level of indirection provided by
185- // mg::create_platform() - we just need to move the implementation
186- // of DefaultServerConfiguration::the_graphics_platform() to the
187- // graphics libraries.
188- // Alternatively, if we want to dynamically load the graphics library
189- // then this would be the place to do that.
190- return mg::create_platform(the_options(), the_display_report());
191+ static SharedLibrary libmirplatformgraphics("libmirplatformgraphics.so");
192+ static auto create_platform = libmirplatformgraphics.load_function<mg::CreatePlatform>("create_platform");
193+ return create_platform(the_options(), the_display_report());
194 });
195 }
196
197
198=== modified file 'src/server/graphics/CMakeLists.txt'
199--- src/server/graphics/CMakeLists.txt 2013-06-14 18:24:09 +0000
200+++ src/server/graphics/CMakeLists.txt 2013-06-21 15:26:27 +0000
201@@ -32,5 +32,6 @@
202 mirlogging
203
204 ${MIR_COMMON_PLATFORM_LIBRARIES}
205- ${GLESv2_LIBRARIES}
206+ ${EGL_LDFLAGS} ${EGL_LIBRARIES}
207+ ${GLESv2_LDFLAGS} ${GLESv2_LIBRARIES}
208 )
209
210=== modified file 'src/server/graphics/android/CMakeLists.txt'
211--- src/server/graphics/android/CMakeLists.txt 2013-05-21 21:43:25 +0000
212+++ src/server/graphics/android/CMakeLists.txt 2013-06-21 15:26:27 +0000
213@@ -5,7 +5,7 @@
214 )
215
216 add_library(
217- mirplatformgraphics STATIC
218+ mirplatformgraphics SHARED
219
220 android_platform.cpp
221 android_buffer_allocator.cpp
222@@ -33,9 +33,12 @@
223
224 target_link_libraries(
225 mirplatformgraphics
226- mircompositor
227+ mirserver
228+ mirsharedandroid
229
230 ${LIBHARDWARE_LIBRARIES}
231 ${EGL_LDFLAGS} ${EGL_LIBRARIES}
232 ${GLESv2_LDFLAGS} ${GLESv2_LIBRARIES}
233 )
234+
235+install(TARGETS mirplatformgraphics LIBRARY DESTINATION lib)
236
237=== modified file 'src/server/graphics/android/android_platform.cpp'
238--- src/server/graphics/android/android_platform.cpp 2013-06-20 23:34:40 +0000
239+++ src/server/graphics/android/android_platform.cpp 2013-06-21 15:26:27 +0000
240@@ -86,11 +86,11 @@
241 for(auto i=0; i<buffer_handle->numFds; i++)
242 {
243 packer->pack_fd(buffer_handle->data[offset++]);
244- }
245+ }
246 for(auto i=0; i<buffer_handle->numInts; i++)
247 {
248 packer->pack_data(buffer_handle->data[offset++]);
249- }
250+ }
251
252 packer->pack_stride(buffer->stride());
253 }
254@@ -100,7 +100,7 @@
255 return std::make_shared<mga::InternalClient>();
256 }
257
258-std::shared_ptr<mg::Platform> mg::create_platform(std::shared_ptr<mo::Option> const& /*options*/, std::shared_ptr<DisplayReport> const& display_report)
259+extern "C" std::shared_ptr<mg::Platform> mg::create_platform(std::shared_ptr<mo::Option> const& /*options*/, std::shared_ptr<DisplayReport> const& display_report)
260 {
261 return std::make_shared<mga::AndroidPlatform>(display_report);
262 }
263
264=== modified file 'src/server/graphics/gbm/CMakeLists.txt'
265--- src/server/graphics/gbm/CMakeLists.txt 2013-06-05 20:36:34 +0000
266+++ src/server/graphics/gbm/CMakeLists.txt 2013-06-21 15:26:27 +0000
267@@ -11,7 +11,7 @@
268
269
270 add_library(
271- mirplatformgraphics STATIC
272+ mirplatformgraphics SHARED
273
274 gbm_platform.cpp
275 gbm_buffer_allocator.cpp
276@@ -34,11 +34,12 @@
277
278 target_link_libraries(
279 mirplatformgraphics
280- mircompositor
281- mirlogging
282+ mirserver
283
284 ${DRM_LDFLAGS} ${DRM_LIBRARIES}
285 ${GBM_LDFLAGS} ${GBM_LIBRARIES}
286 ${EGL_LDFLAGS} ${EGL_LIBRARIES}
287 ${GLESv2_LDFLAGS} ${GLESv2_LIBRARIES}
288 )
289+
290+install(TARGETS mirplatformgraphics LIBRARY DESTINATION lib)
291
292=== modified file 'src/server/graphics/gbm/gbm_platform.cpp'
293--- src/server/graphics/gbm/gbm_platform.cpp 2013-06-20 23:34:40 +0000
294+++ src/server/graphics/gbm/gbm_platform.cpp 2013-06-21 15:26:27 +0000
295@@ -144,7 +144,7 @@
296 return std::make_shared<mgg::InternalClient>(internal_native_display);
297 }
298
299-std::shared_ptr<mg::Platform> mg::create_platform(std::shared_ptr<mo::Option> const& options, std::shared_ptr<DisplayReport> const& report)
300+extern "C" std::shared_ptr<mg::Platform> mg::create_platform(std::shared_ptr<mo::Option> const& options, std::shared_ptr<DisplayReport> const& report)
301 {
302 auto real_fops = std::make_shared<RealVTFileOperations>();
303 auto vt = std::make_shared<mgg::LinuxVirtualTerminal>(real_fops, options->get("vt", 0), report);
304
305=== added file 'src/server/shared_library.cpp'
306--- src/server/shared_library.cpp 1970-01-01 00:00:00 +0000
307+++ src/server/shared_library.cpp 2013-06-21 15:26:27 +0000
308@@ -0,0 +1,55 @@
309+/*
310+ * Copyright © 2013 Canonical Ltd.
311+ *
312+ * This program is free software: you can redistribute it and/or modify it
313+ * under the terms of the GNU General Public License version 3,
314+ * as published by the Free Software Foundation.
315+ *
316+ * This program is distributed in the hope that it will be useful,
317+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
318+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
319+ * GNU General Public License for more details.
320+ *
321+ * You should have received a copy of the GNU General Public License
322+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
323+ *
324+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
325+ */
326+
327+#include "mir/shared_library.h"
328+
329+#include <boost/throw_exception.hpp>
330+#include <boost/exception/info.hpp>
331+
332+#include <dlfcn.h>
333+
334+#include <stdexcept>
335+
336+mir::SharedLibrary::SharedLibrary(char const* library_name) :
337+ so(dlopen(library_name, RTLD_NOW))
338+{
339+ if (!so)
340+ {
341+ BOOST_THROW_EXCEPTION(std::runtime_error(dlerror()));
342+ }
343+}
344+
345+mir::SharedLibrary::SharedLibrary(std::string const& library_name) :
346+ SharedLibrary(library_name.c_str()) {}
347+
348+mir::SharedLibrary::~SharedLibrary()
349+{
350+ dlclose(so);
351+}
352+
353+void* mir::SharedLibrary::load_symbol(char const* function_name) const
354+{
355+ if (void* result = dlsym(so, function_name))
356+ {
357+ return result;
358+ }
359+ else
360+ {
361+ BOOST_THROW_EXCEPTION(std::runtime_error(dlerror()));
362+ }
363+}
364
365=== modified file 'tests/integration-tests/CMakeLists.txt'
366--- tests/integration-tests/CMakeLists.txt 2013-05-30 03:50:54 +0000
367+++ tests/integration-tests/CMakeLists.txt 2013-06-21 15:26:27 +0000
368@@ -47,6 +47,7 @@
369 mir-test-cucumber
370
371 mirserver
372+ mirplatformgraphics
373 mirclient
374 mirdraw
375 mirtestdraw
376
377=== modified file 'tests/unit-tests/CMakeLists.txt'
378--- tests/unit-tests/CMakeLists.txt 2013-05-20 15:55:48 +0000
379+++ tests/unit-tests/CMakeLists.txt 2013-06-21 15:26:27 +0000
380@@ -6,6 +6,7 @@
381
382 test_gmock_fixes.cpp
383 test_asio_main_loop.cpp
384+ shared_library_test.cpp
385 )
386
387 add_subdirectory(options/)
388@@ -29,6 +30,7 @@
389
390 mirclient
391 mirserver
392+ mirplatformgraphics
393 mirdraw
394 mirtestdraw
395 mirlogging
396
397=== added file 'tests/unit-tests/shared_library_test.cpp'
398--- tests/unit-tests/shared_library_test.cpp 1970-01-01 00:00:00 +0000
399+++ tests/unit-tests/shared_library_test.cpp 2013-06-21 15:26:27 +0000
400@@ -0,0 +1,114 @@
401+/*
402+ * Copyright © 2013 Canonical Ltd.
403+ *
404+ * This program is free software: you can redistribute it and/or modify it
405+ * under the terms of the GNU General Public License version 3,
406+ * as published by the Free Software Foundation.
407+ *
408+ * This program is distributed in the hope that it will be useful,
409+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
410+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
411+ * GNU General Public License for more details.
412+ *
413+ * You should have received a copy of the GNU General Public License
414+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
415+ *
416+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
417+ */
418+
419+#include "mir/shared_library.h"
420+
421+#include <gtest/gtest.h>
422+
423+#include <boost/exception/diagnostic_information.hpp>
424+
425+#include <stdexcept>
426+
427+namespace
428+{
429+class HasSubstring
430+{
431+public:
432+ HasSubstring(char const* substring) : substring(substring) {}
433+
434+ friend::testing::AssertionResult operator,(std::string const& target, HasSubstring const& match)
435+ {
436+ if (std::string::npos != target.find(match.substring))
437+ return ::testing::AssertionSuccess();
438+ else
439+ return ::testing::AssertionFailure() <<
440+ "The target:\n\"" << target << "\"\n"
441+ "Does not contain:\n\"" << match.substring << "\"";
442+ }
443+
444+private:
445+ char const* const substring;
446+
447+ HasSubstring(HasSubstring const&) = delete;
448+ HasSubstring& operator=(HasSubstring const&) = delete;
449+};
450+
451+#define EXPECT_THAT(target, condition) EXPECT_TRUE((target, condition))
452+
453+char const* const nonexistent_library = "nonexistent_library";
454+char const* const existing_library = "libmirplatformgraphics.so";
455+char const* const nonexistent_function = "nonexistent_library";
456+char const* const existing_function = "create_platform";
457+}
458+
459+TEST(SharedLibrary, load_nonexistent_library_fails)
460+{
461+ EXPECT_THROW({ mir::SharedLibrary nonexistent(nonexistent_library); }, std::runtime_error);
462+}
463+
464+TEST(SharedLibrary, load_nonexistent_library_fails_with_useful_info)
465+{
466+ try
467+ {
468+ mir::SharedLibrary nonexistent(nonexistent_library);
469+ }
470+ catch (std::exception const& error)
471+ {
472+ auto info = boost::diagnostic_information(error);
473+
474+ EXPECT_THAT(info, HasSubstring("cannot open shared object")) << "What went wrong";
475+ EXPECT_THAT(info, HasSubstring(nonexistent_library)) << "Name of library";
476+ }
477+}
478+
479+TEST(SharedLibrary, load_valid_library_works)
480+{
481+ mir::SharedLibrary existing(existing_library);
482+}
483+
484+TEST(SharedLibrary, load_nonexistent_function_fails)
485+{
486+ mir::SharedLibrary existing(existing_library);
487+
488+ EXPECT_THROW({ existing.load_function<void(*)()>(nonexistent_function); }, std::runtime_error);
489+}
490+
491+TEST(SharedLibrary, load_nonexistent_function_fails_with_useful_info)
492+{
493+ mir::SharedLibrary existing(existing_library);
494+
495+ try
496+ {
497+ existing.load_function<void(*)()>(nonexistent_function);
498+ }
499+ catch (std::exception const& error)
500+ {
501+ auto info = boost::diagnostic_information(error);
502+
503+ EXPECT_THAT(info, HasSubstring("undefined symbol")) << "What went wrong";
504+ EXPECT_THAT(info, HasSubstring(existing_library)) << "Name of library";
505+ EXPECT_THAT(info, HasSubstring(nonexistent_function)) << "Name of function";
506+ }
507+}
508+
509+TEST(SharedLibrary, load_valid_function_works)
510+{
511+ mir::SharedLibrary existing(existing_library);
512+ existing.load_function<void(*)()>(existing_function);
513+}
514+

Subscribers

People subscribed via source and target branches