Mir

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

Proposed by Cemil Azizoglu
Status: Work in progress
Proposed branch: lp:~cemil-azizoglu/mir/improve-raii
Merge into: lp:mir
Diff against target: 5102 lines (+917/-1962)
52 files modified
src/include/server/mir/compositor/buffer_bundle.h (+4/-5)
src/include/server/mir/compositor/buffer_handle.h (+61/-0)
src/include/server/mir/compositor/buffer_queue.h (+7/-5)
src/include/server/mir/compositor/buffer_stream.h (+0/-63)
src/include/server/mir/default_server_configuration.h (+4/-4)
src/include/server/mir/scene/buffer_queue_factory.h (+11/-11)
src/server/compositor/CMakeLists.txt (+2/-3)
src/server/compositor/buffer_handle.cpp (+63/-0)
src/server/compositor/buffer_queue.cpp (+52/-43)
src/server/compositor/buffer_queue_factory.cpp (+7/-12)
src/server/compositor/buffer_queue_factory.h (+12/-12)
src/server/compositor/buffer_stream_surfaces.cpp (+0/-101)
src/server/compositor/buffer_stream_surfaces.h (+0/-69)
src/server/compositor/default_configuration.cpp (+6/-6)
src/server/compositor/default_display_buffer_compositor.cpp (+0/-1)
src/server/compositor/gl_renderer.cpp (+0/-1)
src/server/compositor/temporary_buffers.cpp (+0/-92)
src/server/compositor/temporary_buffers.h (+0/-76)
src/server/frontend/session_mediator.cpp (+0/-1)
src/server/scene/basic_surface.cpp (+25/-37)
src/server/scene/basic_surface.h (+5/-7)
src/server/scene/default_configuration.cpp (+1/-1)
src/server/scene/surface_allocator.cpp (+7/-9)
src/server/scene/surface_allocator.h (+3/-3)
src/server/symbols.map (+1/-1)
tests/include/mir_test_doubles/mock_buffer_bundle.h (+14/-10)
tests/include/mir_test_doubles/mock_buffer_stream.h (+0/-67)
tests/include/mir_test_doubles/mock_surface.h (+2/-2)
tests/include/mir_test_doubles/stub_buffer_bundle.h (+26/-23)
tests/integration-tests/compositor/CMakeLists.txt (+0/-1)
tests/integration-tests/compositor/test_buffer_stream.cpp (+0/-405)
tests/integration-tests/compositor/test_swapping_swappers.cpp (+2/-4)
tests/integration-tests/graphics/android/test_buffer_integration.cpp (+1/-1)
tests/integration-tests/surface_composition.cpp (+2/-9)
tests/integration-tests/test_exchange_buffer.cpp (+26/-21)
tests/integration-tests/test_session.cpp (+0/-1)
tests/integration-tests/test_surface_stack_with_compositor.cpp (+9/-12)
tests/integration-tests/test_swapinterval.cpp (+23/-23)
tests/unit-tests/compositor/CMakeLists.txt (+1/-2)
tests/unit-tests/compositor/test_buffer_handle.cpp (+40/-0)
tests/unit-tests/compositor/test_buffer_queue.cpp (+422/-395)
tests/unit-tests/compositor/test_buffer_stream.cpp (+0/-194)
tests/unit-tests/compositor/test_gl_renderer.cpp (+1/-2)
tests/unit-tests/compositor/test_temporary_buffers.cpp (+0/-149)
tests/unit-tests/examples/test_demo_compositor.cpp (+2/-2)
tests/unit-tests/frontend/test_session_mediator.cpp (+0/-1)
tests/unit-tests/graphics/test_program_factory.cpp (+1/-2)
tests/unit-tests/scene/test_basic_surface.cpp (+13/-13)
tests/unit-tests/scene/test_session_manager.cpp (+2/-2)
tests/unit-tests/scene/test_surface.cpp (+23/-21)
tests/unit-tests/scene/test_surface_impl.cpp (+11/-12)
tests/unit-tests/scene/test_surface_stack.cpp (+25/-25)
To merge this branch: bzr merge lp:~cemil-azizoglu/mir/improve-raii
Reviewer Review Type Date Requested Status
Alberto Aguirre (community) Needs Fixing
PS Jenkins bot (community) continuous-integration Approve
Alexandros Frantzis (community) Needs Fixing
Daniel van Vugt Needs Fixing
Alan Griffiths Needs Fixing
Kevin DuBois (community) Needs Fixing
Review via email: mp+250219@code.launchpad.net

Commit message

Improve raii in the way compositor and snapshot buffers are handled in the buffer queue.

Description of the change

Improve raii in buffer queue, which results in doing away with TemporaryBuffer and BufferStream (server-side) classes (at the cost of introducing a small BufferHandle class). Also BufferStreamFactory is now BufferQueueFactory.

The BufferBundle (and hence the BufferQueue) interface has been simplified due to the fact that now buffers are returned to the queue as part of BufferHandle destructor and not via an explicit call. This simplifies error handling during buffer releases.

Also, temporary buffers inheriting from Buffer is avoided, since they no longer exist. (This previously prevented Buffer being cast as the correct platform buffer type, though we found a different way to handle that case).

The heart of this MP lies in buffer_queue.cpp. For review purposes, one should start from compositor_acquire/snapshot_acquire functions and fan out from there.

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

Seems like (more or less) an even trade-off to me as to what we had before.
typing:
auto b = bundle->compositor_acquire(...);
b->buffer()->methods();
saves on having to update the Temporary*Buffer adapter objects, but is more awkward to type, compared to:
auto b = bundle->compositor_acquire(...);
b->methods();

84 +mc::BufferHandle::BufferHandle(BufferBundle* bundle,
We used to preserve ownership of the BufferBundle in the temporary buffers, seems like something that could cause problems around the client's destruction if we don't have BufferBundle ownership, and are trying to return in the destructor of BufferHandle.

169 + explicit CompositorBufferHandle(BufferBundle* bundle,
177 + explicit SnapshotBufferHandle(BufferBundle* bundle,
spacing

161 + std::shared_ptr<graphics::Buffer> buffer);
170 + std::shared_ptr<graphics::Buffer> buffer);
178 + std::shared_ptr<graphics::Buffer> buffer);
const&

We already have a "native handle", might be over-using the word "Handle" in mc::BufferHandle. (I'm mostly just trying to avoid writing: mg::BufferHandle handle{...}; handle->buffer()->native_buffer_handle() )

257 + std::shared_ptr<mc::BufferHandle> const acquired_buffer =
258 + std::make_shared<mc::SnapshotBufferHandle>(this, buffer_for(current_compositor_buffer, buffers));
259 +
260 + return acquired_buffer;
could just:
return std::make_shared<mc::SnapshotBufferHandle(...)

review: Needs Fixing
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

===
48 + virtual std::shared_ptr<BufferHandle> compositor_acquire(void const* user_id) = 0;
49 + virtual void compositor_release(graphics::Buffer* const buffer) = 0;
50 + virtual std::shared_ptr<BufferHandle> snapshot_acquire() = 0;
51 + virtual void snapshot_release(graphics::Buffer* const buffer) = 0;
==

I'd rather have compositor_acquire and snapshot_acquire return a BufferHandle by value.
BufferHandle should be a moveable only type.

The BufferHandle constructor could also be:

BufferHande(std::function<void()> const& release)

Then we can remove compositor_release and snapshot_release.

===
334 + return buffer_bundle->compositor_acquire(user_id)->buffer();
===

Nobody is holding the return shared_ptr<BufferHandle> so at the end of this scope, the buffer will be returned to the queue - possibly resulting in tearing artifacts.

In order for this to work correctly the caller of lock_compositor_buffer (i.e. SurfaceSnapshot) needs to be able to receive the BufferHandle object. That would pretty much make BufferStream a useless replicated interface - they should all just collapse to BufferBundle instead.

===
160 + explicit BufferHandle(BufferBundle* bundle,
161 + std::shared_ptr<graphics::Buffer> buffer);
162 + BufferBundle* buffer_bundle;
===

As mentioned above this could probably be:

class BufferHandle
{
public:
    typedef std::function<void(graphics::Buffer* buffer)> Callback;
    explicit BufferHandle(std::shared_ptr<graphics::Buffer> const& buffer,
                          Callback const& release);

    //Move constructor
    BufferHandle(BufferHandle&& other);
    //Move assignment
    BufferHandle& operator=(BufferHandle&& other);

    std::shared_ptr<graphics::Buffer> buffer();

private:
    // Moveable only type
    BufferHandle(BufferHandle const&) = delete;
    BufferHandle& operator=(BufferHandle const&) = delete;

    std::shared_ptr<graphics::Buffer> wrapped;
    Callback release;
};

===
213 + std::shared_ptr<mc::BufferHandle> const acquired_buffer =
214 + std::make_shared<mc::CompositorBufferHandle>(this, buffer_for(current_compositor_buffer, buffers));
===

With the BufferHandle above then this would become:

BufferHandle const handle{buffer_for(current_compositor_buffer, buffers),
 [weak_ptr_this](Buffer* buffer)
 {
    if (auto self = weak_ptr_this.lock())
    {
       compositor_release(buffer);
    }
 }

The weak_ptr_this is needed to ensure you won't be calling dead code if the BufferQueue gets destroyed before one of the BufferHandles. Alternatively, you could keep a shared_ptr instead to keep the buffer queue object alive but I would prefer the BufferHandle to not impose that requirement.

The above will require enabled_shared_from_this support in the BufferQueue class.

review: Needs Fixing
Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

@Alberto, @Kevin, your comments should have been addressed.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~cemil-azizoglu/mir/improve-raii updated
2375. By Cemil Azizoglu

Fix Android.

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

I knew this was coming. And by numbers I like the simplification. But the fact that some of our most sensitive test cases are being rewritten en-masse scares me. We'll all need to do some careful manual testing of this.

review: Abstain
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

2993 + ASSERT_NO_THROW(q = std::shared_ptr<mc::BufferQueue>(
2994 + new mc::BufferQueue(nbuffers, allocator, basic_properties, policy_factory)));

Here and elsewhere, better with std::make_shared<>

review: Needs Fixing
lp:~cemil-azizoglu/mir/improve-raii updated
2376. By Cemil Azizoglu

Use make_shared.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

===
68 +typedef std::function<void(graphics::Buffer* buffer)> release_callback;
===

Should be ReleaseCallback according to the mir style guide:
http://unity.ubuntu.com/mir/cppguide/index.html#Type_Names

===
80 + virtual ~BufferHandle();
===

Not needed

===
356 + if (release_fn)
357 + release_fn(wrapped.get());
===
I think Move assignment should not cause the buffer to be released back to the queue.
That would be analogous to move assigning a unique_ptr and having the ptr be deleted while doing that.

===
1198 + compositor_buffer_handle{nullptr, nullptr},
1209 + if (!compositor_buffer_handle.buffer())
1210 + compositor_buffer_handle = underlying_buffer_queue->compositor_acquire(compositor_id);
===

Maybe a bit cleaner (but not blocking) if you allow BufferHandle to be default constructed and implement the negation operator,
so that line 1198 is not needed then, and line 1209 just becomes: if (!compositor_buffer_handle)

===
1623 + return std::move(compositor::BufferHandle(stub_compositor_buffer, nullptr));
1628 + return std::move(compositor::BufferHandle(stub_compositor_buffer, nullptr));
===

You ca do away with the std::move

Needs information:

Do the BufferStream integration and unit tests (BufferStreamTest.*) overlap with other tests?
Otherwise they should be updated but kept not removed.

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

(1) Regression: Did some quick manual testing. Fullscreen bypassed surfaces are visibly tearing when using this branch...
   mir_demo_client_egltriangle -f
   mir_demo_client_eglplasma

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

This is what happens when we rewrite test cases en-masse. Regression tests stop protecting us from regressions.

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

Or for even more tearing, try:
  mir_demo_client_egltriangle -f -n

Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

348 + release_fn(std::move(other.release_fn))
367 + if (release_fn)

Unfortunately the standard says that move-constructing a std::function from another std::function leaves the latter in a valid but unspecified state. So "if (release_fn)" in the destructor is not guaranteed to be false after the move. We could use "if (wrapped && release_fn)" instead, since std::shared_ptr provides the guarantee we need.

Also note that after we remove (as mentioned by Alberto above):

356 + if (release_fn)
357 + release_fn(wrapped.get());

we could use the default implementations of move-construct and move-assign methods (we would need to explicitly define them with "= default");

review: Needs Fixing
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

> 348 + release_fn(std::move(other.release_fn))
> 367 + if (release_fn)
>
> Unfortunately the standard says that move-constructing a std::function from
> another std::function leaves the latter in a valid but unspecified state. So
> "if (release_fn)" in the destructor is not guaranteed to be false after the
> move.

That's so weird. I guess you could use other.swap(release_fn) in the constructor body instead. I hope that's well defined :)

lp:~cemil-azizoglu/mir/improve-raii updated
2377. By Cemil Azizoglu

Fixes for review feedback.

Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

@Alberto, Alexandros, thanks. Should be fixed now.

@Alberto, I have yet to check if we have overlapping buffer stream tests.

@Daniel, thanks for testing. I cannot see tearing in

mir_demo_client_egltriangle -f
mir_demo_client_eglplasma

I see tearing and general corruption when I run
mir_demo_client_egltriangle -f -n
However, when I run this on the trunk, the triangle moves once every second or so. Is this what youre seeing? And doesn't -n mean don't wait for vsync, so isn't tearing expected?

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

Cemil,

You're using radeon still right? In that case the "once every second or so" is sadly expected. See bug 1211700. Seems only intel has the ability to unthrottle rendering without starving the server process of GPU time. radeon and nouveau are not so good at fair scheduling the GPU. IIRC, proprietary drivers have no such problems. So I guess don't use the "-n" option on your machine. Still, tearing is obviously wrong.

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

BTW, bypass is weird. And I think kdub's overlay logic requires the same approach.

To avoid tearing the compositor has to briefly hold both (at least 2) of the client's buffers so as to retain the guarantee for the scan-out hardware that whatever is on-screen is not touched by the client till something else is definitely on screen.

// buffer B is on screen
acquire buffer A
scan out buffer A
release buffer B (to the client)
wait for vblank // allows client almost 16ms to render new B
acquire buffer B
scan out buffer B
release buffer A (to the client)
wait for vblank // allows client almost 16ms to render new A
acquire buffer A
scan out buffer A
release buffer B

That's for normal bypass/overlays. If you use "-n" then framedropping mode forces the BufferQueue to have at least 3 buffers {A,B,C}. So the screen can't ever be starved of the newest frame by an unthrottled client (that issue applies to all compositing, not just bypass). But we always guarantee that and that's not the (radeon) bug you're seeing.

lp:~cemil-azizoglu/mir/improve-raii updated
2378. By Cemil Azizoglu

Address CI failures.

Revision history for this message
Kevin DuBois (kdub) wrote :

> This is what happens when we rewrite test cases en-masse. Regression tests
> stop protecting us from regressions.

+1, and the tests that have been rewritten are some of the most carefully written to avoid sensitive problems. We haven't had a tearing regression in quite a while (12+ months), so changing so much core testing and swapping code makes me nervous, especially because tearing is a very public regression that everyone tends to notice.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

===
360 + release_fn = std::move(other.release_fn);
===

This has a similar issue:

From http://www.cplusplus.com/reference/functional/function/operator=/
"
(2) move assignment
The object acquires the target of rhs.
rhs is left in an unspecified but valid state.
"

The tearing occurs in bypass (or overlays with android) because the implementation of post_renderables_if_optimizable in mesa and android keep a copy of the shared_ptr<Buffer> to guarantee it wouldn't be released to the client. This has changed now, as holding a reference to the buffer no longer implies the same behavior. Some rework is needed there (which I think it's good, because we should avoid nebulous ownership semantics)

review: Needs Fixing
Revision history for this message
Kevin DuBois (kdub) wrote :

> implies the same behavior. Some rework is needed there (which I think it's
> good, because we should avoid nebulous ownership semantics)

I don't think the current semantics are nebulous. The TemporaryBuffers are a Buffer resource; they're a guarantee that they have a buffer locked for a particular purpose for a period of time. Likewise the {mgm/mga}::Buffers are a Buffer resource too, but they have the lifetime of the allocation we request from the driver.

Revision history for this message
Kevin DuBois (kdub) wrote :

>
> > implies the same behavior. Some rework is needed there (which I think it's
> > good, because we should avoid nebulous ownership semantics)
>
> I don't think the current semantics are nebulous. The TemporaryBuffers are a
> Buffer resource; they're a guarantee that they have a buffer locked for a
> particular purpose for a period of time. Likewise the {mgm/mga}::Buffers are a
> Buffer resource too, but they have the lifetime of the allocation we request
> from the driver.

Furthermore, from mg::Display::post_renderables_if_optimizable()'s perspective, the buffers that are sent there don't even have to be associated with the BufferQueue stuff. We'll hit problems with the cursor (and, in ~kdub/mir/demo-titlebar, the decorations), if we start requiring that the resource passed to the 2d optimized function is sourced from the BufferQueues.

lp:~cemil-azizoglu/mir/improve-raii updated
2379. By Cemil Azizoglu

Do away with unnecessary std::move()

2380. By Cemil Azizoglu

Fix another case of std::move(std::function()).

Unmerged revisions

2380. By Cemil Azizoglu

Fix another case of std::move(std::function()).

2379. By Cemil Azizoglu

Do away with unnecessary std::move()

2378. By Cemil Azizoglu

Address CI failures.

2377. By Cemil Azizoglu

Fixes for review feedback.

2376. By Cemil Azizoglu

Use make_shared.

2375. By Cemil Azizoglu

Fix Android.

2374. By Cemil Azizoglu

Add BufferHandle test.

2373. By Cemil Azizoglu

Fix test properly.

2372. By Cemil Azizoglu

Fix a test.

2371. By Cemil Azizoglu

