Mir

Merge lp:~raof/mir/require-egl-extensions into lp:mir

Proposed by Chris Halse Rogers
Status: Work in progress
Proposed branch: lp:~raof/mir/require-egl-extensions
Merge into: lp:mir
Diff against target: 329 lines (+240/-1)
9 files modified
CMakeLists.txt (+1/-0)
src/include/platform/mir/graphics/require_egl_extensions.h (+44/-0)
src/platform/CMakeLists.txt (+1/-0)
src/platform/graphics/CMakeLists.txt (+6/-1)
src/platform/graphics/require_egl_extensions.cpp (+53/-0)
src/platform/symbols.map (+7/-0)
tests/mir_test_doubles/mock_egl.cpp (+25/-0)
tests/unit-tests/graphics/CMakeLists.txt (+1/-0)
tests/unit-tests/graphics/test_require_egl_extensions.cpp (+102/-0)
To merge this branch: bzr merge lp:~raof/mir/require-egl-extensions
Reviewer Review Type Date Requested Status
Cemil Azizoglu (community) Approve
Mir CI Bot continuous-integration Needs Fixing
Review via email: mp+293709@code.launchpad.net

Commit message

Add mg::require_egl_extensions.

A helper function that takes a list of EGL extension strings and a display, checks whether or not they are all supported or throws an exception containing the list of unsupported extensions.

Description of the change

Add mg::require_egl_extensions.

A helper function that takes a list of EGL extension strings and a display, checks whether or not they are all supported or throws an exception containing the list of unsupported extensions.

To post a comment you must log in.
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Wait, libepoxy is the helper function. Why do we need to wrap the helper functions in more helper functions?

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

Because I got bored manually checking epoxy_has_extension() and accumulating the results in a couple of different places.

It's also nice if your exception message contains *all* the missing extensions, rather than the first one you hit.

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

Oh, yeah. I probably need to make Mir depend on libepoxy-dev if I'm going to use it...

Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

Ok

Nit :
A bit out of place here
+ ${PROJECT_SOURCE_DIR}/src/include/platform/mir/graphics/require_egl_extensions.h

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

I'm no longer sure if I'll end up using this, so WIP for now.

Unmerged revisions

3497. By Chris Halse Rogers

Document what mg::require_egl_extensions does

3496. By Chris Halse Rogers

Add mg::require_egl_extensions.

This provides a convenient way of asserting that a list of extensions are supported.

3495. By Chris Halse Rogers

