~ubuntu-branches/ubuntu/utopic/mir/utopic-proposed

« back to all changes in this revision

Viewing changes to tests/unit-tests/scene/test_basic_surface.cpp

  • Committer: Package Import Robot
  • Author(s): Ubuntu daily release
  • Date: 2014-03-10 19:28:46 UTC
  • mto: This revision was merged to the branch mainline in revision 63.
  • Revision ID: package-import@ubuntu.com-20140310192846-rq9qm3ec26yrelo2
Tags: upstream-0.1.6+14.04.20140310
ImportĀ upstreamĀ versionĀ 0.1.6+14.04.20140310

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright Ā© 2013-2014 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/scene/basic_surface.h"
 
20
 
 
21
#include "mir/geometry/rectangle.h"
 
22
 
 
23
#include "mir_test_doubles/mock_buffer_stream.h"
 
24
#include "mir_test/fake_shared.h"
 
25
 
 
26
#include "src/server/report/null_report_factory.h"
 
27
 
 
28
#include <algorithm>
 
29
#include <gtest/gtest.h>
 
30
#include <gmock/gmock.h>
 
31
 
 
32
namespace mc = mir::compositor;
 
33
namespace mi = mir::input;
 
34
namespace mr = mir::report;
 
35
namespace ms = mir::scene;
 
36
namespace mt = mir::test;
 
37
namespace mtd = mt::doubles;
 
38
namespace geom = mir::geometry;
 
39
 
 
40
namespace
 
41
{
 
42
class MockCallback
 
43
{
 
44
public:
 
45
    MOCK_METHOD0(call, void());
 
46
};
 
47
 
 
48
struct BasicSurfaceTest : public testing::Test
 
49
{
 
50
    void SetUp()
 
51
    {
 
52
        name = std::string("aa");
 
53
        top_left = geom::Point{geom::X{4}, geom::Y{7}};
 
54
        size = geom::Size{5, 9};
 
55
        rect = geom::Rectangle{top_left, size};
 
56
        null_change_cb = []{};
 
57
        mock_change_cb = std::bind(&MockCallback::call, &mock_callback);
 
58
    }
 
59
    std::string name;
 
60
    geom::Point top_left;
 
61
    geom::Size size;
 
62
    geom::Rectangle rect;
 
63
 
 
64
    testing::NiceMock<MockCallback> mock_callback;
 
65
    std::function<void()> null_change_cb;
 
66
    std::function<void()> mock_change_cb;
 
67
    std::shared_ptr<testing::NiceMock<mtd::MockBufferStream>> mock_buffer_stream =
 
68
        std::make_shared<testing::NiceMock<mtd::MockBufferStream>>();
 
69
    std::shared_ptr<ms::SceneReport> const report = mr::null_scene_report();
 
70
};
 
71
 
 
72
}
 
73
 
 
74
TEST_F(BasicSurfaceTest, basics)
 
75
{
 
76
    ms::BasicSurface data{
 
77
        name,
 
78
        rect,
 
79
        null_change_cb,
 
80
        false,
 
81
        mock_buffer_stream,
 
82
        std::shared_ptr<mi::InputChannel>(),
 
83
        report};
 
84
 
 
85
    EXPECT_EQ(name, data.name());
 
86
    EXPECT_EQ(rect.size, data.size());
 
87
    EXPECT_EQ(rect.top_left, data.top_left());
 
88
    EXPECT_FALSE(data.shaped());
 
89
}
 
90
 
 
91
TEST_F(BasicSurfaceTest, update_top_left)
 
92
{
 
93
    EXPECT_CALL(mock_callback, call())
 
94
        .Times(1);
 
95
 
 
96
    ms::BasicSurface storage{
 
97
        name,
 
98
        rect,
 
99
        mock_change_cb,
 
100
        false,
 
101
        mock_buffer_stream,
 
102
        std::shared_ptr<mi::InputChannel>(),
 
103
        report};
 
104
 
 
105
    EXPECT_EQ(rect.top_left, storage.top_left());
 
106
 
 
107
    auto new_top_left = geom::Point{geom::X{6}, geom::Y{10}};
 
108
    storage.move_to(new_top_left);
 
109
    EXPECT_EQ(new_top_left, storage.top_left());
 
110
}
 
111
 
 
112
TEST_F(BasicSurfaceTest, update_size)
 
113
{
 
114
    geom::Size const new_size{34, 56};
 
115
 
 
116
    EXPECT_CALL(mock_callback, call())
 
117
        .Times(1);
 
118
 
 
119
    ms::BasicSurface storage{
 
120
        name,
 
121
        rect,
 
122
        mock_change_cb,
 
123
        false,
 
124
        mock_buffer_stream,
 
125
        std::shared_ptr<mi::InputChannel>(),
 
126
        report};
 
127
 
 
128
    EXPECT_EQ(rect.size, storage.size());
 
129
    EXPECT_NE(new_size, storage.size());
 
130
 
 
131
    auto old_transformation = storage.transformation();
 
132
 
 
133
    storage.resize(new_size);
 
134
    EXPECT_EQ(new_size, storage.size());
 
135
    EXPECT_NE(old_transformation, storage.transformation());
 
136
}
 
