~hikiko/mir/mir.unity8-desktop-session

« back to all changes in this revision

Viewing changes to tests/unit-tests/compositor/test_multi_threaded_compositor.cpp

  • Committer: Package Import Robot
  • Author(s): Ubuntu daily release, Daniel van Vugt, Ubuntu daily release
  • Date: 2014-02-04 14:49:07 UTC
  • mfrom: (1.1.55)
  • Revision ID: package-import@ubuntu.com-20140204144907-2lcyf87mba5rdca6
Tags: 0.1.4+14.04.20140204-0ubuntu1
[ Daniel van Vugt ]
* New upstream release 0.1.4 (https://launchpad.net/mir/+milestone/0.1.4)
  - Fixed snapshotting and flicker problems for Unity8 on various Nexus
    devices.
  - Enhanced reporting of performance information:
    . Report input latency in InputReport/InputReceiverReport.
    . Added a CompositorReport for logging compositor performance and state.
  - Added a new package "mir-utils" containing new tools:
    . mirping: Displays round-trip times between client and server
    . mirout: Displays the monitor layout/configuration details
  - Added GL texture caching to improve performance when multiple surfaces
    are visible.
  - Added opacity controls to mir_demo_server_shell
  - Mir server ABI bumped to 13. Client ABI bumped to 5.
  - Removed lots of Android headers, replaced by build-dep: android-headers
  - Added support for translucent nested servers.
  - tests: Fix unitialized values and incorrect fd closing loops
  - Fix unitialized values and incorrect fd closing loops.
  - client: Add basic MirScreencast C API.
  - config: start moving default values for config options from all the
    call sites to the setup
  - tests: Provide a helper for running clients with a stub ClientPlatform.
  - android: split out HWC layers into their own file and add a
    mga::CompositionLayer type that depends on the interface mg::Renderable.
  - client: Add basic MirOutputCapture class.
  - client: Don't create mesa ClientBuffer objects from invalid
    MirBufferPackages.
  - Optimize surface resizing to avoid doing anything if the dimensions
    are unchanged.
  - SwitchingBundle - add operator<< for debugging.
  - support hwcomposer 1.2 for android 4.4 on nexus 4 (which needs hwc1.2
    support). This patch adds hwc1.2 device construction, as well as progs
    the 'skip' layer in HWC to the buffer properties of the framebuffer.
  - demo-shell: Add simple keyboard controls to rotate outputs; Ctrl +
    Alt + <arrow-key>. Fixes: https://bugs.launchpad.net/bugs/1203215.
  - frontend: exposing internals of the RPC mechanism to enable custom
    function calls to be added.
  - Make udev wrapper into a top-level citizen
  - compositor: ignore double requests to start or stop the
    MultiThreadedCompositor.
  - Add DisplayBuffer::orientation(), to tell the Renderer if we need it
    to do screen rotation in GL (for platforms which don't implement 
    rotation natively) Fixes: https://bugs.launchpad.net/bugs/1203215.
  - graphics: add an post_update function that takes a list of renderables
    to the display buffer. This will let the display buffer take advantage
    of full-surface overlays on android.
  - android-input: Improve debug output
  - the stock qcom 8960 hwcomposer chokes on getDisplayAttributes if the
    submitted arrays are not at least size 6. patched the qcom android 4.2
    hwcomposer driver on the ubuntu touch images to work properly, but
    causes us problems with in-the wild drivers, and the new 4.4 drivers.
    Make sure we always submit a larger-than-needed array to this function.
  - frontend: refactoring to make it easier to expose the underlying RPC
    transport on the server side.
  - Don't assume pressure value is zero if not yet known
  - build: Expose options to allow building but not running tests by default.
  - Translucent Server which prefers a transparent pixel format
  - frontend: refactor ProtobufMessageProcessor to separate out generic
    response sending logic from specific message handling.
  - client: expose the part of the client RPC infrastructure needed for
    downstream to prototype their own message sending.
  - Bugs fixed:
    . unity8 display flickers and stops responding on Nexus 7 (grouper)
      (LP: #1238695)
    . Mir gets textures/buffers confused when running both scroll and flicker
      demos (LP: #1263592)
    . Some snapshots on Nexus10 upside-down (LP: #1263741)
    . mir_unit_tests is crashing with SIGSEGV in libhybris gl functions
      (LP: #1264968)
    . Some snapshots on Nexus10 have swapped red/blue channels (LP: #1265787)
    . Bypass causes some non-bypassed surfaces (on top) to be invisible
      (LP: #1266385)
    . helgrind: Possible data race - MirConnection::mutex not used
      consistently (LP: #1243575)
    . helgrind: Lock order violated (potential deadlock) in
      ConnectionSurfaceMap (LP: #1243576)
    . helgrind: Possible data race - inconsistent locking in PendingCallCache
      (LP: #1243578)
    . helgrind: Lock order violated in
      mir::client::ConnectionSurfaceMap::erase(int) (LP: #1243584)
    . [enhancement] Allow a Mir nested server to have a transparent
      background (LP: #1256702)
    . Compiling without tests fails (-DMIR_ENABLE_TESTS=NO) (LP: #1263724)
    . examples, doc: Make it clear and consistent how to use
      a non-root client with a root compositor endpoint. 
      (LP: #1272143)
    . Avoid linking to umockdev on platforms (android) which don't yet
      use it. This allows mir_unit_tests to run on touch images again
      (LP: #1271434)
    . Workaround for N4 nested server issue. This change removes
      mir_pixel_format_bgr_888 - HAL_PIXEL_FORMAT_RGB_888 from the
      list of supported pixel formats on android. (LP: #1272041)
    . Don't ask glUniformMatrix4fv to transpose your matrix. That option
      was officially deprecated between OpenGL and OpenGL|ES. And some
      drivers like the Nexus 10 don't implement it, resulting in incorrect
      transformations and even nothing on screen! (LP: #1271853)
    . Fixes: bug 1272143 (LP: #1272143)
    . fix integration test failure on the galaxy nexus that was due to
      creating two surfaces and registering the same buffer twice. Fixes:
      (LP: #1272597)
    . Implement screen rotation in GLRenderer, for platforms
      which can't do it natively in DisplayBuffer.
      (LP: #1203215)
    . Add an "orientation" field to output structures in preparation for
      screen rotation. It's not yet functionally wired to anything.
      (LP: #1203215)
    . Only use SwitchingBundle::last_consumed after it has been
      set. Otherwise SwitchingBundle::compositor_acquire could follow a bogus
      code path. (LP:#1270964)
    . tests: Override configuration to avoid creating an (unused)
      filesystem endpoint for connections when using InProcessServer. 
      (LP: #1271604)
    . frontend: ensure that BasicConnector threads don't exit
      immediately. (LP: #1271655)

[ Ubuntu daily release ]
* New rebuild forced

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
#include "mir/compositor/display_buffer_compositor.h"
21
21
#include "mir/compositor/scene.h"
22
22
#include "mir/compositor/display_buffer_compositor_factory.h"
 
23
#include "mir/compositor/compositor_report.h"
23
24
#include "mir_test_doubles/null_display.h"
24
25
#include "mir_test_doubles/null_display_buffer.h"
25
26
#include "mir_test_doubles/mock_display_buffer.h"
 
27
#include "mir_test_doubles/mock_compositor_report.h"
26
28
 
27
29
#include <unordered_map>
28
30
#include <unordered_set>
74
76
    }
75
77
 
76
78
private:
77
 
    std::vector<mtd::MockDisplayBuffer> buffers;
 
79
    std::vector<testing::NiceMock<mtd::MockDisplayBuffer>> buffers;
78
80
};
79
81
 
80
82
class StubScene : public mc::Scene
113
115
    std::mutex callback_mutex;
114
116
};
115
117
 
 
118
class MockScene : public mc::Scene
 
119
{
 
120
public:
 
121
    MOCK_METHOD2(for_each_if, void(mc::FilterForScene&, mc::OperatorForScene&));
 
122
    MOCK_METHOD2(reverse_for_each_if, void(mc::FilterForScene&, mc::OperatorForScene&));
 
123
    MOCK_METHOD1(set_change_callback, void(std::function<void()> const&));
 
124
    MOCK_METHOD0(lock, void());
 
125
    MOCK_METHOD0(unlock, void());
 
126
};
 
127
 
116
128
class RecordingDisplayBufferCompositor : public mc::DisplayBufferCompositor
117
129
{
118
130
public:
296
308
    }
297
309
};
298
310
 
 
311
auto const null_report = std::make_shared<mc::NullCompositorReport>();
 
312
 
299
313
}
300
314
 
301
315
TEST(MultiThreadedCompositor, compositing_happens_in_different_threads)
307
321
    auto display = std::make_shared<StubDisplay>(nbuffers);
308
322
    auto scene = std::make_shared<StubScene>();
309
323
    auto db_compositor_factory = std::make_shared<RecordingDisplayBufferCompositorFactory>();
310
 
    mc::MultiThreadedCompositor compositor{display, scene, db_compositor_factory};
 
324
    mc::MultiThreadedCompositor compositor{display, scene, db_compositor_factory, null_report};
311
325
 
312
326
    compositor.start();
313
327
 
320
334
    EXPECT_TRUE(db_compositor_factory->buffers_rendered_in_different_threads());
321
335
}
322
336
 
 
337
TEST(MultiThreadedCompositor, reports_in_the_right_places)
 
338
{
 
339
    using namespace testing;
 
340
 
 
341
    auto display = std::make_shared<StubDisplayWithMockBuffers>(1);
 
342
    auto scene = std::make_shared<StubScene>();
 
343
    auto db_compositor_factory =
 
344
        std::make_shared<RecordingDisplayBufferCompositorFactory>();
 
345
    auto mock_report = std::make_shared<mtd::MockCompositorReport>();
 
346
    mc::MultiThreadedCompositor compositor{display, scene,
 
347
                                           db_compositor_factory,
 
348
                                           mock_report};
 
349
 
 
350
    EXPECT_CALL(*mock_report, started())
 
351
        .Times(1);
 
352
 
 
353
    display->for_each_mock_buffer([](mtd::MockDisplayBuffer& mock_buf)
 
354
    {
 
355
        EXPECT_CALL(mock_buf, make_current()).Times(1);
 
356
        EXPECT_CALL(mock_buf, view_area())
 
357
            .WillOnce(Return(geom::Rectangle()));
 
358
    });
 
359
 
 
360
    EXPECT_CALL(*mock_report, added_display(_,_,_,_,_))
 
361
        .Times(1);
 
362
    EXPECT_CALL(*mock_report, scheduled())
 
363
        .Times(1);
 
364
 
 
365
    display->for_each_mock_buffer([](mtd::MockDisplayBuffer& mock_buf)
 
366
    {
 
367
        EXPECT_CALL(mock_buf, release_current()).Times(1);
 
368
    });
 
369
 
 
370
    EXPECT_CALL(*mock_report, stopped())
 
371
        .Times(AtLeast(1));
 
372
 
 
373
    compositor.start();
 
374
    scene->emit_change_event();
 
375
    while (!db_compositor_factory->check_record_count_for_each_buffer(1, mc::max_client_buffers))
 
376
        std::this_thread::yield();
 
377
    compositor.stop();
 
378
}
 
379
 
323
380
/*
324
381
 * It's difficult to test that a render won't happen, without some further
325
382
 * introspective capabilities that would complicate the code. This test will
338
395
    auto display = std::make_shared<StubDisplay>(nbuffers);
339
396
    auto scene = std::make_shared<StubScene>();
340
397
    auto db_compositor_factory = std::make_shared<RecordingDisplayBufferCompositorFactory>();
341
 
    mc::MultiThreadedCompositor compositor{display, scene, db_compositor_factory};
 
398
    mc::MultiThreadedCompositor compositor{display, scene, db_compositor_factory, null_report};
342
399
 
343
400
    // Verify we're actually starting at zero frames
344
401
    EXPECT_TRUE(db_compositor_factory->check_record_count_for_each_buffer(nbuffers, 0, 0));
398
455
    auto display = std::make_shared<StubDisplay>(nbuffers);
399
456
    auto scene = std::make_shared<StubScene>();
400
457
    auto db_compositor_factory = std::make_shared<SurfaceUpdatingDisplayBufferCompositorFactory>(scene);
401
 
    mc::MultiThreadedCompositor compositor{display, scene, db_compositor_factory};
 
458
    mc::MultiThreadedCompositor compositor{display, scene, db_compositor_factory, null_report};
402
459
 
403
460
    compositor.start();
404
461
 
417
474
    auto display = std::make_shared<StubDisplayWithMockBuffers>(nbuffers);
418
475
    auto scene = std::make_shared<StubScene>();
419
476
    auto db_compositor_factory = std::make_shared<NullDisplayBufferCompositorFactory>();
420
 
    mc::MultiThreadedCompositor compositor{display, scene, db_compositor_factory};
 
477
    mc::MultiThreadedCompositor compositor{display, scene, db_compositor_factory, null_report};
421
478
 
422
479
    display->for_each_mock_buffer([](mtd::MockDisplayBuffer& mock_buf)
423
480
    {
 
481
        EXPECT_CALL(mock_buf, view_area())
 
482
            .WillOnce(Return(geom::Rectangle()));
424
483
        EXPECT_CALL(mock_buf, make_current()).Times(1);
425
484
        EXPECT_CALL(mock_buf, release_current()).Times(1);
426
485
    });
428
487
    compositor.start();
429
488
    compositor.stop();
430
489
}
 
490
 
 
491
TEST(MultiThreadedCompositor, double_start_or_stop_ignored)
 
492
{
 
493
    unsigned int const nbuffers{3};
 
494
    auto display = std::make_shared<StubDisplayWithMockBuffers>(nbuffers);
 
495
    auto mock_scene = std::make_shared<MockScene>();
 
496
    auto db_compositor_factory = std::make_shared<NullDisplayBufferCompositorFactory>();
 
497
    auto mock_report = std::make_shared<testing::NiceMock<mtd::MockCompositorReport>>();
 
498
    EXPECT_CALL(*mock_report, started())
 
499
        .Times(1);
 
500
    EXPECT_CALL(*mock_report, stopped())
 
501
        .Times(1);
 
502
    EXPECT_CALL(*mock_scene, set_change_callback(testing::_))
 
503
        .Times(2);
 
504
 
 
505
    mc::MultiThreadedCompositor compositor{display, mock_scene, db_compositor_factory, mock_report};
 
506
 
 
507
    compositor.start();
 
508
    compositor.start();
 
509
    compositor.stop();
 
510
    compositor.stop();
 
511
}