~ubuntu-branches/ubuntu/wily/mir/wily-proposed

« back to all changes in this revision

Viewing changes to tests/unit-tests/graphics/android/test_hwc_display.cpp

  • Committer: Package Import Robot
  • Author(s): Ubuntu daily release
  • Date: 2014-10-10 14:01:26 UTC
  • mto: This revision was merged to the branch mainline in revision 84.
  • Revision ID: package-import@ubuntu.com-20141010140126-n1czko8na1kuz4ll
Tags: upstream-0.8.0+14.10.20141010
ImportĀ upstreamĀ versionĀ 0.8.0+14.10.20141010

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright Ā© 2013 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/platform/graphics/android/display_buffer.h"
20
 
#include "src/platform/graphics/android/android_display.h"
21
 
#include "src/platform/graphics/android/gl_context.h"
22
 
#include "src/platform/graphics/android/android_format_conversion-inl.h"
23
 
#include "mir_test_doubles/mock_display_device.h"
24
 
#include "mir_test_doubles/mock_display_report.h"
25
 
#include "mir_test_doubles/stub_renderable.h"
26
 
#include "mir_test_doubles/mock_egl.h"
27
 
#include "mir_test_doubles/mock_gl.h"
28
 
#include "mir/graphics/android/mir_native_window.h"
29
 
#include "mir_test_doubles/stub_driver_interpreter.h"
30
 
#include "mir_test_doubles/stub_display_buffer.h"
31
 
#include "mir_test_doubles/stub_buffer.h"
32
 
#include "mir_test_doubles/stub_gl_config.h"
33
 
#include "mir_test_doubles/mock_framebuffer_bundle.h"
34
 
#include "mir_test_doubles/stub_gl_program_factory.h"
35
 
#include <memory>
36
 
 
37
 
namespace geom=mir::geometry;
38
 
namespace mg=mir::graphics;
39
 
namespace mga=mir::graphics::android;
40
 
namespace mtd=mir::test::doubles;
41
 
 
42
 
namespace
43
 
{
44
 
class AndroidDisplayBuffer : public ::testing::Test
45
 
{
46
 
protected:
47
 
    virtual void SetUp()
48
 
    {
49
 
        stub_buffer = std::make_shared<testing::NiceMock<mtd::StubBuffer>>();
50
 
        mock_display_device = std::make_shared<testing::NiceMock<mtd::MockDisplayDevice>>();
51
 
        native_window = std::make_shared<mg::android::MirNativeWindow>(std::make_shared<mtd::StubDriverInterpreter>());
52
 
 
53
 
        visual_id = 5;
54
 
        dummy_display = mock_egl.fake_egl_display;
55
 
        dummy_config = mock_egl.fake_configs[0];
56
 
        dummy_context = mock_egl.fake_egl_context;
57
 
        testing::NiceMock<mtd::MockDisplayReport> report;
58
 
        mtd::StubGLConfig stub_gl_config;
59
 
 
60
 
        gl_context = std::make_shared<mga::PbufferGLContext>(
61
 
            mga::to_mir_format(mock_egl.fake_visual_id), stub_gl_config, report);
62
 
 
63
 
        mock_fb_bundle = std::make_shared<testing::NiceMock<mtd::MockFBBundle>>();
64
 
 
65
 
        ON_CALL(*mock_fb_bundle, fb_format())
66
 
            .WillByDefault(testing::Return(mir_pixel_format_abgr_8888));
67
 
        ON_CALL(*mock_fb_bundle, fb_size())
68
 
            .WillByDefault(testing::Return(display_size));
69
 
        ON_CALL(*mock_fb_bundle, fb_refresh_rate())
70
 
            .WillByDefault(testing::Return(refresh_rate));
71
 
    }
72
 
 
73
 
    testing::NiceMock<mtd::MockEGL> mock_egl;
74
 
    testing::NiceMock<mtd::MockGL> mock_gl;
75
 
    mtd::StubGLProgramFactory stub_program_factory;
76
 
 
77
 
    int visual_id;
78
 
    EGLConfig dummy_config;
79
 
    EGLDisplay dummy_display;
80
 
    EGLContext dummy_context;
81
 
    std::shared_ptr<mga::GLContext> gl_context;
82
 
 
83
 
    std::shared_ptr<mtd::StubBuffer> stub_buffer;
84
 
    std::shared_ptr<ANativeWindow> native_window;
85
 
    std::shared_ptr<mtd::MockDisplayDevice> mock_display_device;
86
 
    std::shared_ptr<mtd::MockFBBundle> mock_fb_bundle;
87
 
    geom::Size const display_size{433,232};
88
 
    double const refresh_rate{60.0};
89
 
};
90
 
}
91
 
 
92
 
