Mir

Merge lp:~cemil-azizoglu/mir/improve-raii-take2 into lp:mir

Proposed by Cemil Azizoglu
Status: Work in progress
Proposed branch: lp:~cemil-azizoglu/mir/improve-raii-take2
Merge into: lp:mir
Diff against target: 1613 lines (+370/-596)
16 files modified
src/server/compositor/CMakeLists.txt (+1/-1)
src/server/compositor/buffer_bundle.h (+4/-6)
src/server/compositor/buffer_handle.cpp (+42/-0)
src/server/compositor/buffer_handle.h (+62/-0)
src/server/compositor/buffer_queue.cpp (+37/-38)
src/server/compositor/buffer_queue.h (+4/-4)
src/server/compositor/buffer_stream_surfaces.cpp (+4/-6)
src/server/compositor/temporary_buffers.cpp (+0/-92)
src/server/compositor/temporary_buffers.h (+0/-76)
tests/include/mir_test_doubles/mock_buffer_bundle.h (+5/-5)
tests/integration-tests/compositor/test_swapping_swappers.cpp (+1/-3)
tests/unit-tests/compositor/CMakeLists.txt (+1/-1)
tests/unit-tests/compositor/test_buffer_handle.cpp (+65/-0)
tests/unit-tests/compositor/test_buffer_queue.cpp (+137/-198)
tests/unit-tests/compositor/test_buffer_stream.cpp (+7/-17)
tests/unit-tests/compositor/test_temporary_buffers.cpp (+0/-149)
To merge this branch: bzr merge lp:~cemil-azizoglu/mir/improve-raii-take2
Reviewer Review Type Date Requested Status
Mir development team Pending
Review via email: mp+254097@code.launchpad.net

Description of the change

Improve RAII take 2

To post a comment you must log in.

Unmerged revisions

2354. By Cemil Azizoglu

Merge trunk

2353. By Cemil Azizoglu

Whitespace.

2352. By Cemil Azizoglu

Don't include buffer_bundle.h.

2351. By Cemil Azizoglu

Do away with compositor/snapshot handle subclasses.

2350. By Cemil Azizoglu

Merge trunk.

2349. By Cemil Azizoglu

Use release_callback.

2348. By Cemil Azizoglu

Address review comments (more to do).

2347. By Cemil Azizoglu

Remove auto var.

2346. By Cemil Azizoglu

const &

2345. By Cemil Azizoglu

