Mir

Merge lp:~cemil-azizoglu/mir/buffer_handle into lp:mir

Proposed by Cemil Azizoglu
Status: Work in progress
Proposed branch: lp:~cemil-azizoglu/mir/buffer_handle
Merge into: lp:mir
Diff against target: 1085 lines (+308/-306)
23 files modified
examples/render_overlays.cpp (+8/-0)
include/platform/mir/graphics/buffer_handle.h (+61/-0)
include/platform/mir/graphics/renderable.h (+7/-0)
src/include/server/mir/compositor/buffer_stream.h (+4/-3)
src/platform/graphics/CMakeLists.txt (+1/-0)
src/platform/graphics/buffer_handle.cpp (+66/-0)
src/platform/symbols.map (+4/-0)
src/platforms/mesa/server/display_buffer.cpp (+42/-43)
src/platforms/mesa/server/display_buffer.h (+3/-2)
src/server/compositor/CMakeLists.txt (+0/-1)
src/server/compositor/buffer_bundle.h (+3/-6)
src/server/compositor/buffer_queue.cpp (+43/-39)
src/server/compositor/buffer_queue.h (+7/-5)
src/server/compositor/buffer_stream_surfaces.cpp (+4/-7)
src/server/compositor/buffer_stream_surfaces.h (+5/-3)
src/server/compositor/default_display_buffer_compositor.cpp (+2/-4)
src/server/compositor/temporary_buffers.cpp (+0/-97)
src/server/compositor/temporary_buffers.h (+0/-77)
src/server/graphics/software_cursor.cpp (+8/-0)
src/server/input/android/android_pointer_controller.cpp (+4/-3)
src/server/input/touchspot_controller.cpp (+8/-1)
src/server/scene/basic_surface.cpp (+28/-14)
src/server/scene/basic_surface.h (+0/-1)
To merge this branch: bzr merge lp:~cemil-azizoglu/mir/buffer_handle
Reviewer Review Type Date Requested Status
Mir development team Pending
Review via email: mp+253873@code.launchpad.net

Description of the change

Introduce BufferHandle.

To post a comment you must log in.
lp:~cemil-azizoglu/mir/buffer_handle updated
2415. By Cemil Azizoglu

Remove forgotten member

2416. By Cemil Azizoglu

whitespace

2417. By Cemil Azizoglu

- Move BufferHAndle from mir::compositor to mir::graphics namespace.
- Also Move buffer_handle.cpp under platform.

2418. By Cemil Azizoglu

Minimally working implementation.

2419. By Cemil Azizoglu

Software cursor

2420. By Cemil Azizoglu

touchspot fix

2421. By Cemil Azizoglu

Minor fixes

2422. By Cemil Azizoglu

merge trunk.

Unmerged revisions

2422. By Cemil Azizoglu

merge trunk.

2421. By Cemil Azizoglu

Minor fixes

2420. By Cemil Azizoglu

touchspot fix

2419. By Cemil Azizoglu

Software cursor

2418. By Cemil Azizoglu

Minimally working implementation.

2417. By Cemil Azizoglu

- Move BufferHAndle from mir::compositor to mir::graphics namespace.
- Also Move buffer_handle.cpp under platform.

2416. By Cemil Azizoglu

whitespace

2415. By Cemil Azizoglu

Remove forgotten member

2414. By Cemil Azizoglu

Add buffer_handle() interface to Renderable.

2413. By Cemil Azizoglu