TEST_F(AndroidDisplayBuffer, can_post_update_with_gl_only)
93
 
{
94
 
    using namespace testing;
95
 
 
96
 
    InSequence seq;
97
 
    EXPECT_CALL(*mock_display_device, post_gl(_))
98
 
        .Times(Exactly(1));
99
 
 
100
 
    mg::RenderableList renderlist{};
101
 
    mga::DisplayBuffer db(
102
 
        mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory, mga::OverlayOptimization::enabled);
103
 
    db.post_update();
104
 
}
105
 
 
106
 
TEST_F(AndroidDisplayBuffer, posts_overlay_list_returns_display_device_decision)
107
 
{
108
 
    using namespace testing;
109
 
    mg::RenderableList renderlist{
110
 
        std::make_shared<mtd::StubRenderable>(),
111
 
        std::make_shared<mtd::StubRenderable>()};
112
 
 
113
 
    EXPECT_CALL(*mock_display_device, post_overlays(_, Ref(renderlist), _))
114
 
        .Times(2)
115
 
        .WillOnce(Return(true))
116
 
        .WillOnce(Return(false));
117
 
 
118
 
    mga::DisplayBuffer db(
119
 
        mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory, mga::OverlayOptimization::enabled);
120
 
    EXPECT_TRUE(db.post_renderables_if_optimizable(renderlist)); 
121
 
    EXPECT_FALSE(db.post_renderables_if_optimizable(renderlist)); 
122
 
}
123
 
 
124
 
TEST_F(AndroidDisplayBuffer, defaults_to_normal_orientation)
125
 
{
126
 
    mga::DisplayBuffer db(
127
 
        mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory, mga::OverlayOptimization::enabled);
128
 
 
129
 
    EXPECT_EQ(mir_orientation_normal, db.orientation());
130
 
}
131
 
 
132
 
TEST_F(AndroidDisplayBuffer, orientation_is_passed_through)
133
 
{
134
 
    mga::DisplayBuffer db(
135
 
        mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory, mga::OverlayOptimization::enabled);
136
 
 
137
 
    for (auto const& ori : {mir_orientation_normal,
138
 
                            mir_orientation_left,
139
 
                            mir_orientation_right,
140
 
                            mir_orientation_inverted})
141
 
    {
142
 
        auto config = db.configuration();
143
 
        config.orientation = ori;
144
 
        db.configure(config);
145
 
        EXPECT_EQ(ori, db.orientation());
146
 
    }
147
 
}
148
 
 
149
 
TEST_F(AndroidDisplayBuffer, rotation_transposes_dimensions)
150
 