Fix spacing.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/server/compositor/CMakeLists.txt'
2--- src/server/compositor/CMakeLists.txt 2015-01-21 07:34:50 +0000
3+++ src/server/compositor/CMakeLists.txt 2015-03-25 14:30:39 +0000
4@@ -3,7 +3,6 @@
5
6 default_display_buffer_compositor.cpp
7 default_display_buffer_compositor_factory.cpp
8- temporary_buffers.cpp
9 buffer_stream_factory.cpp
10 buffer_stream_surfaces.cpp
11 gl_renderer.cpp
12@@ -16,6 +15,7 @@
13 compositing_screencast.cpp
14 timeout_frame_dropping_policy_factory.cpp
15 buffer_queue.cpp
16+ buffer_handle.cpp
17 recently_used_cache.cpp
18 )
19
20
21=== modified file 'src/server/compositor/buffer_bundle.h'
22--- src/server/compositor/buffer_bundle.h 2015-01-21 08:53:28 +0000
23+++ src/server/compositor/buffer_bundle.h 2015-03-25 14:30:39 +0000
24@@ -1,5 +1,5 @@
25 /*
26- * Copyright © 2013 Canonical Ltd.
27+ * Copyright © 2013, 2015 Canonical Ltd.
28 *
29 * This program is free software: you can redistribute it and/or modify it
30 * under the terms of the GNU General Public License version 3,
31@@ -29,6 +29,7 @@
32
33 namespace compositor
34 {
35+class BufferHandle;
36
37 class BufferBundle
38 {
39@@ -48,11 +49,8 @@
40 * collisions, all callers should determine user_id
41 * in the same way (e.g. always use "this" pointer).
42 */
43- virtual std::shared_ptr<graphics::Buffer>
44- compositor_acquire(void const* user_id) = 0;
45- virtual void compositor_release(std::shared_ptr<graphics::Buffer> const&) = 0;
46- virtual std::shared_ptr<graphics::Buffer> snapshot_acquire() = 0;
47- virtual void snapshot_release(std::shared_ptr<graphics::Buffer> const&) = 0;
48+ virtual std::shared_ptr<BufferHandle> compositor_acquire(void const* user_id) = 0;
49+ virtual std::shared_ptr<BufferHandle> snapshot_acquire() = 0;
50
51 virtual graphics::BufferProperties properties() const = 0;
52 virtual void allow_framedropping(bool dropping_allowed) = 0;
53
54=== added file 'src/server/compositor/buffer_handle.cpp'
55--- src/server/compositor/buffer_handle.cpp 1970-01-01 00:00:00 +0000
56+++ src/server/compositor/buffer_handle.cpp 2015-03-25 14:30:39 +0000
57@@ -0,0 +1,42 @@
58+/*
59+ * Copyright © 2015 Canonical Ltd.
60+ *
61+ * This program is free software: you can redistribute it and/or modify it
62+ * under the terms of the GNU General Public License version 3,
63+ * as published by the Free Software Foundation.
64+ *
65+ * This program is distributed in the hope that it will be useful,
66+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
67+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
68+ * GNU General Public License for more details.
69+ *
70+ * You should have received a copy of the GNU General Public License
71+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
72+ *
73+ * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com>
74+ */
75+
76+#include "buffer_handle.h"
77+
78+namespace mc = mir::compositor;
79+namespace mg = mir::graphics;
80+
81+mc::BufferHandle::BufferHandle(BufferBundle* bundle,
82+ std::shared_ptr<mg::Buffer> const& buffer,
83+ release_callback const& release)
84+ : buffer_bundle(bundle),
85+ wrapped(buffer),
86+ release_fn(release)
87+{
88+}
89+
90+mc::BufferHandle::~BufferHandle()
91+{
92+ if (release_fn)
93+ release_fn(wrapped.get());
94+}
95+
96+std::shared_ptr<mg::Buffer> mc::BufferHandle::buffer()
97+{
98+ return wrapped;
99+}
100
101=== added file 'src/server/compositor/buffer_handle.h'
102--- src/server/compositor/buffer_handle.h 1970-01-01 00:00:00 +0000
103+++ src/server/compositor/buffer_handle.h 2015-03-25 14:30:39 +0000
104@@ -0,0 +1,62 @@
105+/*
106+ * Copyright © 2015 Canonical Ltd.
107+ *
108+ * This program is free software: you can redistribute it and/or modify it
109+ * under the terms of the GNU General Public License version 3,
110+ * as published by the Free Software Foundation.
111+ *
112+ * This program is distributed in the hope that it will be useful,
113+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
114+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
115+ * GNU General Public License for more details.
116+ *
117+ * You should have received a copy of the GNU General Public License
118+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
119+ *
120+ * Authored by:
121+ * Cemil Azizoglu <cemil.azizoglu@canonical.com>
122+ */
123+
124+#ifndef MIR_BUFFER_HANDLE_H_
125+#define MIR_BUFFER_HANDLE_H_
126+
127+#include <memory>
128+
129+namespace mir
130+{
131+namespace graphics { class Buffer; }
132+
133+namespace compositor
134+{
135+
136+class BufferBundle;
137+
138+typedef std::function<void(graphics::Buffer* buffer)> release_callback;
139+
140+class BufferHandle
141+{
142+public:
143+ explicit BufferHandle(BufferBundle* bundle,
144+ std::shared_ptr<graphics::Buffer> const& buffer,
145+ release_callback const& release);
146+
147+ virtual ~BufferHandle();
148+
149+ std::shared_ptr<graphics::Buffer> buffer();
150+
151+ BufferHandle(BufferHandle&& other);
152+ BufferHandle& operator=(BufferHandle&& other);
153+
154+private:
155+ BufferHandle(BufferHandle const&) = delete;
156+ BufferHandle& operator=(BufferHandle const&) = delete;
157+
158+ BufferBundle* buffer_bundle;
159+ std::shared_ptr<graphics::Buffer> wrapped;
160+ release_callback const release_fn;
161+};
162+
163+}
164+}
165+
166+#endif /* MIR_BUFFER_HANDLE_H_*/
167
168=== modified file 'src/server/compositor/buffer_queue.cpp'
169--- src/server/compositor/buffer_queue.cpp 2015-03-24 16:02:48 +0000
170+++ src/server/compositor/buffer_queue.cpp 2015-03-25 14:30:39 +0000
171@@ -19,6 +19,7 @@
172
173 #include "mir/graphics/graphic_buffer_allocator.h"
174 #include "mir/graphics/buffer_id.h"
175+#include "buffer_handle.h"
176 #include "mir/lockable_callback.h"
177
178 #include <boost/throw_exception.hpp>
179@@ -239,7 +240,7 @@
180 ready_to_composite_queue.push_back(buffer);
181 }
182
183-std::shared_ptr<mg::Buffer>
184+std::shared_ptr<mc::BufferHandle>
185 mc::BufferQueue::compositor_acquire(void const* user_id)
186 {
187 std::unique_lock<decltype(guard)> lock(guard);
188@@ -285,8 +286,27 @@
189
190 buffers_sent_to_compositor.push_back(current_compositor_buffer);
191
192- std::shared_ptr<mg::Buffer> const acquired_buffer =
193- buffer_for(current_compositor_buffer, buffers);
194+ std::shared_ptr<mc::BufferHandle> const acquired_buffer =
195+ std::make_shared<mc::BufferHandle>(
196+ this,
197+ buffer_for(current_compositor_buffer, buffers),
198+ [this](mg::Buffer* b)
199+ {
200+ std::unique_lock<decltype(guard)> lock(guard);
201+
202+ remove(b, buffers_sent_to_compositor);
203+
204+ /* Not ready to release it yet, other compositors still reference this buffer */
205+ if (contains(b, buffers_sent_to_compositor))
206+ return;
207+
208+ if (nbuffers <= 1)
209+ return;
210+
211+ if (current_compositor_buffer != b)
212+ release(b, std::move(lock));
213+ }
214+ );
215
216 if (buffer_to_release)
217 release(buffer_to_release, std::move(lock));
218@@ -294,44 +314,23 @@
219 return acquired_buffer;
220 }
221
222-void mc::BufferQueue::compositor_release(std::shared_ptr<graphics::Buffer> const& buffer)
223-{
224- std::unique_lock<decltype(guard)> lock(guard);
225-
226- if (!remove(buffer.get(), buffers_sent_to_compositor))
227- {
228- BOOST_THROW_EXCEPTION(
229- std::logic_error("unexpected release: buffer was not given to compositor"));
230- }
231-
232- /* Not ready to release it yet, other compositors still reference this buffer */
233- if (contains(buffer.get(), buffers_sent_to_compositor))
234- return;
235-
236- if (nbuffers <= 1)
237- return;
238-
239- if (current_compositor_buffer != buffer.get())
240- release(buffer.get(), std::move(lock));
241-}
242-
243-std::shared_ptr<mg::Buffer> mc::BufferQueue::snapshot_acquire()
244+std::shared_ptr<mc::BufferHandle> mc::BufferQueue::snapshot_acquire()
245 {
246 std::unique_lock<decltype(guard)> lock(guard);
247 pending_snapshots.push_back(current_compositor_buffer);
248- return buffer_for(current_compositor_buffer, buffers);
249-}
250-
251-void mc::BufferQueue::snapshot_release(std::shared_ptr<graphics::Buffer> const& buffer)
252-{
253- std::unique_lock<std::mutex> lock(guard);
254- if (!remove(buffer.get(), pending_snapshots))
255- {
256- BOOST_THROW_EXCEPTION(
257- std::logic_error("unexpected release: no buffers were given to snapshotter"));
258- }
259-
260- snapshot_released.notify_all();
261+
262+ return std::make_shared<mc::BufferHandle>(
263+ this,
264+ buffer_for(current_compositor_buffer, buffers),
265+ [this](mg::Buffer* b)
266+ {
267+ std::unique_lock<std::mutex> lock(guard);
268+
269+ remove(b, pending_snapshots);
270+
271+ snapshot_released.notify_all();
272+ }
273+ );
274 }
275
276 mg::BufferProperties mc::BufferQueue::properties() const
277
278=== modified file 'src/server/compositor/buffer_queue.h'
279--- src/server/compositor/buffer_queue.h 2015-03-24 16:02:48 +0000
280+++ src/server/compositor/buffer_queue.h 2015-03-25 14:30:39 +0000
281@@ -37,6 +37,8 @@
282 namespace compositor
283 {
284
285+class BufferHandle;
286+
287 class BufferQueue : public BufferBundle
288 {
289 public:
290@@ -49,10 +51,8 @@
291
292 void client_acquire(Callback complete) override;
293 void client_release(graphics::Buffer* buffer) override;
294- std::shared_ptr<graphics::Buffer> compositor_acquire(void const* user_id) override;
295- void compositor_release(std::shared_ptr<graphics::Buffer> const& buffer) override;
296- std::shared_ptr<graphics::Buffer> snapshot_acquire() override;
297- void snapshot_release(std::shared_ptr<graphics::Buffer> const& buffer) override;
298+ std::shared_ptr<BufferHandle> compositor_acquire(void const* user_id) override;
299+ std::shared_ptr<BufferHandle> snapshot_acquire() override;
300
301 graphics::BufferProperties properties() const override;
302 void allow_framedropping(bool dropping_allowed) override;
303
304=== modified file 'src/server/compositor/buffer_stream_surfaces.cpp'
305--- src/server/compositor/buffer_stream_surfaces.cpp 2015-01-21 08:53:28 +0000
306+++ src/server/compositor/buffer_stream_surfaces.cpp 2015-03-25 14:30:39 +0000
307@@ -1,5 +1,5 @@
308 /*
309- * Copyright © 2012 Canonical Ltd.
310+ * Copyright © 2012, 2015 Canonical Ltd.
311 *
312 * This program is free software: you can redistribute it and/or modify it
313 * under the terms of the GNU General Public License version 3,
314@@ -19,10 +19,9 @@
315
316 #include "buffer_stream_surfaces.h"
317 #include "buffer_bundle.h"
318+#include "buffer_handle.h"
319 #include "mir/graphics/buffer_properties.h"
320
321-#include "temporary_buffers.h"
322-
323 namespace mc = mir::compositor;
324 namespace mg = mir::graphics;
325 namespace geom = mir::geometry;
326@@ -40,13 +39,12 @@
327 std::shared_ptr<mg::Buffer> mc::BufferStreamSurfaces::lock_compositor_buffer(
328 void const* user_id)
329 {
330- return std::make_shared<mc::TemporaryCompositorBuffer>(
331- buffer_bundle, user_id);
332+ return buffer_bundle->compositor_acquire(user_id)->buffer();
333 }
334
335 std::shared_ptr<mg::Buffer> mc::BufferStreamSurfaces::lock_snapshot_buffer()
336 {
337- return std::make_shared<mc::TemporarySnapshotBuffer>(buffer_bundle);
338+ return buffer_bundle->snapshot_acquire()->buffer();
339 }
340
341 void mc::BufferStreamSurfaces::acquire_client_buffer(
342
343=== removed file 'src/server/compositor/temporary_buffers.cpp'
344--- src/server/compositor/temporary_buffers.cpp 2015-03-24 16:02:48 +0000
345+++ src/server/compositor/temporary_buffers.cpp 1970-01-01 00:00:00 +0000
346@@ -1,92 +0,0 @@
347-/*
348- * Copyright © 2012 Canonical Ltd.
349- *
350- * This program is free software: you can redistribute it and/or modify it
351- * under the terms of the GNU General Public License version 3,
352- * as published by the Free Software Foundation.
353- *
354- * This program is distributed in the hope that it will be useful,
355- * but WITHOUT ANY WARRANTY; without even the implied warranty of
356- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
357- * GNU General Public License for more details.
358- *
359- * You should have received a copy of the GNU General Public License
360- * along with this program. If not, see <http://www.gnu.org/licenses/>.
361- *
362- * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
363- */
364-
365-#include "buffer_bundle.h"
366-#include "temporary_buffers.h"
367-
368-#include <boost/throw_exception.hpp>
369-#include <stdexcept>
370-
371-namespace mc=mir::compositor;
372-namespace mg=mir::graphics;
373-namespace geom=mir::geometry;
374-
375-mc::TemporaryBuffer::TemporaryBuffer(std::shared_ptr<mg::Buffer> const& real_buffer)
376- : buffer(real_buffer)
377-{
378-}
379-
380-mc::TemporaryCompositorBuffer::TemporaryCompositorBuffer(
381- std::shared_ptr<BufferBundle> const& bun, void const* user_id)
382- : TemporaryBuffer(bun->compositor_acquire(user_id)),
383- bundle(bun)
384-{
385-}
386-
387-mc::TemporaryCompositorBuffer::~TemporaryCompositorBuffer()
388-{
389- bundle->compositor_release(buffer);
390-}
391-
392-mc::TemporarySnapshotBuffer::TemporarySnapshotBuffer(
393- std::shared_ptr<BufferBundle> const& bun)
394- : TemporaryBuffer(bun->snapshot_acquire()),
395- bundle(bun)
396-{
397-}
398-
399-mc::TemporarySnapshotBuffer::~TemporarySnapshotBuffer()
400-{
401- bundle->snapshot_release(buffer);
402-}
403-
404-geom::Size mc::TemporaryBuffer::size() const
405-{
406- return buffer->size();
407-}
408-
409-geom::Stride mc::TemporaryBuffer::stride() const
410-{
411- return buffer->stride();
412-}
413-
414-MirPixelFormat mc::TemporaryBuffer::pixel_format() const
415-{
416- return buffer->pixel_format();
417-}
418-
419-mg::BufferID mc::TemporaryBuffer::id() const
420-{
421- return buffer->id();
422-}
423-
424-void mc::TemporaryBuffer::gl_bind_to_texture()
425-{
426- buffer->gl_bind_to_texture();
427-}
428-
429-std::shared_ptr<mg::NativeBuffer> mc::TemporaryBuffer::native_buffer_handle() const
430-{
431- return buffer->native_buffer_handle();
432-}
433-
434-void mc::TemporaryBuffer::write(unsigned char const*, size_t)
435-{
436- BOOST_THROW_EXCEPTION(
437- std::runtime_error("Write to temporary buffer snapshot is ill advised and indicates programmer error"));
438-}
439
440=== removed file 'src/server/compositor/temporary_buffers.h'
441--- src/server/compositor/temporary_buffers.h 2015-03-24 16:02:48 +0000
442+++ src/server/compositor/temporary_buffers.h 1970-01-01 00:00:00 +0000
443@@ -1,76 +0,0 @@
444-/*
445- * Copyright © 2012 Canonical Ltd.
446- *
447- * This program is free software: you can redistribute it and/or modify it
448- * under the terms of the GNU General Public License version 3,
449- * as published by the Free Software Foundation.
450- *
451- * This program is distributed in the hope that it will be useful,
452- * but WITHOUT ANY WARRANTY; without even the implied warranty of
453- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
454- * GNU General Public License for more details.
455- *
456- * You should have received a copy of the GNU General Public License
457- * along with this program. If not, see <http://www.gnu.org/licenses/>.
458- *
459- * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
460- */
461-
462-#ifndef MIR_COMPOSITOR_TEMPORARY_BUFFERS_H_
463-#define MIR_COMPOSITOR_TEMPORARY_BUFFERS_H_
464-
465-#include "mir/graphics/buffer.h"
466-#include "mir/graphics/buffer_id.h"
467-
468-namespace mg = mir::graphics;
469-
470-namespace mir
471-{
472-namespace compositor
473-{
474-
475-class BufferBundle;
476-class BackBufferStrategy;
477-
478-class TemporaryBuffer : public mg::Buffer
479-{
480-public:
481- geometry::Size size() const override;
482- geometry::Stride stride() const override;
483- MirPixelFormat pixel_format() const override;
484- mg::BufferID id() const override;
485- void gl_bind_to_texture() override;
486- std::shared_ptr<mg::NativeBuffer> native_buffer_handle() const override;
487- void write (unsigned char const* data, size_t size) override;
488-
489-protected:
490- explicit TemporaryBuffer(std::shared_ptr<mg::Buffer> const& real_buffer);
491- std::shared_ptr<mg::Buffer> const buffer;
492-};
493-
494-class TemporaryCompositorBuffer : public TemporaryBuffer
495-{
496-public:
497- explicit TemporaryCompositorBuffer(
498- std::shared_ptr<BufferBundle> const& bun, void const* user_id);
499- ~TemporaryCompositorBuffer();
500-
501-private:
502- std::shared_ptr<BufferBundle> const bundle;
503-};
504-
505-class TemporarySnapshotBuffer : public TemporaryBuffer
506-{
507-public:
508- explicit TemporarySnapshotBuffer(
509- std::shared_ptr<BufferBundle> const& bun);
510- ~TemporarySnapshotBuffer();
511-
512-private:
513- std::shared_ptr<BufferBundle> const bundle;
514-};
515-
516-}
517-}
518-
519-#endif /* MIR_COMPOSITOR_TEMPORARY_BUFFERS_H_ */
520
521=== modified file 'tests/include/mir_test_doubles/mock_buffer_bundle.h'
522--- tests/include/mir_test_doubles/mock_buffer_bundle.h 2015-01-21 08:53:28 +0000
523+++ tests/include/mir_test_doubles/mock_buffer_bundle.h 2015-03-25 14:30:39 +0000
524@@ -1,5 +1,5 @@
525 /*
526- * Copyright © 2013 Canonical Ltd.
527+ * Copyright © 2013, 2015 Canonical Ltd.
528 *
529 * This program is free software: you can redistribute it and/or modify it
530 * under the terms of the GNU General Public License version 3,
531@@ -39,10 +39,10 @@
532
533 MOCK_METHOD1(client_acquire, void(std::function<void(graphics::Buffer*)>));
534 MOCK_METHOD1(client_release, void(graphics::Buffer*));
535- MOCK_METHOD1(compositor_acquire, std::shared_ptr<graphics::Buffer>(void const*));
536- MOCK_METHOD1(compositor_release, void(std::shared_ptr<graphics::Buffer> const&));
537- MOCK_METHOD0(snapshot_acquire, std::shared_ptr<graphics::Buffer>());
538- MOCK_METHOD1(snapshot_release, void(std::shared_ptr<graphics::Buffer> const&));
539+ MOCK_METHOD1(compositor_acquire, std::shared_ptr<compositor::BufferHandle>(void const*));
540+ MOCK_METHOD1(compositor_release, void(graphics::Buffer* const));
541+ MOCK_METHOD0(snapshot_acquire, std::shared_ptr<compositor::BufferHandle>());
542+ MOCK_METHOD1(snapshot_release, void(graphics::Buffer* const));
543 MOCK_METHOD1(allow_framedropping, void(bool));
544 MOCK_CONST_METHOD0(properties, graphics::BufferProperties());
545 MOCK_METHOD0(force_client_abort, void());
546
547=== modified file 'tests/integration-tests/compositor/test_swapping_swappers.cpp'
548--- tests/integration-tests/compositor/test_swapping_swappers.cpp 2015-01-21 07:34:50 +0000
549+++ tests/integration-tests/compositor/test_swapping_swappers.cpp 2015-03-25 14:30:39 +0000
550@@ -1,5 +1,5 @@
551 /*
552- * Copyright © 2013 Canonical Ltd.
553+ * Copyright © 2013, 2015 Canonical Ltd.
554 *
555 * This program is free software: you can redistribute it and/or modify
556 * it under the terms of the GNU General Public License version 3 as
557@@ -105,7 +105,6 @@
558 {
559 auto b = switching_bundle->compositor_acquire(0);
560 std::this_thread::yield();
561- switching_bundle->compositor_release(b);
562 }
563 });
564
565@@ -149,7 +148,6 @@
566 {
567 auto b = switching_bundle->compositor_acquire(0);
568 std::this_thread::yield();
569- switching_bundle->compositor_release(b);
570 }
571 });
572
573
574=== modified file 'tests/unit-tests/compositor/CMakeLists.txt'
575--- tests/unit-tests/compositor/CMakeLists.txt 2015-03-24 16:02:48 +0000
576+++ tests/unit-tests/compositor/CMakeLists.txt 2015-03-25 14:30:39 +0000
577@@ -1,7 +1,7 @@
578 list(APPEND UNIT_TEST_SOURCES
579 ${CMAKE_CURRENT_SOURCE_DIR}/test_default_display_buffer_compositor.cpp
580 ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer_stream.cpp
581- ${CMAKE_CURRENT_SOURCE_DIR}/test_temporary_buffers.cpp
582+ ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer_handle.cpp
583 ${CMAKE_CURRENT_SOURCE_DIR}/test_multi_threaded_compositor.cpp
584 ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer_queue.cpp
585 ${CMAKE_CURRENT_SOURCE_DIR}/test_gl_renderer.cpp
586
587=== added file 'tests/unit-tests/compositor/test_buffer_handle.cpp'
588--- tests/unit-tests/compositor/test_buffer_handle.cpp 1970-01-01 00:00:00 +0000
589+++ tests/unit-tests/compositor/test_buffer_handle.cpp 2015-03-25 14:30:39 +0000
590@@ -0,0 +1,65 @@
591+/*
592+ * Copyright © 2015 Canonical Ltd.
593+ *
594+ * This program is free software: you can redistribute it and/or modify
595+ * it under the terms of the GNU General Public License version 3 as
596+ * published by the Free Software Foundation.
597+ *
598+ * This program is distributed in the hope that it will be useful,
599+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
600+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
601+ * GNU General Public License for more details.
602+ *
603+ * You should have received a copy of the GNU General Public License
604+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
605+ *
606+ * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com>
607+ */
608+
609+#include "mir_test_doubles/stub_buffer.h"
610+#include "mir_test_doubles/mock_buffer_bundle.h"
611+#include "src/server/compositor/buffer_handle.h"
612+
613+#include <gtest/gtest.h>
614+
615+namespace mc = mir::compositor;
616+namespace mtd = mir::test::doubles;
617+
618+class BufferHandleTest : public ::testing::Test
619+{
620+protected:
621+ BufferHandleTest()
622+ {
623+ mock_buffer = std::make_shared<mtd::StubBuffer>();
624+ mock_bundle = std::make_shared<mtd::MockBufferBundle>();
625+ }
626+
627+ std::shared_ptr<mtd::StubBuffer> mock_buffer;
628+ std::shared_ptr<mtd::MockBufferBundle> mock_bundle;
629+};
630+
631+TEST_F(BufferHandleTest, can_contain_handout_and_release_compositor_buffer)
632+{
633+ using namespace testing;
634+
635+ std::shared_ptr<mc::BufferHandle> buffer_handle =
636+ std::make_shared<mc::CompositorBufferHandle>(mock_bundle.get(), mock_buffer);
637+
638+ EXPECT_CALL(*mock_bundle, compositor_release(_))
639+ .Times(1);
640+
641+ ASSERT_EQ(buffer_handle->buffer(), mock_buffer);
642+}
643+
644+TEST_F(BufferHandleTest, can_contain_handout_and_release_snapshot_buffer)
645+{
646+ using namespace testing;
647+
648+ std::shared_ptr<mc::BufferHandle> buffer_handle =
649+ std::make_shared<mc::SnapshotBufferHandle>(mock_bundle.get(), mock_buffer);
650+
651+ EXPECT_CALL(*mock_bundle, snapshot_release(_))
652+ .Times(1);
653+
654+ ASSERT_EQ(buffer_handle->buffer(), mock_buffer);
655+}
656
657=== modified file 'tests/unit-tests/compositor/test_buffer_queue.cpp'
658--- tests/unit-tests/compositor/test_buffer_queue.cpp 2015-03-24 16:02:48 +0000
659+++ tests/unit-tests/compositor/test_buffer_queue.cpp 2015-03-25 14:30:39 +0000
660@@ -18,6 +18,7 @@
661 */
662
663 #include "src/server/compositor/buffer_queue.h"
664+#include "src/server/compositor/buffer_handle.h"
665 #include "mir_test_doubles/stub_buffer_allocator.h"
666 #include "mir_test_doubles/stub_buffer.h"
667 #include "mir_test_doubles/stub_frame_dropping_policy_factory.h"
668@@ -155,7 +156,7 @@
669 {
670 while (!done)
671 {
672- bundle.compositor_release(bundle.compositor_acquire(nullptr));
673+ bundle.compositor_acquire(nullptr);
674 std::this_thread::yield();
675 }
676 }
677@@ -165,7 +166,7 @@
678 {
679 while (!done)
680 {
681- bundle.snapshot_release(bundle.snapshot_acquire());
682+ bundle.snapshot_acquire();
683 std::this_thread::yield();
684 }
685 }
686@@ -212,18 +213,18 @@
687 auto next_request = client_acquire_async(*q);
688 EXPECT_THAT(next_request->has_acquired_buffer(), Eq(false));
689
690- auto comp_buffer = q->compositor_acquire(this);
691- auto client_id = handle->id();
692-
693- /* Client and compositor always share the same buffer */
694- EXPECT_THAT(client_id, Eq(comp_buffer->id()));
695-
696- EXPECT_NO_THROW(handle->release_buffer());
697- EXPECT_NO_THROW(q->compositor_release(comp_buffer));
698+ {
699+ auto comp_buffer_handle = q->compositor_acquire(this);
700+ auto client_id = handle->id();
701+
702+ /* Client and compositor always share the same buffer */
703+ EXPECT_THAT(client_id, Eq(comp_buffer_handle->buffer()->id()));
704+
705+ EXPECT_NO_THROW(handle->release_buffer());
706+ }
707
708 /* Simulate a composite pass */
709- comp_buffer = q->compositor_acquire(this);
710- q->compositor_release(comp_buffer);
711+ q->compositor_acquire(this);
712
713 /* The request should now be fullfilled after compositor
714 * released the buffer
715@@ -244,17 +245,17 @@
716 auto buffer = handle->buffer();
717 ASSERT_THAT(buffer->size(), Eq(expect_size));
718
719- /* Client and compositor share the same buffer so
720- * expect the new size
721- */
722- std::shared_ptr<mg::Buffer> comp_buffer;
723- ASSERT_NO_THROW(comp_buffer = q.compositor_acquire(this));
724+ {
725+ /* Client and compositor share the same buffer so
726+ * expect the new size
727+ */
728+ ASSERT_NO_THROW(q.compositor_acquire(this)->buffer());
729
730- EXPECT_THAT(buffer->size(), Eq(expect_size));
731- EXPECT_NO_THROW(q.compositor_release(comp_buffer));
732+ EXPECT_THAT(buffer->size(), Eq(expect_size));
733+ }
734
735 EXPECT_NO_THROW(handle->release_buffer());
736- EXPECT_NO_THROW(q.compositor_release(q.compositor_acquire(this)));
737+ EXPECT_NO_THROW(q.compositor_acquire(this));
738 }
739
740 TEST_F(BufferQueueTest, framedropping_is_disabled_by_default)
741@@ -320,7 +321,7 @@
742 ASSERT_THAT(handle1->has_acquired_buffer(), Eq(false));
743
744 for (int i = 0; i < nbuffers + 1; ++i)
745- q.compositor_release(q.compositor_acquire(this));
746+ q.compositor_acquire(this);
747
748 EXPECT_THAT(handle1->has_acquired_buffer(), Eq(true));
749 EXPECT_THAT(handle2->has_acquired_buffer(), Eq(true));
750@@ -346,15 +347,18 @@
751 auto client_id = handle->id();
752 handle->release_buffer();
753
754- auto comp_buffer = q.compositor_acquire(main_compositor);
755- auto composited_id = comp_buffer->id();
756- q.compositor_release(comp_buffer);
757+ mg::BufferID composited_id;
758+ {
759+ auto comp_buffer_handle = q.compositor_acquire(main_compositor);
760+ composited_id = comp_buffer_handle->buffer()->id();
761+ }
762
763 EXPECT_THAT(composited_id, Eq(client_id));
764
765- comp_buffer = q.compositor_acquire(second_compositor);
766- EXPECT_THAT(composited_id, Eq(comp_buffer->id()));
767- q.compositor_release(comp_buffer);
768+ {
769+ auto comp_buffer_handle = q.compositor_acquire(second_compositor);
770+ EXPECT_THAT(composited_id, Eq(comp_buffer_handle->buffer()->id()));
771+ }
772 }
773 }
774 }
775@@ -389,9 +393,8 @@
776 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
777 handle->release_buffer();
778
779- auto comp_buffer = q.compositor_acquire(this);
780- EXPECT_THAT(client_id, Eq(comp_buffer->id()));
781- q.compositor_release(comp_buffer);
782+ auto comp_buffer_handle = q.compositor_acquire(this);
783+ EXPECT_THAT(client_id, Eq(comp_buffer_handle->buffer()->id()));
784 }
785
786 TEST_F(BufferQueueTest, throws_on_out_of_order_client_release)
787@@ -461,9 +464,8 @@
788 auto client_id = handle->id();
789 ASSERT_NO_THROW(handle->release_buffer());
790
791- auto comp_buffer = q.compositor_acquire(this);
792- EXPECT_THAT(client_id, Eq(comp_buffer->id()));
793- EXPECT_NO_THROW(q.compositor_release(comp_buffer));
794+ auto comp_buffer_handle = q.compositor_acquire(this);
795+ EXPECT_THAT(client_id, Eq(comp_buffer_handle->buffer()->id()));
796 }
797 }
798
799@@ -482,9 +484,8 @@
800 for (int monitor = 0; monitor < 10; monitor++)
801 {
802 void const* user_id = reinterpret_cast<void const*>(monitor);
803- auto comp_buffer = q.compositor_acquire(user_id);
804- EXPECT_THAT(client_id, Eq(comp_buffer->id()));
805- q.compositor_release(comp_buffer);
806+ auto comp_buffer_handle = q.compositor_acquire(user_id);
807+ EXPECT_THAT(client_id, Eq(comp_buffer_handle->buffer()->id()));
808 }
809 }
810 }
811@@ -511,18 +512,16 @@
812 for (int monitor = 0; monitor < 10; monitor++)
813 {
814 void const* user_id = reinterpret_cast<void const*>(monitor);
815- auto comp_buffer = q.compositor_acquire(user_id);
816- ASSERT_EQ(client_id1, comp_buffer->id());
817- q.compositor_release(comp_buffer);
818+ auto comp_buffer_handle = q.compositor_acquire(user_id);
819+ ASSERT_EQ(client_id1, comp_buffer_handle->buffer()->id());
820 }
821
822 // Still many monitors... verify they all get the second frame.
823 for (int monitor = 0; monitor < 10; monitor++)
824 {
825 void const* user_id = reinterpret_cast<void const*>(monitor);
826- auto comp_buffer = q.compositor_acquire(user_id);
827- ASSERT_EQ(client_id2, comp_buffer->id());
828- q.compositor_release(comp_buffer);
829+ auto comp_buffer_handle = q.compositor_acquire(user_id);
830+ ASSERT_EQ(client_id2, comp_buffer_handle->buffer()->id());
831 }
832 }
833 }
834@@ -553,9 +552,8 @@
835
836 for (auto const& client_id : client_release_sequence)
837 {
838- auto comp_buffer = q.compositor_acquire(this);
839- EXPECT_THAT(client_id, Eq(comp_buffer->id()));
840- q.compositor_release(comp_buffer);
841+ auto comp_buffer_handle = q.compositor_acquire(this);
842+ EXPECT_THAT(client_id, Eq(comp_buffer_handle->buffer()->id()));
843 }
844 }
845 }
846@@ -568,10 +566,7 @@
847 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);
848
849 for (int i = 0; i < 100; i++)
850- {
851- auto buffer = q.compositor_acquire(this);
852- q.compositor_release(buffer);
853- }
854+ q.compositor_acquire(this);
855 }
856 }
857
858@@ -600,10 +595,11 @@
859 {
860 while (!done)
861 {
862- std::shared_ptr<mg::Buffer> buffer;
863- EXPECT_NO_THROW(buffer = q.compositor_acquire(this));
864- EXPECT_THAT(buffer, Ne(nullptr));
865- EXPECT_NO_THROW(q.compositor_release(buffer));
866+ {
867+ std::shared_ptr<mg::Buffer> buffer;
868+ EXPECT_NO_THROW(buffer = q.compositor_acquire(this)->buffer());
869+ EXPECT_THAT(buffer, Ne(nullptr));
870+ }
871 std::this_thread::yield();
872 }
873 });
874@@ -634,30 +630,13 @@
875 for (int monitor_id = 0; monitor_id < 10; monitor_id++)
876 {
877 void const* user_id = reinterpret_cast<void const*>(monitor_id);
878- auto buffer = q.compositor_acquire(user_id);
879- ASSERT_THAT(buffer.get(), Eq(last_client_acquired_buffer));
880- q.compositor_release(buffer);
881+ auto buffer_handle = q.compositor_acquire(user_id);
882+ ASSERT_THAT(buffer_handle->buffer().get(), Eq(last_client_acquired_buffer));
883 }
884 }
885 }
886 }
887
888-TEST_F(BufferQueueTest, compositor_release_verifies_parameter)
889-{
890- for (int nbuffers = 1; nbuffers <= max_nbuffers_to_test; ++nbuffers)
891- {
892- mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);
893-
894- auto handle = client_acquire_async(q);
895- ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
896- handle->release_buffer();
897-
898- auto comp_buffer = q.compositor_acquire(this);
899- q.compositor_release(comp_buffer);
900- EXPECT_THROW(q.compositor_release(comp_buffer), std::logic_error);
901- }
902-}
903-
904 /* Regression test for LP#1270964 */
905 TEST_F(BufferQueueTest, compositor_client_interleaved)
906 {
907@@ -673,12 +652,11 @@
908 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
909
910 // in the original bug, compositor would be given the wrong buffer here
911- auto compositor_buffer = q.compositor_acquire(this);
912+ auto compositor_buffer_handle = q.compositor_acquire(this);
913
914- EXPECT_THAT(compositor_buffer->id(), Eq(first_ready_buffer_id));
915+ EXPECT_THAT(compositor_buffer_handle->buffer()->id(), Eq(first_ready_buffer_id));
916
917 handle->release_buffer();
918- q.compositor_release(compositor_buffer);
919 }
920
921 TEST_F(BufferQueueTest, overlapping_compositors_get_different_frames)
922@@ -688,7 +666,7 @@
923 {
924 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);
925
926- std::shared_ptr<mg::Buffer> compositor[2];
927+ std::shared_ptr<mc::BufferHandle> compositor[2];
928
929 auto handle = client_acquire_async(q);
930 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
931@@ -703,19 +681,16 @@
932 for (int i = 0; i < 20; i++)
933 {
934 // Two compositors acquired, and they're always different...
935- ASSERT_THAT(compositor[0]->id(), Ne(compositor[1]->id()));
936+ ASSERT_THAT(compositor[0]->buffer()->id(), Ne(compositor[1]->buffer()->id()));
937
938 // One of the compositors (the oldest one) gets a new buffer...
939 int oldest = i & 1;
940- q.compositor_release(compositor[oldest]);
941+ compositor[oldest].reset();
942 auto handle = client_acquire_async(q);
943 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
944 handle->release_buffer();
945 compositor[oldest] = q.compositor_acquire(this);
946 }
947-
948- q.compositor_release(compositor[0]);
949- q.compositor_release(compositor[1]);
950 }
951 }
952
953@@ -725,11 +700,10 @@
954 {
955 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);
956
957- auto comp_buffer = q.compositor_acquire(this);
958- auto snapshot = q.snapshot_acquire();
959- EXPECT_THAT(snapshot->id(), Eq(comp_buffer->id()));
960- q.compositor_release(comp_buffer);
961- q.snapshot_release(snapshot);
962+ auto comp_buffer_handle = q.compositor_acquire(this);
963+ auto snapshot_handle = q.snapshot_acquire();
964+ EXPECT_THAT(snapshot_handle->buffer()->id(),
965+ Eq(comp_buffer_handle->buffer()->id()));
966 }
967 }
968
969@@ -746,9 +720,10 @@
970 {
971 mc::BufferQueue q(1, allocator, basic_properties, policy_factory);
972
973- auto snapshot = q.snapshot_acquire();
974- q.drop_client_requests();
975- q.snapshot_release(snapshot);
976+ {
977+ auto snapshot = q.snapshot_acquire();
978+ q.drop_client_requests();
979+ }
980
981 auto client = client_acquire_async(q);
982 ASSERT_FALSE(client->has_acquired_buffer());
983@@ -761,36 +736,9 @@
984 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);
985 int const num_snapshots = 100;
986
987- std::shared_ptr<mg::Buffer> buf[num_snapshots];
988+ std::shared_ptr<mc::BufferHandle> buf[num_snapshots];
989 for (int i = 0; i < num_snapshots; i++)
990 buf[i] = q.snapshot_acquire();
991-
992- for (int i = 0; i < num_snapshots; i++)
993- q.snapshot_release(buf[i]);
994- }
995-}
996-
997-TEST_F(BufferQueueTest, snapshot_release_verifies_parameter)
998-{
999- for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)
1000- {
1001- mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);
1002-
1003- auto handle = client_acquire_async(q);
1004- ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
1005- handle->release_buffer();
1006-
1007- auto comp_buffer = q.compositor_acquire(this);
1008- EXPECT_THROW(q.snapshot_release(comp_buffer), std::logic_error);
1009-
1010- handle = client_acquire_async(q);
1011- ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
1012- auto snapshot = q.snapshot_acquire();
1013-
1014- EXPECT_THAT(snapshot->id(), Eq(comp_buffer->id()));
1015- EXPECT_THAT(snapshot->id(), Ne(handle->id()));
1016- EXPECT_NO_THROW(q.snapshot_release(snapshot));
1017- EXPECT_THROW(q.snapshot_release(snapshot), std::logic_error);
1018 }
1019 }
1020
1021@@ -892,8 +840,7 @@
1022 {
1023 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1024
1025- auto buf = q.compositor_acquire(this);
1026- q.compositor_release(buf);
1027+ q.compositor_acquire(this);
1028
1029 if (frame == compose_frames)
1030 {
1031@@ -950,8 +897,7 @@
1032 {
1033 std::this_thread::sleep_for(frame_time);
1034 sync.lock();
1035- auto buf = q.compositor_acquire(this);
1036- q.compositor_release(buf);
1037+ q.compositor_acquire(this);
1038 sync.unlock();
1039
1040 if (frame == compose_frames)
1041@@ -1007,9 +953,8 @@
1042 ASSERT_THAT(expect_size, Eq(buffer->size()));
1043 handle->release_buffer();
1044
1045- auto comp_buffer = q.compositor_acquire(this);
1046- ASSERT_THAT(expect_size, Eq(comp_buffer->size()));
1047- q.compositor_release(comp_buffer);
1048+ auto comp_buffer_handle = q.compositor_acquire(this);
1049+ ASSERT_THAT(expect_size, Eq(comp_buffer_handle->buffer()->size()));
1050 }
1051 }
1052 }
1053@@ -1065,25 +1010,22 @@
1054 width += dx;
1055 height += dy;
1056
1057- auto buffer = q.compositor_acquire(this);
1058+ auto buffer_handle = q.compositor_acquire(this);
1059
1060 // Verify the compositor gets resized buffers, eventually
1061- ASSERT_THAT(buffer->size(), Eq(expect_size));
1062+ ASSERT_THAT(buffer_handle->buffer()->size(), Eq(expect_size));
1063
1064 // Verify the compositor gets buffers with *contents*, ie. that
1065 // they have not been resized prematurely and are empty.
1066- ASSERT_THAT(history[consume], Eq(buffer->id()));
1067-
1068- q.compositor_release(buffer);
1069+ ASSERT_THAT(history[consume], Eq(buffer_handle->buffer()->id()));
1070 }
1071
1072 // Verify the final buffer size sticks
1073 const geom::Size final_size{width - dx, height - dy};
1074 for (int unchanging = 0; unchanging < 100; ++unchanging)
1075 {
1076- auto buffer = q.compositor_acquire(this);
1077- ASSERT_THAT(buffer->size(), Eq(final_size));
1078- q.compositor_release(buffer);
1079+ auto buffer_handle = q.compositor_acquire(this);
1080+ ASSERT_THAT(buffer_handle->buffer()->size(), Eq(final_size));
1081 }
1082 }
1083 }
1084@@ -1103,7 +1045,7 @@
1085
1086 // Start rendering one (don't finish)
1087 auto d = q.compositor_acquire(nullptr);
1088- ASSERT_EQ(first, d.get());
1089+ ASSERT_EQ(first, d->buffer().get());
1090
1091 auto second = client_acquire_sync(q);
1092 q.client_release(second);
1093@@ -1121,8 +1063,6 @@
1094 // will produce another frame.
1095 if (end->has_acquired_buffer())
1096 ASSERT_NE(second, end->buffer());
1097-
1098- q.compositor_release(d);
1099 }
1100 }
1101
1102@@ -1151,8 +1091,8 @@
1103 for (int n = 0; n < nbuffers-1; ++n)
1104 {
1105 auto c = q.compositor_acquire(nullptr);
1106- compositing.push_back(c);
1107- ASSERT_EQ(order[n], c.get());
1108+ compositing.push_back(c->buffer());
1109+ ASSERT_EQ(order[n], c->buffer().get());
1110 }
1111
1112 // Ensure it's not the newest frame that gets dropped to satisfy the
1113@@ -1249,12 +1189,12 @@
1114 auto const handle = client_acquire_async(q);
1115 EXPECT_THAT(handle->has_acquired_buffer(), Eq(false));
1116
1117- auto buf = q.compositor_acquire(this);
1118- q.compositor_release(buf);
1119+ q.compositor_acquire(this);
1120
1121- buf = q.compositor_acquire(this);
1122- EXPECT_THAT(buf->size(), Eq(new_size));
1123- q.compositor_release(buf);
1124+ {
1125+ auto buf_handle = q.compositor_acquire(this);
1126+ EXPECT_THAT(buf_handle->buffer()->size(), Eq(new_size));
1127+ }
1128 }
1129
1130 TEST_F(BufferQueueTest, double_buffered_client_is_not_blocked_prematurely)
1131@@ -1268,19 +1208,19 @@
1132 q.client_release(client_acquire_sync(q));
1133 auto b = q.compositor_acquire(this);
1134
1135- ASSERT_NE(a.get(), b.get());
1136+ ASSERT_NE(a->buffer(), b->buffer());
1137
1138- q.compositor_release(a);
1139+ a.reset();
1140 q.client_release(client_acquire_sync(q));
1141
1142- q.compositor_release(b);
1143+ b.reset();
1144
1145 /*
1146 * Update to the original test case; This additional compositor acquire
1147 * represents the fixing of LP: #1395581 in the compositor logic.
1148 */
1149 if (q.buffers_ready_for_compositor(this))
1150- q.compositor_release(q.compositor_acquire(this));
1151+ q.compositor_acquire(this);
1152
1153 auto handle = client_acquire_async(q);
1154 // With the fix, a buffer will be available instantaneously:
1155@@ -1310,27 +1250,27 @@
1156
1157 ASSERT_NE(a.get(), b.get());
1158
1159- q.compositor_release(a);
1160+ a.reset();
1161
1162 auto w = client_acquire_async(q);
1163 ASSERT_TRUE(w->has_acquired_buffer());
1164 w->release_buffer();
1165
1166- q.compositor_release(b);
1167+ b.reset();
1168
1169 /*
1170 * Update to the original test case; This additional compositor acquire
1171 * represents the fixing of LP: #1395581 in the compositor logic.
1172 */
1173 if (q.buffers_ready_for_compositor(this))
1174- q.compositor_release(q.compositor_acquire(this));
1175+ q.compositor_acquire(this);
1176
1177 auto z = client_acquire_async(q);
1178 ASSERT_TRUE(z->has_acquired_buffer());
1179 z->release_buffer();
1180
1181- q.compositor_release(q.compositor_acquire(this));
1182- q.compositor_release(q.compositor_acquire(this));
1183+ q.compositor_acquire(this);
1184+ q.compositor_acquire(this);
1185 }
1186 }
1187
1188@@ -1353,11 +1293,11 @@
1189 auto b = q.compositor_acquire(this);
1190
1191 // Release frame 1
1192- q.compositor_release(a);
1193+ a.reset();
1194 // Produce frame 3
1195 q.client_release(client_acquire_sync(q));
1196 // Release frame 2
1197- q.compositor_release(b);
1198+ b.reset();
1199
1200 // Verify frame 3 is ready for the first compositor
1201 ASSERT_THAT(q.buffers_ready_for_compositor(this), Ge(1));
1202@@ -1366,8 +1306,6 @@
1203 // Verify frame 3 is ready for a second compositor
1204 int const that = 0;
1205 ASSERT_THAT(q.buffers_ready_for_compositor(&that), Ge(1));
1206-
1207- q.compositor_release(c);
1208 }
1209 }
1210
1211@@ -1394,7 +1332,7 @@
1212 for (int m = 0; m < nmonitors; ++m)
1213 {
1214 ASSERT_EQ(1, q.buffers_ready_for_compositor(&monitor[m]));
1215- q.compositor_release(q.compositor_acquire(&monitor[m]));
1216+ q.compositor_acquire(&monitor[m]);
1217 ASSERT_EQ(0, q.buffers_ready_for_compositor(&monitor[m]));
1218 }
1219 }
1220@@ -1410,11 +1348,11 @@
1221 mc::BufferQueue q{nbuffers, allocator, basic_properties, policy_factory};
1222 q.allow_framedropping(true);
1223
1224- std::vector<std::shared_ptr<mg::Buffer>> buffers;
1225+ std::vector<std::shared_ptr<mc::BufferHandle>> buffer_handles;
1226
1227 /* The client can never own this acquired buffer */
1228- auto comp_buffer = q.compositor_acquire(this);
1229- buffers.push_back(comp_buffer);
1230+ auto comp_buffer_handle = q.compositor_acquire(this);
1231+ buffer_handles.push_back(comp_buffer_handle);
1232
1233 /* Let client release all possible buffers so they go into
1234 * the ready queue
1235@@ -1424,14 +1362,14 @@
1236 auto handle = client_acquire_async(q);
1237 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
1238 /* Check the client never got the compositor buffer acquired above */
1239- ASSERT_THAT(handle->id(), Ne(comp_buffer->id()));
1240+ ASSERT_THAT(handle->id(), Ne(comp_buffer_handle->buffer()->id()));
1241 handle->release_buffer();
1242 }
1243
1244 /* Let the compositor acquire all ready buffers */
1245 for (int i = 0; i < nbuffers; ++i)
1246 {
1247- buffers.push_back(q.compositor_acquire(this));
1248+ buffer_handles.push_back(q.compositor_acquire(this));
1249 }
1250
1251 /* At this point the queue has 0 free buffers and 0 ready buffers
1252@@ -1444,10 +1382,9 @@
1253 if (!handle->has_acquired_buffer())
1254 {
1255 /* Release compositor buffers so that the client can get one */
1256- for (auto const& buffer : buffers)
1257- {
1258- q.compositor_release(buffer);
1259- }
1260+ for (auto& buf_handle : buffer_handles)
1261+ buf_handle.reset();
1262+
1263 EXPECT_THAT(handle->has_acquired_buffer(), Eq(true));
1264 }
1265 }
1266@@ -1470,7 +1407,7 @@
1267 {
1268 while (!done)
1269 {
1270- auto buffer = q.compositor_acquire(this);
1271+ auto buffer_handle = q.compositor_acquire(this);
1272
1273 {
1274 std::unique_lock<std::mutex> lock(client_buffer_guard);
1275@@ -1480,12 +1417,11 @@
1276 time_for_client_to_acquire,
1277 [&]()->bool{ return client_buffer; }))
1278 {
1279- ASSERT_THAT(buffer->id(), Ne(client_buffer->id()));
1280+ ASSERT_THAT(buffer_handle->buffer()->id(), Ne(client_buffer->id()));
1281 }
1282 }
1283
1284 std::this_thread::yield();
1285- q.compositor_release(buffer);
1286 }
1287 });
1288
1289@@ -1521,23 +1457,24 @@
1290 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
1291
1292 auto client_id = handle->id();
1293- std::vector<std::shared_ptr<mg::Buffer>> buffers;
1294+ std::vector<std::shared_ptr<mc::BufferHandle>> buffer_handles;
1295 for (int j = 0; j < nbuffers; j++)
1296 {
1297- auto buffer = q.compositor_acquire(this);
1298- ASSERT_THAT(client_id, Ne(buffer->id()));
1299- buffers.push_back(buffer);
1300+ auto buffer_handle = q.compositor_acquire(this);
1301+ ASSERT_THAT(client_id, Ne(buffer_handle->buffer()->id()));
1302+ buffer_handles.push_back(buffer_handle);
1303 }
1304
1305- for (auto const& buffer: buffers)
1306- q.compositor_release(buffer);
1307+ for (auto& buf_handle: buffer_handles)
1308+ buf_handle.reset();
1309
1310 handle->release_buffer();
1311
1312- /* Flush out one ready buffer */
1313- auto buffer = q.compositor_acquire(this);
1314- ASSERT_THAT(client_id, Eq(buffer->id()));
1315- q.compositor_release(buffer);
1316+ {
1317+ /* Flush out one ready buffer */
1318+ auto buffer_handle = q.compositor_acquire(this);
1319+ ASSERT_THAT(client_id, Eq(buffer_handle->buffer()->id()));
1320+ }
1321 }
1322 }
1323 }
1324@@ -1569,11 +1506,9 @@
1325
1326 /* Have a second compositor advance the current compositor buffer at least twice */
1327 for (int acquires = 0; acquires < nbuffers; ++acquires)
1328- {
1329- auto comp_buffer = q.compositor_acquire(second_compositor);
1330- q.compositor_release(comp_buffer);
1331- }
1332- q.compositor_release(comp_buffer1);
1333+ q.compositor_acquire(second_compositor);
1334+
1335+ comp_buffer1.reset();
1336
1337 /* An async client should still be able to cycle through all the available buffers */
1338 std::atomic<bool> done(false);
1339@@ -1666,8 +1601,7 @@
1340 q.client_release(client_acquire_sync(q));
1341 }};
1342
1343- auto b = q.compositor_acquire(this);
1344- q.compositor_release(b);
1345+ q.compositor_acquire(this);
1346 }
1347
1348 TEST_F(BufferQueueTest, first_user_is_recorded)
1349@@ -1676,9 +1610,10 @@
1350 {
1351 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);
1352
1353- auto comp = q.compositor_acquire(this);
1354- EXPECT_TRUE(q.is_a_current_buffer_user(this));
1355- q.compositor_release(comp);
1356+ {
1357+ auto comp = q.compositor_acquire(this);
1358+ EXPECT_TRUE(q.is_a_current_buffer_user(this));
1359+ }
1360 }
1361 }
1362
1363@@ -1708,12 +1643,15 @@
1364
1365 q.drop_old_buffers();
1366
1367- auto comp = q.compositor_acquire(this);
1368- ASSERT_THAT(comp->id(), Eq(handle2->id()));
1369- q.compositor_release(comp);
1370+ {
1371+ auto buffer_handle = q.compositor_acquire(this);
1372+ ASSERT_THAT(buffer_handle->buffer()->id(), Eq(handle2->id()));
1373+ }
1374
1375- comp = q.compositor_acquire(this);
1376- ASSERT_THAT(comp->id(), Eq(handle2->id()));
1377+ {
1378+ auto buffer_handle = q.compositor_acquire(this);
1379+ ASSERT_THAT(buffer_handle->buffer()->id(), Eq(handle2->id()));
1380+ }
1381 }
1382
1383 TEST_F(BufferQueueTest, gives_new_compositor_the_newest_buffer_after_dropping_old_buffers)
1384@@ -1727,9 +1665,10 @@
1385 ASSERT_THAT(handle1->has_acquired_buffer(), Eq(true));
1386 handle1->release_buffer();
1387
1388- auto comp = q.compositor_acquire(this);
1389- ASSERT_THAT(comp->id(), Eq(handle1->id()));
1390- q.compositor_release(comp);
1391+ {
1392+ auto buffer_handle = q.compositor_acquire(this);
1393+ ASSERT_THAT(buffer_handle->buffer()->id(), Eq(handle1->id()));
1394+ }
1395
1396 auto handle2 = client_acquire_async(q);
1397 ASSERT_THAT(handle2->has_acquired_buffer(), Eq(true));
1398@@ -1737,6 +1676,6 @@
1399
1400 q.drop_old_buffers();
1401
1402- auto comp2 = q.compositor_acquire(new_compositor_id);
1403- ASSERT_THAT(comp2->id(), Eq(handle2->id()));
1404+ auto buffer_handle2 = q.compositor_acquire(new_compositor_id);
1405+ ASSERT_THAT(buffer_handle2->buffer()->id(), Eq(handle2->id()));
1406 }
1407
1408=== modified file 'tests/unit-tests/compositor/test_buffer_stream.cpp'
1409--- tests/unit-tests/compositor/test_buffer_stream.cpp 2015-01-21 07:34:50 +0000
1410+++ tests/unit-tests/compositor/test_buffer_stream.cpp 2015-03-25 14:30:39 +0000
1411@@ -1,5 +1,5 @@
1412 /*
1413- * Copyright © 2012 Canonical Ltd.
1414+ * Copyright © 2012, 2015 Canonical Ltd.
1415 *
1416 * This program is free software: you can redistribute it and/or modify
1417 * it under the terms of the GNU General Public License version 3 as
1418@@ -21,6 +21,7 @@
1419 #include "mir_test_doubles/stub_buffer.h"
1420 #include "mir_test_doubles/mock_buffer_bundle.h"
1421 #include "mir_test/gmock_fixes.h"
1422+#include "src/server/compositor/buffer_handle.h"
1423
1424 #include <gmock/gmock.h>
1425 #include <gtest/gtest.h>
1426@@ -92,28 +93,17 @@
1427 mc::BufferStreamSurfaces buffer_stream(mock_bundle);
1428 }
1429
1430-TEST_F(BufferStreamTest, get_buffer_for_compositor_handles_resources)
1431-{
1432- using namespace testing;
1433-
1434- EXPECT_CALL(*mock_bundle, compositor_acquire(_))
1435- .Times(1)
1436- .WillOnce(Return(mock_buffer));
1437- EXPECT_CALL(*mock_bundle, compositor_release(_))
1438- .Times(1);
1439-
1440- mc::BufferStreamSurfaces buffer_stream(mock_bundle);
1441-
1442- buffer_stream.lock_compositor_buffer(0);
1443-}
1444-
1445 TEST_F(BufferStreamTest, get_buffer_for_compositor_can_lock)
1446 {
1447 using namespace testing;
1448
1449+ std::shared_ptr<mc::BufferHandle> stub_handle =
1450+ std::make_shared<mc::CompositorBufferHandle>(mock_bundle.get(), mock_buffer);
1451+
1452 EXPECT_CALL(*mock_bundle, compositor_acquire(_))
1453 .Times(1)
1454- .WillOnce(Return(mock_buffer));
1455+ .WillOnce(ReturnPointee(&stub_handle));
1456+
1457 EXPECT_CALL(*mock_bundle, compositor_release(_))
1458 .Times(1);
1459
1460
1461=== removed file 'tests/unit-tests/compositor/test_temporary_buffers.cpp'
1462--- tests/unit-tests/compositor/test_temporary_buffers.cpp 2015-01-21 07:34:50 +0000
1463+++ tests/unit-tests/compositor/test_temporary_buffers.cpp 1970-01-01 00:00:00 +0000
1464@@ -1,149 +0,0 @@
1465-/*
1466- * Copyright © 2012 Canonical Ltd.
1467- *
1468- * This program is free software: you can redistribute it and/or modify
1469- * it under the terms of the GNU General Public License version 3 as
1470- * published by the Free Software Foundation.
1471- *
1472- * This program is distributed in the hope that it will be useful,
1473- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1474- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1475- * GNU General Public License for more details.
1476- *
1477- * You should have received a copy of the GNU General Public License
1478- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1479- *
1480- * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
1481- */
1482-
1483-#include "src/server/compositor/temporary_buffers.h"
1484-#include "mir_test_doubles/mock_buffer.h"
1485-#include "mir_test_doubles/stub_buffer.h"
1486-#include "mir_test_doubles/mock_buffer_bundle.h"
1487-#include <gtest/gtest.h>
1488-#include <stdexcept>
1489-
1490-namespace mtd=mir::test::doubles;
1491-namespace mg = mir::graphics;
1492-namespace mc=mir::compositor;
1493-namespace geom=mir::geometry;
1494-
1495-namespace
1496-{
1497-class TemporaryTestBuffer : public mc::TemporaryBuffer
1498-{
1499-public:
1500- TemporaryTestBuffer(const std::shared_ptr<mg::Buffer>& buf)
1501- : TemporaryBuffer(buf)
1502- {
1503- }
1504-};
1505-
1506-class TemporaryBuffersTest : public ::testing::Test
1507-{
1508-public:
1509- TemporaryBuffersTest()
1510- : buffer_size{1024, 768},
1511- buffer_stride{1024},
1512- buffer_pixel_format{mir_pixel_format_abgr_8888},
1513- mock_buffer{std::make_shared<testing::NiceMock<mtd::MockBuffer>>(
1514- buffer_size, buffer_stride, buffer_pixel_format)},
1515- mock_bundle{std::make_shared<testing::NiceMock<mtd::MockBufferBundle>>()}
1516- {
1517- using namespace testing;
1518-
1519- ON_CALL(*mock_bundle, client_acquire(_))
1520- .WillByDefault(InvokeArgument<0>(mock_buffer.get()));
1521- ON_CALL(*mock_bundle, compositor_acquire(_))
1522- .WillByDefault(Return(mock_buffer));
1523- }
1524-
1525- geom::Size const buffer_size;
1526- geom::Stride const buffer_stride;
1527- MirPixelFormat const buffer_pixel_format;
1528- std::shared_ptr<mtd::MockBuffer> const mock_buffer;
1529- std::shared_ptr<mtd::MockBufferBundle> mock_bundle;
1530-};
1531-}
1532-
1533-TEST_F(TemporaryBuffersTest, compositor_buffer_acquires_and_releases)
1534-{
1535- using namespace testing;
1536- EXPECT_CALL(*mock_bundle, compositor_acquire(_))
1537- .WillOnce(Return(mock_buffer));
1538- EXPECT_CALL(*mock_bundle, compositor_release(_))
1539- .Times(1);
1540-
1541- mc::TemporaryCompositorBuffer proxy_buffer(mock_bundle, 0);
1542-}
1543-
1544-TEST_F(TemporaryBuffersTest, snapshot_buffer_acquires_and_releases)
1545-{
1546- using namespace testing;
1547- EXPECT_CALL(*mock_bundle, snapshot_acquire())
1548- .WillOnce(Return(mock_buffer));
1549- EXPECT_CALL(*mock_bundle, snapshot_release(_))
1550- .Times(1);
1551-
1552- mc::TemporarySnapshotBuffer proxy_buffer(mock_bundle);
1553-}
1554-
1555-TEST_F(TemporaryBuffersTest, base_test_size)
1556-{
1557- TemporaryTestBuffer proxy_buffer(mock_buffer);
1558- EXPECT_CALL(*mock_buffer, size())
1559- .Times(1);
1560-
1561- geom::Size size;
1562- size = proxy_buffer.size();
1563- EXPECT_EQ(buffer_size, size);
1564-}
1565-
1566-TEST_F(TemporaryBuffersTest, base_test_stride)
1567-{
1568- TemporaryTestBuffer proxy_buffer(mock_buffer);
1569- EXPECT_CALL(*mock_buffer, stride())
1570- .Times(1);
1571-
1572- geom::Stride stride;
1573- stride = proxy_buffer.stride();
1574- EXPECT_EQ(buffer_stride, stride);
1575-}
1576-
1577-TEST_F(TemporaryBuffersTest, base_test_pixel_format)
1578-{
1579- TemporaryTestBuffer proxy_buffer(mock_buffer);
1580- EXPECT_CALL(*mock_buffer, pixel_format())
1581- .Times(1);
1582-
1583- MirPixelFormat pixel_format;
1584- pixel_format = proxy_buffer.pixel_format();
1585- EXPECT_EQ(buffer_pixel_format, pixel_format);
1586-}
1587-
1588-TEST_F(TemporaryBuffersTest, base_gl_bind_to_texture)
1589-{
1590- TemporaryTestBuffer proxy_buffer(mock_buffer);
1591- EXPECT_CALL(*mock_buffer, gl_bind_to_texture())
1592- .Times(1);
1593-
1594- proxy_buffer.gl_bind_to_texture();
1595-}
1596-
1597-TEST_F(TemporaryBuffersTest, base_test_id)
1598-{
1599- TemporaryTestBuffer proxy_buffer(mock_buffer);
1600- EXPECT_CALL(*mock_buffer, id())
1601- .Times(1);
1602-
1603- proxy_buffer.id();
1604-}
1605-
1606-TEST_F(TemporaryBuffersTest, base_test_native_buffer_handle)
1607-{
1608- TemporaryTestBuffer proxy_buffer(mock_buffer);
1609- EXPECT_CALL(*mock_buffer, native_buffer_handle())
1610- .Times(1);
1611-
1612- proxy_buffer.native_buffer_handle();
1613-}

Subscribers

People subscribed via source and target branches