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
=== modified file 'include/client/mir_toolkit/mir_surface.h'
--- include/client/mir_toolkit/mir_surface.h 2015-04-14 11:29:11 +0000
+++ include/client/mir_toolkit/mir_surface.h 2015-04-17 13:13:57 +0000
@@ -323,6 +323,14 @@
323bool mir_surface_spec_set_preferred_orientation(MirSurfaceSpec* spec, MirOrientationMode mode);323bool mir_surface_spec_set_preferred_orientation(MirSurfaceSpec* spec, MirOrientationMode mode);
324324
325/**325/**
326 * Set the requested buffering mode.
327 * \param [in] spec Specification to mutate
328 * \param [in] mode Requested buffering mode
329 * \return False if buffering mode is not a valid attribute of this surface type.
330 */
331bool mir_surface_spec_set_buffering_mode(MirSurfaceSpec* spec, MirBufferingMode mode);
332
333/**
326 * Release the resources held by a MirSurfaceSpec.334 * Release the resources held by a MirSurfaceSpec.
327 *335 *
328 * \param [in] spec Specification to release336 * \param [in] spec Specification to release
329337
=== modified file 'include/common/mir_toolkit/common.h'
--- include/common/mir_toolkit/common.h 2015-03-31 02:35:42 +0000
+++ include/common/mir_toolkit/common.h 2015-04-17 13:13:57 +0000
@@ -166,6 +166,13 @@
166 mir_edge_attachment_any = mir_edge_attachment_vertical |166 mir_edge_attachment_any = mir_edge_attachment_vertical |
167 mir_edge_attachment_horizontal167 mir_edge_attachment_horizontal
168} MirEdgeAttachment;168} MirEdgeAttachment;
169
170typedef enum MirBufferingMode
171{
172 mir_buffering_mode_default = 0,
173 mir_buffering_mode_double = 2,
174 mir_buffering_mode_triple = 3
175} MirBufferingMode;
169/**@}*/176/**@}*/
170177
171#endif178#endif
172179
=== modified file 'include/server/mir/scene/surface_creation_parameters.h'
--- include/server/mir/scene/surface_creation_parameters.h 2015-04-14 10:23:11 +0000
+++ include/server/mir/scene/surface_creation_parameters.h 2015-04-17 13:13:57 +0000
@@ -87,6 +87,7 @@
87 mir::optional_value<frontend::SurfaceId> parent_id;87 mir::optional_value<frontend::SurfaceId> parent_id;
88 mir::optional_value<geometry::Rectangle> aux_rect;88 mir::optional_value<geometry::Rectangle> aux_rect;
89 mir::optional_value<MirEdgeAttachment> edge_attachment;89 mir::optional_value<MirEdgeAttachment> edge_attachment;
90 mir::optional_value<MirBufferingMode> buffering_mode;
9091
91 std::weak_ptr<Surface> parent;92 std::weak_ptr<Surface> parent;
9293
9394
=== modified file 'src/client/mir_surface.cpp'
--- src/client/mir_surface.cpp 2015-04-14 11:29:11 +0000
+++ src/client/mir_surface.cpp 2015-04-17 13:13:57 +0000
@@ -96,6 +96,7 @@
96 SERIALIZE_OPTION_IF_SET(min_height, message);96 SERIALIZE_OPTION_IF_SET(min_height, message);
97 SERIALIZE_OPTION_IF_SET(max_width, message);97 SERIALIZE_OPTION_IF_SET(max_width, message);
98 SERIALIZE_OPTION_IF_SET(max_height, message);98 SERIALIZE_OPTION_IF_SET(max_height, message);
99 SERIALIZE_OPTION_IF_SET(buffering_mode, message);
99100
100 if (parent.is_set() && parent.value() != nullptr)101 if (parent.is_set() && parent.value() != nullptr)
101 message.set_parent_id(parent.value()->id());102 message.set_parent_id(parent.value()->id());
@@ -563,6 +564,7 @@
563 COPY_IF_SET(min_height);564 COPY_IF_SET(min_height);
564 COPY_IF_SET(max_width);565 COPY_IF_SET(max_width);
565 COPY_IF_SET(max_height);566 COPY_IF_SET(max_height);
567 COPY_IF_SET(buffering_mode);
566 #undef COPY_IF_SET568 #undef COPY_IF_SET
567569
568 if (spec.surface_name.is_set())570 if (spec.surface_name.is_set())
569571
=== modified file 'src/client/mir_surface.h'
--- src/client/mir_surface.h 2015-04-09 15:59:52 +0000
+++ src/client/mir_surface.h 2015-04-17 13:13:57 +0000
@@ -75,6 +75,7 @@
75 mir::optional_value<int> height;75 mir::optional_value<int> height;
76 mir::optional_value<MirPixelFormat> pixel_format;76 mir::optional_value<MirPixelFormat> pixel_format;
77 mir::optional_value<MirBufferUsage> buffer_usage;77 mir::optional_value<MirBufferUsage> buffer_usage;
78 mir::optional_value<MirBufferingMode> buffering_mode;
7879
79 mir::optional_value<std::string> surface_name;80 mir::optional_value<std::string> surface_name;
80 mir::optional_value<uint32_t> output_id;81 mir::optional_value<uint32_t> output_id;
8182
=== modified file 'src/client/mir_surface_api.cpp'
--- src/client/mir_surface_api.cpp 2015-04-16 08:32:47 +0000
+++ src/client/mir_surface_api.cpp 2015-04-17 13:13:57 +0000
@@ -224,6 +224,12 @@
224 return true;224 return true;
225}225}
226226
227bool mir_surface_spec_set_buffering_mode(MirSurfaceSpec* spec, MirBufferingMode mode)
228{
229 spec->buffering_mode = mode;
230 return true;
231}
232
227void mir_surface_spec_release(MirSurfaceSpec* spec)233void mir_surface_spec_release(MirSurfaceSpec* spec)
228{234{
229 delete spec;235 delete spec;
230236
=== modified file 'src/client/symbols.map'
--- src/client/symbols.map 2015-04-16 08:32:47 +0000
+++ src/client/symbols.map 2015-04-17 13:13:57 +0000
@@ -163,6 +163,7 @@
163 mir_surface_event_get_attribute;163 mir_surface_event_get_attribute;
164 mir_surface_event_get_attribute_value;164 mir_surface_event_get_attribute_value;
165 mir_surface_set_swapinterval;165 mir_surface_set_swapinterval;
166 mir_surface_spec_set_buffering_mode;
166 mir_surface_spec_set_min_width;167 mir_surface_spec_set_min_width;
167 mir_surface_spec_set_min_height;168 mir_surface_spec_set_min_height;
168 mir_surface_spec_set_max_width;169 mir_surface_spec_set_max_width;
169170
=== modified file 'src/protobuf/mir_protobuf.proto'
--- src/protobuf/mir_protobuf.proto 2015-04-14 10:23:11 +0000
+++ src/protobuf/mir_protobuf.proto 2015-04-17 13:13:57 +0000
@@ -31,6 +31,8 @@
31 optional int32 min_height = 14;31 optional int32 min_height = 14;
32 optional int32 max_width = 15;32 optional int32 max_width = 15;
33 optional int32 max_height = 16;33 optional int32 max_height = 16;
34
35 optional int32 buffering_mode = 17;
34}36}
3537
36// If and when we break our protocol backward-compatibility, this could be38// If and when we break our protocol backward-compatibility, this could be
@@ -53,6 +55,8 @@
53 optional int32 min_height = 14;55 optional int32 min_height = 14;
54 optional int32 max_width = 15;56 optional int32 max_width = 15;
55 optional int32 max_height = 16;57 optional int32 max_height = 16;
58
59 optional int32 buffering_mode = 17;
56}60}
5761
5862
5963
=== modified file 'src/server/frontend/session_mediator.cpp'
--- src/server/frontend/session_mediator.cpp 2015-04-16 20:59:36 +0000
+++ src/server/frontend/session_mediator.cpp 2015-04-17 13:13:57 +0000
@@ -239,6 +239,7 @@
239 COPY_IF_SET(min_height);239 COPY_IF_SET(min_height);
240 COPY_IF_SET(max_width);240 COPY_IF_SET(max_width);
241 COPY_IF_SET(max_height);241 COPY_IF_SET(max_height);
242 COPY_IF_SET(buffering_mode);
242243
243 #undef COPY_IF_SET244 #undef COPY_IF_SET
244245
245246
=== modified file 'src/server/scene/surface_allocator.cpp'
--- src/server/scene/surface_allocator.cpp 2015-03-31 02:35:42 +0000
+++ src/server/scene/surface_allocator.cpp 2015-04-17 13:13:57 +0000
@@ -58,9 +58,17 @@
58 mg::BufferProperties buffer_properties{params.size,58 mg::BufferProperties buffer_properties{params.size,
59 params.pixel_format,59 params.pixel_format,
60 params.buffer_usage};60 params.buffer_usage};
61 int buffers = nbuffers;
62 if (params.buffering_mode.is_set())
63 {
64 if (params.buffering_mode.value() == mir_buffering_mode_double)
65 buffers = 2;
66 else if (params.buffering_mode.value() == mir_buffering_mode_triple)
67 buffers = 3;
68 }
69
61 auto buffer_stream = buffer_stream_factory->create_buffer_stream(70 auto buffer_stream = buffer_stream_factory->create_buffer_stream(
62 nbuffers,71 buffers, buffer_properties);
63 buffer_properties);
64 auto actual_size = geom::Rectangle{params.top_left, buffer_stream->stream_size()};72 auto actual_size = geom::Rectangle{params.top_left, buffer_stream->stream_size()};
6573
66 bool nonrectangular = has_alpha(params.pixel_format);74 bool nonrectangular = has_alpha(params.pixel_format);
6775
=== modified file 'src/server/scene/surface_creation_parameters.cpp'
--- src/server/scene/surface_creation_parameters.cpp 2015-01-23 03:50:26 +0000
+++ src/server/scene/surface_creation_parameters.cpp 2015-04-17 13:13:57 +0000
@@ -151,6 +151,7 @@
151 lhs.state == rhs.state &&151 lhs.state == rhs.state &&
152 lhs.type == rhs.type &&152 lhs.type == rhs.type &&
153 lhs.preferred_orientation == rhs.preferred_orientation &&153 lhs.preferred_orientation == rhs.preferred_orientation &&
154 lhs.buffering_mode == rhs.buffering_mode &&
154 lhs.parent_id == rhs.parent_id;155 lhs.parent_id == rhs.parent_id;
155}156}
156157
157158
=== modified file 'tests/acceptance-tests/CMakeLists.txt'
--- tests/acceptance-tests/CMakeLists.txt 2015-04-09 06:20:31 +0000
+++ tests/acceptance-tests/CMakeLists.txt 2015-04-17 13:13:57 +0000
@@ -41,6 +41,7 @@
41 test_shell_control_of_surface_configuration.cpp41 test_shell_control_of_surface_configuration.cpp
42 test_render_override.cpp42 test_render_override.cpp
43 test_surface_modifications.cpp43 test_surface_modifications.cpp
44 test_client_surface_buffering_mode.cpp
44)45)
4546
46if (MIR_TEST_PLATFORM STREQUAL "mesa")47if (MIR_TEST_PLATFORM STREQUAL "mesa")
4748
=== added file 'tests/acceptance-tests/test_client_surface_buffering_mode.cpp'
--- tests/acceptance-tests/test_client_surface_buffering_mode.cpp 1970-01-01 00:00:00 +0000
+++ tests/acceptance-tests/test_client_surface_buffering_mode.cpp 2015-04-17 13:13:57 +0000
@@ -0,0 +1,133 @@
1/*
2 * Copyright © 2015 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: Alexandros Frantzis <alexandros.frantzis@canonical.com>
17 */
18
19#include "mir_toolkit/mir_client_library.h"
20#include "mir_toolkit/debug/surface.h"
21
22#include "mir_test_framework/connected_client_headless_server.h"
23#include "mir_test_framework/stub_server_platform_factory.h"
24
25#include <unordered_set>
26#include <chrono>
27
28#include <gtest/gtest.h>
29#include <gmock/gmock.h>
30
31namespace mtf = mir_test_framework;
32
33using namespace std::literals::chrono_literals;
34
35namespace
36{
37
38struct WithDefaultSurfaceBuffers : mtf::ConnectedClientHeadlessServer,
39 ::testing::WithParamInterface<int>
40{
41 WithDefaultSurfaceBuffers()
42 {
43 add_to_environment("MIR_SERVER_NBUFFERS", std::to_string(GetParam()).c_str());
44 // In triple buffering mode the server initially allocates only two buffers,
45 // and the third on demand. We use a non-zero vsync interval so that the client
46 // can swap buffers faster than the server can process them, which forces the
47 // server to allocate all surface buffers.
48 mtf::set_next_vsync_interval(5ms);
49 }
50
51 template<typename T> using UPtr = std::unique_ptr<T,void(*)(T*)>;
52
53 UPtr<MirSurface> create_surface_with_buffering_mode(MirBufferingMode mode)
54 {
55 auto const spec = UPtr<MirSurfaceSpec>{
56 mir_connection_create_spec_for_normal_surface(
57 connection, 640, 480, mir_pixel_format_argb_8888),
58 mir_surface_spec_release};
59
60 mir_surface_spec_set_buffering_mode(spec.get(), mode);
61
62 return UPtr<MirSurface>{
63 mir_surface_create_sync(spec.get()), mir_surface_release_sync};
64 }
65
66 UPtr<MirSurface> create_surface_without_buffering_mode()
67 {
68 auto const spec = UPtr<MirSurfaceSpec>{
69 mir_connection_create_spec_for_normal_surface(
70 connection, 640, 480, mir_pixel_format_argb_8888),
71 mir_surface_spec_release};
72
73 return UPtr<MirSurface>{
74 mir_surface_create_sync(spec.get()), mir_surface_release_sync};
75 }
76
77 unsigned int number_of_buffers_for(MirSurface* surface)
78 {
79 std::unordered_set<uint32_t> buffers;
80
81 for (int i = 0; i != 10; ++i)
82 {
83 mir_buffer_stream_swap_buffers_sync(
84 mir_surface_get_buffer_stream(surface));
85 buffers.insert(
86 mir_debug_surface_current_buffer_id(surface));
87 }
88
89 return buffers.size();
90 }
91};
92
93}
94
95TEST_P(WithDefaultSurfaceBuffers, allocates_two_buffers_when_client_requests_double_buffering)
96{
97 using namespace testing;
98
99 auto const surface = create_surface_with_buffering_mode(mir_buffering_mode_double);
100
101 EXPECT_THAT(number_of_buffers_for(surface.get()), Eq(2));
102}
103
104TEST_P(WithDefaultSurfaceBuffers, allocates_three_buffers_when_client_requests_triple_buffering)
105{
106 using namespace testing;
107
108 auto const surface = create_surface_with_buffering_mode(mir_buffering_mode_triple);
109
110 EXPECT_THAT(number_of_buffers_for(surface.get()), Eq(3));
111}
112
113TEST_P(WithDefaultSurfaceBuffers, allocates_default_buffers_when_client_requests_default_buffering)
114{
115 using namespace testing;
116
117 auto const surface = create_surface_with_buffering_mode(mir_buffering_mode_default);
118
119 EXPECT_THAT(number_of_buffers_for(surface.get()), Eq(GetParam()));
120}
121
122TEST_P(WithDefaultSurfaceBuffers, allocates_default_buffers_when_client_does_not_specify_buffering)
123{
124 using namespace testing;
125
126 auto const surface = create_surface_without_buffering_mode();
127
128 EXPECT_THAT(number_of_buffers_for(surface.get()), Eq(GetParam()));
129}
130
131INSTANTIATE_TEST_CASE_P(MirServer,
132 WithDefaultSurfaceBuffers,
133 ::testing::Values(2,3));
0134
=== modified file 'tests/include/mir_test_doubles/null_display_sync_group.h'
--- tests/include/mir_test_doubles/null_display_sync_group.h 2015-02-20 19:44:17 +0000
+++ tests/include/mir_test_doubles/null_display_sync_group.h 2015-04-17 13:13:57 +0000
@@ -24,6 +24,7 @@
24#include "null_display_buffer.h"24#include "null_display_buffer.h"
25#include "stub_display_buffer.h"25#include "stub_display_buffer.h"
26#include <thread>26#include <thread>
27#include <chrono>
2728
28namespace mir29namespace mir
29{30{
@@ -36,12 +37,23 @@
36{37{
37public:38public:
38 StubDisplaySyncGroup(std::vector<geometry::Rectangle> const& output_rects)39 StubDisplaySyncGroup(std::vector<geometry::Rectangle> const& output_rects)
39 : output_rects{output_rects}40 : StubDisplaySyncGroup(output_rects, std::chrono::milliseconds{0})
41 {
42 }
43
44 StubDisplaySyncGroup(geometry::Size sz)
45 : StubDisplaySyncGroup({{{0,0}, sz}}, std::chrono::milliseconds{0})
46 {
47 }
48
49 StubDisplaySyncGroup(std::vector<geometry::Rectangle> const& output_rects,
50 std::chrono::milliseconds vsync_interval)
51 : output_rects{output_rects},
52 vsync_interval{vsync_interval}
40 {53 {
41 for (auto const& output_rect : output_rects)54 for (auto const& output_rect : output_rects)
42 display_buffers.emplace_back(output_rect);55 display_buffers.emplace_back(output_rect);
43 }56 }
44 StubDisplaySyncGroup(geometry::Size sz) : StubDisplaySyncGroup({{{0,0}, sz}}) {}
4557
46 void for_each_display_buffer(std::function<void(graphics::DisplayBuffer&)> const& f) override58 void for_each_display_buffer(std::function<void(graphics::DisplayBuffer&)> const& f) override
47 {59 {
@@ -52,12 +64,16 @@
52 void post() override64 void post() override
53 {65 {
54 /* yield() is needed to ensure reasonable runtime under valgrind for some tests */66 /* yield() is needed to ensure reasonable runtime under valgrind for some tests */
55 std::this_thread::yield();67 if (vsync_interval == vsync_interval.zero())
68 std::this_thread::yield();
69 else
70 std::this_thread::sleep_for(vsync_interval);
56 }71 }
5772
58private:73private:
59 std::vector<geometry::Rectangle> const output_rects;74 std::vector<geometry::Rectangle> const output_rects;
60 std::vector<StubDisplayBuffer> display_buffers;75 std::vector<StubDisplayBuffer> display_buffers;
76 std::chrono::milliseconds vsync_interval{0};
61};77};
6278
63struct NullDisplaySyncGroup : graphics::DisplaySyncGroup79struct NullDisplaySyncGroup : graphics::DisplaySyncGroup
6480
=== modified file 'tests/include/mir_test_doubles/stub_display.h'
--- tests/include/mir_test_doubles/stub_display.h 2015-03-31 02:35:42 +0000
+++ tests/include/mir_test_doubles/stub_display.h 2015-04-17 13:13:57 +0000
@@ -27,6 +27,7 @@
27#include "mir/geometry/rectangle.h"27#include "mir/geometry/rectangle.h"
2828
29#include <vector>29#include <vector>
30#include <chrono>
3031
31namespace mir32namespace mir
32{33{
@@ -39,15 +40,21 @@
39{40{
40public:41public:
41 StubDisplay(std::vector<geometry::Rectangle> const& output_rects) :42 StubDisplay(std::vector<geometry::Rectangle> const& output_rects) :
43 StubDisplay(output_rects, std::chrono::milliseconds::zero())
44 {
45 }
46
47 StubDisplay(unsigned int nbuffers) :
48 StubDisplay(generate_stub_rects(nbuffers))
49 {
50 }
51
52 StubDisplay(std::vector<geometry::Rectangle> const& output_rects,
53 std::chrono::milliseconds vsync_interval) :
42 output_rects(output_rects)54 output_rects(output_rects)
43 {55 {
44 for (auto const& rect : output_rects)56 for (auto const& rect : output_rects)
45 groups.emplace_back(new StubDisplaySyncGroup({rect}));57 groups.emplace_back(new StubDisplaySyncGroup({rect}, vsync_interval));
46 }
47
48 StubDisplay(unsigned int nbuffers) :
49 StubDisplay(generate_stub_rects(nbuffers))
50 {
51 }58 }
5259
53 void for_each_display_sync_group(std::function<void(graphics::DisplaySyncGroup&)> const& f) override60 void for_each_display_sync_group(std::function<void(graphics::DisplaySyncGroup&)> const& f) override
5461
=== modified file 'tests/include/mir_test_framework/stub_server_platform_factory.h'
--- tests/include/mir_test_framework/stub_server_platform_factory.h 2015-04-09 06:20:31 +0000
+++ tests/include/mir_test_framework/stub_server_platform_factory.h 2015-04-17 13:13:57 +0000
@@ -26,6 +26,7 @@
26#include <vector>26#include <vector>
27#include <memory>27#include <memory>
28#include <string>28#include <string>
29#include <chrono>
2930
30namespace geom = mir::geometry;31namespace geom = mir::geometry;
3132
@@ -53,6 +54,8 @@
5354
54void set_next_preset_display(std::shared_ptr<mir::graphics::Display> const& display);55void set_next_preset_display(std::shared_ptr<mir::graphics::Display> const& display);
5556
57void set_next_vsync_interval(std::chrono::milliseconds interval);
58
56mir::UniqueModulePtr<FakeInputDevice> add_fake_input_device(mir::input::InputDeviceInfo const& info);59mir::UniqueModulePtr<FakeInputDevice> add_fake_input_device(mir::input::InputDeviceInfo const& info);
57}60}
58#endif /* MIR_TEST_FRAMEWORK_STUB_SERVER_PLATFORM_FACTORY_ */61#endif /* MIR_TEST_FRAMEWORK_STUB_SERVER_PLATFORM_FACTORY_ */
5962
=== modified file 'tests/mir_test_framework/stub_server_platform_factory.cpp'
--- tests/mir_test_framework/stub_server_platform_factory.cpp 2015-04-09 06:20:31 +0000
+++ tests/mir_test_framework/stub_server_platform_factory.cpp 2015-04-17 13:13:57 +0000
@@ -87,3 +87,16 @@
8787
88 return add_device(info);88 return add_device(info);
89}89}
90
91void mtf::set_next_vsync_interval(
92 std::chrono::milliseconds interval)
93{
94 ensure_platform_library();
95
96 using func_sig = void(*)(std::chrono::milliseconds);
97
98 auto const set_next_vsync_interval =
99 platform_graphics_lib->load_function<func_sig>("set_next_vsync_interval");
100
101 return set_next_vsync_interval(interval);
102}
90103
=== modified file 'tests/mir_test_framework/stubbed_graphics_platform.cpp'
--- tests/mir_test_framework/stubbed_graphics_platform.cpp 2015-03-31 02:35:42 +0000
+++ tests/mir_test_framework/stubbed_graphics_platform.cpp 2015-04-17 13:13:57 +0000
@@ -228,6 +228,7 @@
228namespace228namespace
229{229{
230std::shared_ptr<mg::Display> display_preset;230std::shared_ptr<mg::Display> display_preset;
231std::chrono::milliseconds vsync_interval;
231}232}
232233
233std::shared_ptr<mg::Display> mtf::StubGraphicPlatform::create_display(234std::shared_ptr<mg::Display> mtf::StubGraphicPlatform::create_display(
@@ -238,7 +239,9 @@
238 if (display_preset)239 if (display_preset)
239 return std::move(display_preset);240 return std::move(display_preset);
240241
241 return std::make_shared<mtd::StubDisplay>(display_rects);242 auto const tmp_vsync = vsync_interval;
243 vsync_interval = std::chrono::milliseconds::zero();
244 return std::make_shared<mtd::StubDisplay>(display_rects, tmp_vsync);
242}245}
243246
244namespace247namespace
@@ -334,3 +337,8 @@
334{337{
335 display_preset = display;338 display_preset = display;
336}339}
340
341extern "C" void set_next_vsync_interval(std::chrono::milliseconds interval)
342{
343 vsync_interval = interval;
344}

Subscribers

People subscribed via source and target branches