137
 
 
138
TEST_F(BasicSurfaceTest, test_surface_set_rotation_updates_transform)
 
139
{
 
140
    EXPECT_CALL(mock_callback, call())
 
141
        .Times(1);
 
142
 
 
143
    ms::BasicSurface storage{
 
144
        name,
 
145
        rect,
 
146
        mock_change_cb,
 
147
        false,
 
148
        mock_buffer_stream,
 
149
        std::shared_ptr<mi::InputChannel>(),
 
150
        report};
 
151
 
 
152
    auto original_transformation = storage.transformation();
 
153
 
 
154
    storage.set_rotation(60.0f, glm::vec3{0.0f, 0.0f, 1.0f});
 
155
    auto rotated_transformation = storage.transformation();
 
156
    EXPECT_NE(original_transformation, rotated_transformation);
 
157
}
 
158
 
 
159
TEST_F(BasicSurfaceTest, test_surface_transformation_cache_refreshes)
 
160
{
 
161
    using namespace testing;
 
162
 
 
163
    const geom::Size sz{geom::Width{85}, geom::Height{43}};
 
164
    const geom::Rectangle origin{geom::Point{geom::X{77}, geom::Y{88}}, sz};
 
165
    const geom::Rectangle moved_pt{geom::Point{geom::X{55}, geom::Y{66}}, sz};
 
166
    ms::BasicSurface storage{
 
167
        name,
 
168
        origin,
 
169
        null_change_cb,
 
170
        false,
 
171
        mock_buffer_stream,
 
172
        std::shared_ptr<mi::InputChannel>(),
 
173
        report};
 
174
 
 
175
    glm::mat4 t0 = storage.transformation();
 
176
    storage.move_to(moved_pt.top_left);
 
177
    EXPECT_NE(t0, storage.transformation());
 
178
    storage.move_to(origin.top_left);
 
179
    EXPECT_EQ(t0, storage.transformation());
 
180
 
 
181
    storage.set_rotation(60.0f, glm::vec3{0.0f, 0.0f, 1.0f});
 
182
    glm::mat4 t1 = storage.transformation();
 
183
    EXPECT_NE(t0, t1);
 
184
}
 
185
 
 
186
TEST_F(BasicSurfaceTest, test_surface_set_alpha_notifies_changes)
 
187
{
 
188
    using namespace testing;
 
189
    EXPECT_CALL(mock_callback, call())
 
190
        .Times(1);
 
191
 
 
192
    ms::BasicSurface surface_state{
 
193
        name,
 
194
        rect,
 
195
        mock_change_cb,
 
196
        false,
 
197
        mock_buffer_stream,
 
198
        std::shared_ptr<mi::InputChannel>(),
 
199
        report};
 
200
 
 
201
    float alpha = 0.5f;
 
202
    surface_state.set_alpha(0.5f);
 
203
    EXPECT_THAT(alpha, FloatEq(surface_state.alpha()));
 
204
}
 
205
 
 
206
TEST_F(BasicSurfaceTest, test_surface_is_opaque_by_default)
 
207
{
 
208
    using namespace testing;
 
209
    ms::BasicSurface surface_state{
 
210
        name,
 
211
        rect,
 
212
        null_change_cb,
 
213
        false,
 
214
        mock_buffer_stream,
 
215
        std::shared_ptr<mi::InputChannel>(),
 
216
        report};
 
217
 
 
218
    EXPECT_THAT(1.0f, FloatEq(surface_state.alpha()));
 
219
    EXPECT_FALSE(surface_state.shaped());
 
220
}
 
221
 
 
222
TEST_F(BasicSurfaceTest, test_surface_apply_rotation)
 
223
{
 
224
    EXPECT_CALL(mock_callback, call())
 
225
        .Times(1);
 
226
 
 
227
    ms::BasicSurface surface_state{
 
228
        name,
 
229
        rect,
 
230
        mock_change_cb,
 
231
        false,
 
232
        mock_buffer_stream,
 
233
        std::shared_ptr<mi::InputChannel>(),
 
234
        report};
 
235
 
 
236
    surface_state.set_rotation(60.0f, glm::vec3{0.0f, 0.0f, 1.0f});
 
237
}
 
238
 
 
239
TEST_F(BasicSurfaceTest, test_surface_should_be_rendered_in)
 
240
{
 
241
    ms::BasicSurface surface_state{
 
242
        name,
 
243
        rect,
 
244
        mock_change_cb,
 
245
        false,
 
246
        mock_buffer_stream,
 
247
        std::shared_ptr<mi::InputChannel>(),
 
248
        report};
 
249
 
 
250
    geom::Rectangle output_rect{geom::Point{0,0}, geom::Size{100, 100}};
 
251
 
 
252
    //not renderable by default
 
253
    EXPECT_FALSE(surface_state.should_be_rendered_in(rect));
 
254
 
 
255
    surface_state.set_hidden(false);
 
256
    //not renderable if no first frame has been posted by client, regardless of hide state
 
257
    EXPECT_FALSE(surface_state.should_be_rendered_in(output_rect));
 
258
    surface_state.set_hidden(true);
 
259
    EXPECT_FALSE(surface_state.should_be_rendered_in(output_rect));
 
260
 
 
261
    surface_state.frame_posted();
 
262
    EXPECT_FALSE(surface_state.should_be_rendered_in(output_rect));
 
263
 
 
264
    surface_state.set_hidden(false);
 
265
    EXPECT_TRUE(surface_state.should_be_rendered_in(output_rect));
 
266
 
 
267
    // Not renderable if not overlapping with supplied rect
 
268
    geom::Rectangle output_rect1{geom::Point{100,100}, geom::Size{100, 100}};
 
269
    EXPECT_FALSE(surface_state.should_be_rendered_in(output_rect1));
 
270
}
 