{
151
 
    using namespace testing;
152
 
 
153
 
    int const width = 123;
154
 
    int const height = 456;
155
 
    geom::Size const normal{width, height};
156
 
    geom::Size const transposed{height, width};
157
 
 
158
 
    EXPECT_CALL(*mock_fb_bundle, fb_size())
159
 
        .WillRepeatedly(Return(normal));
160
 
 
161
 
    mga::DisplayBuffer db(
162
 
        mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory, mga::OverlayOptimization::enabled);
163
 
 
164
 
    EXPECT_EQ(normal, db.view_area().size);
165
 
 
166
 
    auto config = db.configuration();
167
 
 
168
 
    config.orientation = mir_orientation_right;
169
 
    db.configure(config);
170
 
    EXPECT_EQ(transposed, db.view_area().size);
171
 
 
172
 
    config.orientation = mir_orientation_inverted;
173
 
    db.configure(config);
174
 
    EXPECT_EQ(normal, db.view_area().size);
175
 
 
176
 
    config.orientation = mir_orientation_left;
177
 
    db.configure(config);
178
 
    EXPECT_EQ(transposed, db.view_area().size);
179
 
}
180
 
 
181
 
TEST_F(AndroidDisplayBuffer, reports_correct_size)
182
 
{
183
 
    using namespace testing;
184
 
 
185
 
    mga::DisplayBuffer db(
186
 
        mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory, mga::OverlayOptimization::enabled);
187
 
 
188
 
    auto view_area = db.view_area();
189
 
 
190
 
    geom::Point origin_pt{geom::X{0}, geom::Y{0}};
191
 
    EXPECT_EQ(display_size, view_area.size);
192
 
    EXPECT_EQ(origin_pt, view_area.top_left);
193
 
}
194
 
 
195
 
TEST_F(AndroidDisplayBuffer, creates_egl_context_from_shared_context)
196
 
