Mir

Merge lp:~kdub/mir/testable-surface-tracking into lp:mir

Proposed by Kevin DuBois
Status: Merged
Approved by: Kevin DuBois
Approved revision: no longer in the source branch.
Merged at revision: 1860
Proposed branch: lp:~kdub/mir/testable-surface-tracking
Merge into: lp:mir
Prerequisite: lp:~kdub/mir/more-testable-mediator
Diff against target: 570 lines (+312/-86)
7 files modified
src/server/frontend/CMakeLists.txt (+1/-0)
src/server/frontend/session_mediator.cpp (+10/-18)
src/server/frontend/session_mediator.h (+2/-3)
src/server/frontend/surface_tracker.cpp (+63/-0)
src/server/frontend/surface_tracker.h (+64/-0)
tests/unit-tests/frontend/test_client_buffer_tracker.cpp (+100/-1)
tests/unit-tests/frontend/test_session_mediator.cpp (+72/-64)
To merge this branch: bzr merge lp:~kdub/mir/testable-surface-tracking
Reviewer Review Type Date Requested Status
Daniel van Vugt Abstain
PS Jenkins bot (community) continuous-integration Approve
Alan Griffiths Approve
Review via email: mp+230814@code.launchpad.net

Commit message

frontend: SessionMediator: extract the session tracking of Surface and BufferId's into one place so session mediator is less concerned with it. This makes session mediator a bit more testable.

Description of the change

frontend: SessionMediator: extract the session tracking of Surface and BufferId's into one place so session mediator is less concerned with it. This makes session mediator a bit more testable.

This is a break-out of my tdd-iteration around the exchange_buffer rpc changes. Subsequent branches rely on associating BufferId's and SurfaceId's in a way that was difficult to test with the logic scattered between ClientBufferTracker and SessionMediator. This branch has no ABI change.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

While it makes sense to separate out the tracker logic I'm not sure that it is useful to be able to mock SurfaceTracker.

I'd be inclined to hoist the implementation from SessionSurfaceTracker and avoiding the constructor parameter for SessionMediator by just having a data member.

But I won't block on that as a mockable SurfaceTracker may be what is needed by the follow-up.

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

(1) This is an ABI break. We probably don't need the ABI numbers bumped again since they have already for 0.7 but we do need the new header mentioned in *sha1sums:

+++ src/server/frontend/session_mediator.h 2014-08-15 17:55:26 +0000
82 +#include "surface_tracker.h"

Just run: tools/update-all-ABI-sha1sums.sh

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

Whoops, that's a private file. I was wrong.

