Status: | Merged | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Approved by: | Alberto Aguirre | ||||||||||||||||||||||||
Approved revision: | 3022 | ||||||||||||||||||||||||
Merged at revision: | 1249 | ||||||||||||||||||||||||
Proposed branch: | lp:mir/0.17 | ||||||||||||||||||||||||
Merge into: | lp:mir/ubuntu | ||||||||||||||||||||||||
Diff against target: |
865 lines (+427/-65) 23 files modified
CMakeLists.txt (+1/-1) debian/changelog (+20/-0) debian/control (+1/-0) debian/mir-client-platform-mesa-dev.install (+1/-0) include/platform/mir/graphics/display_configuration.h (+3/-0) src/platform/graphics/display_configuration.cpp (+23/-0) src/platforms/android/client/android_client_platform.cpp (+3/-14) src/platforms/common/client/mir/CMakeLists.txt (+1/-0) src/platforms/common/client/mir/weak_egl.cpp (+65/-0) src/platforms/common/client/mir/weak_egl.h (+47/-0) src/platforms/mesa/CMakeLists.txt (+10/-1) src/platforms/mesa/client/client_platform.cpp (+6/-17) src/platforms/mesa/mir-client-platform-mesa-dev.pc.in (+1/-1) src/platforms/mesa/mir-client-platform-mesa.pc.in (+7/-0) src/server/graphics/nested/display.cpp (+39/-6) src/server/graphics/nested/display.h (+6/-0) src/server/input/display_input_region.cpp (+4/-1) src/server/scene/rendering_tracker.cpp (+12/-0) src/server/scene/rendering_tracker.h (+2/-1) src/server/scene/surface_stack.cpp (+11/-8) tests/acceptance-tests/test_nested_mir.cpp (+109/-15) tests/unit-tests/input/test_display_input_region.cpp (+11/-0) tests/unit-tests/scene/test_surface_stack.cpp (+44/-0) |
||||||||||||||||||||||||
To merge this branch: | bzr merge lp:mir/0.17 | ||||||||||||||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Mir development team | Pending | ||
Review via email: mp+276704@code.launchpad.net |
Commit message
Mir 0.17.1 release
Description of the change
Mir 0.17.1 release
- 3017. By Alberto Aguirre
-
Avoid __attribute_
_((weak) ) as that will fail to resolve symbols from
lazily loaded libraries (like Qt platform plugins apparently).Cherry picked from lp:mir r3060
- 3018. By Alberto Aguirre
-
Update changelog
- 3019. By Brandon Schaefer
-
Add missing shlibs:Depends entry to libmircookie1 package dependency list
- 3020. By Alberto Aguirre
-
Update changelog, new bugfix entry
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:3020
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 3021. By Alexandros Frantzis
-
input: Return an empty input region bounding rectangle when there are no outputs.
Cherry picked from lp:mir r3085
- 3022. By Alberto Aguirre
-
Update changelog
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:3022
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'CMakeLists.txt' | |||
2 | --- CMakeLists.txt 2015-10-08 09:48:35 +0000 | |||
3 | +++ CMakeLists.txt 2015-11-05 16:01:02 +0000 | |||
4 | @@ -28,7 +28,7 @@ | |||
5 | 28 | 28 | ||
6 | 29 | set(MIR_VERSION_MAJOR 0) | 29 | set(MIR_VERSION_MAJOR 0) |
7 | 30 | set(MIR_VERSION_MINOR 17) | 30 | set(MIR_VERSION_MINOR 17) |
9 | 31 | set(MIR_VERSION_PATCH 0) | 31 | set(MIR_VERSION_PATCH 1) |
10 | 32 | 32 | ||
11 | 33 | add_definitions(-DMIR_VERSION_MAJOR=${MIR_VERSION_MAJOR}) | 33 | add_definitions(-DMIR_VERSION_MAJOR=${MIR_VERSION_MAJOR}) |
12 | 34 | add_definitions(-DMIR_VERSION_MINOR=${MIR_VERSION_MINOR}) | 34 | add_definitions(-DMIR_VERSION_MINOR=${MIR_VERSION_MINOR}) |
13 | 35 | 35 | ||
14 | === modified file 'debian/changelog' | |||
15 | --- debian/changelog 2015-10-08 16:12:19 +0000 | |||
16 | +++ debian/changelog 2015-11-05 16:01:02 +0000 | |||
17 | @@ -1,3 +1,23 @@ | |||
18 | 1 | mir (0.17.1) UNRELEASED; urgency=medium | ||
19 | 2 | |||
20 | 3 | * New upstream release 0.17.1 (https://launchpad.net/mir/+milestone/0.17.1) | ||
21 | 4 | - No ABI changes. Bug fix release only. | ||
22 | 5 | - Bugs fixed: | ||
23 | 6 | . compositing never stops when external monitor is connected | ||
24 | 7 | (LP: #1499039) | ||
25 | 8 | . half screen on external monitor (LP: #1511538) | ||
26 | 9 | . Nested servers don't apply their display configuration at startup | ||
27 | 10 | (LP: #1492269) | ||
28 | 11 | . libmircookie1 package does not list libnettle as dependency | ||
29 | 12 | (LP: #1513225) | ||
30 | 13 | . unity-system-compositor crash, no interaction on windowed mode | ||
31 | 14 | (LP: #1511095) | ||
32 | 15 | . mir_connection_get_egl_pixel_format() crashes (LP: #1510218) | ||
33 | 16 | . [regression] mir-client-platform-mesa-dev pkg-config file dropped | ||
34 | 17 | (LP: #1509005) | ||
35 | 18 | |||
36 | 19 | -- Alberto Aguirre <alberto.aguirre@canonical.com> Wed, 04 Nov 2015 15:08:54 -0600 | ||
37 | 20 | |||
38 | 1 | mir (0.17.0+15.10.20151008.2-0ubuntu1) wily; urgency=medium | 21 | mir (0.17.0+15.10.20151008.2-0ubuntu1) wily; urgency=medium |
39 | 2 | 22 | ||
40 | 3 | [ Alexandros Frantzis ] | 23 | [ Alexandros Frantzis ] |
41 | 4 | 24 | ||
42 | === modified file 'debian/control' | |||
43 | --- debian/control 2015-10-05 02:18:18 +0000 | |||
44 | +++ debian/control 2015-11-05 16:01:02 +0000 | |||
45 | @@ -424,6 +424,7 @@ | |||
46 | 424 | Multi-Arch: same | 424 | Multi-Arch: same |
47 | 425 | Pre-Depends: ${misc:Pre-Depends} | 425 | Pre-Depends: ${misc:Pre-Depends} |
48 | 426 | Depends: ${misc:Depends}, | 426 | Depends: ${misc:Depends}, |
49 | 427 | ${shlibs:Depends} | ||
50 | 427 | Description: Produce and verify spoof-resistant timestamps - runtime library | 428 | Description: Produce and verify spoof-resistant timestamps - runtime library |
51 | 428 | libmircookie provides a simple mechanism for a group of cooperating processes | 429 | libmircookie provides a simple mechanism for a group of cooperating processes |
52 | 429 | to hand out and verify difficult-to-forge timestamps to untrusted 3rd parties. | 430 | to hand out and verify difficult-to-forge timestamps to untrusted 3rd parties. |
53 | 430 | 431 | ||
54 | === modified file 'debian/mir-client-platform-mesa-dev.install' | |||
55 | --- debian/mir-client-platform-mesa-dev.install 2015-09-24 22:30:09 +0000 | |||
56 | +++ debian/mir-client-platform-mesa-dev.install 2015-11-05 16:01:02 +0000 | |||
57 | @@ -1,2 +1,3 @@ | |||
58 | 1 | usr/include/mirplatform/mir_toolkit/mesa | 1 | usr/include/mirplatform/mir_toolkit/mesa |
59 | 2 | usr/lib/*/pkgconfig/mir-client-platform-mesa-dev.pc | ||
60 | 2 | usr/lib/*/pkgconfig/mir-client-platform-mesa.pc | 3 | usr/lib/*/pkgconfig/mir-client-platform-mesa.pc |
61 | 3 | 4 | ||
62 | === modified file 'include/platform/mir/graphics/display_configuration.h' | |||
63 | --- include/platform/mir/graphics/display_configuration.h 2015-10-05 05:22:49 +0000 | |||
64 | +++ include/platform/mir/graphics/display_configuration.h 2015-11-05 16:01:02 +0000 | |||
65 | @@ -181,6 +181,9 @@ | |||
66 | 181 | DisplayConfiguration& operator=(DisplayConfiguration const& c) = delete; | 181 | DisplayConfiguration& operator=(DisplayConfiguration const& c) = delete; |
67 | 182 | }; | 182 | }; |
68 | 183 | 183 | ||
69 | 184 | bool operator==(DisplayConfiguration const& lhs, DisplayConfiguration const& rhs); | ||
70 | 185 | bool operator!=(DisplayConfiguration const& lhs, DisplayConfiguration const& rhs); | ||
71 | 186 | |||
72 | 184 | std::ostream& operator<<(std::ostream& out, DisplayConfiguration const& val); | 187 | std::ostream& operator<<(std::ostream& out, DisplayConfiguration const& val); |
73 | 185 | 188 | ||
74 | 186 | } | 189 | } |
75 | 187 | 190 | ||
76 | === modified file 'src/platform/graphics/display_configuration.cpp' | |||
77 | --- src/platform/graphics/display_configuration.cpp 2015-10-02 05:14:37 +0000 | |||
78 | +++ src/platform/graphics/display_configuration.cpp 2015-11-05 16:01:02 +0000 | |||
79 | @@ -145,6 +145,7 @@ | |||
80 | 145 | 145 | ||
81 | 146 | out << "\tscale: " << val.scale << std::endl; | 146 | out << "\tscale: " << val.scale << std::endl; |
82 | 147 | out << "\tform factor: " << as_string(val.form_factor) << std::endl; | 147 | out << "\tform factor: " << as_string(val.form_factor) << std::endl; |
83 | 148 | out << "\torientation: " << val.orientation << '\n'; | ||
84 | 148 | out << "}" << std::endl; | 149 | out << "}" << std::endl; |
85 | 149 | 150 | ||
86 | 150 | return out; | 151 | return out; |
87 | @@ -219,6 +220,28 @@ | |||
88 | 219 | return !(val1 == val2); | 220 | return !(val1 == val2); |
89 | 220 | } | 221 | } |
90 | 221 | 222 | ||
91 | 223 | bool mg::operator==(DisplayConfiguration const& lhs, DisplayConfiguration const& rhs) | ||
92 | 224 | { | ||
93 | 225 | std::vector<DisplayConfigurationCard> lhs_cards; | ||
94 | 226 | std::vector<DisplayConfigurationOutput> lhs_outputs; | ||
95 | 227 | |||
96 | 228 | lhs.for_each_card([&lhs_cards](DisplayConfigurationCard const& card) { lhs_cards.emplace_back(card); }); | ||
97 | 229 | lhs.for_each_output([&lhs_outputs](DisplayConfigurationOutput const& output) { lhs_outputs.emplace_back(output); }); | ||
98 | 230 | |||
99 | 231 | std::vector<DisplayConfigurationCard> rhs_cards; | ||
100 | 232 | std::vector<DisplayConfigurationOutput> rhs_outputs; | ||
101 | 233 | |||
102 | 234 | rhs.for_each_card([&rhs_cards](DisplayConfigurationCard const& card) { rhs_cards.emplace_back(card); }); | ||
103 | 235 | rhs.for_each_output([&rhs_outputs](DisplayConfigurationOutput const& output) { rhs_outputs.emplace_back(output); }); | ||
104 | 236 | |||
105 | 237 | return lhs_cards == rhs_cards && lhs_outputs == rhs_outputs; | ||
106 | 238 | } | ||
107 | 239 | |||
108 | 240 | bool mg::operator!=(DisplayConfiguration const& lhs, DisplayConfiguration const& rhs) | ||
109 | 241 | { | ||
110 | 242 | return !(lhs == rhs); | ||
111 | 243 | } | ||
112 | 244 | |||
113 | 222 | namespace | 245 | namespace |
114 | 223 | { | 246 | { |
115 | 224 | mir::geometry::Rectangle extents_of( | 247 | mir::geometry::Rectangle extents_of( |
116 | 225 | 248 | ||
117 | === modified file 'src/platforms/android/client/android_client_platform.cpp' | |||
118 | --- src/platforms/android/client/android_client_platform.cpp 2015-07-21 04:30:03 +0000 | |||
119 | +++ src/platforms/android/client/android_client_platform.cpp 2015-11-05 16:01:02 +0000 | |||
120 | @@ -24,6 +24,7 @@ | |||
121 | 24 | #include "android_client_buffer_factory.h" | 24 | #include "android_client_buffer_factory.h" |
122 | 25 | #include "egl_native_surface_interpreter.h" | 25 | #include "egl_native_surface_interpreter.h" |
123 | 26 | 26 | ||
124 | 27 | #include "mir/weak_egl.h" | ||
125 | 27 | #include <EGL/egl.h> | 28 | #include <EGL/egl.h> |
126 | 28 | 29 | ||
127 | 29 | #include <boost/throw_exception.hpp> | 30 | #include <boost/throw_exception.hpp> |
128 | @@ -124,19 +125,6 @@ | |||
129 | 124 | return buf->anwb(); | 125 | return buf->anwb(); |
130 | 125 | } | 126 | } |
131 | 126 | 127 | ||
132 | 127 | /* | ||
133 | 128 | * Driver modules get dlopened with RTLD_NOW, meaning that if the below egl | ||
134 | 129 | * functions aren't found in memory the driver fails to load. This would | ||
135 | 130 | * normally prevent software clients (those not linked to libEGL) from | ||
136 | 131 | * successfully loading our client module, but if we mark the undefined | ||
137 | 132 | * egl function symbols as "weak" then their absence is no longer an error, | ||
138 | 133 | * even with RTLD_NOW. | ||
139 | 134 | */ | ||
140 | 135 | extern "C" EGLAPI EGLBoolean EGLAPIENTRY | ||
141 | 136 | eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, | ||
142 | 137 | EGLint attribute, EGLint *value) | ||
143 | 138 | __attribute__((weak)); | ||
144 | 139 | |||
145 | 140 | MirPixelFormat mcla::AndroidClientPlatform::get_egl_pixel_format( | 128 | MirPixelFormat mcla::AndroidClientPlatform::get_egl_pixel_format( |
146 | 141 | EGLDisplay disp, EGLConfig conf) const | 129 | EGLDisplay disp, EGLConfig conf) const |
147 | 142 | { | 130 | { |
148 | @@ -144,7 +132,8 @@ | |||
149 | 144 | 132 | ||
150 | 145 | // EGL_KHR_platform_android says this will always work... | 133 | // EGL_KHR_platform_android says this will always work... |
151 | 146 | EGLint vis = 0; | 134 | EGLint vis = 0; |
153 | 147 | if (eglGetConfigAttrib(disp, conf, EGL_NATIVE_VISUAL_ID, &vis)) | 135 | mcl::WeakEGL weak; |
154 | 136 | if (weak.eglGetConfigAttrib(disp, conf, EGL_NATIVE_VISUAL_ID, &vis)) | ||
155 | 148 | mir_format = mir::graphics::android::to_mir_format(vis); | 137 | mir_format = mir::graphics::android::to_mir_format(vis); |
156 | 149 | 138 | ||
157 | 150 | return mir_format; | 139 | return mir_format; |
158 | 151 | 140 | ||
159 | === modified file 'src/platforms/common/client/mir/CMakeLists.txt' | |||
160 | --- src/platforms/common/client/mir/CMakeLists.txt 2015-01-19 14:16:46 +0000 | |||
161 | +++ src/platforms/common/client/mir/CMakeLists.txt 2015-11-05 16:01:02 +0000 | |||
162 | @@ -2,4 +2,5 @@ | |||
163 | 2 | 2 | ||
164 | 3 | add_library(client_platform_common OBJECT | 3 | add_library(client_platform_common OBJECT |
165 | 4 | aging_buffer.cpp | 4 | aging_buffer.cpp |
166 | 5 | weak_egl.cpp | ||
167 | 5 | ) | 6 | ) |
168 | 6 | 7 | ||
169 | === added file 'src/platforms/common/client/mir/weak_egl.cpp' | |||
170 | --- src/platforms/common/client/mir/weak_egl.cpp 1970-01-01 00:00:00 +0000 | |||
171 | +++ src/platforms/common/client/mir/weak_egl.cpp 2015-11-05 16:01:02 +0000 | |||
172 | @@ -0,0 +1,65 @@ | |||
173 | 1 | /* | ||
174 | 2 | * EGL without any linkage requirements! | ||
175 | 3 | * ~~~ | ||
176 | 4 | * Copyright © 2015 Canonical Ltd. | ||
177 | 5 | * | ||
178 | 6 | * This program is free software: you can redistribute it and/or modify it | ||
179 | 7 | * under the terms of the GNU Lesser General Public License version 3, | ||
180 | 8 | * as published by the Free Software Foundation. | ||
181 | 9 | * | ||
182 | 10 | * This program is distributed in the hope that it will be useful, | ||
183 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
184 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
185 | 13 | * GNU Lesser General Public License for more details. | ||
186 | 14 | * | ||
187 | 15 | * You should have received a copy of the GNU Lesser General Public License | ||
188 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
189 | 17 | * | ||
190 | 18 | * Authored by: Daniel van Vugt <daniel.van.vugt@canonical.com> | ||
191 | 19 | */ | ||
192 | 20 | |||
193 | 21 | #include "weak_egl.h" | ||
194 | 22 | #include <dlfcn.h> | ||
195 | 23 | |||
196 | 24 | namespace mir { namespace client { | ||
197 | 25 | |||
198 | 26 | WeakEGL::WeakEGL() | ||
199 | 27 | : egl1(nullptr) | ||
200 | 28 | , pGetConfigAttrib(nullptr) | ||
201 | 29 | { | ||
202 | 30 | } | ||
203 | 31 | |||
204 | 32 | WeakEGL::~WeakEGL() | ||
205 | 33 | { | ||
206 | 34 | if (egl1) | ||
207 | 35 | dlclose(egl1); | ||
208 | 36 | } | ||
209 | 37 | |||
210 | 38 | EGLBoolean WeakEGL::eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, | ||
211 | 39 | EGLint attribute, EGLint* value) | ||
212 | 40 | { | ||
213 | 41 | if (find("eglGetConfigAttrib", (void**)&pGetConfigAttrib)) | ||
214 | 42 | return pGetConfigAttrib(dpy, config, attribute, value); | ||
215 | 43 | else | ||
216 | 44 | return EGL_FALSE; | ||
217 | 45 | } | ||
218 | 46 | |||
219 | 47 | bool WeakEGL::find(char const* name, void** func) | ||
220 | 48 | { | ||
221 | 49 | if (!*func) | ||
222 | 50 | { | ||
223 | 51 | // RTLD_DEFAULT is first choice to support wrappers like MockEGL | ||
224 | 52 | if (!(*func = dlsym(RTLD_DEFAULT, name))) | ||
225 | 53 | { | ||
226 | 54 | // This will work more in real-world situations if the library | ||
227 | 55 | // is hidden behind an RTLD_LOCAL (e.g. a Qt plugin) | ||
228 | 56 | if (!egl1) | ||
229 | 57 | egl1 = dlopen("libEGL.so.1", RTLD_NOLOAD|RTLD_LAZY); | ||
230 | 58 | if (egl1) | ||
231 | 59 | *func = dlsym(egl1, name); | ||
232 | 60 | } | ||
233 | 61 | } | ||
234 | 62 | return *func != nullptr; | ||
235 | 63 | } | ||
236 | 64 | |||
237 | 65 | }} // namespace mir::client | ||
238 | 0 | 66 | ||
239 | === added file 'src/platforms/common/client/mir/weak_egl.h' | |||
240 | --- src/platforms/common/client/mir/weak_egl.h 1970-01-01 00:00:00 +0000 | |||
241 | +++ src/platforms/common/client/mir/weak_egl.h 2015-11-05 16:01:02 +0000 | |||
242 | @@ -0,0 +1,47 @@ | |||
243 | 1 | /* | ||
244 | 2 | * EGL without any linkage requirements! | ||
245 | 3 | * ~~~ | ||
246 | 4 | * Copyright © 2015 Canonical Ltd. | ||
247 | 5 | * | ||
248 | 6 | * This program is free software: you can redistribute it and/or modify it | ||
249 | 7 | * under the terms of the GNU Lesser General Public License version 3, | ||
250 | 8 | * as published by the Free Software Foundation. | ||
251 | 9 | * | ||
252 | 10 | * This program is distributed in the hope that it will be useful, | ||
253 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
254 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
255 | 13 | * GNU Lesser General Public License for more details. | ||
256 | 14 | * | ||
257 | 15 | * You should have received a copy of the GNU Lesser General Public License | ||
258 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
259 | 17 | * | ||
260 | 18 | * Authored by: Daniel van Vugt <daniel.van.vugt@canonical.com> | ||
261 | 19 | */ | ||
262 | 20 | |||
263 | 21 | #ifndef MIR_CLIENT_WEAK_EGL_H_ | ||
264 | 22 | #define MIR_CLIENT_WEAK_EGL_H_ | ||
265 | 23 | |||
266 | 24 | #include <EGL/egl.h> | ||
267 | 25 | #include <dlfcn.h> | ||
268 | 26 | |||
269 | 27 | namespace mir { namespace client { | ||
270 | 28 | |||
271 | 29 | class WeakEGL | ||
272 | 30 | { | ||
273 | 31 | public: | ||
274 | 32 | WeakEGL(); | ||
275 | 33 | ~WeakEGL(); | ||
276 | 34 | EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, | ||
277 | 35 | EGLint attribute, EGLint* value); | ||
278 | 36 | |||
279 | 37 | private: | ||
280 | 38 | bool find(char const* name, void** func); | ||
281 | 39 | |||
282 | 40 | void* egl1; | ||
283 | 41 | EGLBoolean (*pGetConfigAttrib)(EGLDisplay dpy, EGLConfig config, | ||
284 | 42 | EGLint attribute, EGLint* value); | ||
285 | 43 | }; | ||
286 | 44 | |||
287 | 45 | }} // namespace mir::client | ||
288 | 46 | |||
289 | 47 | #endif // MIR_CLIENT_WEAK_EGL_H_ | ||
290 | 0 | 48 | ||
291 | === modified file 'src/platforms/mesa/CMakeLists.txt' | |||
292 | --- src/platforms/mesa/CMakeLists.txt 2015-09-24 22:30:09 +0000 | |||
293 | +++ src/platforms/mesa/CMakeLists.txt 2015-11-05 16:01:02 +0000 | |||
294 | @@ -1,6 +1,12 @@ | |||
295 | 1 | set(INCLUDEDIR "${CMAKE_INSTALL_PREFIX}/include") | 1 | set(INCLUDEDIR "${CMAKE_INSTALL_PREFIX}/include") |
296 | 2 | 2 | ||
297 | 3 | configure_file( | 3 | configure_file( |
298 | 4 | ${CMAKE_CURRENT_SOURCE_DIR}/mir-client-platform-mesa-dev.pc.in | ||
299 | 5 | ${CMAKE_CURRENT_BINARY_DIR}/mir-client-platform-mesa-dev.pc | ||
300 | 6 | @ONLY | ||
301 | 7 | ) | ||
302 | 8 | |||
303 | 9 | configure_file( | ||
304 | 4 | ${CMAKE_CURRENT_SOURCE_DIR}/mir-client-platform-mesa.pc.in | 10 | ${CMAKE_CURRENT_SOURCE_DIR}/mir-client-platform-mesa.pc.in |
305 | 5 | ${CMAKE_CURRENT_BINARY_DIR}/mir-client-platform-mesa.pc | 11 | ${CMAKE_CURRENT_BINARY_DIR}/mir-client-platform-mesa.pc |
306 | 6 | @ONLY | 12 | @ONLY |
307 | @@ -20,6 +26,9 @@ | |||
308 | 20 | ) | 26 | ) |
309 | 21 | 27 | ||
310 | 22 | install( | 28 | install( |
312 | 23 | FILES ${CMAKE_CURRENT_BINARY_DIR}/mir-client-platform-mesa.pc | 29 | FILES |
313 | 30 | ${CMAKE_CURRENT_BINARY_DIR}/mir-client-platform-mesa-dev.pc | ||
314 | 31 | ${CMAKE_CURRENT_BINARY_DIR}/mir-client-platform-mesa.pc | ||
315 | 32 | |||
316 | 24 | DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig | 33 | DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig |
317 | 25 | ) | 34 | ) |
318 | 26 | 35 | ||
319 | === modified file 'src/platforms/mesa/client/client_platform.cpp' | |||
320 | --- src/platforms/mesa/client/client_platform.cpp 2015-07-17 08:08:44 +0000 | |||
321 | +++ src/platforms/mesa/client/client_platform.cpp 2015-11-05 16:01:02 +0000 | |||
322 | @@ -23,6 +23,7 @@ | |||
323 | 23 | #include "native_surface.h" | 23 | #include "native_surface.h" |
324 | 24 | #include "mir/client_buffer_factory.h" | 24 | #include "mir/client_buffer_factory.h" |
325 | 25 | #include "mir/client_context.h" | 25 | #include "mir/client_context.h" |
326 | 26 | #include "mir/weak_egl.h" | ||
327 | 26 | #include "mir_toolkit/mesa/platform_operation.h" | 27 | #include "mir_toolkit/mesa/platform_operation.h" |
328 | 27 | 28 | ||
329 | 28 | #include <cstring> | 29 | #include <cstring> |
330 | @@ -179,19 +180,6 @@ | |||
331 | 179 | } | 180 | } |
332 | 180 | 181 | ||
333 | 181 | 182 | ||
334 | 182 | /* | ||
335 | 183 | * Driver modules get dlopened with RTLD_NOW, meaning that if the below egl | ||
336 | 184 | * functions aren't found in memory the driver fails to load. This would | ||
337 | 185 | * normally prevent software clients (those not linked to libEGL) from | ||
338 | 186 | * successfully loading our client module, but if we mark the undefined | ||
339 | 187 | * egl function symbols as "weak" then their absence is no longer an error, | ||
340 | 188 | * even with RTLD_NOW. | ||
341 | 189 | */ | ||
342 | 190 | extern "C" EGLAPI EGLBoolean EGLAPIENTRY | ||
343 | 191 | eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, | ||
344 | 192 | EGLint attribute, EGLint *value) | ||
345 | 193 | __attribute__((weak)); | ||
346 | 194 | |||
347 | 195 | MirPixelFormat mclm::ClientPlatform::get_egl_pixel_format( | 183 | MirPixelFormat mclm::ClientPlatform::get_egl_pixel_format( |
348 | 196 | EGLDisplay disp, EGLConfig conf) const | 184 | EGLDisplay disp, EGLConfig conf) const |
349 | 197 | { | 185 | { |
350 | @@ -208,10 +196,11 @@ | |||
351 | 208 | * EGL_NATIVE_VISUAL_ID, so ignore that for now. | 196 | * EGL_NATIVE_VISUAL_ID, so ignore that for now. |
352 | 209 | */ | 197 | */ |
353 | 210 | EGLint r = 0, g = 0, b = 0, a = 0; | 198 | EGLint r = 0, g = 0, b = 0, a = 0; |
358 | 211 | eglGetConfigAttrib(disp, conf, EGL_RED_SIZE, &r); | 199 | mcl::WeakEGL weak; |
359 | 212 | eglGetConfigAttrib(disp, conf, EGL_GREEN_SIZE, &g); | 200 | weak.eglGetConfigAttrib(disp, conf, EGL_RED_SIZE, &r); |
360 | 213 | eglGetConfigAttrib(disp, conf, EGL_BLUE_SIZE, &b); | 201 | weak.eglGetConfigAttrib(disp, conf, EGL_GREEN_SIZE, &g); |
361 | 214 | eglGetConfigAttrib(disp, conf, EGL_ALPHA_SIZE, &a); | 202 | weak.eglGetConfigAttrib(disp, conf, EGL_BLUE_SIZE, &b); |
362 | 203 | weak.eglGetConfigAttrib(disp, conf, EGL_ALPHA_SIZE, &a); | ||
363 | 215 | 204 | ||
364 | 216 | if (r == 8 && g == 8 && b == 8) | 205 | if (r == 8 && g == 8 && b == 8) |
365 | 217 | { | 206 | { |
366 | 218 | 207 | ||
367 | === renamed file 'src/platforms/mesa/mir-client-platform-mesa.pc.in' => 'src/platforms/mesa/mir-client-platform-mesa-dev.pc.in' | |||
368 | --- src/platforms/mesa/mir-client-platform-mesa.pc.in 2015-10-07 12:53:33 +0000 | |||
369 | +++ src/platforms/mesa/mir-client-platform-mesa-dev.pc.in 2015-11-05 16:01:02 +0000 | |||
370 | @@ -1,6 +1,6 @@ | |||
371 | 1 | includedir=@INCLUDEDIR@/mirplatform | 1 | includedir=@INCLUDEDIR@/mirplatform |
372 | 2 | 2 | ||
374 | 3 | Name: mir-client-platform-mesa | 3 | Name: mir-client-platform-mesa-dev |
375 | 4 | Description: Mir Mesa client platform development files | 4 | Description: Mir Mesa client platform development files |
376 | 5 | Version: @MIR_VERSION@ | 5 | Version: @MIR_VERSION@ |
377 | 6 | Requires.private: mirclient | 6 | Requires.private: mirclient |
378 | 7 | 7 | ||
379 | === added file 'src/platforms/mesa/mir-client-platform-mesa.pc.in' | |||
380 | --- src/platforms/mesa/mir-client-platform-mesa.pc.in 1970-01-01 00:00:00 +0000 | |||
381 | +++ src/platforms/mesa/mir-client-platform-mesa.pc.in 2015-11-05 16:01:02 +0000 | |||
382 | @@ -0,0 +1,7 @@ | |||
383 | 1 | includedir=@INCLUDEDIR@/mirplatform | ||
384 | 2 | |||
385 | 3 | Name: mir-client-platform-mesa | ||
386 | 4 | Description: Mir Mesa client platform development files | ||
387 | 5 | Version: @MIR_VERSION@ | ||
388 | 6 | Requires.private: mirclient | ||
389 | 7 | Cflags: -I${includedir} | ||
390 | 0 | 8 | ||
391 | === modified file 'src/server/graphics/nested/display.cpp' | |||
392 | --- src/server/graphics/nested/display.cpp 2015-10-06 09:28:48 +0000 | |||
393 | +++ src/server/graphics/nested/display.cpp 2015-11-05 16:01:02 +0000 | |||
394 | @@ -29,6 +29,9 @@ | |||
395 | 29 | #include "mir/graphics/overlapping_output_grouping.h" | 29 | #include "mir/graphics/overlapping_output_grouping.h" |
396 | 30 | #include "mir/graphics/gl_config.h" | 30 | #include "mir/graphics/gl_config.h" |
397 | 31 | #include "mir/graphics/egl_error.h" | 31 | #include "mir/graphics/egl_error.h" |
398 | 32 | #include "mir_toolkit/mir_blob.h" | ||
399 | 33 | #include "mir_toolkit/mir_connection.h" | ||
400 | 34 | #include "mir/raii.h" | ||
401 | 32 | 35 | ||
402 | 33 | #include <boost/throw_exception.hpp> | 36 | #include <boost/throw_exception.hpp> |
403 | 34 | #include <stdexcept> | 37 | #include <stdexcept> |
404 | @@ -145,6 +148,20 @@ | |||
405 | 145 | return std::chrono::milliseconds::zero(); | 148 | return std::chrono::milliseconds::zero(); |
406 | 146 | } | 149 | } |
407 | 147 | 150 | ||
408 | 151 | namespace | ||
409 | 152 | { | ||
410 | 153 | auto copy_config(MirDisplayConfiguration* conf) -> std::shared_ptr<MirDisplayConfiguration> | ||
411 | 154 | { | ||
412 | 155 | auto const blob = mir::raii::deleter_for( | ||
413 | 156 | mir_blob_from_display_configuration(conf), | ||
414 | 157 | [] (MirBlob* b) { mir_blob_release(b); }); | ||
415 | 158 | |||
416 | 159 | return std::shared_ptr<MirDisplayConfiguration>{ | ||
417 | 160 | mir_blob_to_display_configuration(blob.get()), | ||
418 | 161 | [] (MirDisplayConfiguration* c) { if (c) mir_display_config_destroy(c); }}; | ||
419 | 162 | } | ||
420 | 163 | } | ||
421 | 164 | |||
422 | 148 | mgn::Display::Display( | 165 | mgn::Display::Display( |
423 | 149 | std::shared_ptr<mg::Platform> const& platform, | 166 | std::shared_ptr<mg::Platform> const& platform, |
424 | 150 | std::shared_ptr<HostConnection> const& connection, | 167 | std::shared_ptr<HostConnection> const& connection, |
425 | @@ -159,10 +176,15 @@ | |||
426 | 159 | display_report{display_report}, | 176 | display_report{display_report}, |
427 | 160 | egl_display{connection->egl_native_display(), gl_config}, | 177 | egl_display{connection->egl_native_display(), gl_config}, |
428 | 161 | cursor_listener{cursor_listener}, | 178 | cursor_listener{cursor_listener}, |
430 | 162 | outputs{} | 179 | outputs{}, |
431 | 180 | current_configuration(std::make_unique<NestedDisplayConfiguration>(connection->create_display_config())) | ||
432 | 163 | { | 181 | { |
433 | 164 | std::shared_ptr<DisplayConfiguration> conf(configuration()); | 182 | std::shared_ptr<DisplayConfiguration> conf(configuration()); |
434 | 165 | initial_conf_policy->apply_to(*conf); | 183 | initial_conf_policy->apply_to(*conf); |
435 | 184 | |||
436 | 185 | if (*current_configuration != *conf) | ||
437 | 186 | apply_to_connection(*conf); | ||
438 | 187 | |||
439 | 166 | create_surfaces(*conf); | 188 | create_surfaces(*conf); |
440 | 167 | } | 189 | } |
441 | 168 | 190 | ||
442 | @@ -181,8 +203,8 @@ | |||
443 | 181 | 203 | ||
444 | 182 | std::unique_ptr<mg::DisplayConfiguration> mgn::Display::configuration() const | 204 | std::unique_ptr<mg::DisplayConfiguration> mgn::Display::configuration() const |
445 | 183 | { | 205 | { |
448 | 184 | return std::make_unique<NestedDisplayConfiguration>( | 206 | std::lock_guard<std::mutex> lock(configuration_mutex); |
449 | 185 | connection->create_display_config()); | 207 | return std::make_unique<NestedDisplayConfiguration>(copy_config(*current_configuration)); |
450 | 186 | } | 208 | } |
451 | 187 | 209 | ||
452 | 188 | void mgn::Display::complete_display_initialization(MirPixelFormat format) | 210 | void mgn::Display::complete_display_initialization(MirPixelFormat format) |
453 | @@ -195,8 +217,12 @@ | |||
454 | 195 | 217 | ||
455 | 196 | void mgn::Display::configure(mg::DisplayConfiguration const& configuration) | 218 | void mgn::Display::configure(mg::DisplayConfiguration const& configuration) |
456 | 197 | { | 219 | { |
459 | 198 | create_surfaces(configuration); | 220 | std::lock_guard<std::mutex> lock(configuration_mutex); |
460 | 199 | apply_to_connection(configuration); | 221 | if (*current_configuration != configuration) |
461 | 222 | { | ||
462 | 223 | apply_to_connection(configuration); | ||
463 | 224 | create_surfaces(configuration); | ||
464 | 225 | } | ||
465 | 200 | } | 226 | } |
466 | 201 | 227 | ||
467 | 202 | void mgn::Display::create_surfaces(mg::DisplayConfiguration const& configuration) | 228 | void mgn::Display::create_surfaces(mg::DisplayConfiguration const& configuration) |
468 | @@ -254,13 +280,20 @@ | |||
469 | 254 | auto const& conf = dynamic_cast<NestedDisplayConfiguration const&>(configuration); | 280 | auto const& conf = dynamic_cast<NestedDisplayConfiguration const&>(configuration); |
470 | 255 | 281 | ||
471 | 256 | connection->apply_display_config(*conf); | 282 | connection->apply_display_config(*conf); |
472 | 283 | |||
473 | 284 | current_configuration = std::make_unique<NestedDisplayConfiguration>(copy_config(conf)); | ||
474 | 257 | } | 285 | } |
475 | 258 | 286 | ||
476 | 259 | void mgn::Display::register_configuration_change_handler( | 287 | void mgn::Display::register_configuration_change_handler( |
477 | 260 | EventHandlerRegister& /*handlers*/, | 288 | EventHandlerRegister& /*handlers*/, |
478 | 261 | DisplayConfigurationChangeHandler const& conf_change_handler) | 289 | DisplayConfigurationChangeHandler const& conf_change_handler) |
479 | 262 | { | 290 | { |
481 | 263 | connection->set_display_config_change_callback(conf_change_handler); | 291 | auto const handler = [this, conf_change_handler] { |
482 | 292 | current_configuration = std::make_unique<NestedDisplayConfiguration>(connection->create_display_config()); | ||
483 | 293 | conf_change_handler(); | ||
484 | 294 | }; | ||
485 | 295 | |||
486 | 296 | connection->set_display_config_change_callback(handler); | ||
487 | 264 | } | 297 | } |
488 | 265 | 298 | ||
489 | 266 | void mgn::Display::register_pause_resume_handlers( | 299 | void mgn::Display::register_pause_resume_handlers( |
490 | 267 | 300 | ||
491 | === modified file 'src/server/graphics/nested/display.h' | |||
492 | --- src/server/graphics/nested/display.h 2015-08-20 02:44:54 +0000 | |||
493 | +++ src/server/graphics/nested/display.h 2015-11-05 16:01:02 +0000 | |||
494 | @@ -52,6 +52,8 @@ | |||
495 | 52 | 52 | ||
496 | 53 | namespace nested | 53 | namespace nested |
497 | 54 | { | 54 | { |
498 | 55 | class NestedDisplayConfiguration; | ||
499 | 56 | |||
500 | 55 | namespace detail | 57 | namespace detail |
501 | 56 | { | 58 | { |
502 | 57 | 59 | ||
503 | @@ -151,6 +153,10 @@ | |||
504 | 151 | 153 | ||
505 | 152 | std::mutex outputs_mutex; | 154 | std::mutex outputs_mutex; |
506 | 153 | std::unordered_map<DisplayConfigurationOutputId, std::shared_ptr<detail::DisplaySyncGroup>> outputs; | 155 | std::unordered_map<DisplayConfigurationOutputId, std::shared_ptr<detail::DisplaySyncGroup>> outputs; |
507 | 156 | |||
508 | 157 | std::mutex mutable configuration_mutex; | ||
509 | 158 | std::unique_ptr<NestedDisplayConfiguration> current_configuration; | ||
510 | 159 | |||
511 | 154 | void create_surfaces(mir::graphics::DisplayConfiguration const& configuration); | 160 | void create_surfaces(mir::graphics::DisplayConfiguration const& configuration); |
512 | 155 | void apply_to_connection(mir::graphics::DisplayConfiguration const& configuration); | 161 | void apply_to_connection(mir::graphics::DisplayConfiguration const& configuration); |
513 | 156 | void complete_display_initialization(MirPixelFormat format); | 162 | void complete_display_initialization(MirPixelFormat format); |
514 | 157 | 163 | ||
515 | === modified file 'src/server/input/display_input_region.cpp' | |||
516 | --- src/server/input/display_input_region.cpp 2015-09-24 02:16:12 +0000 | |||
517 | +++ src/server/input/display_input_region.cpp 2015-11-05 16:01:02 +0000 | |||
518 | @@ -51,7 +51,10 @@ | |||
519 | 51 | // to group a touchscreen with a display. So for now, just return the view area | 51 | // to group a touchscreen with a display. So for now, just return the view area |
520 | 52 | // of the first display, as that matches the most common systems (laptops with touchscreens, | 52 | // of the first display, as that matches the most common systems (laptops with touchscreens, |
521 | 53 | // phone/tablets with touchscreens). | 53 | // phone/tablets with touchscreens). |
523 | 54 | return *rectangles.begin(); | 54 | if (rectangles.size() != 0) |
524 | 55 | return *rectangles.begin(); | ||
525 | 56 | else | ||
526 | 57 | return geom::Rectangle{}; | ||
527 | 55 | } | 58 | } |
528 | 56 | 59 | ||
529 | 57 | void mi::DisplayInputRegion::confine(geom::Point& point) | 60 | void mi::DisplayInputRegion::confine(geom::Point& point) |
530 | 58 | 61 | ||
531 | === modified file 'src/server/scene/rendering_tracker.cpp' | |||
532 | --- src/server/scene/rendering_tracker.cpp 2015-02-22 07:46:25 +0000 | |||
533 | +++ src/server/scene/rendering_tracker.cpp 2015-11-05 16:01:02 +0000 | |||
534 | @@ -68,6 +68,18 @@ | |||
535 | 68 | configure_visibility(mir_surface_visibility_occluded); | 68 | configure_visibility(mir_surface_visibility_occluded); |
536 | 69 | } | 69 | } |
537 | 70 | 70 | ||
538 | 71 | bool ms::RenderingTracker::is_exposed_in(mc::CompositorID cid) const | ||
539 | 72 | { | ||
540 | 73 | std::lock_guard<std::mutex> lock{guard}; | ||
541 | 74 | |||
542 | 75 | ensure_is_active_compositor(cid); | ||
543 | 76 | |||
544 | 77 | if (occlusions.size() == 0) | ||
545 | 78 | return true; | ||
546 | 79 | |||
547 | 80 | return occlusions.find(cid) == occlusions.end(); | ||
548 | 81 | } | ||
549 | 82 | |||
550 | 71 | bool ms::RenderingTracker::occluded_in_all_active_compositors() | 83 | bool ms::RenderingTracker::occluded_in_all_active_compositors() |
551 | 72 | { | 84 | { |
552 | 73 | return occlusions == active_compositors_; | 85 | return occlusions == active_compositors_; |
553 | 74 | 86 | ||
554 | === modified file 'src/server/scene/rendering_tracker.h' | |||
555 | --- src/server/scene/rendering_tracker.h 2015-02-22 07:46:25 +0000 | |||
556 | +++ src/server/scene/rendering_tracker.h 2015-11-05 16:01:02 +0000 | |||
557 | @@ -42,6 +42,7 @@ | |||
558 | 42 | void rendered_in(compositor::CompositorID cid); | 42 | void rendered_in(compositor::CompositorID cid); |
559 | 43 | void occluded_in(compositor::CompositorID cid); | 43 | void occluded_in(compositor::CompositorID cid); |
560 | 44 | void active_compositors(std::set<compositor::CompositorID> const& cids); | 44 | void active_compositors(std::set<compositor::CompositorID> const& cids); |
561 | 45 | bool is_exposed_in(compositor::CompositorID cid) const; | ||
562 | 45 | 46 | ||
563 | 46 | private: | 47 | private: |
564 | 47 | bool occluded_in_all_active_compositors(); | 48 | bool occluded_in_all_active_compositors(); |
565 | @@ -52,7 +53,7 @@ | |||
566 | 52 | std::weak_ptr<Surface> const weak_surface; | 53 | std::weak_ptr<Surface> const weak_surface; |
567 | 53 | std::set<compositor::CompositorID> occlusions; | 54 | std::set<compositor::CompositorID> occlusions; |
568 | 54 | std::set<compositor::CompositorID> active_compositors_; | 55 | std::set<compositor::CompositorID> active_compositors_; |
570 | 55 | std::mutex guard; | 56 | std::mutex mutable guard; |
571 | 56 | }; | 57 | }; |
572 | 57 | 58 | ||
573 | 58 | } | 59 | } |
574 | 59 | 60 | ||
575 | === modified file 'src/server/scene/surface_stack.cpp' | |||
576 | --- src/server/scene/surface_stack.cpp 2015-06-18 02:46:16 +0000 | |||
577 | +++ src/server/scene/surface_stack.cpp 2015-11-05 16:01:02 +0000 | |||
578 | @@ -168,15 +168,18 @@ | |||
579 | 168 | // TODO: Rename mir_surface_attrib_visibility as it's obviously | 168 | // TODO: Rename mir_surface_attrib_visibility as it's obviously |
580 | 169 | // confusing with visible() | 169 | // confusing with visible() |
581 | 170 | if (surface->visible() && | 170 | if (surface->visible() && |
584 | 171 | surface->query(mir_surface_attrib_visibility) == | 171 | surface->query(mir_surface_attrib_visibility) == mir_surface_visibility_exposed) |
583 | 172 | mir_surface_visibility_exposed) | ||
585 | 173 | { | 172 | { |
592 | 174 | // Note that we ask the surface and not a Renderable. | 173 | auto const tracker = rendering_trackers.find(surface.get()); |
593 | 175 | // This is because we don't want to waste time and resources | 174 | if (tracker != rendering_trackers.end() && tracker->second->is_exposed_in(id)) |
594 | 176 | // on a snapshot till we're sure we need it... | 175 | { |
595 | 177 | int ready = surface->buffers_ready_for_compositor(id); | 176 | // Note that we ask the surface and not a Renderable. |
596 | 178 | if (ready > result) | 177 | // This is because we don't want to waste time and resources |
597 | 179 | result = ready; | 178 | // on a snapshot till we're sure we need it... |
598 | 179 | int ready = surface->buffers_ready_for_compositor(id); | ||
599 | 180 | if (ready > result) | ||
600 | 181 | result = ready; | ||
601 | 182 | } | ||
602 | 180 | } | 183 | } |
603 | 181 | } | 184 | } |
604 | 182 | } | 185 | } |
605 | 183 | 186 | ||
606 | === modified file 'tests/acceptance-tests/test_nested_mir.cpp' | |||
607 | --- tests/acceptance-tests/test_nested_mir.cpp 2015-10-07 17:08:36 +0000 | |||
608 | +++ tests/acceptance-tests/test_nested_mir.cpp 2015-11-05 16:01:02 +0000 | |||
609 | @@ -22,12 +22,14 @@ | |||
610 | 22 | #include "mir/input/cursor_images.h" | 22 | #include "mir/input/cursor_images.h" |
611 | 23 | #include "mir/graphics/display.h" | 23 | #include "mir/graphics/display.h" |
612 | 24 | #include "mir/graphics/display_configuration.h" | 24 | #include "mir/graphics/display_configuration.h" |
613 | 25 | #include "mir/graphics/display_configuration_policy.h" | ||
614 | 25 | #include "mir/graphics/display_configuration_report.h" | 26 | #include "mir/graphics/display_configuration_report.h" |
615 | 26 | #include "mir/input/cursor_listener.h" | 27 | #include "mir/input/cursor_listener.h" |
616 | 27 | #include "mir/cached_ptr.h" | 28 | #include "mir/cached_ptr.h" |
617 | 28 | #include "mir/main_loop.h" | 29 | #include "mir/main_loop.h" |
618 | 29 | #include "mir/scene/session_coordinator.h" | 30 | #include "mir/scene/session_coordinator.h" |
619 | 30 | #include "mir/scene/session.h" | 31 | #include "mir/scene/session.h" |
620 | 32 | #include "mir/shell/display_configuration_controller.h" | ||
621 | 31 | #include "mir/shell/host_lifecycle_event_listener.h" | 33 | #include "mir/shell/host_lifecycle_event_listener.h" |
622 | 32 | 34 | ||
623 | 33 | #include "mir_test_framework/headless_in_process_server.h" | 35 | #include "mir_test_framework/headless_in_process_server.h" |
624 | @@ -183,10 +185,41 @@ | |||
625 | 183 | bool hidden{false}; | 185 | bool hidden{false}; |
626 | 184 | }; | 186 | }; |
627 | 185 | 187 | ||
628 | 188 | struct MockDisplayConfigurationPolicy : mg::DisplayConfigurationPolicy | ||
629 | 189 | { | ||
630 | 190 | MOCK_METHOD1(apply_to, void (mg::DisplayConfiguration&)); | ||
631 | 191 | }; | ||
632 | 192 | |||
633 | 186 | class NestedMirRunner : public mtf::HeadlessNestedServerRunner | 193 | class NestedMirRunner : public mtf::HeadlessNestedServerRunner |
634 | 187 | { | 194 | { |
635 | 188 | public: | 195 | public: |
636 | 189 | NestedMirRunner(std::string const& connection_string) | 196 | NestedMirRunner(std::string const& connection_string) |
637 | 197 | : NestedMirRunner(connection_string, true) | ||
638 | 198 | { | ||
639 | 199 | start_server(); | ||
640 | 200 | } | ||
641 | 201 | |||
642 | 202 | virtual ~NestedMirRunner() | ||
643 | 203 | { | ||
644 | 204 | stop_server(); | ||
645 | 205 | } | ||
646 | 206 | |||
647 | 207 | std::shared_ptr<MockHostLifecycleEventListener> the_mock_host_lifecycle_event_listener() | ||
648 | 208 | { | ||
649 | 209 | return mock_host_lifecycle_event_listener([] | ||
650 | 210 | { return std::make_shared<NiceMock<MockHostLifecycleEventListener>>(); }); | ||
651 | 211 | } | ||
652 | 212 | |||
653 | 213 | std::shared_ptr<CursorWrapper> cursor_wrapper; | ||
654 | 214 | |||
655 | 215 | virtual std::shared_ptr<MockDisplayConfigurationPolicy> mock_display_configuration_policy() | ||
656 | 216 | { | ||
657 | 217 | return mock_display_configuration_policy_([this] | ||
658 | 218 | { return std::make_shared<NiceMock<MockDisplayConfigurationPolicy>>(); }); | ||
659 | 219 | } | ||
660 | 220 | |||
661 | 221 | protected: | ||
662 | 222 | NestedMirRunner(std::string const& connection_string, bool) | ||
663 | 190 | : mtf::HeadlessNestedServerRunner(connection_string) | 223 | : mtf::HeadlessNestedServerRunner(connection_string) |
664 | 191 | { | 224 | { |
665 | 192 | server.override_the_host_lifecycle_event_listener([this] | 225 | server.override_the_host_lifecycle_event_listener([this] |
666 | @@ -197,24 +230,15 @@ | |||
667 | 197 | 230 | ||
668 | 198 | server.override_the_cursor_images([] { return std::make_shared<CursorImages>(); }); | 231 | server.override_the_cursor_images([] { return std::make_shared<CursorImages>(); }); |
669 | 199 | 232 | ||
685 | 200 | start_server(); | 233 | server.wrap_display_configuration_policy([this] |
686 | 201 | } | 234 | (std::shared_ptr<mg::DisplayConfigurationPolicy> const&) |
687 | 202 | 235 | { return mock_display_configuration_policy(); }); | |
688 | 203 | ~NestedMirRunner() | 236 | } |
674 | 204 | { | ||
675 | 205 | stop_server(); | ||
676 | 206 | } | ||
677 | 207 | |||
678 | 208 | std::shared_ptr<MockHostLifecycleEventListener> the_mock_host_lifecycle_event_listener() | ||
679 | 209 | { | ||
680 | 210 | return mock_host_lifecycle_event_listener([] | ||
681 | 211 | { return std::make_shared<NiceMock<MockHostLifecycleEventListener>>(); }); | ||
682 | 212 | } | ||
683 | 213 | |||
684 | 214 | std::shared_ptr<CursorWrapper> cursor_wrapper; | ||
689 | 215 | 237 | ||
690 | 216 | private: | 238 | private: |
691 | 217 | mir::CachedPtr<MockHostLifecycleEventListener> mock_host_lifecycle_event_listener; | 239 | mir::CachedPtr<MockHostLifecycleEventListener> mock_host_lifecycle_event_listener; |
692 | 240 | |||
693 | 241 | mir::CachedPtr<MockDisplayConfigurationPolicy> mock_display_configuration_policy_; | ||
694 | 218 | }; | 242 | }; |
695 | 219 | 243 | ||
696 | 220 | struct NestedServer : mtf::HeadlessInProcessServer | 244 | struct NestedServer : mtf::HeadlessInProcessServer |
697 | @@ -376,6 +400,7 @@ | |||
698 | 376 | // No post on surface creation | 400 | // No post on surface creation |
699 | 377 | EXPECT_CALL(*mock_session_mediator_report, session_submit_buffer_called(_)).Times(0); | 401 | EXPECT_CALL(*mock_session_mediator_report, session_submit_buffer_called(_)).Times(0); |
700 | 378 | NestedMirRunner nested_mir{new_connection()}; | 402 | NestedMirRunner nested_mir{new_connection()}; |
701 | 403 | |||
702 | 379 | auto const connection = mir_connect_sync(nested_mir.new_connection().c_str(), __PRETTY_FUNCTION__); | 404 | auto const connection = mir_connect_sync(nested_mir.new_connection().c_str(), __PRETTY_FUNCTION__); |
703 | 380 | auto const surface = mtf::make_any_surface(connection); | 405 | auto const surface = mtf::make_any_surface(connection); |
704 | 381 | 406 | ||
705 | @@ -692,3 +717,72 @@ | |||
706 | 692 | // surface as the host cursor then reverts to default. | 717 | // surface as the host cursor then reverts to default. |
707 | 693 | Mock::VerifyAndClearExpectations(mock_cursor.get()); | 718 | Mock::VerifyAndClearExpectations(mock_cursor.get()); |
708 | 694 | } | 719 | } |
709 | 720 | |||
710 | 721 | TEST_F(NestedServer, applies_display_config_on_startup) | ||
711 | 722 | { | ||
712 | 723 | mt::WaitCondition condition; | ||
713 | 724 | |||
714 | 725 | auto const expected_config = server.the_display()->configuration(); | ||
715 | 726 | expected_config->for_each_output([](mg::UserDisplayConfigurationOutput& output) | ||
716 | 727 | { output.orientation = mir_orientation_inverted;}); | ||
717 | 728 | |||
718 | 729 | EXPECT_CALL(*the_mock_display_configuration_report(), new_configuration(mt::DisplayConfigMatches(std::ref(*expected_config)))) | ||
719 | 730 | .WillRepeatedly(InvokeWithoutArgs([&] { condition.wake_up_everyone(); })); | ||
720 | 731 | |||
721 | 732 | struct MyNestedMirRunner : NestedMirRunner | ||
722 | 733 | { | ||
723 | 734 | MyNestedMirRunner(std::string const& connection_string) : | ||
724 | 735 | NestedMirRunner(connection_string, true) | ||
725 | 736 | { | ||
726 | 737 | start_server(); | ||
727 | 738 | } | ||
728 | 739 | |||
729 | 740 | std::shared_ptr<MockDisplayConfigurationPolicy> mock_display_configuration_policy() override | ||
730 | 741 | { | ||
731 | 742 | auto result = std::make_unique<MockDisplayConfigurationPolicy>(); | ||
732 | 743 | EXPECT_CALL(*result, apply_to(_)).Times(AnyNumber()) | ||
733 | 744 | .WillOnce(Invoke([](mg::DisplayConfiguration& config) | ||
734 | 745 | { | ||
735 | 746 | config.for_each_output([](mg::UserDisplayConfigurationOutput& output) | ||
736 | 747 | { output.orientation = mir_orientation_inverted; }); | ||
737 | 748 | })); | ||
738 | 749 | |||
739 | 750 | return std::shared_ptr<MockDisplayConfigurationPolicy>(std::move(result)); | ||
740 | 751 | } | ||
741 | 752 | } nested_mir{new_connection()}; | ||
742 | 753 | |||
743 | 754 | auto const connection = mir_connect_sync(nested_mir.new_connection().c_str(), __PRETTY_FUNCTION__); | ||
744 | 755 | auto const surface = make_and_paint_surface(connection); | ||
745 | 756 | |||
746 | 757 | condition.wait_for_at_most_seconds(1); | ||
747 | 758 | Mock::VerifyAndClearExpectations(the_mock_display_configuration_report().get()); | ||
748 | 759 | |||
749 | 760 | EXPECT_TRUE(condition.woken()); | ||
750 | 761 | |||
751 | 762 | mir_surface_release_sync(surface); | ||
752 | 763 | mir_connection_release(connection); | ||
753 | 764 | } | ||
754 | 765 | |||
755 | 766 | TEST_F(NestedServer, base_configuration_change_in_host_is_seen_in_nested) | ||
756 | 767 | { | ||
757 | 768 | NestedMirRunner nested_mir{new_connection()}; | ||
758 | 769 | auto const connection = mir_connect_sync(nested_mir.new_connection().c_str(), __PRETTY_FUNCTION__); | ||
759 | 770 | auto const surface = make_and_paint_surface(connection); | ||
760 | 771 | auto const config_policy = nested_mir.mock_display_configuration_policy(); | ||
761 | 772 | std::shared_ptr<mg::DisplayConfiguration> const new_config{server.the_display()->configuration()}; | ||
762 | 773 | new_config->for_each_output([](mg::UserDisplayConfigurationOutput& output) | ||
763 | 774 | { output.orientation = mir_orientation_inverted;}); | ||
764 | 775 | |||
765 | 776 | mt::WaitCondition condition; | ||
766 | 777 | EXPECT_CALL(*config_policy, apply_to(mt::DisplayConfigMatches(std::ref(*new_config)))) | ||
767 | 778 | .WillOnce(InvokeWithoutArgs([&] { condition.wake_up_everyone(); })); | ||
768 | 779 | |||
769 | 780 | server.the_display_configuration_controller()->set_default_display_configuration(new_config); | ||
770 | 781 | |||
771 | 782 | condition.wait_for_at_most_seconds(1); | ||
772 | 783 | Mock::VerifyAndClearExpectations(config_policy.get()); | ||
773 | 784 | EXPECT_TRUE(condition.woken()); | ||
774 | 785 | |||
775 | 786 | mir_surface_release_sync(surface); | ||
776 | 787 | mir_connection_release(connection); | ||
777 | 788 | } | ||
778 | 695 | 789 | ||
779 | === modified file 'tests/unit-tests/input/test_display_input_region.cpp' | |||
780 | --- tests/unit-tests/input/test_display_input_region.cpp 2015-09-24 02:16:12 +0000 | |||
781 | +++ tests/unit-tests/input/test_display_input_region.cpp 2015-11-05 16:01:02 +0000 | |||
782 | @@ -80,3 +80,14 @@ | |||
783 | 80 | } | 80 | } |
784 | 81 | 81 | ||
785 | 82 | } | 82 | } |
786 | 83 | |||
787 | 84 | TEST(DisplayInputRegionTest, returns_empty_bounding_rectangle_when_there_are_no_outputs) | ||
788 | 85 | { | ||
789 | 86 | geom::Rectangle const empty_rect{}; | ||
790 | 87 | auto const stub_display = std::make_shared<mtd::StubDisplay>(0); | ||
791 | 88 | |||
792 | 89 | mi::DisplayInputRegion input_region{stub_display}; | ||
793 | 90 | |||
794 | 91 | auto const bounding_rect = input_region.bounding_rectangle(); | ||
795 | 92 | EXPECT_EQ(empty_rect, bounding_rect); | ||
796 | 93 | } | ||
797 | 83 | 94 | ||
798 | === modified file 'tests/unit-tests/scene/test_surface_stack.cpp' | |||
799 | --- tests/unit-tests/scene/test_surface_stack.cpp 2015-06-26 08:00:59 +0000 | |||
800 | +++ tests/unit-tests/scene/test_surface_stack.cpp 2015-11-05 16:01:02 +0000 | |||
801 | @@ -339,6 +339,7 @@ | |||
802 | 339 | { | 339 | { |
803 | 340 | using namespace testing; | 340 | using namespace testing; |
804 | 341 | ms::SurfaceStack stack{report}; | 341 | ms::SurfaceStack stack{report}; |
805 | 342 | stack.register_compositor(this); | ||
806 | 342 | mtd::StubBuffer stub_buffer; | 343 | mtd::StubBuffer stub_buffer; |
807 | 343 | int ready = 0; | 344 | int ready = 0; |
808 | 344 | auto mock_queue = std::make_shared<testing::NiceMock<mtd::MockBufferBundle>>(); | 345 | auto mock_queue = std::make_shared<testing::NiceMock<mtd::MockBufferBundle>>(); |
809 | @@ -384,6 +385,7 @@ | |||
810 | 384 | using namespace testing; | 385 | using namespace testing; |
811 | 385 | 386 | ||
812 | 386 | ms::SurfaceStack stack{report}; | 387 | ms::SurfaceStack stack{report}; |
813 | 388 | stack.register_compositor(this); | ||
814 | 387 | auto surface = std::make_shared<ms::BasicSurface>( | 389 | auto surface = std::make_shared<ms::BasicSurface>( |
815 | 388 | std::string("stub"), | 390 | std::string("stub"), |
816 | 389 | geom::Rectangle{{},{}}, | 391 | geom::Rectangle{{},{}}, |
817 | @@ -405,6 +407,48 @@ | |||
818 | 405 | EXPECT_EQ(0, stack.frames_pending(this)); | 407 | EXPECT_EQ(0, stack.frames_pending(this)); |
819 | 406 | } | 408 | } |
820 | 407 | 409 | ||
821 | 410 | TEST_F(SurfaceStack, scene_doesnt_count_pending_frames_from_partially_exposed_surfaces) | ||
822 | 411 | { // Regression test for LP: #1499039 | ||
823 | 412 | using namespace testing; | ||
824 | 413 | |||
825 | 414 | // Partially exposed means occluded in one compositor but not another | ||
826 | 415 | ms::SurfaceStack stack{report}; | ||
827 | 416 | auto const comp1 = reinterpret_cast<mc::CompositorID>(0); | ||
828 | 417 | auto const comp2 = reinterpret_cast<mc::CompositorID>(1); | ||
829 | 418 | |||
830 | 419 | stack.register_compositor(comp1); | ||
831 | 420 | stack.register_compositor(comp2); | ||
832 | 421 | auto surface = std::make_shared<ms::BasicSurface>( | ||
833 | 422 | std::string("stub"), | ||
834 | 423 | geom::Rectangle{{},{}}, | ||
835 | 424 | false, | ||
836 | 425 | std::make_shared<mtd::StubBufferStream>(), | ||
837 | 426 | std::shared_ptr<mir::input::InputChannel>(), | ||
838 | 427 | std::shared_ptr<mir::input::InputSender>(), | ||
839 | 428 | std::shared_ptr<mg::CursorImage>(), | ||
840 | 429 | report); | ||
841 | 430 | |||
842 | 431 | stack.add_surface(surface, default_params.depth, default_params.input_mode); | ||
843 | 432 | post_a_frame(*surface); | ||
844 | 433 | post_a_frame(*surface); | ||
845 | 434 | post_a_frame(*surface); | ||
846 | 435 | |||
847 | 436 | EXPECT_EQ(3, stack.frames_pending(comp2)); | ||
848 | 437 | auto elements = stack.scene_elements_for(comp1); | ||
849 | 438 | for (auto const& elem : elements) | ||
850 | 439 | { | ||
851 | 440 | elem->rendered(); | ||
852 | 441 | } | ||
853 | 442 | |||
854 | 443 | elements = stack.scene_elements_for(comp2); | ||
855 | 444 | for (auto const& elem : elements) | ||
856 | 445 | { | ||
857 | 446 | elem->occluded(); | ||
858 | 447 | } | ||
859 | 448 | |||
860 | 449 | EXPECT_EQ(0, stack.frames_pending(comp2)); | ||
861 | 450 | } | ||
862 | 451 | |||
863 | 408 | TEST_F(SurfaceStack, surfaces_are_emitted_by_layer) | 452 | TEST_F(SurfaceStack, surfaces_are_emitted_by_layer) |
864 | 409 | { | 453 | { |
865 | 410 | using namespace testing; | 454 | using namespace testing; |
FAILED: Continuous integration, rev:3016 jenkins. qa.ubuntu. com/job/ mir-ubuntu- ci/87/ jenkins. qa.ubuntu. com/job/ mir-android- wily-i386- build/43/ console s-jenkins. ubuntu- ci:8080/ job/mir- clang-ts- wily-amd64- build/460/ console jenkins. qa.ubuntu. com/job/ mir-clang- wily-amd64- build/1132/ console jenkins. qa.ubuntu. com/job/ mir-ubuntu- wily-amd64- ci/42 jenkins. qa.ubuntu. com/job/ mir-ubuntu- wily-amd64- ci/42/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ mir-ubuntu- wily-armhf- ci/45/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/mir- ubuntu- ci/87/rebuild
http://