Mir

Merge lp:~afrantzis/mir/client-surface-buffering-mode into lp:mir

Proposed by Alexandros Frantzis
Status: Work in progress
Proposed branch: lp:~afrantzis/mir/client-surface-buffering-mode
Merge into: lp:mir
Diff against target: 499 lines (+233/-12)
18 files modified
include/client/mir_toolkit/mir_surface.h (+8/-0)
include/common/mir_toolkit/common.h (+7/-0)
include/server/mir/scene/surface_creation_parameters.h (+1/-0)
src/client/mir_surface.cpp (+2/-0)
src/client/mir_surface.h (+1/-0)
src/client/mir_surface_api.cpp (+6/-0)
src/client/symbols.map (+1/-0)
src/protobuf/mir_protobuf.proto (+4/-0)
src/server/frontend/session_mediator.cpp (+1/-0)
src/server/scene/surface_allocator.cpp (+10/-2)
src/server/scene/surface_creation_parameters.cpp (+1/-0)
tests/acceptance-tests/CMakeLists.txt (+1/-0)
tests/acceptance-tests/test_client_surface_buffering_mode.cpp (+133/-0)
tests/include/mir_test_doubles/null_display_sync_group.h (+19/-3)
tests/include/mir_test_doubles/stub_display.h (+13/-6)
tests/include/mir_test_framework/stub_server_platform_factory.h (+3/-0)
tests/mir_test_framework/stub_server_platform_factory.cpp (+13/-0)
tests/mir_test_framework/stubbed_graphics_platform.cpp (+9/-1)
To merge this branch: bzr merge lp:~afrantzis/mir/client-surface-buffering-mode
Reviewer Review Type Date Requested Status
Robert Carr (community) Approve
Chris Halse Rogers Needs Information
PS Jenkins bot (community) continuous-integration Approve
Kevin DuBois (community) Needs Information
Daniel van Vugt Needs Fixing
Alan Griffiths Approve
Review via email: mp+256455@code.launchpad.net

Commit message

client,server: Allow clients to specify the buffering mode for their surfaces

Description of the change

client,server: Allow clients to specify the buffering mode for their surfaces

This MP only allows setting the buffering mode at surface creation time. In the future it may be useful to also allow changing the buffering mode after creation time.

To post a comment you must log in.
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

89+bool mir_surface_spec_set_buffering_mode(MirSurfaceSpec* spec, MirBufferingMode mode)
90+{
91+ spec->buffering_mode = mode;
92+ return true;
93+}

Possibly worth validating the buffering mode at this point and returning false if it is nonsense?

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

std::chrono::milliseconds{0}

You can use literals now

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

OK

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

7: [ FAILED ] ServerShutdown.normal_exit_removes_endpoint
7: [ FAILED ] ClientFocusNotification.a_surface_is_notified_of_receiving_focus
7: [ FAILED ] ClientFocusNotification.two_surfaces_are_notified_of_gaining_and_losing_focus
7: [ FAILED ] ClientCredsTestFixture.session_authorizer_receives_pid_of_connecting_clients
7: [ FAILED ] ClientCredsTestFixture.authorizer_may_prevent_connection_of_clients
7: [ FAILED ] ServerDisconnect.is_detected_by_client
7: [ FAILED ] ServerDisconnect.doesnt_stop_client_calling_API_functions
7: [ FAILED ] ServerDisconnect.causes_client_to_terminate_by_default
7: [ FAILED ] ServerStartup.creates_endpoint_on_filesystem
7: [ FAILED ] ServerStartup.after_server_sigkilled_can_start_new_instance
7: [ FAILED ] UnresponsiveClient.does_not_hang_server
7: [ FAILED ] CustomInputDispatcher.receives_input
7: [ FAILED ] CustomInputDispatcher.gets_started_and_stopped
7: [ FAILED ] CustomInputDispatcher.receives_focus_changes
7: [ FAILED ] FocusSelection.when_surface_created_shell_is_notified_of_session
7: [ FAILED ] FocusSelection.when_surface_created_input_focus_is_set

