Mir

Merge lp:~raof/mir/further-buffer-plumbing-cleanup into lp:mir

Proposed by Chris Halse Rogers
Status: Merged
Approved by: Alan Griffiths
Approved revision: no longer in the source branch.
Merged at revision: 4229
Proposed branch: lp:~raof/mir/further-buffer-plumbing-cleanup
Merge into: lp:mir
Prerequisite: lp:~raof/mir/no-ipc-on-compositor-threads
Diff against target: 1034 lines (+171/-490)
11 files modified
src/server/compositor/CMakeLists.txt (+0/-1)
src/server/compositor/buffer_acquisition.h (+17/-2)
src/server/compositor/multi_monitor_arbiter.cpp (+11/-66)
src/server/compositor/multi_monitor_arbiter.h (+1/-16)
src/server/compositor/stream.cpp (+2/-4)
src/server/compositor/temporary_buffers.cpp (+0/-81)
src/server/compositor/temporary_buffers.h (+0/-74)
tests/integration-tests/test_buffer_scheduling.cpp (+31/-7)
tests/unit-tests/compositor/CMakeLists.txt (+0/-1)
tests/unit-tests/compositor/test_multi_monitor_arbiter.cpp (+109/-95)
tests/unit-tests/compositor/test_temporary_buffers.cpp (+0/-143)
To merge this branch: bzr merge lp:~raof/mir/further-buffer-plumbing-cleanup
Reviewer Review Type Date Requested Status
Mir CI Bot continuous-integration Approve
Alan Griffiths Approve
Brandon Schaefer (community) Approve
Review via email: mp+326987@code.launchpad.net

Commit message

Remove even more manual reference counting of mg::Buffer-s.

To post a comment you must log in.
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

FAILED: Continuous integration, rev:4219
https://mir-jenkins.ubuntu.com/job/mir-ci/3479/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/4752/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4910
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=artful/4899
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/4899
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4899
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4789
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4789/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4789
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4789/artifact/output/*zip*/output.zip
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4789/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4789
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4789/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4789
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4789/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4789
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4789/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4789
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4789/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4789
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4789/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/3479/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:4220
https://mir-jenkins.ubuntu.com/job/mir-ci/3483/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/4758
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4916
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=artful/4905
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/4905
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4905
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4795
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4795/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4795
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4795/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4795
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4795/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4795
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4795/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4795
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4795/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4795
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4795/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4795
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4795/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4795
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4795/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/3483/rebuild

review: Approve (continuous-integration)
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

I dont have the full context on the reason for temp buffers, but this clean up looks very nice.

review: Approve
Revision history for this message
Chris Halse Rogers (raof) wrote :

The temp buffers were there to wrap
compositor_acquire/compositor_release and
snapshot_acquire/snapshot_release, mainly in order to drive the
buffer-release IPC.

Since we now drive the buffer-release IPC based on when the buffer
submitted to the queue hits refcount 0, we no longer need the extra
wrapper.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

I think this is OK, but from past experience this is a fragile piece of functionality.

Are we completely sure that the change from "onscreen_buffers" to "current_buffer" accommodates multi-monitor?

review: Needs Information
Revision history for this message
Chris Halse Rogers (raof) wrote :

Yes.

There's always a current_buffer to give out to a compositor, and it is advanced at the same times that a new buffer was pushed to the front of onscreen_buffers.

We needed onscreen_buffers in order to reference-count the buffers we'd handed out to ensure they were returned to the client only when unused. Since we now do that directly in the shared_ptr<>, onscreen_buffers is no longer necessary.

You can see that we only ever push onto the front of onscreen_buffers and only ever access the buffer associated with the front of onscreen_buffers.

In addition to this theoretical analysis, it correctly runs lots of clients on my 3-head AMD/NVIDIA hybrid system, including clients that span heads (and, indeed, GPUs), and also appears correct in clone mode.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> In addition to this theoretical analysis, it correctly runs lots of clients on
> my 3-head AMD/NVIDIA hybrid system, including clients that span heads (and,
> indeed, GPUs), and also appears correct in clone mode.

Thanks, I couldn't try that as I'm away from my desktop.

review: Approve
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:4221
https://mir-jenkins.ubuntu.com/job/mir-ci/3502/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/4791
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4966
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=artful/4955
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/4955
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4955
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4828
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4828/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4828
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4828/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4828
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4828/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4828
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4828/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4828
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4828/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4828
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4828/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4828
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4828/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4828
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4828/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/3502/rebuild

