Merge lp:~vanvugt/mir/timerless-multimonitor-frame-sync into lp:~mir-team/mir/trunk
- timerless-multimonitor-frame-sync
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~vanvugt/mir/timerless-multimonitor-frame-sync |
Merge into: | lp:~mir-team/mir/trunk |
Prerequisite: | lp:~vanvugt/mir/bypass |
Diff against target: |
1180 lines (+176/-173) 33 files modified
include/server/mir/compositor/buffer_stream_surfaces.h (+2/-1) include/server/mir/compositor/renderer.h (+1/-1) include/server/mir/surfaces/buffer_stream.h (+2/-1) include/test/mir_test_doubles/mock_buffer_bundle.h (+1/-1) include/test/mir_test_doubles/mock_buffer_stream.h (+2/-1) include/test/mir_test_doubles/mock_surface_renderer.h (+1/-1) include/test/mir_test_doubles/stub_buffer_stream.h (+1/-1) src/server/compositor/buffer_bundle.h (+2/-1) src/server/compositor/buffer_stream_surfaces.cpp (+4/-2) src/server/compositor/default_display_buffer_compositor.cpp (+28/-3) src/server/compositor/default_display_buffer_compositor.h (+2/-0) src/server/compositor/gl_renderer.cpp (+4/-2) src/server/compositor/gl_renderer.h (+3/-1) src/server/compositor/switching_bundle.cpp (+5/-7) src/server/compositor/switching_bundle.h (+3/-6) src/server/compositor/temporary_buffers.cpp (+2/-2) src/server/compositor/temporary_buffers.h (+1/-1) src/server/surfaces/surface.cpp (+1/-1) tests/acceptance-tests/test_server_shutdown.cpp (+1/-1) tests/integration-tests/compositor/test_buffer_stream.cpp (+15/-21) tests/integration-tests/compositor/test_swapping_swappers.cpp (+4/-2) tests/integration-tests/shell/test_session.cpp (+2/-2) tests/integration-tests/test_surface_first_frame_sync.cpp (+1/-1) tests/integration-tests/test_swapinterval.cpp (+1/-1) tests/mir_test_framework/testing_server_options.cpp (+2/-2) tests/unit-tests/compositor/test_buffer_stream.cpp (+4/-4) tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp (+8/-8) tests/unit-tests/compositor/test_gl_renderer.cpp (+1/-1) tests/unit-tests/compositor/test_rendering_operator.cpp (+1/-1) tests/unit-tests/compositor/test_switching_bundle.cpp (+65/-91) tests/unit-tests/compositor/test_temporary_buffers.cpp (+3/-3) tests/unit-tests/surfaces/test_surface.cpp (+1/-1) tests/unit-tests/surfaces/test_surface_stack.cpp (+2/-1) |
To merge this branch: | bzr merge lp:~vanvugt/mir/timerless-multimonitor-frame-sync |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alan Griffiths | Needs Fixing | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Review via email: mp+182085@code.launchpad.net |
This proposal has been superseded by a proposal from 2013-08-29.
Commit message
Dramatically improved multi-monitor frame synchronization, using a global
frame count equivalent to the highest refresh rate of all monitors. This is
much more reliable than the old logic which was based on timers.
This fixes LP: #1210478
Description of the change
This version depends on the bypass branch in order to minimize conflicts. But I can remove that dependency if required.
Also, this branch conflicts with lp:~vanvugt/mir/remove-unused-buffer-methods.
PS Jenkins bot (ps-jenkins) wrote : | # |
Chris Halse Rogers (raof) wrote : | # |
Mostly looks good to me, only nitpick:
160 + local_frame_count <= 0) // Wrap around, unlikely, but handle it...
I'm not a huge fan of testing unsigned values for <= 0. Maybe make it == 0?
Daniel van Vugt (vanvugt) wrote : | # |
I prefer to keep "<= 0". It's extra protection against regressions if anyone changes it to signed in future.
Daniel van Vugt (vanvugt) wrote : | # |
I have what looks like a test setup to reproduce LP: #1216472 now, and it looks like it is not fixed by this :(
Alan Griffiths (alan-griffiths) wrote : | # |
I like the approach, but some small concerns:
159 + if (global_
160 + local_frame_count <= 0) // Wrap around, unlikely, but handle it...
161 + {
162 + global_
163 + }
164 + else
165 + {
166 + local_frame_count = global_
167 + }
As there is no synchronization between the first load and the store I don't think the logic is mathematically correct. Could we improve on this by using compare_exchange? (Not that I think there's much chance of a problem in practice.)
~~~~
134 +std::atomic_ulong mc::DefaultDisp
There's no reason for this to be "published" in a header: it could be a namespace scope variable (in anonymous namespace) rather than a static class member.
~~~~
I don't have a better name but "frameno" doesn't really indicate what the parameter is for.
Daniel van Vugt (vanvugt) wrote : | # |
Alan, I was thinking the same. Just haven't got to it yet.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:950
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Daniel van Vugt (vanvugt) wrote : | # |
Alternatively, see:
https:/
which is not blocked by bypass.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:952
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Alan Griffiths (alan-griffiths) wrote : | # |
Review: Needs Fixing
162 + if (global_frame_count < local_frame_count || local_frame_count <= 0)
163 + global_frame_count = local_frame_count;
164 + else
165 + local_frame_count = global_frame_count;
166 + }
Start with:
thread 1: local_frame_count = MAX_UNIT
thread 2: local_frame_count = MAX_UNIT-1
thread 1 runs through this code leaving:
global_frame_count == (t1)local_
Then thread 2 runs through it leaving:
global_frame_count == (t2)local_
When the result needed by the algorithm is:
global_frame_count == (t2)local_
Things do sort themselves out and the error is mostly harmless (and only occurs occasionally) but it could be improved upon. Vis:
162 + if (global_frame_count < local_frame_count || local_frame_count <= 0)
if (global_frame_count - local_frame_count > UNIT_MAX/2)
Alan Griffiths (alan-griffiths) wrote : | # |
I'm still not entirely happy with the naming - frameno, global_frame_count and local_frame_count are not really what their names suggest. They are neither identifiers nor counts but actually sequence numbers.
Preview Diff
1 | === modified file 'include/server/mir/compositor/buffer_stream_surfaces.h' | |||
2 | --- include/server/mir/compositor/buffer_stream_surfaces.h 2013-08-09 01:37:53 +0000 | |||
3 | +++ include/server/mir/compositor/buffer_stream_surfaces.h 2013-08-29 09:10:29 +0000 | |||
4 | @@ -41,7 +41,8 @@ | |||
5 | 41 | 41 | ||
6 | 42 | std::shared_ptr<graphics::Buffer> secure_client_buffer(); | 42 | std::shared_ptr<graphics::Buffer> secure_client_buffer(); |
7 | 43 | 43 | ||
9 | 44 | std::shared_ptr<graphics::Buffer> lock_compositor_buffer() override; | 44 | std::shared_ptr<graphics::Buffer> |
10 | 45 | lock_compositor_buffer(unsigned long frameno) override; | ||
11 | 45 | std::shared_ptr<graphics::Buffer> lock_snapshot_buffer() override; | 46 | std::shared_ptr<graphics::Buffer> lock_snapshot_buffer() override; |
12 | 46 | 47 | ||
13 | 47 | geometry::PixelFormat get_stream_pixel_format(); | 48 | geometry::PixelFormat get_stream_pixel_format(); |
14 | 48 | 49 | ||
15 | === modified file 'include/server/mir/compositor/renderer.h' | |||
16 | --- include/server/mir/compositor/renderer.h 2013-08-09 01:37:53 +0000 | |||
17 | +++ include/server/mir/compositor/renderer.h 2013-08-29 09:10:29 +0000 | |||
18 | @@ -37,7 +37,7 @@ | |||
19 | 37 | public: | 37 | public: |
20 | 38 | virtual ~Renderer() = default; | 38 | virtual ~Renderer() = default; |
21 | 39 | 39 | ||
23 | 40 | virtual void clear() = 0; | 40 | virtual void clear(unsigned long frameno) = 0; |
24 | 41 | virtual void render(std::function<void(std::shared_ptr<void> const&)> save_resource, | 41 | virtual void render(std::function<void(std::shared_ptr<void> const&)> save_resource, |
25 | 42 | CompositingCriteria const& info, surfaces::BufferStream& stream) = 0; | 42 | CompositingCriteria const& info, surfaces::BufferStream& stream) = 0; |
26 | 43 | 43 | ||
27 | 44 | 44 | ||
28 | === modified file 'include/server/mir/surfaces/buffer_stream.h' | |||
29 | --- include/server/mir/surfaces/buffer_stream.h 2013-08-09 01:37:53 +0000 | |||
30 | +++ include/server/mir/surfaces/buffer_stream.h 2013-08-29 09:10:29 +0000 | |||
31 | @@ -42,7 +42,8 @@ | |||
32 | 42 | virtual ~BufferStream() {/* TODO: make nothrow */} | 42 | virtual ~BufferStream() {/* TODO: make nothrow */} |
33 | 43 | 43 | ||
34 | 44 | virtual std::shared_ptr<graphics::Buffer> secure_client_buffer() = 0; | 44 | virtual std::shared_ptr<graphics::Buffer> secure_client_buffer() = 0; |
36 | 45 | virtual std::shared_ptr<graphics::Buffer> lock_compositor_buffer() = 0; | 45 | virtual std::shared_ptr<graphics::Buffer> |
37 | 46 | lock_compositor_buffer(unsigned long frameno) = 0; | ||
38 | 46 | virtual std::shared_ptr<graphics::Buffer> lock_snapshot_buffer() = 0; | 47 | virtual std::shared_ptr<graphics::Buffer> lock_snapshot_buffer() = 0; |
39 | 47 | virtual geometry::PixelFormat get_stream_pixel_format() = 0; | 48 | virtual geometry::PixelFormat get_stream_pixel_format() = 0; |
40 | 48 | virtual geometry::Size stream_size() = 0; | 49 | virtual geometry::Size stream_size() = 0; |
41 | 49 | 50 | ||
42 | === modified file 'include/test/mir_test_doubles/mock_buffer_bundle.h' | |||
43 | --- include/test/mir_test_doubles/mock_buffer_bundle.h 2013-08-09 01:37:53 +0000 | |||
44 | +++ include/test/mir_test_doubles/mock_buffer_bundle.h 2013-08-29 09:10:29 +0000 | |||
45 | @@ -39,7 +39,7 @@ | |||
46 | 39 | 39 | ||
47 | 40 | MOCK_METHOD0(client_acquire, std::shared_ptr<graphics::Buffer>()); | 40 | MOCK_METHOD0(client_acquire, std::shared_ptr<graphics::Buffer>()); |
48 | 41 | MOCK_METHOD1(client_release, void(std::shared_ptr<graphics::Buffer> const&)); | 41 | MOCK_METHOD1(client_release, void(std::shared_ptr<graphics::Buffer> const&)); |
50 | 42 | MOCK_METHOD0(compositor_acquire, std::shared_ptr<graphics::Buffer>()); | 42 | MOCK_METHOD1(compositor_acquire, std::shared_ptr<graphics::Buffer>(unsigned long)); |
51 | 43 | MOCK_METHOD1(compositor_release, void(std::shared_ptr<graphics::Buffer> const&)); | 43 | MOCK_METHOD1(compositor_release, void(std::shared_ptr<graphics::Buffer> const&)); |
52 | 44 | MOCK_METHOD0(snapshot_acquire, std::shared_ptr<graphics::Buffer>()); | 44 | MOCK_METHOD0(snapshot_acquire, std::shared_ptr<graphics::Buffer>()); |
53 | 45 | MOCK_METHOD1(snapshot_release, void(std::shared_ptr<graphics::Buffer> const&)); | 45 | MOCK_METHOD1(snapshot_release, void(std::shared_ptr<graphics::Buffer> const&)); |
54 | 46 | 46 | ||
55 | === modified file 'include/test/mir_test_doubles/mock_buffer_stream.h' | |||
56 | --- include/test/mir_test_doubles/mock_buffer_stream.h 2013-08-09 01:37:53 +0000 | |||
57 | +++ include/test/mir_test_doubles/mock_buffer_stream.h 2013-08-29 09:10:29 +0000 | |||
58 | @@ -32,7 +32,8 @@ | |||
59 | 32 | struct MockBufferStream : public surfaces::BufferStream | 32 | struct MockBufferStream : public surfaces::BufferStream |
60 | 33 | { | 33 | { |
61 | 34 | MOCK_METHOD0(secure_client_buffer, std::shared_ptr<graphics::Buffer>()); | 34 | MOCK_METHOD0(secure_client_buffer, std::shared_ptr<graphics::Buffer>()); |
63 | 35 | MOCK_METHOD0(lock_compositor_buffer, std::shared_ptr<graphics::Buffer>()); | 35 | MOCK_METHOD1(lock_compositor_buffer, |
64 | 36 | std::shared_ptr<graphics::Buffer>(unsigned long)); | ||
65 | 36 | MOCK_METHOD0(lock_snapshot_buffer, std::shared_ptr<graphics::Buffer>()); | 37 | MOCK_METHOD0(lock_snapshot_buffer, std::shared_ptr<graphics::Buffer>()); |
66 | 37 | 38 | ||
67 | 38 | MOCK_METHOD0(get_stream_pixel_format, geometry::PixelFormat()); | 39 | MOCK_METHOD0(get_stream_pixel_format, geometry::PixelFormat()); |
68 | 39 | 40 | ||
69 | === modified file 'include/test/mir_test_doubles/mock_surface_renderer.h' | |||
70 | --- include/test/mir_test_doubles/mock_surface_renderer.h 2013-08-09 01:37:53 +0000 | |||
71 | +++ include/test/mir_test_doubles/mock_surface_renderer.h 2013-08-29 09:10:29 +0000 | |||
72 | @@ -33,7 +33,7 @@ | |||
73 | 33 | { | 33 | { |
74 | 34 | MOCK_METHOD3(render, void( | 34 | MOCK_METHOD3(render, void( |
75 | 35 | std::function<void(std::shared_ptr<void> const&)>, compositor::CompositingCriteria const&, surfaces::BufferStream&)); | 35 | std::function<void(std::shared_ptr<void> const&)>, compositor::CompositingCriteria const&, surfaces::BufferStream&)); |
77 | 36 | MOCK_METHOD0(clear, void()); | 36 | MOCK_METHOD1(clear, void(unsigned long)); |
78 | 37 | 37 | ||
79 | 38 | ~MockSurfaceRenderer() noexcept {} | 38 | ~MockSurfaceRenderer() noexcept {} |
80 | 39 | }; | 39 | }; |
81 | 40 | 40 | ||
82 | === modified file 'include/test/mir_test_doubles/stub_buffer_stream.h' | |||
83 | --- include/test/mir_test_doubles/stub_buffer_stream.h 2013-08-09 01:37:53 +0000 | |||
84 | +++ include/test/mir_test_doubles/stub_buffer_stream.h 2013-08-29 09:10:29 +0000 | |||
85 | @@ -42,7 +42,7 @@ | |||
86 | 42 | return stub_client_buffer; | 42 | return stub_client_buffer; |
87 | 43 | } | 43 | } |
88 | 44 | 44 | ||
90 | 45 | std::shared_ptr<graphics::Buffer> lock_compositor_buffer() | 45 | std::shared_ptr<graphics::Buffer> lock_compositor_buffer(unsigned long) |
91 | 46 | { | 46 | { |
92 | 47 | return stub_compositor_buffer; | 47 | return stub_compositor_buffer; |
93 | 48 | } | 48 | } |
94 | 49 | 49 | ||
95 | === modified file 'src/server/compositor/buffer_bundle.h' | |||
96 | --- src/server/compositor/buffer_bundle.h 2013-08-09 01:37:53 +0000 | |||
97 | +++ src/server/compositor/buffer_bundle.h 2013-08-29 09:10:29 +0000 | |||
98 | @@ -36,7 +36,8 @@ | |||
99 | 36 | virtual ~BufferBundle() noexcept {} | 36 | virtual ~BufferBundle() noexcept {} |
100 | 37 | virtual std::shared_ptr<graphics::Buffer> client_acquire() = 0; | 37 | virtual std::shared_ptr<graphics::Buffer> client_acquire() = 0; |
101 | 38 | virtual void client_release(std::shared_ptr<graphics::Buffer> const&) = 0; | 38 | virtual void client_release(std::shared_ptr<graphics::Buffer> const&) = 0; |
103 | 39 | virtual std::shared_ptr<graphics::Buffer> compositor_acquire() = 0; | 39 | virtual std::shared_ptr<graphics::Buffer> |
104 | 40 | compositor_acquire(unsigned long frameno) = 0; | ||
105 | 40 | virtual void compositor_release(std::shared_ptr<graphics::Buffer> const&) = 0; | 41 | virtual void compositor_release(std::shared_ptr<graphics::Buffer> const&) = 0; |
106 | 41 | virtual std::shared_ptr<graphics::Buffer> snapshot_acquire() = 0; | 42 | virtual std::shared_ptr<graphics::Buffer> snapshot_acquire() = 0; |
107 | 42 | virtual void snapshot_release(std::shared_ptr<graphics::Buffer> const&) = 0; | 43 | virtual void snapshot_release(std::shared_ptr<graphics::Buffer> const&) = 0; |
108 | 43 | 44 | ||
109 | === modified file 'src/server/compositor/buffer_stream_surfaces.cpp' | |||
110 | --- src/server/compositor/buffer_stream_surfaces.cpp 2013-08-09 01:37:53 +0000 | |||
111 | +++ src/server/compositor/buffer_stream_surfaces.cpp 2013-08-29 09:10:29 +0000 | |||
112 | @@ -37,9 +37,11 @@ | |||
113 | 37 | force_requests_to_complete(); | 37 | force_requests_to_complete(); |
114 | 38 | } | 38 | } |
115 | 39 | 39 | ||
117 | 40 | std::shared_ptr<mg::Buffer> mc::BufferStreamSurfaces::lock_compositor_buffer() | 40 | std::shared_ptr<mg::Buffer> mc::BufferStreamSurfaces::lock_compositor_buffer( |
118 | 41 | unsigned long frameno) | ||
119 | 41 | { | 42 | { |
121 | 42 | return std::make_shared<mc::TemporaryCompositorBuffer>(buffer_bundle); | 43 | return std::make_shared<mc::TemporaryCompositorBuffer>( |
122 | 44 | buffer_bundle, frameno); | ||
123 | 43 | } | 45 | } |
124 | 44 | 46 | ||
125 | 45 | std::shared_ptr<mg::Buffer> mc::BufferStreamSurfaces::lock_snapshot_buffer() | 47 | std::shared_ptr<mg::Buffer> mc::BufferStreamSurfaces::lock_snapshot_buffer() |
126 | 46 | 48 | ||
127 | === modified file 'src/server/compositor/default_display_buffer_compositor.cpp' | |||
128 | --- src/server/compositor/default_display_buffer_compositor.cpp 2013-08-26 03:21:56 +0000 | |||
129 | +++ src/server/compositor/default_display_buffer_compositor.cpp 2013-08-29 09:10:29 +0000 | |||
130 | @@ -49,6 +49,14 @@ | |||
131 | 49 | mir::geometry::Rectangle const& enclosing_region; | 49 | mir::geometry::Rectangle const& enclosing_region; |
132 | 50 | }; | 50 | }; |
133 | 51 | 51 | ||
134 | 52 | std::mutex global_frameno_lock; | ||
135 | 53 | unsigned long global_frameno = 0; | ||
136 | 54 | |||
137 | 55 | bool wrapped_greater_or_equal(unsigned long a, unsigned long b) | ||
138 | 56 | { | ||
139 | 57 | return (a - b) < (~0UL / 2UL); | ||
140 | 58 | } | ||
141 | 59 | |||
142 | 52 | } | 60 | } |
143 | 53 | 61 | ||
144 | 54 | mc::DefaultDisplayBufferCompositor::DefaultDisplayBufferCompositor( | 62 | mc::DefaultDisplayBufferCompositor::DefaultDisplayBufferCompositor( |
145 | @@ -59,16 +67,32 @@ | |||
146 | 59 | : mc::BasicDisplayBufferCompositor{display_buffer}, | 67 | : mc::BasicDisplayBufferCompositor{display_buffer}, |
147 | 60 | scene{scene}, | 68 | scene{scene}, |
148 | 61 | renderer{renderer}, | 69 | renderer{renderer}, |
150 | 62 | overlay_renderer{overlay_renderer} | 70 | overlay_renderer{overlay_renderer}, |
151 | 71 | local_frameno{global_frameno} | ||
152 | 63 | { | 72 | { |
153 | 64 | } | 73 | } |
154 | 65 | 74 | ||
155 | 75 | |||
156 | 66 | void mc::DefaultDisplayBufferCompositor::composite() | 76 | void mc::DefaultDisplayBufferCompositor::composite() |
157 | 67 | { | 77 | { |
158 | 68 | static bool got_bypass_env = false; | 78 | static bool got_bypass_env = false; |
159 | 69 | static bool bypass_env = true; | 79 | static bool bypass_env = true; |
160 | 70 | bool bypassed = false; | 80 | bool bypassed = false; |
161 | 71 | 81 | ||
162 | 82 | /* | ||
163 | 83 | * Increment frame counts for each tick of the fastest instance of | ||
164 | 84 | * DefaultDisplayBufferCompositor. This means for the fastest refresh | ||
165 | 85 | * rate of all attached outputs. | ||
166 | 86 | */ | ||
167 | 87 | local_frameno++; | ||
168 | 88 | { | ||
169 | 89 | std::lock_guard<std::mutex> lock(global_frameno_lock); | ||
170 | 90 | if (wrapped_greater_or_equal(local_frameno, global_frameno)) | ||
171 | 91 | global_frameno = local_frameno; | ||
172 | 92 | else | ||
173 | 93 | local_frameno = global_frameno; | ||
174 | 94 | } | ||
175 | 95 | |||
176 | 72 | if (!got_bypass_env) | 96 | if (!got_bypass_env) |
177 | 73 | { | 97 | { |
178 | 74 | const char *env = getenv("MIR_BYPASS"); | 98 | const char *env = getenv("MIR_BYPASS"); |
179 | @@ -91,7 +115,8 @@ | |||
180 | 91 | if (filter.fullscreen_on_top()) | 115 | if (filter.fullscreen_on_top()) |
181 | 92 | { | 116 | { |
182 | 93 | auto bypass_buf = | 117 | auto bypass_buf = |
184 | 94 | match.topmost_fullscreen()->lock_compositor_buffer(); | 118 | match.topmost_fullscreen()->lock_compositor_buffer( |
185 | 119 | local_frameno); | ||
186 | 95 | 120 | ||
187 | 96 | if (bypass_buf->can_bypass()) | 121 | if (bypass_buf->can_bypass()) |
188 | 97 | { | 122 | { |
189 | @@ -110,7 +135,7 @@ | |||
190 | 110 | mir::geometry::Rectangle const& view_area, | 135 | mir::geometry::Rectangle const& view_area, |
191 | 111 | std::function<void(std::shared_ptr<void> const&)> save_resource) | 136 | std::function<void(std::shared_ptr<void> const&)> save_resource) |
192 | 112 | { | 137 | { |
194 | 113 | renderer->clear(); | 138 | renderer->clear(local_frameno); |
195 | 114 | 139 | ||
196 | 115 | mc::RenderingOperator applicator(*renderer, save_resource); | 140 | mc::RenderingOperator applicator(*renderer, save_resource); |
197 | 116 | FilterForVisibleSceneInRegion selector(view_area); | 141 | FilterForVisibleSceneInRegion selector(view_area); |
198 | 117 | 142 | ||
199 | === modified file 'src/server/compositor/default_display_buffer_compositor.h' | |||
200 | --- src/server/compositor/default_display_buffer_compositor.h 2013-07-25 04:18:04 +0000 | |||
201 | +++ src/server/compositor/default_display_buffer_compositor.h 2013-08-29 09:10:29 +0000 | |||
202 | @@ -53,6 +53,8 @@ | |||
203 | 53 | std::shared_ptr<Scene> const scene; | 53 | std::shared_ptr<Scene> const scene; |
204 | 54 | std::shared_ptr<Renderer> const renderer; | 54 | std::shared_ptr<Renderer> const renderer; |
205 | 55 | std::shared_ptr<OverlayRenderer> const overlay_renderer; | 55 | std::shared_ptr<OverlayRenderer> const overlay_renderer; |
206 | 56 | |||
207 | 57 | unsigned long local_frameno; | ||
208 | 56 | }; | 58 | }; |
209 | 57 | 59 | ||
210 | 58 | } | 60 | } |
211 | 59 | 61 | ||
212 | === modified file 'src/server/compositor/gl_renderer.cpp' | |||
213 | --- src/server/compositor/gl_renderer.cpp 2013-08-23 01:44:53 +0000 | |||
214 | +++ src/server/compositor/gl_renderer.cpp 2013-08-29 09:10:29 +0000 | |||
215 | @@ -235,6 +235,7 @@ | |||
216 | 235 | } | 235 | } |
217 | 236 | 236 | ||
218 | 237 | mc::GLRenderer::GLRenderer(geom::Rectangle const& display_area) | 237 | mc::GLRenderer::GLRenderer(geom::Rectangle const& display_area) |
219 | 238 | : frameno{0} | ||
220 | 238 | { | 239 | { |
221 | 239 | resources.setup(display_area); | 240 | resources.setup(display_area); |
222 | 240 | } | 241 | } |
223 | @@ -265,7 +266,7 @@ | |||
224 | 265 | /* Use the renderable's texture */ | 266 | /* Use the renderable's texture */ |
225 | 266 | glBindTexture(GL_TEXTURE_2D, resources.texture); | 267 | glBindTexture(GL_TEXTURE_2D, resources.texture); |
226 | 267 | 268 | ||
228 | 268 | auto region_resource = stream.lock_compositor_buffer(); | 269 | auto region_resource = stream.lock_compositor_buffer(frameno); |
229 | 269 | region_resource->bind_to_texture(); | 270 | region_resource->bind_to_texture(); |
230 | 270 | save_resource(region_resource); | 271 | save_resource(region_resource); |
231 | 271 | 272 | ||
232 | @@ -277,8 +278,9 @@ | |||
233 | 277 | glDisableVertexAttribArray(resources.position_attr_loc); | 278 | glDisableVertexAttribArray(resources.position_attr_loc); |
234 | 278 | } | 279 | } |
235 | 279 | 280 | ||
237 | 280 | void mc::GLRenderer::clear() | 281 | void mc::GLRenderer::clear(unsigned long frame) |
238 | 281 | { | 282 | { |
239 | 283 | frameno = frame; | ||
240 | 282 | glClear(GL_COLOR_BUFFER_BIT); | 284 | glClear(GL_COLOR_BUFFER_BIT); |
241 | 283 | } | 285 | } |
242 | 284 | 286 | ||
243 | 285 | 287 | ||
244 | === modified file 'src/server/compositor/gl_renderer.h' | |||
245 | --- src/server/compositor/gl_renderer.h 2013-08-09 01:37:53 +0000 | |||
246 | +++ src/server/compositor/gl_renderer.h 2013-08-29 09:10:29 +0000 | |||
247 | @@ -36,7 +36,7 @@ | |||
248 | 36 | /* From renderer */ | 36 | /* From renderer */ |
249 | 37 | void render(std::function<void(std::shared_ptr<void> const&)> save_resource, | 37 | void render(std::function<void(std::shared_ptr<void> const&)> save_resource, |
250 | 38 | CompositingCriteria const& info, surfaces::BufferStream& stream); | 38 | CompositingCriteria const& info, surfaces::BufferStream& stream); |
252 | 39 | void clear(); | 39 | void clear(unsigned long frameno) override; |
253 | 40 | 40 | ||
254 | 41 | ~GLRenderer() noexcept {} | 41 | ~GLRenderer() noexcept {} |
255 | 42 | 42 | ||
256 | @@ -60,6 +60,8 @@ | |||
257 | 60 | }; | 60 | }; |
258 | 61 | 61 | ||
259 | 62 | Resources resources; | 62 | Resources resources; |
260 | 63 | |||
261 | 64 | unsigned long frameno; | ||
262 | 63 | }; | 65 | }; |
263 | 64 | 66 | ||
264 | 65 | } | 67 | } |
265 | 66 | 68 | ||
266 | === modified file 'src/server/compositor/switching_bundle.cpp' | |||
267 | --- src/server/compositor/switching_bundle.cpp 2013-08-09 01:37:53 +0000 | |||
268 | +++ src/server/compositor/switching_bundle.cpp 2013-08-29 09:10:29 +0000 | |||
269 | @@ -76,6 +76,7 @@ | |||
270 | 76 | first_ready{0}, nready{0}, | 76 | first_ready{0}, nready{0}, |
271 | 77 | first_client{0}, nclients{0}, | 77 | first_client{0}, nclients{0}, |
272 | 78 | snapshot{-1}, nsnapshotters{0}, | 78 | snapshot{-1}, nsnapshotters{0}, |
273 | 79 | last_consumed{0}, | ||
274 | 79 | overlapping_compositors{false}, | 80 | overlapping_compositors{false}, |
275 | 80 | framedropping{false}, force_drop{0} | 81 | framedropping{false}, force_drop{0} |
276 | 81 | { | 82 | { |
277 | @@ -85,8 +86,6 @@ | |||
278 | 85 | "nbuffers betwee 1 and " + | 86 | "nbuffers betwee 1 and " + |
279 | 86 | std::to_string(MAX_NBUFFERS))); | 87 | std::to_string(MAX_NBUFFERS))); |
280 | 87 | } | 88 | } |
281 | 88 | |||
282 | 89 | last_consumed = now() - std::chrono::seconds(1); | ||
283 | 90 | } | 89 | } |
284 | 91 | 90 | ||
285 | 92 | int mc::SwitchingBundle::nfree() const | 91 | int mc::SwitchingBundle::nfree() const |
286 | @@ -259,15 +258,14 @@ | |||
287 | 259 | cond.notify_all(); | 258 | cond.notify_all(); |
288 | 260 | } | 259 | } |
289 | 261 | 260 | ||
291 | 262 | std::shared_ptr<mg::Buffer> mc::SwitchingBundle::compositor_acquire() | 261 | std::shared_ptr<mg::Buffer> mc::SwitchingBundle::compositor_acquire( |
292 | 262 | unsigned long frameno) | ||
293 | 263 | { | 263 | { |
294 | 264 | std::unique_lock<std::mutex> lock(guard); | 264 | std::unique_lock<std::mutex> lock(guard); |
295 | 265 | int compositor; | 265 | int compositor; |
296 | 266 | 266 | ||
297 | 267 | auto t = now(); | ||
298 | 268 | |||
299 | 269 | // Multi-monitor acquires close to each other get the same frame: | 267 | // Multi-monitor acquires close to each other get the same frame: |
301 | 270 | bool same_frame = (t - last_consumed) < std::chrono::milliseconds(10); | 268 | bool same_frame = (frameno == last_consumed); |
302 | 271 | 269 | ||
303 | 272 | int avail = nfree(); | 270 | int avail = nfree(); |
304 | 273 | bool can_recycle = ncompositors || avail; | 271 | bool can_recycle = ncompositors || avail; |
305 | @@ -296,7 +294,7 @@ | |||
306 | 296 | first_ready = next(first_ready); | 294 | first_ready = next(first_ready); |
307 | 297 | nready--; | 295 | nready--; |
308 | 298 | ncompositors++; | 296 | ncompositors++; |
310 | 299 | last_consumed = t; | 297 | last_consumed = frameno; |
311 | 300 | } | 298 | } |
312 | 301 | 299 | ||
313 | 302 | overlapping_compositors = (ncompositors > 1); | 300 | overlapping_compositors = (ncompositors > 1); |
314 | 303 | 301 | ||
315 | === modified file 'src/server/compositor/switching_bundle.h' | |||
316 | --- src/server/compositor/switching_bundle.h 2013-08-09 01:37:53 +0000 | |||
317 | +++ src/server/compositor/switching_bundle.h 2013-08-29 09:10:29 +0000 | |||
318 | @@ -24,7 +24,6 @@ | |||
319 | 24 | #include <condition_variable> | 24 | #include <condition_variable> |
320 | 25 | #include <mutex> | 25 | #include <mutex> |
321 | 26 | #include <memory> | 26 | #include <memory> |
322 | 27 | #include <chrono> | ||
323 | 28 | 27 | ||
324 | 29 | namespace mir | 28 | namespace mir |
325 | 30 | { | 29 | { |
326 | @@ -47,7 +46,8 @@ | |||
327 | 47 | 46 | ||
328 | 48 | std::shared_ptr<graphics::Buffer> client_acquire(); | 47 | std::shared_ptr<graphics::Buffer> client_acquire(); |
329 | 49 | void client_release(std::shared_ptr<graphics::Buffer> const&); | 48 | void client_release(std::shared_ptr<graphics::Buffer> const&); |
331 | 50 | std::shared_ptr<graphics::Buffer> compositor_acquire(); | 49 | std::shared_ptr<graphics::Buffer> |
332 | 50 | compositor_acquire(unsigned long frameno) override; | ||
333 | 51 | void compositor_release(std::shared_ptr<graphics::Buffer> const& released_buffer); | 51 | void compositor_release(std::shared_ptr<graphics::Buffer> const& released_buffer); |
334 | 52 | std::shared_ptr<graphics::Buffer> snapshot_acquire(); | 52 | std::shared_ptr<graphics::Buffer> snapshot_acquire(); |
335 | 53 | void snapshot_release(std::shared_ptr<graphics::Buffer> const& released_buffer); | 53 | void snapshot_release(std::shared_ptr<graphics::Buffer> const& released_buffer); |
336 | @@ -89,10 +89,7 @@ | |||
337 | 89 | std::mutex guard; | 89 | std::mutex guard; |
338 | 90 | std::condition_variable cond; | 90 | std::condition_variable cond; |
339 | 91 | 91 | ||
344 | 92 | typedef std::chrono::high_resolution_clock::time_point time_point; | 92 | unsigned long last_consumed; |
341 | 93 | static time_point now() | ||
342 | 94 | { return std::chrono::high_resolution_clock::now(); } | ||
343 | 95 | time_point last_consumed; | ||
345 | 96 | 93 | ||
346 | 97 | bool overlapping_compositors; | 94 | bool overlapping_compositors; |
347 | 98 | 95 | ||
348 | 99 | 96 | ||
349 | === modified file 'src/server/compositor/temporary_buffers.cpp' | |||
350 | --- src/server/compositor/temporary_buffers.cpp 2013-08-13 07:56:50 +0000 | |||
351 | +++ src/server/compositor/temporary_buffers.cpp 2013-08-29 09:10:29 +0000 | |||
352 | @@ -41,8 +41,8 @@ | |||
353 | 41 | } | 41 | } |
354 | 42 | 42 | ||
355 | 43 | mc::TemporaryCompositorBuffer::TemporaryCompositorBuffer( | 43 | mc::TemporaryCompositorBuffer::TemporaryCompositorBuffer( |
358 | 44 | std::shared_ptr<BufferBundle> const& bun) | 44 | std::shared_ptr<BufferBundle> const& bun, unsigned long frameno) |
359 | 45 | : TemporaryBuffer(bun->compositor_acquire()), | 45 | : TemporaryBuffer(bun->compositor_acquire(frameno)), |
360 | 46 | bundle(bun) | 46 | bundle(bun) |
361 | 47 | { | 47 | { |
362 | 48 | } | 48 | } |
363 | 49 | 49 | ||
364 | === modified file 'src/server/compositor/temporary_buffers.h' | |||
365 | --- src/server/compositor/temporary_buffers.h 2013-08-13 07:56:50 +0000 | |||
366 | +++ src/server/compositor/temporary_buffers.h 2013-08-29 09:10:29 +0000 | |||
367 | @@ -62,7 +62,7 @@ | |||
368 | 62 | { | 62 | { |
369 | 63 | public: | 63 | public: |
370 | 64 | explicit TemporaryCompositorBuffer( | 64 | explicit TemporaryCompositorBuffer( |
372 | 65 | std::shared_ptr<BufferBundle> const& bun); | 65 | std::shared_ptr<BufferBundle> const& bun, unsigned long frameno); |
373 | 66 | ~TemporaryCompositorBuffer(); | 66 | ~TemporaryCompositorBuffer(); |
374 | 67 | 67 | ||
375 | 68 | private: | 68 | private: |
376 | 69 | 69 | ||
377 | === modified file 'src/server/surfaces/surface.cpp' | |||
378 | --- src/server/surfaces/surface.cpp 2013-08-09 01:37:53 +0000 | |||
379 | +++ src/server/surfaces/surface.cpp 2013-08-29 09:10:29 +0000 | |||
380 | @@ -125,7 +125,7 @@ | |||
381 | 125 | 125 | ||
382 | 126 | std::shared_ptr<mg::Buffer> ms::Surface::compositor_buffer() const | 126 | std::shared_ptr<mg::Buffer> ms::Surface::compositor_buffer() const |
383 | 127 | { | 127 | { |
385 | 128 | return surface_buffer_stream->lock_compositor_buffer(); | 128 | return surface_buffer_stream->lock_compositor_buffer(0); |
386 | 129 | } | 129 | } |
387 | 130 | 130 | ||
388 | 131 | std::shared_ptr<mg::Buffer> ms::Surface::snapshot_buffer() const | 131 | std::shared_ptr<mg::Buffer> ms::Surface::snapshot_buffer() const |
389 | 132 | 132 | ||
390 | === modified file 'tests/acceptance-tests/test_server_shutdown.cpp' | |||
391 | --- tests/acceptance-tests/test_server_shutdown.cpp 2013-08-26 03:00:33 +0000 | |||
392 | +++ tests/acceptance-tests/test_server_shutdown.cpp 2013-08-29 09:10:29 +0000 | |||
393 | @@ -58,7 +58,7 @@ | |||
394 | 58 | std::this_thread::yield(); | 58 | std::this_thread::yield(); |
395 | 59 | } | 59 | } |
396 | 60 | 60 | ||
398 | 61 | void clear() {} | 61 | void clear(unsigned long) override {} |
399 | 62 | }; | 62 | }; |
400 | 63 | 63 | ||
401 | 64 | 64 | ||
402 | 65 | 65 | ||
403 | === modified file 'tests/integration-tests/compositor/test_buffer_stream.cpp' | |||
404 | --- tests/integration-tests/compositor/test_buffer_stream.cpp 2013-08-09 01:37:53 +0000 | |||
405 | +++ tests/integration-tests/compositor/test_buffer_stream.cpp 2013-08-29 09:10:29 +0000 | |||
406 | @@ -64,11 +64,6 @@ | |||
407 | 64 | mc::BufferStreamSurfaces buffer_stream; | 64 | mc::BufferStreamSurfaces buffer_stream; |
408 | 65 | }; | 65 | }; |
409 | 66 | 66 | ||
410 | 67 | void sleep_one_frame() | ||
411 | 68 | { | ||
412 | 69 | std::this_thread::sleep_for(std::chrono::milliseconds(16)); | ||
413 | 70 | } | ||
414 | 71 | |||
415 | 72 | } | 67 | } |
416 | 73 | 68 | ||
417 | 74 | TEST_F(BufferStreamTest, gives_same_back_buffer_until_more_available) | 69 | TEST_F(BufferStreamTest, gives_same_back_buffer_until_more_available) |
418 | @@ -77,8 +72,8 @@ | |||
419 | 77 | auto client1_id = client1->id(); | 72 | auto client1_id = client1->id(); |
420 | 78 | client1.reset(); | 73 | client1.reset(); |
421 | 79 | 74 | ||
424 | 80 | auto comp1 = buffer_stream.lock_compositor_buffer(); | 75 | auto comp1 = buffer_stream.lock_compositor_buffer(1); |
425 | 81 | auto comp2 = buffer_stream.lock_compositor_buffer(); | 76 | auto comp2 = buffer_stream.lock_compositor_buffer(1); |
426 | 82 | 77 | ||
427 | 83 | EXPECT_EQ(comp1->id(), comp2->id()); | 78 | EXPECT_EQ(comp1->id(), comp2->id()); |
428 | 84 | EXPECT_EQ(comp1->id(), client1_id); | 79 | EXPECT_EQ(comp1->id(), client1_id); |
429 | @@ -86,8 +81,7 @@ | |||
430 | 86 | comp1.reset(); | 81 | comp1.reset(); |
431 | 87 | 82 | ||
432 | 88 | buffer_stream.secure_client_buffer().reset(); | 83 | buffer_stream.secure_client_buffer().reset(); |
435 | 89 | sleep_one_frame(); | 84 | auto comp3 = buffer_stream.lock_compositor_buffer(2); |
434 | 90 | auto comp3 = buffer_stream.lock_compositor_buffer(); | ||
436 | 91 | 85 | ||
437 | 92 | EXPECT_NE(client1_id, comp3->id()); | 86 | EXPECT_NE(client1_id, comp3->id()); |
438 | 93 | 87 | ||
439 | @@ -95,7 +89,7 @@ | |||
440 | 95 | auto comp3_id = comp3->id(); | 89 | auto comp3_id = comp3->id(); |
441 | 96 | comp3.reset(); | 90 | comp3.reset(); |
442 | 97 | 91 | ||
444 | 98 | auto comp4 = buffer_stream.lock_compositor_buffer(); | 92 | auto comp4 = buffer_stream.lock_compositor_buffer(2); |
445 | 99 | EXPECT_EQ(comp3_id, comp4->id()); | 93 | EXPECT_EQ(comp3_id, comp4->id()); |
446 | 100 | } | 94 | } |
447 | 101 | 95 | ||
448 | @@ -104,13 +98,13 @@ | |||
449 | 104 | for (int i = 0; i < nbuffers - 1; i++) | 98 | for (int i = 0; i < nbuffers - 1; i++) |
450 | 105 | buffer_stream.secure_client_buffer().reset(); | 99 | buffer_stream.secure_client_buffer().reset(); |
451 | 106 | 100 | ||
453 | 107 | auto first_monitor = buffer_stream.lock_compositor_buffer(); | 101 | auto first_monitor = buffer_stream.lock_compositor_buffer(1); |
454 | 108 | auto first_compositor_id = first_monitor->id(); | 102 | auto first_compositor_id = first_monitor->id(); |
455 | 109 | first_monitor.reset(); | 103 | first_monitor.reset(); |
456 | 110 | 104 | ||
457 | 111 | for (int m = 0; m < 10; m++) | 105 | for (int m = 0; m < 10; m++) |
458 | 112 | { | 106 | { |
460 | 113 | auto monitor = buffer_stream.lock_compositor_buffer(); | 107 | auto monitor = buffer_stream.lock_compositor_buffer(1); |
461 | 114 | ASSERT_EQ(first_compositor_id, monitor->id()); | 108 | ASSERT_EQ(first_compositor_id, monitor->id()); |
462 | 115 | } | 109 | } |
463 | 116 | } | 110 | } |
464 | @@ -120,12 +114,10 @@ | |||
465 | 120 | if (nbuffers > 1) | 114 | if (nbuffers > 1) |
466 | 121 | { | 115 | { |
467 | 122 | buffer_stream.secure_client_buffer().reset(); | 116 | buffer_stream.secure_client_buffer().reset(); |
471 | 123 | auto comp1 = buffer_stream.lock_compositor_buffer(); | 117 | auto comp1 = buffer_stream.lock_compositor_buffer(1); |
469 | 124 | |||
470 | 125 | sleep_one_frame(); | ||
472 | 126 | 118 | ||
473 | 127 | buffer_stream.secure_client_buffer().reset(); | 119 | buffer_stream.secure_client_buffer().reset(); |
475 | 128 | auto comp2 = buffer_stream.lock_compositor_buffer(); | 120 | auto comp2 = buffer_stream.lock_compositor_buffer(2); |
476 | 129 | 121 | ||
477 | 130 | EXPECT_NE(comp1->id(), comp2->id()); | 122 | EXPECT_NE(comp1->id(), comp2->id()); |
478 | 131 | 123 | ||
479 | @@ -139,14 +131,14 @@ | |||
480 | 139 | buffer_stream.secure_client_buffer().reset(); | 131 | buffer_stream.secure_client_buffer().reset(); |
481 | 140 | auto client1 = buffer_stream.secure_client_buffer(); | 132 | auto client1 = buffer_stream.secure_client_buffer(); |
482 | 141 | 133 | ||
485 | 142 | auto comp1 = buffer_stream.lock_compositor_buffer(); | 134 | auto comp1 = buffer_stream.lock_compositor_buffer(123); |
486 | 143 | auto comp2 = buffer_stream.lock_compositor_buffer(); | 135 | auto comp2 = buffer_stream.lock_compositor_buffer(123); |
487 | 144 | 136 | ||
488 | 145 | EXPECT_EQ(comp1->id(), comp2->id()); | 137 | EXPECT_EQ(comp1->id(), comp2->id()); |
489 | 146 | 138 | ||
490 | 147 | comp1.reset(); | 139 | comp1.reset(); |
491 | 148 | 140 | ||
493 | 149 | auto comp3 = buffer_stream.lock_compositor_buffer(); | 141 | auto comp3 = buffer_stream.lock_compositor_buffer(123); |
494 | 150 | 142 | ||
495 | 151 | EXPECT_EQ(comp2->id(), comp3->id()); | 143 | EXPECT_EQ(comp2->id(), comp3->id()); |
496 | 152 | } | 144 | } |
497 | @@ -167,13 +159,15 @@ | |||
498 | 167 | void compositor_loop(ms::BufferStream &stream, | 159 | void compositor_loop(ms::BufferStream &stream, |
499 | 168 | std::atomic<bool> &done) | 160 | std::atomic<bool> &done) |
500 | 169 | { | 161 | { |
501 | 162 | unsigned long count = 0; | ||
502 | 163 | |||
503 | 170 | while (!done.load()) | 164 | while (!done.load()) |
504 | 171 | { | 165 | { |
506 | 172 | auto comp1 = stream.lock_compositor_buffer(); | 166 | auto comp1 = stream.lock_compositor_buffer(++count); |
507 | 173 | ASSERT_NE(nullptr, comp1); | 167 | ASSERT_NE(nullptr, comp1); |
508 | 174 | 168 | ||
509 | 175 | // Also stress test getting a second compositor buffer before yielding | 169 | // Also stress test getting a second compositor buffer before yielding |
511 | 176 | auto comp2 = stream.lock_compositor_buffer(); | 170 | auto comp2 = stream.lock_compositor_buffer(count); |
512 | 177 | ASSERT_NE(nullptr, comp2); | 171 | ASSERT_NE(nullptr, comp2); |
513 | 178 | 172 | ||
514 | 179 | std::this_thread::yield(); | 173 | std::this_thread::yield(); |
515 | 180 | 174 | ||
516 | === modified file 'tests/integration-tests/compositor/test_swapping_swappers.cpp' | |||
517 | --- tests/integration-tests/compositor/test_swapping_swappers.cpp 2013-08-09 01:37:53 +0000 | |||
518 | +++ tests/integration-tests/compositor/test_swapping_swappers.cpp 2013-08-29 09:10:29 +0000 | |||
519 | @@ -72,9 +72,10 @@ | |||
520 | 72 | auto g = std::async(std::launch::async, | 72 | auto g = std::async(std::launch::async, |
521 | 73 | [this] | 73 | [this] |
522 | 74 | { | 74 | { |
523 | 75 | unsigned long count = 0; | ||
524 | 75 | while(!client_thread_done) | 76 | while(!client_thread_done) |
525 | 76 | { | 77 | { |
527 | 77 | auto b = switching_bundle->compositor_acquire(); | 78 | auto b = switching_bundle->compositor_acquire(++count); |
528 | 78 | std::this_thread::yield(); | 79 | std::this_thread::yield(); |
529 | 79 | switching_bundle->compositor_release(b); | 80 | switching_bundle->compositor_release(b); |
530 | 80 | } | 81 | } |
531 | @@ -116,9 +117,10 @@ | |||
532 | 116 | auto g = std::async(std::launch::async, | 117 | auto g = std::async(std::launch::async, |
533 | 117 | [this] | 118 | [this] |
534 | 118 | { | 119 | { |
535 | 120 | unsigned long count = 0; | ||
536 | 119 | while(!client_thread_done) | 121 | while(!client_thread_done) |
537 | 120 | { | 122 | { |
539 | 121 | auto b = switching_bundle->compositor_acquire(); | 123 | auto b = switching_bundle->compositor_acquire(++count); |
540 | 122 | std::this_thread::yield(); | 124 | std::this_thread::yield(); |
541 | 123 | switching_bundle->compositor_release(b); | 125 | switching_bundle->compositor_release(b); |
542 | 124 | } | 126 | } |
543 | 125 | 127 | ||
544 | === modified file 'tests/integration-tests/shell/test_session.cpp' | |||
545 | --- tests/integration-tests/shell/test_session.cpp 2013-08-12 01:44:15 +0000 | |||
546 | +++ tests/integration-tests/shell/test_session.cpp 2013-08-29 09:10:29 +0000 | |||
547 | @@ -95,11 +95,11 @@ | |||
548 | 95 | { | 95 | { |
549 | 96 | struct StubRenderer : public mc::Renderer | 96 | struct StubRenderer : public mc::Renderer |
550 | 97 | { | 97 | { |
552 | 98 | void clear() {} | 98 | void clear(unsigned long) override {} |
553 | 99 | void render(std::function<void(std::shared_ptr<void> const&)>, | 99 | void render(std::function<void(std::shared_ptr<void> const&)>, |
554 | 100 | mc::CompositingCriteria const&, mir::surfaces::BufferStream& stream) | 100 | mc::CompositingCriteria const&, mir::surfaces::BufferStream& stream) |
555 | 101 | { | 101 | { |
557 | 102 | stream.lock_compositor_buffer(); | 102 | stream.lock_compositor_buffer(0); |
558 | 103 | } | 103 | } |
559 | 104 | 104 | ||
560 | 105 | void ensure_no_live_buffers_bound() {} | 105 | void ensure_no_live_buffers_bound() {} |
561 | 106 | 106 | ||
562 | === modified file 'tests/integration-tests/test_surface_first_frame_sync.cpp' | |||
563 | --- tests/integration-tests/test_surface_first_frame_sync.cpp 2013-08-26 03:00:33 +0000 | |||
564 | +++ tests/integration-tests/test_surface_first_frame_sync.cpp 2013-08-29 09:10:29 +0000 | |||
565 | @@ -96,7 +96,7 @@ | |||
566 | 96 | { | 96 | { |
567 | 97 | } | 97 | } |
568 | 98 | 98 | ||
570 | 99 | void clear() {} | 99 | void clear(unsigned long) override {} |
571 | 100 | 100 | ||
572 | 101 | void render(std::function<void(std::shared_ptr<void> const&)>, mc::CompositingCriteria const&, ms::BufferStream&) | 101 | void render(std::function<void(std::shared_ptr<void> const&)>, mc::CompositingCriteria const&, ms::BufferStream&) |
573 | 102 | { | 102 | { |
574 | 103 | 103 | ||
575 | === modified file 'tests/integration-tests/test_swapinterval.cpp' | |||
576 | --- tests/integration-tests/test_swapinterval.cpp 2013-08-26 03:00:33 +0000 | |||
577 | +++ tests/integration-tests/test_swapinterval.cpp 2013-08-29 09:10:29 +0000 | |||
578 | @@ -57,7 +57,7 @@ | |||
579 | 57 | } | 57 | } |
580 | 58 | 58 | ||
581 | 59 | std::shared_ptr<mg::Buffer> secure_client_buffer() { return std::make_shared<mtd::StubBuffer>(); } | 59 | std::shared_ptr<mg::Buffer> secure_client_buffer() { return std::make_shared<mtd::StubBuffer>(); } |
583 | 60 | std::shared_ptr<mg::Buffer> lock_compositor_buffer() { return std::make_shared<mtd::StubBuffer>(); } | 60 | std::shared_ptr<mg::Buffer> lock_compositor_buffer(unsigned long) { return std::make_shared<mtd::StubBuffer>(); } |
584 | 61 | std::shared_ptr<mg::Buffer> lock_snapshot_buffer() { return std::make_shared<mtd::StubBuffer>(); } | 61 | std::shared_ptr<mg::Buffer> lock_snapshot_buffer() { return std::make_shared<mtd::StubBuffer>(); } |
585 | 62 | geom::PixelFormat get_stream_pixel_format() { return geom::PixelFormat::abgr_8888; } | 62 | geom::PixelFormat get_stream_pixel_format() { return geom::PixelFormat::abgr_8888; } |
586 | 63 | geom::Size stream_size() { return geom::Size{}; } | 63 | geom::Size stream_size() { return geom::Size{}; } |
587 | 64 | 64 | ||
588 | === modified file 'tests/mir_test_framework/testing_server_options.cpp' | |||
589 | --- tests/mir_test_framework/testing_server_options.cpp 2013-08-27 10:19:54 +0000 | |||
590 | +++ tests/mir_test_framework/testing_server_options.cpp 2013-08-29 09:10:29 +0000 | |||
591 | @@ -200,10 +200,10 @@ | |||
592 | 200 | mc::CompositingCriteria const&, ms::BufferStream& stream) | 200 | mc::CompositingCriteria const&, ms::BufferStream& stream) |
593 | 201 | { | 201 | { |
594 | 202 | // Need to acquire the texture to cycle buffers | 202 | // Need to acquire the texture to cycle buffers |
596 | 203 | stream.lock_compositor_buffer(); | 203 | stream.lock_compositor_buffer(0); |
597 | 204 | } | 204 | } |
598 | 205 | 205 | ||
600 | 206 | void clear() {} | 206 | void clear(unsigned long) override {} |
601 | 207 | }; | 207 | }; |
602 | 208 | 208 | ||
603 | 209 | class StubRendererFactory : public mc::RendererFactory | 209 | class StubRendererFactory : public mc::RendererFactory |
604 | 210 | 210 | ||
605 | === modified file 'tests/unit-tests/compositor/test_buffer_stream.cpp' | |||
606 | --- tests/unit-tests/compositor/test_buffer_stream.cpp 2013-08-09 01:37:53 +0000 | |||
607 | +++ tests/unit-tests/compositor/test_buffer_stream.cpp 2013-08-29 09:10:29 +0000 | |||
608 | @@ -95,7 +95,7 @@ | |||
609 | 95 | { | 95 | { |
610 | 96 | using namespace testing; | 96 | using namespace testing; |
611 | 97 | 97 | ||
613 | 98 | EXPECT_CALL(*mock_bundle, compositor_acquire()) | 98 | EXPECT_CALL(*mock_bundle, compositor_acquire(_)) |
614 | 99 | .Times(1) | 99 | .Times(1) |
615 | 100 | .WillOnce(Return(mock_buffer)); | 100 | .WillOnce(Return(mock_buffer)); |
616 | 101 | EXPECT_CALL(*mock_bundle, compositor_release(_)) | 101 | EXPECT_CALL(*mock_bundle, compositor_release(_)) |
617 | @@ -103,14 +103,14 @@ | |||
618 | 103 | 103 | ||
619 | 104 | mc::BufferStreamSurfaces buffer_stream(mock_bundle); | 104 | mc::BufferStreamSurfaces buffer_stream(mock_bundle); |
620 | 105 | 105 | ||
622 | 106 | buffer_stream.lock_compositor_buffer(); | 106 | buffer_stream.lock_compositor_buffer(0); |
623 | 107 | } | 107 | } |
624 | 108 | 108 | ||
625 | 109 | TEST_F(BufferStreamTest, get_buffer_for_compositor_can_lock) | 109 | TEST_F(BufferStreamTest, get_buffer_for_compositor_can_lock) |
626 | 110 | { | 110 | { |
627 | 111 | using namespace testing; | 111 | using namespace testing; |
628 | 112 | 112 | ||
630 | 113 | EXPECT_CALL(*mock_bundle, compositor_acquire()) | 113 | EXPECT_CALL(*mock_bundle, compositor_acquire(_)) |
631 | 114 | .Times(1) | 114 | .Times(1) |
632 | 115 | .WillOnce(Return(mock_buffer)); | 115 | .WillOnce(Return(mock_buffer)); |
633 | 116 | EXPECT_CALL(*mock_bundle, compositor_release(_)) | 116 | EXPECT_CALL(*mock_bundle, compositor_release(_)) |
634 | @@ -118,7 +118,7 @@ | |||
635 | 118 | 118 | ||
636 | 119 | mc::BufferStreamSurfaces buffer_stream(mock_bundle); | 119 | mc::BufferStreamSurfaces buffer_stream(mock_bundle); |
637 | 120 | 120 | ||
639 | 121 | buffer_stream.lock_compositor_buffer(); | 121 | buffer_stream.lock_compositor_buffer(0); |
640 | 122 | } | 122 | } |
641 | 123 | 123 | ||
642 | 124 | TEST_F(BufferStreamTest, get_buffer_for_client_releases_resources) | 124 | TEST_F(BufferStreamTest, get_buffer_for_client_releases_resources) |
643 | 125 | 125 | ||
644 | === modified file 'tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp' | |||
645 | --- tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp 2013-08-26 03:00:33 +0000 | |||
646 | +++ tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp 2013-08-29 09:10:29 +0000 | |||
647 | @@ -97,7 +97,7 @@ | |||
648 | 97 | { | 97 | { |
649 | 98 | } | 98 | } |
650 | 99 | 99 | ||
652 | 100 | void clear() { renderer->clear(); } | 100 | void clear(unsigned long f) override { renderer->clear(f); } |
653 | 101 | void render(std::function<void(std::shared_ptr<void> const&)> save_resource, | 101 | void render(std::function<void(std::shared_ptr<void> const&)> save_resource, |
654 | 102 | mc::CompositingCriteria const& info, mir::surfaces::BufferStream& stream) | 102 | mc::CompositingCriteria const& info, mir::surfaces::BufferStream& stream) |
655 | 103 | { | 103 | { |
656 | @@ -254,7 +254,7 @@ | |||
657 | 254 | auto compositor_buffer = std::make_shared<mtd::MockBuffer>(); | 254 | auto compositor_buffer = std::make_shared<mtd::MockBuffer>(); |
658 | 255 | EXPECT_CALL(*compositor_buffer, can_bypass()) | 255 | EXPECT_CALL(*compositor_buffer, can_bypass()) |
659 | 256 | .WillOnce(Return(true)); | 256 | .WillOnce(Return(true)); |
661 | 257 | EXPECT_CALL(scene.stub_stream, lock_compositor_buffer()) | 257 | EXPECT_CALL(scene.stub_stream, lock_compositor_buffer(_)) |
662 | 258 | .WillOnce(Return(compositor_buffer)); | 258 | .WillOnce(Return(compositor_buffer)); |
663 | 259 | 259 | ||
664 | 260 | mc::DefaultDisplayBufferCompositorFactory factory( | 260 | mc::DefaultDisplayBufferCompositorFactory factory( |
665 | @@ -303,7 +303,7 @@ | |||
666 | 303 | auto compositor_buffer = std::make_shared<mtd::MockBuffer>(); | 303 | auto compositor_buffer = std::make_shared<mtd::MockBuffer>(); |
667 | 304 | EXPECT_CALL(*compositor_buffer, can_bypass()) | 304 | EXPECT_CALL(*compositor_buffer, can_bypass()) |
668 | 305 | .Times(0); | 305 | .Times(0); |
670 | 306 | EXPECT_CALL(scene.stub_stream, lock_compositor_buffer()) | 306 | EXPECT_CALL(scene.stub_stream, lock_compositor_buffer(_)) |
671 | 307 | .Times(0); | 307 | .Times(0); |
672 | 308 | 308 | ||
673 | 309 | mc::DefaultDisplayBufferCompositorFactory factory( | 309 | mc::DefaultDisplayBufferCompositorFactory factory( |
674 | @@ -352,7 +352,7 @@ | |||
675 | 352 | auto compositor_buffer = std::make_shared<mtd::MockBuffer>(); | 352 | auto compositor_buffer = std::make_shared<mtd::MockBuffer>(); |
676 | 353 | EXPECT_CALL(*compositor_buffer, can_bypass()) | 353 | EXPECT_CALL(*compositor_buffer, can_bypass()) |
677 | 354 | .Times(0); | 354 | .Times(0); |
679 | 355 | EXPECT_CALL(scene.stub_stream, lock_compositor_buffer()) | 355 | EXPECT_CALL(scene.stub_stream, lock_compositor_buffer(_)) |
680 | 356 | .Times(0); | 356 | .Times(0); |
681 | 357 | 357 | ||
682 | 358 | mc::DefaultDisplayBufferCompositorFactory factory( | 358 | mc::DefaultDisplayBufferCompositorFactory factory( |
683 | @@ -399,7 +399,7 @@ | |||
684 | 399 | FakeScene scene(renderable_vec); | 399 | FakeScene scene(renderable_vec); |
685 | 400 | 400 | ||
686 | 401 | auto compositor_buffer = std::make_shared<mtd::MockBuffer>(); | 401 | auto compositor_buffer = std::make_shared<mtd::MockBuffer>(); |
688 | 402 | EXPECT_CALL(scene.stub_stream, lock_compositor_buffer()) | 402 | EXPECT_CALL(scene.stub_stream, lock_compositor_buffer(_)) |
689 | 403 | .WillOnce(Return(compositor_buffer)); | 403 | .WillOnce(Return(compositor_buffer)); |
690 | 404 | EXPECT_CALL(*compositor_buffer, can_bypass()) | 404 | EXPECT_CALL(*compositor_buffer, can_bypass()) |
691 | 405 | .WillRepeatedly(Return(false)); | 405 | .WillRepeatedly(Return(false)); |
692 | @@ -450,7 +450,7 @@ | |||
693 | 450 | auto compositor_buffer = std::make_shared<mtd::MockBuffer>(); | 450 | auto compositor_buffer = std::make_shared<mtd::MockBuffer>(); |
694 | 451 | EXPECT_CALL(*compositor_buffer, can_bypass()) | 451 | EXPECT_CALL(*compositor_buffer, can_bypass()) |
695 | 452 | .Times(0); | 452 | .Times(0); |
697 | 453 | EXPECT_CALL(scene.stub_stream, lock_compositor_buffer()) | 453 | EXPECT_CALL(scene.stub_stream, lock_compositor_buffer(_)) |
698 | 454 | .Times(0); | 454 | .Times(0); |
699 | 455 | 455 | ||
700 | 456 | mc::DefaultDisplayBufferCompositorFactory factory( | 456 | mc::DefaultDisplayBufferCompositorFactory factory( |
701 | @@ -476,7 +476,7 @@ | |||
702 | 476 | .Times(0); | 476 | .Times(0); |
703 | 477 | EXPECT_CALL(renderer_factory.mock_renderer, render(_,Ref(fullscreen),_)) | 477 | EXPECT_CALL(renderer_factory.mock_renderer, render(_,Ref(fullscreen),_)) |
704 | 478 | .Times(0); | 478 | .Times(0); |
706 | 479 | EXPECT_CALL(scene.stub_stream, lock_compositor_buffer()) | 479 | EXPECT_CALL(scene.stub_stream, lock_compositor_buffer(_)) |
707 | 480 | .WillOnce(Return(compositor_buffer)); | 480 | .WillOnce(Return(compositor_buffer)); |
708 | 481 | EXPECT_CALL(*compositor_buffer, can_bypass()) | 481 | EXPECT_CALL(*compositor_buffer, can_bypass()) |
709 | 482 | .WillOnce(Return(true)); | 482 | .WillOnce(Return(true)); |
710 | @@ -494,7 +494,7 @@ | |||
711 | 494 | .Times(1); | 494 | .Times(1); |
712 | 495 | EXPECT_CALL(renderer_factory.mock_renderer, render(_,Ref(fullscreen),_)) | 495 | EXPECT_CALL(renderer_factory.mock_renderer, render(_,Ref(fullscreen),_)) |
713 | 496 | .Times(0); | 496 | .Times(0); |
715 | 497 | EXPECT_CALL(scene.stub_stream, lock_compositor_buffer()) | 497 | EXPECT_CALL(scene.stub_stream, lock_compositor_buffer(_)) |
716 | 498 | .Times(0); | 498 | .Times(0); |
717 | 499 | EXPECT_CALL(*compositor_buffer, can_bypass()) | 499 | EXPECT_CALL(*compositor_buffer, can_bypass()) |
718 | 500 | .Times(0); | 500 | .Times(0); |
719 | 501 | 501 | ||
720 | === modified file 'tests/unit-tests/compositor/test_gl_renderer.cpp' | |||
721 | --- tests/unit-tests/compositor/test_gl_renderer.cpp 2013-08-09 01:37:53 +0000 | |||
722 | +++ tests/unit-tests/compositor/test_gl_renderer.cpp 2013-08-29 09:10:29 +0000 | |||
723 | @@ -319,7 +319,7 @@ | |||
724 | 319 | 319 | ||
725 | 320 | EXPECT_CALL(mock_gl, glBindTexture(GL_TEXTURE_2D, stub_texture)); | 320 | EXPECT_CALL(mock_gl, glBindTexture(GL_TEXTURE_2D, stub_texture)); |
726 | 321 | 321 | ||
728 | 322 | EXPECT_CALL(stream, lock_compositor_buffer()) | 322 | EXPECT_CALL(stream, lock_compositor_buffer(_)) |
729 | 323 | .Times(1) | 323 | .Times(1) |
730 | 324 | .WillOnce(Return(mt::fake_shared(gr))); | 324 | .WillOnce(Return(mt::fake_shared(gr))); |
731 | 325 | EXPECT_CALL(gr, bind_to_texture()); | 325 | EXPECT_CALL(gr, bind_to_texture()); |
732 | 326 | 326 | ||
733 | === modified file 'tests/unit-tests/compositor/test_rendering_operator.cpp' | |||
734 | --- tests/unit-tests/compositor/test_rendering_operator.cpp 2013-08-09 01:37:53 +0000 | |||
735 | +++ tests/unit-tests/compositor/test_rendering_operator.cpp 2013-08-29 09:10:29 +0000 | |||
736 | @@ -46,7 +46,7 @@ | |||
737 | 46 | { | 46 | { |
738 | 47 | } | 47 | } |
739 | 48 | 48 | ||
741 | 49 | void clear() {} | 49 | void clear(unsigned long) override {} |
742 | 50 | 50 | ||
743 | 51 | void render(std::function<void(std::shared_ptr<void> const&)> save_resource, | 51 | void render(std::function<void(std::shared_ptr<void> const&)> save_resource, |
744 | 52 | mc::CompositingCriteria const&, ms::BufferStream&) | 52 | mc::CompositingCriteria const&, ms::BufferStream&) |
745 | 53 | 53 | ||
746 | === modified file 'tests/unit-tests/compositor/test_switching_bundle.cpp' | |||
747 | --- tests/unit-tests/compositor/test_switching_bundle.cpp 2013-08-09 01:37:53 +0000 | |||
748 | +++ tests/unit-tests/compositor/test_switching_bundle.cpp 2013-08-29 09:10:29 +0000 | |||
749 | @@ -102,19 +102,12 @@ | |||
750 | 102 | 102 | ||
751 | 103 | namespace | 103 | namespace |
752 | 104 | { | 104 | { |
753 | 105 | const int frame_rate = 60; | ||
754 | 106 | const std::chrono::microseconds frame_time(1000000 / frame_rate); | ||
755 | 107 | |||
756 | 108 | void sleep_one_frame() | ||
757 | 109 | { | ||
758 | 110 | std::this_thread::sleep_for(frame_time); | ||
759 | 111 | } | ||
760 | 112 | |||
761 | 113 | void composite_thread(mc::SwitchingBundle &bundle, | 105 | void composite_thread(mc::SwitchingBundle &bundle, |
762 | 106 | unsigned long &frameno, | ||
763 | 114 | mg::BufferID &composited) | 107 | mg::BufferID &composited) |
764 | 115 | { | 108 | { |
767 | 116 | sleep_one_frame(); | 109 | frameno++; |
768 | 117 | auto buffer = bundle.compositor_acquire(); | 110 | auto buffer = bundle.compositor_acquire(frameno); |
769 | 118 | composited = buffer->id(); | 111 | composited = buffer->id(); |
770 | 119 | bundle.compositor_release(buffer); | 112 | bundle.compositor_release(buffer); |
771 | 120 | } | 113 | } |
772 | @@ -126,6 +119,7 @@ | |||
773 | 126 | { | 119 | { |
774 | 127 | mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties); | 120 | mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties); |
775 | 128 | mg::BufferID prev_id, prev_prev_id; | 121 | mg::BufferID prev_id, prev_prev_id; |
776 | 122 | unsigned long frameno = 0; | ||
777 | 129 | 123 | ||
778 | 130 | ASSERT_FALSE(bundle.framedropping_allowed()); | 124 | ASSERT_FALSE(bundle.framedropping_allowed()); |
779 | 131 | 125 | ||
780 | @@ -137,6 +131,7 @@ | |||
781 | 137 | 131 | ||
782 | 138 | std::thread compositor(composite_thread, | 132 | std::thread compositor(composite_thread, |
783 | 139 | std::ref(bundle), | 133 | std::ref(bundle), |
784 | 134 | std::ref(frameno), | ||
785 | 140 | std::ref(composited_id)); | 135 | std::ref(composited_id)); |
786 | 141 | 136 | ||
787 | 142 | compositor.join(); | 137 | compositor.join(); |
788 | @@ -148,7 +143,7 @@ | |||
789 | 148 | prev_prev_id = prev_id; | 143 | prev_prev_id = prev_id; |
790 | 149 | prev_id = composited_id; | 144 | prev_id = composited_id; |
791 | 150 | 145 | ||
793 | 151 | auto second_monitor = bundle.compositor_acquire(); | 146 | auto second_monitor = bundle.compositor_acquire(frameno); |
794 | 152 | ASSERT_EQ(composited_id, second_monitor->id()); | 147 | ASSERT_EQ(composited_id, second_monitor->id()); |
795 | 153 | bundle.compositor_release(second_monitor); | 148 | bundle.compositor_release(second_monitor); |
796 | 154 | } | 149 | } |
797 | @@ -160,6 +155,7 @@ | |||
798 | 160 | for (int nbuffers = 2; nbuffers <= 5; nbuffers++) | 155 | for (int nbuffers = 2; nbuffers <= 5; nbuffers++) |
799 | 161 | { | 156 | { |
800 | 162 | mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties); | 157 | mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties); |
801 | 158 | unsigned int frameno = 0; | ||
802 | 163 | 159 | ||
803 | 164 | bundle.allow_framedropping(true); | 160 | bundle.allow_framedropping(true); |
804 | 165 | mg::BufferID last_client_id; | 161 | mg::BufferID last_client_id; |
805 | @@ -176,11 +172,12 @@ | |||
806 | 176 | // Flush the pipeline of previously ready buffers | 172 | // Flush the pipeline of previously ready buffers |
807 | 177 | for (int k = 0; k < nbuffers-1; k++) | 173 | for (int k = 0; k < nbuffers-1; k++) |
808 | 178 | { | 174 | { |
811 | 179 | bundle.compositor_release(bundle.compositor_acquire()); | 175 | frameno++; |
812 | 180 | sleep_one_frame(); | 176 | bundle.compositor_release(bundle.compositor_acquire(frameno)); |
813 | 181 | } | 177 | } |
814 | 182 | 178 | ||
816 | 183 | auto compositor = bundle.compositor_acquire(); | 179 | frameno++; |
817 | 180 | auto compositor = bundle.compositor_acquire(frameno); | ||
818 | 184 | ASSERT_EQ(last_client_id, compositor->id()); | 181 | ASSERT_EQ(last_client_id, compositor->id()); |
819 | 185 | bundle.compositor_release(compositor); | 182 | bundle.compositor_release(compositor); |
820 | 186 | } | 183 | } |
821 | @@ -200,7 +197,7 @@ | |||
822 | 200 | bundle.client_release(client2); | 197 | bundle.client_release(client2); |
823 | 201 | client2.reset(); | 198 | client2.reset(); |
824 | 202 | 199 | ||
826 | 203 | auto compositor = bundle.compositor_acquire(); | 200 | auto compositor = bundle.compositor_acquire(1); |
827 | 204 | EXPECT_EQ(client1_id, compositor->id()); | 201 | EXPECT_EQ(client1_id, compositor->id()); |
828 | 205 | bundle.compositor_release(compositor); | 202 | bundle.compositor_release(compositor); |
829 | 206 | } | 203 | } |
830 | @@ -231,6 +228,7 @@ | |||
831 | 231 | for (int nbuffers = 1; nbuffers <= 5; nbuffers++) | 228 | for (int nbuffers = 1; nbuffers <= 5; nbuffers++) |
832 | 232 | { | 229 | { |
833 | 233 | mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties); | 230 | mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties); |
834 | 231 | unsigned long frameno = 0; | ||
835 | 234 | 232 | ||
836 | 235 | auto client = bundle.client_acquire(); | 233 | auto client = bundle.client_acquire(); |
837 | 236 | auto client_id = client->id(); | 234 | auto client_id = client->id(); |
838 | @@ -238,7 +236,8 @@ | |||
839 | 238 | 236 | ||
840 | 239 | for (int monitor = 0; monitor < 10; monitor++) | 237 | for (int monitor = 0; monitor < 10; monitor++) |
841 | 240 | { | 238 | { |
843 | 241 | auto compositor = bundle.compositor_acquire(); | 239 | frameno++; |
844 | 240 | auto compositor = bundle.compositor_acquire(frameno); | ||
845 | 242 | ASSERT_EQ(client_id, compositor->id()); | 241 | ASSERT_EQ(client_id, compositor->id()); |
846 | 243 | bundle.compositor_release(compositor); | 242 | bundle.compositor_release(compositor); |
847 | 244 | } | 243 | } |
848 | @@ -250,13 +249,14 @@ | |||
849 | 250 | for (int nbuffers = 1; nbuffers <= 5; nbuffers++) | 249 | for (int nbuffers = 1; nbuffers <= 5; nbuffers++) |
850 | 251 | { | 250 | { |
851 | 252 | mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties); | 251 | mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties); |
852 | 252 | unsigned long frameno = 0; | ||
853 | 253 | const int N = 100; | 253 | const int N = 100; |
854 | 254 | 254 | ||
855 | 255 | bundle.force_requests_to_complete(); | 255 | bundle.force_requests_to_complete(); |
856 | 256 | 256 | ||
857 | 257 | std::shared_ptr<mg::Buffer> buf[N]; | 257 | std::shared_ptr<mg::Buffer> buf[N]; |
858 | 258 | for (int i = 0; i < N; i++) | 258 | for (int i = 0; i < N; i++) |
860 | 259 | buf[i] = bundle.compositor_acquire(); | 259 | buf[i] = bundle.compositor_acquire(++frameno); |
861 | 260 | 260 | ||
862 | 261 | for (int i = 0; i < N; i++) | 261 | for (int i = 0; i < N; i++) |
863 | 262 | bundle.compositor_release(buf[i]); | 262 | bundle.compositor_release(buf[i]); |
864 | @@ -268,6 +268,7 @@ | |||
865 | 268 | for (int nbuffers = 1; nbuffers <= 5; nbuffers++) | 268 | for (int nbuffers = 1; nbuffers <= 5; nbuffers++) |
866 | 269 | { | 269 | { |
867 | 270 | mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties); | 270 | mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties); |
868 | 271 | unsigned long frameno = 1; | ||
869 | 271 | 272 | ||
870 | 272 | mg::BufferID client_id; | 273 | mg::BufferID client_id; |
871 | 273 | 274 | ||
872 | @@ -282,12 +283,12 @@ | |||
873 | 282 | 283 | ||
874 | 283 | for (int monitor_id = 0; monitor_id < 10; monitor_id++) | 284 | for (int monitor_id = 0; monitor_id < 10; monitor_id++) |
875 | 284 | { | 285 | { |
877 | 285 | auto compositor = bundle.compositor_acquire(); | 286 | auto compositor = bundle.compositor_acquire(frameno); |
878 | 286 | ASSERT_EQ(client_id, compositor->id()); | 287 | ASSERT_EQ(client_id, compositor->id()); |
879 | 287 | bundle.compositor_release(compositor); | 288 | bundle.compositor_release(compositor); |
880 | 288 | } | 289 | } |
881 | 289 | 290 | ||
883 | 290 | sleep_one_frame(); | 291 | frameno++; |
884 | 291 | } | 292 | } |
885 | 292 | } | 293 | } |
886 | 293 | } | 294 | } |
887 | @@ -297,6 +298,7 @@ | |||
888 | 297 | for (int nbuffers = 2; nbuffers <= 5; nbuffers++) | 298 | for (int nbuffers = 2; nbuffers <= 5; nbuffers++) |
889 | 298 | { | 299 | { |
890 | 299 | mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties); | 300 | mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties); |
891 | 301 | unsigned long frameno = 0; | ||
892 | 300 | 302 | ||
893 | 301 | auto client = bundle.client_acquire(); | 303 | auto client = bundle.client_acquire(); |
894 | 302 | 304 | ||
895 | @@ -306,7 +308,7 @@ | |||
896 | 306 | ); | 308 | ); |
897 | 307 | bundle.client_release(client); | 309 | bundle.client_release(client); |
898 | 308 | 310 | ||
900 | 309 | auto compositor1 = bundle.compositor_acquire(); | 311 | auto compositor1 = bundle.compositor_acquire(++frameno); |
901 | 310 | bundle.compositor_release(compositor1); | 312 | bundle.compositor_release(compositor1); |
902 | 311 | EXPECT_THROW( | 313 | EXPECT_THROW( |
903 | 312 | bundle.compositor_release(compositor1), | 314 | bundle.compositor_release(compositor1), |
904 | @@ -321,15 +323,16 @@ | |||
905 | 321 | for (int nbuffers = 2; nbuffers <= 5; nbuffers++) | 323 | for (int nbuffers = 2; nbuffers <= 5; nbuffers++) |
906 | 322 | { | 324 | { |
907 | 323 | mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties); | 325 | mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties); |
908 | 326 | unsigned long frameno = 1; | ||
909 | 324 | 327 | ||
910 | 325 | std::shared_ptr<mg::Buffer> compositor[2]; | 328 | std::shared_ptr<mg::Buffer> compositor[2]; |
911 | 326 | 329 | ||
912 | 327 | bundle.client_release(bundle.client_acquire()); | 330 | bundle.client_release(bundle.client_acquire()); |
914 | 328 | compositor[0] = bundle.compositor_acquire(); | 331 | compositor[0] = bundle.compositor_acquire(frameno); |
915 | 329 | 332 | ||
917 | 330 | sleep_one_frame(); | 333 | frameno++; |
918 | 331 | bundle.client_release(bundle.client_acquire()); | 334 | bundle.client_release(bundle.client_acquire()); |
920 | 332 | compositor[1] = bundle.compositor_acquire(); | 335 | compositor[1] = bundle.compositor_acquire(frameno); |
921 | 333 | 336 | ||
922 | 334 | for (int i = 0; i < 20; i++) | 337 | for (int i = 0; i < 20; i++) |
923 | 335 | { | 338 | { |
924 | @@ -340,8 +343,8 @@ | |||
925 | 340 | int oldest = i & 1; | 343 | int oldest = i & 1; |
926 | 341 | bundle.compositor_release(compositor[oldest]); | 344 | bundle.compositor_release(compositor[oldest]); |
927 | 342 | bundle.client_release(bundle.client_acquire()); | 345 | bundle.client_release(bundle.client_acquire()); |
930 | 343 | sleep_one_frame(); | 346 | frameno++; |
931 | 344 | compositor[oldest] = bundle.compositor_acquire(); | 347 | compositor[oldest] = bundle.compositor_acquire(frameno); |
932 | 345 | } | 348 | } |
933 | 346 | 349 | ||
934 | 347 | bundle.compositor_release(compositor[0]); | 350 | bundle.compositor_release(compositor[0]); |
935 | @@ -355,7 +358,7 @@ | |||
936 | 355 | { | 358 | { |
937 | 356 | mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties); | 359 | mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties); |
938 | 357 | 360 | ||
940 | 358 | auto compositor = bundle.compositor_acquire(); | 361 | auto compositor = bundle.compositor_acquire(1); |
941 | 359 | auto snapshot = bundle.snapshot_acquire(); | 362 | auto snapshot = bundle.snapshot_acquire(); |
942 | 360 | EXPECT_EQ(snapshot->id(), compositor->id()); | 363 | EXPECT_EQ(snapshot->id(), compositor->id()); |
943 | 361 | bundle.compositor_release(compositor); | 364 | bundle.compositor_release(compositor); |
944 | @@ -385,7 +388,7 @@ | |||
945 | 385 | { | 388 | { |
946 | 386 | mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties); | 389 | mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties); |
947 | 387 | 390 | ||
949 | 388 | auto compositor = bundle.compositor_acquire(); | 391 | auto compositor = bundle.compositor_acquire(1); |
950 | 389 | 392 | ||
951 | 390 | EXPECT_THROW( | 393 | EXPECT_THROW( |
952 | 391 | bundle.snapshot_release(compositor), | 394 | bundle.snapshot_release(compositor), |
953 | @@ -418,9 +421,10 @@ | |||
954 | 418 | void compositor_thread(mc::SwitchingBundle &bundle, | 421 | void compositor_thread(mc::SwitchingBundle &bundle, |
955 | 419 | std::atomic<bool> &done) | 422 | std::atomic<bool> &done) |
956 | 420 | { | 423 | { |
957 | 424 | unsigned long frameno = 0; | ||
958 | 421 | while (!done) | 425 | while (!done) |
959 | 422 | { | 426 | { |
961 | 423 | bundle.compositor_release(bundle.compositor_acquire()); | 427 | bundle.compositor_release(bundle.compositor_acquire(++frameno)); |
962 | 424 | std::this_thread::yield(); | 428 | std::this_thread::yield(); |
963 | 425 | } | 429 | } |
964 | 426 | } | 430 | } |
965 | @@ -510,6 +514,7 @@ | |||
966 | 510 | for (int nbuffers = 1; nbuffers <= 5; nbuffers++) | 514 | for (int nbuffers = 1; nbuffers <= 5; nbuffers++) |
967 | 511 | { | 515 | { |
968 | 512 | mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties); | 516 | mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties); |
969 | 517 | unsigned long frameno = 0; | ||
970 | 513 | 518 | ||
971 | 514 | bundle.allow_framedropping(false); | 519 | bundle.allow_framedropping(false); |
972 | 515 | 520 | ||
973 | @@ -520,9 +525,9 @@ | |||
974 | 520 | 525 | ||
975 | 521 | for (int frame = 0; frame < nframes; frame++) | 526 | for (int frame = 0; frame < nframes; frame++) |
976 | 522 | { | 527 | { |
978 | 523 | sleep_one_frame(); | 528 | frameno++; |
979 | 524 | 529 | ||
981 | 525 | auto compositor = bundle.compositor_acquire(); | 530 | auto compositor = bundle.compositor_acquire(frameno); |
982 | 526 | auto compositor_id = compositor->id(); | 531 | auto compositor_id = compositor->id(); |
983 | 527 | bundle.compositor_release(compositor); | 532 | bundle.compositor_release(compositor); |
984 | 528 | 533 | ||
985 | @@ -542,15 +547,16 @@ | |||
986 | 542 | for (int nbuffers = 3; nbuffers <= 5; nbuffers++) | 547 | for (int nbuffers = 3; nbuffers <= 5; nbuffers++) |
987 | 543 | { | 548 | { |
988 | 544 | mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties); | 549 | mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties); |
989 | 550 | unsigned long frameno = 1; | ||
990 | 545 | 551 | ||
991 | 546 | std::shared_ptr<mg::Buffer> compositor[2]; | 552 | std::shared_ptr<mg::Buffer> compositor[2]; |
992 | 547 | 553 | ||
993 | 548 | bundle.client_release(bundle.client_acquire()); | 554 | bundle.client_release(bundle.client_acquire()); |
995 | 549 | compositor[0] = bundle.compositor_acquire(); | 555 | compositor[0] = bundle.compositor_acquire(frameno); |
996 | 550 | 556 | ||
998 | 551 | sleep_one_frame(); | 557 | frameno++; |
999 | 552 | bundle.client_release(bundle.client_acquire()); | 558 | bundle.client_release(bundle.client_acquire()); |
1001 | 553 | compositor[1] = bundle.compositor_acquire(); | 559 | compositor[1] = bundle.compositor_acquire(frameno); |
1002 | 554 | 560 | ||
1003 | 555 | for (int i = 0; i < 20; i++) | 561 | for (int i = 0; i < 20; i++) |
1004 | 556 | { | 562 | { |
1005 | @@ -566,8 +572,8 @@ | |||
1006 | 566 | int oldest = i & 1; | 572 | int oldest = i & 1; |
1007 | 567 | bundle.compositor_release(compositor[oldest]); | 573 | bundle.compositor_release(compositor[oldest]); |
1008 | 568 | 574 | ||
1011 | 569 | sleep_one_frame(); | 575 | frameno++; |
1012 | 570 | compositor[oldest] = bundle.compositor_acquire(); | 576 | compositor[oldest] = bundle.compositor_acquire(frameno); |
1013 | 571 | } | 577 | } |
1014 | 572 | 578 | ||
1015 | 573 | bundle.compositor_release(compositor[0]); | 579 | bundle.compositor_release(compositor[0]); |
1016 | @@ -649,85 +655,53 @@ | |||
1017 | 649 | namespace | 655 | namespace |
1018 | 650 | { | 656 | { |
1019 | 651 | void realtime_compositor_thread(mc::SwitchingBundle &bundle, | 657 | void realtime_compositor_thread(mc::SwitchingBundle &bundle, |
1020 | 658 | unsigned long frames, | ||
1021 | 652 | std::atomic<bool> &done) | 659 | std::atomic<bool> &done) |
1022 | 653 | { | 660 | { |
1024 | 654 | while (!done) | 661 | std::this_thread::sleep_for(std::chrono::milliseconds(1000)); |
1025 | 662 | |||
1026 | 663 | for (unsigned long frame = 0; frame < frames; frame++) | ||
1027 | 655 | { | 664 | { |
1030 | 656 | auto buf = bundle.compositor_acquire(); | 665 | std::this_thread::sleep_for(std::chrono::milliseconds(100)); |
1031 | 657 | sleep_one_frame(); | 666 | |
1032 | 667 | auto buf = bundle.compositor_acquire(frame); | ||
1033 | 658 | bundle.compositor_release(buf); | 668 | bundle.compositor_release(buf); |
1034 | 659 | } | 669 | } |
1035 | 670 | done.store(true); | ||
1036 | 660 | } | 671 | } |
1037 | 661 | } | 672 | } |
1038 | 662 | 673 | ||
1039 | 663 | TEST_F(SwitchingBundleTest, client_framerate_matches_compositor) | 674 | TEST_F(SwitchingBundleTest, client_framerate_matches_compositor) |
1040 | 664 | { | 675 | { |
1041 | 665 | const int expected = | ||
1042 | 666 | std::chrono::duration_cast<std::chrono::microseconds>(frame_time) | ||
1043 | 667 | .count(); | ||
1044 | 668 | |||
1045 | 669 | int nframes = 0; | ||
1046 | 670 | int nhiccups = 0; | ||
1047 | 671 | |||
1048 | 672 | for (int nbuffers = 2; nbuffers <= 3; nbuffers++) | 676 | for (int nbuffers = 2; nbuffers <= 3; nbuffers++) |
1049 | 673 | { | 677 | { |
1050 | 674 | mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties); | 678 | mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties); |
1051 | 679 | unsigned long client_frames = 0; | ||
1052 | 680 | const unsigned long compose_frames = 20; | ||
1053 | 675 | 681 | ||
1054 | 676 | bundle.allow_framedropping(false); | 682 | bundle.allow_framedropping(false); |
1055 | 677 | 683 | ||
1058 | 678 | std::atomic<bool> done; | 684 | std::atomic<bool> done(false); |
1057 | 679 | done = false; | ||
1059 | 680 | 685 | ||
1060 | 681 | std::thread monitor1(realtime_compositor_thread, | 686 | std::thread monitor1(realtime_compositor_thread, |
1068 | 682 | std::ref(bundle), std::ref(done)); | 687 | std::ref(bundle), |
1069 | 683 | std::thread monitor2(realtime_compositor_thread, | 688 | compose_frames, |
1070 | 684 | std::ref(bundle), std::ref(done)); | 689 | std::ref(done)); |
1071 | 685 | std::thread monitor3(realtime_compositor_thread, | 690 | |
1072 | 686 | std::ref(bundle), std::ref(done)); | 691 | bundle.client_release(bundle.client_acquire()); |
1073 | 687 | 692 | ||
1074 | 688 | for (int attempt = 0; attempt < 2; attempt++) | 693 | while (!done.load()) |
1075 | 689 | { | 694 | { |
1107 | 690 | // Initial queue filling is not throttled... | 695 | bundle.client_release(bundle.client_acquire()); |
1108 | 691 | for (int f = 0; f < nbuffers + 1; f++) | 696 | client_frames++; |
1109 | 692 | bundle.client_release(bundle.client_acquire()); | 697 | std::this_thread::yield(); |
1079 | 693 | |||
1080 | 694 | auto prev = std::chrono::high_resolution_clock::now(); | ||
1081 | 695 | |||
1082 | 696 | for (int second = 0; second < 2; second++) | ||
1083 | 697 | { | ||
1084 | 698 | for (int frame = 0; frame < frame_rate; frame++) | ||
1085 | 699 | { | ||
1086 | 700 | bundle.client_release(bundle.client_acquire()); | ||
1087 | 701 | |||
1088 | 702 | auto t = std::chrono::high_resolution_clock::now(); | ||
1089 | 703 | auto d = t - prev; | ||
1090 | 704 | prev = t; | ||
1091 | 705 | |||
1092 | 706 | int measured_frame_time_usec = | ||
1093 | 707 | std::chrono::duration_cast<std::chrono::microseconds>(d) | ||
1094 | 708 | .count(); | ||
1095 | 709 | |||
1096 | 710 | nframes++; | ||
1097 | 711 | if (expected * 0.7f > measured_frame_time_usec || | ||
1098 | 712 | expected * 1.3f < measured_frame_time_usec) | ||
1099 | 713 | { | ||
1100 | 714 | nhiccups++; | ||
1101 | 715 | } | ||
1102 | 716 | } | ||
1103 | 717 | } | ||
1104 | 718 | |||
1105 | 719 | // Simulate a pause/resume like VT switching | ||
1106 | 720 | bundle.force_requests_to_complete(); | ||
1110 | 721 | } | 698 | } |
1111 | 722 | 699 | ||
1112 | 723 | done = true; | ||
1113 | 724 | |||
1114 | 725 | monitor1.join(); | 700 | monitor1.join(); |
1115 | 726 | monitor2.join(); | ||
1116 | 727 | monitor3.join(); | ||
1117 | 728 | 701 | ||
1120 | 729 | int hiccups_percent = nhiccups * 100 / nframes; | 702 | // Roughly compose_frames == client_frames within 50% |
1121 | 730 | ASSERT_LT(hiccups_percent, 10); | 703 | ASSERT_GT(client_frames, compose_frames / 2); |
1122 | 704 | ASSERT_LT(client_frames, compose_frames * 3 / 2); | ||
1123 | 731 | } | 705 | } |
1124 | 732 | } | 706 | } |
1125 | 733 | 707 | ||
1126 | 734 | 708 | ||
1127 | === modified file 'tests/unit-tests/compositor/test_temporary_buffers.cpp' | |||
1128 | --- tests/unit-tests/compositor/test_temporary_buffers.cpp 2013-08-09 01:37:53 +0000 | |||
1129 | +++ tests/unit-tests/compositor/test_temporary_buffers.cpp 2013-08-29 09:10:29 +0000 | |||
1130 | @@ -54,7 +54,7 @@ | |||
1131 | 54 | 54 | ||
1132 | 55 | ON_CALL(*mock_bundle, client_acquire()) | 55 | ON_CALL(*mock_bundle, client_acquire()) |
1133 | 56 | .WillByDefault(Return(mock_buffer)); | 56 | .WillByDefault(Return(mock_buffer)); |
1135 | 57 | ON_CALL(*mock_bundle, compositor_acquire()) | 57 | ON_CALL(*mock_bundle, compositor_acquire(_)) |
1136 | 58 | .WillByDefault(Return(mock_buffer)); | 58 | .WillByDefault(Return(mock_buffer)); |
1137 | 59 | } | 59 | } |
1138 | 60 | 60 | ||
1139 | @@ -92,12 +92,12 @@ | |||
1140 | 92 | TEST_F(TemporaryBuffersTest, compositor_buffer_acquires_and_releases) | 92 | TEST_F(TemporaryBuffersTest, compositor_buffer_acquires_and_releases) |
1141 | 93 | { | 93 | { |
1142 | 94 | using namespace testing; | 94 | using namespace testing; |
1144 | 95 | EXPECT_CALL(*mock_bundle, compositor_acquire()) | 95 | EXPECT_CALL(*mock_bundle, compositor_acquire(_)) |
1145 | 96 | .WillOnce(Return(mock_buffer)); | 96 | .WillOnce(Return(mock_buffer)); |
1146 | 97 | EXPECT_CALL(*mock_bundle, compositor_release(_)) | 97 | EXPECT_CALL(*mock_bundle, compositor_release(_)) |
1147 | 98 | .Times(1); | 98 | .Times(1); |
1148 | 99 | 99 | ||
1150 | 100 | mc::TemporaryCompositorBuffer proxy_buffer(mock_bundle); | 100 | mc::TemporaryCompositorBuffer proxy_buffer(mock_bundle, 0); |
1151 | 101 | } | 101 | } |
1152 | 102 | 102 | ||
1153 | 103 | TEST_F(TemporaryBuffersTest, snapshot_buffer_acquires_and_releases) | 103 | TEST_F(TemporaryBuffersTest, snapshot_buffer_acquires_and_releases) |
1154 | 104 | 104 | ||
1155 | === modified file 'tests/unit-tests/surfaces/test_surface.cpp' | |||
1156 | --- tests/unit-tests/surfaces/test_surface.cpp 2013-08-09 01:37:53 +0000 | |||
1157 | +++ tests/unit-tests/surfaces/test_surface.cpp 2013-08-29 09:10:29 +0000 | |||
1158 | @@ -308,7 +308,7 @@ | |||
1159 | 308 | ms::Surface surf(mock_basic_state, mock_buffer_stream, std::shared_ptr<mi::InputChannel>()); | 308 | ms::Surface surf(mock_basic_state, mock_buffer_stream, std::shared_ptr<mi::InputChannel>()); |
1160 | 309 | auto buffer_resource = std::make_shared<mtd::StubBuffer>(); | 309 | auto buffer_resource = std::make_shared<mtd::StubBuffer>(); |
1161 | 310 | 310 | ||
1163 | 311 | EXPECT_CALL(*mock_buffer_stream, lock_compositor_buffer()) | 311 | EXPECT_CALL(*mock_buffer_stream, lock_compositor_buffer(_)) |
1164 | 312 | .Times(AtLeast(1)) | 312 | .Times(AtLeast(1)) |
1165 | 313 | .WillOnce(Return(buffer_resource)); | 313 | .WillOnce(Return(buffer_resource)); |
1166 | 314 | 314 | ||
1167 | 315 | 315 | ||
1168 | === modified file 'tests/unit-tests/surfaces/test_surface_stack.cpp' | |||
1169 | --- tests/unit-tests/surfaces/test_surface_stack.cpp 2013-08-26 03:00:33 +0000 | |||
1170 | +++ tests/unit-tests/surfaces/test_surface_stack.cpp 2013-08-29 09:10:29 +0000 | |||
1171 | @@ -69,7 +69,8 @@ | |||
1172 | 69 | public: | 69 | public: |
1173 | 70 | virtual std::shared_ptr<mg::Buffer> client_acquire() { return std::shared_ptr<mg::Buffer>(); } | 70 | virtual std::shared_ptr<mg::Buffer> client_acquire() { return std::shared_ptr<mg::Buffer>(); } |
1174 | 71 | virtual void client_release(std::shared_ptr<mg::Buffer> const&) {} | 71 | virtual void client_release(std::shared_ptr<mg::Buffer> const&) {} |
1176 | 72 | virtual std::shared_ptr<mg::Buffer> compositor_acquire(){ return std::shared_ptr<mg::Buffer>(); }; | 72 | virtual std::shared_ptr<mg::Buffer> compositor_acquire(unsigned long) |
1177 | 73 | { return std::shared_ptr<mg::Buffer>(); }; | ||
1178 | 73 | virtual void compositor_release(std::shared_ptr<mg::Buffer> const&){} | 74 | virtual void compositor_release(std::shared_ptr<mg::Buffer> const&){} |
1179 | 74 | virtual std::shared_ptr<mg::Buffer> snapshot_acquire(){ return std::shared_ptr<mg::Buffer>(); }; | 75 | virtual std::shared_ptr<mg::Buffer> snapshot_acquire(){ return std::shared_ptr<mg::Buffer>(); }; |
1180 | 75 | virtual void snapshot_release(std::shared_ptr<mg::Buffer> const&){} | 76 | virtual void snapshot_release(std::shared_ptr<mg::Buffer> const&){} |
PASSED: Continuous integration, rev:948 jenkins. qa.ubuntu. com/job/ mir-ci/ 1392/ jenkins. qa.ubuntu. com/job/ mir-android- saucy-i386- build/1865 jenkins. qa.ubuntu. com/job/ mir-clang- saucy-amd64- build/1750 jenkins. qa.ubuntu. com/job/ mir-saucy- amd64-ci/ 630 jenkins. qa.ubuntu. com/job/ mir-saucy- amd64-ci/ 630/artifact/ work/output/ *zip*/output. zip
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild: s-jenkins: 8080/job/ mir-ci/ 1392/rebuild
http://