review: Abstain

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/server/frontend/CMakeLists.txt'
2--- src/server/frontend/CMakeLists.txt 2014-08-06 12:22:34 +0000
3+++ src/server/frontend/CMakeLists.txt 2014-08-15 17:55:26 +0000
4@@ -16,6 +16,7 @@
5 socket_messenger.cpp
6 event_sender.cpp
7 surface.cpp
8+ surface_tracker.cpp
9 unauthorized_display_changer.cpp
10 unauthorized_screencast.cpp
11 session_credentials.cpp
12
13=== modified file 'src/server/frontend/session_mediator.cpp'
14--- src/server/frontend/session_mediator.cpp 2014-08-14 08:18:45 +0000
15+++ src/server/frontend/session_mediator.cpp 2014-08-15 17:55:26 +0000
16@@ -45,6 +45,7 @@
17 #include "mir/fd.h"
18
19 #include "mir/geometry/rectangles.h"
20+#include "surface_tracker.h"
21 #include "client_buffer_tracker.h"
22 #include "protobuf_buffer_packer.h"
23
24@@ -83,7 +84,8 @@
25 resource_cache(resource_cache),
26 screencast(screencast),
27 connection_context(connection_context),
28- cursor_images(cursor_images)
29+ cursor_images(cursor_images),
30+ surface_tracker{static_cast<size_t>(client_buffer_cache_size)}
31 {
32 }
33
34@@ -142,24 +144,14 @@
35 Surface& surface,
36 std::function<void(graphics::Buffer*, graphics::BufferIpcMsgType)> complete)
37 {
38- auto& tracker = client_buffer_tracker[surf_id];
39- if (!tracker) tracker = std::make_shared<ClientBufferTracker>(client_buffer_cache_size);
40-
41- auto& client_buffer = client_buffer_resource[surf_id];
42- surface.swap_buffers(client_buffer,
43- [&tracker, &client_buffer, complete](mg::Buffer* new_buffer)
44+ surface.swap_buffers(
45+ surface_tracker.last_buffer(surf_id),
46+ [this, surf_id, complete](mg::Buffer* new_buffer)
47 {
48-
49- client_buffer = new_buffer;
50- auto id = client_buffer->id();
51- auto need_full_ipc = !tracker->client_has(id);
52-
53- tracker->add(id);
54-
55- if (need_full_ipc)
56- complete(client_buffer, mg::BufferIpcMsgType::full_msg);
57+ if (surface_tracker.track_buffer(surf_id, new_buffer))
58+ complete(new_buffer, mg::BufferIpcMsgType::update_msg);
59 else
60- complete(client_buffer, mg::BufferIpcMsgType::update_msg);
61+ complete(new_buffer, mg::BufferIpcMsgType::full_msg);
62 });
63 }
64
65@@ -275,7 +267,7 @@
66 auto const id = SurfaceId(request->value());
67
68 session->destroy_surface(id);
69- client_buffer_tracker.erase(id);
70+ surface_tracker.remove_surface(id);
71 }
72
73 // TODO: We rely on this sending responses synchronously.
74
75=== modified file 'src/server/frontend/session_mediator.h'
76--- src/server/frontend/session_mediator.h 2014-07-30 15:25:54 +0000
77+++ src/server/frontend/session_mediator.h 2014-08-15 17:55:26 +0000
78@@ -24,9 +24,9 @@
79 #include "mir/frontend/surface_id.h"
80 #include "mir/graphics/platform.h"
81 #include "mir_toolkit/common.h"
82+#include "surface_tracker.h"
83
84 #include <functional>
85-#include <unordered_map>
86 #include <memory>
87 #include <mutex>
88 #include <vector>
89@@ -186,8 +186,7 @@
90 ConnectionContext const connection_context;
91 std::shared_ptr<input::CursorImages> const cursor_images;
92
93- std::unordered_map<SurfaceId,graphics::Buffer*> client_buffer_resource;
94- std::unordered_map<SurfaceId, std::shared_ptr<ClientBufferTracker>> client_buffer_tracker;
95+ SurfaceTracker surface_tracker;
96
97 std::mutex session_mutex;
98 std::weak_ptr<Session> weak_session;
99
100=== added file 'src/server/frontend/surface_tracker.cpp'
101--- src/server/frontend/surface_tracker.cpp 1970-01-01 00:00:00 +0000
102+++ src/server/frontend/surface_tracker.cpp 2014-08-15 17:55:26 +0000
103@@ -0,0 +1,63 @@
104+/*
105+ * Copyright © 2013 Canonical Ltd.
106+ *
107+ * This program is free software: you can redistribute it and/or modify
108+ * it under the terms of the GNU General Public License version 3 as
109+ * published by the Free Software Foundation.
110+ *
111+ * This program is distributed in the hope that it will be useful,
112+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
113+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
114+ * GNU General Public License for more details.
115+ *
116+ * You should have received a copy of the GNU General Public License
117+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
118+ *
119+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
120+ */
121+
122+#include "surface_tracker.h"
123+#include "mir/graphics/buffer.h"
124+#include "mir/graphics/buffer_id.h"
125+
126+namespace mf = mir::frontend;
127+namespace mg = mir::graphics;
128+
129+mf::SurfaceTracker::SurfaceTracker(size_t client_cache_size) :
130+ client_cache_size{client_cache_size}
131+{
132+}
133+
134+bool mf::SurfaceTracker::track_buffer(SurfaceId surface_id, mg::Buffer* buffer)
135+{
136+ auto& tracker = client_buffer_tracker[surface_id];
137+ if (!tracker)
138+ tracker = std::make_shared<ClientBufferTracker>(client_cache_size);
139+
140+ auto already_tracked = tracker->client_has(buffer->id());
141+ tracker->add(buffer->id());
142+
143+ client_buffer_resource[surface_id] = buffer;
144+ return already_tracked;
145+}
146+
147+void mf::SurfaceTracker::remove_surface(SurfaceId surface_id)
148+{
149+ auto it = client_buffer_tracker.find(surface_id);
150+ if (it != client_buffer_tracker.end())
151+ client_buffer_tracker.erase(it);
152+
153+ auto last_buffer_it = client_buffer_resource.find(surface_id);
154+ if (last_buffer_it != client_buffer_resource.end())
155+ client_buffer_resource.erase(last_buffer_it);
156+}
157+
158+mg::Buffer* mf::SurfaceTracker::last_buffer(SurfaceId surface_id) const
159+{
160+ auto it = client_buffer_resource.find(surface_id);
161+ if (it != client_buffer_resource.end())
162+ return it->second;
163+ else
164+ //should really throw, but that is difficult with the way the code currently works
165+ return nullptr;
166+}
167
168=== added file 'src/server/frontend/surface_tracker.h'
169--- src/server/frontend/surface_tracker.h 1970-01-01 00:00:00 +0000
170+++ src/server/frontend/surface_tracker.h 2014-08-15 17:55:26 +0000
171@@ -0,0 +1,64 @@
172+/*
173+ * Copyright © 2013 Canonical Ltd.
174+ *
175+ * This program is free software: you can redistribute it and/or modify
176+ * it under the terms of the GNU General Public License version 3 as
177+ * published by the Free Software Foundation.
178+ *
179+ * This program is distributed in the hope that it will be useful,
180+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
181+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
182+ * GNU General Public License for more details.
183+ *
184+ * You should have received a copy of the GNU General Public License
185+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
186+ *
187+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
188+ */
189+
190+#ifndef MIR_FRONTEND_SURFACE_TRACKER_H_
191+#define MIR_FRONTEND_SURFACE_TRACKER_H_
192+
193+#include "mir/frontend/surface_id.h"
194+#include "client_buffer_tracker.h"
195+#include <unordered_map>
196+#include <memory>
197+
198+namespace mir
199+{
200+namespace graphics
201+{
202+class Buffer;
203+}
204+namespace frontend
205+{
206+
207+class SurfaceTracker
208+{
209+public:
210+ SurfaceTracker(size_t client_cache_size);
211+ SurfaceTracker(SurfaceTracker const&) = delete;
212+ SurfaceTracker& operator=(SurfaceTracker const&) = delete;
213+
214+ /* track a buffer as associated with a surface
215+ * \param surface_id id that the the buffer is associated with
216+ * \param buffer buffer to be tracked (TODO: should be a shared_ptr)
217+ * \returns true if the buffer is already tracked
218+ * false if the buffer is not tracked
219+ */
220+ bool track_buffer(SurfaceId, graphics::Buffer*);
221+ /* removes the surface id from all tracking */
222+ void remove_surface(SurfaceId);
223+ /* accesses the last buffer given to track_buffer() for the given SurfaceId */
224+ graphics::Buffer* last_buffer(SurfaceId) const;
225+private:
226+ size_t const client_cache_size;
227+
228+ std::unordered_map<SurfaceId, graphics::Buffer*> client_buffer_resource;
229+ std::unordered_map<SurfaceId, std::shared_ptr<ClientBufferTracker>> client_buffer_tracker;
230+};
231+
232+}
233+}
234+
235+#endif // MIR_FRONTEND_SURFACE_TRACKER_H_
236
237=== modified file 'tests/unit-tests/frontend/test_client_buffer_tracker.cpp'
238--- tests/unit-tests/frontend/test_client_buffer_tracker.cpp 2013-08-28 03:41:48 +0000
239+++ tests/unit-tests/frontend/test_client_buffer_tracker.cpp 2014-08-15 17:55:26 +0000
240@@ -16,11 +16,14 @@
241 * Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
242 */
243
244-#include "../../src/server/frontend/client_buffer_tracker.h"
245+#include "src/server/frontend/client_buffer_tracker.h"
246+#include "src/server/frontend/surface_tracker.h"
247 #include "mir/graphics/buffer_id.h"
248+#include "mir_test_doubles/stub_buffer.h"
249
250 #include <gtest/gtest.h>
251
252+namespace mtd = mir::test::doubles;
253 namespace mf = mir::frontend;
254 namespace mg = mir::graphics;
255
256@@ -106,3 +109,99 @@
257 EXPECT_TRUE(tracker.client_has(ids[i]));
258 }
259 }
260+
261+struct SurfaceTracker : public testing::Test
262+{
263+ mtd::StubBuffer stub_buffer0;
264+ mtd::StubBuffer stub_buffer1;
265+ mtd::StubBuffer stub_buffer2;
266+ mtd::StubBuffer stub_buffer3;
267+ mf::SurfaceId surf_id0{0};
268+ mf::SurfaceId surf_id1{1};
269+ size_t const client_cache_size{3};
270+};
271+
272+TEST_F(SurfaceTracker, only_returns_true_if_buffer_already_tracked)
273+{
274+ mf::SurfaceTracker tracker{client_cache_size};
275+
276+ EXPECT_FALSE(tracker.track_buffer(surf_id0, &stub_buffer0));
277+ EXPECT_TRUE(tracker.track_buffer(surf_id0, &stub_buffer0));
278+
279+ EXPECT_FALSE(tracker.track_buffer(surf_id0, &stub_buffer1));
280+ EXPECT_FALSE(tracker.track_buffer(surf_id1, &stub_buffer0));
281+ EXPECT_FALSE(tracker.track_buffer(surf_id1, &stub_buffer1));
282+}
283+
284+TEST_F(SurfaceTracker, removals_remove_buffer_instances)
285+{
286+ mf::SurfaceTracker tracker{client_cache_size};
287+ EXPECT_FALSE(tracker.track_buffer(surf_id0, &stub_buffer0));
288+ EXPECT_FALSE(tracker.track_buffer(surf_id1, &stub_buffer0));
289+
290+ EXPECT_TRUE(tracker.track_buffer(surf_id0, &stub_buffer0));
291+ EXPECT_TRUE(tracker.track_buffer(surf_id1, &stub_buffer0));
292+ EXPECT_EQ(&stub_buffer0, tracker.last_buffer(surf_id0));
293+
294+ tracker.remove_surface(surf_id0);
295+ EXPECT_EQ(nullptr, tracker.last_buffer(surf_id0));
296+
297+ EXPECT_FALSE(tracker.track_buffer(surf_id0, &stub_buffer0));
298+ EXPECT_TRUE(tracker.track_buffer(surf_id1, &stub_buffer0));
299+
300+ tracker.remove_surface(mf::SurfaceId{33});
301+}
302+
303+TEST_F(SurfaceTracker, last_client_buffer)
304+{
305+ mf::SurfaceTracker tracker{client_cache_size};
306+
307+ tracker.track_buffer(surf_id0, &stub_buffer0);
308+ EXPECT_EQ(&stub_buffer0, tracker.last_buffer(surf_id0));
309+ tracker.track_buffer(surf_id0, &stub_buffer1);
310+ EXPECT_EQ(&stub_buffer1, tracker.last_buffer(surf_id0));
311+
312+ EXPECT_EQ(nullptr, tracker.last_buffer(surf_id1));
313+
314+ tracker.track_buffer(surf_id1, &stub_buffer0);
315+ EXPECT_EQ(&stub_buffer0, tracker.last_buffer(surf_id1));
316+}
317+
318+TEST_F(SurfaceTracker, buffers_expire_if_they_overrun_cache_size)
319+{
320+ mf::SurfaceTracker tracker{client_cache_size};
321+
322+ EXPECT_FALSE(tracker.track_buffer(surf_id0, &stub_buffer0));
323+ EXPECT_FALSE(tracker.track_buffer(surf_id0, &stub_buffer1));
324+ EXPECT_FALSE(tracker.track_buffer(surf_id0, &stub_buffer2));
325+ //stub_buffer0 forced out
326+ EXPECT_FALSE(tracker.track_buffer(surf_id0, &stub_buffer3));
327+ //tracker reports its never seen stub_buffer0
328+ EXPECT_FALSE(tracker.track_buffer(surf_id0, &stub_buffer0));
329+ EXPECT_TRUE(tracker.track_buffer(surf_id0, &stub_buffer3));
330+
331+ EXPECT_EQ(&stub_buffer3, tracker.last_buffer(surf_id0));
332+
333+ EXPECT_TRUE(tracker.track_buffer(surf_id0, &stub_buffer3));
334+ EXPECT_TRUE(tracker.track_buffer(surf_id0, &stub_buffer0));
335+ EXPECT_TRUE(tracker.track_buffer(surf_id0, &stub_buffer2));
336+ EXPECT_FALSE(tracker.track_buffer(surf_id0, &stub_buffer1));
337+}
338+
339+TEST_F(SurfaceTracker, buffers_only_affect_associated_surfaces)
340+{
341+ mf::SurfaceTracker tracker{client_cache_size};
342+
343+ EXPECT_FALSE(tracker.track_buffer(surf_id0, &stub_buffer0));
344+ EXPECT_FALSE(tracker.track_buffer(surf_id0, &stub_buffer1));
345+ EXPECT_FALSE(tracker.track_buffer(surf_id0, &stub_buffer2));
346+ EXPECT_EQ(&stub_buffer2, tracker.last_buffer(surf_id0));
347+
348+ EXPECT_FALSE(tracker.track_buffer(surf_id1, &stub_buffer0));
349+ EXPECT_EQ(&stub_buffer2, tracker.last_buffer(surf_id0));
350+ EXPECT_EQ(&stub_buffer0, tracker.last_buffer(surf_id1));
351+
352+ EXPECT_FALSE(tracker.track_buffer(surf_id0, &stub_buffer3));
353+ EXPECT_EQ(&stub_buffer3, tracker.last_buffer(surf_id0));
354+ EXPECT_EQ(&stub_buffer0, tracker.last_buffer(surf_id1));
355+}
356
357=== modified file 'tests/unit-tests/frontend/test_session_mediator.cpp'
358--- tests/unit-tests/frontend/test_session_mediator.cpp 2014-08-15 17:55:26 +0000
359+++ tests/unit-tests/frontend/test_session_mediator.cpp 2014-08-15 17:55:26 +0000
360@@ -20,6 +20,7 @@
361 #include "src/server/frontend/session_mediator.h"
362 #include "src/server/report/null_report_factory.h"
363 #include "src/server/frontend/resource_cache.h"
364+#include "src/server/frontend/surface_tracker.h"
365 #include "src/server/scene/application_session.h"
366 #include "mir/graphics/display.h"
367 #include "mir/graphics/display_configuration.h"
368@@ -244,6 +245,16 @@
369 mp::DRMMagic drm_request;
370 mp::DRMAuthMagicStatus drm_response;
371
372+ mtd::StubBuffer buffer1;
373+ mtd::StubBuffer buffer2;
374+
375+ void toggle_buffers(mg::Buffer* b, std::function<void(mg::Buffer* new_buffer)> complete)
376+ {
377+ if ((!b) || (b == &buffer1))
378+ complete(&buffer2);
379+ if (b == &buffer2)
380+ complete(&buffer1);
381+ }
382 };
383 }
384
385@@ -405,34 +416,22 @@
386 TEST_F(SessionMediator, session_only_sends_mininum_information_for_buffers)
387 {
388 using namespace testing;
389- mtd::StubBuffer buffer1;
390- mtd::StubBuffer buffer2;
391- mp::Buffer buffer_response[3];
392- auto surface = stubbed_session->mock_surface_at(mf::SurfaceId{0});
393- Sequence seq;
394+ mf::SurfaceId surf_id{0};
395+ auto surface = stubbed_session->mock_surface_at(surf_id);
396+ ON_CALL(*surface, swap_buffers(_,_))
397+ .WillByDefault(Invoke(this, &SessionMediator::toggle_buffers));
398
399 //create
400- EXPECT_CALL(*surface, swap_buffers(_, _))
401- .InSequence(seq)
402- .WillOnce(InvokeArgument<1>(&buffer2));
403+ Sequence seq;
404 EXPECT_CALL(*graphics_platform, fill_buffer_package(_, &buffer2, mg::BufferIpcMsgType::full_msg))
405 .InSequence(seq);
406 //swap1
407- EXPECT_CALL(*surface, swap_buffers(&buffer2, _))
408- .InSequence(seq)
409- .WillOnce(InvokeArgument<1>(&buffer1));
410 EXPECT_CALL(*graphics_platform, fill_buffer_package(_, &buffer1, mg::BufferIpcMsgType::full_msg))
411 .InSequence(seq);
412 //swap2
413- EXPECT_CALL(*surface, swap_buffers(&buffer1, _))
414- .InSequence(seq)
415- .WillOnce(InvokeArgument<1>(&buffer2));
416 EXPECT_CALL(*graphics_platform, fill_buffer_package(_, &buffer2, mg::BufferIpcMsgType::update_msg))
417 .InSequence(seq);
418 //swap3
419- EXPECT_CALL(*surface, swap_buffers(&buffer2, _))
420- .InSequence(seq)
421- .WillOnce(InvokeArgument<1>(&buffer1));
422 EXPECT_CALL(*graphics_platform, fill_buffer_package(_, &buffer1, mg::BufferIpcMsgType::update_msg))
423 .InSequence(seq);
424
425@@ -440,57 +439,64 @@
426
427 mediator.create_surface(nullptr, &surface_parameters, &surface_response, null_callback.get());
428 surface_id_request = surface_response.id();
429- mediator.next_buffer(nullptr, &surface_id_request, &buffer_response[0], null_callback.get());
430- mediator.next_buffer(nullptr, &surface_id_request, &buffer_response[1], null_callback.get());
431- mediator.next_buffer(nullptr, &surface_id_request, &buffer_response[2], null_callback.get());
432+ mediator.next_buffer(nullptr, &surface_id_request, &buffer_response, null_callback.get());
433+ mediator.next_buffer(nullptr, &surface_id_request, &buffer_response, null_callback.get());
434+ mediator.next_buffer(nullptr, &surface_id_request, &buffer_response, null_callback.get());
435 mediator.disconnect(nullptr, nullptr, nullptr, null_callback.get());
436 }
437
438 TEST_F(SessionMediator, session_with_multiple_surfaces_only_sends_needed_buffers)
439 {
440 using namespace testing;
441- mtd::StubBuffer buffer[4];
442- mf::SurfaceId first_id{0};
443- mf::SurfaceId second_id{1};
444-
445+ auto surface0 = stubbed_session->mock_surface_at(mf::SurfaceId{0});
446+ auto surface1 = stubbed_session->mock_surface_at(mf::SurfaceId{1});
447+ ON_CALL(*surface0, swap_buffers(_,_))
448+ .WillByDefault(Invoke(this, &SessionMediator::toggle_buffers));
449+ ON_CALL(*surface1, swap_buffers(_,_))
450+ .WillByDefault(Invoke(this, &SessionMediator::toggle_buffers));
451+ EXPECT_CALL(*graphics_platform, fill_buffer_package(_,_,mg::BufferIpcMsgType::full_msg))
452+ .Times(4);
453+ EXPECT_CALL(*graphics_platform, fill_buffer_package(_,_,mg::BufferIpcMsgType::update_msg))
454+ .Times(4);
455+
456+ mediator.connect(nullptr, &connect_parameters, &connection, null_callback.get());
457+
458+ mp::Surface surface_response[2];
459 mp::SurfaceId buffer_request[2];
460- buffer_request[0].set_value(first_id.as_value());
461- buffer_request[1].set_value(second_id.as_value());
462-
463- auto surface1 = stubbed_session->mock_surface_at(first_id);
464- auto surface2 = stubbed_session->mock_surface_at(second_id);
465- EXPECT_CALL(*surface1, swap_buffers(_,_))
466- .WillOnce(InvokeArgument<1>(&buffer[0]))
467- .WillOnce(InvokeArgument<1>(&buffer[1]))
468- .WillOnce(InvokeArgument<1>(&buffer[0]))
469- .WillOnce(InvokeArgument<1>(&buffer[1]));
470- EXPECT_CALL(*surface2, swap_buffers(_,_))
471- .WillOnce(InvokeArgument<1>(&buffer[2]))
472- .WillOnce(InvokeArgument<1>(&buffer[3]))
473- .WillOnce(InvokeArgument<1>(&buffer[2]))
474- .WillOnce(InvokeArgument<1>(&buffer[3]));
475-
476- mediator.connect(nullptr, &connect_parameters, &connection, null_callback.get());
477-
478- mediator.connect(nullptr, &connect_parameters, &connection, null_callback.get());
479-
480- mp::Surface surface_response[2];
481- mp::Buffer buffer_response[6];
482-
483- EXPECT_CALL(*graphics_platform, fill_buffer_package(_,_,mg::BufferIpcMsgType::full_msg))
484- .Times(4);
485- EXPECT_CALL(*graphics_platform, fill_buffer_package(_,_,mg::BufferIpcMsgType::update_msg))
486- .Times(4);
487-
488 mediator.create_surface(nullptr, &surface_parameters, &surface_response[0], null_callback.get());
489 mediator.create_surface(nullptr, &surface_parameters, &surface_response[1], null_callback.get());
490- mediator.next_buffer(nullptr, &buffer_request[0], &buffer_response[0], null_callback.get());
491- mediator.next_buffer(nullptr, &buffer_request[1], &buffer_response[1], null_callback.get());
492- mediator.next_buffer(nullptr, &buffer_request[0], &buffer_response[2], null_callback.get());
493- mediator.next_buffer(nullptr, &buffer_request[1], &buffer_response[3], null_callback.get());
494- mediator.next_buffer(nullptr, &buffer_request[0], &buffer_response[4], null_callback.get());
495- mediator.next_buffer(nullptr, &buffer_request[1], &buffer_response[5], null_callback.get());
496-
497+ buffer_request[0] = surface_response[0].id();
498+ buffer_request[1] = surface_response[1].id();
499+
500+ mediator.next_buffer(nullptr, &buffer_request[0], &buffer_response, null_callback.get());
501+ mediator.next_buffer(nullptr, &buffer_request[1], &buffer_response, null_callback.get());
502+ mediator.next_buffer(nullptr, &buffer_request[0], &buffer_response, null_callback.get());
503+ mediator.next_buffer(nullptr, &buffer_request[1], &buffer_response, null_callback.get());
504+ mediator.next_buffer(nullptr, &buffer_request[0], &buffer_response, null_callback.get());
505+ mediator.next_buffer(nullptr, &buffer_request[1], &buffer_response, null_callback.get());
506+
507+ mediator.disconnect(nullptr, nullptr, nullptr, null_callback.get());
508+}
509+
510+TEST_F(SessionMediator, destroys_tracker_associated_with_destroyed_surface)
511+{
512+ using namespace testing;
513+ mf::SurfaceId first_id{0};
514+ mp::Surface surface_response;
515+
516+ EXPECT_CALL(*graphics_platform, fill_buffer_package(_,_,mg::BufferIpcMsgType::full_msg))
517+ .Times(2);
518+
519+ mediator.connect(nullptr, &connect_parameters, &connection, null_callback.get());
520+ mediator.create_surface(nullptr, &surface_parameters, &surface_response, null_callback.get());
521+ surface_id_request.set_value(first_id.as_value());
522+ mediator.release_surface(nullptr, &surface_id_request, nullptr, null_callback.get());
523+
524+ stubbed_session->last_surface_id = first_id.as_value();
525+
526+ mediator.create_surface(nullptr, &surface_parameters, &surface_response, null_callback.get());
527+ surface_id_request.set_value(first_id.as_value());
528+ mediator.release_surface(nullptr, &surface_id_request, nullptr, null_callback.get());
529 mediator.disconnect(nullptr, nullptr, nullptr, null_callback.get());
530 }
531
532@@ -503,8 +509,8 @@
533 mp::Surface surface_response;
534
535 auto surface1 = stubbed_session->mock_surface_at(mf::SurfaceId{0});
536- EXPECT_CALL(*surface1, swap_buffers(_, _))
537- .WillOnce(InvokeArgument<1>(&buffer));
538+ ON_CALL(*surface1, swap_buffers(_,_))
539+ .WillByDefault(InvokeArgument<1>(&buffer));
540
541 mediator.create_surface(nullptr, &surface_request, &surface_response, null_callback.get());
542 mp::SurfaceId our_surface{surface_response.id()};
543@@ -512,6 +518,7 @@
544 /* Creating a new surface should not affect our surfaces' buffers */
545 EXPECT_CALL(*surface1, swap_buffers(_, _)).Times(0);
546 mediator.create_surface(nullptr, &surface_request, &surface_response, null_callback.get());
547+ Mock::VerifyAndClearExpectations(surface1.get());
548
549 mp::SurfaceId new_surface{surface_response.id()};
550 mp::Buffer buffer_response;
551@@ -520,7 +527,7 @@
552 mediator.next_buffer(nullptr, &new_surface, &buffer_response, null_callback.get());
553
554 /* Getting the next buffer of our surface should post the original */
555- EXPECT_CALL(*surface1, swap_buffers(Eq(&buffer), _)).Times(1);
556+ EXPECT_CALL(*surface1, swap_buffers(Eq(&buffer),_)).Times(1);
557
558 mediator.next_buffer(nullptr, &our_surface, &buffer_response, null_callback.get());
559 mediator.disconnect(nullptr, nullptr, nullptr, null_callback.get());
560@@ -559,8 +566,9 @@
561 mf::SessionMediator mediator{
562 shell, graphics_platform, mock_display_selector,
563 surface_pixel_formats, report,
564- std::make_shared<mtd::NullEventSink>(),
565- resource_cache, stub_screencast, &connector, nullptr};
566+ std::make_shared<mtd::NullEventSink>(), resource_cache,
567+ std::make_shared<mtd::NullScreencast>(),
568+ nullptr, nullptr};
569
570 mediator.connect(nullptr, &connect_parameters, &connection, null_callback.get());
571

Subscribers

People subscribed via source and target branches