review: Approve (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

FAILED: Autolanding.
Unapproved changes made after approval.
https://mir-jenkins.ubuntu.com/job/mir-autolanding/1389/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/4872
    None: https://mir-jenkins.ubuntu.com/job/generic-land-mp/1514/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/5085
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=artful/5074
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/5074
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/5074
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4909
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4909/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4909
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4909/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4909
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4909/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4909
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4909/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4909
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4909/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4909
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4909/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4909
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4909/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4909
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4909/artifact/output/*zip*/output.zip

review: Needs Fixing (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

FAILED: Autolanding.
More details in the following jenkins job:
https://mir-jenkins.ubuntu.com/job/mir-autolanding/1389/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/4872
    FAILURE: https://mir-jenkins.ubuntu.com/job/generic-land-mp/1514/console
    None: https://mir-jenkins.ubuntu.com/job/generic-land-mp/1515/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/5085
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=artful/5074
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/5074
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/5074
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4909
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4909/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4909
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4909/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4909
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4909/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4909
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4909/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4909
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4909/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4909
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4909/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4909
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4909/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4909
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4909/artifact/output/*zip*/output.zip

review: Needs Fixing (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/server/compositor/CMakeLists.txt'
--- src/server/compositor/CMakeLists.txt 2017-05-22 23:26:24 +0000
+++ src/server/compositor/CMakeLists.txt 2017-08-08 04:14:04 +0000
@@ -9,7 +9,6 @@
99
10 default_display_buffer_compositor.cpp10 default_display_buffer_compositor.cpp
11 default_display_buffer_compositor_factory.cpp11 default_display_buffer_compositor_factory.cpp
12 temporary_buffers.cpp
13 buffer_stream_factory.cpp12 buffer_stream_factory.cpp
14 multi_threaded_compositor.cpp13 multi_threaded_compositor.cpp
15 occlusion.cpp14 occlusion.cpp
1615
=== modified file 'src/server/compositor/buffer_acquisition.h'
--- src/server/compositor/buffer_acquisition.h 2017-07-28 17:00:43 +0000
+++ src/server/compositor/buffer_acquisition.h 2017-08-08 04:14:04 +0000
@@ -36,6 +36,11 @@
36 /**36 /**
37 * Acquire the next buffer that's ready to display/composite.37 * Acquire the next buffer that's ready to display/composite.
38 *38 *
39 * \note The returned buffer is considered in-use until the its
40 * use-count reaches 0. In-use buffers will not be returned
41 * to the client, so for best performance it is important to
42 * release the returned buffer as soon as possible.
43 *
39 * \param [in] user_id A unique identifier of who is going to use the44 * \param [in] user_id A unique identifier of who is going to use the
40 * buffer, to ensure that separate users representing45 * buffer, to ensure that separate users representing
41 * separate monitors who need the same frame will get46 * separate monitors who need the same frame will get
@@ -46,9 +51,19 @@
46 */51 */
47 virtual std::shared_ptr<graphics::Buffer>52 virtual std::shared_ptr<graphics::Buffer>
48 compositor_acquire(void const* user_id) = 0;53 compositor_acquire(void const* user_id) = 0;
49 virtual void compositor_release(std::shared_ptr<graphics::Buffer> const&) = 0;54
55 /**
56 * Acquire the most recently displayed buffer.
57 *
58 * In contrast with compositor_acquire() this does not consume a client
59 * buffer.
60 *
61 * Like compositor_acquire(), you should release your reference to the
62 * returned buffer as soon as possible.
63 *
64 * \return A shared reference to the most recent visible client buffer.
65 */
50 virtual std::shared_ptr<graphics::Buffer> snapshot_acquire() = 0;66 virtual std::shared_ptr<graphics::Buffer> snapshot_acquire() = 0;
51 virtual void snapshot_release(std::shared_ptr<graphics::Buffer> const&) = 0;
52 virtual ~BufferAcquisition() = default;67 virtual ~BufferAcquisition() = default;
5368
54protected:69protected:
5570
=== modified file 'src/server/compositor/multi_monitor_arbiter.cpp'
--- src/server/compositor/multi_monitor_arbiter.cpp 2017-07-28 17:00:43 +0000
+++ src/server/compositor/multi_monitor_arbiter.cpp 2017-08-08 04:14:04 +0000
@@ -36,95 +36,40 @@
3636
37mc::MultiMonitorArbiter::~MultiMonitorArbiter()37mc::MultiMonitorArbiter::~MultiMonitorArbiter()
38{38{
39 std::lock_guard<decltype(mutex)> lk(mutex);
40 for(auto it = onscreen_buffers.begin(); it != onscreen_buffers.end(); it++)
41 {
42 if (it->use_count == 0)
43 it->buffer.reset();
44 }
45
46}39}
4740
48std::shared_ptr<mg::Buffer> mc::MultiMonitorArbiter::compositor_acquire(compositor::CompositorID id)41std::shared_ptr<mg::Buffer> mc::MultiMonitorArbiter::compositor_acquire(compositor::CompositorID id)
49{42{
50 std::lock_guard<decltype(mutex)> lk(mutex);43 std::lock_guard<decltype(mutex)> lk(mutex);
5144
52 if (onscreen_buffers.empty() && !schedule->num_scheduled())45 if (!current_buffer && !schedule->num_scheduled())
53 BOOST_THROW_EXCEPTION(std::logic_error("no buffer to give to compositor"));46 BOOST_THROW_EXCEPTION(std::logic_error("no buffer to give to compositor"));
5447
55 if (current_buffer_users.find(id) != current_buffer_users.end() || onscreen_buffers.empty())48 if (current_buffer_users.find(id) != current_buffer_users.end() || !current_buffer)
56 {49 {
57 if (schedule->num_scheduled())50 if (schedule->num_scheduled())
58 onscreen_buffers.emplace_front(schedule->next_buffer(), 0);51 current_buffer = schedule->next_buffer();
59 current_buffer_users.clear();52 current_buffer_users.clear();
60 }53 }
61 current_buffer_users.insert(id);54 current_buffer_users.insert(id);
6255
63 auto& last_entry = onscreen_buffers.front();56 return current_buffer;
64 last_entry.use_count++;
65 auto last_entry_buffer = last_entry.buffer;
66 clean_onscreen_buffers(lk);
67 return last_entry_buffer;
68}
69
70void mc::MultiMonitorArbiter::compositor_release(std::shared_ptr<mg::Buffer> const& buffer)
71{
72 std::lock_guard<decltype(mutex)> lk(mutex);
73
74 decrease_refcount_for(buffer->id(), lk);
75
76 if (onscreen_buffers.begin()->buffer != buffer)
77 clean_onscreen_buffers(lk);
78}
79
80void mc::MultiMonitorArbiter::decrease_refcount_for(mg::BufferID id, std::lock_guard<std::mutex> const&)
81{
82 auto it = std::find_if(onscreen_buffers.begin(), onscreen_buffers.end(),
83 [&id](ScheduleEntry const& s) { return s.buffer->id() == id; });
84 if (it == onscreen_buffers.end())
85 BOOST_THROW_EXCEPTION(std::logic_error("buffer not scheduled"));
86 it->use_count--;
87}
88
89void mc::MultiMonitorArbiter::clean_onscreen_buffers(std::lock_guard<std::mutex> const&)
90{
91 for(auto it = onscreen_buffers.begin(); it != onscreen_buffers.end();)
92 {
93 if ((it->use_count == 0) &&
94 (it != onscreen_buffers.begin() || schedule->num_scheduled())) //ensure monitors always have a buffer
95 {
96 it = onscreen_buffers.erase(it);
97 }
98 else
99 {
100 it++;
101 }
102 }
103}57}
10458
105std::shared_ptr<mg::Buffer> mc::MultiMonitorArbiter::snapshot_acquire()59std::shared_ptr<mg::Buffer> mc::MultiMonitorArbiter::snapshot_acquire()
106{60{
107 std::lock_guard<decltype(mutex)> lk(mutex);61 std::lock_guard<decltype(mutex)> lk(mutex);
10862
109 if (onscreen_buffers.empty() && !schedule->num_scheduled())63 if (!current_buffer && !schedule->num_scheduled())
110 BOOST_THROW_EXCEPTION(std::logic_error("no buffer to give to snapshotter"));64 BOOST_THROW_EXCEPTION(std::logic_error("no buffer to give to snapshotter"));
11165
112 if (onscreen_buffers.empty())66 if (!current_buffer)
113 {67 {
114 if (schedule->num_scheduled())68 if (schedule->num_scheduled())
115 onscreen_buffers.emplace_front(schedule->next_buffer(), 0);69 current_buffer = schedule->next_buffer();
116 }70 }
11771
118 auto& last_entry = onscreen_buffers.front();72 return current_buffer;
119 last_entry.use_count++;
120 return last_entry.buffer;
121}
122
123void mc::MultiMonitorArbiter::snapshot_release(std::shared_ptr<mg::Buffer> const& buffer)
124{
125 std::lock_guard<decltype(mutex)> lk(mutex);
126 decrease_refcount_for(buffer->id(), lk);
127 clean_onscreen_buffers(lk);
128}73}
12974
130void mc::MultiMonitorArbiter::set_schedule(std::shared_ptr<Schedule> const& new_schedule)75void mc::MultiMonitorArbiter::set_schedule(std::shared_ptr<Schedule> const& new_schedule)
@@ -137,13 +82,13 @@
137{82{
138 std::lock_guard<decltype(mutex)> lk(mutex);83 std::lock_guard<decltype(mutex)> lk(mutex);
139 return schedule->num_scheduled() ||84 return schedule->num_scheduled() ||
140 ((current_buffer_users.find(id) == current_buffer_users.end()) && !onscreen_buffers.empty());85 ((current_buffer_users.find(id) == current_buffer_users.end()) && current_buffer);
141}86}
14287
143bool mc::MultiMonitorArbiter::has_buffer()88bool mc::MultiMonitorArbiter::has_buffer()
144{89{
145 std::lock_guard<decltype(mutex)> lk(mutex);90 std::lock_guard<decltype(mutex)> lk(mutex);
146 return !onscreen_buffers.empty();91 return static_cast<bool>(current_buffer);
147}92}
14893
149void mc::MultiMonitorArbiter::advance_schedule()94void mc::MultiMonitorArbiter::advance_schedule()
@@ -151,7 +96,7 @@
151 std::lock_guard<decltype(mutex)> lk(mutex);96 std::lock_guard<decltype(mutex)> lk(mutex);
152 if (schedule->num_scheduled())97 if (schedule->num_scheduled())
153 {98 {
154 onscreen_buffers.emplace_front(schedule->next_buffer(), 0);99 current_buffer = schedule->next_buffer();
155 current_buffer_users.clear();100 current_buffer_users.clear();
156 } 101 }
157}102}
158103
=== modified file 'src/server/compositor/multi_monitor_arbiter.h'
--- src/server/compositor/multi_monitor_arbiter.h 2017-07-28 17:00:43 +0000
+++ src/server/compositor/multi_monitor_arbiter.h 2017-08-08 04:14:04 +0000
@@ -42,30 +42,15 @@
42 ~MultiMonitorArbiter();42 ~MultiMonitorArbiter();
4343
44 std::shared_ptr<graphics::Buffer> compositor_acquire(compositor::CompositorID id) override;44 std::shared_ptr<graphics::Buffer> compositor_acquire(compositor::CompositorID id) override;
45 void compositor_release(std::shared_ptr<graphics::Buffer> const&) override;
46 std::shared_ptr<graphics::Buffer> snapshot_acquire() override;45 std::shared_ptr<graphics::Buffer> snapshot_acquire() override;
47 void snapshot_release(std::shared_ptr<graphics::Buffer> const&) override;
48 void set_schedule(std::shared_ptr<Schedule> const& schedule);46 void set_schedule(std::shared_ptr<Schedule> const& schedule);
49 bool buffer_ready_for(compositor::CompositorID id);47 bool buffer_ready_for(compositor::CompositorID id);
50 bool has_buffer();48 bool has_buffer();
51 void advance_schedule();49 void advance_schedule();
5250
53private:51private:
54 void decrease_refcount_for(graphics::BufferID id, std::lock_guard<std::mutex> const&);
55 void clean_onscreen_buffers(std::lock_guard<std::mutex> const&);
56
57 std::mutex mutable mutex;52 std::mutex mutable mutex;
58 struct ScheduleEntry53 std::shared_ptr<graphics::Buffer> current_buffer;
59 {
60 ScheduleEntry(std::shared_ptr<graphics::Buffer> const& buffer, unsigned int use_count) :
61 buffer(buffer),
62 use_count(use_count)
63 {
64 }
65 std::shared_ptr<graphics::Buffer> buffer;
66 unsigned int use_count;
67 };
68 std::deque<ScheduleEntry> onscreen_buffers;
69 std::set<compositor::CompositorID> current_buffer_users;54 std::set<compositor::CompositorID> current_buffer_users;
70 std::shared_ptr<Schedule> schedule;55 std::shared_ptr<Schedule> schedule;
71};56};
7257
=== modified file 'src/server/compositor/stream.cpp'
--- src/server/compositor/stream.cpp 2017-08-08 04:14:03 +0000
+++ src/server/compositor/stream.cpp 2017-08-08 04:14:04 +0000
@@ -20,7 +20,6 @@
20#include "stream.h"20#include "stream.h"
21#include "queueing_schedule.h"21#include "queueing_schedule.h"
22#include "dropping_schedule.h"22#include "dropping_schedule.h"
23#include "temporary_buffers.h"
24#include "mir/graphics/buffer.h"23#include "mir/graphics/buffer.h"
25#include <boost/throw_exception.hpp>24#include <boost/throw_exception.hpp>
2625
@@ -73,8 +72,7 @@
73void mc::Stream::with_most_recent_buffer_do(std::function<void(mg::Buffer&)> const& fn)72void mc::Stream::with_most_recent_buffer_do(std::function<void(mg::Buffer&)> const& fn)
74{73{
75 std::lock_guard<decltype(mutex)> lk(mutex); 74 std::lock_guard<decltype(mutex)> lk(mutex);
76 TemporarySnapshotBuffer buffer(arbiter);75 fn(*arbiter->snapshot_acquire());
77 fn(buffer);
78}76}
7977
80MirPixelFormat mc::Stream::pixel_format() const78MirPixelFormat mc::Stream::pixel_format() const
@@ -96,7 +94,7 @@
9694
97std::shared_ptr<mg::Buffer> mc::Stream::lock_compositor_buffer(void const* id)95std::shared_ptr<mg::Buffer> mc::Stream::lock_compositor_buffer(void const* id)
98{96{
99 return std::make_shared<mc::TemporaryCompositorBuffer>(arbiter, id);97 return arbiter->compositor_acquire(id);
100}98}
10199
102geom::Size mc::Stream::stream_size()100geom::Size mc::Stream::stream_size()
103101
=== removed file 'src/server/compositor/temporary_buffers.cpp'
--- src/server/compositor/temporary_buffers.cpp 2017-07-28 17:00:43 +0000
+++ src/server/compositor/temporary_buffers.cpp 1970-01-01 00:00:00 +0000
@@ -1,81 +0,0 @@
1/*
2 * Copyright © 2012 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 or 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
17 */
18
19#include "buffer_acquisition.h"
20#include "temporary_buffers.h"
21
22#include <boost/throw_exception.hpp>
23#include <stdexcept>
24
25namespace mc=mir::compositor;
26namespace mg=mir::graphics;
27namespace geom=mir::geometry;
28
29mc::TemporaryBuffer::TemporaryBuffer(std::shared_ptr<mg::Buffer> const& real_buffer)
30 : buffer(real_buffer)
31{
32}
33
34mc::TemporaryCompositorBuffer::TemporaryCompositorBuffer(
35 std::shared_ptr<BufferAcquisition> const& acquisition, void const* user_id)
36 : TemporaryBuffer(acquisition->compositor_acquire(user_id)),
37 acquisition(acquisition)
38{
39}
40
41mc::TemporaryCompositorBuffer::~TemporaryCompositorBuffer()
42{
43 acquisition->compositor_release(buffer);
44}
45
46mc::TemporarySnapshotBuffer::TemporarySnapshotBuffer(
47 std::shared_ptr<BufferAcquisition> const& acquisition)
48 : TemporaryBuffer(acquisition->snapshot_acquire()),
49 acquisition(acquisition)
50{
51}
52
53mc::TemporarySnapshotBuffer::~TemporarySnapshotBuffer()
54{
55 acquisition->snapshot_release(buffer);
56}
57
58geom::Size mc::TemporaryBuffer::size() const
59{
60 return buffer->size();
61}
62
63MirPixelFormat mc::TemporaryBuffer::pixel_format() const
64{
65 return buffer->pixel_format();
66}
67
68mg::BufferID mc::TemporaryBuffer::id() const
69{
70 return buffer->id();
71}
72
73std::shared_ptr<mg::NativeBuffer> mc::TemporaryBuffer::native_buffer_handle() const
74{
75 return buffer->native_buffer_handle();
76}
77
78mg::NativeBufferBase* mc::TemporaryBuffer::native_buffer_base()
79{
80 return buffer->native_buffer_base();
81}
820
=== removed file 'src/server/compositor/temporary_buffers.h'
--- src/server/compositor/temporary_buffers.h 2017-07-28 17:00:43 +0000
+++ src/server/compositor/temporary_buffers.h 1970-01-01 00:00:00 +0000
@@ -1,74 +0,0 @@
1/*
2 * Copyright © 2012 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 or 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
17 */
18
19#ifndef MIR_COMPOSITOR_TEMPORARY_BUFFERS_H_
20#define MIR_COMPOSITOR_TEMPORARY_BUFFERS_H_
21
22#include "mir/graphics/buffer.h"
23#include "mir/graphics/buffer_id.h"
24
25namespace mg = mir::graphics;
26
27namespace mir
28{
29namespace compositor
30{
31
32class BufferAcquisition;
33class BackBufferStrategy;
34
35class TemporaryBuffer : public mg::Buffer
36{
37public:
38 geometry::Size size() const override;
39 MirPixelFormat pixel_format() const override;
40 mg::BufferID id() const override;
41 std::shared_ptr<mg::NativeBuffer> native_buffer_handle() const override;
42 graphics::NativeBufferBase* native_buffer_base() override;
43
44protected:
45 explicit TemporaryBuffer(std::shared_ptr<mg::Buffer> const& real_buffer);
46 std::shared_ptr<mg::Buffer> const buffer;
47};
48
49class TemporaryCompositorBuffer : public TemporaryBuffer
50{
51public:
52 explicit TemporaryCompositorBuffer(
53 std::shared_ptr<BufferAcquisition> const& acquisition, void const* user_id);
54 ~TemporaryCompositorBuffer();
55
56private:
57 std::shared_ptr<BufferAcquisition> const acquisition;
58};
59
60class TemporarySnapshotBuffer : public TemporaryBuffer
61{
62public:
63 explicit TemporarySnapshotBuffer(
64 std::shared_ptr<BufferAcquisition> const& acquisition);
65 ~TemporarySnapshotBuffer();
66
67private:
68 std::shared_ptr<BufferAcquisition> const acquisition;
69};
70
71}
72}
73
74#endif /* MIR_COMPOSITOR_TEMPORARY_BUFFERS_H_ */
750
=== modified file 'tests/integration-tests/test_buffer_scheduling.cpp'
--- tests/integration-tests/test_buffer_scheduling.cpp 2017-07-28 17:00:43 +0000
+++ tests/integration-tests/test_buffer_scheduling.cpp 2017-08-08 04:14:04 +0000
@@ -24,7 +24,6 @@
24#include "src/client/protobuf_to_native_buffer.h"24#include "src/client/protobuf_to_native_buffer.h"
25#include "src/client/connection_surface_map.h"25#include "src/client/connection_surface_map.h"
26#include "src/server/compositor/stream.h"26#include "src/server/compositor/stream.h"
27#include "src/server/compositor/temporary_buffers.h"
28#include "mir/test/doubles/stub_client_buffer_factory.h"27#include "mir/test/doubles/stub_client_buffer_factory.h"
29#include "mir/test/doubles/mock_client_buffer_factory.h"28#include "mir/test/doubles/mock_client_buffer_factory.h"
30#include "mir/test/doubles/stub_buffer_allocator.h"29#include "mir/test/doubles/stub_buffer_allocator.h"
@@ -454,22 +453,49 @@
454 return never_blocks; 453 return never_blocks;
455}454}
456455
457class AutoSendBuffer : public mc::TemporaryBuffer456class AutoSendBuffer : public mg::Buffer
458{457{
459public:458public:
460 AutoSendBuffer(459 AutoSendBuffer(
461 std::shared_ptr<mg::Buffer> const& wrapped,460 std::shared_ptr<mg::Buffer> const& wrapped,
462 std::shared_ptr<mf::BufferSink> const& sink)461 std::shared_ptr<mf::BufferSink> const& sink)
463 : TemporaryBuffer(wrapped),462 : wrapped{wrapped},
464 sink{sink}463 sink{sink}
465 {464 {
466 }465 }
467466
468 ~AutoSendBuffer()467 ~AutoSendBuffer()
469 {468 {
470 sink->update_buffer(*buffer);469 sink->update_buffer(*wrapped);
471 }470 }
471
472 std::shared_ptr<mg::NativeBuffer> native_buffer_handle() const override
473 {
474 return wrapped->native_buffer_handle();
475 }
476
477 mg::BufferID id() const override
478 {
479 return wrapped->id();
480 }
481
482 geom::Size size() const override
483 {
484 return wrapped->size();
485 }
486
487 MirPixelFormat pixel_format() const override
488 {
489 return wrapped->pixel_format();
490 }
491
492 mg::NativeBufferBase *native_buffer_base() override
493 {
494 return wrapped->native_buffer_base();
495 }
496
472private:497private:
498 std::shared_ptr<mg::Buffer> const wrapped;
473 std::shared_ptr<mf::BufferSink> const sink;499 std::shared_ptr<mf::BufferSink> const sink;
474};500};
475501
@@ -1175,7 +1201,6 @@
1175 producer->produce();1201 producer->produce();
1176 a = consumer->consume_resource();1202 a = consumer->consume_resource();
1177 b = consumer->consume_resource();1203 b = consumer->consume_resource();
1178 EXPECT_THAT(a, Ne(b));
1179 }1204 }
1180 a.reset();1205 a.reset();
1181 b.reset();1206 b.reset();
@@ -1214,7 +1239,6 @@
1214 {1239 {
1215 first = consumer->consume_resource();1240 first = consumer->consume_resource();
1216 second = consumer->consume_resource();1241 second = consumer->consume_resource();
1217 EXPECT_THAT(first, Ne(second));
1218 producer->produce();1242 producer->produce();
1219 }1243 }
12201244
12211245
=== modified file 'tests/unit-tests/compositor/CMakeLists.txt'
--- tests/unit-tests/compositor/CMakeLists.txt 2017-07-04 04:06:59 +0000
+++ tests/unit-tests/compositor/CMakeLists.txt 2017-08-08 04:14:04 +0000
@@ -1,7 +1,6 @@
1list(APPEND UNIT_TEST_SOURCES1list(APPEND UNIT_TEST_SOURCES
2 ${CMAKE_CURRENT_SOURCE_DIR}/test_default_display_buffer_compositor.cpp2 ${CMAKE_CURRENT_SOURCE_DIR}/test_default_display_buffer_compositor.cpp
3 ${CMAKE_CURRENT_SOURCE_DIR}/test_stream.cpp3 ${CMAKE_CURRENT_SOURCE_DIR}/test_stream.cpp
4 ${CMAKE_CURRENT_SOURCE_DIR}/test_temporary_buffers.cpp
5 ${CMAKE_CURRENT_SOURCE_DIR}/test_multi_threaded_compositor.cpp4 ${CMAKE_CURRENT_SOURCE_DIR}/test_multi_threaded_compositor.cpp
6 ${CMAKE_CURRENT_SOURCE_DIR}/test_occlusion.cpp5 ${CMAKE_CURRENT_SOURCE_DIR}/test_occlusion.cpp
7 ${CMAKE_CURRENT_SOURCE_DIR}/test_screencast_display_buffer.cpp6 ${CMAKE_CURRENT_SOURCE_DIR}/test_screencast_display_buffer.cpp
87
=== modified file 'tests/unit-tests/compositor/test_multi_monitor_arbiter.cpp'
--- tests/unit-tests/compositor/test_multi_monitor_arbiter.cpp 2017-08-08 04:14:03 +0000
+++ tests/unit-tests/compositor/test_multi_monitor_arbiter.cpp 2017-08-08 04:14:04 +0000
@@ -21,7 +21,6 @@
21#include "mir/test/doubles/stub_buffer_allocator.h"21#include "mir/test/doubles/stub_buffer_allocator.h"
22#include "src/server/compositor/multi_monitor_arbiter.h"22#include "src/server/compositor/multi_monitor_arbiter.h"
23#include "src/server/compositor/schedule.h"23#include "src/server/compositor/schedule.h"
24#include "src/server/compositor/temporary_buffers.h"
2524
26#include <gtest/gtest.h>25#include <gtest/gtest.h>
27using namespace testing;26using namespace testing;
@@ -83,13 +82,13 @@
83 std::shared_ptr<mg::Buffer> const& buffer,82 std::shared_ptr<mg::Buffer> const& buffer,
84 std::shared_ptr<bool> const& destroyed)83 std::shared_ptr<bool> const& destroyed)
85{84{
86 class DestructionNotifyingBuffer : public mc::TemporaryBuffer85 class DestructionNotifyingBuffer : public mg::Buffer
87 {86 {
88 public:87 public:
89 DestructionNotifyingBuffer(88 DestructionNotifyingBuffer(
90 std::shared_ptr<mg::Buffer> const& buffer,89 std::shared_ptr<mg::Buffer> const& buffer,
91 std::shared_ptr<bool> const& destroyed)90 std::shared_ptr<bool> const& destroyed)
92 : TemporaryBuffer(buffer),91 : wrapped{buffer},
93 destroyed{destroyed}92 destroyed{destroyed}
94 {93 {
95 }94 }
@@ -98,7 +97,34 @@
98 {97 {
99 *destroyed = true;98 *destroyed = true;
100 }99 }
100
101 std::shared_ptr<mg::NativeBuffer> native_buffer_handle() const override
102 {
103 return wrapped->native_buffer_handle();
104 }
105
106 mg::BufferID id() const override
107 {
108 return wrapped->id();
109 }
110
111 mir::geometry::Size size() const override
112 {
113 return wrapped->size();
114 }
115
116 MirPixelFormat pixel_format() const override
117 {
118 return wrapped->pixel_format();
119 }
120
121 mg::NativeBufferBase *native_buffer_base() override
122 {
123 return wrapped->native_buffer_base();
124 }
125
101 private:126 private:
127 std::shared_ptr<mg::Buffer> const wrapped;
102 std::shared_ptr<bool> const destroyed;128 std::shared_ptr<bool> const destroyed;
103 };129 };
104130
@@ -133,7 +159,6 @@
133159
134 auto cbuffer = arbiter.compositor_acquire(this);160 auto cbuffer = arbiter.compositor_acquire(this);
135 schedule.set_schedule({buffers[1]});161 schedule.set_schedule({buffers[1]});
136 arbiter.compositor_release(cbuffer);
137 cbuffer.reset();162 cbuffer.reset();
138 // We need to acquire a new buffer - the current one is on-screen, so can't be sent back.163 // We need to acquire a new buffer - the current one is on-screen, so can't be sent back.
139 arbiter.compositor_acquire(this);164 arbiter.compositor_acquire(this);
@@ -182,22 +207,17 @@
182{207{
183 schedule.set_schedule({buffers[0],buffers[1],buffers[2],buffers[3],buffers[4]});208 schedule.set_schedule({buffers[0],buffers[1],buffers[2],buffers[3],buffers[4]});
184209
185 auto cbuffer1 = arbiter.compositor_acquire(this);210 auto id1 = arbiter.compositor_acquire(this)->id();
186 arbiter.compositor_release(cbuffer1);211 auto id2 = arbiter.compositor_acquire(this)->id();
187 auto cbuffer2 = arbiter.compositor_acquire(this);212 auto id3 = arbiter.compositor_acquire(this)->id();
188 arbiter.compositor_release(cbuffer2);213 auto id4 = arbiter.compositor_acquire(this)->id();
189 auto cbuffer3 = arbiter.compositor_acquire(this);214 auto iddqd = arbiter.compositor_acquire(this)->id();
190 arbiter.compositor_release(cbuffer3);
191 auto cbuffer4 = arbiter.compositor_acquire(this);
192 arbiter.compositor_release(cbuffer4);
193 auto cbuffer5 = arbiter.compositor_acquire(this);
194 arbiter.compositor_release(cbuffer5);
195215
196 EXPECT_THAT(cbuffer1, IsSameBufferAs(buffers[0]));216 EXPECT_THAT(id1, Eq(buffers[0]->id()));
197 EXPECT_THAT(cbuffer2, IsSameBufferAs(buffers[1]));217 EXPECT_THAT(id2, Eq(buffers[1]->id()));
198 EXPECT_THAT(cbuffer3, IsSameBufferAs(buffers[2]));218 EXPECT_THAT(id3, Eq(buffers[2]->id()));
199 EXPECT_THAT(cbuffer4, IsSameBufferAs(buffers[3]));219 EXPECT_THAT(id4, Eq(buffers[3]->id()));
200 EXPECT_THAT(cbuffer5, IsSameBufferAs(buffers[4]));220 EXPECT_THAT(iddqd, Eq(buffers[4]->id()));
201}221}
202222
203TEST_F(MultiMonitorArbiter, compositor_consumes_all_buffers_when_operating_as_a_bypassed_buffer_would)223TEST_F(MultiMonitorArbiter, compositor_consumes_all_buffers_when_operating_as_a_bypassed_buffer_would)
@@ -206,20 +226,28 @@
206226
207 auto cbuffer1 = arbiter.compositor_acquire(this);227 auto cbuffer1 = arbiter.compositor_acquire(this);
208 auto cbuffer2 = arbiter.compositor_acquire(this);228 auto cbuffer2 = arbiter.compositor_acquire(this);
209 arbiter.compositor_release(cbuffer1);229 auto id1 = cbuffer1->id();
230 cbuffer1.reset();
231
210 auto cbuffer3 = arbiter.compositor_acquire(this);232 auto cbuffer3 = arbiter.compositor_acquire(this);
211 arbiter.compositor_release(cbuffer2);233 auto id2 = cbuffer2->id();
234 cbuffer2.reset();
235
212 auto cbuffer4 = arbiter.compositor_acquire(this);236 auto cbuffer4 = arbiter.compositor_acquire(this);
213 arbiter.compositor_release(cbuffer3);237 auto id3 = cbuffer3->id();
238 cbuffer3.reset();
239
214 auto cbuffer5 = arbiter.compositor_acquire(this);240 auto cbuffer5 = arbiter.compositor_acquire(this);
215 arbiter.compositor_release(cbuffer4);241 auto id4 = cbuffer4->id();
216 arbiter.compositor_release(cbuffer5);242 cbuffer4.reset();
243 auto id5 = cbuffer5->id();
244 cbuffer5.reset();
217245
218 EXPECT_THAT(cbuffer1, IsSameBufferAs(buffers[0]));246 EXPECT_THAT(id1, Eq(buffers[0]->id()));
219 EXPECT_THAT(cbuffer2, IsSameBufferAs(buffers[1]));247 EXPECT_THAT(id2, Eq(buffers[1]->id()));
220 EXPECT_THAT(cbuffer3, IsSameBufferAs(buffers[2]));248 EXPECT_THAT(id3, Eq(buffers[2]->id()));
221 EXPECT_THAT(cbuffer4, IsSameBufferAs(buffers[3]));249 EXPECT_THAT(id4, Eq(buffers[3]->id()));
222 EXPECT_THAT(cbuffer5, IsSameBufferAs(buffers[4]));250 EXPECT_THAT(id5, Eq(buffers[4]->id()));
223}251}
224252
225TEST_F(MultiMonitorArbiter, multimonitor_compositor_buffer_syncs_to_fastest_with_more_queueing)253TEST_F(MultiMonitorArbiter, multimonitor_compositor_buffer_syncs_to_fastest_with_more_queueing)
@@ -287,8 +315,7 @@
287 auto cbuffer1 = arbiter.compositor_acquire(this);315 auto cbuffer1 = arbiter.compositor_acquire(this);
288 auto cbuffer2 = arbiter.compositor_acquire(&that);316 auto cbuffer2 = arbiter.compositor_acquire(&that);
289 auto sbuffer1 = arbiter.snapshot_acquire();317 auto sbuffer1 = arbiter.snapshot_acquire();
290 arbiter.snapshot_release(sbuffer1);318 cbuffer2.reset();
291 arbiter.compositor_release(cbuffer2);
292 cbuffer2 = arbiter.compositor_acquire(&that);319 cbuffer2 = arbiter.compositor_acquire(&that);
293320
294 auto sbuffer2 = arbiter.snapshot_acquire();321 auto sbuffer2 = arbiter.snapshot_acquire();
@@ -302,17 +329,15 @@
302 auto that = 4;329 auto that = 4;
303 auto a_few_times = 5u;330 auto a_few_times = 5u;
304 auto cbuffer1 = arbiter.compositor_acquire(this);331 auto cbuffer1 = arbiter.compositor_acquire(this);
305 std::vector<std::shared_ptr<mg::Buffer>> snapshot_buffers(a_few_times);332 std::vector<mg::BufferID> snapshot_buffers(a_few_times);
306 for(auto i = 0u; i < a_few_times; i++)333 for(auto i = 0u; i < a_few_times; i++)
307 {334 {
308 auto b = arbiter.snapshot_acquire();335 snapshot_buffers[i] = arbiter.snapshot_acquire()->id();
309 arbiter.snapshot_release(b);
310 snapshot_buffers[i] = b;
311 }336 }
312 auto cbuffer2 = arbiter.compositor_acquire(&that);337 auto cbuffer2 = arbiter.compositor_acquire(&that);
313338
314 EXPECT_THAT(cbuffer1, IsSameBufferAs(cbuffer2));339 EXPECT_THAT(cbuffer1, IsSameBufferAs(cbuffer2));
315 EXPECT_THAT(snapshot_buffers, Each(IsSameBufferAs(cbuffer1)));340 EXPECT_THAT(snapshot_buffers, Each(Eq(cbuffer1->id())));
316}341}
317342
318TEST_F(MultiMonitorArbiter, no_buffers_available_throws_on_snapshot)343TEST_F(MultiMonitorArbiter, no_buffers_available_throws_on_snapshot)
@@ -333,14 +358,12 @@
333 });358 });
334 auto cbuffer1 = arbiter.compositor_acquire(this);359 auto cbuffer1 = arbiter.compositor_acquire(this);
335 auto sbuffer1 = arbiter.snapshot_acquire();360 auto sbuffer1 = arbiter.snapshot_acquire();
336 arbiter.compositor_release(cbuffer1);
337 cbuffer1.reset();361 cbuffer1.reset();
338362
339 // Acquire a new buffer so first one is no longer onscreen.363 // Acquire a new buffer so first one is no longer onscreen.
340 arbiter.compositor_acquire(this);364 arbiter.compositor_acquire(this);
341365
342 EXPECT_FALSE(*buffer_released);366 EXPECT_FALSE(*buffer_released);
343 arbiter.snapshot_release(sbuffer1);
344 sbuffer1.reset();367 sbuffer1.reset();
345 EXPECT_TRUE(*buffer_released);368 EXPECT_TRUE(*buffer_released);
346}369}
@@ -361,9 +384,7 @@
361 EXPECT_THAT(cbuffer1, IsSameBufferAs(cbuffer2));384 EXPECT_THAT(cbuffer1, IsSameBufferAs(cbuffer2));
362385
363 auto cbuffer3 = arbiter.compositor_acquire(&comp_id1);386 auto cbuffer3 = arbiter.compositor_acquire(&comp_id1);
364 arbiter.compositor_release(cbuffer2);
365 EXPECT_FALSE(*buffer_released);387 EXPECT_FALSE(*buffer_released);
366 arbiter.compositor_release(cbuffer1);
367 cbuffer1.reset();388 cbuffer1.reset();
368 cbuffer2.reset();389 cbuffer2.reset();
369 EXPECT_TRUE(*buffer_released);390 EXPECT_TRUE(*buffer_released);
@@ -375,15 +396,13 @@
375 int comp_id2{0};396 int comp_id2{0};
376 schedule.set_schedule({buffers[0],buffers[1]});397 schedule.set_schedule({buffers[0],buffers[1]});
377398
378 auto cbuffer1 = arbiter.compositor_acquire(&comp_id1); //buffer[0]399 auto id1 = arbiter.compositor_acquire(&comp_id1)->id(); //buffer[0]
379 arbiter.compositor_release(cbuffer1);400 auto id2 = arbiter.compositor_acquire(&comp_id2)->id(); //buffer[0]
380 auto cbuffer2 = arbiter.compositor_acquire(&comp_id2); //buffer[0]
381 arbiter.compositor_release(cbuffer2);
382401
383 auto cbuffer3 = arbiter.compositor_acquire(&comp_id1); //buffer[1]402 auto cbuffer3 = arbiter.compositor_acquire(&comp_id1); //buffer[1]
384 403
385 EXPECT_THAT(cbuffer1, IsSameBufferAs(cbuffer2));404 EXPECT_THAT(id1, Eq(id2));
386 EXPECT_THAT(cbuffer1, IsSameBufferAs(buffers[0]));405 EXPECT_THAT(id1, Eq(buffers[0]->id()));
387 EXPECT_THAT(cbuffer3, IsSameBufferAs(buffers[1]));406 EXPECT_THAT(cbuffer3, IsSameBufferAs(buffers[1]));
388}407}
389408
@@ -407,23 +426,16 @@
407 });426 });
408427
409 auto b1 = arbiter.compositor_acquire(&comp_id1);428 auto b1 = arbiter.compositor_acquire(&comp_id1);
410 arbiter.compositor_release(b1);429 b1.reset();
411 auto b2 = arbiter.compositor_acquire(&comp_id1);430 auto b2 = arbiter.compositor_acquire(&comp_id1);
412 arbiter.compositor_release(b2);431 b2.reset();
413 auto b3 = arbiter.compositor_acquire(&comp_id1);432 auto b3 = arbiter.compositor_acquire(&comp_id1);
414 auto b5 = arbiter.compositor_acquire(&comp_id2);433 auto b5 = arbiter.compositor_acquire(&comp_id2);
415 arbiter.compositor_release(b3);434 b3.reset();
416 auto b4 = arbiter.compositor_acquire(&comp_id1);435 auto b4 = arbiter.compositor_acquire(&comp_id1);
417 arbiter.compositor_release(b5);436 b5.reset();
418 arbiter.compositor_release(b4);437 b4.reset();
419 auto b6 = arbiter.compositor_acquire(&comp_id1);438 auto b6 = arbiter.compositor_acquire(&comp_id1);
420 arbiter.compositor_release(b6);
421
422 b1.reset();
423 b2.reset();
424 b3.reset();
425 b4.reset();
426 b5.reset();
427 b6.reset();439 b6.reset();
428440
429 EXPECT_THAT(buffer_released, Each(Pointee(true)));441 EXPECT_THAT(buffer_released, Each(Pointee(true)));
@@ -441,13 +453,12 @@
441 auto b1 = arbiter.compositor_acquire(&comp_id1);453 auto b1 = arbiter.compositor_acquire(&comp_id1);
442 EXPECT_FALSE(arbiter.buffer_ready_for(&comp_id1));454 EXPECT_FALSE(arbiter.buffer_ready_for(&comp_id1));
443 EXPECT_TRUE(arbiter.buffer_ready_for(&comp_id2));455 EXPECT_TRUE(arbiter.buffer_ready_for(&comp_id2));
444 arbiter.compositor_release(b1);456 b1.reset();
445457
446 auto b2 = arbiter.compositor_acquire(&comp_id2);458 auto b2 = arbiter.compositor_acquire(&comp_id2);
447 EXPECT_FALSE(arbiter.buffer_ready_for(&comp_id1));459 EXPECT_FALSE(arbiter.buffer_ready_for(&comp_id1));
448 EXPECT_FALSE(arbiter.buffer_ready_for(&comp_id2));460 EXPECT_FALSE(arbiter.buffer_ready_for(&comp_id2));
449 arbiter.compositor_release(b2);461}
450}
451462
452TEST_F(MultiMonitorArbiter, other_compositor_ready_status_advances_with_fastest_compositor)463TEST_F(MultiMonitorArbiter, other_compositor_ready_status_advances_with_fastest_compositor)
453{464{
@@ -458,23 +469,19 @@
458 EXPECT_TRUE(arbiter.buffer_ready_for(&comp_id1));469 EXPECT_TRUE(arbiter.buffer_ready_for(&comp_id1));
459 EXPECT_TRUE(arbiter.buffer_ready_for(&comp_id2));470 EXPECT_TRUE(arbiter.buffer_ready_for(&comp_id2));
460471
461 auto b1 = arbiter.compositor_acquire(&comp_id1);472 arbiter.compositor_acquire(&comp_id1);
462 arbiter.compositor_release(b1);473 EXPECT_TRUE(arbiter.buffer_ready_for(&comp_id1));
463 EXPECT_TRUE(arbiter.buffer_ready_for(&comp_id1));474 EXPECT_TRUE(arbiter.buffer_ready_for(&comp_id2));
464 EXPECT_TRUE(arbiter.buffer_ready_for(&comp_id2));475
465476 arbiter.compositor_acquire(&comp_id1);
466 b1 = arbiter.compositor_acquire(&comp_id1);477 EXPECT_TRUE(arbiter.buffer_ready_for(&comp_id1));
467 arbiter.compositor_release(b1);478 EXPECT_TRUE(arbiter.buffer_ready_for(&comp_id2));
468 EXPECT_TRUE(arbiter.buffer_ready_for(&comp_id1));479
469 EXPECT_TRUE(arbiter.buffer_ready_for(&comp_id2));480 arbiter.compositor_acquire(&comp_id1);
470
471 b1 = arbiter.compositor_acquire(&comp_id1);
472 arbiter.compositor_release(b1);
473 EXPECT_FALSE(arbiter.buffer_ready_for(&comp_id1));481 EXPECT_FALSE(arbiter.buffer_ready_for(&comp_id1));
474 EXPECT_TRUE(arbiter.buffer_ready_for(&comp_id2));482 EXPECT_TRUE(arbiter.buffer_ready_for(&comp_id2));
475483
476 b1 = arbiter.compositor_acquire(&comp_id2);484 arbiter.compositor_acquire(&comp_id2);
477 arbiter.compositor_release(b1);
478 EXPECT_FALSE(arbiter.buffer_ready_for(&comp_id1));485 EXPECT_FALSE(arbiter.buffer_ready_for(&comp_id1));
479 EXPECT_FALSE(arbiter.buffer_ready_for(&comp_id2));486 EXPECT_FALSE(arbiter.buffer_ready_for(&comp_id2));
480}487}
@@ -497,8 +504,6 @@
497 auto b2 = arbiter.compositor_acquire(&comp_id1);504 auto b2 = arbiter.compositor_acquire(&comp_id1);
498 EXPECT_THAT(b1, IsSameBufferAs(buffers[0]));505 EXPECT_THAT(b1, IsSameBufferAs(buffers[0]));
499 EXPECT_THAT(b2, IsSameBufferAs(buffers[1]));506 EXPECT_THAT(b2, IsSameBufferAs(buffers[1]));
500 arbiter.compositor_release(b1);
501 arbiter.compositor_release(b2);
502 b1.reset();507 b1.reset();
503 b2.reset();508 b2.reset();
504509
@@ -512,20 +517,26 @@
512 schedule.set_schedule({buffers[0], buffers[1], buffers[0], buffers[1]});517 schedule.set_schedule({buffers[0], buffers[1], buffers[0], buffers[1]});
513518
514 auto b1 = arbiter.compositor_acquire(&comp_id1);519 auto b1 = arbiter.compositor_acquire(&comp_id1);
520 auto id1 = b1->id();
515 auto b2 = arbiter.compositor_acquire(&comp_id1);521 auto b2 = arbiter.compositor_acquire(&comp_id1);
516 arbiter.compositor_release(b1);522 auto id2 = b2->id();
523
524 b1.reset();
517525
518 auto b3 = arbiter.compositor_acquire(&comp_id2);526 auto b3 = arbiter.compositor_acquire(&comp_id2);
527 auto id3 = b3->id();
519 auto b4 = arbiter.compositor_acquire(&comp_id2);528 auto b4 = arbiter.compositor_acquire(&comp_id2);
520 arbiter.compositor_release(b3);529 auto id4 = b4->id();
521530
522 arbiter.compositor_release(b2);531 b3.reset();
523 arbiter.compositor_release(b4);532
524533 b2.reset();
525 EXPECT_THAT(b1, IsSameBufferAs(buffers[0]));534 b4.reset();
526 EXPECT_THAT(b2, IsSameBufferAs(buffers[1]));535
527 EXPECT_THAT(b3, IsSameBufferAs(buffers[1]));536 EXPECT_THAT(id1, Eq(buffers[0]->id()));
528 EXPECT_THAT(b4, IsSameBufferAs(buffers[0]));537 EXPECT_THAT(id2, Eq(buffers[1]->id()));
538 EXPECT_THAT(id3, Eq(buffers[1]->id()));
539 EXPECT_THAT(id4, Eq(buffers[0]->id()));
529540
530} 541}
531542
@@ -540,22 +551,25 @@
540 buffers[0], buffers[1], buffers[2]});551 buffers[0], buffers[1], buffers[2]});
541552
542 auto b1 = arbiter.compositor_acquire(&comp_id1);553 auto b1 = arbiter.compositor_acquire(&comp_id1);
554 auto id1 = b1->id();
543 auto b2 = arbiter.compositor_acquire(&comp_id2);555 auto b2 = arbiter.compositor_acquire(&comp_id2);
544 arbiter.compositor_release(b1); //send nothing556 auto id2 = b2->id();
557 b1.reset(); // Send nothing
545558
546 auto b3 = arbiter.compositor_acquire(&comp_id1);559 auto b3 = arbiter.compositor_acquire(&comp_id1);
547 arbiter.compositor_release(b3); //send nothing560 auto id3 = b3->id();
561 b3.reset(); // Send nothing
548562
549 auto b4 = arbiter.compositor_acquire(&comp_id2);563 auto b4 = arbiter.compositor_acquire(&comp_id2);
550 arbiter.compositor_release(b2); //send 0564 auto id4 = b4->id();
565 b2.reset(); // Send 0
551566
552 auto b5 = arbiter.compositor_acquire(&comp_id1);567 auto b5 = arbiter.compositor_acquire(&comp_id1);
553 arbiter.compositor_release(b5); //send nothing
554568
555 EXPECT_THAT(b1, IsSameBufferAs(buffers[0]));569 EXPECT_THAT(id1, Eq(buffers[0]->id()));
556 EXPECT_THAT(b2, IsSameBufferAs(buffers[0]));570 EXPECT_THAT(id2, Eq(buffers[0]->id()));
557 EXPECT_THAT(b3, IsSameBufferAs(buffers[1]));571 EXPECT_THAT(id3, Eq(buffers[1]->id()));
558 EXPECT_THAT(b4, IsSameBufferAs(buffers[1]));572 EXPECT_THAT(id4, Eq(buffers[1]->id()));
559 EXPECT_THAT(b5, IsSameBufferAs(buffers[2]));573 EXPECT_THAT(b5, IsSameBufferAs(buffers[2]));
560}574}
561575
562576
=== removed file 'tests/unit-tests/compositor/test_temporary_buffers.cpp'
--- tests/unit-tests/compositor/test_temporary_buffers.cpp 2017-07-28 17:00:43 +0000
+++ tests/unit-tests/compositor/test_temporary_buffers.cpp 1970-01-01 00:00:00 +0000
@@ -1,143 +0,0 @@
1/*
2 * Copyright © 2012 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 or 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
17 */
18
19#include "src/server/compositor/temporary_buffers.h"
20#include "src/server/compositor/buffer_acquisition.h"
21#include "mir/test/doubles/mock_buffer.h"
22#include "mir/test/doubles/stub_buffer.h"
23#include <gtest/gtest.h>
24#include <stdexcept>
25
26namespace mtd=mir::test::doubles;
27namespace mg = mir::graphics;
28namespace mc=mir::compositor;
29namespace geom=mir::geometry;
30
31namespace
32{
33class TemporaryTestBuffer : public mc::TemporaryBuffer
34{
35public:
36 TemporaryTestBuffer(const std::shared_ptr<mg::Buffer>& buf)
37 : TemporaryBuffer(buf)
38 {
39 }
40};
41
42struct MockBufferAcquisition : mc::BufferAcquisition
43{
44 MOCK_METHOD1(compositor_acquire, std::shared_ptr<mg::Buffer>(void const*));
45 MOCK_METHOD1(compositor_release, void(std::shared_ptr<mg::Buffer> const&));
46 MOCK_METHOD0(snapshot_acquire, std::shared_ptr<mg::Buffer>());
47 MOCK_METHOD1(snapshot_release, void(std::shared_ptr<mg::Buffer> const&));
48};
49
50class TemporaryBuffersTest : public ::testing::Test
51{
52public:
53 TemporaryBuffersTest()
54 : buffer_size{1024, 768},
55 buffer_stride{1024},
56 buffer_pixel_format{mir_pixel_format_abgr_8888},
57 mock_buffer{std::make_shared<testing::NiceMock<mtd::MockBuffer>>(
58 buffer_size, buffer_stride, buffer_pixel_format)},
59 mock_acquisition{std::make_shared<testing::NiceMock<MockBufferAcquisition>>()}
60 {
61 using namespace testing;
62 ON_CALL(*mock_acquisition, compositor_acquire(_))
63 .WillByDefault(Return(mock_buffer));
64 }
65
66 geom::Size const buffer_size;
67 geom::Stride const buffer_stride;
68 MirPixelFormat const buffer_pixel_format;
69 std::shared_ptr<mtd::MockBuffer> const mock_buffer;
70 std::shared_ptr<MockBufferAcquisition> mock_acquisition;
71};
72}
73
74TEST_F(TemporaryBuffersTest, compositor_buffer_acquires_and_releases)
75{
76 using namespace testing;
77 EXPECT_CALL(*mock_acquisition, compositor_acquire(_))
78 .WillOnce(Return(mock_buffer));
79 EXPECT_CALL(*mock_acquisition, compositor_release(_))
80 .Times(1);
81
82 mc::TemporaryCompositorBuffer proxy_buffer(mock_acquisition, 0);
83}
84
85TEST_F(TemporaryBuffersTest, snapshot_buffer_acquires_and_releases)
86{
87 using namespace testing;
88 EXPECT_CALL(*mock_acquisition, snapshot_acquire())
89 .WillOnce(Return(mock_buffer));
90 EXPECT_CALL(*mock_acquisition, snapshot_release(_))
91 .Times(1);
92
93 mc::TemporarySnapshotBuffer proxy_buffer(mock_acquisition);
94}
95
96TEST_F(TemporaryBuffersTest, base_test_size)
97{
98 TemporaryTestBuffer proxy_buffer(mock_buffer);
99 EXPECT_CALL(*mock_buffer, size())
100 .Times(1);
101
102 geom::Size size;
103 size = proxy_buffer.size();
104 EXPECT_EQ(buffer_size, size);
105}
106
107TEST_F(TemporaryBuffersTest, base_test_pixel_format)
108{
109 TemporaryTestBuffer proxy_buffer(mock_buffer);
110 EXPECT_CALL(*mock_buffer, pixel_format())
111 .Times(1);
112
113 MirPixelFormat pixel_format;
114 pixel_format = proxy_buffer.pixel_format();
115 EXPECT_EQ(buffer_pixel_format, pixel_format);
116}
117
118TEST_F(TemporaryBuffersTest, base_test_id)
119{
120 TemporaryTestBuffer proxy_buffer(mock_buffer);
121 EXPECT_CALL(*mock_buffer, id())
122 .Times(1);
123
124 proxy_buffer.id();
125}
126
127TEST_F(TemporaryBuffersTest, base_test_native_buffer_handle)
128{
129 TemporaryTestBuffer proxy_buffer(mock_buffer);
130 EXPECT_CALL(*mock_buffer, native_buffer_handle())
131 .Times(1);
132
133 proxy_buffer.native_buffer_handle();
134}
135
136TEST_F(TemporaryBuffersTest, forwards_native_buffer_base_to_wrapped_buffer)
137{
138 TemporaryTestBuffer proxy_buffer(mock_buffer);
139 EXPECT_CALL(*mock_buffer, native_buffer_base())
140 .Times(1);
141
142 proxy_buffer.native_buffer_base();
143}

Subscribers

People subscribed via source and target branches