11: [ FAILED ] MultiplexingDispatchableTest.removal_is_threadsafe

Ehh?

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

(0) In general I don't think this is a good idea. When I finish dynamic switching:
   https://code.launchpad.net/~vanvugt/mir/ddouble
only clients using the default auto setting will benefit. But we want all clients to benefit. So I suggest disapprove based on that.

(1) This enum doesn't need to exist. An int is clearer:
28 +typedef enum MirBufferingMode
29 +{
30 + mir_buffering_mode_default = 0,
31 + mir_buffering_mode_double = 2,
32 + mir_buffering_mode_triple = 3
33 +} MirBufferingMode;

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

(0) Come to think of it, there still is a use case for this. In future if we support single buffering properly then we need this interface.

(1) Still needs to be an int.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote :

It might be more flexible to just let the clients acquire more than one buffer at once, and then the clients just submit the buffer that they last-generated to the server for it to use.

Advantages:
* Gets us a bit closer to server-or-client-allocated buffers (as opposed to our server allocated buffers nowadays)
* This diffuses the density of the logic in BufferQueue a bit, as the client shares in the responsibility of how the flip chain works.
* The server doesn't even have to know if the client is running in swapinterval 0 or not, it would just have a last-submitted buffer.
* Nested-passthrough can use the normal BufferQueue, instead of dancing around the limitation that it can only get one buffer at a time.
* nested becomes an normal platform, as it has a way to allocate a buffer.
* we don't have to hash out what "double" and "triple" means exactly in the client api.

review: Needs Information
2491. By Alexandros Frantzis

client: Make mir_surface_spec_set_buffering_mode symbol public

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Chris Halse Rogers (raof) wrote :

*Needs discussion*

It *would* be more flexible for the client to be able to borrow multiple buffers. The simplifications Kevin mentions look pretty enticing.

It'd also make Daniel happy; we can make es2gears produce higher numbers in swapinterval 0 mode :).

This seems like it'd need a bit of design, though; particularly - what happens on resize or other invalidation, does the client need to submit buffers in the same order as received from the server?

Also worth wondering how we can use this to make Vulkan WSI easier.

review: Needs Information
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

> (0) In general I don't think this is a good idea. When I finish dynamic
> switching:
> https://code.launchpad.net/~vanvugt/mir/ddouble
> only clients using the default auto setting will benefit. But we want all
> clients to benefit. So I suggest disapprove based on that.

Any predictive algorithm needs the ability to be disabled. Especially by the client, as that the entity that has more knowledge about it's own rendering (And the tradeoffs it wants to make) that what you can guess at the server

Revision history for this message
Robert Carr (robertcarr) wrote :

Kevins approach is compelling.

This is a good gain for now though.

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

"Kevin's approach" sounds like what was described in bug 1253868. Maybe we need to reopen that...

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

It seems that we need to make some decisions at a higher level first (i.e. do allow clients to hold multiple buffers?) before deciding whether what's proposed in this MP is needed. The sprint seems a good time to discuss further.

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

Yeah, I was expecting that we'd discuss this at the sprint.

Unmerged revisions

2491. By Alexandros Frantzis

client: Make mir_surface_spec_set_buffering_mode symbol public

2490. By Alexandros Frantzis