Merge trunk

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== renamed file 'src/server/compositor/buffer_bundle.h' => 'src/include/server/mir/compositor/buffer_bundle.h'
--- src/server/compositor/buffer_bundle.h 2015-01-21 08:53:28 +0000
+++ src/include/server/mir/compositor/buffer_bundle.h 2015-03-20 19:31:52 +0000
@@ -29,6 +29,7 @@
2929
30namespace compositor30namespace compositor
31{31{
32class BufferHandle;
3233
33class BufferBundle34class BufferBundle
34{35{
@@ -48,16 +49,14 @@
48 * collisions, all callers should determine user_id49 * collisions, all callers should determine user_id
49 * in the same way (e.g. always use "this" pointer).50 * in the same way (e.g. always use "this" pointer).
50 */51 */
51 virtual std::shared_ptr<graphics::Buffer>52 virtual BufferHandle compositor_acquire(void const* user_id) = 0;
52 compositor_acquire(void const* user_id) = 0;53 virtual BufferHandle snapshot_acquire() = 0;
53 virtual void compositor_release(std::shared_ptr<graphics::Buffer> const&) = 0;
54 virtual std::shared_ptr<graphics::Buffer> snapshot_acquire() = 0;
55 virtual void snapshot_release(std::shared_ptr<graphics::Buffer> const&) = 0;
5654
57 virtual graphics::BufferProperties properties() const = 0;55 virtual graphics::BufferProperties properties() const = 0;
58 virtual void allow_framedropping(bool dropping_allowed) = 0;56 virtual void allow_framedropping(bool dropping_allowed) = 0;
59 virtual void force_requests_to_complete() = 0;57 virtual void force_requests_to_complete() = 0;
60 virtual void resize(const geometry::Size &newsize) = 0;58 virtual void resize(const geometry::Size &newsize) = 0;
59 virtual geometry::Size size() const = 0;
61 virtual int buffers_ready_for_compositor(void const* user_id) const = 0;60 virtual int buffers_ready_for_compositor(void const* user_id) const = 0;
6261
63 /**62 /**
6463
=== added file 'src/include/server/mir/compositor/buffer_handle.h'
--- src/include/server/mir/compositor/buffer_handle.h 1970-01-01 00:00:00 +0000
+++ src/include/server/mir/compositor/buffer_handle.h 2015-03-20 19:31:52 +0000
@@ -0,0 +1,61 @@
1/*
2 * Copyright © 2015 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 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:
17 * Cemil Azizoglu <cemil.azizoglu@canonical.com>
18 */
19
20#ifndef MIR_BUFFER_HANDLE_H_
21#define MIR_BUFFER_HANDLE_H_
22
23#include <memory>
24
25namespace mir
26{
27namespace graphics { class Buffer; }
28
29namespace compositor
30{
31
32typedef std::function<void(graphics::Buffer* buffer)> ReleaseCallback;
33
34class BufferHandle
35{
36public:
37 explicit BufferHandle(
38 std::shared_ptr<graphics::Buffer> const& buffer,
39 ReleaseCallback const& release);
40
41 BufferHandle(BufferHandle&& other);
42 BufferHandle& operator=(BufferHandle&& other);
43 BufferHandle() = default;
44
45 ~BufferHandle();
46
47 std::shared_ptr<graphics::Buffer> buffer();
48 bool operator!();
49
50private:
51 BufferHandle(BufferHandle const&) = delete;
52 BufferHandle& operator=(BufferHandle const&) = delete;
53
54 std::shared_ptr<graphics::Buffer> wrapped;
55 ReleaseCallback release_fn;
56};
57
58}
59}
60
61#endif /* MIR_BUFFER_HANDLE_H_*/
062
=== renamed file 'src/server/compositor/buffer_queue.h' => 'src/include/server/mir/compositor/buffer_queue.h'
--- src/server/compositor/buffer_queue.h 2015-03-06 03:52:41 +0000
+++ src/include/server/mir/compositor/buffer_queue.h 2015-03-20 19:31:52 +0000
@@ -37,7 +37,10 @@
37namespace compositor37namespace compositor
38{38{
3939
40class BufferQueue : public BufferBundle40class BufferHandle;
41
42class BufferQueue : public BufferBundle,
43 public std::enable_shared_from_this<BufferQueue>
41{44{
42public:45public:
43 typedef std::function<void(graphics::Buffer* buffer)> Callback;46 typedef std::function<void(graphics::Buffer* buffer)> Callback;
@@ -49,15 +52,14 @@
4952
50 void client_acquire(Callback complete) override;53 void client_acquire(Callback complete) override;
51 void client_release(graphics::Buffer* buffer) override;54 void client_release(graphics::Buffer* buffer) override;
52 std::shared_ptr<graphics::Buffer> compositor_acquire(void const* user_id) override;55 BufferHandle compositor_acquire(void const* user_id) override;
53 void compositor_release(std::shared_ptr<graphics::Buffer> const& buffer) override;56 BufferHandle snapshot_acquire() override;
54 std::shared_ptr<graphics::Buffer> snapshot_acquire() override;
55 void snapshot_release(std::shared_ptr<graphics::Buffer> const& buffer) override;
5657
57 graphics::BufferProperties properties() const override;58 graphics::BufferProperties properties() const override;
58 void allow_framedropping(bool dropping_allowed) override;59 void allow_framedropping(bool dropping_allowed) override;
59 void force_requests_to_complete() override;60 void force_requests_to_complete() override;
60 void resize(const geometry::Size &newsize) override;61 void resize(const geometry::Size &newsize) override;
62 geometry::Size size() const override;
61 int buffers_ready_for_compositor(void const* user_id) const override;63 int buffers_ready_for_compositor(void const* user_id) const override;
62 int buffers_free_for_client() const override;64 int buffers_free_for_client() const override;
63 bool framedropping_allowed() const;65 bool framedropping_allowed() const;
6466
=== removed file 'src/include/server/mir/compositor/buffer_stream.h'
--- src/include/server/mir/compositor/buffer_stream.h 2015-01-21 08:53:28 +0000
+++ src/include/server/mir/compositor/buffer_stream.h 1970-01-01 00:00:00 +0000
@@ -1,63 +0,0 @@
1/*
2 * Copyright © 2012-2014 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 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:
17 * Kevin DuBois <kevin.dubois@canonical.com>
18 */
19
20#ifndef MIR_COMPOSITOR_BUFFER_STREAM_H_
21#define MIR_COMPOSITOR_BUFFER_STREAM_H_
22
23#include "mir/geometry/size.h"
24#include "mir_toolkit/common.h"
25#include "mir/graphics/buffer_id.h"
26
27#include <memory>
28
29namespace mir
30{
31namespace graphics
32{
33class Buffer;
34}
35
36namespace compositor
37{
38
39class BufferStream
40{
41public:
42 virtual ~BufferStream() = default;
43
44 virtual void acquire_client_buffer(
45 std::function<void(graphics::Buffer* buffer)> complete) = 0;
46 virtual void release_client_buffer(graphics::Buffer* buf) = 0;
47 virtual std::shared_ptr<graphics::Buffer>
48 lock_compositor_buffer(void const* user_id) = 0;
49 virtual std::shared_ptr<graphics::Buffer> lock_snapshot_buffer() = 0;
50 virtual MirPixelFormat get_stream_pixel_format() = 0;
51 virtual geometry::Size stream_size() = 0;
52 virtual void resize(geometry::Size const& size) = 0;
53 virtual void allow_framedropping(bool) = 0;
54 virtual void force_requests_to_complete() = 0;
55 virtual int buffers_ready_for_compositor(void const* user_id) const = 0;
56 virtual void drop_old_buffers() = 0;
57 virtual void drop_client_requests() = 0;
58};
59
60}
61}
62
63#endif /* MIR_COMPOSITOR_BUFFER_STREAM_H_ */
640
=== modified file 'src/include/server/mir/default_server_configuration.h'
--- src/include/server/mir/default_server_configuration.h 2015-03-06 03:52:41 +0000
+++ src/include/server/mir/default_server_configuration.h 2015-03-20 19:31:52 +0000
@@ -45,7 +45,7 @@
45namespace compositor45namespace compositor
46{46{
47class Renderer;47class Renderer;
48class BufferStreamFactory;48class BufferQueueFactory;
49class Scene;49class Scene;
50class Drawer;50class Drawer;
51class DisplayBufferCompositorFactory;51class DisplayBufferCompositorFactory;
@@ -87,7 +87,7 @@
87{87{
88class SurfaceFactory;88class SurfaceFactory;
89class BroadcastingSessionEventSink;89class BroadcastingSessionEventSink;
90class BufferStreamFactory;90class BufferQueueFactory;
91class MediatingDisplayChanger;91class MediatingDisplayChanger;
92class PixelBuffer;92class PixelBuffer;
93class PlacementStrategy;93class PlacementStrategy;
@@ -278,7 +278,7 @@
278 /** @name scene configuration - dependencies278 /** @name scene configuration - dependencies
279 * dependencies of scene on the rest of the Mir279 * dependencies of scene on the rest of the Mir
280 * @{ */280 * @{ */
281 virtual std::shared_ptr<scene::BufferStreamFactory> the_buffer_stream_factory();281 virtual std::shared_ptr<scene::BufferQueueFactory> the_buffer_queue_factory();
282 virtual std::shared_ptr<scene::SceneReport> the_scene_report();282 virtual std::shared_ptr<scene::SceneReport> the_scene_report();
283 /** @} */283 /** @} */
284284
@@ -389,7 +389,7 @@
389 CachedPtr<frontend::ConnectionCreator> prompt_connection_creator;389 CachedPtr<frontend::ConnectionCreator> prompt_connection_creator;
390 CachedPtr<frontend::Screencast> screencast;390 CachedPtr<frontend::Screencast> screencast;
391 CachedPtr<compositor::RendererFactory> renderer_factory;391 CachedPtr<compositor::RendererFactory> renderer_factory;
392 CachedPtr<compositor::BufferStreamFactory> buffer_stream_factory;392 CachedPtr<compositor::BufferQueueFactory> buffer_queue_factory;
393 CachedPtr<compositor::FrameDroppingPolicyFactory> frame_dropping_policy_factory;393 CachedPtr<compositor::FrameDroppingPolicyFactory> frame_dropping_policy_factory;
394 CachedPtr<scene::SurfaceStack> surface_stack;394 CachedPtr<scene::SurfaceStack> surface_stack;
395 CachedPtr<scene::SceneReport> scene_report;395 CachedPtr<scene::SceneReport> scene_report;
396396
=== renamed file 'src/include/server/mir/scene/buffer_stream_factory.h' => 'src/include/server/mir/scene/buffer_queue_factory.h'
--- src/include/server/mir/scene/buffer_stream_factory.h 2015-03-16 03:39:55 +0000
+++ src/include/server/mir/scene/buffer_queue_factory.h 2015-03-20 19:31:52 +0000
@@ -18,33 +18,33 @@
18 * Thomas Voss <thomas.voss@canonical.com>18 * Thomas Voss <thomas.voss@canonical.com>
19 */19 */
2020
21#ifndef MIR_SCENE_BUFFER_STREAM_FACTORY_H_21#ifndef MIR_SCENE_BUFFER_QUEUE_FACTORY_H_
22#define MIR_SCENE_BUFFER_STREAM_FACTORY_H_22#define MIR_SCENE_BUFFER_QUEUE_FACTORY_H_
2323
24#include <memory>24#include <memory>
2525
26namespace mir26namespace mir
27{27{
28namespace compositor { class BufferStream; }28namespace compositor { class BufferBundle; }
29namespace graphics { struct BufferProperties; }29namespace graphics { struct BufferProperties; }
3030
31namespace scene31namespace scene
32{32{
33class BufferStreamFactory33class BufferQueueFactory
34{34{
35public:35public:
36 virtual ~BufferStreamFactory() = default;36 virtual ~BufferQueueFactory() = default;
3737
38 virtual std::shared_ptr<compositor::BufferStream> create_buffer_stream(38 virtual std::shared_ptr<compositor::BufferBundle> create_buffer_queue(
39 int nbuffers, graphics::BufferProperties const& buffer_properties) = 0;39 int nbuffers, graphics::BufferProperties const& buffer_properties) = 0;
4040
41protected:41protected:
42 BufferStreamFactory() = default;42 BufferQueueFactory() = default;
43 BufferStreamFactory(const BufferStreamFactory&) = delete;43 BufferQueueFactory(const BufferQueueFactory&) = delete;
44 BufferStreamFactory& operator=(const BufferStreamFactory&) = delete;44 BufferQueueFactory& operator=(const BufferQueueFactory&) = delete;
45};45};
4646
47}47}
48}48}
4949
50#endif // MIR_SCENE_BUFFER_STREAM_FACTORY_H_50#endif // MIR_SCENE_BUFFER_QUEUE_FACTORY_H_
5151
=== modified file 'src/server/compositor/CMakeLists.txt'
--- src/server/compositor/CMakeLists.txt 2015-01-21 07:34:50 +0000
+++ src/server/compositor/CMakeLists.txt 2015-03-20 19:31:52 +0000
@@ -3,9 +3,7 @@
33
4 default_display_buffer_compositor.cpp4 default_display_buffer_compositor.cpp
5 default_display_buffer_compositor_factory.cpp5 default_display_buffer_compositor_factory.cpp
6 temporary_buffers.cpp6 buffer_queue_factory.cpp
7 buffer_stream_factory.cpp
8 buffer_stream_surfaces.cpp
9 gl_renderer.cpp7 gl_renderer.cpp
10 gl_renderer_factory.cpp8 gl_renderer_factory.cpp
11 gl_program_family.cpp9 gl_program_family.cpp
@@ -16,6 +14,7 @@
16 compositing_screencast.cpp14 compositing_screencast.cpp
17 timeout_frame_dropping_policy_factory.cpp15 timeout_frame_dropping_policy_factory.cpp
18 buffer_queue.cpp16 buffer_queue.cpp
17 buffer_handle.cpp
19 recently_used_cache.cpp18 recently_used_cache.cpp
20)19)
2120
2221
=== added file 'src/server/compositor/buffer_handle.cpp'
--- src/server/compositor/buffer_handle.cpp 1970-01-01 00:00:00 +0000
+++ src/server/compositor/buffer_handle.cpp 2015-03-20 19:31:52 +0000
@@ -0,0 +1,63 @@
1/*
2 * Copyright © 2015 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 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: Cemil Azizoglu <cemil.azizoglu@canonical.com>
17 */
18
19#include "mir/compositor/buffer_handle.h"
20
21namespace mc = mir::compositor;
22namespace mg = mir::graphics;
23
24mc::BufferHandle::BufferHandle(std::shared_ptr<mg::Buffer> const& buffer,
25 ReleaseCallback const& release)
26 : wrapped(buffer),
27 release_fn(release)
28{
29}
30
31mc::BufferHandle::BufferHandle(BufferHandle&& other)
32 : wrapped(std::move(other.wrapped))
33{
34 // We can't std:move a std::function as it leaves the "other" unspecified
35 release_fn.swap(other.release_fn);
36}
37
38mc::BufferHandle& mc::BufferHandle::operator=(BufferHandle&& other)
39{
40 if (this != &other)
41 {
42 wrapped = std::move(other.wrapped);
43 release_fn.swap(other.release_fn);
44 }
45
46 return *this;
47}
48
49bool mc::BufferHandle::operator!()
50{
51 return (wrapped == nullptr);
52}
53
54mc::BufferHandle::~BufferHandle()
55{
56 if (release_fn)
57 release_fn(wrapped.get());
58}
59
60std::shared_ptr<mg::Buffer> mc::BufferHandle::buffer()
61{
62 return wrapped;
63}
064
=== modified file 'src/server/compositor/buffer_queue.cpp'
--- src/server/compositor/buffer_queue.cpp 2015-03-06 03:52:41 +0000
+++ src/server/compositor/buffer_queue.cpp 2015-03-20 19:31:52 +0000
@@ -15,10 +15,11 @@
15 *15 *
16 */16 */
1717
18#include "buffer_queue.h"18#include "mir/compositor/buffer_queue.h"
1919
20#include "mir/graphics/graphic_buffer_allocator.h"20#include "mir/graphics/graphic_buffer_allocator.h"
21#include "mir/graphics/buffer_id.h"21#include "mir/graphics/buffer_id.h"
22#include "mir/compositor/buffer_handle.h"
22#include "mir/lockable_callback.h"23#include "mir/lockable_callback.h"
2324
24#include <boost/throw_exception.hpp>25#include <boost/throw_exception.hpp>
@@ -28,6 +29,7 @@
2829
29namespace mc = mir::compositor;30namespace mc = mir::compositor;
30namespace mg = mir::graphics;31namespace mg = mir::graphics;
32namespace geom = mir::geometry;
3133
32namespace34namespace
33{35{
@@ -239,8 +241,7 @@
239 ready_to_composite_queue.push_back(buffer);241 ready_to_composite_queue.push_back(buffer);
240}242}
241243
242std::shared_ptr<mg::Buffer>244mc::BufferHandle mc::BufferQueue::compositor_acquire(void const* user_id)
243mc::BufferQueue::compositor_acquire(void const* user_id)
244{245{
245 std::unique_lock<decltype(guard)> lock(guard);246 std::unique_lock<decltype(guard)> lock(guard);
246247
@@ -285,53 +286,56 @@
285286
286 buffers_sent_to_compositor.push_back(current_compositor_buffer);287 buffers_sent_to_compositor.push_back(current_compositor_buffer);
287288
288 std::shared_ptr<mg::Buffer> const acquired_buffer =289 std::weak_ptr<BufferQueue> weak_this = shared_from_this();
289 buffer_for(current_compositor_buffer, buffers);290
291 mc::BufferHandle acquired_buffer(
292 buffer_for(current_compositor_buffer, buffers),
293 [weak_this](mg::Buffer* b)
294 {
295 if (auto self = weak_this.lock())
296 {
297 std::unique_lock<decltype(self->guard)> lock(self->guard);
298
299 remove(b, self->buffers_sent_to_compositor);
300
301 /* Not ready to release it yet, other compositors still reference this buffer */
302 if (contains(b, self->buffers_sent_to_compositor))
303 return;
304
305 if (self->nbuffers <= 1)
306 return;
307
308 if (self->current_compositor_buffer != b)
309 self->release(b, std::move(lock));
310 }
311 });
290312
291 if (buffer_to_release)313 if (buffer_to_release)
292 release(buffer_to_release, std::move(lock));314 release(buffer_to_release, std::move(lock));
293315
294 return acquired_buffer;316 return std::move(acquired_buffer);
295}317}
296318
297void mc::BufferQueue::compositor_release(std::shared_ptr<graphics::Buffer> const& buffer)319mc::BufferHandle mc::BufferQueue::snapshot_acquire()
298{
299 std::unique_lock<decltype(guard)> lock(guard);
300
301 if (!remove(buffer.get(), buffers_sent_to_compositor))
302 {
303 BOOST_THROW_EXCEPTION(
304 std::logic_error("unexpected release: buffer was not given to compositor"));
305 }
306
307 /* Not ready to release it yet, other compositors still reference this buffer */
308 if (contains(buffer.get(), buffers_sent_to_compositor))
309 return;
310
311 if (nbuffers <= 1)
312 return;
313
314 if (current_compositor_buffer != buffer.get())
315 release(buffer.get(), std::move(lock));
316}
317
318std::shared_ptr<mg::Buffer> mc::BufferQueue::snapshot_acquire()
319{320{
320 std::unique_lock<decltype(guard)> lock(guard);321 std::unique_lock<decltype(guard)> lock(guard);
321 pending_snapshots.push_back(current_compositor_buffer);322 pending_snapshots.push_back(current_compositor_buffer);
322 return buffer_for(current_compositor_buffer, buffers);323
323}324 std::weak_ptr<BufferQueue> weak_this = shared_from_this();
324325
325void mc::BufferQueue::snapshot_release(std::shared_ptr<graphics::Buffer> const& buffer)326 return std::move(mc::BufferHandle(
326{327 buffer_for(current_compositor_buffer, buffers),
327 std::unique_lock<std::mutex> lock(guard);328 [weak_this](mg::Buffer* b)
328 if (!remove(buffer.get(), pending_snapshots))329 {
329 {330 if (auto self = weak_this.lock())
330 BOOST_THROW_EXCEPTION(331 {
331 std::logic_error("unexpected release: no buffers were given to snapshotter"));332 std::unique_lock<std::mutex> lock(self->guard);
332 }333
333334 remove(b, self->pending_snapshots);
334 snapshot_released.notify_all();335
336 self->snapshot_released.notify_all();
337 }
338 }));
335}339}
336340
337mg::BufferProperties mc::BufferQueue::properties() const341mg::BufferProperties mc::BufferQueue::properties() const
@@ -367,6 +371,11 @@
367 }371 }
368}372}
369373
374geom::Size mc::BufferQueue::size() const
375{
376 return properties().size;
377}
378
370void mc::BufferQueue::resize(geometry::Size const& new_size)379void mc::BufferQueue::resize(geometry::Size const& new_size)
371{380{
372 std::lock_guard<decltype(guard)> lock(guard);381 std::lock_guard<decltype(guard)> lock(guard);
373382
=== renamed file 'src/server/compositor/buffer_stream_factory.cpp' => 'src/server/compositor/buffer_queue_factory.cpp'
--- src/server/compositor/buffer_stream_factory.cpp 2015-03-16 03:39:55 +0000
+++ src/server/compositor/buffer_queue_factory.cpp 2015-03-20 19:31:52 +0000
@@ -18,10 +18,9 @@
18 * Thomas Voss <thomas.voss@canonical.com>18 * Thomas Voss <thomas.voss@canonical.com>
19 */19 */
2020
21#include "buffer_stream_factory.h"21#include "buffer_queue_factory.h"
22#include "buffer_stream_surfaces.h"
23#include "mir/graphics/buffer_properties.h"22#include "mir/graphics/buffer_properties.h"
24#include "buffer_queue.h"23#include "mir/compositor/buffer_queue.h"
25#include "mir/graphics/buffer.h"24#include "mir/graphics/buffer.h"
26#include "mir/graphics/buffer_id.h"25#include "mir/graphics/buffer_id.h"
27#include "mir/graphics/graphic_buffer_allocator.h"26#include "mir/graphics/graphic_buffer_allocator.h"
@@ -32,10 +31,9 @@
3231
33namespace mc = mir::compositor;32namespace mc = mir::compositor;
34namespace mg = mir::graphics;33namespace mg = mir::graphics;
35namespace ms = mir::scene;
3634
37mc::BufferStreamFactory::BufferStreamFactory(std::shared_ptr<mg::GraphicBufferAllocator> const& gralloc,35mc::BufferQueueFactory::BufferQueueFactory(std::shared_ptr<mg::GraphicBufferAllocator> const& gralloc,
38 std::shared_ptr<mc::FrameDroppingPolicyFactory> const& policy_factory)36 std::shared_ptr<mc::FrameDroppingPolicyFactory> const& policy_factory)
39 : gralloc(gralloc),37 : gralloc(gralloc),
40 policy_factory{policy_factory}38 policy_factory{policy_factory}
41{39{
@@ -43,11 +41,8 @@
43 assert(policy_factory);41 assert(policy_factory);
44}42}
4543
4644std::shared_ptr<mc::BufferBundle> mc::BufferQueueFactory::create_buffer_queue(
47std::shared_ptr<mc::BufferStream> mc::BufferStreamFactory::create_buffer_stream(45 int nbuffers, mg::BufferProperties const& buffer_properties)
48 int nbuffers, mg::BufferProperties const& buffer_properties)
49{46{
50 auto switching_bundle = std::make_shared<mc::BufferQueue>(47 return std::make_shared<mc::BufferQueue>(nbuffers, gralloc, buffer_properties, *policy_factory);
51 nbuffers, gralloc, buffer_properties, *policy_factory);
52 return std::make_shared<mc::BufferStreamSurfaces>(switching_bundle);
53}48}
5449
=== renamed file 'src/server/compositor/buffer_stream_factory.h' => 'src/server/compositor/buffer_queue_factory.h'
--- src/server/compositor/buffer_stream_factory.h 2015-03-16 03:39:55 +0000
+++ src/server/compositor/buffer_queue_factory.h 2015-03-20 19:31:52 +0000
@@ -18,10 +18,10 @@
18 * Thomas Voss <thomas.voss@canonical.com>18 * Thomas Voss <thomas.voss@canonical.com>
19 */19 */
2020
21#ifndef MIR_COMPOSITOR_BUFFER_STREAM_FACTORY_H_21#ifndef MIR_COMPOSITOR_BUFFER_QUEUE_FACTORY_H_
22#define MIR_COMPOSITOR_BUFFER_STREAM_FACTORY_H_22#define MIR_COMPOSITOR_BUFFER_QUEUE_FACTORY_H_
2323
24#include "mir/scene/buffer_stream_factory.h"24#include "mir/scene/buffer_queue_factory.h"
25#include "mir/compositor/frame_dropping_policy_factory.h"25#include "mir/compositor/frame_dropping_policy_factory.h"
2626
27#include <memory>27#include <memory>
@@ -35,16 +35,16 @@
35namespace compositor35namespace compositor
36{36{
3737
38class BufferStreamFactory : public scene::BufferStreamFactory38class BufferQueueFactory : public scene::BufferQueueFactory
39{39{
40public:40public:
41 BufferStreamFactory(std::shared_ptr<graphics::GraphicBufferAllocator> const& gralloc,41 BufferQueueFactory(std::shared_ptr<graphics::GraphicBufferAllocator> const& gralloc,
42 std::shared_ptr<FrameDroppingPolicyFactory> const& policy_factory);42 std::shared_ptr<FrameDroppingPolicyFactory> const& policy_factory);
4343
44 virtual ~BufferStreamFactory() {}44 virtual ~BufferQueueFactory() {}
4545
46 virtual std::shared_ptr<BufferStream> create_buffer_stream(46 virtual std::shared_ptr<BufferBundle> create_buffer_queue(
47 int nbuffers, graphics::BufferProperties const&) override;47 int nbuffers, graphics::BufferProperties const& buffer_properties) override;
4848
49private:49private:
50 std::shared_ptr<graphics::GraphicBufferAllocator> gralloc;50 std::shared_ptr<graphics::GraphicBufferAllocator> gralloc;
@@ -55,4 +55,4 @@
55}55}
5656
5757
58#endif /* MIR_COMPOSITOR_BUFFER_STREAM_FACTORY_H_ */58#endif /* MIR_COMPOSITOR_BUFFER_QUEUE_FACTORY_H_ */
5959
=== removed file 'src/server/compositor/buffer_stream_surfaces.cpp'
--- src/server/compositor/buffer_stream_surfaces.cpp 2015-01-21 08:53:28 +0000
+++ src/server/compositor/buffer_stream_surfaces.cpp 1970-01-01 00:00:00 +0000
@@ -1,101 +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 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:
17 * Kevin DuBois <kevin.dubois@canonical.com>
18 */
19
20#include "buffer_stream_surfaces.h"
21#include "buffer_bundle.h"
22#include "mir/graphics/buffer_properties.h"
23
24#include "temporary_buffers.h"
25
26namespace mc = mir::compositor;
27namespace mg = mir::graphics;
28namespace geom = mir::geometry;
29
30mc::BufferStreamSurfaces::BufferStreamSurfaces(std::shared_ptr<BufferBundle> const& buffer_bundle)
31 : buffer_bundle(buffer_bundle)
32{
33}
34
35mc::BufferStreamSurfaces::~BufferStreamSurfaces()
36{
37 force_requests_to_complete();
38}
39
40std::shared_ptr<mg::Buffer> mc::BufferStreamSurfaces::lock_compositor_buffer(
41 void const* user_id)
42{
43 return std::make_shared<mc::TemporaryCompositorBuffer>(
44 buffer_bundle, user_id);
45}
46
47std::shared_ptr<mg::Buffer> mc::BufferStreamSurfaces::lock_snapshot_buffer()
48{
49 return std::make_shared<mc::TemporarySnapshotBuffer>(buffer_bundle);
50}
51
52void mc::BufferStreamSurfaces::acquire_client_buffer(
53 std::function<void(graphics::Buffer* buffer)> complete)
54{
55 buffer_bundle->client_acquire(complete);
56}
57
58void mc::BufferStreamSurfaces::release_client_buffer(graphics::Buffer* buf)
59{
60 buffer_bundle->client_release(buf);
61}
62
63MirPixelFormat mc::BufferStreamSurfaces::get_stream_pixel_format()
64{
65 return buffer_bundle->properties().format;
66}
67
68geom::Size mc::BufferStreamSurfaces::stream_size()
69{
70 return buffer_bundle->properties().size;
71}
72
73void mc::BufferStreamSurfaces::resize(geom::Size const& size)
74{
75 buffer_bundle->resize(size);
76}
77
78void mc::BufferStreamSurfaces::force_requests_to_complete()
79{
80 buffer_bundle->force_requests_to_complete();
81}
82
83void mc::BufferStreamSurfaces::allow_framedropping(bool allow)
84{
85 buffer_bundle->allow_framedropping(allow);
86}
87
88int mc::BufferStreamSurfaces::buffers_ready_for_compositor(void const* user_id) const
89{
90 return buffer_bundle->buffers_ready_for_compositor(user_id);
91}
92
93void mc::BufferStreamSurfaces::drop_old_buffers()
94{
95 buffer_bundle->drop_old_buffers();
96}
97
98void mc::BufferStreamSurfaces::drop_client_requests()
99{
100 buffer_bundle->drop_client_requests();
101}
1020
=== removed file 'src/server/compositor/buffer_stream_surfaces.h'
--- src/server/compositor/buffer_stream_surfaces.h 2015-01-21 08:53:28 +0000
+++ src/server/compositor/buffer_stream_surfaces.h 1970-01-01 00:00:00 +0000
@@ -1,69 +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 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:
17 * Kevin DuBois <kevin.dubois@canonical.com>
18 */
19
20#ifndef MIR_COMPOSITOR_BUFFER_STREAM_SCENE_H_
21#define MIR_COMPOSITOR_BUFFER_STREAM_SCENE_H_
22
23#include "mir/compositor/buffer_stream.h"
24
25#include <mutex>
26
27namespace mir
28{
29namespace compositor
30{
31
32class BufferIDUniqueGenerator;
33class BufferBundle;
34class BackBufferStrategy;
35
36class BufferStreamSurfaces : public BufferStream
37{
38public:
39 BufferStreamSurfaces(std::shared_ptr<BufferBundle> const& swapper);
40 ~BufferStreamSurfaces();
41
42 void acquire_client_buffer(std::function<void(graphics::Buffer* buffer)> complete) override;
43 void release_client_buffer(graphics::Buffer* buf) override;
44
45 std::shared_ptr<graphics::Buffer>
46 lock_compositor_buffer(void const* user_id) override;
47 std::shared_ptr<graphics::Buffer> lock_snapshot_buffer() override;
48
49 MirPixelFormat get_stream_pixel_format() override;
50 geometry::Size stream_size() override;
51 void resize(geometry::Size const& size) override;
52 void allow_framedropping(bool) override;
53 void force_requests_to_complete() override;
54 int buffers_ready_for_compositor(void const* user_id) const override;
55 void drop_old_buffers() override;
56 void drop_client_requests() override;
57
58protected:
59 BufferStreamSurfaces(const BufferStreamSurfaces&) = delete;
60 BufferStreamSurfaces& operator=(const BufferStreamSurfaces&) = delete;
61
62private:
63 std::shared_ptr<BufferBundle> const buffer_bundle;
64};
65
66}
67}
68
69#endif /* MIR_COMPOSITOR_BUFFER_STREAM_SCENE_H_ */
700
=== modified file 'src/server/compositor/default_configuration.cpp'
--- src/server/compositor/default_configuration.cpp 2015-03-12 03:19:52 +0000
+++ src/server/compositor/default_configuration.cpp 2015-03-20 19:31:52 +0000
@@ -19,7 +19,7 @@
19#include "mir/default_server_configuration.h"19#include "mir/default_server_configuration.h"
2020
21#include "mir/shell/shell.h"21#include "mir/shell/shell.h"
22#include "buffer_stream_factory.h"22#include "buffer_queue_factory.h"
23#include "default_display_buffer_compositor_factory.h"23#include "default_display_buffer_compositor_factory.h"
24#include "multi_threaded_compositor.h"24#include "multi_threaded_compositor.h"
25#include "gl_renderer_factory.h"25#include "gl_renderer_factory.h"
@@ -36,14 +36,14 @@
36namespace ms = mir::scene;36namespace ms = mir::scene;
37namespace mf = mir::frontend;37namespace mf = mir::frontend;
3838
39std::shared_ptr<ms::BufferStreamFactory>39std::shared_ptr<ms::BufferQueueFactory>
40mir::DefaultServerConfiguration::the_buffer_stream_factory()40mir::DefaultServerConfiguration::the_buffer_queue_factory()
41{41{
42 return buffer_stream_factory(42 return buffer_queue_factory(
43 [this]()43 [this]()
44 {44 {
45 return std::make_shared<mc::BufferStreamFactory>(the_buffer_allocator(),45 return std::make_shared<mc::BufferQueueFactory>(the_buffer_allocator(),
46 the_frame_dropping_policy_factory());46 the_frame_dropping_policy_factory());
47 });47 });
48}48}
4949
5050
=== modified file 'src/server/compositor/default_display_buffer_compositor.cpp'
--- src/server/compositor/default_display_buffer_compositor.cpp 2015-03-12 03:19:52 +0000
+++ src/server/compositor/default_display_buffer_compositor.cpp 2015-03-20 19:31:52 +0000
@@ -25,7 +25,6 @@
25#include "mir/graphics/renderable.h"25#include "mir/graphics/renderable.h"
26#include "mir/graphics/display_buffer.h"26#include "mir/graphics/display_buffer.h"
27#include "mir/graphics/buffer.h"27#include "mir/graphics/buffer.h"
28#include "mir/compositor/buffer_stream.h"
29#include "occlusion.h"28#include "occlusion.h"
30#include <mutex>29#include <mutex>
31#include <cstdlib>30#include <cstdlib>
3231
=== modified file 'src/server/compositor/gl_renderer.cpp'
--- src/server/compositor/gl_renderer.cpp 2015-03-06 03:52:41 +0000
+++ src/server/compositor/gl_renderer.cpp 2015-03-20 19:31:52 +0000
@@ -17,7 +17,6 @@
1717
18#define MIR_LOG_COMPONENT "GL"18#define MIR_LOG_COMPONENT "GL"
19#include "mir/compositor/gl_renderer.h"19#include "mir/compositor/gl_renderer.h"
20#include "mir/compositor/buffer_stream.h"
21#include "mir/compositor/destination_alpha.h"20#include "mir/compositor/destination_alpha.h"
22#include "mir/graphics/renderable.h"21#include "mir/graphics/renderable.h"
23#include "mir/graphics/buffer.h"22#include "mir/graphics/buffer.h"
2423
=== removed file 'src/server/compositor/temporary_buffers.cpp'
--- src/server/compositor/temporary_buffers.cpp 2015-03-06 03:52:41 +0000
+++ src/server/compositor/temporary_buffers.cpp 1970-01-01 00:00:00 +0000
@@ -1,92 +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 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_bundle.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<BufferBundle> const& bun, void const* user_id)
36 : TemporaryBuffer(bun->compositor_acquire(user_id)),
37 bundle(bun)
38{
39}
40
41mc::TemporaryCompositorBuffer::~TemporaryCompositorBuffer()
42{
43 bundle->compositor_release(buffer);
44}
45
46mc::TemporarySnapshotBuffer::TemporarySnapshotBuffer(
47 std::shared_ptr<BufferBundle> const& bun)
48 : TemporaryBuffer(bun->snapshot_acquire()),
49 bundle(bun)
50{
51}
52
53mc::TemporarySnapshotBuffer::~TemporarySnapshotBuffer()
54{
55 bundle->snapshot_release(buffer);
56}
57
58geom::Size mc::TemporaryBuffer::size() const
59{
60 return buffer->size();
61}
62
63geom::Stride mc::TemporaryBuffer::stride() const
64{
65 return buffer->stride();
66}
67
68MirPixelFormat mc::TemporaryBuffer::pixel_format() const
69{
70 return buffer->pixel_format();
71}
72
73mg::BufferID mc::TemporaryBuffer::id() const
74{
75 return buffer->id();
76}
77
78void mc::TemporaryBuffer::gl_bind_to_texture()
79{
80 buffer->gl_bind_to_texture();
81}
82
83std::shared_ptr<mg::NativeBuffer> mc::TemporaryBuffer::native_buffer_handle() const
84{
85 return buffer->native_buffer_handle();
86}
87
88void mc::TemporaryBuffer::write(unsigned char const*, size_t)
89{
90 BOOST_THROW_EXCEPTION(
91 std::runtime_error("Write to temporary buffer snapshot is ill advised and indicates programmer error"));
92}
930
=== removed file 'src/server/compositor/temporary_buffers.h'
--- src/server/compositor/temporary_buffers.h 2015-03-06 03:52:41 +0000
+++ src/server/compositor/temporary_buffers.h 1970-01-01 00:00:00 +0000
@@ -1,76 +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 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 BufferBundle;
33class BackBufferStrategy;
34
35class TemporaryBuffer : public mg::Buffer
36{
37public:
38 geometry::Size size() const override;
39 geometry::Stride stride() const override;
40 MirPixelFormat pixel_format() const override;
41 mg::BufferID id() const override;
42 void gl_bind_to_texture() override;
43 std::shared_ptr<mg::NativeBuffer> native_buffer_handle() const override;
44 void write (unsigned char const* data, size_t size) override;
45
46protected:
47 explicit TemporaryBuffer(std::shared_ptr<mg::Buffer> const& real_buffer);
48 std::shared_ptr<mg::Buffer> const buffer;
49};
50
51class TemporaryCompositorBuffer : public TemporaryBuffer
52{
53public:
54 explicit TemporaryCompositorBuffer(
55 std::shared_ptr<BufferBundle> const& bun, void const* user_id);
56 ~TemporaryCompositorBuffer();
57
58private:
59 std::shared_ptr<BufferBundle> const bundle;
60};
61
62class TemporarySnapshotBuffer : public TemporaryBuffer
63{
64public:
65 explicit TemporarySnapshotBuffer(
66 std::shared_ptr<BufferBundle> const& bun);
67 ~TemporarySnapshotBuffer();
68
69private:
70 std::shared_ptr<BufferBundle> const bundle;
71};
72
73}
74}
75
76#endif /* MIR_COMPOSITOR_TEMPORARY_BUFFERS_H_ */
770
=== modified file 'src/server/frontend/session_mediator.cpp'
--- src/server/frontend/session_mediator.cpp 2015-03-13 05:12:55 +0000
+++ src/server/frontend/session_mediator.cpp 2015-03-20 19:31:52 +0000
@@ -30,7 +30,6 @@
30#include "mir/graphics/buffer_id.h"30#include "mir/graphics/buffer_id.h"
31#include "mir/graphics/buffer.h"31#include "mir/graphics/buffer.h"
32#include "mir/input/cursor_images.h"32#include "mir/input/cursor_images.h"
33#include "mir/compositor/buffer_stream.h"
34#include "mir/geometry/dimensions.h"33#include "mir/geometry/dimensions.h"
35#include "mir/frontend/display_changer.h"34#include "mir/frontend/display_changer.h"
36#include "mir/graphics/display_configuration.h"35#include "mir/graphics/display_configuration.h"
3736
=== modified file 'src/server/scene/basic_surface.cpp'
--- src/server/scene/basic_surface.cpp 2015-03-18 18:48:02 +0000
+++ src/server/scene/basic_surface.cpp 2015-03-20 19:31:52 +0000
@@ -19,15 +19,14 @@
19 */19 */
2020
21#include "basic_surface.h"21#include "basic_surface.h"
22#include "mir/compositor/buffer_stream.h"
23#include "mir/frontend/event_sink.h"22#include "mir/frontend/event_sink.h"
24#include "mir/input/input_channel.h"23#include "mir/input/input_channel.h"
25#include "mir/shell/input_targeter.h"24#include "mir/shell/input_targeter.h"
26#include "mir/input/input_sender.h"25#include "mir/input/input_sender.h"
27#include "mir/graphics/buffer.h"26#include "mir/graphics/buffer.h"
28#include "mir/geometry/displacement.h"27#include "mir/geometry/displacement.h"
29
30#include "mir/scene/scene_report.h"28#include "mir/scene/scene_report.h"
29#include "mir/compositor/buffer_bundle.h"
3130
32#include <boost/throw_exception.hpp>31#include <boost/throw_exception.hpp>
3332
@@ -119,7 +118,7 @@
119 geometry::Rectangle rect,118 geometry::Rectangle rect,
120 std::weak_ptr<Surface> const& parent,119 std::weak_ptr<Surface> const& parent,
121 bool nonrectangular,120 bool nonrectangular,
122 std::shared_ptr<mc::BufferStream> const& buffer_stream,121 std::shared_ptr<mc::BufferBundle> const& buffer_queue,
123 std::shared_ptr<mi::InputChannel> const& input_channel,122 std::shared_ptr<mi::InputChannel> const& input_channel,
124 std::shared_ptr<input::InputSender> const& input_sender,123 std::shared_ptr<input::InputSender> const& input_sender,
125 std::shared_ptr<mg::CursorImage> const& cursor_image,124 std::shared_ptr<mg::CursorImage> const& cursor_image,
@@ -132,7 +131,7 @@
132 input_mode(mi::InputReceptionMode::normal),131 input_mode(mi::InputReceptionMode::normal),
133 nonrectangular(nonrectangular),132 nonrectangular(nonrectangular),
134 custom_input_rectangles(),133 custom_input_rectangles(),
135 surface_buffer_stream(buffer_stream),134 buffer_queue(buffer_queue),
136 server_input_channel(input_channel),135 server_input_channel(input_channel),
137 input_sender(input_sender),136 input_sender(input_sender),
138 cursor_image_(cursor_image),137 cursor_image_(cursor_image),
@@ -146,32 +145,27 @@
146 std::string const& name,145 std::string const& name,
147 geometry::Rectangle rect,146 geometry::Rectangle rect,
148 bool nonrectangular,147 bool nonrectangular,
149 std::shared_ptr<mc::BufferStream> const& buffer_stream,148 std::shared_ptr<mc::BufferBundle> const& buffer_queue,
150 std::shared_ptr<mi::InputChannel> const& input_channel,149 std::shared_ptr<mi::InputChannel> const& input_channel,
151 std::shared_ptr<input::InputSender> const& input_sender,150 std::shared_ptr<input::InputSender> const& input_sender,
152 std::shared_ptr<mg::CursorImage> const& cursor_image,151 std::shared_ptr<mg::CursorImage> const& cursor_image,
153 std::shared_ptr<SceneReport> const& report) :152 std::shared_ptr<SceneReport> const& report) :
154 BasicSurface(name, rect, std::shared_ptr<Surface>{nullptr}, nonrectangular,buffer_stream,153 BasicSurface(name, rect, std::shared_ptr<Surface>{nullptr}, nonrectangular, buffer_queue,
155 input_channel, input_sender, cursor_image, report)154 input_channel, input_sender, cursor_image, report)
156{155{
157}156}
158157
159void ms::BasicSurface::force_requests_to_complete()158void ms::BasicSurface::force_requests_to_complete()
160{159{
161 surface_buffer_stream->force_requests_to_complete();160 buffer_queue->force_requests_to_complete();
162}161}
163162
164ms::BasicSurface::~BasicSurface() noexcept163ms::BasicSurface::~BasicSurface() noexcept
165{164{
166 report->surface_deleted(this, surface_name);165 report->surface_deleted(this, surface_name);
167166
168 if (surface_buffer_stream) // some tests use null for surface_buffer_stream167 if (buffer_queue)
169 surface_buffer_stream->drop_client_requests();168 buffer_queue->drop_client_requests();
170}
171
172std::shared_ptr<mc::BufferStream> ms::BasicSurface::buffer_stream() const
173{
174 return surface_buffer_stream;
175}169}
176170
177std::string ms::BasicSurface::name() const171std::string ms::BasicSurface::name() const
@@ -217,14 +211,14 @@
217211
218MirPixelFormat ms::BasicSurface::pixel_format() const212MirPixelFormat ms::BasicSurface::pixel_format() const
219{213{
220 return surface_buffer_stream->get_stream_pixel_format();214 return buffer_queue->properties().format;
221}215}
222216
223void ms::BasicSurface::swap_buffers(mg::Buffer* old_buffer, std::function<void(mg::Buffer* new_buffer)> complete)217void ms::BasicSurface::swap_buffers(mg::Buffer* old_buffer, std::function<void(mg::Buffer* new_buffer)> complete)
224{218{
225 if (old_buffer)219 if (old_buffer)
226 {220 {
227 surface_buffer_stream->release_client_buffer(old_buffer);221 buffer_queue->client_release(old_buffer);
228 {222 {
229 std::unique_lock<std::mutex> lk(guard);223 std::unique_lock<std::mutex> lk(guard);
230 first_frame_posted = true;224 first_frame_posted = true;
@@ -238,17 +232,12 @@
238 observers.frame_posted(1);232 observers.frame_posted(1);
239 }233 }
240234
241 surface_buffer_stream->acquire_client_buffer(complete);235 buffer_queue->client_acquire(complete);
242}236}
243237
244void ms::BasicSurface::allow_framedropping(bool allow)238void ms::BasicSurface::allow_framedropping(bool allow)
245{239{
246 surface_buffer_stream->allow_framedropping(allow);240 buffer_queue->allow_framedropping(allow);
247}
248
249std::shared_ptr<mg::Buffer> ms::BasicSurface::snapshot_buffer() const
250{
251 return surface_buffer_stream->lock_snapshot_buffer();
252}241}
253242
254bool ms::BasicSurface::supports_input() const243bool ms::BasicSurface::supports_input() const
@@ -291,7 +280,7 @@
291 * not predictable here. Such critical exceptions would arise from280 * not predictable here. Such critical exceptions would arise from
292 * the platform buffer allocator as a runtime_error via:281 * the platform buffer allocator as a runtime_error via:
293 */282 */
294 surface_buffer_stream->resize(new_size);283 buffer_queue->resize(new_size);
295284
296 // Now the buffer stream has successfully resized, update the state second;285 // Now the buffer stream has successfully resized, update the state second;
297 {286 {
@@ -393,8 +382,8 @@
393void ms::BasicSurface::with_most_recent_buffer_do(382void ms::BasicSurface::with_most_recent_buffer_do(
394 std::function<void(mg::Buffer&)> const& exec)383 std::function<void(mg::Buffer&)> const& exec)
395{384{
396 auto buf = snapshot_buffer();385 auto buffer_handle = buffer_queue->snapshot_acquire();
397 exec(*buf);386 exec(*(buffer_handle.buffer()));
398}387}
399388
400389
@@ -636,7 +625,7 @@
636 visibility_ = new_visibility;625 visibility_ = new_visibility;
637 lg.unlock();626 lg.unlock();
638 if (new_visibility == mir_surface_visibility_exposed)627 if (new_visibility == mir_surface_visibility_exposed)
639 surface_buffer_stream->drop_old_buffers();628 buffer_queue->drop_old_buffers();
640 observers.attrib_changed(mir_surface_attrib_visibility, visibility_);629 observers.attrib_changed(mir_surface_attrib_visibility, visibility_);
641 }630 }
642631
@@ -669,15 +658,14 @@
669{658{
670public:659public:
671 SurfaceSnapshot(660 SurfaceSnapshot(
672 std::shared_ptr<mc::BufferStream> const& stream,661 std::shared_ptr<mc::BufferBundle> const& bq,
673 void const* compositor_id,662 void const* compositor_id,
674 geom::Rectangle const& position,663 geom::Rectangle const& position,
675 glm::mat4 const& transform,664 glm::mat4 const& transform,
676 float alpha,665 float alpha,
677 bool shaped,666 bool shaped,
678 mg::Renderable::ID id)667 mg::Renderable::ID id)
679 : underlying_buffer_stream{stream},668 : underlying_buffer_queue{bq},
680 compositor_buffer{nullptr},
681 compositor_id{compositor_id},669 compositor_id{compositor_id},
682 alpha_{alpha},670 alpha_{alpha},
683 shaped_{shaped},671 shaped_{shaped},
@@ -693,9 +681,9 @@
693 681
694 std::shared_ptr<mg::Buffer> buffer() const override682 std::shared_ptr<mg::Buffer> buffer() const override
695 {683 {
696 if (!compositor_buffer)684 if (!compositor_buffer_handle)
697 compositor_buffer = underlying_buffer_stream->lock_compositor_buffer(compositor_id);685 compositor_buffer_handle = underlying_buffer_queue->compositor_acquire(compositor_id);
698 return compositor_buffer;686 return compositor_buffer_handle.buffer();
699 }687 }
700688
701 geom::Rectangle screen_position() const override689 geom::Rectangle screen_position() const override
@@ -713,8 +701,8 @@
713 mg::Renderable::ID id() const override701 mg::Renderable::ID id() const override
714 { return id_; }702 { return id_; }
715private:703private:
716 std::shared_ptr<mc::BufferStream> const underlying_buffer_stream;704 std::shared_ptr<mc::BufferBundle> const underlying_buffer_queue;
717 std::shared_ptr<mg::Buffer> mutable compositor_buffer;705 mc::BufferHandle mutable compositor_buffer_handle;
718 void const*const compositor_id;706 void const*const compositor_id;
719 float const alpha_;707 float const alpha_;
720 bool const shaped_;708 bool const shaped_;
@@ -729,7 +717,7 @@
729 std::unique_lock<std::mutex> lk(guard);717 std::unique_lock<std::mutex> lk(guard);
730718
731 return std::make_unique<SurfaceSnapshot>(719 return std::make_unique<SurfaceSnapshot>(
732 surface_buffer_stream,720 buffer_queue,
733 compositor_id,721 compositor_id,
734 surface_rect,722 surface_rect,
735 transformation_matrix,723 transformation_matrix,
@@ -741,7 +729,7 @@
741int ms::BasicSurface::buffers_ready_for_compositor(void const* id) const729int ms::BasicSurface::buffers_ready_for_compositor(void const* id) const
742{730{
743 std::unique_lock<std::mutex> lk(guard);731 std::unique_lock<std::mutex> lk(guard);
744 return surface_buffer_stream->buffers_ready_for_compositor(id);732 return buffer_queue->buffers_ready_for_compositor(id);
745}733}
746734
747void ms::BasicSurface::consume(MirEvent const& event)735void ms::BasicSurface::consume(MirEvent const& event)
748736
=== modified file 'src/server/scene/basic_surface.h'
--- src/server/scene/basic_surface.h 2015-03-12 03:19:52 +0000
+++ src/server/scene/basic_surface.h 2015-03-20 19:31:52 +0000
@@ -22,6 +22,7 @@
22#include "mir/scene/surface.h"22#include "mir/scene/surface.h"
23#include "mir/basic_observers.h"23#include "mir/basic_observers.h"
24#include "mir/scene/surface_observer.h"24#include "mir/scene/surface_observer.h"
25#include "mir/compositor/buffer_handle.h"
2526
26#include "mir/geometry/rectangle.h"27#include "mir/geometry/rectangle.h"
2728
@@ -38,7 +39,7 @@
38namespace compositor39namespace compositor
39{40{
40struct BufferIPCPackage;41struct BufferIPCPackage;
41class BufferStream;42class BufferBundle;
42}43}
43namespace frontend { class EventSink; }44namespace frontend { class EventSink; }
44namespace graphics45namespace graphics
@@ -82,7 +83,7 @@
82 std::string const& name,83 std::string const& name,
83 geometry::Rectangle rect,84 geometry::Rectangle rect,
84 bool nonrectangular,85 bool nonrectangular,
85 std::shared_ptr<compositor::BufferStream> const& buffer_stream,86 std::shared_ptr<compositor::BufferBundle> const& buffer_queue,
86 std::shared_ptr<input::InputChannel> const& input_channel,87 std::shared_ptr<input::InputChannel> const& input_channel,
87 std::shared_ptr<input::InputSender> const& sender,88 std::shared_ptr<input::InputSender> const& sender,
88 std::shared_ptr<graphics::CursorImage> const& cursor_image,89 std::shared_ptr<graphics::CursorImage> const& cursor_image,
@@ -93,7 +94,7 @@
93 geometry::Rectangle rect,94 geometry::Rectangle rect,
94 std::weak_ptr<Surface> const& parent,95 std::weak_ptr<Surface> const& parent,
95 bool nonrectangular,96 bool nonrectangular,
96 std::shared_ptr<compositor::BufferStream> const& buffer_stream,97 std::shared_ptr<compositor::BufferBundle> const& buffer_queue,
97 std::shared_ptr<input::InputChannel> const& input_channel,98 std::shared_ptr<input::InputChannel> const& input_channel,
98 std::shared_ptr<input::InputSender> const& sender,99 std::shared_ptr<input::InputSender> const& sender,
99 std::shared_ptr<graphics::CursorImage> const& cursor_image,100 std::shared_ptr<graphics::CursorImage> const& cursor_image,
@@ -111,7 +112,6 @@
111112
112 MirPixelFormat pixel_format() const override;113 MirPixelFormat pixel_format() const override;
113114
114 std::shared_ptr<graphics::Buffer> snapshot_buffer() const;
115 void swap_buffers(graphics::Buffer* old_buffer, std::function<void(graphics::Buffer* new_buffer)> complete) override;115 void swap_buffers(graphics::Buffer* old_buffer, std::function<void(graphics::Buffer* new_buffer)> complete) override;
116 void force_requests_to_complete() override;116 void force_requests_to_complete() override;
117117
@@ -124,8 +124,6 @@
124124
125 void set_input_region(std::vector<geometry::Rectangle> const& input_rectangles) override;125 void set_input_region(std::vector<geometry::Rectangle> const& input_rectangles) override;
126126
127 std::shared_ptr<compositor::BufferStream> buffer_stream() const;
128
129 void resize(geometry::Size const& size) override;127 void resize(geometry::Size const& size) override;
130 geometry::Point top_left() const override;128 geometry::Point top_left() const override;
131 geometry::Rectangle input_bounds() const override;129 geometry::Rectangle input_bounds() const override;
@@ -186,7 +184,7 @@
186 input::InputReceptionMode input_mode;184 input::InputReceptionMode input_mode;
187 const bool nonrectangular;185 const bool nonrectangular;
188 std::vector<geometry::Rectangle> custom_input_rectangles;186 std::vector<geometry::Rectangle> custom_input_rectangles;
189 std::shared_ptr<compositor::BufferStream> const surface_buffer_stream;187 std::shared_ptr<compositor::BufferBundle> const buffer_queue;
190 std::shared_ptr<input::InputChannel> const server_input_channel;188 std::shared_ptr<input::InputChannel> const server_input_channel;
191 std::shared_ptr<input::InputSender> const input_sender;189 std::shared_ptr<input::InputSender> const input_sender;
192 std::shared_ptr<graphics::CursorImage> cursor_image_;190 std::shared_ptr<graphics::CursorImage> cursor_image_;
193191
=== modified file 'src/server/scene/default_configuration.cpp'
--- src/server/scene/default_configuration.cpp 2015-03-16 03:39:55 +0000
+++ src/server/scene/default_configuration.cpp 2015-03-20 19:31:52 +0000
@@ -73,7 +73,7 @@
73 [this]()73 [this]()
74 {74 {
75 return std::make_shared<ms::SurfaceAllocator>(75 return std::make_shared<ms::SurfaceAllocator>(
76 the_buffer_stream_factory(),76 the_buffer_queue_factory(),
77 the_options()->get<int>(options::nbuffers_opt),77 the_options()->get<int>(options::nbuffers_opt),
78 the_input_channel_factory(),78 the_input_channel_factory(),
79 the_input_sender(),79 the_input_sender(),
8080
=== modified file 'src/server/scene/surface_allocator.cpp'
--- src/server/scene/surface_allocator.cpp 2015-03-16 03:39:55 +0000
+++ src/server/scene/surface_allocator.cpp 2015-03-20 19:31:52 +0000
@@ -17,9 +17,9 @@
17 */17 */
1818
19#include "surface_allocator.h"19#include "surface_allocator.h"
20#include "mir/scene/buffer_stream_factory.h"20#include "mir/scene/buffer_queue_factory.h"
21#include "mir/compositor/buffer_stream.h"
22#include "mir/input/input_channel_factory.h"21#include "mir/input/input_channel_factory.h"
22#include "mir/compositor/buffer_bundle.h"
23#include "basic_surface.h"23#include "basic_surface.h"
2424
25namespace geom=mir::geometry;25namespace geom=mir::geometry;
@@ -36,13 +36,13 @@
36}36}
3737
38ms::SurfaceAllocator::SurfaceAllocator(38ms::SurfaceAllocator::SurfaceAllocator(
39 std::shared_ptr<BufferStreamFactory> const& stream_factory,39 std::shared_ptr<BufferQueueFactory> const& buffer_queue_factory,
40 int nbuffers,40 int nbuffers,
41 std::shared_ptr<input::InputChannelFactory> const& input_factory,41 std::shared_ptr<input::InputChannelFactory> const& input_factory,
42 std::shared_ptr<input::InputSender> const& input_sender,42 std::shared_ptr<input::InputSender> const& input_sender,
43 std::shared_ptr<mg::CursorImage> const& default_cursor_image,43 std::shared_ptr<mg::CursorImage> const& default_cursor_image,
44 std::shared_ptr<SceneReport> const& report) :44 std::shared_ptr<SceneReport> const& report) :
45 buffer_stream_factory(stream_factory),45 buffer_queue_factory(buffer_queue_factory),
46 nbuffers(nbuffers),46 nbuffers(nbuffers),
47 input_factory(input_factory),47 input_factory(input_factory),
48 input_sender(input_sender),48 input_sender(input_sender),
@@ -58,10 +58,8 @@
58 mg::BufferProperties buffer_properties{params.size,58 mg::BufferProperties buffer_properties{params.size,
59 params.pixel_format,59 params.pixel_format,
60 params.buffer_usage};60 params.buffer_usage};
61 auto buffer_stream = buffer_stream_factory->create_buffer_stream(61 auto buffer_queue = buffer_queue_factory->create_buffer_queue(nbuffers, buffer_properties);
62 nbuffers,62 auto actual_size = geom::Rectangle{params.top_left, buffer_queue->size()};
63 buffer_properties);
64 auto actual_size = geom::Rectangle{params.top_left, buffer_stream->stream_size()};
6563
66 bool nonrectangular = has_alpha(params.pixel_format);64 bool nonrectangular = has_alpha(params.pixel_format);
67 auto input_channel = input_factory->make_input_channel();65 auto input_channel = input_factory->make_input_channel();
@@ -70,7 +68,7 @@
70 actual_size,68 actual_size,
71 params.parent,69 params.parent,
72 nonrectangular,70 nonrectangular,
73 buffer_stream,71 buffer_queue,
74 input_channel,72 input_channel,
75 input_sender,73 input_sender,
76 default_cursor_image,74 default_cursor_image,
7775
=== modified file 'src/server/scene/surface_allocator.h'
--- src/server/scene/surface_allocator.h 2015-03-16 03:39:55 +0000
+++ src/server/scene/surface_allocator.h 2015-03-20 19:31:52 +0000
@@ -34,14 +34,14 @@
34}34}
35namespace scene35namespace scene
36{36{
37class BufferStreamFactory;37class BufferQueueFactory;
38class SceneReport;38class SceneReport;
39class SurfaceConfigurator;39class SurfaceConfigurator;
4040
41class SurfaceAllocator : public SurfaceFactory41class SurfaceAllocator : public SurfaceFactory
42{42{
43public:43public:
44 SurfaceAllocator(std::shared_ptr<BufferStreamFactory> const& bb_factory,44 SurfaceAllocator(std::shared_ptr<BufferQueueFactory> const& buffer_queue_factory,
45 int buffers,45 int buffers,
46 std::shared_ptr<input::InputChannelFactory> const& input_factory,46 std::shared_ptr<input::InputChannelFactory> const& input_factory,
47 std::shared_ptr<input::InputSender> const& input_sender,47 std::shared_ptr<input::InputSender> const& input_sender,
@@ -51,7 +51,7 @@
51 std::shared_ptr<Surface> create_surface(SurfaceCreationParameters const& params) override;51 std::shared_ptr<Surface> create_surface(SurfaceCreationParameters const& params) override;
5252
53private:53private:
54 std::shared_ptr<BufferStreamFactory> const buffer_stream_factory;54 std::shared_ptr<BufferQueueFactory> const buffer_queue_factory;
55 int const nbuffers;55 int const nbuffers;
56 std::shared_ptr<input::InputChannelFactory> const input_factory;56 std::shared_ptr<input::InputChannelFactory> const input_factory;
57 std::shared_ptr<input::InputSender> const input_sender;57 std::shared_ptr<input::InputSender> const input_sender;
5858
=== modified file 'src/server/symbols.map'
--- src/server/symbols.map 2015-03-16 03:39:55 +0000
+++ src/server/symbols.map 2015-03-20 19:31:52 +0000
@@ -515,7 +515,7 @@
515 mir::DefaultServerConfiguration::new_ipc_factory*;515 mir::DefaultServerConfiguration::new_ipc_factory*;
516 mir::DefaultServerConfiguration::the_android_input_dispatcher*;516 mir::DefaultServerConfiguration::the_android_input_dispatcher*;
517 mir::DefaultServerConfiguration::the_buffer_allocator*;517 mir::DefaultServerConfiguration::the_buffer_allocator*;
518 mir::DefaultServerConfiguration::the_buffer_stream_factory*;518 mir::DefaultServerConfiguration::the_buffer_queue_factory*;
519 mir::DefaultServerConfiguration::the_clock*;519 mir::DefaultServerConfiguration::the_clock*;
520 mir::DefaultServerConfiguration::the_composite_event_filter*;520 mir::DefaultServerConfiguration::the_composite_event_filter*;
521 mir::DefaultServerConfiguration::the_compositor*;521 mir::DefaultServerConfiguration::the_compositor*;
522522
=== modified file 'tests/include/mir_test_doubles/mock_buffer_bundle.h'
--- tests/include/mir_test_doubles/mock_buffer_bundle.h 2015-01-21 08:53:28 +0000
+++ tests/include/mir_test_doubles/mock_buffer_bundle.h 2015-03-20 19:31:52 +0000
@@ -18,7 +18,8 @@
18#ifndef MIR_TEST_DOUBLES_MOCK_BUFFER_BUNDLE_H_18#ifndef MIR_TEST_DOUBLES_MOCK_BUFFER_BUNDLE_H_
19#define MIR_TEST_DOUBLES_MOCK_BUFFER_BUNDLE_H_19#define MIR_TEST_DOUBLES_MOCK_BUFFER_BUNDLE_H_
2020
21#include "src/server/compositor/buffer_bundle.h"21#include "mir/compositor/buffer_handle.h"
22#include "mir/compositor/buffer_bundle.h"
2223
23#include <gmock/gmock.h>24#include <gmock/gmock.h>
2425
@@ -37,19 +38,22 @@
37 ~MockBufferBundle() noexcept38 ~MockBufferBundle() noexcept
38 {}39 {}
3940
40 MOCK_METHOD1(client_acquire, void(std::function<void(graphics::Buffer*)>));41 MOCK_METHOD1(client_acquire, void(std::function<void(graphics::Buffer*)>));
41 MOCK_METHOD1(client_release, void(graphics::Buffer*));42 MOCK_METHOD1(client_release, void(graphics::Buffer*));
42 MOCK_METHOD1(compositor_acquire, std::shared_ptr<graphics::Buffer>(void const*));43 MOCK_CONST_METHOD0(properties, graphics::BufferProperties());
43 MOCK_METHOD1(compositor_release, void(std::shared_ptr<graphics::Buffer> const&));
44 MOCK_METHOD0(snapshot_acquire, std::shared_ptr<graphics::Buffer>());
45 MOCK_METHOD1(snapshot_release, void(std::shared_ptr<graphics::Buffer> const&));
46 MOCK_METHOD1(allow_framedropping, void(bool));44 MOCK_METHOD1(allow_framedropping, void(bool));
47 MOCK_CONST_METHOD0(properties, graphics::BufferProperties());
48 MOCK_METHOD0(force_client_abort, void());
49 MOCK_METHOD0(force_requests_to_complete, void());45 MOCK_METHOD0(force_requests_to_complete, void());
50 MOCK_METHOD1(resize, void(const geometry::Size &));46 MOCK_METHOD1(resize, void(const geometry::Size &));
47 MOCK_CONST_METHOD0(size, geometry::Size());
51 MOCK_METHOD0(drop_old_buffers, void());48 MOCK_METHOD0(drop_old_buffers, void());
52 int buffers_ready_for_compositor(void const*) const override { return 1; }49 MOCK_CONST_METHOD1(buffers_ready_for_compositor, int(void const*));
50
51 // TODO: Latest gmock (1.7.0) can't handle moveable only classes.
52 // The trunk can. We should be able to mock this once released.
53 compositor::BufferHandle compositor_acquire(void const*) override
54 { return std::move(compositor::BufferHandle(nullptr, nullptr)); }
55 compositor::BufferHandle snapshot_acquire() override
56 { return std::move(compositor::BufferHandle(nullptr, nullptr)); }
53 int buffers_free_for_client() const override { return 1; }57 int buffers_free_for_client() const override { return 1; }
54 void drop_client_requests() override {}58 void drop_client_requests() override {}
55};59};
5660
=== removed file 'tests/include/mir_test_doubles/mock_buffer_stream.h'
--- tests/include/mir_test_doubles/mock_buffer_stream.h 2015-01-21 08:53:28 +0000
+++ tests/include/mir_test_doubles/mock_buffer_stream.h 1970-01-01 00:00:00 +0000
@@ -1,67 +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 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_TEST_DOUBLES_MOCK_BUFFER_STREAM_H_
20#define MIR_TEST_DOUBLES_MOCK_BUFFER_STREAM_H_
21
22#include "mir/compositor/buffer_stream.h"
23
24#include <gmock/gmock.h>
25
26namespace mir
27{
28namespace test
29{
30namespace doubles
31{
32struct MockBufferStream : public compositor::BufferStream
33{
34 int buffers_ready_{0};
35 int buffers_ready(void const*)
36 {
37 if (buffers_ready_)
38 return buffers_ready_--;
39 return 0;
40 }
41
42 MockBufferStream()
43 {
44 ON_CALL(*this, buffers_ready_for_compositor(::testing::_))
45 .WillByDefault(testing::Invoke(this, &MockBufferStream::buffers_ready));
46 }
47 MOCK_METHOD1(acquire_client_buffer, void(std::function<void(graphics::Buffer* buffer)>));
48 MOCK_METHOD1(release_client_buffer, void(graphics::Buffer*));
49 MOCK_METHOD1(lock_compositor_buffer,
50 std::shared_ptr<graphics::Buffer>(void const*));
51 MOCK_METHOD0(lock_snapshot_buffer, std::shared_ptr<graphics::Buffer>());
52
53 MOCK_METHOD0(get_stream_pixel_format, MirPixelFormat());
54 MOCK_METHOD0(stream_size, geometry::Size());
55 MOCK_METHOD1(resize, void(geometry::Size const&));
56 MOCK_METHOD0(force_client_completion, void());
57 MOCK_METHOD1(allow_framedropping, void(bool));
58 MOCK_METHOD0(force_requests_to_complete, void());
59 MOCK_CONST_METHOD1(buffers_ready_for_compositor, int(void const*));
60 MOCK_METHOD0(drop_old_buffers, void());
61 MOCK_METHOD0(drop_client_requests, void());
62};
63}
64}
65}
66
67#endif /* MIR_TEST_DOUBLES_MOCK_BUFFER_STREAM_H_ */
680
=== modified file 'tests/include/mir_test_doubles/mock_surface.h'
--- tests/include/mir_test_doubles/mock_surface.h 2015-02-03 15:07:44 +0000
+++ tests/include/mir_test_doubles/mock_surface.h 2015-03-20 19:31:52 +0000
@@ -21,7 +21,7 @@
2121
22#include "src/server/scene/basic_surface.h"22#include "src/server/scene/basic_surface.h"
23#include "src/server/report/null_report_factory.h"23#include "src/server/report/null_report_factory.h"
24#include "mock_buffer_stream.h"24#include "mock_buffer_bundle.h"
2525
26#include <gmock/gmock.h>26#include <gmock/gmock.h>
2727
@@ -39,7 +39,7 @@
39 {},39 {},
40 {{},{}},40 {{},{}},
41 true,41 true,
42 std::make_shared<testing::NiceMock<MockBufferStream>>(),42 std::make_shared<testing::NiceMock<MockBufferBundle>>(),
43 {},43 {},
44 {},44 {},
45 {},45 {},
4646
=== renamed file 'tests/include/mir_test_doubles/stub_buffer_stream.h' => 'tests/include/mir_test_doubles/stub_buffer_bundle.h'
--- tests/include/mir_test_doubles/stub_buffer_stream.h 2015-01-22 10:20:30 +0000
+++ tests/include/mir_test_doubles/stub_buffer_bundle.h 2015-03-20 19:31:52 +0000
@@ -16,10 +16,11 @@
16 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>16 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
17 */17 */
1818
19#ifndef MIR_TEST_DOUBLES_NULL_BUFFER_STREAM_H_19#ifndef MIR_TEST_DOUBLES_NULL_BUFFER_BUNDLE_H_
20#define MIR_TEST_DOUBLES_NULL_BUFFER_STREAM_H_20#define MIR_TEST_DOUBLES_NULL_BUFFER_BUNDLE_H_
2121
22#include <mir/compositor/buffer_stream.h>22#include "mir/compositor/buffer_handle.h"
23#include <mir/compositor/buffer_bundle.h>
23#include <mir_test_doubles/stub_buffer.h>24#include <mir_test_doubles/stub_buffer.h>
2425
25namespace mir26namespace mir
@@ -29,42 +30,37 @@
29namespace doubles30namespace doubles
30{31{
3132
32class StubBufferStream : public compositor::BufferStream33class StubBufferBundle : public compositor::BufferBundle
33{34{
34public:35public:
35 StubBufferStream()36 StubBufferBundle()
36 {37 {
37 stub_compositor_buffer = std::make_shared<StubBuffer>();38 stub_compositor_buffer = std::make_shared<StubBuffer>();
38 }39 }
3940
40 void acquire_client_buffer(41 void client_acquire(
41 std::function<void(graphics::Buffer* buffer)> complete) override42 std::function<void(graphics::Buffer* buffer)> complete) override
42 {43 {
43 complete(&stub_client_buffer);44 complete(&stub_client_buffer);
44 }45 }
4546
46 void release_client_buffer(graphics::Buffer*) override47 void client_release(graphics::Buffer*) override
47 {48 {
48 ++nready;49 ++nready;
49 }50 }
5051
51 std::shared_ptr<graphics::Buffer> lock_compositor_buffer(void const*) override52 compositor::BufferHandle compositor_acquire(void const*) override
52 {53 {
53 --nready;54 --nready;
54 return stub_compositor_buffer;55 return compositor::BufferHandle(stub_compositor_buffer, nullptr);
55 }56 }
5657
57 std::shared_ptr<graphics::Buffer> lock_snapshot_buffer() override58 compositor::BufferHandle snapshot_acquire() override
58 {59 {
59 return stub_compositor_buffer;60 return compositor::BufferHandle(stub_compositor_buffer, nullptr);
60 }61 }
6162
62 MirPixelFormat get_stream_pixel_format() override63 geometry::Size size() const override
63 {
64 return MirPixelFormat();
65 }
66
67 geometry::Size stream_size() override
68 {64 {
69 return geometry::Size();65 return geometry::Size();
70 }66 }
@@ -81,11 +77,18 @@
81 {77 {
82 }78 }
8379
80 int buffers_free_for_client() const override { return 0; }
81
84 int buffers_ready_for_compositor(void const*) const override { return nready; }82 int buffers_ready_for_compositor(void const*) const override { return nready; }
8583
86 void drop_old_buffers() override {}84 void drop_old_buffers() override {}
87 void drop_client_requests() override {}85 void drop_client_requests() override {}
8886
87 graphics::BufferProperties properties() const override
88 { return graphics::BufferProperties(geometry::Size{0, 0},
89 mir_pixel_format_invalid,
90 graphics::BufferUsage::undefined); }
91
89 StubBuffer stub_client_buffer;92 StubBuffer stub_client_buffer;
90 std::shared_ptr<graphics::Buffer> stub_compositor_buffer;93 std::shared_ptr<graphics::Buffer> stub_compositor_buffer;
91 int nready = 0;94 int nready = 0;
@@ -95,4 +98,4 @@
95}98}
96} // namespace mir99} // namespace mir
97100
98#endif /* MIR_TEST_DOUBLES_NULL_BUFFER_STREAM_H_ */101#endif /* MIR_TEST_DOUBLES_NULL_BUFFER_BUNDLE_H_ */
99102
=== modified file 'tests/integration-tests/compositor/CMakeLists.txt'
--- tests/integration-tests/compositor/CMakeLists.txt 2013-07-24 05:13:16 +0000
+++ tests/integration-tests/compositor/CMakeLists.txt 2015-03-20 19:31:52 +0000
@@ -2,7 +2,6 @@
2 APPEND INTEGRATION_TESTS_SRCS2 APPEND INTEGRATION_TESTS_SRCS
3 ${CMAKE_CURRENT_SOURCE_DIR}/test_swapping_swappers.cpp3 ${CMAKE_CURRENT_SOURCE_DIR}/test_swapping_swappers.cpp
4 ${CMAKE_CURRENT_SOURCE_DIR}/test_synchronizer.cpp4 ${CMAKE_CURRENT_SOURCE_DIR}/test_synchronizer.cpp
5 ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer_stream.cpp
6)5)
76
8set(7set(
98
=== removed file 'tests/integration-tests/compositor/test_buffer_stream.cpp'
--- tests/integration-tests/compositor/test_buffer_stream.cpp 2015-03-06 03:52:41 +0000
+++ tests/integration-tests/compositor/test_buffer_stream.cpp 1970-01-01 00:00:00 +0000
@@ -1,405 +0,0 @@
1/*
2 * Copyright © 2013-2015 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 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: Alexandros Frantzis <alexandros.frantzis@canonical.com>
17 */
18
19#include "src/server/compositor/buffer_stream_surfaces.h"
20#include "mir/graphics/graphic_buffer_allocator.h"
21
22#include "src/server/compositor/buffer_queue.h"
23#include "src/server/compositor/timeout_frame_dropping_policy_factory.h"
24
25#include "mir_test_doubles/stub_buffer.h"
26#include "mir_test_doubles/stub_buffer_allocator.h"
27#include "mir_test_doubles/mock_timer.h"
28#include "mir_test/signal.h"
29
30#include <gmock/gmock.h>
31
32#include <condition_variable>
33#include <thread>
34#include <chrono>
35#include <atomic>
36
37namespace mc = mir::compositor;
38namespace mg = mir::graphics;
39namespace mtd = mir::test::doubles;
40namespace mt =mir::test;
41namespace geom = mir::geometry;
42
43using namespace ::testing;
44
45namespace
46{
47
48struct BufferStreamSurfaces : mc::BufferStreamSurfaces
49{
50 using mc::BufferStreamSurfaces::BufferStreamSurfaces;
51
52 void acquire_client_buffer_async(mg::Buffer*& buffer,
53 std::shared_ptr<mt::Signal> const& signal)
54 {
55 acquire_client_buffer(
56 [signal, &buffer](mg::Buffer* new_buffer)
57 {
58 buffer = new_buffer;
59 signal->raise();
60 });
61 }
62
63 // Convenient functions to allow tests to be written in linear style
64 mg::Buffer* acquire_client_buffer_blocking()
65 {
66 mg::Buffer* buffer = nullptr;
67 auto signal = std::make_shared<mt::Signal>();
68 acquire_client_buffer_async(buffer, signal);
69 signal->wait();
70 return buffer;
71 }
72
73 void swap_client_buffers_blocking(mg::Buffer*& buffer)
74 {
75 if (buffer)
76 release_client_buffer(buffer);
77
78 buffer = acquire_client_buffer_blocking();
79 }
80};
81
82struct BufferStreamTest : public ::testing::Test
83{
84 BufferStreamTest()
85 : clock{std::make_shared<mt::FakeClock>()},
86 timer{std::make_shared<mtd::FakeTimer>(clock)},
87 frame_drop_timeout{1000},
88 nbuffers{3},
89 buffer_stream{create_bundle()}
90 {
91 }
92
93 int buffers_free_for_client() const
94 {
95 return buffer_queue->buffers_free_for_client();
96 }
97
98 std::shared_ptr<mc::BufferBundle> create_bundle()
99 {
100 auto allocator = std::make_shared<mtd::StubBufferAllocator>();
101 mg::BufferProperties properties{geom::Size{380, 210},
102 mir_pixel_format_abgr_8888,
103 mg::BufferUsage::hardware};
104 mc::TimeoutFrameDroppingPolicyFactory policy_factory{timer,
105 frame_drop_timeout};
106
107 buffer_queue = std::make_shared<mc::BufferQueue>(nbuffers,
108 allocator,
109 properties,
110 policy_factory);
111
112 return buffer_queue;
113 }
114
115 std::shared_ptr<mt::FakeClock> clock;
116 std::shared_ptr<mtd::FakeTimer> timer;
117 std::chrono::milliseconds const frame_drop_timeout;
118 const int nbuffers;
119 std::shared_ptr<mc::BufferQueue> buffer_queue;
120 BufferStreamSurfaces buffer_stream;
121};
122
123}
124
125TEST_F(BufferStreamTest, gives_same_back_buffer_until_more_available)
126{
127 mg::Buffer* client1 = buffer_stream.acquire_client_buffer_blocking();
128 auto client1_id = client1->id();
129 buffer_stream.release_client_buffer(client1);
130
131 auto comp1 = buffer_stream.lock_compositor_buffer(nullptr);
132 auto comp2 = buffer_stream.lock_compositor_buffer(nullptr);
133
134 EXPECT_EQ(comp1->id(), comp2->id());
135 EXPECT_EQ(comp1->id(), client1_id);
136
137 comp1.reset();
138
139 mg::Buffer* client2 = buffer_stream.acquire_client_buffer_blocking();
140 auto client2_id = client2->id();
141 buffer_stream.release_client_buffer(client2);
142
143 auto comp3 = buffer_stream.lock_compositor_buffer(nullptr);
144
145 EXPECT_NE(client1_id, comp3->id());
146 EXPECT_EQ(client2_id, comp3->id());
147
148 comp2.reset();
149 auto comp3_id = comp3->id();
150 comp3.reset();
151
152 auto comp4 = buffer_stream.lock_compositor_buffer(nullptr);
153 EXPECT_EQ(comp3_id, comp4->id());
154}
155
156TEST_F(BufferStreamTest, gives_all_monitors_the_same_buffer)
157{
158 mg::Buffer* client_buffer{nullptr};
159 int const prefill = buffers_free_for_client();
160 for (int i = 0; i < prefill; ++i)
161 buffer_stream.swap_client_buffers_blocking(client_buffer);
162
163 auto first_monitor = buffer_stream.lock_compositor_buffer(0);
164 auto first_compositor_id = first_monitor->id();
165 first_monitor.reset();
166
167 for (int m = 1; m <= 10; m++)
168 {
169 const void *th = reinterpret_cast<const void*>(m);
170 auto monitor = buffer_stream.lock_compositor_buffer(th);
171 ASSERT_EQ(first_compositor_id, monitor->id());
172 }
173}
174
175TEST_F(BufferStreamTest, gives_different_back_buffer_asap)
176{
177 buffer_stream.release_client_buffer(buffer_stream.acquire_client_buffer_blocking());
178 auto comp1 = buffer_stream.lock_compositor_buffer(nullptr);
179
180 buffer_stream.release_client_buffer(buffer_stream.acquire_client_buffer_blocking());
181 auto comp2 = buffer_stream.lock_compositor_buffer(nullptr);
182
183 EXPECT_NE(comp1->id(), comp2->id());
184
185 comp1.reset();
186 comp2.reset();
187}
188
189TEST_F(BufferStreamTest, resize_affects_client_buffers_immediately)
190{
191 auto old_size = buffer_stream.stream_size();
192
193 mg::Buffer* client = buffer_stream.acquire_client_buffer_blocking();
194 EXPECT_EQ(old_size, client->size());
195 buffer_stream.release_client_buffer(client);
196
197 buffer_stream.lock_compositor_buffer(this);
198
199 geom::Size const new_size
200 {
201 old_size.width.as_int() * 2,
202 old_size.height.as_int() * 3
203 };
204 buffer_stream.resize(new_size);
205 EXPECT_EQ(new_size, buffer_stream.stream_size());
206
207 client = buffer_stream.acquire_client_buffer_blocking();
208 EXPECT_EQ(new_size, client->size());
209 buffer_stream.release_client_buffer(client);
210
211 buffer_stream.lock_compositor_buffer(this);
212
213 buffer_stream.resize(old_size);
214 EXPECT_EQ(old_size, buffer_stream.stream_size());
215
216 buffer_stream.lock_compositor_buffer(this);
217
218 client = buffer_stream.acquire_client_buffer_blocking();
219 EXPECT_EQ(old_size, client->size());
220 buffer_stream.release_client_buffer(client);
221}
222
223TEST_F(BufferStreamTest, compositor_gets_resized_buffers)
224{
225 auto old_size = buffer_stream.stream_size();
226
227 mg::Buffer* client = buffer_stream.acquire_client_buffer_blocking();
228 buffer_stream.release_client_buffer(client);
229
230 geom::Size const new_size
231 {
232 old_size.width.as_int() * 2,
233 old_size.height.as_int() * 3
234 };
235 buffer_stream.resize(new_size);
236 EXPECT_EQ(new_size, buffer_stream.stream_size());
237
238 auto comp1 = buffer_stream.lock_compositor_buffer(nullptr);
239
240 client = buffer_stream.acquire_client_buffer_blocking();
241 buffer_stream.release_client_buffer(client);
242
243 EXPECT_EQ(old_size, comp1->size());
244 comp1.reset();
245
246 auto comp2 = buffer_stream.lock_compositor_buffer(nullptr);
247
248 client = buffer_stream.acquire_client_buffer_blocking();
249 buffer_stream.release_client_buffer(client);
250
251 EXPECT_EQ(new_size, comp2->size());
252 comp2.reset();
253
254 auto comp3 = buffer_stream.lock_compositor_buffer(nullptr);
255
256 client = buffer_stream.acquire_client_buffer_blocking();
257 buffer_stream.release_client_buffer(client);
258
259 EXPECT_EQ(new_size, comp3->size());
260 comp3.reset();
261
262 buffer_stream.resize(old_size);
263 EXPECT_EQ(old_size, buffer_stream.stream_size());
264
265 auto comp4 = buffer_stream.lock_compositor_buffer(nullptr);
266
267 // No client frames "drawn" since resize(old_size), so compositor gets new_size
268 client = buffer_stream.acquire_client_buffer_blocking();
269 buffer_stream.release_client_buffer(client);
270 EXPECT_EQ(new_size, comp4->size());
271 comp4.reset();
272
273 auto comp5 = buffer_stream.lock_compositor_buffer(nullptr);
274
275 // Generate a new frame, which should be back to old_size now
276 client = buffer_stream.acquire_client_buffer_blocking();
277 buffer_stream.release_client_buffer(client);
278 EXPECT_EQ(old_size, comp5->size());
279 comp5.reset();
280}
281
282TEST_F(BufferStreamTest, can_get_partly_released_back_buffer)
283{
284 mg::Buffer* client = buffer_stream.acquire_client_buffer_blocking();
285 buffer_stream.release_client_buffer(client);
286
287 int a, b, c;
288 auto comp1 = buffer_stream.lock_compositor_buffer(&a);
289 auto comp2 = buffer_stream.lock_compositor_buffer(&b);
290
291 EXPECT_EQ(comp1->id(), comp2->id());
292
293 comp1.reset();
294
295 auto comp3 = buffer_stream.lock_compositor_buffer(&c);
296
297 EXPECT_EQ(comp2->id(), comp3->id());
298}
299
300namespace
301{
302
303void client_loop(int nframes, BufferStreamSurfaces& stream)
304{
305 mg::Buffer* out_buffer{nullptr};
306 for (int f = 0; f < nframes; f++)
307 {
308 stream.swap_client_buffers_blocking(out_buffer);
309 ASSERT_NE(nullptr, out_buffer);
310 std::this_thread::yield();
311 }
312}
313
314void compositor_loop(mc::BufferStream &stream,
315 std::atomic<bool> &done)
316{
317 while (!done.load())
318 {
319 auto comp1 = stream.lock_compositor_buffer(nullptr);
320 ASSERT_NE(nullptr, comp1);
321
322 // Also stress test getting a second compositor buffer before yielding
323 auto comp2 = stream.lock_compositor_buffer(nullptr);
324 ASSERT_NE(nullptr, comp2);
325
326 std::this_thread::yield();
327
328 comp1.reset();
329 comp2.reset();
330 }
331}
332
333void snapshot_loop(mc::BufferStream &stream,
334 std::atomic<bool> &done)
335{
336 while (!done.load())
337 {
338 auto out_region = stream.lock_snapshot_buffer();
339 ASSERT_NE(nullptr, out_region);
340 std::this_thread::yield();
341 }
342}
343
344}
345
346TEST_F(BufferStreamTest, stress_test_distinct_buffers)
347{
348 // More would be good, but armhf takes too long
349 const int num_snapshotters{2};
350 const int num_frames{200};
351
352 std::atomic<bool> done;
353 done = false;
354
355 std::thread client(client_loop,
356 num_frames,
357 std::ref(buffer_stream));
358
359 std::thread compositor(compositor_loop,
360 std::ref(buffer_stream),
361 std::ref(done));
362
363 std::vector<std::shared_ptr<std::thread>> snapshotters;
364 for (unsigned int i = 0; i < num_snapshotters; i++)
365 {
366 snapshotters.push_back(
367 std::make_shared<std::thread>(snapshot_loop,
368 std::ref(buffer_stream),
369 std::ref(done)));
370 }
371
372 client.join();
373
374 done = true;
375
376 buffer_stream.force_requests_to_complete();
377
378 compositor.join();
379
380 for (auto &s : snapshotters)
381 s->join();
382}
383
384TEST_F(BufferStreamTest, blocked_client_is_released_on_timeout)
385{
386 using namespace testing;
387
388 mg::Buffer* placeholder{nullptr};
389
390 // Grab all the buffers...
391 int max = buffers_free_for_client();
392 for (int i = 0; i < max; ++i)
393 {
394 placeholder = buffer_stream.acquire_client_buffer_blocking();
395 buffer_stream.release_client_buffer(placeholder);
396 }
397
398 auto swap_completed = std::make_shared<mt::Signal>();
399 buffer_stream.acquire_client_buffer([swap_completed](mg::Buffer*) {swap_completed->raise();});
400
401 EXPECT_FALSE(swap_completed->raised());
402 clock->advance_time(frame_drop_timeout + std::chrono::milliseconds{1});
403
404 EXPECT_TRUE(swap_completed->wait_for(std::chrono::milliseconds{100}));
405}
4060
=== modified file 'tests/integration-tests/compositor/test_swapping_swappers.cpp'
--- tests/integration-tests/compositor/test_swapping_swappers.cpp 2015-01-21 07:34:50 +0000
+++ tests/integration-tests/compositor/test_swapping_swappers.cpp 2015-03-20 19:31:52 +0000
@@ -20,8 +20,8 @@
20#include "mir_test_doubles/stub_frame_dropping_policy_factory.h"20#include "mir_test_doubles/stub_frame_dropping_policy_factory.h"
21#include "multithread_harness.h"21#include "multithread_harness.h"
2222
23#include "src/server/compositor/buffer_queue.h"23#include "mir/compositor/buffer_handle.h"
24#include "src/server/compositor/buffer_stream_surfaces.h"24#include "mir/compositor/buffer_queue.h"
25#include "mir/graphics/graphic_buffer_allocator.h"25#include "mir/graphics/graphic_buffer_allocator.h"
2626
27#include <gmock/gmock.h>27#include <gmock/gmock.h>
@@ -105,7 +105,6 @@
105 {105 {
106 auto b = switching_bundle->compositor_acquire(0);106 auto b = switching_bundle->compositor_acquire(0);
107 std::this_thread::yield();107 std::this_thread::yield();
108 switching_bundle->compositor_release(b);
109 }108 }
110 });109 });
111110
@@ -149,7 +148,6 @@
149 {148 {
150 auto b = switching_bundle->compositor_acquire(0);149 auto b = switching_bundle->compositor_acquire(0);
151 std::this_thread::yield();150 std::this_thread::yield();
152 switching_bundle->compositor_release(b);
153 }151 }
154 });152 });
155153
156154
=== modified file 'tests/integration-tests/graphics/android/test_buffer_integration.cpp'
--- tests/integration-tests/graphics/android/test_buffer_integration.cpp 2015-01-22 09:00:14 +0000
+++ tests/integration-tests/graphics/android/test_buffer_integration.cpp 2015-03-20 19:31:52 +0000
@@ -17,7 +17,7 @@
17 */17 */
1818
19#include "src/platforms/android/server/android_graphic_buffer_allocator.h"19#include "src/platforms/android/server/android_graphic_buffer_allocator.h"
20#include "src/server/compositor/buffer_queue.h"20#include "mir/compositor/buffer_queue.h"
21#include "src/server/report/null_report_factory.h"21#include "src/server/report/null_report_factory.h"
22#include "mir/graphics/android/native_buffer.h"22#include "mir/graphics/android/native_buffer.h"
23#include "mir/graphics/buffer_properties.h"23#include "mir/graphics/buffer_properties.h"
2424
=== modified file 'tests/integration-tests/surface_composition.cpp'
--- tests/integration-tests/surface_composition.cpp 2015-02-03 15:07:44 +0000
+++ tests/integration-tests/surface_composition.cpp 2015-03-20 19:31:52 +0000
@@ -18,8 +18,7 @@
1818
19#include "src/server/scene/basic_surface.h"19#include "src/server/scene/basic_surface.h"
20#include "src/server/report/null_report_factory.h"20#include "src/server/report/null_report_factory.h"
21#include "src/server/compositor/buffer_stream_surfaces.h"21#include "mir/compositor/buffer_queue.h"
22#include "src/server/compositor/buffer_queue.h"
2322
24#include "mir_test_doubles/stub_buffer_allocator.h"23#include "mir_test_doubles/stub_buffer_allocator.h"
25#include "mir_test_doubles/stub_frame_dropping_policy_factory.h"24#include "mir_test_doubles/stub_frame_dropping_policy_factory.h"
@@ -49,7 +48,7 @@
49 std::string("SurfaceComposition"),48 std::string("SurfaceComposition"),
50 geom::Rectangle{{},{}},49 geom::Rectangle{{},{}},
51 false,50 false,
52 create_buffer_stream(),51 create_buffer_bundle(),
53 create_input_channel(),52 create_input_channel(),
54 create_input_sender(),53 create_input_sender(),
55 create_cursor_image(),54 create_cursor_image(),
@@ -59,12 +58,6 @@
5958
60 int const number_of_buffers = 3;59 int const number_of_buffers = 3;
6160
62 auto create_buffer_stream() const
63 ->std::shared_ptr<mc::BufferStream>
64 {
65 return std::make_shared<mc::BufferStreamSurfaces>(create_buffer_bundle());
66 }
67
68 auto create_buffer_bundle() const61 auto create_buffer_bundle() const
69 -> std::shared_ptr<mc::BufferBundle>62 -> std::shared_ptr<mc::BufferBundle>
70 {63 {
7164
=== modified file 'tests/integration-tests/test_exchange_buffer.cpp'
--- tests/integration-tests/test_exchange_buffer.cpp 2015-03-16 03:39:55 +0000
+++ tests/integration-tests/test_exchange_buffer.cpp 2015-03-20 19:31:52 +0000
@@ -26,8 +26,9 @@
26#include "mir/graphics/buffer_id.h"26#include "mir/graphics/buffer_id.h"
27#include "mir/graphics/buffer_ipc_message.h"27#include "mir/graphics/buffer_ipc_message.h"
28#include "mir/graphics/platform_operation_message.h"28#include "mir/graphics/platform_operation_message.h"
29#include "mir/scene/buffer_stream_factory.h"29#include "mir/scene/buffer_queue_factory.h"
30#include "mir/compositor/buffer_stream.h"30#include "mir/compositor/buffer_handle.h"
31#include "mir/compositor/buffer_bundle.h"
31#include "mir_toolkit/mir_client_library.h"32#include "mir_toolkit/mir_client_library.h"
32#include "src/client/mir_connection.h"33#include "src/client/mir_connection.h"
33#include <chrono>34#include <chrono>
@@ -54,14 +55,14 @@
54 return arg;55 return arg;
55}56}
5657
57struct StubStream : public mc::BufferStream58struct StubQueue : public mc::BufferBundle
58{59{
59 StubStream(std::vector<mg::BufferID> const& ids) :60 StubQueue(std::vector<mg::BufferID> const& ids) :
60 buffer_id_seq(ids)61 buffer_id_seq(ids)
61 {62 {
62 }63 }
6364
64 void acquire_client_buffer(std::function<void(mg::Buffer* buffer)> complete)65 void client_acquire(std::function<void(mg::Buffer* buffer)> complete)
65 {66 {
66 std::shared_ptr<mg::Buffer> stub_buffer;67 std::shared_ptr<mg::Buffer> stub_buffer;
67 if (buffers_acquired < buffer_id_seq.size())68 if (buffers_acquired < buffer_id_seq.size())
@@ -73,13 +74,11 @@
73 complete(stub_buffer.get());74 complete(stub_buffer.get());
74 }75 }
7576
76 void release_client_buffer(mg::Buffer*) {}77 void client_release(mg::Buffer*) {}
77 std::shared_ptr<mg::Buffer> lock_compositor_buffer(void const*)78 mc::BufferHandle compositor_acquire(void const*)
78 { return std::make_shared<mtd::StubBuffer>(); }79 { return std::move(mc::BufferHandle(std::make_shared<mtd::StubBuffer>(), nullptr)); }
79 std::shared_ptr<mg::Buffer> lock_snapshot_buffer()80 mc::BufferHandle snapshot_acquire()
80 { return std::make_shared<mtd::StubBuffer>(); }81 { return std::move(mc::BufferHandle(std::make_shared<mtd::StubBuffer>(), nullptr)); }
81 MirPixelFormat get_stream_pixel_format() { return mir_pixel_format_abgr_8888; }
82 geom::Size stream_size() { return geom::Size{1,212121}; }
83 void resize(geom::Size const&) {};82 void resize(geom::Size const&) {};
84 void allow_framedropping(bool) {};83 void allow_framedropping(bool) {};
85 void force_requests_to_complete() {};84 void force_requests_to_complete() {};
@@ -87,20 +86,26 @@
87 void drop_old_buffers() {}86 void drop_old_buffers() {}
88 void drop_client_requests() override {}87 void drop_client_requests() override {}
8988
89 mg::BufferProperties properties() const override
90 { return mg::BufferProperties(geom::Size{0, 0},
91 mir_pixel_format_invalid,
92 mg::BufferUsage::undefined); }
93 geom::Size size() const override { return geom::Size{1,212121}; }
94 int buffers_free_for_client() const override { return 0; }
95
90 std::vector<std::shared_ptr<mg::Buffer>> client_buffers;96 std::vector<std::shared_ptr<mg::Buffer>> client_buffers;
91 std::vector<mg::BufferID> const buffer_id_seq;97 std::vector<mg::BufferID> const buffer_id_seq;
92 unsigned int buffers_acquired{0};98 unsigned int buffers_acquired{0};
93};99};
94100
95struct StubStreamFactory : public msc::BufferStreamFactory101struct StubQueueFactory : public msc::BufferQueueFactory
96{102{
97 StubStreamFactory(std::vector<mg::BufferID> const& ids) :103 StubQueueFactory(std::vector<mg::BufferID> const& ids) :
98 buffer_id_seq(ids)104 buffer_id_seq(ids)
99 {}105 {}
100106
101 std::shared_ptr<mc::BufferStream> create_buffer_stream(107 std::shared_ptr<mc::BufferBundle> create_buffer_queue(int, mg::BufferProperties const&) override
102 int, mg::BufferProperties const&) override108 { return std::make_shared<StubQueue>(buffer_id_seq); }
103 { return std::make_shared<StubStream>(buffer_id_seq); }
104 std::vector<mg::BufferID> const buffer_id_seq;109 std::vector<mg::BufferID> const buffer_id_seq;
105};110};
106111
@@ -176,7 +181,7 @@
176 ExchangeServerConfiguration(181 ExchangeServerConfiguration(
177 std::vector<mg::BufferID> const& id_seq,182 std::vector<mg::BufferID> const& id_seq,
178 std::shared_ptr<mg::PlatformIpcOperations> const& ipc_ops) :183 std::shared_ptr<mg::PlatformIpcOperations> const& ipc_ops) :
179 stream_factory{std::make_shared<StubStreamFactory>(id_seq)},184 queue_factory{std::make_shared<StubQueueFactory>(id_seq)},
180 platform{std::make_shared<StubPlatform>(ipc_ops)}185 platform{std::make_shared<StubPlatform>(ipc_ops)}
181 {186 {
182 }187 }
@@ -186,12 +191,12 @@
186 return platform;191 return platform;
187 }192 }
188193
189 std::shared_ptr<msc::BufferStreamFactory> the_buffer_stream_factory() override194 std::shared_ptr<msc::BufferQueueFactory> the_buffer_queue_factory() override
190 {195 {
191 return stream_factory;196 return queue_factory;
192 }197 }
193198
194 std::shared_ptr<msc::BufferStreamFactory> const stream_factory;199 std::shared_ptr<msc::BufferQueueFactory> const queue_factory;
195 std::shared_ptr<mg::Platform> const platform;200 std::shared_ptr<mg::Platform> const platform;
196};201};
197202
198203
=== modified file 'tests/integration-tests/test_session.cpp'
--- tests/integration-tests/test_session.cpp 2015-03-12 03:19:52 +0000
+++ tests/integration-tests/test_session.cpp 2015-03-20 19:31:52 +0000
@@ -25,7 +25,6 @@
25#include "mir/scene/surface.h"25#include "mir/scene/surface.h"
26#include "mir/scene/surface_creation_parameters.h"26#include "mir/scene/surface_creation_parameters.h"
27#include "mir/scene/null_session_listener.h"27#include "mir/scene/null_session_listener.h"
28#include "mir/compositor/buffer_stream.h"
29#include "mir/compositor/renderer.h"28#include "mir/compositor/renderer.h"
30#include "mir/compositor/renderer_factory.h"29#include "mir/compositor/renderer_factory.h"
31#include "mir/frontend/connector.h"30#include "mir/frontend/connector.h"
3231
=== modified file 'tests/integration-tests/test_surface_stack_with_compositor.cpp'
--- tests/integration-tests/test_surface_stack_with_compositor.cpp 2015-03-12 03:19:52 +0000
+++ tests/integration-tests/test_surface_stack_with_compositor.cpp 2015-03-20 19:31:52 +0000
@@ -21,11 +21,11 @@
21#include "src/server/report/null_report_factory.h"21#include "src/server/report/null_report_factory.h"
22#include "src/server/scene/surface_stack.h"22#include "src/server/scene/surface_stack.h"
23#include "src/server/compositor/gl_renderer_factory.h"23#include "src/server/compositor/gl_renderer_factory.h"
24#include "mir_test_doubles/mock_buffer_bundle.h"
24#include "src/server/scene/basic_surface.h"25#include "src/server/scene/basic_surface.h"
25#include "src/server/compositor/default_display_buffer_compositor_factory.h"26#include "src/server/compositor/default_display_buffer_compositor_factory.h"
26#include "src/server/compositor/multi_threaded_compositor.h"27#include "src/server/compositor/multi_threaded_compositor.h"
27#include "mir_test/fake_shared.h"28#include "mir_test/fake_shared.h"
28#include "mir_test_doubles/mock_buffer_stream.h"
29#include "mir_test_doubles/null_display.h"29#include "mir_test_doubles/null_display.h"
30#include "mir_test_doubles/stub_renderer.h"30#include "mir_test_doubles/stub_renderer.h"
31#include "mir_test_doubles/stub_display_buffer.h"31#include "mir_test_doubles/stub_display_buffer.h"
@@ -120,27 +120,24 @@
120{120{
121 SurfaceStackCompositor() :121 SurfaceStackCompositor() :
122 timeout{std::chrono::system_clock::now() + std::chrono::seconds(5)},122 timeout{std::chrono::system_clock::now() + std::chrono::seconds(5)},
123 mock_buffer_stream(std::make_shared<testing::NiceMock<mtd::MockBufferStream>>()),123 mock_buffer_bundle(std::make_shared<testing::NiceMock<mtd::MockBufferBundle>>()),
124 stub_surface{std::make_shared<ms::BasicSurface>(124 stub_surface{std::make_shared<ms::BasicSurface>(
125 std::string("stub"),125 std::string("stub"),
126 geom::Rectangle{{0,0},{1,1}},126 geom::Rectangle{{0,0},{1,1}},
127 false,127 false,
128 mock_buffer_stream,128 mock_buffer_bundle,
129 std::shared_ptr<mir::input::InputChannel>(),129 std::shared_ptr<mir::input::InputChannel>(),
130 std::shared_ptr<mtd::StubInputSender>(),130 std::shared_ptr<mtd::StubInputSender>(),
131 std::shared_ptr<mg::CursorImage>(),131 std::shared_ptr<mg::CursorImage>(),
132 null_scene_report)}132 null_scene_report)}
133 {133 {
134 using namespace testing;
135 ON_CALL(*mock_buffer_stream, lock_compositor_buffer(_))
136 .WillByDefault(Return(mt::fake_shared(stubbuf)));
137 }134 }
138 std::shared_ptr<ms::SceneReport> null_scene_report{mr::null_scene_report()};135 std::shared_ptr<ms::SceneReport> null_scene_report{mr::null_scene_report()};
139 ms::SurfaceStack stack{null_scene_report};136 ms::SurfaceStack stack{null_scene_report};
140 std::shared_ptr<mc::CompositorReport> null_comp_report{mr::null_compositor_report()};137 std::shared_ptr<mc::CompositorReport> null_comp_report{mr::null_compositor_report()};
141 StubRendererFactory renderer_factory;138 StubRendererFactory renderer_factory;
142 std::chrono::system_clock::time_point timeout;139 std::chrono::system_clock::time_point timeout;
143 std::shared_ptr<mtd::MockBufferStream> mock_buffer_stream;140 std::shared_ptr<mtd::MockBufferBundle> mock_buffer_bundle;
144 std::shared_ptr<ms::BasicSurface> stub_surface;141 std::shared_ptr<ms::BasicSurface> stub_surface;
145 ms::SurfaceCreationParameters default_params;142 ms::SurfaceCreationParameters default_params;
146 mtd::StubBuffer stubbuf;143 mtd::StubBuffer stubbuf;
@@ -203,7 +200,7 @@
203TEST_F(SurfaceStackCompositor, compositor_runs_until_all_surfaces_buffers_are_consumed)200TEST_F(SurfaceStackCompositor, compositor_runs_until_all_surfaces_buffers_are_consumed)
204{201{
205 using namespace testing;202 using namespace testing;
206 ON_CALL(*mock_buffer_stream, buffers_ready_for_compositor(_))203 ON_CALL(*mock_buffer_bundle, buffers_ready_for_compositor(_))
207 .WillByDefault(Return(5));204 .WillByDefault(Return(5));
208205
209 mc::MultiThreadedCompositor mt_compositor(206 mc::MultiThreadedCompositor mt_compositor(
@@ -224,7 +221,7 @@
224TEST_F(SurfaceStackCompositor, bypassed_compositor_runs_until_all_surfaces_buffers_are_consumed)221TEST_F(SurfaceStackCompositor, bypassed_compositor_runs_until_all_surfaces_buffers_are_consumed)
225{222{
226 using namespace testing;223 using namespace testing;
227 ON_CALL(*mock_buffer_stream, buffers_ready_for_compositor(_))224 ON_CALL(*mock_buffer_bundle, buffers_ready_for_compositor(_))
228 .WillByDefault(Return(5));225 .WillByDefault(Return(5));
229226
230 stub_surface->resize(geom::Size{10,10});227 stub_surface->resize(geom::Size{10,10});
@@ -247,7 +244,7 @@
247TEST_F(SurfaceStackCompositor, an_empty_scene_retriggers)244TEST_F(SurfaceStackCompositor, an_empty_scene_retriggers)
248{245{
249 using namespace testing;246 using namespace testing;
250 ON_CALL(*mock_buffer_stream, buffers_ready_for_compositor(_))247 ON_CALL(*mock_buffer_bundle, buffers_ready_for_compositor(_))
251 .WillByDefault(Return(0));248 .WillByDefault(Return(0));
252249
253 mc::MultiThreadedCompositor mt_compositor(250 mc::MultiThreadedCompositor mt_compositor(
@@ -311,8 +308,8 @@
311TEST_F(SurfaceStackCompositor, buffer_updates_trigger_composition)308TEST_F(SurfaceStackCompositor, buffer_updates_trigger_composition)
312{309{
313 using namespace testing;310 using namespace testing;
314 ON_CALL(*mock_buffer_stream, buffers_ready_for_compositor(_))311 ON_CALL(*mock_buffer_bundle, buffers_ready_for_compositor(_))
315 .WillByDefault(testing::Return(1));312 .WillByDefault(Return(1));
316 stack.add_surface(stub_surface, default_params.depth, default_params.input_mode);313 stack.add_surface(stub_surface, default_params.depth, default_params.input_mode);
317 stub_surface->swap_buffers(&stubbuf, [](mg::Buffer*){});314 stub_surface->swap_buffers(&stubbuf, [](mg::Buffer*){});
318315
319316
=== modified file 'tests/integration-tests/test_swapinterval.cpp'
--- tests/integration-tests/test_swapinterval.cpp 2015-03-16 03:39:55 +0000
+++ tests/integration-tests/test_swapinterval.cpp 2015-03-20 19:31:52 +0000
@@ -23,12 +23,12 @@
23#include "mir/compositor/compositor.h"23#include "mir/compositor/compositor.h"
24#include "mir/compositor/display_buffer_compositor.h"24#include "mir/compositor/display_buffer_compositor.h"
25#include "mir/compositor/scene.h"25#include "mir/compositor/scene.h"
26#include "mir/compositor/buffer_stream.h"26#include "mir/compositor/buffer_bundle.h"
27#include "mir/scene/buffer_stream_factory.h"27#include "mir/scene/buffer_queue_factory.h"
2828
29#include "mir_test_framework/display_server_test_fixture.h"29#include "mir_test_framework/display_server_test_fixture.h"
30#include "mir_test_doubles/stub_buffer.h"30#include "mir_test_doubles/stub_buffer.h"
31#include "mir_test_doubles/stub_buffer_stream.h"31#include "mir_test_doubles/stub_buffer_bundle.h"
3232
33#include "mir_toolkit/mir_client_library.h"33#include "mir_toolkit/mir_client_library.h"
3434
@@ -49,22 +49,23 @@
49{49{
50char const* const mir_test_socket = mtf::test_socket_file().c_str();50char const* const mir_test_socket = mtf::test_socket_file().c_str();
5151
52class CountingBufferStream : public mtd::StubBufferStream52class CountingBufferBundle : public mtd::StubBufferBundle
53{53{
54public:54public:
55 CountingBufferStream(int render_operations_fd)55 CountingBufferBundle(int render_operations_fd)
56 : render_operations_fd(render_operations_fd)56 : render_operations_fd(render_operations_fd)
57 {57 {
58 }58 }
5959
60 std::shared_ptr<mg::Buffer> lock_compositor_buffer(void const*) override60 mc::BufferHandle compositor_acquire(void const*) override
61 { return std::make_shared<mtd::StubBuffer>(); }61 {
6262 return std::move(mc::BufferHandle(nullptr, nullptr));
63 std::shared_ptr<mg::Buffer> lock_snapshot_buffer() override63 }
64 { return std::make_shared<mtd::StubBuffer>(); }64
6565 mc::BufferHandle snapshot_acquire() override
66 MirPixelFormat get_stream_pixel_format() override66 {
67 { return mir_pixel_format_abgr_8888; }67 return std::move(mc::BufferHandle(nullptr, nullptr));
68 }
6869
69 void allow_framedropping(bool) override70 void allow_framedropping(bool) override
70 {71 {
@@ -75,18 +76,17 @@
75 int render_operations_fd;76 int render_operations_fd;
76};77};
7778
78class StubStreamFactory : public ms::BufferStreamFactory79class StubQueueFactory : public ms::BufferQueueFactory
79{80{
80public:81public:
81 StubStreamFactory(int render_operations_fd)82 StubQueueFactory(int render_operations_fd)
82 : render_operations_fd(render_operations_fd)83 : render_operations_fd(render_operations_fd)
83 {84 {
84 }85 }
8586
86 std::shared_ptr<mc::BufferStream> create_buffer_stream(87 std::shared_ptr<mc::BufferBundle> create_buffer_queue(int, mg::BufferProperties const&) override
87 int, mg::BufferProperties const&) override
88 {88 {
89 return std::make_shared<CountingBufferStream>(render_operations_fd);89 return std::make_shared<CountingBufferBundle>(render_operations_fd);
90 }90 }
91private:91private:
92 int render_operations_fd;92 int render_operations_fd;
@@ -128,11 +128,11 @@
128 close(rendering_ops_pipe[1]);128 close(rendering_ops_pipe[1]);
129 }129 }
130130
131 std::shared_ptr<ms::BufferStreamFactory> the_buffer_stream_factory() override131 std::shared_ptr<ms::BufferQueueFactory> the_buffer_queue_factory() override
132 {132 {
133 if (!stub_stream_factory)133 if (!stub_queue_factory)
134 stub_stream_factory = std::make_shared<StubStreamFactory>(rendering_ops_pipe[1]);134 stub_queue_factory = std::make_shared<StubQueueFactory>(rendering_ops_pipe[1]);
135 return stub_stream_factory;135 return stub_queue_factory;
136 }136 }
137137
138 int num_of_swapinterval_devices()138 int num_of_swapinterval_devices()
@@ -147,7 +147,7 @@
147 }147 }
148148
149 int rendering_ops_pipe[2];149 int rendering_ops_pipe[2];
150 std::shared_ptr<StubStreamFactory> stub_stream_factory;150 std::shared_ptr<StubQueueFactory> stub_queue_factory;
151 } server_config;151 } server_config;
152152
153 launch_server_process(server_config);153 launch_server_process(server_config);
154154
=== modified file 'tests/unit-tests/compositor/CMakeLists.txt'
--- tests/unit-tests/compositor/CMakeLists.txt 2015-03-06 03:52:41 +0000
+++ tests/unit-tests/compositor/CMakeLists.txt 2015-03-20 19:31:52 +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_buffer_stream.cpp3 ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer_handle.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_buffer_queue.cpp5 ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer_queue.cpp
7 ${CMAKE_CURRENT_SOURCE_DIR}/test_gl_renderer.cpp6 ${CMAKE_CURRENT_SOURCE_DIR}/test_gl_renderer.cpp
87
=== added file 'tests/unit-tests/compositor/test_buffer_handle.cpp'
--- tests/unit-tests/compositor/test_buffer_handle.cpp 1970-01-01 00:00:00 +0000
+++ tests/unit-tests/compositor/test_buffer_handle.cpp 2015-03-20 19:31:52 +0000
@@ -0,0 +1,40 @@
1/*
2 * Copyright © 2015 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 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: Cemil Azizoglu <cemil.azizoglu@canonical.com>
17 */
18
19#include "mir_test_doubles/stub_buffer.h"
20#include "mir/compositor/buffer_handle.h"
21#include "mir_test/fake_shared.h"
22
23namespace mc = mir::compositor;
24namespace mg = mir::graphics;
25namespace mt = mir::test;
26namespace mtd = mir::test::doubles;
27
28TEST(BufferHandleTest, can_contain_handout_and_release_buffer)
29{
30 mtd::StubBuffer mock_buffer;
31
32 mc::BufferHandle buffer_handle(
33 mt::fake_shared(mock_buffer),
34 [&](mg::Buffer* b)
35 {
36 ASSERT_EQ(b, &mock_buffer);
37 });
38
39 ASSERT_EQ(buffer_handle.buffer().get(), &mock_buffer);
40}
041
=== modified file 'tests/unit-tests/compositor/test_buffer_queue.cpp'
--- tests/unit-tests/compositor/test_buffer_queue.cpp 2015-03-06 03:52:41 +0000
+++ tests/unit-tests/compositor/test_buffer_queue.cpp 2015-03-20 19:31:52 +0000
@@ -17,7 +17,8 @@
17 * Alberto Aguirre <alberto.aguirre@canonical.com>17 * Alberto Aguirre <alberto.aguirre@canonical.com>
18 */18 */
1919
20#include "src/server/compositor/buffer_queue.h"20#include "mir/compositor/buffer_queue.h"
21#include "mir/compositor/buffer_handle.h"
21#include "mir_test_doubles/stub_buffer_allocator.h"22#include "mir_test_doubles/stub_buffer_allocator.h"
22#include "mir_test_doubles/stub_buffer.h"23#include "mir_test_doubles/stub_buffer.h"
23#include "mir_test_doubles/stub_frame_dropping_policy_factory.h"24#include "mir_test_doubles/stub_frame_dropping_policy_factory.h"
@@ -155,7 +156,7 @@
155{156{
156 while (!done)157 while (!done)
157 {158 {
158 bundle.compositor_release(bundle.compositor_acquire(nullptr));159 bundle.compositor_acquire(nullptr);
159 std::this_thread::yield();160 std::this_thread::yield();
160 }161 }
161}162}
@@ -165,7 +166,7 @@
165{166{
166 while (!done)167 while (!done)
167 {168 {
168 bundle.snapshot_release(bundle.snapshot_acquire());169 bundle.snapshot_acquire();
169 std::this_thread::yield();170 std::this_thread::yield();
170 }171 }
171}172}
@@ -196,10 +197,8 @@
196197
197TEST_F(BufferQueueTest, buffer_queue_of_one_is_supported)198TEST_F(BufferQueueTest, buffer_queue_of_one_is_supported)
198{199{
199 std::unique_ptr<mc::BufferQueue> q;200 std::shared_ptr<mc::BufferQueue> q;
200 ASSERT_NO_THROW(q = std::move(201 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(1, allocator, basic_properties, policy_factory));
201 std::unique_ptr<mc::BufferQueue>(
202 new mc::BufferQueue(1, allocator, basic_properties, policy_factory))));
203 ASSERT_THAT(q, Ne(nullptr));202 ASSERT_THAT(q, Ne(nullptr));
204203
205 auto handle = client_acquire_async(*q);204 auto handle = client_acquire_async(*q);
@@ -212,18 +211,18 @@
212 auto next_request = client_acquire_async(*q);211 auto next_request = client_acquire_async(*q);
213 EXPECT_THAT(next_request->has_acquired_buffer(), Eq(false));212 EXPECT_THAT(next_request->has_acquired_buffer(), Eq(false));
214213
215 auto comp_buffer = q->compositor_acquire(this);214 {
216 auto client_id = handle->id();215 auto comp_buffer_handle = q->compositor_acquire(this);
217216 auto client_id = handle->id();
218 /* Client and compositor always share the same buffer */217
219 EXPECT_THAT(client_id, Eq(comp_buffer->id()));218 /* Client and compositor always share the same buffer */
220219 EXPECT_THAT(client_id, Eq(comp_buffer_handle.buffer()->id()));
221 EXPECT_NO_THROW(handle->release_buffer());220
222 EXPECT_NO_THROW(q->compositor_release(comp_buffer));221 EXPECT_NO_THROW(handle->release_buffer());
222 }
223223
224 /* Simulate a composite pass */224 /* Simulate a composite pass */
225 comp_buffer = q->compositor_acquire(this);225 q->compositor_acquire(this);
226 q->compositor_release(comp_buffer);
227226
228 /* The request should now be fullfilled after compositor227 /* The request should now be fullfilled after compositor
229 * released the buffer228 * released the buffer
@@ -234,27 +233,29 @@
234233
235TEST_F(BufferQueueTest, buffer_queue_of_one_supports_resizing)234TEST_F(BufferQueueTest, buffer_queue_of_one_supports_resizing)
236{235{
237 mc::BufferQueue q(1, allocator, basic_properties, policy_factory);236 std::shared_ptr<mc::BufferQueue> q;
237 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(1, allocator, basic_properties, policy_factory));
238 ASSERT_THAT(q, Ne(nullptr));
238239
239 const geom::Size expect_size{10, 20};240 const geom::Size expect_size{10, 20};
240 q.resize(expect_size);241 q->resize(expect_size);
241242
242 auto handle = client_acquire_async(q);243 auto handle = client_acquire_async(*q);
243 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));244 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
244 auto buffer = handle->buffer();245 auto buffer = handle->buffer();
245 ASSERT_THAT(buffer->size(), Eq(expect_size));246 ASSERT_THAT(buffer->size(), Eq(expect_size));
246247 {
247 /* Client and compositor share the same buffer so248 /* Client and compositor share the same buffer so
248 * expect the new size249 * expect the new size
249 */250 */
250 std::shared_ptr<mg::Buffer> comp_buffer;251 auto comp_buffer_handle = q->compositor_acquire(this);
251 ASSERT_NO_THROW(comp_buffer = q.compositor_acquire(this));252 ASSERT_NO_THROW(comp_buffer_handle.buffer());
252253
253 EXPECT_THAT(buffer->size(), Eq(expect_size));254 EXPECT_THAT(buffer->size(), Eq(expect_size));
254 EXPECT_NO_THROW(q.compositor_release(comp_buffer));255 }
255256
256 EXPECT_NO_THROW(handle->release_buffer());257 EXPECT_NO_THROW(handle->release_buffer());
257 EXPECT_NO_THROW(q.compositor_release(q.compositor_acquire(this)));258 EXPECT_NO_THROW(q->compositor_acquire(this));
258}259}
259260
260TEST_F(BufferQueueTest, framedropping_is_disabled_by_default)261TEST_F(BufferQueueTest, framedropping_is_disabled_by_default)
@@ -302,25 +303,27 @@
302TEST_F(BufferQueueTest, clients_can_have_multiple_pending_completions)303TEST_F(BufferQueueTest, clients_can_have_multiple_pending_completions)
303{304{
304 int const nbuffers = 3;305 int const nbuffers = 3;
305 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);306 std::shared_ptr<mc::BufferQueue> q;
307 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
308 ASSERT_THAT(q, Ne(nullptr));
306309
307 int const prefill = q.buffers_free_for_client();310 int const prefill = q->buffers_free_for_client();
308 ASSERT_THAT(prefill, Gt(0));311 ASSERT_THAT(prefill, Gt(0));
309 for (int i = 0; i < prefill; ++i)312 for (int i = 0; i < prefill; ++i)
310 {313 {
311 auto handle = client_acquire_async(q);314 auto handle = client_acquire_async(*q);
312 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));315 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
313 handle->release_buffer();316 handle->release_buffer();
314 }317 }
315318
316 auto handle1 = client_acquire_async(q);319 auto handle1 = client_acquire_async(*q);
317 ASSERT_THAT(handle1->has_acquired_buffer(), Eq(false));320 ASSERT_THAT(handle1->has_acquired_buffer(), Eq(false));
318321
319 auto handle2 = client_acquire_async(q);322 auto handle2 = client_acquire_async(*q);
320 ASSERT_THAT(handle1->has_acquired_buffer(), Eq(false));323 ASSERT_THAT(handle1->has_acquired_buffer(), Eq(false));
321324
322 for (int i = 0; i < nbuffers + 1; ++i)325 for (int i = 0; i < nbuffers + 1; ++i)
323 q.compositor_release(q.compositor_acquire(this));326 q->compositor_acquire(this);
324327
325 EXPECT_THAT(handle1->has_acquired_buffer(), Eq(true));328 EXPECT_THAT(handle1->has_acquired_buffer(), Eq(true));
326 EXPECT_THAT(handle2->has_acquired_buffer(), Eq(true));329 EXPECT_THAT(handle2->has_acquired_buffer(), Eq(true));
@@ -334,27 +337,32 @@
334{337{
335 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)338 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)
336 {339 {
337 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);340 std::shared_ptr<mc::BufferQueue> q;
338 ASSERT_THAT(q.framedropping_allowed(), Eq(false));341 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
342 ASSERT_THAT(q, Ne(nullptr));
343 ASSERT_THAT(q->framedropping_allowed(), Eq(false));
339344
340 void const* main_compositor = reinterpret_cast<void const*>(0);345 void const* main_compositor = reinterpret_cast<void const*>(0);
341 void const* second_compositor = reinterpret_cast<void const*>(1);346 void const* second_compositor = reinterpret_cast<void const*>(1);
342 for (int i = 0; i < 20; i++)347 for (int i = 0; i < 20; i++)
343 {348 {
344 auto handle = client_acquire_async(q);349 auto handle = client_acquire_async(*q);
345 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));350 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
346 auto client_id = handle->id();351 auto client_id = handle->id();
347 handle->release_buffer();352 handle->release_buffer();
348353
349 auto comp_buffer = q.compositor_acquire(main_compositor);354 mg::BufferID composited_id;
350 auto composited_id = comp_buffer->id();355 {
351 q.compositor_release(comp_buffer);356 auto comp_buffer_handle = q->compositor_acquire(main_compositor);
357 composited_id = comp_buffer_handle.buffer()->id();
358 }
352359
353 EXPECT_THAT(composited_id, Eq(client_id));360 EXPECT_THAT(composited_id, Eq(client_id));
354361
355 comp_buffer = q.compositor_acquire(second_compositor);362 {
356 EXPECT_THAT(composited_id, Eq(comp_buffer->id()));363 auto comp_buffer_handle = q->compositor_acquire(second_compositor);
357 q.compositor_release(comp_buffer);364 EXPECT_THAT(composited_id, Eq(comp_buffer_handle.buffer()->id()));
365 }
358 }366 }
359 }367 }
360}368}
@@ -378,20 +386,21 @@
378/* Regression test for LP: #1210042 */386/* Regression test for LP: #1210042 */
379TEST_F(BufferQueueTest, clients_dont_recycle_startup_buffer)387TEST_F(BufferQueueTest, clients_dont_recycle_startup_buffer)
380{388{
381 mc::BufferQueue q(3, allocator, basic_properties, policy_factory);389 std::shared_ptr<mc::BufferQueue> q;
390 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(3, allocator, basic_properties, policy_factory));
391 ASSERT_THAT(q, Ne(nullptr));
382392
383 auto handle = client_acquire_async(q);393 auto handle = client_acquire_async(*q);
384 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));394 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
385 auto client_id = handle->id();395 auto client_id = handle->id();
386 handle->release_buffer();396 handle->release_buffer();
387397
388 handle = client_acquire_async(q);398 handle = client_acquire_async(*q);
389 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));399 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
390 handle->release_buffer();400 handle->release_buffer();
391401
392 auto comp_buffer = q.compositor_acquire(this);402 auto comp_buffer_handle = q->compositor_acquire(this);
393 EXPECT_THAT(client_id, Eq(comp_buffer->id()));403 EXPECT_THAT(client_id, Eq(comp_buffer_handle.buffer()->id()));
394 q.compositor_release(comp_buffer);
395}404}
396405
397TEST_F(BufferQueueTest, throws_on_out_of_order_client_release)406TEST_F(BufferQueueTest, throws_on_out_of_order_client_release)
@@ -418,12 +427,14 @@
418{427{
419 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)428 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)
420 {429 {
421 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);430 std::shared_ptr<mc::BufferQueue> q;
431 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
432 ASSERT_THAT(q, Ne(nullptr));
422433
423 std::atomic<bool> done(false);434 std::atomic<bool> done(false);
424 auto unblock = [&done] { done = true; };435 auto unblock = [&done] { done = true; };
425 mt::AutoUnblockThread compositor(unblock,436 mt::AutoUnblockThread compositor(unblock,
426 compositor_thread, std::ref(q), std::ref(done));437 compositor_thread, std::ref(*q), std::ref(done));
427438
428 std::unordered_set<uint32_t> ids_acquired;439 std::unordered_set<uint32_t> ids_acquired;
429 int const max_ownable_buffers = nbuffers - 1;440 int const max_ownable_buffers = nbuffers - 1;
@@ -432,7 +443,7 @@
432 std::vector<mg::Buffer *> client_buffers;443 std::vector<mg::Buffer *> client_buffers;
433 for (int acquires = 0; acquires < max_ownable_buffers; ++acquires)444 for (int acquires = 0; acquires < max_ownable_buffers; ++acquires)
434 {445 {
435 auto handle = client_acquire_async(q);446 auto handle = client_acquire_async(*q);
436 handle->wait_for(std::chrono::seconds(1));447 handle->wait_for(std::chrono::seconds(1));
437 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));448 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
438 ids_acquired.insert(handle->id().as_value());449 ids_acquired.insert(handle->id().as_value());
@@ -441,7 +452,7 @@
441452
442 for (auto const& buffer : client_buffers)453 for (auto const& buffer : client_buffers)
443 {454 {
444 q.client_release(buffer);455 q->client_release(buffer);
445 }456 }
446 }457 }
447458
@@ -453,17 +464,18 @@
453{464{
454 for (int nbuffers = 1; nbuffers <= max_nbuffers_to_test; ++nbuffers)465 for (int nbuffers = 1; nbuffers <= max_nbuffers_to_test; ++nbuffers)
455 {466 {
456 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);467 std::shared_ptr<mc::BufferQueue> q;
468 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
469 ASSERT_THAT(q, Ne(nullptr));
457470
458 auto handle = client_acquire_async(q);471 auto handle = client_acquire_async(*q);
459 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));472 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
460473
461 auto client_id = handle->id();474 auto client_id = handle->id();
462 ASSERT_NO_THROW(handle->release_buffer());475 ASSERT_NO_THROW(handle->release_buffer());
463476
464 auto comp_buffer = q.compositor_acquire(this);477 auto comp_buffer_handle = q->compositor_acquire(this);
465 EXPECT_THAT(client_id, Eq(comp_buffer->id()));478 EXPECT_THAT(client_id, Eq(comp_buffer_handle.buffer()->id()));
466 EXPECT_NO_THROW(q.compositor_release(comp_buffer));
467 }479 }
468}480}
469481
@@ -471,9 +483,11 @@
471{483{
472 for (int nbuffers = 1; nbuffers <= max_nbuffers_to_test; ++nbuffers)484 for (int nbuffers = 1; nbuffers <= max_nbuffers_to_test; ++nbuffers)
473 {485 {
474 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);486 std::shared_ptr<mc::BufferQueue> q;
487 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
488 ASSERT_THAT(q, Ne(nullptr));
475489
476 auto handle = client_acquire_async(q);490 auto handle = client_acquire_async(*q);
477 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));491 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
478492
479 auto client_id = handle->id();493 auto client_id = handle->id();
@@ -482,9 +496,8 @@
482 for (int monitor = 0; monitor < 10; monitor++)496 for (int monitor = 0; monitor < 10; monitor++)
483 {497 {
484 void const* user_id = reinterpret_cast<void const*>(monitor);498 void const* user_id = reinterpret_cast<void const*>(monitor);
485 auto comp_buffer = q.compositor_acquire(user_id);499 auto comp_buffer_handle = q->compositor_acquire(user_id);
486 EXPECT_THAT(client_id, Eq(comp_buffer->id()));500 EXPECT_THAT(client_id, Eq(comp_buffer_handle.buffer()->id()));
487 q.compositor_release(comp_buffer);
488 }501 }
489 }502 }
490}503}
@@ -493,16 +506,18 @@
493{ // Regression test for LP: #1420678506{ // Regression test for LP: #1420678
494 for (int nbuffers = 3; nbuffers <= max_nbuffers_to_test; ++nbuffers)507 for (int nbuffers = 3; nbuffers <= max_nbuffers_to_test; ++nbuffers)
495 {508 {
496 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);509 std::shared_ptr<mc::BufferQueue> q;
510 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
511 ASSERT_THAT(q, Ne(nullptr));
497512
498 // Client generates first frame513 // Client generates first frame
499 auto handle1 = client_acquire_async(q);514 auto handle1 = client_acquire_async(*q);
500 ASSERT_TRUE(handle1->has_acquired_buffer());515 ASSERT_TRUE(handle1->has_acquired_buffer());
501 auto client_id1 = handle1->id();516 auto client_id1 = handle1->id();
502 handle1->release_buffer();517 handle1->release_buffer();
503518
504 // Client generates second frame519 // Client generates second frame
505 auto handle2 = client_acquire_async(q);520 auto handle2 = client_acquire_async(*q);
506 ASSERT_TRUE(handle2->has_acquired_buffer());521 ASSERT_TRUE(handle2->has_acquired_buffer());
507 auto client_id2 = handle2->id();522 auto client_id2 = handle2->id();
508 handle2->release_buffer();523 handle2->release_buffer();
@@ -511,18 +526,16 @@
511 for (int monitor = 0; monitor < 10; monitor++)526 for (int monitor = 0; monitor < 10; monitor++)
512 {527 {
513 void const* user_id = reinterpret_cast<void const*>(monitor);528 void const* user_id = reinterpret_cast<void const*>(monitor);
514 auto comp_buffer = q.compositor_acquire(user_id);529 auto comp_buffer_handle = q->compositor_acquire(user_id);
515 ASSERT_EQ(client_id1, comp_buffer->id());530 ASSERT_EQ(client_id1, comp_buffer_handle.buffer()->id());
516 q.compositor_release(comp_buffer);
517 }531 }
518532
519 // Still many monitors... verify they all get the second frame.533 // Still many monitors... verify they all get the second frame.
520 for (int monitor = 0; monitor < 10; monitor++)534 for (int monitor = 0; monitor < 10; monitor++)
521 {535 {
522 void const* user_id = reinterpret_cast<void const*>(monitor);536 void const* user_id = reinterpret_cast<void const*>(monitor);
523 auto comp_buffer = q.compositor_acquire(user_id);537 auto comp_buffer_handle = q->compositor_acquire(user_id);
524 ASSERT_EQ(client_id2, comp_buffer->id());538 ASSERT_EQ(client_id2, comp_buffer_handle.buffer()->id());
525 q.compositor_release(comp_buffer);
526 }539 }
527 }540 }
528}541}
@@ -531,7 +544,9 @@
531{544{
532 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)545 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)
533 {546 {
534 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);547 std::shared_ptr<mc::BufferQueue> q;
548 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
549 ASSERT_THAT(q, Ne(nullptr));
535550
536 for (int i = 0; i < 10; ++i)551 for (int i = 0; i < 10; ++i)
537 {552 {
@@ -540,7 +555,7 @@
540 int const max_ownable_buffers = nbuffers - 1;555 int const max_ownable_buffers = nbuffers - 1;
541 for (int i = 0; i < max_ownable_buffers; ++i)556 for (int i = 0; i < max_ownable_buffers; ++i)
542 {557 {
543 auto handle = client_acquire_async(q);558 auto handle = client_acquire_async(*q);
544 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));559 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
545 buffers.push_back(handle->buffer());560 buffers.push_back(handle->buffer());
546 }561 }
@@ -548,14 +563,13 @@
548 for (auto buffer : buffers)563 for (auto buffer : buffers)
549 {564 {
550 client_release_sequence.push_back(buffer->id());565 client_release_sequence.push_back(buffer->id());
551 q.client_release(buffer);566 q->client_release(buffer);
552 }567 }
553568
554 for (auto const& client_id : client_release_sequence)569 for (auto const& client_id : client_release_sequence)
555 {570 {
556 auto comp_buffer = q.compositor_acquire(this);571 auto comp_buffer_handle = q->compositor_acquire(this);
557 EXPECT_THAT(client_id, Eq(comp_buffer->id()));572 EXPECT_THAT(client_id, Eq(comp_buffer_handle.buffer()->id()));
558 q.compositor_release(comp_buffer);
559 }573 }
560 }574 }
561 }575 }
@@ -565,13 +579,12 @@
565{579{
566 for (int nbuffers = 1; nbuffers <= max_nbuffers_to_test; ++nbuffers)580 for (int nbuffers = 1; nbuffers <= max_nbuffers_to_test; ++nbuffers)
567 {581 {
568 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);582 std::shared_ptr<mc::BufferQueue> q;
583 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
584 ASSERT_THAT(q, Ne(nullptr));
569585
570 for (int i = 0; i < 100; i++)586 for (int i = 0; i < 100; i++)
571 {587 q->compositor_acquire(this);
572 auto buffer = q.compositor_acquire(this);
573 q.compositor_release(buffer);
574 }
575 }588 }
576}589}
577590
@@ -579,8 +592,10 @@
579{592{
580 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)593 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)
581 {594 {
582 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);595 std::shared_ptr<mc::BufferQueue> q;
583 q.allow_framedropping(false);596 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
597 ASSERT_THAT(q, Ne(nullptr));
598 q->allow_framedropping(false);
584599
585 std::atomic<bool> done(false);600 std::atomic<bool> done(false);
586 auto unblock = [&done] { done = true; };601 auto unblock = [&done] { done = true; };
@@ -589,7 +604,7 @@
589 {604 {
590 for (int nframes = 0; nframes < 100; ++nframes)605 for (int nframes = 0; nframes < 100; ++nframes)
591 {606 {
592 auto handle = client_acquire_async(q);607 auto handle = client_acquire_async(*q);
593 handle->wait_for(std::chrono::seconds(1));608 handle->wait_for(std::chrono::seconds(1));
594 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));609 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
595 handle->release_buffer();610 handle->release_buffer();
@@ -600,10 +615,11 @@
600 {615 {
601 while (!done)616 while (!done)
602 {617 {
603 std::shared_ptr<mg::Buffer> buffer;618 {
604 EXPECT_NO_THROW(buffer = q.compositor_acquire(this));619 std::shared_ptr<mg::Buffer> buffer;
605 EXPECT_THAT(buffer, Ne(nullptr));620 EXPECT_NO_THROW(buffer = q->compositor_acquire(this).buffer());
606 EXPECT_NO_THROW(q.compositor_release(buffer));621 EXPECT_THAT(buffer, Ne(nullptr));
622 }
607 std::this_thread::yield();623 std::this_thread::yield();
608 }624 }
609 });625 });
@@ -617,7 +633,9 @@
617{633{
618 for (int nbuffers = 1; nbuffers <= max_nbuffers_to_test; ++nbuffers)634 for (int nbuffers = 1; nbuffers <= max_nbuffers_to_test; ++nbuffers)
619 {635 {
620 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);636 std::shared_ptr<mc::BufferQueue> q;
637 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
638 ASSERT_THAT(q, Ne(nullptr));
621639
622 mg::Buffer* last_client_acquired_buffer{nullptr};640 mg::Buffer* last_client_acquired_buffer{nullptr};
623641
@@ -625,7 +643,7 @@
625 {643 {
626 if (i % 10 == 0)644 if (i % 10 == 0)
627 {645 {
628 auto handle = client_acquire_async(q);646 auto handle = client_acquire_async(*q);
629 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));647 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
630 last_client_acquired_buffer = handle->buffer();648 last_client_acquired_buffer = handle->buffer();
631 handle->release_buffer();649 handle->release_buffer();
@@ -634,51 +652,35 @@
634 for (int monitor_id = 0; monitor_id < 10; monitor_id++)652 for (int monitor_id = 0; monitor_id < 10; monitor_id++)
635 {653 {
636 void const* user_id = reinterpret_cast<void const*>(monitor_id);654 void const* user_id = reinterpret_cast<void const*>(monitor_id);
637 auto buffer = q.compositor_acquire(user_id);655 auto buffer_handle = q->compositor_acquire(user_id);
638 ASSERT_THAT(buffer.get(), Eq(last_client_acquired_buffer));656 ASSERT_THAT(buffer_handle.buffer().get(), Eq(last_client_acquired_buffer));
639 q.compositor_release(buffer);
640 }657 }
641 }658 }
642 }659 }
643}660}
644661
645TEST_F(BufferQueueTest, compositor_release_verifies_parameter)
646{
647 for (int nbuffers = 1; nbuffers <= max_nbuffers_to_test; ++nbuffers)
648 {
649 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);
650
651 auto handle = client_acquire_async(q);
652 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
653 handle->release_buffer();
654
655 auto comp_buffer = q.compositor_acquire(this);
656 q.compositor_release(comp_buffer);
657 EXPECT_THROW(q.compositor_release(comp_buffer), std::logic_error);
658 }
659}
660
661/* Regression test for LP#1270964 */662/* Regression test for LP#1270964 */
662TEST_F(BufferQueueTest, compositor_client_interleaved)663TEST_F(BufferQueueTest, compositor_client_interleaved)
663{664{
664 mc::BufferQueue q(3, allocator, basic_properties, policy_factory);665 std::shared_ptr<mc::BufferQueue> q;
666 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(3, allocator, basic_properties, policy_factory));
667 ASSERT_THAT(q, Ne(nullptr));
665668
666 auto handle = client_acquire_async(q);669 auto handle = client_acquire_async(*q);
667 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));670 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
668671
669 auto first_ready_buffer_id = handle->id();672 auto first_ready_buffer_id = handle->id();
670 handle->release_buffer();673 handle->release_buffer();
671674
672 handle = client_acquire_async(q);675 handle = client_acquire_async(*q);
673 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));676 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
674677
675 // in the original bug, compositor would be given the wrong buffer here678 // in the original bug, compositor would be given the wrong buffer here
676 auto compositor_buffer = q.compositor_acquire(this);679 auto compositor_buffer_handle = q->compositor_acquire(this);
677680
678 EXPECT_THAT(compositor_buffer->id(), Eq(first_ready_buffer_id));681 EXPECT_THAT(compositor_buffer_handle.buffer()->id(), Eq(first_ready_buffer_id));
679682
680 handle->release_buffer();683 handle->release_buffer();
681 q.compositor_release(compositor_buffer);
682}684}
683685
684TEST_F(BufferQueueTest, overlapping_compositors_get_different_frames)686TEST_F(BufferQueueTest, overlapping_compositors_get_different_frames)
@@ -686,36 +688,42 @@
686 // This test simulates bypass behaviour688 // This test simulates bypass behaviour
687 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)689 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)
688 {690 {
689 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);691 std::shared_ptr<mc::BufferQueue> q;
690692 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
691 std::shared_ptr<mg::Buffer> compositor[2];693 ASSERT_THAT(q, Ne(nullptr));
692694
693 auto handle = client_acquire_async(q);695 mc::BufferHandle *compositor[] =
694 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));696 { new mc::BufferHandle(nullptr, nullptr),
695 handle->release_buffer();697 new mc::BufferHandle(nullptr, nullptr) };
696 compositor[0] = q.compositor_acquire(this);698
697699 auto handle = client_acquire_async(*q);
698 handle = client_acquire_async(q);700 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
699 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));701 handle->release_buffer();
700 handle->release_buffer();702 *compositor[0] = q->compositor_acquire(this);
701 compositor[1] = q.compositor_acquire(this);703
704 handle = client_acquire_async(*q);
705 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
706 handle->release_buffer();
707 *compositor[1] = q->compositor_acquire(this);
702708
703 for (int i = 0; i < 20; i++)709 for (int i = 0; i < 20; i++)
704 {710 {
705 // Two compositors acquired, and they're always different...711 // Two compositors acquired, and they're always different...
706 ASSERT_THAT(compositor[0]->id(), Ne(compositor[1]->id()));712 ASSERT_THAT(compositor[0]->buffer()->id(), Ne(compositor[1]->buffer()->id()));
707
708 // One of the compositors (the oldest one) gets a new buffer...713 // One of the compositors (the oldest one) gets a new buffer...
709 int oldest = i & 1;714 int oldest = i & 1;
710 q.compositor_release(compositor[oldest]);715 delete compositor[oldest];
711 auto handle = client_acquire_async(q);716 compositor[oldest] = nullptr;
717 auto handle = client_acquire_async(*q);
712 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));718 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
713 handle->release_buffer();719 handle->release_buffer();
714 compositor[oldest] = q.compositor_acquire(this);720 compositor[oldest] = new mc::BufferHandle(nullptr, nullptr);
721 *compositor[oldest] = q->compositor_acquire(this);
715 }722 }
716723
717 q.compositor_release(compositor[0]);724 for (int i = 0; i < 2; i++)
718 q.compositor_release(compositor[1]);725 if (compositor[i])
726 delete compositor[i];
719 }727 }
720}728}
721729
@@ -723,13 +731,14 @@
723{731{
724 for (int nbuffers = 1; nbuffers <= max_nbuffers_to_test; ++nbuffers)732 for (int nbuffers = 1; nbuffers <= max_nbuffers_to_test; ++nbuffers)
725 {733 {
726 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);734 std::shared_ptr<mc::BufferQueue> q;
735 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
736 ASSERT_THAT(q, Ne(nullptr));
727737
728 auto comp_buffer = q.compositor_acquire(this);738 auto comp_buffer_handle = q->compositor_acquire(this);
729 auto snapshot = q.snapshot_acquire();739 auto snapshot_handle = q->snapshot_acquire();
730 EXPECT_THAT(snapshot->id(), Eq(comp_buffer->id()));740 EXPECT_THAT(snapshot_handle.buffer()->id(),
731 q.compositor_release(comp_buffer);741 Eq(comp_buffer_handle.buffer()->id()));
732 q.snapshot_release(snapshot);
733 }742 }
734}743}
735744
@@ -744,13 +753,16 @@
744753
745TEST_F(BufferQueueTest, callbacks_cant_happen_after_shutdown_with_snapshots)754TEST_F(BufferQueueTest, callbacks_cant_happen_after_shutdown_with_snapshots)
746{755{
747 mc::BufferQueue q(1, allocator, basic_properties, policy_factory);756 std::shared_ptr<mc::BufferQueue> q;
748757 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(1, allocator, basic_properties, policy_factory));
749 auto snapshot = q.snapshot_acquire();758 ASSERT_THAT(q, Ne(nullptr));
750 q.drop_client_requests();759
751 q.snapshot_release(snapshot);760 {
752761 auto snapshot = q->snapshot_acquire();
753 auto client = client_acquire_async(q);762 q->drop_client_requests();
763 }
764
765 auto client = client_acquire_async(*q);
754 ASSERT_FALSE(client->has_acquired_buffer());766 ASSERT_FALSE(client->has_acquired_buffer());
755}767}
756768
@@ -758,39 +770,19 @@
758{770{
759 for (int nbuffers = 1; nbuffers <= max_nbuffers_to_test; ++nbuffers)771 for (int nbuffers = 1; nbuffers <= max_nbuffers_to_test; ++nbuffers)
760 {772 {
761 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);773 std::shared_ptr<mc::BufferQueue> q;
774 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
775 ASSERT_THAT(q, Ne(nullptr));
762 int const num_snapshots = 100;776 int const num_snapshots = 100;
763777
764 std::shared_ptr<mg::Buffer> buf[num_snapshots];778 std::vector<mc::BufferHandle> bufs;
765 for (int i = 0; i < num_snapshots; i++)779 bufs.reserve(num_snapshots);
766 buf[i] = q.snapshot_acquire();780
767781 for (int i = 0; i < num_snapshots; i++)
768 for (int i = 0; i < num_snapshots; i++)782 bufs.push_back(std::move(mc::BufferHandle(nullptr, nullptr)));
769 q.snapshot_release(buf[i]);783
770 }784 for (int i = 0; i < num_snapshots; i++)
771}785 bufs[i] = q->snapshot_acquire();
772
773TEST_F(BufferQueueTest, snapshot_release_verifies_parameter)
774{
775 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)
776 {
777 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);
778
779 auto handle = client_acquire_async(q);
780 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
781 handle->release_buffer();
782
783 auto comp_buffer = q.compositor_acquire(this);
784 EXPECT_THROW(q.snapshot_release(comp_buffer), std::logic_error);
785
786 handle = client_acquire_async(q);
787 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
788 auto snapshot = q.snapshot_acquire();
789
790 EXPECT_THAT(snapshot->id(), Eq(comp_buffer->id()));
791 EXPECT_THAT(snapshot->id(), Ne(handle->id()));
792 EXPECT_NO_THROW(q.snapshot_release(snapshot));
793 EXPECT_THROW(q.snapshot_release(snapshot), std::logic_error);
794 }786 }
795}787}
796788
@@ -798,31 +790,33 @@
798{790{
799 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)791 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)
800 {792 {
801 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);793 std::shared_ptr<mc::BufferQueue> q;
794 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
795 ASSERT_THAT(q, Ne(nullptr));
802796
803 std::atomic<bool> done(false);797 std::atomic<bool> done(false);
804798
805 auto unblock = [&done]{ done = true;};799 auto unblock = [&done]{ done = true;};
806800
807 mt::AutoUnblockThread compositor(unblock, compositor_thread,801 mt::AutoUnblockThread compositor(unblock, compositor_thread,
808 std::ref(q),802 std::ref(*q),
809 std::ref(done));803 std::ref(done));
810 mt::AutoUnblockThread snapshotter1(unblock, snapshot_thread,804 mt::AutoUnblockThread snapshotter1(unblock, snapshot_thread,
811 std::ref(q),805 std::ref(*q),
812 std::ref(done));806 std::ref(done));
813 mt::AutoUnblockThread snapshotter2(unblock, snapshot_thread,807 mt::AutoUnblockThread snapshotter2(unblock, snapshot_thread,
814 std::ref(q),808 std::ref(*q),
815 std::ref(done));809 std::ref(done));
816810
817 q.allow_framedropping(false);811 q->allow_framedropping(false);
818 mt::AutoJoinThread client1(client_thread, std::ref(q), 1000);812 mt::AutoJoinThread client1(client_thread, std::ref(*q), 1000);
819 client1.stop();813 client1.stop();
820814
821 q.allow_framedropping(true);815 q->allow_framedropping(true);
822 mt::AutoJoinThread client2(client_thread, std::ref(q), 1000);816 mt::AutoJoinThread client2(client_thread, std::ref(*q), 1000);
823 client2.stop();817 client2.stop();
824818
825 mt::AutoJoinThread client3(switching_client_thread, std::ref(q), 1000);819 mt::AutoJoinThread client3(switching_client_thread, std::ref(*q), 1000);
826 client3.stop();820 client3.stop();
827 }821 }
828}822}
@@ -878,11 +872,13 @@
878{872{
879 for (int nbuffers = 2; nbuffers <= 3; nbuffers++)873 for (int nbuffers = 2; nbuffers <= 3; nbuffers++)
880 {874 {
881 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);875 std::shared_ptr<mc::BufferQueue> q;
876 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
877 ASSERT_THAT(q, Ne(nullptr));
882 unsigned long client_frames = 0;878 unsigned long client_frames = 0;
883 const unsigned long compose_frames = 20;879 const unsigned long compose_frames = 20;
884880
885 q.allow_framedropping(false);881 q->allow_framedropping(false);
886882
887 std::atomic<bool> done(false);883 std::atomic<bool> done(false);
888884
@@ -892,8 +888,7 @@
892 {888 {
893 std::this_thread::sleep_for(std::chrono::milliseconds(10));889 std::this_thread::sleep_for(std::chrono::milliseconds(10));
894890
895 auto buf = q.compositor_acquire(this);891 q->compositor_acquire(this);
896 q.compositor_release(buf);
897892
898 if (frame == compose_frames)893 if (frame == compose_frames)
899 {894 {
@@ -905,13 +900,13 @@
905 }900 }
906 });901 });
907902
908 auto handle = client_acquire_async(q);903 auto handle = client_acquire_async(*q);
909 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));904 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
910 handle->release_buffer();905 handle->release_buffer();
911906
912 while (!done.load())907 while (!done.load())
913 {908 {
914 auto handle = client_acquire_async(q);909 auto handle = client_acquire_async(*q);
915 handle->wait_for(std::chrono::seconds(1));910 handle->wait_for(std::chrono::seconds(1));
916 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));911 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
917 handle->release_buffer();912 handle->release_buffer();
@@ -934,12 +929,14 @@
934 */929 */
935 for (int nbuffers = 3; nbuffers <= 3; nbuffers++)930 for (int nbuffers = 3; nbuffers <= 3; nbuffers++)
936 {931 {
937 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);932 std::shared_ptr<mc::BufferQueue> q;
933 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
934 ASSERT_THAT(q, Ne(nullptr));
938 unsigned long client_frames = 0;935 unsigned long client_frames = 0;
939 unsigned long const compose_frames = 100;936 unsigned long const compose_frames = 100;
940 auto const frame_time = std::chrono::milliseconds(16);937 auto const frame_time = std::chrono::milliseconds(16);
941938
942 q.allow_framedropping(false);939 q->allow_framedropping(false);
943940
944 std::atomic<bool> done(false);941 std::atomic<bool> done(false);
945 std::mutex sync;942 std::mutex sync;
@@ -950,8 +947,7 @@
950 {947 {
951 std::this_thread::sleep_for(frame_time);948 std::this_thread::sleep_for(frame_time);
952 sync.lock();949 sync.lock();
953 auto buf = q.compositor_acquire(this);950 q->compositor_acquire(this);
954 q.compositor_release(buf);
955 sync.unlock();951 sync.unlock();
956952
957 if (frame == compose_frames)953 if (frame == compose_frames)
@@ -964,7 +960,7 @@
964 }960 }
965 });961 });
966962
967 auto handle = client_acquire_async(q);963 auto handle = client_acquire_async(*q);
968 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));964 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
969 handle->release_buffer();965 handle->release_buffer();
970966
@@ -972,7 +968,7 @@
972 {968 {
973 sync.lock();969 sync.lock();
974 sync.unlock();970 sync.unlock();
975 auto handle = client_acquire_async(q);971 auto handle = client_acquire_async(*q);
976 handle->wait_for(std::chrono::seconds(1));972 handle->wait_for(std::chrono::seconds(1));
977 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));973 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
978 std::this_thread::sleep_for(frame_time);974 std::this_thread::sleep_for(frame_time);
@@ -992,7 +988,9 @@
992{988{
993 for (int nbuffers = 1; nbuffers <= max_nbuffers_to_test; ++nbuffers)989 for (int nbuffers = 1; nbuffers <= max_nbuffers_to_test; ++nbuffers)
994 {990 {
995 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);991 std::shared_ptr<mc::BufferQueue> q;
992 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
993 ASSERT_THAT(q, Ne(nullptr));
996994
997 for (int width = 1; width < 100; ++width)995 for (int width = 1; width < 100; ++width)
998 {996 {
@@ -1000,16 +998,15 @@
1000998
1001 for (int subframe = 0; subframe < 3; ++subframe)999 for (int subframe = 0; subframe < 3; ++subframe)
1002 {1000 {
1003 q.resize(expect_size);1001 q->resize(expect_size);
1004 auto handle = client_acquire_async(q);1002 auto handle = client_acquire_async(*q);
1005 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));1003 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
1006 auto buffer = handle->buffer();1004 auto buffer = handle->buffer();
1007 ASSERT_THAT(expect_size, Eq(buffer->size()));1005 ASSERT_THAT(expect_size, Eq(buffer->size()));
1008 handle->release_buffer();1006 handle->release_buffer();
10091007
1010 auto comp_buffer = q.compositor_acquire(this);1008 auto comp_buffer_handle = q->compositor_acquire(this);
1011 ASSERT_THAT(expect_size, Eq(comp_buffer->size()));1009 ASSERT_THAT(expect_size, Eq(comp_buffer_handle.buffer()->size()));
1012 q.compositor_release(comp_buffer);
1013 }1010 }
1014 }1011 }
1015 }1012 }
@@ -1027,7 +1024,9 @@
1027{1024{
1028 for (int nbuffers = 1; nbuffers <= max_nbuffers_to_test; ++nbuffers)1025 for (int nbuffers = 1; nbuffers <= max_nbuffers_to_test; ++nbuffers)
1029 {1026 {
1030 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);1027 std::shared_ptr<mc::BufferQueue> q;
1028 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
1029 ASSERT_THAT(q, Ne(nullptr));
1031 std::vector<mg::BufferID> history;1030 std::vector<mg::BufferID> history;
10321031
1033 const int width0 = 123;1032 const int width0 = 123;
@@ -1036,7 +1035,7 @@
1036 const int dy = -3;1035 const int dy = -3;
1037 int width = width0;1036 int width = width0;
1038 int height = height0;1037 int height = height0;
1039 int const nbuffers_to_use = q.buffers_free_for_client();1038 int const nbuffers_to_use = q->buffers_free_for_client();
1040 ASSERT_THAT(nbuffers_to_use, Gt(0));1039 ASSERT_THAT(nbuffers_to_use, Gt(0));
10411040
1042 int max_buffers{max_ownable_buffers(nbuffers)};1041 int max_buffers{max_ownable_buffers(nbuffers)};
@@ -1046,8 +1045,8 @@
1046 width += dx;1045 width += dx;
1047 height += dy;1046 height += dy;
10481047
1049 q.resize(new_size);1048 q->resize(new_size);
1050 auto handle = client_acquire_async(q);1049 auto handle = client_acquire_async(*q);
1051 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));1050 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
1052 history.emplace_back(handle->id());1051 history.emplace_back(handle->id());
1053 auto buffer = handle->buffer();1052 auto buffer = handle->buffer();
@@ -1065,25 +1064,22 @@
1065 width += dx;1064 width += dx;
1066 height += dy;1065 height += dy;
10671066
1068 auto buffer = q.compositor_acquire(this);1067 auto buffer_handle = q->compositor_acquire(this);
10691068
1070 // Verify the compositor gets resized buffers, eventually1069 // Verify the compositor gets resized buffers, eventually
1071 ASSERT_THAT(buffer->size(), Eq(expect_size));1070 ASSERT_THAT(buffer_handle.buffer()->size(), Eq(expect_size));
10721071
1073 // Verify the compositor gets buffers with *contents*, ie. that1072 // Verify the compositor gets buffers with *contents*, ie. that
1074 // they have not been resized prematurely and are empty.1073 // they have not been resized prematurely and are empty.
1075 ASSERT_THAT(history[consume], Eq(buffer->id()));1074 ASSERT_THAT(history[consume], Eq(buffer_handle.buffer()->id()));
1076
1077 q.compositor_release(buffer);
1078 }1075 }
10791076
1080 // Verify the final buffer size sticks1077 // Verify the final buffer size sticks
1081 const geom::Size final_size{width - dx, height - dy};1078 const geom::Size final_size{width - dx, height - dy};
1082 for (int unchanging = 0; unchanging < 100; ++unchanging)1079 for (int unchanging = 0; unchanging < 100; ++unchanging)
1083 {1080 {
1084 auto buffer = q.compositor_acquire(this);1081 auto buffer_handle = q->compositor_acquire(this);
1085 ASSERT_THAT(buffer->size(), Eq(final_size));1082 ASSERT_THAT(buffer_handle.buffer()->size(), Eq(final_size));
1086 q.compositor_release(buffer);
1087 }1083 }
1088 }1084 }
1089}1085}
@@ -1093,23 +1089,22 @@
1093 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)1089 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)
1094 {1090 {
1095 mtd::MockFrameDroppingPolicyFactory policy_factory;1091 mtd::MockFrameDroppingPolicyFactory policy_factory;
1096 mc::BufferQueue q(nbuffers,1092 std::shared_ptr<mc::BufferQueue> q;
1097 allocator,1093 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
1098 basic_properties,1094 ASSERT_THAT(q, Ne(nullptr));
1099 policy_factory);
11001095
1101 auto first = client_acquire_sync(q);1096 auto first = client_acquire_sync(*q);
1102 q.client_release(first);1097 q->client_release(first);
11031098
1104 // Start rendering one (don't finish)1099 // Start rendering one (don't finish)
1105 auto d = q.compositor_acquire(nullptr);1100 auto d = q->compositor_acquire(nullptr);
1106 ASSERT_EQ(first, d.get());1101 ASSERT_EQ(first, d.buffer().get());
11071102
1108 auto second = client_acquire_sync(q);1103 auto second = client_acquire_sync(*q);
1109 q.client_release(second);1104 q->client_release(second);
11101105
1111 // Client waits for a new frame1106 // Client waits for a new frame
1112 auto end = client_acquire_async(q);1107 auto end = client_acquire_async(*q);
11131108
1114 // Surface goes offscreen or occluded; trigger a timeout1109 // Surface goes offscreen or occluded; trigger a timeout
1115 policy_factory.trigger_policies();1110 policy_factory.trigger_policies();
@@ -1121,8 +1116,6 @@
1121 // will produce another frame.1116 // will produce another frame.
1122 if (end->has_acquired_buffer())1117 if (end->has_acquired_buffer())
1123 ASSERT_NE(second, end->buffer());1118 ASSERT_NE(second, end->buffer());
1124
1125 q.compositor_release(d);
1126 }1119 }
1127}1120}
11281121
@@ -1130,34 +1123,33 @@
1130{ // Second regression test for LP: #1396006, LP: #13796851123{ // Second regression test for LP: #1396006, LP: #1379685
1131 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)1124 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)
1132 {1125 {
1133 mc::BufferQueue q(nbuffers,1126 std::shared_ptr<mc::BufferQueue> q;
1134 allocator,1127 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
1135 basic_properties,1128 ASSERT_THAT(q, Ne(nullptr));
1136 policy_factory);
11371129
1138 q.allow_framedropping(true);1130 q->allow_framedropping(true);
11391131
1140 // Fill 'er up1132 // Fill 'er up
1141 std::vector<mg::Buffer*> order;1133 std::vector<mg::Buffer*> order;
1142 for (int f = 0; f < nbuffers; ++f)1134 for (int f = 0; f < nbuffers; ++f)
1143 {1135 {
1144 auto b = client_acquire_sync(q);1136 auto b = client_acquire_sync(*q);
1145 order.push_back(b);1137 order.push_back(b);
1146 q.client_release(b);1138 q->client_release(b);
1147 }1139 }
11481140
1149 // Composite all but one1141 // Composite all but one
1150 std::vector<std::shared_ptr<mg::Buffer>> compositing;1142 std::vector<std::shared_ptr<mg::Buffer>> compositing;
1151 for (int n = 0; n < nbuffers-1; ++n)1143 for (int n = 0; n < nbuffers-1; ++n)
1152 {1144 {
1153 auto c = q.compositor_acquire(nullptr);1145 auto c = q->compositor_acquire(nullptr);
1154 compositing.push_back(c);1146 compositing.push_back(c.buffer());
1155 ASSERT_EQ(order[n], c.get());1147 ASSERT_EQ(order[n], c.buffer().get());
1156 }1148 }
11571149
1158 // Ensure it's not the newest frame that gets dropped to satisfy the1150 // Ensure it's not the newest frame that gets dropped to satisfy the
1159 // client.1151 // client.
1160 auto end = client_acquire_async(q);1152 auto end = client_acquire_async(*q);
11611153
1162 // The queue could solve this problem a few ways. It might choose to1154 // The queue could solve this problem a few ways. It might choose to
1163 // defer framedropping till it's safe, or even allocate additional1155 // defer framedropping till it's safe, or even allocate additional
@@ -1203,25 +1195,24 @@
1203 nbuffers++)1195 nbuffers++)
1204 {1196 {
1205 mtd::MockFrameDroppingPolicyFactory policy_factory;1197 mtd::MockFrameDroppingPolicyFactory policy_factory;
1206 mc::BufferQueue q(nbuffers,1198 std::shared_ptr<mc::BufferQueue> q;
1207 allocator,1199 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
1208 basic_properties,1200 ASSERT_THAT(q, Ne(nullptr));
1209 policy_factory);
12101201
1211 for (int i = 0; i < max_ownable_buffers(nbuffers); i++)1202 for (int i = 0; i < max_ownable_buffers(nbuffers); i++)
1212 {1203 {
1213 auto client = client_acquire_sync(q);1204 auto client = client_acquire_sync(*q);
1214 q.client_release(client);1205 q->client_release(client);
1215 }1206 }
12161207
1217 /* Queue up two pending swaps */1208 /* Queue up two pending swaps */
1218 auto first_swap = client_acquire_async(q);1209 auto first_swap = client_acquire_async(*q);
1219 auto second_swap = client_acquire_async(q);1210 auto second_swap = client_acquire_async(*q);
12201211
1221 ASSERT_FALSE(first_swap->has_acquired_buffer());1212 ASSERT_FALSE(first_swap->has_acquired_buffer());
1222 ASSERT_FALSE(second_swap->has_acquired_buffer());1213 ASSERT_FALSE(second_swap->has_acquired_buffer());
12231214
1224 q.compositor_acquire(nullptr);1215 q->compositor_acquire(nullptr);
12251216
1226 EXPECT_TRUE(first_swap->has_acquired_buffer());1217 EXPECT_TRUE(first_swap->has_acquired_buffer());
1227 EXPECT_FALSE(second_swap->has_acquired_buffer());1218 EXPECT_FALSE(second_swap->has_acquired_buffer());
@@ -1241,48 +1232,54 @@
1241 int const nbuffers{1};1232 int const nbuffers{1};
1242 geom::Size const new_size{123,456};1233 geom::Size const new_size{123,456};
12431234
1244 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);1235 std::shared_ptr<mc::BufferQueue> q;
12451236 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
1246 q.client_release(client_acquire_sync(q));1237 ASSERT_THAT(q, Ne(nullptr));
1247 q.resize(new_size);1238
12481239 q->client_release(client_acquire_sync(*q));
1249 auto const handle = client_acquire_async(q);1240 q->resize(new_size);
1241
1242 auto const handle = client_acquire_async(*q);
1250 EXPECT_THAT(handle->has_acquired_buffer(), Eq(false));1243 EXPECT_THAT(handle->has_acquired_buffer(), Eq(false));
12511244
1252 auto buf = q.compositor_acquire(this);1245 q->compositor_acquire(this);
1253 q.compositor_release(buf);
12541246
1255 buf = q.compositor_acquire(this);1247 {
1256 EXPECT_THAT(buf->size(), Eq(new_size));1248 auto buf_handle = q->compositor_acquire(this);
1257 q.compositor_release(buf);1249 EXPECT_THAT(buf_handle.buffer()->size(), Eq(new_size));
1250 }
1258}1251}
12591252
1260TEST_F(BufferQueueTest, double_buffered_client_is_not_blocked_prematurely)1253TEST_F(BufferQueueTest, double_buffered_client_is_not_blocked_prematurely)
1261{ // Regression test for LP: #13197651254{ // Regression test for LP: #1319765
1262 using namespace testing;1255 using namespace testing;
12631256
1264 mc::BufferQueue q{2, allocator, basic_properties, policy_factory};1257 std::shared_ptr<mc::BufferQueue> q;
12651258 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(2, allocator, basic_properties, policy_factory));
1266 q.client_release(client_acquire_sync(q));1259 ASSERT_THAT(q, Ne(nullptr));
1267 auto a = q.compositor_acquire(this);1260
1268 q.client_release(client_acquire_sync(q));1261 q->client_release(client_acquire_sync(*q));
1269 auto b = q.compositor_acquire(this);1262 auto a = new mc::BufferHandle(nullptr, nullptr);
12701263 *a = q->compositor_acquire(this);
1271 ASSERT_NE(a.get(), b.get());1264 q->client_release(client_acquire_sync(*q));
12721265 auto b = new mc::BufferHandle(nullptr, nullptr);
1273 q.compositor_release(a);1266 *b = q->compositor_acquire(this);
1274 q.client_release(client_acquire_sync(q));1267
12751268 ASSERT_NE(a->buffer().get(), b->buffer().get());
1276 q.compositor_release(b);1269 delete a;
1270
1271 q->client_release(client_acquire_sync(*q));
1272
1273 delete b;
12771274
1278 /*1275 /*
1279 * Update to the original test case; This additional compositor acquire1276 * Update to the original test case; This additional compositor acquire
1280 * represents the fixing of LP: #1395581 in the compositor logic.1277 * represents the fixing of LP: #1395581 in the compositor logic.
1281 */1278 */
1282 if (q.buffers_ready_for_compositor(this))1279 if (q->buffers_ready_for_compositor(this))
1283 q.compositor_release(q.compositor_acquire(this));1280 q->compositor_acquire(this);
12841281
1285 auto handle = client_acquire_async(q);1282 auto handle = client_acquire_async(*q);
1286 // With the fix, a buffer will be available instantaneously:1283 // With the fix, a buffer will be available instantaneously:
1287 ASSERT_TRUE(handle->has_acquired_buffer());1284 ASSERT_TRUE(handle->has_acquired_buffer());
1288 handle->release_buffer();1285 handle->release_buffer();
@@ -1292,45 +1289,49 @@
1292{ // Extended regression test for LP: #13197651289{ // Extended regression test for LP: #1319765
1293 using namespace testing;1290 using namespace testing;
12941291
1295 mc::BufferQueue q{2, allocator, basic_properties, policy_factory};1292 std::shared_ptr<mc::BufferQueue> q;
1293 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(2, allocator, basic_properties, policy_factory));
1294 ASSERT_THAT(q, Ne(nullptr));
12961295
1297 for (int i = 0; i < 100; ++i)1296 for (int i = 0; i < 100; ++i)
1298 {1297 {
1299 auto x = client_acquire_async(q);1298 auto x = client_acquire_async(*q);
1300 ASSERT_TRUE(x->has_acquired_buffer());1299 ASSERT_TRUE(x->has_acquired_buffer());
1301 x->release_buffer();1300 x->release_buffer();
13021301
1303 auto a = q.compositor_acquire(this);1302 auto a = new mc::BufferHandle(nullptr, nullptr);
1303 *a = q->compositor_acquire(this);
13041304
1305 auto y = client_acquire_async(q);1305 auto y = client_acquire_async(*q);
1306 ASSERT_TRUE(y->has_acquired_buffer());1306 ASSERT_TRUE(y->has_acquired_buffer());
1307 y->release_buffer();1307 y->release_buffer();
13081308
1309 auto b = q.compositor_acquire(this);1309 auto b = new mc::BufferHandle(nullptr, nullptr);
1310 1310 *b = q->compositor_acquire(this);
1311 ASSERT_NE(a.get(), b.get());1311
1312 1312 ASSERT_NE(a->buffer(), b->buffer());
1313 q.compositor_release(a);1313
13141314 delete a;
1315 auto w = client_acquire_async(q);1315
1316 auto w = client_acquire_async(*q);
1316 ASSERT_TRUE(w->has_acquired_buffer());1317 ASSERT_TRUE(w->has_acquired_buffer());
1317 w->release_buffer();1318 w->release_buffer();
1318 1319
1319 q.compositor_release(b);1320 delete b;
13201321
1321 /*1322 /*
1322 * Update to the original test case; This additional compositor acquire1323 * Update to the original test case; This additional compositor acquire
1323 * represents the fixing of LP: #1395581 in the compositor logic.1324 * represents the fixing of LP: #1395581 in the compositor logic.
1324 */1325 */
1325 if (q.buffers_ready_for_compositor(this))1326 if (q->buffers_ready_for_compositor(this))
1326 q.compositor_release(q.compositor_acquire(this));1327 q->compositor_acquire(this);
13271328
1328 auto z = client_acquire_async(q);1329 auto z = client_acquire_async(*q);
1329 ASSERT_TRUE(z->has_acquired_buffer());1330 ASSERT_TRUE(z->has_acquired_buffer());
1330 z->release_buffer();1331 z->release_buffer();
13311332
1332 q.compositor_release(q.compositor_acquire(this));1333 q->compositor_acquire(this);
1333 q.compositor_release(q.compositor_acquire(this));1334 q->compositor_acquire(this);
1334 }1335 }
1335}1336}
13361337
@@ -1340,34 +1341,40 @@
1340 1341
1341 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)1342 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)
1342 {1343 {
1343 mc::BufferQueue q{nbuffers, allocator, basic_properties, policy_factory};1344 std::shared_ptr<mc::BufferQueue> q;
1345 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
1346 ASSERT_THAT(q, Ne(nullptr));
1344 1347
1345 // Produce frame 11348 // Produce frame 1
1346 q.client_release(client_acquire_sync(q));1349 q->client_release(client_acquire_sync(*q));
1347 // Acquire frame 11350 // Acquire frame 1
1348 auto a = q.compositor_acquire(this);1351 auto a = new mc::BufferHandle(nullptr, nullptr);
1352 *a = q->compositor_acquire(this);
1349 1353
1350 // Produce frame 21354 // Produce frame 2
1351 q.client_release(client_acquire_sync(q));1355 q->client_release(client_acquire_sync(*q));
1352 // Acquire frame 21356 // Acquire frame 2
1353 auto b = q.compositor_acquire(this);1357 auto b = new mc::BufferHandle(nullptr, nullptr);
1358 *b = q->compositor_acquire(this);
1354 1359
1355 // Release frame 11360 // Release frame 1
1356 q.compositor_release(a);1361 delete a;
1362
1357 // Produce frame 31363 // Produce frame 3
1358 q.client_release(client_acquire_sync(q));1364 q->client_release(client_acquire_sync(*q));
1359 // Release frame 21365 // Release frame 2
1360 q.compositor_release(b);1366 delete b;
1361 1367
1362 // Verify frame 3 is ready for the first compositor1368 // Verify frame 3 is ready for the first compositor
1363 ASSERT_THAT(q.buffers_ready_for_compositor(this), Ge(1));1369 ASSERT_THAT(q->buffers_ready_for_compositor(this), Ge(1));
1364 auto c = q.compositor_acquire(this);1370 auto c = new mc::BufferHandle(nullptr, nullptr);
1371 *c = q->compositor_acquire(this);
13651372
1366 // Verify frame 3 is ready for a second compositor1373 // Verify frame 3 is ready for a second compositor
1367 int const that = 0;1374 int const that = 0;
1368 ASSERT_THAT(q.buffers_ready_for_compositor(&that), Ge(1));1375 ASSERT_THAT(q->buffers_ready_for_compositor(&that), Ge(1));
13691376
1370 q.compositor_release(c);1377 delete c;
1371 }1378 }
1372}1379}
13731380
@@ -1377,25 +1384,27 @@
1377 1384
1378 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)1385 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)
1379 {1386 {
1380 mc::BufferQueue q{nbuffers, allocator, basic_properties, policy_factory};1387 std::shared_ptr<mc::BufferQueue> q;
1388 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
1389 ASSERT_THAT(q, Ne(nullptr));
1381 1390
1382 const int nmonitors = 3;1391 const int nmonitors = 3;
1383 int monitor[nmonitors];1392 int monitor[nmonitors];
13841393
1385 for (int m = 0; m < nmonitors; ++m)1394 for (int m = 0; m < nmonitors; ++m)
1386 {1395 {
1387 ASSERT_EQ(0, q.buffers_ready_for_compositor(&monitor[m]));1396 ASSERT_EQ(0, q->buffers_ready_for_compositor(&monitor[m]));
1388 }1397 }
13891398
1390 // Produce a frame1399 // Produce a frame
1391 q.client_release(client_acquire_sync(q));1400 q->client_release(client_acquire_sync(*q));
13921401
1393 // Consume1402 // Consume
1394 for (int m = 0; m < nmonitors; ++m)1403 for (int m = 0; m < nmonitors; ++m)
1395 {1404 {
1396 ASSERT_EQ(1, q.buffers_ready_for_compositor(&monitor[m]));1405 ASSERT_EQ(1, q->buffers_ready_for_compositor(&monitor[m]));
1397 q.compositor_release(q.compositor_acquire(&monitor[m]));1406 q->compositor_acquire(&monitor[m]);
1398 ASSERT_EQ(0, q.buffers_ready_for_compositor(&monitor[m]));1407 ASSERT_EQ(0, q->buffers_ready_for_compositor(&monitor[m]));
1399 }1408 }
1400 }1409 }
1401}1410}
@@ -1407,47 +1416,47 @@
14071416
1408 int const nbuffers{3};1417 int const nbuffers{3};
14091418
1410 mc::BufferQueue q{nbuffers, allocator, basic_properties, policy_factory};1419 std::shared_ptr<mc::BufferQueue> q;
1411 q.allow_framedropping(true);1420 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
1421 ASSERT_THAT(q, Ne(nullptr));
1422 q->allow_framedropping(true);
14121423
1413 std::vector<std::shared_ptr<mg::Buffer>> buffers;1424 std::vector<mc::BufferHandle> buffer_handles;
14141425
1415 /* The client can never own this acquired buffer */1426 /* The client can never own this acquired buffer */
1416 auto comp_buffer = q.compositor_acquire(this);1427 auto comp_buffer_handle = q->compositor_acquire(this);
1417 buffers.push_back(comp_buffer);1428 auto id_from_comp = comp_buffer_handle.buffer()->id();
1429 buffer_handles.push_back(std::move(comp_buffer_handle));
14181430
1419 /* Let client release all possible buffers so they go into1431 /* Let client release all possible buffers so they go into
1420 * the ready queue1432 * the ready queue
1421 */1433 */
1422 for (int i = 0; i < nbuffers; ++i)1434 for (int i = 0; i < nbuffers; ++i)
1423 {1435 {
1424 auto handle = client_acquire_async(q);1436 auto handle = client_acquire_async(*q);
1425 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));1437 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
1426 /* Check the client never got the compositor buffer acquired above */1438 /* Check the client never got the compositor buffer acquired above */
1427 ASSERT_THAT(handle->id(), Ne(comp_buffer->id()));1439 ASSERT_THAT(handle->id(), Ne(id_from_comp));
1428 handle->release_buffer();1440 handle->release_buffer();
1429 }1441 }
14301442
1431 /* Let the compositor acquire all ready buffers */1443 /* Let the compositor acquire all ready buffers */
1432 for (int i = 0; i < nbuffers; ++i)1444 for (int i = 0; i < nbuffers; ++i)
1433 {1445 buffer_handles.push_back(q->compositor_acquire(this));
1434 buffers.push_back(q.compositor_acquire(this));
1435 }
14361446
1437 /* At this point the queue has 0 free buffers and 0 ready buffers1447 /* At this point the queue has 0 free buffers and 0 ready buffers
1438 * so the next client request should not be satisfied until1448 * so the next client request should not be satisfied until
1439 * a compositor releases its buffers */1449 * a compositor releases its buffers */
1440 auto handle = client_acquire_async(q);1450 auto handle = client_acquire_async(*q);
1441 /* ... unless the BufferQueue is overallocating. In that case it will1451 /* ... unless the BufferQueue is overallocating. In that case it will
1442 * have succeeding in acquiring immediately.1452 * have succeeding in acquiring immediately.
1443 */ 1453 */
1444 if (!handle->has_acquired_buffer())1454 if (!handle->has_acquired_buffer())
1445 {1455 {
1446 /* Release compositor buffers so that the client can get one */1456 /* Release compositor buffers so that the client can get one */
1447 for (auto const& buffer : buffers)1457 for (auto& buf_handle : buffer_handles)
1448 {1458 buf_handle = std::move(mc::BufferHandle(nullptr, nullptr));
1449 q.compositor_release(buffer);1459
1450 }
1451 EXPECT_THAT(handle->has_acquired_buffer(), Eq(true));1460 EXPECT_THAT(handle->has_acquired_buffer(), Eq(true));
1452 }1461 }
1453}1462}
@@ -1458,7 +1467,9 @@
14581467
1459 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)1468 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)
1460 {1469 {
1461 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);1470 std::shared_ptr<mc::BufferQueue> q;
1471 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
1472 ASSERT_THAT(q, Ne(nullptr));
14621473
1463 std::mutex client_buffer_guard;1474 std::mutex client_buffer_guard;
1464 std::condition_variable client_buffer_cv;1475 std::condition_variable client_buffer_cv;
@@ -1470,7 +1481,7 @@
1470 {1481 {
1471 while (!done)1482 while (!done)
1472 {1483 {
1473 auto buffer = q.compositor_acquire(this);1484 auto buffer_handle = q->compositor_acquire(this);
14741485
1475 {1486 {
1476 std::unique_lock<std::mutex> lock(client_buffer_guard);1487 std::unique_lock<std::mutex> lock(client_buffer_guard);
@@ -1480,18 +1491,17 @@
1480 time_for_client_to_acquire,1491 time_for_client_to_acquire,
1481 [&]()->bool{ return client_buffer; }))1492 [&]()->bool{ return client_buffer; }))
1482 {1493 {
1483 ASSERT_THAT(buffer->id(), Ne(client_buffer->id()));1494 ASSERT_THAT(buffer_handle.buffer()->id(), Ne(client_buffer->id()));
1484 }1495 }
1485 }1496 }
14861497
1487 std::this_thread::yield();1498 std::this_thread::yield();
1488 q.compositor_release(buffer);
1489 }1499 }
1490 });1500 });
14911501
1492 for (int i = 0; i < 1000; ++i)1502 for (int i = 0; i < 1000; ++i)
1493 {1503 {
1494 auto handle = client_acquire_async(q);1504 auto handle = client_acquire_async(*q);
1495 handle->wait_for(std::chrono::seconds(1));1505 handle->wait_for(std::chrono::seconds(1));
1496 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));1506 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
14971507
@@ -1514,30 +1524,35 @@
1514{1524{
1515 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)1525 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)
1516 {1526 {
1517 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);1527 std::shared_ptr<mc::BufferQueue> q;
1528 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
1529 ASSERT_THAT(q, Ne(nullptr));
1530
1518 for (int i = 0; i < 100; ++i)1531 for (int i = 0; i < 100; ++i)
1519 {1532 {
1520 auto handle = client_acquire_async(q);1533 auto handle = client_acquire_async(*q);
1521 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));1534 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
15221535
1523 auto client_id = handle->id();1536 auto client_id = handle->id();
1524 std::vector<std::shared_ptr<mg::Buffer>> buffers;1537 std::vector<mc::BufferHandle*> buffer_handles;
1525 for (int j = 0; j < nbuffers; j++)1538 for (int j = 0; j < nbuffers; j++)
1526 {1539 {
1527 auto buffer = q.compositor_acquire(this);1540 auto buffer_handle_ptr = new mc::BufferHandle(nullptr, nullptr);
1528 ASSERT_THAT(client_id, Ne(buffer->id()));1541 *buffer_handle_ptr = q->compositor_acquire(this);
1529 buffers.push_back(buffer);1542 ASSERT_THAT(client_id, Ne(buffer_handle_ptr->buffer()->id()));
1543 buffer_handles.push_back(buffer_handle_ptr);
1530 }1544 }
15311545
1532 for (auto const& buffer: buffers)1546 for (auto& buf_handle: buffer_handles)
1533 q.compositor_release(buffer);1547 delete buf_handle;
15341548
1535 handle->release_buffer();1549 handle->release_buffer();
15361550
1537 /* Flush out one ready buffer */1551 {
1538 auto buffer = q.compositor_acquire(this);1552 /* Flush out one ready buffer */
1539 ASSERT_THAT(client_id, Eq(buffer->id()));1553 auto buffer_handle = q->compositor_acquire(this);
1540 q.compositor_release(buffer);1554 ASSERT_THAT(client_id, Eq(buffer_handle.buffer()->id()));
1555 }
1541 }1556 }
1542 }1557 }
1543}1558}
@@ -1550,36 +1565,36 @@
1550{1565{
1551 for (int nbuffers = 3; nbuffers <= max_nbuffers_to_test; ++nbuffers)1566 for (int nbuffers = 3; nbuffers <= max_nbuffers_to_test; ++nbuffers)
1552 {1567 {
1553 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);1568 std::shared_ptr<mc::BufferQueue> q;
1569 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
1570 ASSERT_THAT(q, Ne(nullptr));
15541571
1555 void const* main_compositor = reinterpret_cast<void const*>(0);1572 void const* main_compositor = reinterpret_cast<void const*>(0);
1556 void const* second_compositor = reinterpret_cast<void const*>(1);1573 void const* second_compositor = reinterpret_cast<void const*>(1);
15571574
1558 /* Hold a reference to current compositor buffer*/1575 auto comp_buffer1 = new mc::BufferHandle(nullptr, nullptr);
1559 auto comp_buffer1 = q.compositor_acquire(main_compositor);1576 *comp_buffer1 = q->compositor_acquire(main_compositor);
15601577
1561 int const prefill = q.buffers_free_for_client();1578 int const prefill = q->buffers_free_for_client();
1562 ASSERT_THAT(prefill, Gt(0));1579 ASSERT_THAT(prefill, Gt(0));
1563 for (int acquires = 0; acquires < prefill; ++acquires)1580 for (int acquires = 0; acquires < prefill; ++acquires)
1564 {1581 {
1565 auto handle = client_acquire_async(q);1582 auto handle = client_acquire_async(*q);
1566 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));1583 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
1567 handle->release_buffer();1584 handle->release_buffer();
1568 }1585 }
15691586
1570 /* Have a second compositor advance the current compositor buffer at least twice */1587 /* Have a second compositor advance the current compositor buffer at least twice */
1571 for (int acquires = 0; acquires < nbuffers; ++acquires)1588 for (int acquires = 0; acquires < nbuffers; ++acquires)
1572 {1589 q->compositor_acquire(second_compositor);
1573 auto comp_buffer = q.compositor_acquire(second_compositor);1590
1574 q.compositor_release(comp_buffer);1591 delete comp_buffer1;
1575 }
1576 q.compositor_release(comp_buffer1);
15771592
1578 /* An async client should still be able to cycle through all the available buffers */1593 /* An async client should still be able to cycle through all the available buffers */
1579 std::atomic<bool> done(false);1594 std::atomic<bool> done(false);
1580 auto unblock = [&done] { done = true; };1595 auto unblock = [&done] { done = true; };
1581 mt::AutoUnblockThread compositor(unblock,1596 mt::AutoUnblockThread compositor(unblock,
1582 compositor_thread, std::ref(q), std::ref(done));1597 compositor_thread, std::ref(*q), std::ref(done));
15831598
1584 std::unordered_set<mg::Buffer *> unique_buffers_acquired;1599 std::unordered_set<mg::Buffer *> unique_buffers_acquired;
1585 int const max_ownable_buffers = nbuffers - 1;1600 int const max_ownable_buffers = nbuffers - 1;
@@ -1588,7 +1603,7 @@
1588 std::vector<mg::Buffer *> client_buffers;1603 std::vector<mg::Buffer *> client_buffers;
1589 for (int acquires = 0; acquires < max_ownable_buffers; ++acquires)1604 for (int acquires = 0; acquires < max_ownable_buffers; ++acquires)
1590 {1605 {
1591 auto handle = client_acquire_async(q);1606 auto handle = client_acquire_async(*q);
1592 handle->wait_for(std::chrono::seconds(1));1607 handle->wait_for(std::chrono::seconds(1));
1593 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));1608 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
1594 unique_buffers_acquired.insert(handle->buffer());1609 unique_buffers_acquired.insert(handle->buffer());
@@ -1597,7 +1612,7 @@
15971612
1598 for (auto const& buffer : client_buffers)1613 for (auto const& buffer : client_buffers)
1599 {1614 {
1600 q.client_release(buffer);1615 q->client_release(buffer);
1601 }1616 }
1602 }1617 }
16031618
@@ -1666,54 +1681,63 @@
1666 q.client_release(client_acquire_sync(q));1681 q.client_release(client_acquire_sync(q));
1667 }};1682 }};
16681683
1669 auto b = q.compositor_acquire(this);1684 q.compositor_acquire(this);
1670 q.compositor_release(b);
1671}1685}
16721686
1673TEST_F(BufferQueueTest, first_user_is_recorded)1687TEST_F(BufferQueueTest, first_user_is_recorded)
1674{1688{
1675 for (int nbuffers = 1; nbuffers <= max_nbuffers_to_test; ++nbuffers)1689 for (int nbuffers = 1; nbuffers <= max_nbuffers_to_test; ++nbuffers)
1676 {1690 {
1677 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);1691 std::shared_ptr<mc::BufferQueue> q;
1692 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
1693 ASSERT_THAT(q, Ne(nullptr));
16781694
1679 auto comp = q.compositor_acquire(this);1695 {
1680 EXPECT_TRUE(q.is_a_current_buffer_user(this));1696 auto comp = q->compositor_acquire(this);
1681 q.compositor_release(comp);1697 EXPECT_TRUE(q->is_a_current_buffer_user(this));
1698 }
1682 }1699 }
1683}1700}
16841701
1685TEST_F(BufferQueueTest, gives_compositor_a_valid_buffer_after_dropping_old_buffers_without_clients)1702TEST_F(BufferQueueTest, gives_compositor_a_valid_buffer_after_dropping_old_buffers_without_clients)
1686{1703{
1687 int const nbuffers = 3;1704 int const nbuffers = 3;
1688 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);1705 std::shared_ptr<mc::BufferQueue> q;
16891706 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
1690 q.drop_old_buffers();1707 ASSERT_THAT(q, Ne(nullptr));
16911708
1692 auto comp = q.compositor_acquire(this);1709 q->drop_old_buffers();
1693 ASSERT_THAT(comp, Ne(nullptr));1710
1711 auto comp = q->compositor_acquire(this);
1712 ASSERT_THAT(comp.buffer(), Ne(nullptr));
1694}1713}
16951714
1696TEST_F(BufferQueueTest, gives_compositor_the_newest_buffer_after_dropping_old_buffers)1715TEST_F(BufferQueueTest, gives_compositor_the_newest_buffer_after_dropping_old_buffers)
1697{1716{
1698 int const nbuffers = 3;1717 int const nbuffers = 3;
1699 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);1718 std::shared_ptr<mc::BufferQueue> q;
1719 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
1720 ASSERT_THAT(q, Ne(nullptr));
17001721
1701 auto handle1 = client_acquire_async(q);1722 auto handle1 = client_acquire_async(*q);
1702 ASSERT_THAT(handle1->has_acquired_buffer(), Eq(true));1723 ASSERT_THAT(handle1->has_acquired_buffer(), Eq(true));
1703 handle1->release_buffer();1724 handle1->release_buffer();
17041725
1705 auto handle2 = client_acquire_async(q);1726 auto handle2 = client_acquire_async(*q);
1706 ASSERT_THAT(handle2->has_acquired_buffer(), Eq(true));1727 ASSERT_THAT(handle2->has_acquired_buffer(), Eq(true));
1707 handle2->release_buffer();1728 handle2->release_buffer();
17081729
1709 q.drop_old_buffers();1730 q->drop_old_buffers();
17101731
1711 auto comp = q.compositor_acquire(this);1732 {
1712 ASSERT_THAT(comp->id(), Eq(handle2->id()));1733 auto buffer_handle = q->compositor_acquire(this);
1713 q.compositor_release(comp);1734 ASSERT_THAT(buffer_handle.buffer()->id(), Eq(handle2->id()));
17141735 }
1715 comp = q.compositor_acquire(this);1736
1716 ASSERT_THAT(comp->id(), Eq(handle2->id()));1737 {
1738 auto buffer_handle = q->compositor_acquire(this);
1739 ASSERT_THAT(buffer_handle.buffer()->id(), Eq(handle2->id()));
1740 }
1717}1741}
17181742
1719TEST_F(BufferQueueTest, gives_new_compositor_the_newest_buffer_after_dropping_old_buffers)1743TEST_F(BufferQueueTest, gives_new_compositor_the_newest_buffer_after_dropping_old_buffers)
@@ -1721,22 +1745,25 @@
1721 int const nbuffers = 3;1745 int const nbuffers = 3;
1722 void const* const new_compositor_id{&nbuffers};1746 void const* const new_compositor_id{&nbuffers};
17231747
1724 mc::BufferQueue q(nbuffers, allocator, basic_properties, policy_factory);1748 std::shared_ptr<mc::BufferQueue> q;
1749 ASSERT_NO_THROW(q = std::make_shared<mc::BufferQueue>(nbuffers, allocator, basic_properties, policy_factory));
1750 ASSERT_THAT(q, Ne(nullptr));
17251751
1726 auto handle1 = client_acquire_async(q);1752 auto handle1 = client_acquire_async(*q);
1727 ASSERT_THAT(handle1->has_acquired_buffer(), Eq(true));1753 ASSERT_THAT(handle1->has_acquired_buffer(), Eq(true));
1728 handle1->release_buffer();1754 handle1->release_buffer();
17291755
1730 auto comp = q.compositor_acquire(this);1756 {
1731 ASSERT_THAT(comp->id(), Eq(handle1->id()));1757 auto buffer_handle = q->compositor_acquire(this);
1732 q.compositor_release(comp);1758 ASSERT_THAT(buffer_handle.buffer()->id(), Eq(handle1->id()));
1759 }
17331760
1734 auto handle2 = client_acquire_async(q);1761 auto handle2 = client_acquire_async(*q);
1735 ASSERT_THAT(handle2->has_acquired_buffer(), Eq(true));1762 ASSERT_THAT(handle2->has_acquired_buffer(), Eq(true));
1736 handle2->release_buffer();1763 handle2->release_buffer();
17371764
1738 q.drop_old_buffers();1765 q->drop_old_buffers();
17391766
1740 auto comp2 = q.compositor_acquire(new_compositor_id);1767 auto buffer_handle2 = q->compositor_acquire(new_compositor_id);
1741 ASSERT_THAT(comp2->id(), Eq(handle2->id()));1768 ASSERT_THAT(buffer_handle2.buffer()->id(), Eq(handle2->id()));
1742}1769}
17431770
=== removed file 'tests/unit-tests/compositor/test_buffer_stream.cpp'
--- tests/unit-tests/compositor/test_buffer_stream.cpp 2015-01-21 07:34:50 +0000
+++ tests/unit-tests/compositor/test_buffer_stream.cpp 1970-01-01 00:00:00 +0000
@@ -1,194 +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 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/buffer_stream_surfaces.h"
20
21#include "mir_test_doubles/stub_buffer.h"
22#include "mir_test_doubles/mock_buffer_bundle.h"
23#include "mir_test/gmock_fixes.h"
24
25#include <gmock/gmock.h>
26#include <gtest/gtest.h>
27
28#include <condition_variable>
29
30namespace mc = mir::compositor;
31namespace mg = mir::graphics;
32namespace geom = mir::geometry;
33namespace mtd = mir::test::doubles;
34
35class BufferStreamTest : public ::testing::Test
36{
37protected:
38 BufferStreamTest()
39 {
40 mock_buffer = std::make_shared<mtd::StubBuffer>();
41 mock_bundle = std::make_shared<mtd::MockBufferBundle>();
42
43 // Two of the tests care about this, the rest should not...
44 EXPECT_CALL(*mock_bundle, force_requests_to_complete())
45 .Times(::testing::AnyNumber());
46 }
47
48 std::shared_ptr<mtd::StubBuffer> mock_buffer;
49 std::shared_ptr<mtd::MockBufferBundle> mock_bundle;
50};
51
52TEST_F(BufferStreamTest, size_query)
53{
54 geom::Size size{4, 5};
55 mg::BufferProperties properties {size, mir_pixel_format_abgr_8888, mg::BufferUsage::hardware};
56 EXPECT_CALL(*mock_bundle, properties())
57 .Times(1)
58 .WillOnce(testing::Return(properties));
59
60 mc::BufferStreamSurfaces buffer_stream(mock_bundle);
61 auto returned_size = buffer_stream.stream_size();
62 EXPECT_EQ(size, returned_size);
63}
64
65TEST_F(BufferStreamTest, pixel_format_query)
66{
67 MirPixelFormat format{mir_pixel_format_abgr_8888};
68 mg::BufferProperties properties {geom::Size{4, 5}, format, mg::BufferUsage::hardware};
69 EXPECT_CALL(*mock_bundle, properties())
70 .Times(1)
71 .WillOnce(testing::Return(properties));
72
73 mc::BufferStreamSurfaces buffer_stream(mock_bundle);
74 auto returned_pf = buffer_stream.get_stream_pixel_format();
75 EXPECT_EQ(format, returned_pf);
76}
77
78TEST_F(BufferStreamTest, force_requests_to_complete)
79{
80 EXPECT_CALL(*mock_bundle, force_requests_to_complete())
81 .Times(2); // Once explcit, once on destruction
82
83 mc::BufferStreamSurfaces buffer_stream(mock_bundle);
84 buffer_stream.force_requests_to_complete();
85}
86
87TEST_F(BufferStreamTest, requests_are_completed_before_destruction)
88{
89 EXPECT_CALL(*mock_bundle, force_requests_to_complete())
90 .Times(1);
91
92 mc::BufferStreamSurfaces buffer_stream(mock_bundle);
93}
94
95TEST_F(BufferStreamTest, get_buffer_for_compositor_handles_resources)
96{
97 using namespace testing;
98
99 EXPECT_CALL(*mock_bundle, compositor_acquire(_))
100 .Times(1)
101 .WillOnce(Return(mock_buffer));
102 EXPECT_CALL(*mock_bundle, compositor_release(_))
103 .Times(1);
104
105 mc::BufferStreamSurfaces buffer_stream(mock_bundle);
106
107 buffer_stream.lock_compositor_buffer(0);
108}
109
110TEST_F(BufferStreamTest, get_buffer_for_compositor_can_lock)
111{
112 using namespace testing;
113
114 EXPECT_CALL(*mock_bundle, compositor_acquire(_))
115 .Times(1)
116 .WillOnce(Return(mock_buffer));
117 EXPECT_CALL(*mock_bundle, compositor_release(_))
118 .Times(1);
119
120 mc::BufferStreamSurfaces buffer_stream(mock_bundle);
121
122 buffer_stream.lock_compositor_buffer(0);
123}
124
125TEST_F(BufferStreamTest, get_buffer_for_client_releases_resources)
126{
127 std::mutex mutex;
128 std::condition_variable cv;
129 mg::Buffer* buffer{nullptr};
130 bool done = false;
131
132 auto const callback =
133 [&](mg::Buffer* new_buffer)
134 {
135 std::unique_lock<decltype(mutex)> lock(mutex);
136 buffer = new_buffer;
137 done = true;
138 cv.notify_one();
139 };
140
141 using namespace testing;
142 mc::BufferStreamSurfaces buffer_stream(mock_bundle);
143
144 InSequence seq;
145 EXPECT_CALL(*mock_bundle, client_acquire(_))
146 .Times(1)
147 .WillOnce(InvokeArgument<0>(mock_buffer.get()));
148 EXPECT_CALL(*mock_bundle, client_release(_))
149 .Times(1);
150 EXPECT_CALL(*mock_bundle, client_acquire(_))
151 .Times(1)
152 .WillOnce(InvokeArgument<0>(mock_buffer.get()));
153
154 buffer_stream.acquire_client_buffer(callback);
155
156 {
157 std::unique_lock<decltype(mutex)> lock(mutex);
158
159 cv.wait(lock, [&]{ return done; });
160 }
161
162 done = false;
163
164 if (buffer)
165 buffer_stream.release_client_buffer(buffer);
166 buffer_stream.acquire_client_buffer(callback);
167
168 {
169 std::unique_lock<decltype(mutex)> lock(mutex);
170
171 cv.wait(lock, [&]{ return done; });
172 }
173}
174
175TEST_F(BufferStreamTest, allow_framedropping_device)
176{
177 EXPECT_CALL(*mock_bundle, allow_framedropping(true))
178 .Times(1);
179
180 mc::BufferStreamSurfaces buffer_stream(mock_bundle);
181 buffer_stream.allow_framedropping(true);
182}
183
184TEST_F(BufferStreamTest, resizes_bundle)
185{
186 geom::Size const new_size{66, 77};
187
188 EXPECT_CALL(*mock_bundle, resize(new_size))
189 .Times(1);
190
191 mc::BufferStreamSurfaces buffer_stream(mock_bundle);
192 buffer_stream.resize(new_size);
193}
194
1950
=== modified file 'tests/unit-tests/compositor/test_gl_renderer.cpp'
--- tests/unit-tests/compositor/test_gl_renderer.cpp 2015-01-22 09:00:14 +0000
+++ tests/unit-tests/compositor/test_gl_renderer.cpp 2015-03-20 19:31:52 +0000
@@ -28,8 +28,7 @@
28#include <mir_test/fake_shared.h>28#include <mir_test/fake_shared.h>
29#include <mir_test_doubles/mock_buffer.h>29#include <mir_test_doubles/mock_buffer.h>
30#include <mir_test_doubles/mock_renderable.h>30#include <mir_test_doubles/mock_renderable.h>
31#include <mir_test_doubles/mock_buffer_stream.h>31#include <mir_test_doubles/mock_buffer_bundle.h>
32#include <mir/compositor/buffer_stream.h>
33#include <mir_test_doubles/mock_gl.h>32#include <mir_test_doubles/mock_gl.h>
3433
35using testing::SetArgPointee;34using testing::SetArgPointee;
3635
=== removed file 'tests/unit-tests/compositor/test_temporary_buffers.cpp'
--- tests/unit-tests/compositor/test_temporary_buffers.cpp 2015-01-21 07:34:50 +0000
+++ tests/unit-tests/compositor/test_temporary_buffers.cpp 1970-01-01 00:00:00 +0000
@@ -1,149 +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 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 "mir_test_doubles/mock_buffer.h"
21#include "mir_test_doubles/stub_buffer.h"
22#include "mir_test_doubles/mock_buffer_bundle.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
42class TemporaryBuffersTest : public ::testing::Test
43{
44public:
45 TemporaryBuffersTest()
46 : buffer_size{1024, 768},
47 buffer_stride{1024},
48 buffer_pixel_format{mir_pixel_format_abgr_8888},
49 mock_buffer{std::make_shared<testing::NiceMock<mtd::MockBuffer>>(
50 buffer_size, buffer_stride, buffer_pixel_format)},
51 mock_bundle{std::make_shared<testing::NiceMock<mtd::MockBufferBundle>>()}
52 {
53 using namespace testing;
54
55 ON_CALL(*mock_bundle, client_acquire(_))
56 .WillByDefault(InvokeArgument<0>(mock_buffer.get()));
57 ON_CALL(*mock_bundle, compositor_acquire(_))
58 .WillByDefault(Return(mock_buffer));
59 }
60
61 geom::Size const buffer_size;
62 geom::Stride const buffer_stride;
63 MirPixelFormat const buffer_pixel_format;
64 std::shared_ptr<mtd::MockBuffer> const mock_buffer;
65 std::shared_ptr<mtd::MockBufferBundle> mock_bundle;
66};
67}
68
69TEST_F(TemporaryBuffersTest, compositor_buffer_acquires_and_releases)
70{
71 using namespace testing;
72 EXPECT_CALL(*mock_bundle, compositor_acquire(_))
73 .WillOnce(Return(mock_buffer));
74 EXPECT_CALL(*mock_bundle, compositor_release(_))
75 .Times(1);
76
77 mc::TemporaryCompositorBuffer proxy_buffer(mock_bundle, 0);
78}
79
80TEST_F(TemporaryBuffersTest, snapshot_buffer_acquires_and_releases)
81{
82 using namespace testing;
83 EXPECT_CALL(*mock_bundle, snapshot_acquire())
84 .WillOnce(Return(mock_buffer));
85 EXPECT_CALL(*mock_bundle, snapshot_release(_))
86 .Times(1);
87
88 mc::TemporarySnapshotBuffer proxy_buffer(mock_bundle);
89}
90
91TEST_F(TemporaryBuffersTest, base_test_size)
92{
93 TemporaryTestBuffer proxy_buffer(mock_buffer);
94 EXPECT_CALL(*mock_buffer, size())
95 .Times(1);
96
97 geom::Size size;
98 size = proxy_buffer.size();
99 EXPECT_EQ(buffer_size, size);
100}
101
102TEST_F(TemporaryBuffersTest, base_test_stride)
103{
104 TemporaryTestBuffer proxy_buffer(mock_buffer);
105 EXPECT_CALL(*mock_buffer, stride())
106 .Times(1);
107
108 geom::Stride stride;
109 stride = proxy_buffer.stride();
110 EXPECT_EQ(buffer_stride, stride);
111}
112
113TEST_F(TemporaryBuffersTest, base_test_pixel_format)
114{
115 TemporaryTestBuffer proxy_buffer(mock_buffer);
116 EXPECT_CALL(*mock_buffer, pixel_format())
117 .Times(1);
118
119 MirPixelFormat pixel_format;
120 pixel_format = proxy_buffer.pixel_format();
121 EXPECT_EQ(buffer_pixel_format, pixel_format);
122}
123
124TEST_F(TemporaryBuffersTest, base_gl_bind_to_texture)
125{
126 TemporaryTestBuffer proxy_buffer(mock_buffer);
127 EXPECT_CALL(*mock_buffer, gl_bind_to_texture())
128 .Times(1);
129
130 proxy_buffer.gl_bind_to_texture();
131}
132
133TEST_F(TemporaryBuffersTest, base_test_id)
134{
135 TemporaryTestBuffer proxy_buffer(mock_buffer);
136 EXPECT_CALL(*mock_buffer, id())
137 .Times(1);
138
139 proxy_buffer.id();
140}
141
142TEST_F(TemporaryBuffersTest, base_test_native_buffer_handle)
143{
144 TemporaryTestBuffer proxy_buffer(mock_buffer);
145 EXPECT_CALL(*mock_buffer, native_buffer_handle())
146 .Times(1);
147
148 proxy_buffer.native_buffer_handle();
149}
1500
=== modified file 'tests/unit-tests/examples/test_demo_compositor.cpp'
--- tests/unit-tests/examples/test_demo_compositor.cpp 2015-03-06 03:52:41 +0000
+++ tests/unit-tests/examples/test_demo_compositor.cpp 2015-03-20 19:31:52 +0000
@@ -27,7 +27,7 @@
2727
28#include "mir_test_doubles/mock_gl.h"28#include "mir_test_doubles/mock_gl.h"
29#include "mir_test_doubles/stub_display_buffer.h"29#include "mir_test_doubles/stub_display_buffer.h"
30#include "mir_test_doubles/stub_buffer_stream.h"30#include "mir_test_doubles/stub_buffer_bundle.h"
31#include "mir_test_doubles/stub_renderable.h"31#include "mir_test_doubles/stub_renderable.h"
32#include "mir_test/fake_shared.h"32#include "mir_test/fake_shared.h"
3333
@@ -61,7 +61,7 @@
61 std::string("stub"),61 std::string("stub"),
62 geom::Rectangle{{0,0},{100,100}},62 geom::Rectangle{{0,0},{100,100}},
63 false,63 false,
64 std::make_shared<mtd::StubBufferStream>(),64 std::make_shared<mtd::StubBufferBundle>(),
65 std::shared_ptr<mir::input::InputChannel>(),65 std::shared_ptr<mir::input::InputChannel>(),
66 std::shared_ptr<mir::input::InputSender>(),66 std::shared_ptr<mir::input::InputSender>(),
67 std::shared_ptr<mir::graphics::CursorImage>(),67 std::shared_ptr<mir::graphics::CursorImage>(),
6868
=== modified file 'tests/unit-tests/frontend/test_session_mediator.cpp'
--- tests/unit-tests/frontend/test_session_mediator.cpp 2015-03-06 03:52:41 +0000
+++ tests/unit-tests/frontend/test_session_mediator.cpp 2015-03-20 19:31:52 +0000
@@ -16,7 +16,6 @@
16 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>16 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
17 */17 */
1818
19#include "mir/compositor/buffer_stream.h"
20#include "src/server/frontend/session_mediator.h"19#include "src/server/frontend/session_mediator.h"
21#include "src/server/report/null_report_factory.h"20#include "src/server/report/null_report_factory.h"
22#include "src/server/frontend/resource_cache.h"21#include "src/server/frontend/resource_cache.h"
2322
=== modified file 'tests/unit-tests/graphics/test_program_factory.cpp'
--- tests/unit-tests/graphics/test_program_factory.cpp 2015-01-21 07:34:50 +0000
+++ tests/unit-tests/graphics/test_program_factory.cpp 2015-03-20 19:31:52 +0000
@@ -29,8 +29,7 @@
29#include <mir_test/fake_shared.h>29#include <mir_test/fake_shared.h>
30#include <mir_test_doubles/mock_buffer.h>30#include <mir_test_doubles/mock_buffer.h>
31#include <mir_test_doubles/mock_renderable.h>31#include <mir_test_doubles/mock_renderable.h>
32#include <mir_test_doubles/mock_buffer_stream.h>32#include <mir_test_doubles/mock_buffer_bundle.h>
33#include <mir/compositor/buffer_stream.h>
34#include <mir_test_doubles/mock_gl.h>33#include <mir_test_doubles/mock_gl.h>
3534
36using testing::SetArgPointee;35using testing::SetArgPointee;
3736
=== modified file 'tests/unit-tests/scene/test_basic_surface.cpp'
--- tests/unit-tests/scene/test_basic_surface.cpp 2015-03-06 03:52:41 +0000
+++ tests/unit-tests/scene/test_basic_surface.cpp 2015-03-20 19:31:52 +0000
@@ -27,7 +27,7 @@
27#include "mir/scene/null_surface_observer.h"27#include "mir/scene/null_surface_observer.h"
28#include "mir/events/event_builders.h"28#include "mir/events/event_builders.h"
2929
30#include "mir_test_doubles/mock_buffer_stream.h"30#include "mir_test_doubles/mock_buffer_bundle.h"
31#include "mir_test_doubles/mock_input_sender.h"31#include "mir_test_doubles/mock_input_sender.h"
32#include "mir_test_doubles/stub_input_sender.h"32#include "mir_test_doubles/stub_input_sender.h"
33#include "mir_test_doubles/stub_buffer.h"33#include "mir_test_doubles/stub_buffer.h"
@@ -92,8 +92,8 @@
92 testing::NiceMock<MockCallback> mock_callback;92 testing::NiceMock<MockCallback> mock_callback;
93 std::function<void()> null_change_cb{[]{}};93 std::function<void()> null_change_cb{[]{}};
94 std::function<void()> mock_change_cb{std::bind(&MockCallback::call, &mock_callback)};94 std::function<void()> mock_change_cb{std::bind(&MockCallback::call, &mock_callback)};
95 std::shared_ptr<testing::NiceMock<mtd::MockBufferStream>> mock_buffer_stream =95 std::shared_ptr<testing::NiceMock<mtd::MockBufferBundle>> mock_buffer_bundle =
96 std::make_shared<testing::NiceMock<mtd::MockBufferStream>>();96 std::make_shared<testing::NiceMock<mtd::MockBufferBundle>>();
97 std::shared_ptr<ms::SceneReport> const report = mr::null_scene_report();97 std::shared_ptr<ms::SceneReport> const report = mr::null_scene_report();
98 void const* compositor_id{nullptr};98 void const* compositor_id{nullptr};
99 std::shared_ptr<ms::LegacySurfaceChangeNotification> observer =99 std::shared_ptr<ms::LegacySurfaceChangeNotification> observer =
@@ -105,7 +105,7 @@
105 name,105 name,
106 rect,106 rect,
107 false,107 false,
108 mock_buffer_stream,108 mock_buffer_bundle,
109 std::shared_ptr<mi::InputChannel>(),109 std::shared_ptr<mi::InputChannel>(),
110 stub_input_sender,110 stub_input_sender,
111 std::shared_ptr<mg::CursorImage>(),111 std::shared_ptr<mg::CursorImage>(),
@@ -135,7 +135,7 @@
135 for (int i = 0; i < N; ++i)135 for (int i = 0; i < N; ++i)
136 {136 {
137 surfaces[i].reset(new ms::BasicSurface(137 surfaces[i].reset(new ms::BasicSurface(
138 name, rect, false, mock_buffer_stream,138 name, rect, false, mock_buffer_bundle,
139 std::shared_ptr<mi::InputChannel>(), stub_input_sender,139 std::shared_ptr<mi::InputChannel>(), stub_input_sender,
140 std::shared_ptr<mg::CursorImage>(), report)140 std::shared_ptr<mg::CursorImage>(), report)
141 );141 );
@@ -155,7 +155,7 @@
155 for (int i = 0; i < N; ++i)155 for (int i = 0; i < N; ++i)
156 {156 {
157 surfaces[i].reset(new ms::BasicSurface(157 surfaces[i].reset(new ms::BasicSurface(
158 name, rect, false, mock_buffer_stream,158 name, rect, false, mock_buffer_bundle,
159 std::shared_ptr<mi::InputChannel>(), stub_input_sender,159 std::shared_ptr<mi::InputChannel>(), stub_input_sender,
160 std::shared_ptr<mg::CursorImage>(), report)160 std::shared_ptr<mg::CursorImage>(), report)
161 );161 );
@@ -260,7 +260,7 @@
260{260{
261 using namespace testing;261 using namespace testing;
262 mtd::StubBuffer mock_buffer;262 mtd::StubBuffer mock_buffer;
263 EXPECT_CALL(*mock_buffer_stream, acquire_client_buffer(_)).Times(2)263 EXPECT_CALL(*mock_buffer_bundle, client_acquire(_)).Times(2)
264 .WillRepeatedly(InvokeArgument<0>(&mock_buffer));264 .WillRepeatedly(InvokeArgument<0>(&mock_buffer));
265265
266 mir::graphics::Buffer* buffer = nullptr;266 mir::graphics::Buffer* buffer = nullptr;
@@ -271,7 +271,7 @@
271 name,271 name,
272 rect,272 rect,
273 false,273 false,
274 mock_buffer_stream,274 mock_buffer_bundle,
275 std::shared_ptr<mi::InputChannel>(),275 std::shared_ptr<mi::InputChannel>(),
276 stub_input_sender,276 stub_input_sender,
277 std::shared_ptr<mg::CursorImage>(),277 std::shared_ptr<mg::CursorImage>(),
@@ -314,7 +314,7 @@
314{314{
315 using namespace testing;315 using namespace testing;
316 mtd::StubBuffer mock_buffer;316 mtd::StubBuffer mock_buffer;
317 EXPECT_CALL(*mock_buffer_stream, acquire_client_buffer(_)).Times(2)317 EXPECT_CALL(*mock_buffer_bundle, client_acquire(_)).Times(2)
318 .WillRepeatedly(InvokeArgument<0>(&mock_buffer));318 .WillRepeatedly(InvokeArgument<0>(&mock_buffer));
319319
320 surface.add_observer(observer);320 surface.add_observer(observer);
@@ -338,7 +338,7 @@
338 name,338 name,
339 geom::Rectangle{pt, one_by_one},339 geom::Rectangle{pt, one_by_one},
340 false,340 false,
341 mock_buffer_stream,341 mock_buffer_bundle,
342 std::shared_ptr<mi::InputChannel>(),342 std::shared_ptr<mi::InputChannel>(),
343 stub_input_sender,343 stub_input_sender,
344 std::shared_ptr<mg::CursorImage>(),344 std::shared_ptr<mg::CursorImage>(),
@@ -376,7 +376,7 @@
376 name,376 name,
377 geom::Rectangle{{0,0}, {100,100}},377 geom::Rectangle{{0,0}, {100,100}},
378 false,378 false,
379 mock_buffer_stream,379 mock_buffer_bundle,
380 std::shared_ptr<mi::InputChannel>(),380 std::shared_ptr<mi::InputChannel>(),
381 stub_input_sender,381 stub_input_sender,
382 std::shared_ptr<mg::CursorImage>(),382 std::shared_ptr<mg::CursorImage>(),
@@ -517,7 +517,7 @@
517 geom::Rectangle{{0,0}, {100,100}},517 geom::Rectangle{{0,0}, {100,100}},
518 parent,518 parent,
519 false,519 false,
520 mock_buffer_stream,520 mock_buffer_bundle,
521 std::shared_ptr<mi::InputChannel>(),521 std::shared_ptr<mi::InputChannel>(),
522 stub_input_sender,522 stub_input_sender,
523 std::shared_ptr<mg::CursorImage>(),523 std::shared_ptr<mg::CursorImage>(),
@@ -678,7 +678,7 @@
678 name,678 name,
679 rect,679 rect,
680 false,680 false,
681 mock_buffer_stream,681 mock_buffer_bundle,
682 std::shared_ptr<mi::InputChannel>(),682 std::shared_ptr<mi::InputChannel>(),
683 mt::fake_shared(mock_sender),683 mt::fake_shared(mock_sender),
684 nullptr,684 nullptr,
685685
=== modified file 'tests/unit-tests/scene/test_session_manager.cpp'
--- tests/unit-tests/scene/test_session_manager.cpp 2015-03-06 03:52:41 +0000
+++ tests/unit-tests/scene/test_session_manager.cpp 2015-03-20 19:31:52 +0000
@@ -29,7 +29,7 @@
2929
30#include "mir_test_doubles/mock_surface_coordinator.h"30#include "mir_test_doubles/mock_surface_coordinator.h"
31#include "mir_test_doubles/mock_session_listener.h"31#include "mir_test_doubles/mock_session_listener.h"
32#include "mir_test_doubles/stub_buffer_stream.h"32#include "mir_test_doubles/stub_buffer_bundle.h"
33#include "mir_test_doubles/null_snapshot_strategy.h"33#include "mir_test_doubles/null_snapshot_strategy.h"
34#include "mir_test_doubles/null_session_event_sink.h"34#include "mir_test_doubles/null_session_event_sink.h"
3535
@@ -78,7 +78,7 @@
78 std::string("stub"),78 std::string("stub"),
79 geom::Rectangle{{},{}},79 geom::Rectangle{{},{}},
80 false,80 false,
81 std::make_shared<mtd::StubBufferStream>(),81 std::make_shared<mtd::StubBufferBundle>(),
82 std::shared_ptr<mi::InputChannel>(),82 std::shared_ptr<mi::InputChannel>(),
83 std::shared_ptr<mi::InputSender>(),83 std::shared_ptr<mi::InputSender>(),
84 std::shared_ptr<mg::CursorImage>(),84 std::shared_ptr<mg::CursorImage>(),
8585
=== modified file 'tests/unit-tests/scene/test_surface.cpp'
--- tests/unit-tests/scene/test_surface.cpp 2015-03-18 18:48:02 +0000
+++ tests/unit-tests/scene/test_surface.cpp 2015-03-20 19:31:52 +0000
@@ -27,7 +27,7 @@
27#include "mir/scene/surface_event_source.h"27#include "mir/scene/surface_event_source.h"
28#include "mir/input/input_channel.h"28#include "mir/input/input_channel.h"
2929
30#include "mir_test_doubles/mock_buffer_stream.h"30#include "mir_test_doubles/mock_buffer_bundle.h"
31#include "mir_test_doubles/mock_input_surface.h"31#include "mir_test_doubles/mock_input_surface.h"
32#include "mir_test_doubles/stub_buffer.h"32#include "mir_test_doubles/stub_buffer.h"
33#include "mir_test_doubles/mock_input_sender.h"33#include "mir_test_doubles/mock_input_sender.h"
@@ -192,7 +192,7 @@
192{192{
193 SurfaceCreation()193 SurfaceCreation()
194 : surface(surface_name,194 : surface(surface_name,
195 rect, false, mock_buffer_stream, 195 rect, false, mock_buffer_bundle,
196 std::make_shared<mtd::StubInputChannel>(),196 std::make_shared<mtd::StubInputChannel>(),
197 std::make_shared<mtd::StubInputSender>(),197 std::make_shared<mtd::StubInputSender>(),
198 nullptr /* cursor_image */, report)198 nullptr /* cursor_image */, report)
@@ -209,11 +209,11 @@
209 notification_count++;209 notification_count++;
210 };210 };
211211
212 ON_CALL(*mock_buffer_stream, acquire_client_buffer(_))212 ON_CALL(*mock_buffer_bundle, client_acquire(_))
213 .WillByDefault(InvokeArgument<0>(&stub_buffer));213 .WillByDefault(InvokeArgument<0>(&stub_buffer));
214 }214 }
215215
216 std::shared_ptr<testing::NiceMock<mtd::MockBufferStream>> mock_buffer_stream = std::make_shared<testing::NiceMock<mtd::MockBufferStream>>();216 std::shared_ptr<testing::NiceMock<mtd::MockBufferBundle>> mock_buffer_bundle = std::make_shared<testing::NiceMock<mtd::MockBufferBundle>>();
217 std::function<void()> change_notification;217 std::function<void()> change_notification;
218 int notification_count = 0;218 int notification_count = 0;
219 mtd::StubBuffer stub_buffer;219 mtd::StubBuffer stub_buffer;
@@ -229,13 +229,15 @@
229229
230}230}
231231
232TEST_F(SurfaceCreation, test_surface_queries_stream_for_pf)232TEST_F(SurfaceCreation, test_surface_queries_bundle_for_pf)
233{233{
234 using namespace testing;234 using namespace testing;
235235
236 EXPECT_CALL(*mock_buffer_stream, get_stream_pixel_format())236 EXPECT_CALL(*mock_buffer_bundle, properties())
237 .Times(1)237 .Times(1)
238 .WillOnce(Return(pf));238 .WillOnce(Return(mg::BufferProperties(geom::Size{0, 0},
239 pf,
240 mg::BufferUsage::undefined)));
239241
240 auto ret_pf = surface.pixel_format();242 auto ret_pf = surface.pixel_format();
241243
@@ -258,7 +260,7 @@
258260
259 mtd::StubBuffer graphics_resource;261 mtd::StubBuffer graphics_resource;
260262
261 EXPECT_CALL(*mock_buffer_stream, acquire_client_buffer(_))263 EXPECT_CALL(*mock_buffer_bundle, client_acquire(_))
262 .Times(1)264 .Times(1)
263 .WillOnce(InvokeArgument<0>(&graphics_resource));265 .WillOnce(InvokeArgument<0>(&graphics_resource));
264266
@@ -267,13 +269,13 @@
267 [&graphics_resource](mg::Buffer* result){ EXPECT_THAT(result, Eq(&graphics_resource)); });269 [&graphics_resource](mg::Buffer* result){ EXPECT_THAT(result, Eq(&graphics_resource)); });
268}270}
269271
270TEST_F(SurfaceCreation, test_surface_gets_ipc_from_stream)272TEST_F(SurfaceCreation, test_surface_gets_ipc_from_bundle)
271{273{
272 using namespace testing;274 using namespace testing;
273275
274 mtd::StubBuffer stub_buffer;276 mtd::StubBuffer stub_buffer;
275277
276 EXPECT_CALL(*mock_buffer_stream, acquire_client_buffer(_))278 EXPECT_CALL(*mock_buffer_bundle, client_acquire(_))
277 .Times(1)279 .Times(1)
278 .WillOnce(InvokeArgument<0>(&stub_buffer));280 .WillOnce(InvokeArgument<0>(&stub_buffer));
279281
@@ -296,12 +298,12 @@
296 EXPECT_EQ(p, surface.top_left());298 EXPECT_EQ(p, surface.top_left());
297}299}
298300
299TEST_F(SurfaceCreation, resize_updates_stream_and_state)301TEST_F(SurfaceCreation, resize_updates_bundle_and_state)
300{302{
301 using namespace testing;303 using namespace testing;
302 geom::Size const new_size{123, 456};304 geom::Size const new_size{123, 456};
303305
304 EXPECT_CALL(*mock_buffer_stream, resize(new_size))306 EXPECT_CALL(*mock_buffer_bundle, resize(new_size))
305 .Times(1);307 .Times(1);
306308
307 auto const mock_event_sink = std::make_shared<MockEventSink>();309 auto const mock_event_sink = std::make_shared<MockEventSink>();
@@ -327,15 +329,15 @@
327329
328 ASSERT_THAT(surface.size(), Ne(new_size));330 ASSERT_THAT(surface.size(), Ne(new_size));
329331
330 EXPECT_CALL(*mock_buffer_stream, resize(new_size)).Times(1);332 EXPECT_CALL(*mock_buffer_bundle, resize(new_size)).Times(1);
331 EXPECT_CALL(*mock_event_sink, handle_event(_)).Times(1);333 EXPECT_CALL(*mock_event_sink, handle_event(_)).Times(1);
332 surface.resize(new_size);334 surface.resize(new_size);
333 EXPECT_THAT(surface.size(), Eq(new_size));335 EXPECT_THAT(surface.size(), Eq(new_size));
334336
335 Mock::VerifyAndClearExpectations(mock_buffer_stream.get());337 Mock::VerifyAndClearExpectations(mock_buffer_bundle.get());
336 Mock::VerifyAndClearExpectations(mock_event_sink.get());338 Mock::VerifyAndClearExpectations(mock_event_sink.get());
337339
338 EXPECT_CALL(*mock_buffer_stream, resize(_)).Times(0);340 EXPECT_CALL(*mock_buffer_bundle, resize(_)).Times(0);
339 EXPECT_CALL(*mock_event_sink, handle_event(_)).Times(0);341 EXPECT_CALL(*mock_event_sink, handle_event(_)).Times(0);
340 surface.resize(new_size);342 surface.resize(new_size);
341 EXPECT_THAT(surface.size(), Eq(new_size));343 EXPECT_THAT(surface.size(), Eq(new_size));
@@ -346,7 +348,7 @@
346 using namespace testing;348 using namespace testing;
347 geom::Size const new_size{123, 456};349 geom::Size const new_size{123, 456};
348350
349 EXPECT_CALL(*mock_buffer_stream, resize(new_size))351 EXPECT_CALL(*mock_buffer_bundle, resize(new_size))
350 .Times(1)352 .Times(1)
351 .WillOnce(Throw(std::runtime_error("bad resize")));353 .WillOnce(Throw(std::runtime_error("bad resize")));
352354
@@ -378,7 +380,7 @@
378 if (expect_size.height <= geom::Height{0})380 if (expect_size.height <= geom::Height{0})
379 expect_size.height = geom::Height{1};381 expect_size.height = geom::Height{1};
380382
381 EXPECT_CALL(*mock_buffer_stream, resize(expect_size)).Times(1);383 EXPECT_CALL(*mock_buffer_bundle, resize(expect_size)).Times(1);
382 EXPECT_NO_THROW({ surface.resize(size); });384 EXPECT_NO_THROW({ surface.resize(size); });
383 EXPECT_EQ(expect_size, surface.size());385 EXPECT_EQ(expect_size, surface.size());
384 }386 }
@@ -407,7 +409,7 @@
407{409{
408 using namespace testing;410 using namespace testing;
409411
410 EXPECT_CALL(*mock_buffer_stream, force_requests_to_complete()).Times(Exactly(1));412 EXPECT_CALL(*mock_buffer_bundle, force_requests_to_complete()).Times(Exactly(1));
411413
412 surface.force_requests_to_complete();414 surface.force_requests_to_complete();
413}415}
@@ -416,7 +418,7 @@
416{418{
417 using namespace testing;419 using namespace testing;
418420
419 EXPECT_CALL(*mock_buffer_stream, allow_framedropping(true))421 EXPECT_CALL(*mock_buffer_bundle, allow_framedropping(true))
420 .Times(1);422 .Times(1);
421423
422 surface.allow_framedropping(true);424 surface.allow_framedropping(true);
@@ -452,7 +454,7 @@
452 surface_name,454 surface_name,
453 rect,455 rect,
454 false,456 false,
455 mock_buffer_stream,457 mock_buffer_bundle,
456 mt::fake_shared(channel),458 mt::fake_shared(channel),
457 std::make_shared<mtd::StubInputSender>(),459 std::make_shared<mtd::StubInputSender>(),
458 std::shared_ptr<mg::CursorImage>(),460 std::shared_ptr<mg::CursorImage>(),
@@ -470,7 +472,7 @@
470 surface_name,472 surface_name,
471 rect,473 rect,
472 false,474 false,
473 mock_buffer_stream,475 mock_buffer_bundle,
474 std::make_shared<mtd::StubInputChannel>(),476 std::make_shared<mtd::StubInputChannel>(),
475 mt::fake_shared(mock_sender),477 mt::fake_shared(mock_sender),
476 std::shared_ptr<mg::CursorImage>(),478 std::shared_ptr<mg::CursorImage>(),
477479
=== modified file 'tests/unit-tests/scene/test_surface_impl.cpp'
--- tests/unit-tests/scene/test_surface_impl.cpp 2015-03-06 03:52:41 +0000
+++ tests/unit-tests/scene/test_surface_impl.cpp 2015-03-20 19:31:52 +0000
@@ -25,8 +25,8 @@
25#include "mir/frontend/event_sink.h"25#include "mir/frontend/event_sink.h"
26#include "mir/graphics/display_configuration.h"26#include "mir/graphics/display_configuration.h"
2727
28#include "mir_test_doubles/stub_buffer_stream.h"28#include "mir_test_doubles/stub_buffer_bundle.h"
29#include "mir_test_doubles/mock_buffer_stream.h"29#include "mir_test_doubles/mock_buffer_bundle.h"
30#include "mir_test_doubles/mock_input_targeter.h"30#include "mir_test_doubles/mock_input_targeter.h"
31#include "mir_test_doubles/stub_input_sender.h"31#include "mir_test_doubles/stub_input_sender.h"
32#include "mir_test_doubles/null_event_sink.h"32#include "mir_test_doubles/null_event_sink.h"
@@ -53,23 +53,22 @@
53namespace53namespace
54{54{
5555
56typedef testing::NiceMock<mtd::MockBufferStream> StubBufferStream;56typedef testing::NiceMock<mtd::MockBufferBundle> StubBufferBundle;
5757
58struct Surface : testing::Test58struct Surface : testing::Test
59{59{
60 std::shared_ptr<StubBufferStream> const buffer_stream = std::make_shared<StubBufferStream>();60 std::shared_ptr<StubBufferBundle> const buffer_bundle = std::make_shared<StubBufferBundle>();
6161
62 void SetUp()62 void SetUp()
63 {63 {
64 using namespace testing;64 using namespace testing;
6565
66 ON_CALL(*buffer_stream, stream_size()).WillByDefault(Return(geom::Size()));66 ON_CALL(*buffer_bundle, size()).WillByDefault(Return(geom::Size()));
67 ON_CALL(*buffer_stream, get_stream_pixel_format()).WillByDefault(Return(mir_pixel_format_abgr_8888));67 ON_CALL(*buffer_bundle, client_acquire(_))
68 ON_CALL(*buffer_stream, acquire_client_buffer(_))
69 .WillByDefault(InvokeArgument<0>(nullptr));68 .WillByDefault(InvokeArgument<0>(nullptr));
70 69
71 surface = std::make_shared<ms::BasicSurface>(std::string("stub"), geom::Rectangle{{},{}}, false,70 surface = std::make_shared<ms::BasicSurface>(std::string("stub"), geom::Rectangle{{},{}}, false,
72 buffer_stream, nullptr /* input_channel */, stub_input_sender,71 buffer_bundle, nullptr /* input_channel */, stub_input_sender,
73 nullptr /* cursor_image */, report);72 nullptr /* cursor_image */, report);
74 }73 }
7574
@@ -264,13 +263,13 @@
264263
265TEST_F(Surface, with_most_recent_buffer_do_uses_compositor_buffer)264TEST_F(Surface, with_most_recent_buffer_do_uses_compositor_buffer)
266{265{
267 auto stub_buffer_stream = std::make_shared<mtd::StubBufferStream>();266 auto stub_buffer_bundle = std::make_shared<mtd::StubBufferBundle>();
268267
269 ms::BasicSurface surf(268 ms::BasicSurface surf(
270 std::string("stub"),269 std::string("stub"),
271 geom::Rectangle{{},{}},270 geom::Rectangle{{},{}},
272 false,271 false,
273 stub_buffer_stream,272 stub_buffer_bundle,
274 std::shared_ptr<mi::InputChannel>(),273 std::shared_ptr<mi::InputChannel>(),
275 stub_input_sender,274 stub_input_sender,
276 std::shared_ptr<mg::CursorImage>(),275 std::shared_ptr<mg::CursorImage>(),
@@ -284,7 +283,7 @@
284 buf_ptr = &buffer;283 buf_ptr = &buffer;
285 });284 });
286285
287 EXPECT_EQ(stub_buffer_stream->stub_compositor_buffer.get(), buf_ptr);286 EXPECT_EQ(stub_buffer_bundle->stub_compositor_buffer.get(), buf_ptr);
288}287}
289288
290TEST_F(Surface, emits_client_close_events)289TEST_F(Surface, emits_client_close_events)
@@ -314,7 +313,7 @@
314 std::string("stub"),313 std::string("stub"),
315 geom::Rectangle{{},{}},314 geom::Rectangle{{},{}},
316 false,315 false,
317 buffer_stream,316 buffer_bundle,
318 std::shared_ptr<mi::InputChannel>(),317 std::shared_ptr<mi::InputChannel>(),
319 stub_input_sender,318 stub_input_sender,
320 std::shared_ptr<mg::CursorImage>(),319 std::shared_ptr<mg::CursorImage>(),
321320
=== modified file 'tests/unit-tests/scene/test_surface_stack.cpp'
--- tests/unit-tests/scene/test_surface_stack.cpp 2015-03-06 03:52:41 +0000
+++ tests/unit-tests/scene/test_surface_stack.cpp 2015-03-20 19:31:52 +0000
@@ -27,9 +27,9 @@
27#include "mir/input/input_channel_factory.h"27#include "mir/input/input_channel_factory.h"
28#include "mir_test_doubles/stub_input_channel.h"28#include "mir_test_doubles/stub_input_channel.h"
29#include "mir_test/fake_shared.h"29#include "mir_test/fake_shared.h"
30#include "mir_test_doubles/stub_buffer_stream.h"30#include "mir_test_doubles/stub_buffer_bundle.h"
31#include "mir_test_doubles/stub_renderable.h"31#include "mir_test_doubles/stub_renderable.h"
32#include "mir_test_doubles/mock_buffer_stream.h"32#include "mir_test_doubles/mock_buffer_bundle.h"
3333
34#include <gmock/gmock.h>34#include <gmock/gmock.h>
35#include <gtest/gtest.h>35#include <gtest/gtest.h>
@@ -125,7 +125,7 @@
125 std::string("stub"),125 std::string("stub"),
126 geom::Rectangle{{},{}},126 geom::Rectangle{{},{}},
127 false,127 false,
128 std::make_shared<mtd::StubBufferStream>(),128 std::make_shared<mtd::StubBufferBundle>(),
129 std::shared_ptr<mir::input::InputChannel>(),129 std::shared_ptr<mir::input::InputChannel>(),
130 std::shared_ptr<mir::input::InputSender>(),130 std::shared_ptr<mir::input::InputSender>(),
131 std::shared_ptr<mg::CursorImage>(),131 std::shared_ptr<mg::CursorImage>(),
@@ -137,7 +137,7 @@
137 std::string("stub"),137 std::string("stub"),
138 geom::Rectangle{{},{}},138 geom::Rectangle{{},{}},
139 false,139 false,
140 std::make_shared<mtd::StubBufferStream>(),140 std::make_shared<mtd::StubBufferBundle>(),
141 std::shared_ptr<mir::input::InputChannel>(),141 std::shared_ptr<mir::input::InputChannel>(),
142 std::shared_ptr<mir::input::InputSender>(),142 std::shared_ptr<mir::input::InputSender>(),
143 std::shared_ptr<mg::CursorImage>(),143 std::shared_ptr<mg::CursorImage>(),
@@ -149,7 +149,7 @@
149 std::string("stub"),149 std::string("stub"),
150 geom::Rectangle{{},{}},150 geom::Rectangle{{},{}},
151 false,151 false,
152 std::make_shared<mtd::StubBufferStream>(),152 std::make_shared<mtd::StubBufferBundle>(),
153 std::shared_ptr<mir::input::InputChannel>(),153 std::shared_ptr<mir::input::InputChannel>(),
154 std::shared_ptr<mir::input::InputSender>(),154 std::shared_ptr<mir::input::InputSender>(),
155 std::shared_ptr<mg::CursorImage>(),155 std::shared_ptr<mg::CursorImage>(),
@@ -161,7 +161,7 @@
161 std::string("stub"),161 std::string("stub"),
162 geom::Rectangle{{},{}},162 geom::Rectangle{{},{}},
163 false,163 false,
164 std::make_shared<mtd::StubBufferStream>(),164 std::make_shared<mtd::StubBufferBundle>(),
165 std::shared_ptr<mir::input::InputChannel>(),165 std::shared_ptr<mir::input::InputChannel>(),
166 std::shared_ptr<mir::input::InputSender>(),166 std::shared_ptr<mir::input::InputSender>(),
167 std::shared_ptr<mg::CursorImage>(),167 std::shared_ptr<mg::CursorImage>(),
@@ -236,7 +236,7 @@
236 std::string("Mary had a little lamb"),236 std::string("Mary had a little lamb"),
237 geom::Rectangle{{},{}},237 geom::Rectangle{{},{}},
238 false,238 false,
239 std::make_shared<mtd::StubBufferStream>(),239 std::make_shared<mtd::StubBufferBundle>(),
240 std::shared_ptr<mir::input::InputChannel>(),240 std::shared_ptr<mir::input::InputChannel>(),
241 std::shared_ptr<mir::input::InputSender>(),241 std::shared_ptr<mir::input::InputSender>(),
242 std::shared_ptr<mg::CursorImage>(),242 std::shared_ptr<mg::CursorImage>(),
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches