~ubuntu-branches/ubuntu/vivid/mir/vivid

« back to all changes in this revision

Viewing changes to tests/acceptance-tests/test_stale_frames.cpp

  • Committer: Package Import Robot
  • Author(s): Ubuntu daily release
  • Date: 2014-08-11 19:52:06 UTC
  • mto: This revision was merged to the branch mainline in revision 77.
  • Revision ID: package-import@ubuntu.com-20140811195206-05ee991qbzvdbmel
Tags: upstream-0.6.0+14.10.20140811
Import upstream version 0.6.0+14.10.20140811

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright © 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: Alexandros Frantzis <alexandros.frantzis@canonical.com>
 
17
 */
 
18
 
 
19
#include "mir_toolkit/mir_client_library.h"
 
20
#include "mir_toolkit/mir_client_library_debug.h"
 
21
 
 
22
#include "mir/compositor/compositor.h"
 
23
#include "mir/compositor/renderer_factory.h"
 
24
#include "mir/graphics/renderable.h"
 
25
#include "mir/graphics/buffer.h"
 
26
#include "mir/graphics/buffer_id.h"
 
27
 
 
28
#include "mir_test_framework/using_stub_client_platform.h"
 
29
#include "mir_test_framework/stubbed_server_configuration.h"
 
30
#include "mir_test_framework/basic_client_server_fixture.h"
 
31
#include "mir_test_doubles/stub_renderer.h"
 
32
 
 
33
#include <gtest/gtest.h>
 
34
#include <gmock/gmock.h>
 
35
 
 
36
#include <mutex>
 
37
#include <condition_variable>
 
38
 
 
39
namespace mtf = mir_test_framework;
 
40
namespace mtd = mir::test::doubles;
 
41
namespace mc = mir::compositor;
 
42
namespace mg = mir::graphics;
 
43
namespace geom = mir::geometry;
 
44
 
 
45
namespace
 