- Remove temporary buffers from the filesystem
- Do away with {compositor|snapshot}_release

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'examples/render_overlays.cpp'
2--- examples/render_overlays.cpp 2015-03-30 03:20:27 +0000
3+++ examples/render_overlays.cpp 2015-03-30 20:21:06 +0000
4@@ -25,6 +25,7 @@
5 #include "mir/graphics/graphic_buffer_allocator.h"
6 #include "mir/graphics/buffer_properties.h"
7 #include "mir_image.h"
8+#include "mir/graphics/buffer_handle.h"
9
10 #include <chrono>
11 #include <csignal>
12@@ -33,6 +34,7 @@
13 namespace mg=mir::graphics;
14 namespace mo=mir::options;
15 namespace geom=mir::geometry;
16+namespace mc=mir::compositor;
17
18 namespace
19 {
20@@ -142,6 +144,12 @@
21 return client->last_rendered();
22 }
23
24+ mg::BufferHandle buffer_handle() const override
25+ {
26+ mg::BufferHandle handle;
27+ return handle;
28+ }
29+
30 geom::Rectangle screen_position() const override
31 {
32 return position;
33
34=== added file 'include/platform/mir/graphics/buffer_handle.h'
35--- include/platform/mir/graphics/buffer_handle.h 1970-01-01 00:00:00 +0000
36+++ include/platform/mir/graphics/buffer_handle.h 2015-03-30 20:21:06 +0000
37@@ -0,0 +1,61 @@
38+/*
39+ * Copyright © 2015 Canonical Ltd.
40+ *
41+ * This program is free software: you can redistribute it and/or modify it
42+ * under the terms of the GNU General Public License version 3,
43+ * as published by the Free Software Foundation.
44+ *
45+ * This program is distributed in the hope that it will be useful,
46+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
47+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
48+ * GNU General Public License for more details.
49+ *
50+ * You should have received a copy of the GNU General Public License
51+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
52+ *
53+ * Authored by:
54+ * Cemil Azizoglu <cemil.azizoglu@canonical.com>
55+ */
56+
57+#ifndef MIR_BUFFER_HANDLE_H_
58+#define MIR_BUFFER_HANDLE_H_
59+
60+#include <memory>
61+
62+namespace mir
63+{
64+namespace graphics
65+{
66+
67+class Buffer;
68+
69+typedef std::function<void(Buffer* buffer)> ReleaseCallback;
70+
71+class BufferHandle
72+{
73+public:
74+ explicit BufferHandle(
75+ std::shared_ptr<Buffer> const& buffer,
76+ ReleaseCallback const& release);
77+
78+ BufferHandle(BufferHandle&& other);
79+ BufferHandle& operator=(BufferHandle&& other);
80+ BufferHandle() = default;
81+
82+ ~BufferHandle();
83+
84+ std::shared_ptr<Buffer> buffer();
85+ bool operator!();
86+
87+private:
88+ BufferHandle(BufferHandle const&) = delete;
89+ BufferHandle& operator=(BufferHandle const&) = delete;
90+
91+ std::shared_ptr<Buffer> wrapped;
92+ ReleaseCallback release_fn;
93+};
94+
95+}
96+}
97+
98+#endif /* MIR_BUFFER_HANDLE_H_*/
99
100=== modified file 'include/platform/mir/graphics/renderable.h'
101--- include/platform/mir/graphics/renderable.h 2015-03-30 03:20:27 +0000
102+++ include/platform/mir/graphics/renderable.h 2015-03-30 20:21:06 +0000
103@@ -26,10 +26,12 @@
104
105 namespace mir
106 {
107+
108 namespace graphics
109 {
110
111 class Buffer;
112+class BufferHandle;
113 class Renderable
114 {
115 public:
116@@ -48,6 +50,11 @@
117 */
118 virtual std::shared_ptr<Buffer> buffer() const = 0;
119
120+ /**
121+ * Return the buffer handle containing the buffer that should be composited/rendered.
122+ */
123+ virtual BufferHandle buffer_handle() const = 0;
124+
125 virtual geometry::Rectangle screen_position() const = 0;
126
127 // These are from the old CompositingCriteria. There is a little bit
128
129=== modified file 'src/include/server/mir/compositor/buffer_stream.h'
130--- src/include/server/mir/compositor/buffer_stream.h 2015-01-21 08:53:28 +0000
131+++ src/include/server/mir/compositor/buffer_stream.h 2015-03-30 20:21:06 +0000
132@@ -23,6 +23,7 @@
133 #include "mir/geometry/size.h"
134 #include "mir_toolkit/common.h"
135 #include "mir/graphics/buffer_id.h"
136+#include "mir/graphics/buffer_handle.h"
137
138 #include <memory>
139
140@@ -31,6 +32,7 @@
141 namespace graphics
142 {
143 class Buffer;
144+class BufferHandle;
145 }
146
147 namespace compositor
148@@ -44,9 +46,8 @@
149 virtual void acquire_client_buffer(
150 std::function<void(graphics::Buffer* buffer)> complete) = 0;
151 virtual void release_client_buffer(graphics::Buffer* buf) = 0;
152- virtual std::shared_ptr<graphics::Buffer>
153- lock_compositor_buffer(void const* user_id) = 0;
154- virtual std::shared_ptr<graphics::Buffer> lock_snapshot_buffer() = 0;
155+ virtual graphics::BufferHandle lock_compositor_buffer(void const* user_id) = 0;
156+ virtual graphics::BufferHandle lock_snapshot_buffer() = 0;
157 virtual MirPixelFormat get_stream_pixel_format() = 0;
158 virtual geometry::Size stream_size() = 0;
159 virtual void resize(geometry::Size const& size) = 0;
160
161=== modified file 'src/platform/graphics/CMakeLists.txt'
162--- src/platform/graphics/CMakeLists.txt 2015-03-30 03:20:27 +0000
163+++ src/platform/graphics/CMakeLists.txt 2015-03-30 20:21:06 +0000
164@@ -13,6 +13,7 @@
165 gl_texture.cpp
166 tessellation_helpers.cpp
167 platform_probe.cpp
168+ buffer_handle.cpp
169 )
170
171 add_library(mirplatformgraphicscommon OBJECT
172
173=== added file 'src/platform/graphics/buffer_handle.cpp'
174--- src/platform/graphics/buffer_handle.cpp 1970-01-01 00:00:00 +0000
175+++ src/platform/graphics/buffer_handle.cpp 2015-03-30 20:21:06 +0000
176@@ -0,0 +1,66 @@
177+/*
178+ * Copyright © 2015 Canonical Ltd.
179+ *
180+ * This program is free software: you can redistribute it and/or modify it
181+ * under the terms of the GNU General Public License version 3,
182+ * as published by the Free Software Foundation.
183+ *
184+ * This program is distributed in the hope that it will be useful,
185+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
186+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
187+ * GNU General Public License for more details.
188+ *
189+ * You should have received a copy of the GNU General Public License
190+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
191+ *
192+ * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com>
193+ */
194+
195+#include "mir/graphics/buffer_handle.h"
196+
197+namespace mg = mir::graphics;
198+
199+mg::BufferHandle::BufferHandle(std::shared_ptr<mg::Buffer> const& buffer,
200+ ReleaseCallback const& release)
201+ : wrapped(buffer),
202+ release_fn(release)
203+{
204+}
205+
206+mg::BufferHandle::BufferHandle(BufferHandle&& other)
207+{
208+ *this = std::move(other);
209+}
210+
211+mg::BufferHandle& mg::BufferHandle::operator=(BufferHandle&& other)
212+{
213+ if (this != &other)
214+ {
215+ // If the current buffer is being assigned a null handle,
216+ // we need to release the buffer.
217+ if (other.wrapped && other.release_fn && release_fn)
218+ release_fn(wrapped.get());
219+ wrapped = std::move(other.wrapped);
220+ release_fn.swap(other.release_fn);
221+ // other is emptied out already, prevent double release
222+ other.release_fn = nullptr;
223+ }
224+
225+ return *this;
226+}
227+
228+bool mg::BufferHandle::operator!()
229+{
230+ return (wrapped == nullptr);
231+}
232+
233+mg::BufferHandle::~BufferHandle()
234+{
235+ if (release_fn)
236+ release_fn(wrapped.get());
237+}
238+
239+std::shared_ptr<mg::Buffer> mg::BufferHandle::buffer()
240+{
241+ return wrapped;
242+}
243
244=== modified file 'src/platform/symbols.map'
245--- src/platform/symbols.map 2015-03-30 12:29:01 +0000
246+++ src/platform/symbols.map 2015-03-30 20:21:06 +0000
247@@ -15,6 +15,10 @@
248 mir::graphics::Buffer::size*;
249 mir::graphics::Buffer::stride*;
250 mir::graphics::Buffer::write*;
251+ mir::graphics::BufferHandle::BufferHandle*;
252+ mir::graphics::BufferHandle::?BufferHandle*;
253+ mir::graphics::BufferHandle::buffer*;
254+ mir::graphics::BufferHandle::operator*;
255 mir::graphics::Cursor::?Cursor*;
256 mir::graphics::Cursor::Cursor*;
257 mir::graphics::Cursor::hide*;
258
259=== modified file 'src/platforms/mesa/server/display_buffer.cpp'
260--- src/platforms/mesa/server/display_buffer.cpp 2015-03-30 03:20:27 +0000
261+++ src/platforms/mesa/server/display_buffer.cpp 2015-03-30 20:21:06 +0000
262@@ -29,7 +29,8 @@
263
264 #include <stdexcept>
265
266-namespace mgm = mir::graphics::mesa;
267+namespace mg = mir::graphics;
268+namespace mgm = mg::mesa;
269 namespace geom = mir::geometry;
270
271 class mgm::BufferObject
272@@ -204,7 +205,8 @@
273 auto bypass_it = std::find_if(renderable_list.rbegin(), renderable_list.rend(), bypass_match);
274 if (bypass_it != renderable_list.rend())
275 {
276- auto bypass_buffer = (*bypass_it)->buffer();
277+ bypass_buffer_handle = (*bypass_it)->buffer_handle();
278+ auto bypass_buffer = bypass_buffer_handle.buffer();
279 auto native = bypass_buffer->native_buffer_handle();
280 auto gbm_native = static_cast<mgm::GBMNativeBuffer*>(native.get());
281 auto bufobj = get_buffer_object(gbm_native->bo);
282@@ -212,14 +214,13 @@
283 native->flags & mir_buffer_flag_can_scanout &&
284 bypass_buffer->size() == geom::Size{fb_width,fb_height})
285 {
286- bypass_buf = bypass_buffer;
287 bypass_bufobj = bufobj;
288 return true;
289 }
290 else
291 {
292- bypass_buf = nullptr;
293 bypass_bufobj = nullptr;
294+ bypass_buffer_handle = mg::BufferHandle(nullptr, nullptr);
295 }
296 }
297 }
298@@ -237,7 +238,7 @@
299 {
300 if (!egl.swap_buffers())
301 fatal_error("Failed to perform buffer swap");
302- bypass_buf = nullptr;
303+ bypass_buffer_handle = mg::BufferHandle(nullptr, nullptr);
304 bypass_bufobj = nullptr;
305 }
306
307@@ -256,7 +257,7 @@
308 * we can unreference the bypass buffer...
309 */
310 if (scheduled_composite_frame)
311- visible_bypass_frame = nullptr;
312+ visible_bypass_buffer_handle = mg::BufferHandle(nullptr, nullptr);
313 /*
314 * Release the last flipped buffer object (which is not displayed anymore)
315 * to make it available for future rendering.
316@@ -268,16 +269,14 @@
317 scheduled_composite_frame = nullptr;
318
319 mgm::BufferObject *bufobj;
320- if (bypass_buf)
321- {
322- bufobj = bypass_bufobj;
323- }
324- else
325+ if (!bypass_buffer_handle)
326 {
327 bufobj = get_front_buffer_object();
328 if (!bufobj)
329 fatal_error("Failed to get front buffer object");
330 }
331+ else
332+ bufobj = bypass_bufobj;
333
334 /*
335 * Schedule the current front buffer object for display, and wait
336@@ -288,7 +287,7 @@
337 */
338 if (!needs_set_crtc && !schedule_page_flip(bufobj))
339 {
340- if (!bypass_buf)
341+ if (!bypass_buffer_handle)
342 bufobj->release();
343 fatal_error("Failed to schedule page flip");
344 }
345@@ -302,7 +301,36 @@
346 needs_set_crtc = false;
347 }
348
349- if (bypass_buf)
350+ if (!bypass_buffer_handle)
351+ {
352+ /*
353+ * Not in clone mode? We can afford to wait for the page flip then,
354+ * making us double-buffered (noticeably less laggy than the triple
355+ * buffering that clone mode requires).
356+ */
357+ if (outputs.size() == 1)
358+ {
359+ wait_for_page_flip();
360+
361+ /*
362+ * bufobj is now physically on screen. Release the old frame...
363+ */
364+ if (visible_composite_frame)
365+ {
366+ visible_composite_frame->release();
367+ visible_composite_frame = nullptr;
368+ }
369+
370+ /*
371+ * visible_composite_frame will be set correctly on the next iteration
372+ * Don't do it here or else bufobj would be released while still
373+ * on screen (hence tearing and artefacts).
374+ */
375+ }
376+
377+ scheduled_composite_frame = bufobj;
378+ }
379+ else
380 {
381 /*
382 * For composited frames we defer wait_for_page_flip till just before
383@@ -322,36 +350,7 @@
384 * the client while its on-screen, which would be seen as tearing or
385 * worse.
386 */
387- visible_bypass_frame = bypass_buf;
388- }
389- else
390- {
391- /*
392- * Not in clone mode? We can afford to wait for the page flip then,
393- * making us double-buffered (noticeably less laggy than the triple
394- * buffering that clone mode requires).
395- */
396- if (outputs.size() == 1)
397- {
398- wait_for_page_flip();
399-
400- /*
401- * bufobj is now physically on screen. Release the old frame...
402- */
403- if (visible_composite_frame)
404- {
405- visible_composite_frame->release();
406- visible_composite_frame = nullptr;
407- }
408-
409- /*
410- * visible_composite_frame will be set correctly on the next iteration
411- * Don't do it here or else bufobj would be released while still
412- * on screen (hence tearing and artefacts).
413- */
414- }
415-
416- scheduled_composite_frame = bufobj;
417+ visible_bypass_buffer_handle = std::move(bypass_buffer_handle);
418 }
419 }
420
421
422=== modified file 'src/platforms/mesa/server/display_buffer.h'
423--- src/platforms/mesa/server/display_buffer.h 2015-03-30 03:20:27 +0000
424+++ src/platforms/mesa/server/display_buffer.h 2015-03-30 20:21:06 +0000
425@@ -22,6 +22,7 @@
426 #include "mir/graphics/display_buffer.h"
427 #include "mir/graphics/display.h"
428 #include "display_helpers.h"
429+#include "mir/graphics/buffer_handle.h"
430
431 #include <vector>
432 #include <memory>
433@@ -79,9 +80,9 @@
434
435 BufferObject* visible_composite_frame;
436 BufferObject* scheduled_composite_frame;
437- std::shared_ptr<graphics::Buffer> visible_bypass_frame;
438- std::shared_ptr<Buffer> bypass_buf{nullptr};
439 BufferObject* bypass_bufobj{nullptr};
440+ graphics::BufferHandle visible_bypass_buffer_handle{nullptr, nullptr};
441+ graphics::BufferHandle bypass_buffer_handle{nullptr, nullptr};
442 std::shared_ptr<Platform> const platform;
443 std::shared_ptr<DisplayReport> const listener;
444 /* DRM helper from mgm::Platform */
445
446=== modified file 'src/server/compositor/CMakeLists.txt'
447--- src/server/compositor/CMakeLists.txt 2015-01-21 07:34:50 +0000
448+++ src/server/compositor/CMakeLists.txt 2015-03-30 20:21:06 +0000
449@@ -3,7 +3,6 @@
450
451 default_display_buffer_compositor.cpp
452 default_display_buffer_compositor_factory.cpp
453- temporary_buffers.cpp
454 buffer_stream_factory.cpp
455 buffer_stream_surfaces.cpp
456 gl_renderer.cpp
457
458=== modified file 'src/server/compositor/buffer_bundle.h'
459--- src/server/compositor/buffer_bundle.h 2015-01-21 08:53:28 +0000
460+++ src/server/compositor/buffer_bundle.h 2015-03-30 20:21:06 +0000
461@@ -25,7 +25,7 @@
462
463 namespace mir
464 {
465-namespace graphics { class Buffer; struct BufferProperties; }
466+namespace graphics { class Buffer; struct BufferProperties; class BufferHandle; }
467
468 namespace compositor
469 {
470@@ -48,11 +48,8 @@
471 * collisions, all callers should determine user_id
472 * in the same way (e.g. always use "this" pointer).
473 */
474- virtual std::shared_ptr<graphics::Buffer>
475- compositor_acquire(void const* user_id) = 0;
476- virtual void compositor_release(std::shared_ptr<graphics::Buffer> const&) = 0;
477- virtual std::shared_ptr<graphics::Buffer> snapshot_acquire() = 0;
478- virtual void snapshot_release(std::shared_ptr<graphics::Buffer> const&) = 0;
479+ virtual graphics::BufferHandle compositor_acquire(void const* user_id) = 0;
480+ virtual graphics::BufferHandle snapshot_acquire() = 0;
481
482 virtual graphics::BufferProperties properties() const = 0;
483 virtual void allow_framedropping(bool dropping_allowed) = 0;
484
485=== modified file 'src/server/compositor/buffer_queue.cpp'
486--- src/server/compositor/buffer_queue.cpp 2015-03-30 03:20:27 +0000
487+++ src/server/compositor/buffer_queue.cpp 2015-03-30 20:21:06 +0000
488@@ -20,6 +20,7 @@
489 #include "mir/graphics/graphic_buffer_allocator.h"
490 #include "mir/graphics/buffer_id.h"
491 #include "mir/lockable_callback.h"
492+#include "mir/graphics/buffer_handle.h"
493
494 #include <boost/throw_exception.hpp>
495 #include <stdexcept>
496@@ -239,8 +240,7 @@
497 ready_to_composite_queue.push_back(buffer);
498 }
499
500-std::shared_ptr<mg::Buffer>
501-mc::BufferQueue::compositor_acquire(void const* user_id)
502+mg::BufferHandle mc::BufferQueue::compositor_acquire(void const* user_id)
503 {
504 std::unique_lock<decltype(guard)> lock(guard);
505
506@@ -285,8 +285,30 @@
507
508 buffers_sent_to_compositor.push_back(current_compositor_buffer);
509
510- std::shared_ptr<mg::Buffer> const acquired_buffer =
511- buffer_for(current_compositor_buffer, buffers);
512+ std::weak_ptr<BufferQueue> weak_this = shared_from_this();
513+
514+ mg::BufferHandle acquired_buffer(
515+ buffer_for(current_compositor_buffer, buffers),
516+ [weak_this](mg::Buffer* b)
517+ {
518+ if (auto self = weak_this.lock())
519+ {
520+ std::unique_lock<decltype(self->guard)> lock(self->guard);
521+
522+ remove(b, self->buffers_sent_to_compositor);
523+
524+ /* Not ready to release it yet, other compositors still reference this buffer */
525+ if (contains(b, self->buffers_sent_to_compositor))
526+ return;
527+
528+ if (self->nbuffers <= 1)
529+ return;
530+
531+ if (self->current_compositor_buffer != b)
532+ self->release(b, std::move(lock));
533+ }
534+ });
535+
536
537 if (buffer_to_release)
538 release(buffer_to_release, std::move(lock));
539@@ -294,44 +316,26 @@
540 return acquired_buffer;
541 }
542
543-void mc::BufferQueue::compositor_release(std::shared_ptr<graphics::Buffer> const& buffer)
544-{
545- std::unique_lock<decltype(guard)> lock(guard);
546-
547- if (!remove(buffer.get(), buffers_sent_to_compositor))
548- {
549- BOOST_THROW_EXCEPTION(
550- std::logic_error("unexpected release: buffer was not given to compositor"));
551- }
552-
553- /* Not ready to release it yet, other compositors still reference this buffer */
554- if (contains(buffer.get(), buffers_sent_to_compositor))
555- return;
556-
557- if (nbuffers <= 1)
558- return;
559-
560- if (current_compositor_buffer != buffer.get())
561- release(buffer.get(), std::move(lock));
562-}
563-
564-std::shared_ptr<mg::Buffer> mc::BufferQueue::snapshot_acquire()
565+mg::BufferHandle mc::BufferQueue::snapshot_acquire()
566 {
567 std::unique_lock<decltype(guard)> lock(guard);
568 pending_snapshots.push_back(current_compositor_buffer);
569- return buffer_for(current_compositor_buffer, buffers);
570-}
571-
572-void mc::BufferQueue::snapshot_release(std::shared_ptr<graphics::Buffer> const& buffer)
573-{
574- std::unique_lock<std::mutex> lock(guard);
575- if (!remove(buffer.get(), pending_snapshots))
576- {
577- BOOST_THROW_EXCEPTION(
578- std::logic_error("unexpected release: no buffers were given to snapshotter"));
579- }
580-
581- snapshot_released.notify_all();
582+
583+ std::weak_ptr<BufferQueue> weak_this = shared_from_this();
584+
585+ return std::move(mg::BufferHandle(
586+ buffer_for(current_compositor_buffer, buffers),
587+ [weak_this](mg::Buffer* b)
588+ {
589+ if (auto self = weak_this.lock())
590+ {
591+ std::unique_lock<std::mutex> lock(self->guard);
592+
593+ remove(b, self->pending_snapshots);
594+
595+ self->snapshot_released.notify_all();
596+ }
597+ }));
598 }
599
600 mg::BufferProperties mc::BufferQueue::properties() const
601
602=== modified file 'src/server/compositor/buffer_queue.h'
603--- src/server/compositor/buffer_queue.h 2015-03-30 03:20:27 +0000
604+++ src/server/compositor/buffer_queue.h 2015-03-30 20:21:06 +0000
605@@ -29,15 +29,19 @@
606
607 namespace mir
608 {
609+
610 namespace graphics
611 {
612 class Buffer;
613 class GraphicBufferAllocator;
614+class BufferHandle;
615 }
616+
617 namespace compositor
618 {
619
620-class BufferQueue : public BufferBundle
621+class BufferQueue : public BufferBundle,
622+ public std::enable_shared_from_this<BufferQueue>
623 {
624 public:
625 typedef std::function<void(graphics::Buffer* buffer)> Callback;
626@@ -49,10 +53,8 @@
627
628 void client_acquire(Callback complete) override;
629 void client_release(graphics::Buffer* buffer) override;
630- std::shared_ptr<graphics::Buffer> compositor_acquire(void const* user_id) override;
631- void compositor_release(std::shared_ptr<graphics::Buffer> const& buffer) override;
632- std::shared_ptr<graphics::Buffer> snapshot_acquire() override;
633- void snapshot_release(std::shared_ptr<graphics::Buffer> const& buffer) override;
634+ graphics::BufferHandle compositor_acquire(void const* user_id) override;
635+ graphics::BufferHandle snapshot_acquire() override;
636
637 graphics::BufferProperties properties() const override;
638 void allow_framedropping(bool dropping_allowed) override;
639
640=== modified file 'src/server/compositor/buffer_stream_surfaces.cpp'
641--- src/server/compositor/buffer_stream_surfaces.cpp 2015-01-21 08:53:28 +0000
642+++ src/server/compositor/buffer_stream_surfaces.cpp 2015-03-30 20:21:06 +0000
643@@ -21,8 +21,6 @@
644 #include "buffer_bundle.h"
645 #include "mir/graphics/buffer_properties.h"
646
647-#include "temporary_buffers.h"
648-
649 namespace mc = mir::compositor;
650 namespace mg = mir::graphics;
651 namespace geom = mir::geometry;
652@@ -37,16 +35,15 @@
653 force_requests_to_complete();
654 }
655
656-std::shared_ptr<mg::Buffer> mc::BufferStreamSurfaces::lock_compositor_buffer(
657+mg::BufferHandle mc::BufferStreamSurfaces::lock_compositor_buffer(
658 void const* user_id)
659 {
660- return std::make_shared<mc::TemporaryCompositorBuffer>(
661- buffer_bundle, user_id);
662+ return buffer_bundle->compositor_acquire(user_id);
663 }
664
665-std::shared_ptr<mg::Buffer> mc::BufferStreamSurfaces::lock_snapshot_buffer()
666+mg::BufferHandle mc::BufferStreamSurfaces::lock_snapshot_buffer()
667 {
668- return std::make_shared<mc::TemporarySnapshotBuffer>(buffer_bundle);
669+ return buffer_bundle->snapshot_acquire();
670 }
671
672 void mc::BufferStreamSurfaces::acquire_client_buffer(
673
674=== modified file 'src/server/compositor/buffer_stream_surfaces.h'
675--- src/server/compositor/buffer_stream_surfaces.h 2015-01-21 08:53:28 +0000
676+++ src/server/compositor/buffer_stream_surfaces.h 2015-03-30 20:21:06 +0000
677@@ -26,6 +26,9 @@
678
679 namespace mir
680 {
681+
682+namespace graphics { class BufferHandle; }
683+
684 namespace compositor
685 {
686
687@@ -42,9 +45,8 @@
688 void acquire_client_buffer(std::function<void(graphics::Buffer* buffer)> complete) override;
689 void release_client_buffer(graphics::Buffer* buf) override;
690
691- std::shared_ptr<graphics::Buffer>
692- lock_compositor_buffer(void const* user_id) override;
693- std::shared_ptr<graphics::Buffer> lock_snapshot_buffer() override;
694+ graphics::BufferHandle lock_compositor_buffer(void const* user_id) override;
695+ graphics::BufferHandle lock_snapshot_buffer() override;
696
697 MirPixelFormat get_stream_pixel_format() override;
698 geometry::Size stream_size() override;
699
700=== modified file 'src/server/compositor/default_display_buffer_compositor.cpp'
701--- src/server/compositor/default_display_buffer_compositor.cpp 2015-03-30 03:20:27 +0000
702+++ src/server/compositor/default_display_buffer_compositor.cpp 2015-03-30 20:21:06 +0000
703@@ -72,11 +72,10 @@
704 */
705 scene_elements.clear(); // Those in use are still in renderable_list
706
707+ report->renderables_in_frame(this, renderable_list);
708+
709 if (display_buffer.post_renderables_if_optimizable(renderable_list))
710- {
711- report->renderables_in_frame(this, renderable_list);
712 renderer->suspend();
713- }
714 else
715 {
716 display_buffer.make_current();
717@@ -86,7 +85,6 @@
718 renderer->render(renderable_list);
719
720 display_buffer.gl_swap_buffers();
721- report->renderables_in_frame(this, renderable_list);
722 report->rendered_frame(this);
723
724 // Release the buffers we did use back to the clients, before starting
725
726=== removed file 'src/server/compositor/temporary_buffers.cpp'
727--- src/server/compositor/temporary_buffers.cpp 2015-03-30 03:20:27 +0000
728+++ src/server/compositor/temporary_buffers.cpp 1970-01-01 00:00:00 +0000
729@@ -1,97 +0,0 @@
730-/*
731- * Copyright © 2012 Canonical Ltd.
732- *
733- * This program is free software: you can redistribute it and/or modify it
734- * under the terms of the GNU General Public License version 3,
735- * as published by the Free Software Foundation.
736- *
737- * This program is distributed in the hope that it will be useful,
738- * but WITHOUT ANY WARRANTY; without even the implied warranty of
739- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
740- * GNU General Public License for more details.
741- *
742- * You should have received a copy of the GNU General Public License
743- * along with this program. If not, see <http://www.gnu.org/licenses/>.
744- *
745- * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
746- */
747-
748-#include "buffer_bundle.h"
749-#include "temporary_buffers.h"
750-
751-#include <boost/throw_exception.hpp>
752-#include <stdexcept>
753-
754-namespace mc=mir::compositor;
755-namespace mg=mir::graphics;
756-namespace geom=mir::geometry;
757-
758-mc::TemporaryBuffer::TemporaryBuffer(std::shared_ptr<mg::Buffer> const& real_buffer)
759- : buffer(real_buffer)
760-{
761-}
762-
763-mc::TemporaryCompositorBuffer::TemporaryCompositorBuffer(
764- std::shared_ptr<BufferBundle> const& bun, void const* user_id)
765- : TemporaryBuffer(bun->compositor_acquire(user_id)),
766- bundle(bun)
767-{
768-}
769-
770-mc::TemporaryCompositorBuffer::~TemporaryCompositorBuffer()
771-{
772- bundle->compositor_release(buffer);
773-}
774-
775-mc::TemporarySnapshotBuffer::TemporarySnapshotBuffer(
776- std::shared_ptr<BufferBundle> const& bun)
777- : TemporaryBuffer(bun->snapshot_acquire()),
778- bundle(bun)
779-{
780-}
781-
782-mc::TemporarySnapshotBuffer::~TemporarySnapshotBuffer()
783-{
784- bundle->snapshot_release(buffer);
785-}
786-
787-geom::Size mc::TemporaryBuffer::size() const
788-{
789- return buffer->size();
790-}
791-
792-geom::Stride mc::TemporaryBuffer::stride() const
793-{
794- return buffer->stride();
795-}
796-
797-MirPixelFormat mc::TemporaryBuffer::pixel_format() const
798-{
799- return buffer->pixel_format();
800-}
801-
802-mg::BufferID mc::TemporaryBuffer::id() const
803-{
804- return buffer->id();
805-}
806-
807-void mc::TemporaryBuffer::gl_bind_to_texture()
808-{
809- buffer->gl_bind_to_texture();
810-}
811-
812-std::shared_ptr<mg::NativeBuffer> mc::TemporaryBuffer::native_buffer_handle() const
813-{
814- return buffer->native_buffer_handle();
815-}
816-
817-void mc::TemporaryBuffer::write(unsigned char const*, size_t)
818-{
819- BOOST_THROW_EXCEPTION(
820- std::runtime_error("Write to temporary buffer snapshot is ill advised and indicates programmer error"));
821-}
822-
823-void mc::TemporaryBuffer::read(std::function<void(unsigned char const*)> const& exec)
824-{
825- buffer->read(exec);
826-}
827
828=== removed file 'src/server/compositor/temporary_buffers.h'
829--- src/server/compositor/temporary_buffers.h 2015-03-30 03:20:27 +0000
830+++ src/server/compositor/temporary_buffers.h 1970-01-01 00:00:00 +0000
831@@ -1,77 +0,0 @@
832-/*
833- * Copyright © 2012 Canonical Ltd.
834- *
835- * This program is free software: you can redistribute it and/or modify it
836- * under the terms of the GNU General Public License version 3,
837- * as published by the Free Software Foundation.
838- *
839- * This program is distributed in the hope that it will be useful,
840- * but WITHOUT ANY WARRANTY; without even the implied warranty of
841- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
842- * GNU General Public License for more details.
843- *
844- * You should have received a copy of the GNU General Public License
845- * along with this program. If not, see <http://www.gnu.org/licenses/>.
846- *
847- * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
848- */
849-
850-#ifndef MIR_COMPOSITOR_TEMPORARY_BUFFERS_H_
851-#define MIR_COMPOSITOR_TEMPORARY_BUFFERS_H_
852-
853-#include "mir/graphics/buffer.h"
854-#include "mir/graphics/buffer_id.h"
855-
856-namespace mg = mir::graphics;
857-
858-namespace mir
859-{
860-namespace compositor
861-{
862-
863-class BufferBundle;
864-class BackBufferStrategy;
865-
866-class TemporaryBuffer : public mg::Buffer
867-{
868-public:
869- geometry::Size size() const override;
870- geometry::Stride stride() const override;
871- MirPixelFormat pixel_format() const override;
872- mg::BufferID id() const override;
873- void gl_bind_to_texture() override;
874- std::shared_ptr<mg::NativeBuffer> native_buffer_handle() const override;
875- void write (unsigned char const* data, size_t size) override;
876- void read (std::function<void(unsigned char const*)> const& do_with_pixels) override;
877-
878-protected:
879- explicit TemporaryBuffer(std::shared_ptr<mg::Buffer> const& real_buffer);
880- std::shared_ptr<mg::Buffer> const buffer;
881-};
882-
883-class TemporaryCompositorBuffer : public TemporaryBuffer
884-{
885-public:
886- explicit TemporaryCompositorBuffer(
887- std::shared_ptr<BufferBundle> const& bun, void const* user_id);
888- ~TemporaryCompositorBuffer();
889-
890-private:
891- std::shared_ptr<BufferBundle> const bundle;
892-};
893-
894-class TemporarySnapshotBuffer : public TemporaryBuffer
895-{
896-public:
897- explicit TemporarySnapshotBuffer(
898- std::shared_ptr<BufferBundle> const& bun);
899- ~TemporarySnapshotBuffer();
900-
901-private:
902- std::shared_ptr<BufferBundle> const bundle;
903-};
904-
905-}
906-}
907-
908-#endif /* MIR_COMPOSITOR_TEMPORARY_BUFFERS_H_ */
909
910=== modified file 'src/server/graphics/software_cursor.cpp'
911--- src/server/graphics/software_cursor.cpp 2015-03-30 03:20:27 +0000
912+++ src/server/graphics/software_cursor.cpp 2015-03-30 20:21:06 +0000
913@@ -23,6 +23,7 @@
914 #include "mir/graphics/renderable.h"
915 #include "mir/graphics/buffer_properties.h"
916 #include "mir/input/scene.h"
917+#include "mir/graphics/buffer_handle.h"
918
919 #include <mutex>
920
921@@ -71,6 +72,13 @@
922 return buffer_;
923 }
924
925+ mg::BufferHandle buffer_handle() const override
926+ {
927+ // Not used for software cursor.
928+ mg::BufferHandle handle;
929+ return handle;
930+ }
931+
932 geom::Rectangle screen_position() const override
933 {
934 std::lock_guard<std::mutex> lock{position_mutex};
935
936=== modified file 'src/server/input/android/android_pointer_controller.cpp'
937--- src/server/input/android/android_pointer_controller.cpp 2015-01-21 07:34:50 +0000
938+++ src/server/input/android/android_pointer_controller.cpp 2015-03-30 20:21:06 +0000
939@@ -123,11 +123,12 @@
940
941 touches.push_back({{x, y}, pressure});
942 }
943-
944- touch_visualizer->visualize_touches(touches);
945+ if (touch_visualizer)
946+ touch_visualizer->visualize_touches(touches);
947 }
948
949 void mia::PointerController::clearSpots()
950 {
951- touch_visualizer->visualize_touches({});
952+ if (touch_visualizer)
953+ touch_visualizer->visualize_touches({});
954 }
955
956=== modified file 'src/server/input/touchspot_controller.cpp'
957--- src/server/input/touchspot_controller.cpp 2015-03-30 03:20:27 +0000
958+++ src/server/input/touchspot_controller.cpp 2015-03-30 20:21:06 +0000
959@@ -26,6 +26,7 @@
960 #include "mir/graphics/renderable.h"
961 #include "mir/geometry/dimensions.h"
962 #include "mir/input/scene.h"
963+#include "mir/graphics/buffer_handle.h"
964
965 namespace mi = mir::input;
966 namespace mg = mir::graphics;
967@@ -56,7 +57,13 @@
968 {
969 return buffer_;
970 }
971-
972+
973+ mg::BufferHandle buffer_handle() const override
974+ {
975+ mg::BufferHandle handle;
976+ return handle;
977+ }
978+
979 geom::Rectangle screen_position() const override
980 {
981 return {position, buffer_->size()};
982
983=== modified file 'src/server/scene/basic_surface.cpp'
984--- src/server/scene/basic_surface.cpp 2015-03-30 03:20:27 +0000
985+++ src/server/scene/basic_surface.cpp 2015-03-30 20:21:06 +0000
986@@ -27,6 +27,7 @@
987 #include "mir/graphics/buffer.h"
988 #include "mir/graphics/cursor_image.h"
989 #include "mir/geometry/displacement.h"
990+#include "mir/graphics/buffer_handle.h"
991
992 #include "mir/scene/scene_report.h"
993 #include "mir/scene/null_surface_observer.h"
994@@ -257,11 +258,6 @@
995 surface_buffer_stream->allow_framedropping(allow);
996 }
997
998-std::shared_ptr<mg::Buffer> ms::BasicSurface::snapshot_buffer() const
999-{
1000- return surface_buffer_stream->lock_snapshot_buffer();
1001-}
1002-
1003 bool ms::BasicSurface::supports_input() const
1004 {
1005 if (server_input_channel && server_input_channel->client_fd() != -1)
1006@@ -404,8 +400,8 @@
1007 void ms::BasicSurface::with_most_recent_buffer_do(
1008 std::function<void(mg::Buffer&)> const& exec)
1009 {
1010- auto buf = snapshot_buffer();
1011- exec(*buf);
1012+ auto buffer_handle = surface_buffer_stream->lock_snapshot_buffer();
1013+ exec(*(buffer_handle.buffer()));
1014 }
1015
1016
1017@@ -809,14 +805,13 @@
1018 bool shaped,
1019 mg::Renderable::ID id)
1020 : underlying_buffer_stream{stream},
1021- compositor_buffer{nullptr},
1022+ buffer_handle_handed_out(false),
1023 compositor_id{compositor_id},
1024 alpha_{alpha},
1025 shaped_{shaped},
1026 screen_position_(position),
1027 transformation_(transform),
1028- id_(id)
1029- {
1030+ id_(id) {
1031 }
1032
1033 ~SurfaceSnapshot()
1034@@ -825,9 +820,27 @@
1035
1036 std::shared_ptr<mg::Buffer> buffer() const override
1037 {
1038- if (!compositor_buffer)
1039- compositor_buffer = underlying_buffer_stream->lock_compositor_buffer(compositor_id);
1040- return compositor_buffer;
1041+ if (buffer_handle_handed_out)
1042+ {
1043+ // Once buffer_handle() is called, the buffer is managed elsewhere
1044+ BOOST_THROW_EXCEPTION(
1045+ std::runtime_error("Calling buffer() after buffer_handle() is called is not allowed"));
1046+ return nullptr;
1047+ }
1048+ else
1049+ {
1050+ if (!compositor_buffer_handle)
1051+ compositor_buffer_handle = underlying_buffer_stream->lock_compositor_buffer(compositor_id);
1052+ }
1053+ return compositor_buffer_handle.buffer();
1054+ }
1055+
1056+ mg::BufferHandle buffer_handle() const override
1057+ {
1058+ if (!compositor_buffer_handle)
1059+ compositor_buffer_handle = underlying_buffer_stream->lock_compositor_buffer(compositor_id);
1060+ buffer_handle_handed_out = true;
1061+ return std::move(compositor_buffer_handle);
1062 }
1063
1064 geom::Rectangle screen_position() const override
1065@@ -846,7 +859,8 @@
1066 { return id_; }
1067 private:
1068 std::shared_ptr<mc::BufferStream> const underlying_buffer_stream;
1069- std::shared_ptr<mg::Buffer> mutable compositor_buffer;
1070+ mg::BufferHandle mutable compositor_buffer_handle;
1071+ bool mutable buffer_handle_handed_out;
1072 void const*const compositor_id;
1073 float const alpha_;
1074 bool const shaped_;
1075
1076=== modified file 'src/server/scene/basic_surface.h'
1077--- src/server/scene/basic_surface.h 2015-03-30 03:20:27 +0000
1078+++ src/server/scene/basic_surface.h 2015-03-30 20:21:06 +0000
1079@@ -113,7 +113,6 @@
1080
1081 MirPixelFormat pixel_format() const override;
1082
1083- std::shared_ptr<graphics::Buffer> snapshot_buffer() const;
1084 void swap_buffers(graphics::Buffer* old_buffer, std::function<void(graphics::Buffer* new_buffer)> complete) override;
1085 void force_requests_to_complete() override;
1086

Subscribers

People subscribed via source and target branches