client,server: Allow clients to specify the buffering mode for their surface

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/client/mir_toolkit/mir_surface.h'
2--- include/client/mir_toolkit/mir_surface.h 2015-04-14 11:29:11 +0000
3+++ include/client/mir_toolkit/mir_surface.h 2015-04-17 13:13:57 +0000
4@@ -323,6 +323,14 @@
5 bool mir_surface_spec_set_preferred_orientation(MirSurfaceSpec* spec, MirOrientationMode mode);
6
7 /**
8+ * Set the requested buffering mode.
9+ * \param [in] spec Specification to mutate
10+ * \param [in] mode Requested buffering mode
11+ * \return False if buffering mode is not a valid attribute of this surface type.
12+ */
13+bool mir_surface_spec_set_buffering_mode(MirSurfaceSpec* spec, MirBufferingMode mode);
14+
15+/**
16 * Release the resources held by a MirSurfaceSpec.
17 *
18 * \param [in] spec Specification to release
19
20=== modified file 'include/common/mir_toolkit/common.h'
21--- include/common/mir_toolkit/common.h 2015-03-31 02:35:42 +0000
22+++ include/common/mir_toolkit/common.h 2015-04-17 13:13:57 +0000
23@@ -166,6 +166,13 @@
24 mir_edge_attachment_any = mir_edge_attachment_vertical |
25 mir_edge_attachment_horizontal
26 } MirEdgeAttachment;
27+
28+typedef enum MirBufferingMode
29+{
30+ mir_buffering_mode_default = 0,
31+ mir_buffering_mode_double = 2,
32+ mir_buffering_mode_triple = 3
33+} MirBufferingMode;
34 /**@}*/
35
36 #endif
37
38=== modified file 'include/server/mir/scene/surface_creation_parameters.h'
39--- include/server/mir/scene/surface_creation_parameters.h 2015-04-14 10:23:11 +0000
40+++ include/server/mir/scene/surface_creation_parameters.h 2015-04-17 13:13:57 +0000
41@@ -87,6 +87,7 @@
42 mir::optional_value<frontend::SurfaceId> parent_id;
43 mir::optional_value<geometry::Rectangle> aux_rect;
44 mir::optional_value<MirEdgeAttachment> edge_attachment;
45+ mir::optional_value<MirBufferingMode> buffering_mode;
46
47 std::weak_ptr<Surface> parent;
48
49
50=== modified file 'src/client/mir_surface.cpp'
51--- src/client/mir_surface.cpp 2015-04-14 11:29:11 +0000
52+++ src/client/mir_surface.cpp 2015-04-17 13:13:57 +0000
53@@ -96,6 +96,7 @@
54 SERIALIZE_OPTION_IF_SET(min_height, message);
55 SERIALIZE_OPTION_IF_SET(max_width, message);
56 SERIALIZE_OPTION_IF_SET(max_height, message);
57+ SERIALIZE_OPTION_IF_SET(buffering_mode, message);
58
59 if (parent.is_set() && parent.value() != nullptr)
60 message.set_parent_id(parent.value()->id());
61@@ -563,6 +564,7 @@
62 COPY_IF_SET(min_height);
63 COPY_IF_SET(max_width);
64 COPY_IF_SET(max_height);
65+ COPY_IF_SET(buffering_mode);
66 #undef COPY_IF_SET
67
68 if (spec.surface_name.is_set())
69
70=== modified file 'src/client/mir_surface.h'
71--- src/client/mir_surface.h 2015-04-09 15:59:52 +0000
72+++ src/client/mir_surface.h 2015-04-17 13:13:57 +0000
73@@ -75,6 +75,7 @@
74 mir::optional_value<int> height;
75 mir::optional_value<MirPixelFormat> pixel_format;
76 mir::optional_value<MirBufferUsage> buffer_usage;
77+ mir::optional_value<MirBufferingMode> buffering_mode;
78
79 mir::optional_value<std::string> surface_name;
80 mir::optional_value<uint32_t> output_id;
81
82=== modified file 'src/client/mir_surface_api.cpp'
83--- src/client/mir_surface_api.cpp 2015-04-16 08:32:47 +0000
84+++ src/client/mir_surface_api.cpp 2015-04-17 13:13:57 +0000
85@@ -224,6 +224,12 @@
86 return true;
87 }
88
89+bool mir_surface_spec_set_buffering_mode(MirSurfaceSpec* spec, MirBufferingMode mode)
90+{
91+ spec->buffering_mode = mode;
92+ return true;
93+}
94+
95 void mir_surface_spec_release(MirSurfaceSpec* spec)
96 {
97 delete spec;
98
99=== modified file 'src/client/symbols.map'
100--- src/client/symbols.map 2015-04-16 08:32:47 +0000
101+++ src/client/symbols.map 2015-04-17 13:13:57 +0000
102@@ -163,6 +163,7 @@
103 mir_surface_event_get_attribute;
104 mir_surface_event_get_attribute_value;
105 mir_surface_set_swapinterval;
106+ mir_surface_spec_set_buffering_mode;
107 mir_surface_spec_set_min_width;
108 mir_surface_spec_set_min_height;
109 mir_surface_spec_set_max_width;
110
111=== modified file 'src/protobuf/mir_protobuf.proto'
112--- src/protobuf/mir_protobuf.proto 2015-04-14 10:23:11 +0000
113+++ src/protobuf/mir_protobuf.proto 2015-04-17 13:13:57 +0000
114@@ -31,6 +31,8 @@
115 optional int32 min_height = 14;
116 optional int32 max_width = 15;
117 optional int32 max_height = 16;
118+
119+ optional int32 buffering_mode = 17;
120 }
121
122 // If and when we break our protocol backward-compatibility, this could be
123@@ -53,6 +55,8 @@
124 optional int32 min_height = 14;
125 optional int32 max_width = 15;
126 optional int32 max_height = 16;
127+
128+ optional int32 buffering_mode = 17;
129 }
130
131
132
133=== modified file 'src/server/frontend/session_mediator.cpp'
134--- src/server/frontend/session_mediator.cpp 2015-04-16 20:59:36 +0000
135+++ src/server/frontend/session_mediator.cpp 2015-04-17 13:13:57 +0000
136@@ -239,6 +239,7 @@
137 COPY_IF_SET(min_height);
138 COPY_IF_SET(max_width);
139 COPY_IF_SET(max_height);
140+ COPY_IF_SET(buffering_mode);
141
142 #undef COPY_IF_SET
143
144
145=== modified file 'src/server/scene/surface_allocator.cpp'
146--- src/server/scene/surface_allocator.cpp 2015-03-31 02:35:42 +0000
147+++ src/server/scene/surface_allocator.cpp 2015-04-17 13:13:57 +0000
148@@ -58,9 +58,17 @@
149 mg::BufferProperties buffer_properties{params.size,
150 params.pixel_format,
151 params.buffer_usage};
152+ int buffers = nbuffers;
153+ if (params.buffering_mode.is_set())
154+ {
155+ if (params.buffering_mode.value() == mir_buffering_mode_double)
156+ buffers = 2;
157+ else if (params.buffering_mode.value() == mir_buffering_mode_triple)
158+ buffers = 3;
159+ }
160+
161 auto buffer_stream = buffer_stream_factory->create_buffer_stream(
162- nbuffers,
163- buffer_properties);
164+ buffers, buffer_properties);
165 auto actual_size = geom::Rectangle{params.top_left, buffer_stream->stream_size()};
166
167 bool nonrectangular = has_alpha(params.pixel_format);
168
169=== modified file 'src/server/scene/surface_creation_parameters.cpp'
170--- src/server/scene/surface_creation_parameters.cpp 2015-01-23 03:50:26 +0000
171+++ src/server/scene/surface_creation_parameters.cpp 2015-04-17 13:13:57 +0000
172@@ -151,6 +151,7 @@
173 lhs.state == rhs.state &&
174 lhs.type == rhs.type &&
175 lhs.preferred_orientation == rhs.preferred_orientation &&
176+ lhs.buffering_mode == rhs.buffering_mode &&
177 lhs.parent_id == rhs.parent_id;
178 }
179
180
181=== modified file 'tests/acceptance-tests/CMakeLists.txt'
182--- tests/acceptance-tests/CMakeLists.txt 2015-04-09 06:20:31 +0000
183+++ tests/acceptance-tests/CMakeLists.txt 2015-04-17 13:13:57 +0000
184@@ -41,6 +41,7 @@
185 test_shell_control_of_surface_configuration.cpp
186 test_render_override.cpp
187 test_surface_modifications.cpp
188+ test_client_surface_buffering_mode.cpp
189 )
190
191 if (MIR_TEST_PLATFORM STREQUAL "mesa")
192
193=== added file 'tests/acceptance-tests/test_client_surface_buffering_mode.cpp'
194--- tests/acceptance-tests/test_client_surface_buffering_mode.cpp 1970-01-01 00:00:00 +0000
195+++ tests/acceptance-tests/test_client_surface_buffering_mode.cpp 2015-04-17 13:13:57 +0000
196@@ -0,0 +1,133 @@
197+/*
198+ * Copyright © 2015 Canonical Ltd.
199+ *
200+ * This program is free software: you can redistribute it and/or modify it
201+ * under the terms of the GNU General Public License version 3,
202+ * as published by the Free Software Foundation.
203+ *
204+ * This program is distributed in the hope that it will be useful,
205+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
206+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
207+ * GNU General Public License for more details.
208+ *
209+ * You should have received a copy of the GNU General Public License
210+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
211+ *
212+ * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
213+ */
214+
215+#include "mir_toolkit/mir_client_library.h"
216+#include "mir_toolkit/debug/surface.h"
217+
218+#include "mir_test_framework/connected_client_headless_server.h"
219+#include "mir_test_framework/stub_server_platform_factory.h"
220+
221+#include <unordered_set>
222+#include <chrono>
223+
224+#include <gtest/gtest.h>
225+#include <gmock/gmock.h>
226+
227+namespace mtf = mir_test_framework;
228+
229+using namespace std::literals::chrono_literals;
230+
231+namespace
232+{
233+
234+struct WithDefaultSurfaceBuffers : mtf::ConnectedClientHeadlessServer,
235+ ::testing::WithParamInterface<int>
236+{
237+ WithDefaultSurfaceBuffers()
238+ {
239+ add_to_environment("MIR_SERVER_NBUFFERS", std::to_string(GetParam()).c_str());
240+ // In triple buffering mode the server initially allocates only two buffers,
241+ // and the third on demand. We use a non-zero vsync interval so that the client
242+ // can swap buffers faster than the server can process them, which forces the
243+ // server to allocate all surface buffers.
244+ mtf::set_next_vsync_interval(5ms);
245+ }
246+
247+ template<typename T> using UPtr = std::unique_ptr<T,void(*)(T*)>;
248+
249+ UPtr<MirSurface> create_surface_with_buffering_mode(MirBufferingMode mode)
250+ {
251+ auto const spec = UPtr<MirSurfaceSpec>{
252+ mir_connection_create_spec_for_normal_surface(
253+ connection, 640, 480, mir_pixel_format_argb_8888),
254+ mir_surface_spec_release};
255+
256+ mir_surface_spec_set_buffering_mode(spec.get(), mode);
257+
258+ return UPtr<MirSurface>{
259+ mir_surface_create_sync(spec.get()), mir_surface_release_sync};
260+ }
261+
262+ UPtr<MirSurface> create_surface_without_buffering_mode()
263+ {
264+ auto const spec = UPtr<MirSurfaceSpec>{
265+ mir_connection_create_spec_for_normal_surface(
266+ connection, 640, 480, mir_pixel_format_argb_8888),
267+ mir_surface_spec_release};
268+
269+ return UPtr<MirSurface>{
270+ mir_surface_create_sync(spec.get()), mir_surface_release_sync};
271+ }
272+
273+ unsigned int number_of_buffers_for(MirSurface* surface)
274+ {
275+ std::unordered_set<uint32_t> buffers;
276+
277+ for (int i = 0; i != 10; ++i)
278+ {
279+ mir_buffer_stream_swap_buffers_sync(
280+ mir_surface_get_buffer_stream(surface));
281+ buffers.insert(
282+ mir_debug_surface_current_buffer_id(surface));
283+ }
284+
285+ return buffers.size();
286+ }
287+};
288+
289+}
290+
291+TEST_P(WithDefaultSurfaceBuffers, allocates_two_buffers_when_client_requests_double_buffering)
292+{
293+ using namespace testing;
294+
295+ auto const surface = create_surface_with_buffering_mode(mir_buffering_mode_double);
296+
297+ EXPECT_THAT(number_of_buffers_for(surface.get()), Eq(2));
298+}
299+
300+TEST_P(WithDefaultSurfaceBuffers, allocates_three_buffers_when_client_requests_triple_buffering)
301+{
302+ using namespace testing;
303+
304+ auto const surface = create_surface_with_buffering_mode(mir_buffering_mode_triple);
305+
306+ EXPECT_THAT(number_of_buffers_for(surface.get()), Eq(3));
307+}
308+
309+TEST_P(WithDefaultSurfaceBuffers, allocates_default_buffers_when_client_requests_default_buffering)
310+{
311+ using namespace testing;
312+
313+ auto const surface = create_surface_with_buffering_mode(mir_buffering_mode_default);
314+
315+ EXPECT_THAT(number_of_buffers_for(surface.get()), Eq(GetParam()));
316+}
317+
318+TEST_P(WithDefaultSurfaceBuffers, allocates_default_buffers_when_client_does_not_specify_buffering)
319+{
320+ using namespace testing;
321+
322+ auto const surface = create_surface_without_buffering_mode();
323+
324+ EXPECT_THAT(number_of_buffers_for(surface.get()), Eq(GetParam()));
325+}
326+
327+INSTANTIATE_TEST_CASE_P(MirServer,
328+ WithDefaultSurfaceBuffers,
329+ ::testing::Values(2,3));
330
331=== modified file 'tests/include/mir_test_doubles/null_display_sync_group.h'
332--- tests/include/mir_test_doubles/null_display_sync_group.h 2015-02-20 19:44:17 +0000
333+++ tests/include/mir_test_doubles/null_display_sync_group.h 2015-04-17 13:13:57 +0000
334@@ -24,6 +24,7 @@
335 #include "null_display_buffer.h"
336 #include "stub_display_buffer.h"
337 #include <thread>
338+#include <chrono>
339
340 namespace mir
341 {
342@@ -36,12 +37,23 @@
343 {
344 public:
345 StubDisplaySyncGroup(std::vector<geometry::Rectangle> const& output_rects)
346- : output_rects{output_rects}
347+ : StubDisplaySyncGroup(output_rects, std::chrono::milliseconds{0})
348+ {
349+ }
350+
351+ StubDisplaySyncGroup(geometry::Size sz)
352+ : StubDisplaySyncGroup({{{0,0}, sz}}, std::chrono::milliseconds{0})
353+ {
354+ }
355+
356+ StubDisplaySyncGroup(std::vector<geometry::Rectangle> const& output_rects,
357+ std::chrono::milliseconds vsync_interval)
358+ : output_rects{output_rects},
359+ vsync_interval{vsync_interval}
360 {
361 for (auto const& output_rect : output_rects)
362 display_buffers.emplace_back(output_rect);
363 }
364- StubDisplaySyncGroup(geometry::Size sz) : StubDisplaySyncGroup({{{0,0}, sz}}) {}
365
366 void for_each_display_buffer(std::function<void(graphics::DisplayBuffer&)> const& f) override
367 {
368@@ -52,12 +64,16 @@
369 void post() override
370 {
371 /* yield() is needed to ensure reasonable runtime under valgrind for some tests */
372- std::this_thread::yield();
373+ if (vsync_interval == vsync_interval.zero())
374+ std::this_thread::yield();
375+ else
376+ std::this_thread::sleep_for(vsync_interval);
377 }
378
379 private:
380 std::vector<geometry::Rectangle> const output_rects;
381 std::vector<StubDisplayBuffer> display_buffers;
382+ std::chrono::milliseconds vsync_interval{0};
383 };
384
385 struct NullDisplaySyncGroup : graphics::DisplaySyncGroup
386
387=== modified file 'tests/include/mir_test_doubles/stub_display.h'
388--- tests/include/mir_test_doubles/stub_display.h 2015-03-31 02:35:42 +0000
389+++ tests/include/mir_test_doubles/stub_display.h 2015-04-17 13:13:57 +0000
390@@ -27,6 +27,7 @@
391 #include "mir/geometry/rectangle.h"
392
393 #include <vector>
394+#include <chrono>
395
396 namespace mir
397 {
398@@ -39,15 +40,21 @@
399 {
400 public:
401 StubDisplay(std::vector<geometry::Rectangle> const& output_rects) :
402+ StubDisplay(output_rects, std::chrono::milliseconds::zero())
403+ {
404+ }
405+
406+ StubDisplay(unsigned int nbuffers) :
407+ StubDisplay(generate_stub_rects(nbuffers))
408+ {
409+ }
410+
411+ StubDisplay(std::vector<geometry::Rectangle> const& output_rects,
412+ std::chrono::milliseconds vsync_interval) :
413 output_rects(output_rects)
414 {
415 for (auto const& rect : output_rects)
416- groups.emplace_back(new StubDisplaySyncGroup({rect}));
417- }
418-
419- StubDisplay(unsigned int nbuffers) :
420- StubDisplay(generate_stub_rects(nbuffers))
421- {
422+ groups.emplace_back(new StubDisplaySyncGroup({rect}, vsync_interval));
423 }
424
425 void for_each_display_sync_group(std::function<void(graphics::DisplaySyncGroup&)> const& f) override
426
427=== modified file 'tests/include/mir_test_framework/stub_server_platform_factory.h'
428--- tests/include/mir_test_framework/stub_server_platform_factory.h 2015-04-09 06:20:31 +0000
429+++ tests/include/mir_test_framework/stub_server_platform_factory.h 2015-04-17 13:13:57 +0000
430@@ -26,6 +26,7 @@
431 #include <vector>
432 #include <memory>
433 #include <string>
434+#include <chrono>
435
436 namespace geom = mir::geometry;
437
438@@ -53,6 +54,8 @@
439
440 void set_next_preset_display(std::shared_ptr<mir::graphics::Display> const& display);
441
442+void set_next_vsync_interval(std::chrono::milliseconds interval);
443+
444 mir::UniqueModulePtr<FakeInputDevice> add_fake_input_device(mir::input::InputDeviceInfo const& info);
445 }
446 #endif /* MIR_TEST_FRAMEWORK_STUB_SERVER_PLATFORM_FACTORY_ */
447
448=== modified file 'tests/mir_test_framework/stub_server_platform_factory.cpp'
449--- tests/mir_test_framework/stub_server_platform_factory.cpp 2015-04-09 06:20:31 +0000
450+++ tests/mir_test_framework/stub_server_platform_factory.cpp 2015-04-17 13:13:57 +0000
451@@ -87,3 +87,16 @@
452
453 return add_device(info);
454 }
455+
456+void mtf::set_next_vsync_interval(
457+ std::chrono::milliseconds interval)
458+{
459+ ensure_platform_library();
460+
461+ using func_sig = void(*)(std::chrono::milliseconds);
462+
463+ auto const set_next_vsync_interval =
464+ platform_graphics_lib->load_function<func_sig>("set_next_vsync_interval");
465+
466+ return set_next_vsync_interval(interval);
467+}
468
469=== modified file 'tests/mir_test_framework/stubbed_graphics_platform.cpp'
470--- tests/mir_test_framework/stubbed_graphics_platform.cpp 2015-03-31 02:35:42 +0000
471+++ tests/mir_test_framework/stubbed_graphics_platform.cpp 2015-04-17 13:13:57 +0000
472@@ -228,6 +228,7 @@
473 namespace
474 {
475 std::shared_ptr<mg::Display> display_preset;
476+std::chrono::milliseconds vsync_interval;
477 }
478
479 std::shared_ptr<mg::Display> mtf::StubGraphicPlatform::create_display(
480@@ -238,7 +239,9 @@
481 if (display_preset)
482 return std::move(display_preset);
483
484- return std::make_shared<mtd::StubDisplay>(display_rects);
485+ auto const tmp_vsync = vsync_interval;
486+ vsync_interval = std::chrono::milliseconds::zero();
487+ return std::make_shared<mtd::StubDisplay>(display_rects, tmp_vsync);
488 }
489
490 namespace
491@@ -334,3 +337,8 @@
492 {
493 display_preset = display;
494 }
495+
496+extern "C" void set_next_vsync_interval(std::chrono::milliseconds interval)
497+{
498+ vsync_interval = interval;
499+}

Subscribers

People subscribed via source and target branches