46
{
 
47
 
 
48
struct StubRenderer : mtd::StubRenderer
 
49
{
 
50
    void render(mg::RenderableList const& renderables) const override
 
51
    {
 
52
        std::lock_guard<std::mutex> lock{mutex};
 
53
        for (auto const& r : renderables)
 
54
            rendered_buffers_.push_back(r->buffer()->id());
 
55
 
 
56
        if (renderables.size() > 0)
 
57
            new_rendered_buffer_cv.notify_all();
 
58
    }
 
59
 
 
60
    std::vector<mg::BufferID> rendered_buffers()
 
61
    {
 
62
        std::lock_guard<std::mutex> lock{mutex};
 
63
        return rendered_buffers_;
 
64
    }
 
65
 
 
66
    std::vector<mg::BufferID> wait_for_new_rendered_buffers()
 
67
    {
 
68
        std::unique_lock<std::mutex> lock{mutex};
 
69
 
 
70
        new_rendered_buffer_cv.wait_for(
 
71
            lock, std::chrono::seconds{2},
 
72
            [this] { return rendered_buffers_.size() != 0; });
 
73
 
 
74
        auto const rendered = std::move(rendered_buffers_);
 
75
        return rendered;
 
76
    }
 
77
 
 
78
    mutable std::mutex mutex;
 
79
    mutable std::condition_variable new_rendered_buffer_cv;
 
80
    mutable std::vector<mg::BufferID> rendered_buffers_;
 
81
};
 
82
 
 
83
class StubRendererFactory : public mc::RendererFactory
 
84
{
 
85
public:
 
86
    std::unique_ptr<mc::Renderer> create_renderer_for(
 
87
        geom::Rectangle const&, mc::DestinationAlpha) override
 
88
    {
 
89
        std::lock_guard<std::mutex> lock{mutex};
 
90
        renderer_ = new StubRenderer();
 
91
        renderer_created_cv.notify_all();
 
92
        return std::unique_ptr<mc::Renderer>{renderer_};
 
93
    }
 
94
 
 
95
    StubRenderer* renderer()
 
96
    {
 
97
        std::unique_lock<std::mutex> lock{mutex};
 
98
 
 
99
        renderer_created_cv.wait_for(
 
100
            lock, std::chrono::seconds{2},
 
101
            [this] { return renderer_ != nullptr; });
 
102
 
 
103
        return renderer_;
 
104
    }
 
105
 
 
106
    void clear_renderer()
 
107
    {
 
108
        std::lock_guard<std::mutex> lock{mutex};
 
109
        renderer_ = nullptr;
 
110
    }
 
111
 
 
112
    std::mutex mutex;
 
113
    std::condition_variable renderer_created_cv;
 
114
    StubRenderer* renderer_ = nullptr;
 
115
};
 
116
 
 
117
struct StubServerConfig : mtf::StubbedServerConfiguration
 
118
{
 
119
    std::shared_ptr<StubRendererFactory> the_stub_renderer_factory()
 
120
    {
 
121
        return stub_renderer_factory(
 
122
            [] { return std::make_shared<StubRendererFactory>(); });
 
123
    }
 
124
 
 
125
    std::shared_ptr<mc::RendererFactory> the_renderer_factory() override
 
126
    {
 
127
        return the_stub_renderer_factory();
 
128
    }
 
129
 
 
130
    mir::CachedPtr<StubRendererFactory> stub_renderer_factory;
 
131
};
 
132
 
 
133
using BasicFixture = mtf::BasicClientServerFixture<StubServerConfig>;
 
134
 
 
135
struct StaleFrames : BasicFixture
 
136
{
 
137
    void SetUp()
 
138
    {
 
139
        BasicFixture::SetUp();
 
140
 
 
141
        client_create_surface();
 
142
    }
 
143
 
 
144
    void TearDown()
 
145
    {
 
146
        mir_surface_release_sync(surface);
 
147
 
 
148
        BasicFixture::TearDown();
 
149
    }
 
150
 
 
151
    void client_create_surface()
 
152
    {
 
153
        MirSurfaceParameters const request_params =
 
154
        {
 
155
            __PRETTY_FUNCTION__,
 
156
            640, 480,
 
157
            mir_pixel_format_abgr_8888,
 
158
            mir_buffer_usage_hardware,
 
159
            mir_display_output_id_invalid
 
160
        };
 
161
 
 
162
        surface = mir_connection_create_surface_sync(connection, &request_params);
 
163
        ASSERT_TRUE(mir_surface_is_valid(surface));
 
164
    }
 
165
 
 
166
    std::vector<mg::BufferID> wait_for_new_rendered_buffers()
 
167
    {
 
168
        return server_configuration.the_stub_renderer_factory()->renderer()->wait_for_new_rendered_buffers();
 
169
    }
 
170
 
 
171
    void stop_compositor()
 
172
    {
 
173
        server_configuration.the_compositor()->stop();
 
174
        server_configuration.the_stub_renderer_factory()->clear_renderer();
 
175
    }
 
176
 
 
177
    void start_compositor()
 
178
    {
 
179
        server_configuration.the_compositor()->start();
 
180
    }
 
181
 
 
182
    MirSurface* surface;
 
183
    mtf::UsingStubClientPlatform using_stub_client_platform;
 
184
};
 
185
 
 
186
}
 
187
 
 
188
TEST_F(StaleFrames, are_dropped_when_restarting_compositor)
 
189
{
 
190
    using namespace testing;
 
191
 
 
192
    stop_compositor();
 
193
 
 
194
    auto const stale_buffer_id1 = mg::BufferID{mir_debug_surface_current_buffer_id(surface)};
 
195
    mir_surface_swap_buffers_sync(surface);
 
196
 
 
197
    auto const stale_buffer_id2 = mg::BufferID{mir_debug_surface_current_buffer_id(surface)};
 
198
    mir_surface_swap_buffers_sync(surface);
 
199
 
 
200
    mir_surface_swap_buffers_sync(surface);
 
201
 
 
202
    start_compositor();
 
203
 
 
204
    auto const new_buffers = wait_for_new_rendered_buffers();
 
205
    EXPECT_THAT(new_buffers, Not(AnyOf(Contains(stale_buffer_id1), Contains(stale_buffer_id2))));
 
206
}