271
 
 
272
TEST_F(BasicSurfaceTest, test_surface_hidden_notifies_changes)
 
273
{
 
274
    using namespace testing;
 
275
    EXPECT_CALL(mock_callback, call())
 
276
        .Times(1);
 
277
 
 
278
    ms::BasicSurface surface_state{
 
279
        name,
 
280
        rect,
 
281
        mock_change_cb,
 
282
        false,
 
283
        mock_buffer_stream,
 
284
        std::shared_ptr<mi::InputChannel>(),
 
285
        report};
 
286
 
 
287
    surface_state.set_hidden(true);
 
288
}
 
289
 
 
290
TEST_F(BasicSurfaceTest, test_surface_frame_posted_notifies_changes)
 
291
{
 
292
    using namespace testing;
 
293
    EXPECT_CALL(mock_callback, call())
 
294
        .Times(1);
 
295
 
 
296
    ms::BasicSurface surface_state{
 
297
        name,
 
298
        rect,
 
299
        mock_change_cb,
 
300
        false,
 
301
        mock_buffer_stream,
 
302
        std::shared_ptr<mi::InputChannel>(),
 
303
        report};
 
304
 
 
305
    surface_state.frame_posted();
 
306
}
 
307
 
 
308
// a 1x1 window at (1,1) will get events at (1,1)
 
309
TEST_F(BasicSurfaceTest, default_region_is_surface_rectangle)
 
310
{
 
311
    geom::Point pt(1,1);
 
312
    geom::Size one_by_one{geom::Width{1}, geom::Height{1}};
 
313
    ms::BasicSurface surface_state{
 
314
        name,
 
315
        geom::Rectangle{pt, one_by_one},
 
316
        mock_change_cb,
 
317
        false,
 
318
        mock_buffer_stream,
 
319
        std::shared_ptr<mi::InputChannel>(),
 
320
        report};
 
321
 
 
322
    std::vector<geom::Point> contained_pt
 
323
    {
 
324
        geom::Point{geom::X{1}, geom::Y{1}}
 
325
    };
 
326
 
 
327
    for(auto x = 0; x <= 3; x++)
 
328
    {
 
329
        for(auto y = 0; y <= 3; y++)
 
330
        {
 
331
            auto test_pt = geom::Point{x, y};
 
332
            auto contains = surface_state.contains(test_pt);
 
333
            if (std::find(contained_pt.begin(), contained_pt.end(), test_pt) != contained_pt.end())
 
334
            {
 
335
                EXPECT_TRUE(contains);
 
336
            }
 
337
            else
 
338
            {
 
339
                EXPECT_FALSE(contains);
 
340
            }
 
341
        }
 
342
    }
 
343
}
 
344
 
 
345
TEST_F(BasicSurfaceTest, set_input_region)
 
346
{
 
347
    std::vector<geom::Rectangle> const rectangles = {
 
348
        {{geom::X{0}, geom::Y{0}}, {geom::Width{1}, geom::Height{1}}}, //region0
 
349
        {{geom::X{1}, geom::Y{1}}, {geom::Width{1}, geom::Height{1}}}  //region1
 
350
    };
 
351
 
 
352
    ms::BasicSurface surface_state{
 
353
        name,
 
354
        rect,
 
355
        mock_change_cb,
 
356
        false,
 
357
        mock_buffer_stream,
 
358
        std::shared_ptr<mi::InputChannel>(),
 
359
        report};
 
360
 
 
361
    surface_state.set_input_region(rectangles);
 
362
 
 
363
    std::vector<geom::Point> contained_pt
 
364
    {
 
365
        //region0 points
 
366
        geom::Point{geom::X{0}, geom::Y{0}},
 
367
        //region1 points
 
368
        geom::Point{geom::X{1}, geom::Y{1}},
 
369
    };
 
370
 
 
371
    for(auto x = 0; x <= 3; x++)
 
372
    {
 
373
        for(auto y = 0; y <= 3; y++)
 
374
        {
 
375
            auto test_pt = geom::Point{x, y};
 
376
            auto contains = surface_state.contains(test_pt);
 
377
            if (std::find(contained_pt.begin(), contained_pt.end(), test_pt) != contained_pt.end())
 
378
            {
 
379
                EXPECT_TRUE(contains);
 
380
            }
 
381
            else
 
382
            {
 
383
                EXPECT_FALSE(contains);
 
384
            }
 
385
        }
 
386
    }
 
387
}