2
* Copyright © 2015 Canonical Ltd.
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.
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.
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/>.
16
* Authored by: Kevin DuBois <kevin.dubois@canonical.com>
19
#include "mir_toolkit/mir_client_library.h"
20
#include "mir_test_framework/connected_client_with_a_surface.h"
21
#include "mir/compositor/display_buffer_compositor.h"
22
#include "mir/compositor/display_buffer_compositor_factory.h"
23
#include "mir/compositor/scene_element.h"
24
#include "mir/compositor/compositor.h"
25
#include "mir/graphics/renderable.h"
28
#include <condition_variable>
29
#include <gtest/gtest.h>
30
#include <gmock/gmock.h>
32
namespace mtf = mir_test_framework;
33
namespace geom = mir::geometry;
34
namespace mc = mir::compositor;
35
namespace mg = mir::graphics;
40
bool operator() (geom::Size const& a, geom::Size const& b)
42
return a.width < b.width && a.height < b.height;
46
struct CompositionTracker
48
bool wait_until_surface_is_rendered_with_size(geom::Size sz)
50
using namespace std::literals::chrono_literals;
51
std::unique_lock<decltype(mutex)> lk(mutex);
52
return cv.wait_for(lk, 4s, [this, sz] {
53
return std::find(rendered_sizes.begin(), rendered_sizes.end(), sz) != rendered_sizes.end();
57
void surface_rendered_with_size(geom::Size sz)
59
std::unique_lock<decltype(mutex)> lk(mutex);
60
rendered_sizes.emplace(sz);
65
std::set<geom::Size, size_less> rendered_sizes;
67
std::condition_variable cv;
70
struct CustomDBC : mc::DisplayBufferCompositor
72
CustomDBC(std::shared_ptr<CompositionTracker> const& tracker) :
77
void composite(mc::SceneElementSequence&& sequence) override
79
for(auto const& element : sequence)
81
auto renderable = element->renderable();
82
renderable->buffer(); //consume buffer to stop compositor from spinning
83
tracker->surface_rendered_with_size(renderable->screen_position().size);
87
std::shared_ptr<CompositionTracker> const tracker;
90
struct CustomDBCFactory : mc::DisplayBufferCompositorFactory
92
CustomDBCFactory(std::shared_ptr<CompositionTracker> const& tracker) :
97
std::unique_ptr<mc::DisplayBufferCompositor> create_compositor_for(mg::DisplayBuffer&) override
99
return std::make_unique<CustomDBC>(tracker);
102
std::shared_ptr<CompositionTracker> const tracker;
105
struct DisplayBufferCompositorOverride : mtf::ConnectedClientWithASurface
107
void SetUp() override
109
using namespace std::literals::chrono_literals;
110
server.override_the_display_buffer_compositor_factory([this]
112
return std::make_shared<CustomDBCFactory>(tracker);
115
mtf::ConnectedClientWithASurface::SetUp();
117
void TearDown() override
119
mtf::ConnectedClientWithASurface::TearDown();
122
std::shared_ptr<CompositionTracker> const tracker{std::make_shared<CompositionTracker>()};
126
TEST_F(DisplayBufferCompositorOverride, composite_called_with_surface)
128
mir_buffer_stream_swap_buffers_sync(mir_surface_get_buffer_stream(surface));
129
EXPECT_TRUE(tracker->wait_until_surface_is_rendered_with_size({surface_params.width, surface_params.height}));