MockEGL: wrap dlopen() to hook libraries that grab libEGL themselves.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2016-05-03 04:36:33 +0000
+++ CMakeLists.txt 2016-05-04 04:43:00 +0000
@@ -194,6 +194,7 @@
194find_package(LTTngUST REQUIRED)194find_package(LTTngUST REQUIRED)
195pkg_check_modules(UDEV REQUIRED libudev)195pkg_check_modules(UDEV REQUIRED libudev)
196pkg_check_modules(GLIB REQUIRED glib-2.0)196pkg_check_modules(GLIB REQUIRED glib-2.0)
197pkg_check_modules(EPOXY REQUIRED epoxy)
197198
198include_directories (SYSTEM ${GLESv2_INCLUDE_DIRS})199include_directories (SYSTEM ${GLESv2_INCLUDE_DIRS})
199include_directories (SYSTEM ${EGL_INCLUDE_DIRS})200include_directories (SYSTEM ${EGL_INCLUDE_DIRS})
200201
=== added file 'src/include/platform/mir/graphics/require_egl_extensions.h'
--- src/include/platform/mir/graphics/require_egl_extensions.h 1970-01-01 00:00:00 +0000
+++ src/include/platform/mir/graphics/require_egl_extensions.h 2016-05-04 04:43:00 +0000
@@ -0,0 +1,44 @@
1/*
2 * Copyright © 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
17 */
18#ifndef MIR_GRAPHICS_REQUIRE_EGL_EXTENSIONS_H_
19#define MIR_GRAPHICS_REQUIRE_EGL_EXTENSIONS_H_
20
21#include <initializer_list>
22
23// Manually define EGLDisplay to avoid needing to pull epoxy header in here
24#ifndef EGLDisplay
25typedef void* EGLDisplay;
26#endif
27
28namespace mir
29{
30namespace graphics
31{
32/**
33 * Check that dpy supports all of extensions.
34 *
35 * \param [in] dpy The EGLDisplay to query (or EGL_NO_DISPLAY for EGL client extensions)
36 * \param [in] extensions The list of EGL extensions to check for
37 * \throw A std::runtime_error if any extension in extensions is not supported. The exception
38 * description will include a list of all the unsupported extensions.
39 */
40void require_egl_extensions(EGLDisplay dpy, std::initializer_list<char const*> const& extensions);
41}
42}
43
44#endif //MIR_GRAPHICS_REQUIRE_EGL_EXTENSIONS_H_
045
=== modified file 'src/platform/CMakeLists.txt'
--- src/platform/CMakeLists.txt 2016-01-29 08:18:22 +0000
+++ src/platform/CMakeLists.txt 2016-05-04 04:43:00 +0000
@@ -19,6 +19,7 @@
19set(MIR_PLATFORM_REFERENCES19set(MIR_PLATFORM_REFERENCES
20 ${EGL_LDFLAGS} ${EGL_LIBRARIES}20 ${EGL_LDFLAGS} ${EGL_LIBRARIES}
21 ${GLESv2_LDFLAGS} ${GLESv2_LIBRARIES}21 ${GLESv2_LDFLAGS} ${GLESv2_LIBRARIES}
22 ${EPOXY_LDFLAGS} ${EPOXY_LIBRARIES}
22)23)
2324
24add_subdirectory(graphics/)25add_subdirectory(graphics/)
2526
=== modified file 'src/platform/graphics/CMakeLists.txt'
--- src/platform/graphics/CMakeLists.txt 2016-03-29 07:30:50 +0000
+++ src/platform/graphics/CMakeLists.txt 2016-05-04 04:43:00 +0000
@@ -1,4 +1,7 @@
1include_directories(${GLESv2_INCLUDE_DIRS})1include_directories(
2 ${GLESv2_INCLUDE_DIRS}
3 ${EPOXY_INCLUDE_DIRS}
4)
25
3set(6set(
4 GRAPHICS_SOURCES7 GRAPHICS_SOURCES
@@ -11,6 +14,8 @@
11 pixel_format_utils.cpp14 pixel_format_utils.cpp
12 overlapping_output_grouping.cpp15 overlapping_output_grouping.cpp
13 platform_probe.cpp16 platform_probe.cpp
17 ${PROJECT_SOURCE_DIR}/src/include/platform/mir/graphics/require_egl_extensions.h
18 require_egl_extensions.cpp
14)19)
1520
16add_library(mirplatformgraphicscommon OBJECT21add_library(mirplatformgraphicscommon OBJECT
1722
=== added file 'src/platform/graphics/require_egl_extensions.cpp'
--- src/platform/graphics/require_egl_extensions.cpp 1970-01-01 00:00:00 +0000
+++ src/platform/graphics/require_egl_extensions.cpp 2016-05-04 04:43:00 +0000
@@ -0,0 +1,53 @@
1/*
2 * Copyright © 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
17 */
18
19#include "mir/graphics/require_egl_extensions.h"
20
21#include <epoxy/egl.h>
22
23#include <stdexcept>
24#include <vector>
25#include <sstream>
26#include <boost/throw_exception.hpp>
27
28namespace mg = mir::graphics;
29
30void mg::require_egl_extensions(
31 EGLDisplay dpy,
32 std::initializer_list<char const*> const& extensions)
33{
34 using namespace std::string_literals;
35 std::vector<char const*> missing_extensions;
36 for (auto extension : extensions)
37 {
38 if (!epoxy_has_egl_extension(dpy, extension))
39 {
40 missing_extensions.push_back(extension);
41 }
42 }
43 if (!missing_extensions.empty())
44 {
45 std::stringstream exception_message;
46 exception_message << "Missing required extension" << (missing_extensions.size() > 1 ? "s:" : ":");
47 for (auto missing_extension : missing_extensions)
48 {
49 exception_message << " " << missing_extension;
50 }
51 BOOST_THROW_EXCEPTION(std::runtime_error{exception_message.str()});
52 }
53}
054
=== modified file 'src/platform/symbols.map'
--- src/platform/symbols.map 2016-03-29 07:30:50 +0000
+++ src/platform/symbols.map 2016-05-04 04:43:00 +0000
@@ -288,3 +288,10 @@
288 mir::udev::Context::ctx*;288 mir::udev::Context::ctx*;
289 };289 };
290} MIRPLATFORM_11;290} MIRPLATFORM_11;
291
292MIR_PLATFORM_0.24 {
293 global:
294 extern "C++" {
295 mir::graphics::require_egl_extensions*;
296 };
297} MIR_PLATFORM_0.21;
291298
=== modified file 'tests/mir_test_doubles/mock_egl.cpp'
--- tests/mir_test_doubles/mock_egl.cpp 2016-01-29 08:18:22 +0000
+++ tests/mir_test_doubles/mock_egl.cpp 2016-05-04 04:43:00 +0000
@@ -21,6 +21,7 @@
21#include "mir/egl_native_surface.h"21#include "mir/egl_native_surface.h"
2222
23#include "mir/test/doubles/mock_egl.h"23#include "mir/test/doubles/mock_egl.h"
24#include <dlfcn.h>
24#include <gtest/gtest.h>25#include <gtest/gtest.h>
2526
26namespace mtd = mir::test::doubles;27namespace mtd = mir::test::doubles;
@@ -198,6 +199,30 @@
198 return; \199 return; \
199 }200 }
200201
202/*
203 * libepoxy will try and dlopen libEGL.so.1, so we have to
204 * wrap dlopen() and return the main executable for EGL
205 */
206void* dlopen(char const* filename, int flags) __THROWNL
207{
208 static void* (*real_dlopen)(char const*, int) = nullptr;
209
210 if (real_dlopen == nullptr)
211 {
212 real_dlopen =
213 reinterpret_cast<void*(*)(char const*, int)>(dlsym(RTLD_NEXT, "dlopen"));
214 }
215
216 if (strcmp(filename, "libEGL.so.1") == 0)
217 {
218 return real_dlopen(NULL, flags);
219 }
220 else
221 {
222 return real_dlopen(filename, flags);
223 }
224}
225
201EGLint eglGetError (void)226EGLint eglGetError (void)
202{227{
203 CHECK_GLOBAL_MOCK(EGLint)228 CHECK_GLOBAL_MOCK(EGLint)
204229
=== modified file 'tests/unit-tests/graphics/CMakeLists.txt'
--- tests/unit-tests/graphics/CMakeLists.txt 2016-05-03 04:36:33 +0000
+++ tests/unit-tests/graphics/CMakeLists.txt 2016-05-04 04:43:00 +0000
@@ -10,6 +10,7 @@
10 ${CMAKE_CURRENT_SOURCE_DIR}/test_overlapping_output_grouping.cpp10 ${CMAKE_CURRENT_SOURCE_DIR}/test_overlapping_output_grouping.cpp
11 ${CMAKE_CURRENT_SOURCE_DIR}/test_software_cursor.cpp11 ${CMAKE_CURRENT_SOURCE_DIR}/test_software_cursor.cpp
12 ${CMAKE_CURRENT_SOURCE_DIR}/test_anonymous_shm_file.cpp12 ${CMAKE_CURRENT_SOURCE_DIR}/test_anonymous_shm_file.cpp
13 ${CMAKE_CURRENT_SOURCE_DIR}/test_require_egl_extensions.cpp
13)14)
1415
1516
1617
=== added file 'tests/unit-tests/graphics/test_require_egl_extensions.cpp'
--- tests/unit-tests/graphics/test_require_egl_extensions.cpp 1970-01-01 00:00:00 +0000
+++ tests/unit-tests/graphics/test_require_egl_extensions.cpp 2016-05-04 04:43:00 +0000
@@ -0,0 +1,102 @@
1/*
2 * Copyright © 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by:
17 * Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
18 */
19
20#include "mir/graphics/require_egl_extensions.h"
21#include "mir/test/doubles/mock_egl.h"
22#include <stdexcept>
23
24#include <gtest/gtest.h>
25#include <gmock/gmock.h>
26
27namespace mg = mir::graphics;
28namespace mtd = mir::test::doubles;
29using namespace testing;
30
31typedef mtd::MockEGL::generic_function_pointer_t func_ptr_t;
32class RequireEglExtensions : public ::testing::Test
33{
34protected:
35 virtual void SetUp()
36 {
37 }
38
39 testing::NiceMock<mtd::MockEGL> mock_egl;
40};
41
42TEST_F(RequireEglExtensions, succeeds_if_all_extensions_are_found)
43{
44 ON_CALL(mock_egl, eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS))
45 .WillByDefault(
46 Return("EGL_EXT_platform_base EGL_EXT_platform_device EGL_EXT_device_base"));
47
48 mg::require_egl_extensions(EGL_NO_DISPLAY, {
49 "EGL_EXT_platform_base",
50 "EGL_EXT_platform_device",
51 "EGL_EXT_device_base"
52 });
53}
54
55TEST_F(RequireEglExtensions, succeeds_if_all_client_extensions_are_found)
56{
57 ON_CALL(mock_egl, eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS))
58 .WillByDefault(
59 Return("EGL_EXT_platform_base EGL_EXT_platform_device EGL_EXT_device_base"));
60
61 mg::require_egl_extensions(EGL_NO_DISPLAY, {
62 "EGL_EXT_platform_base",
63 "EGL_EXT_platform_device",
64 "EGL_EXT_device_base"
65 });
66}
67
68TEST_F(RequireEglExtensions, succeeds_if_all_display_extensions_are_found)
69{
70 EGLDisplay dummy = reinterpret_cast<EGLDisplay>(0xdeadbeef);
71 ON_CALL(mock_egl, eglQueryString(dummy, EGL_EXTENSIONS))
72 .WillByDefault(
73 Return("EGL_KHR_image EGL_KHR_image_base EGL_KHR_reusable_sync EGL_KHR_stream"));
74
75 mg::require_egl_extensions(dummy, {
76 "EGL_KHR_image",
77 "EGL_KHR_image_base",
78 });
79}
80
81TEST_F(RequireEglExtensions, fails_with_list_of_unsupported_extensions)
82{
83 ON_CALL(mock_egl, eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS))
84 .WillByDefault(Return("EGL_EXT_device_base"));
85
86 auto required_extensions = {
87 "EGL_EXT_platform_base",
88 "EGL_EXT_device_base",
89 "EGL_EXT_platform_device",
90 };
91 try
92 {
93 mg::require_egl_extensions(EGL_NO_DISPLAY, required_extensions);
94 }
95 catch (std::runtime_error const& err)
96 {
97 EXPECT_THAT(err.what(), AllOf(HasSubstr("EGL_EXT_platform_base"), HasSubstr("EGL_EXT_platform_device")));
98 return;
99 }
100
101 FAIL() << "require_egl_extensions unexpectedly succeeded";
102}

Subscribers

People subscribed via source and target branches