{
197
 
    using namespace testing;
198
 
 
199
 
    EGLint const expected_attr[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
200
 
 
201
 
    EXPECT_CALL(mock_egl, eglCreateContext(
202
 
        dummy_display, _, dummy_context, mtd::AttrMatches(expected_attr)))
203
 
        .Times(1)
204
 
        .WillOnce(Return(mock_egl.fake_egl_context));
205
 
    EXPECT_CALL(mock_egl, eglCreateWindowSurface(
206
 
        dummy_display, _, native_window.get(), NULL))
207
 
        .Times(1)
208
 
        .WillOnce(Return(mock_egl.fake_egl_surface));
209
 
    EXPECT_CALL(mock_egl, eglDestroySurface(dummy_display, mock_egl.fake_egl_surface))
210
 
        .Times(AtLeast(1));
211
 
    EXPECT_CALL(mock_egl, eglDestroyContext(dummy_display, mock_egl.fake_egl_context))
212
 
        .Times(AtLeast(1));
213
 
 
214
 
    mga::DisplayBuffer db(
215
 
        mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory, mga::OverlayOptimization::enabled);
216
 
    testing::Mock::VerifyAndClearExpectations(&mock_egl);
217
 
}
218
 
 
219
 
TEST_F(AndroidDisplayBuffer, fails_on_egl_resource_creation)
220
 
{
221
 
    using namespace testing;
222
 
    EXPECT_CALL(mock_egl, eglCreateContext(_,_,_,_))
223
 
        .Times(2)
224
 
        .WillOnce(Return(EGL_NO_CONTEXT))
225
 
        .WillOnce(Return(mock_egl.fake_egl_context));
226
 
    EXPECT_CALL(mock_egl, eglCreateWindowSurface(_,_,_,_))
227
 
        .Times(1)
228
 
        .WillOnce(Return(EGL_NO_SURFACE));
229
 
 
230
 
    EXPECT_THROW(
231
 
    {
232
 
        mga::DisplayBuffer db(
233
 
            mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory, mga::OverlayOptimization::enabled);
234
 
    }, std::runtime_error);
235
 
 
236
 
    EXPECT_THROW(
237
 
    {
238
 
        mga::DisplayBuffer db(
239
 
            mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory, mga::OverlayOptimization::enabled);
240
 
    }, std::runtime_error);
241
 
}
242
 
 
243
 
TEST_F(AndroidDisplayBuffer, can_make_current)
244
 
{
245
 
    using namespace testing;
246
 
    EGLContext fake_ctxt = reinterpret_cast<EGLContext>(0x4422);
247
 
    EGLSurface fake_surf = reinterpret_cast<EGLSurface>(0x33984);
248
 
    ON_CALL(mock_egl, eglCreateContext(_,_,_,_))
249
 
        .WillByDefault(Return(fake_ctxt));
250
 
    ON_CALL(mock_egl, eglCreateWindowSurface(_,_,_,_))
251
 
        .WillByDefault(Return(fake_surf));
252
 
 
253
 
    mga::DisplayBuffer db(
254
 
        mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory, mga::OverlayOptimization::enabled);
255
 
    
256
 
    EXPECT_CALL(mock_egl, eglMakeCurrent(dummy_display, fake_surf, fake_surf, fake_ctxt))
257
 
        .Times(2)
258
 
        .WillOnce(Return(EGL_TRUE))
259
 
        .WillOnce(Return(EGL_FALSE));
260
 
 
261
 
    db.make_current();
262
 
    EXPECT_THROW(
263
 
    {
264
 
        db.make_current();
265
 
    }, std::runtime_error);
266
 
}
267
 
 
268
 
TEST_F(AndroidDisplayBuffer, release_current)
269
 
{
270
 
    using namespace testing;
271
 
    mga::DisplayBuffer db(
272
 
        mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory, mga::OverlayOptimization::enabled);
273
 
 
274
 
    EXPECT_CALL(mock_egl, eglMakeCurrent(dummy_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
275
 
        .Times(1);
276
 
    db.release_current();
277
 
}
278
 
 
279
 
TEST_F(AndroidDisplayBuffer, sets_display_power_mode_to_on_at_start)
280
 
{
281
 
    using namespace testing;
282
 
    mga::DisplayBuffer db(
283
 
        mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory, mga::OverlayOptimization::enabled);
284
 
    auto config = db.configuration();
285
 
    EXPECT_EQ(mir_power_mode_on, config.power_mode);
286
 
}
287
 
 
288
 
TEST_F(AndroidDisplayBuffer, changes_display_power_mode)
289
 
{
290
 
    using namespace testing;
291
 
    mga::DisplayBuffer db(
292
 
        mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory, mga::OverlayOptimization::enabled);
293
 
 
294
 
    Sequence seq;
295
 
    EXPECT_CALL(*mock_display_device, mode(mir_power_mode_off))
296
 
        .InSequence(seq);
297
 
    EXPECT_CALL(*mock_display_device, mode(mir_power_mode_on))
298
 
        .InSequence(seq);
299
 
 
300
 
    auto config = db.configuration();
301
 
    config.power_mode = mir_power_mode_off;
302
 
    db.configure(config);
303
 
 
304
 
    config = db.configuration();
305
 
    config.power_mode = mir_power_mode_on;
306
 
    db.configure(config); 
307
 
}
308
 
 
309
 
TEST_F(AndroidDisplayBuffer, disregards_double_display_power_mode_request)
310
 
{
311
 
    using namespace testing;
312
 
    mga::DisplayBuffer db(
313
 
        mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory, mga::OverlayOptimization::enabled);
314
 
 
315
 
    EXPECT_CALL(*mock_display_device, mode(mir_power_mode_off))
316
 
        .Times(1);
317
 
 
318
 
    auto config = db.configuration();
319
 
    config.power_mode = mir_power_mode_off;
320
 
    db.configure(config);
321
 
    config.power_mode = mir_power_mode_suspend;
322
 
    db.configure(config);
323
 
    config.power_mode = mir_power_mode_standby;
324
 
    db.configure(config);
325
 
}
326
 
 
327
 
//configuration tests
328
 
TEST_F(AndroidDisplayBuffer, display_orientation_supported)
329
 
{
330
 
    using namespace testing;
331
 
 
332
 
    EXPECT_CALL(*mock_display_device, apply_orientation(mir_orientation_left))
333
 
        .Times(1)
334
 
        .WillOnce(Return(true));
335
 
 
336
 
    mga::DisplayBuffer db(
337
 
        mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory, mga::OverlayOptimization::enabled);
338
 
 
339
 
    auto config = db.configuration();
340
 
    config.orientation = mir_orientation_left;
341
 
    db.configure(config); 
342
 
 
343
 
    config = db.configuration();
344
 
    EXPECT_EQ(mir_orientation_normal, config.orientation);
345
 
}
346
 
 
347
 
TEST_F(AndroidDisplayBuffer, display_orientation_not_supported)
348
 
{
349
 
    using namespace testing;
350
 
    EXPECT_CALL(*mock_display_device, apply_orientation(mir_orientation_left))
351
 
        .Times(1)
352
 
        .WillOnce(Return(false));
353
 
 
354
 
    mga::DisplayBuffer db(
355
 
        mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory, mga::OverlayOptimization::enabled);
356
 
 
357
 
    auto config = db.configuration();
358
 
    config.orientation = mir_orientation_left;
359
 
    db.configure(config); 
360
 
 
361
 
    config = db.configuration();
362
 
    EXPECT_EQ(mir_orientation_left, config.orientation);
363
 
}
364
 
 
365
 
TEST_F(AndroidDisplayBuffer, incorrect_display_configure_throws)
366
 
{
367
 
    mga::DisplayBuffer db(
368
 
        mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory, mga::OverlayOptimization::enabled);
369
 
    auto config = db.configuration();
370
 
    //error
371
 
    config.current_format = mir_pixel_format_invalid;
372
 
    EXPECT_THROW({
373
 
        db.configure(config);
374
 
    }, std::runtime_error); 
375
 
}
376
 
 
377
 
TEST_F(AndroidDisplayBuffer, android_display_configuration_info)
378
 
{
379
 
    mga::DisplayBuffer db(
380
 
        mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory, mga::OverlayOptimization::enabled);
381
 
    auto disp_conf = db.configuration();
382
 
 
383
 
    ASSERT_EQ(1u, disp_conf.modes.size());
384
 
    auto& disp_mode = disp_conf.modes[0];
385
 
    EXPECT_EQ(display_size, disp_mode.size);
386
 
 
387
 
    EXPECT_EQ(mg::DisplayConfigurationOutputId{1}, disp_conf.id);
388
 
    EXPECT_EQ(mg::DisplayConfigurationCardId{0}, disp_conf.card_id);
389
 
    EXPECT_TRUE(disp_conf.connected);
390
 
    EXPECT_TRUE(disp_conf.used);
391
 
    auto origin = geom::Point{0,0};
392
 
    EXPECT_EQ(origin, disp_conf.top_left);
393
 
    EXPECT_EQ(0, disp_conf.current_mode_index);
394
 
 
395
 
    EXPECT_EQ(refresh_rate, disp_mode.vrefresh_hz);
396
 
    //TODO fill physical_size_mm fields accordingly;
397
 
}
398
 
 
399
 
TEST_F(AndroidDisplayBuffer, does_not_use_alpha)
400
 
{
401
 
    mga::DisplayBuffer db(
402
 
        mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory, mga::OverlayOptimization::enabled);
403
 
 
404
 
    EXPECT_FALSE(db.uses_alpha());
405
 
}
406
 
 
407
 
TEST_F(AndroidDisplayBuffer, reject_list_if_option_disabled)
408
 
{
409
 
    mg::RenderableList renderlist{std::make_shared<mtd::StubRenderable>()};
410
 
    mga::DisplayBuffer db(
411
 
        mock_fb_bundle,
412
 
        mock_display_device,
413
 
        native_window,
414
 
        *gl_context,
415
 
        stub_program_factory,
416
 
        mga::OverlayOptimization::disabled);
417
 
 
418
 
    EXPECT_FALSE(db.post_renderables_if_optimizable(renderlist)); 
419
 
}