Mir

Merge lp:~mir-team/mir/trunk-0.1.5 into lp:mir/0.1

Proposed by kevin gunn
Status: Merged
Merged at revision: 1175
Proposed branch: lp:~mir-team/mir/trunk-0.1.5
Merge into: lp:mir/0.1
Diff against target: 5417 lines (+1934/-662)
121 files modified
CMakeLists.txt (+1/-1)
debian/changelog (+49/-0)
debian/control (+4/-4)
debian/libmirclient7.install (+1/-1)
debian/libmirserver15.install (+1/-1)
debian/mir-utils.install (+1/-0)
examples/demo-inprocess-surface-client/inprocess_egl_client.cpp (+4/-2)
examples/render_surfaces.cpp (+3/-2)
include/platform/mir/graphics/display.h (+2/-2)
include/server/mir/compositor/buffer_stream.h (+1/-1)
include/server/mir/default_server_configuration.h (+3/-0)
include/server/mir/frontend/message_processor.h (+15/-1)
include/server/mir/frontend/screencast.h (+55/-0)
include/server/mir/frontend/shell.h (+8/-2)
include/server/mir/frontend/surface.h (+8/-1)
include/server/mir/frontend/template_protobuf_message_processor.h (+1/-3)
include/server/mir/shell/session.h (+6/-5)
include/shared/mir/int_wrapper.h (+16/-18)
include/test/mir_test_doubles/mock_buffer_bundle.h (+1/-1)
include/test/mir_test_doubles/mock_buffer_stream.h (+1/-1)
include/test/mir_test_doubles/mock_display.h (+1/-1)
include/test/mir_test_doubles/mock_fb_hal_device.h (+1/-3)
include/test/mir_test_doubles/mock_frontend_surface.h (+1/-1)
include/test/mir_test_doubles/mock_hwc_composer_device_1.h (+9/-1)
include/test/mir_test_doubles/mock_screencast.h (+50/-0)
include/test/mir_test_doubles/mock_shell.h (+6/-3)
include/test/mir_test_doubles/mock_shell_session.h (+2/-1)
include/test/mir_test_doubles/null_display.h (+4/-2)
include/test/mir_test_doubles/null_screencast.h (+52/-0)
include/test/mir_test_doubles/stub_buffer_stream.h (+2/-2)
include/test/mir_test_doubles/stub_display_configuration.h (+7/-0)
include/test/mir_test_doubles/stub_ipc_factory.h (+2/-2)
include/test/mir_test_doubles/stub_shell.h (+1/-1)
include/test/mir_test_doubles/stub_shell_session.h (+6/-1)
src/client/CMakeLists.txt (+2/-2)
src/client/mir_screencast.cpp (+13/-3)
src/client/mir_screencast.h (+1/-0)
src/client/mir_screencast_api.cpp (+15/-8)
src/client/rpc/mir_socket_rpc_channel.cpp (+7/-0)
src/platform/graphics/android/android_alloc_adaptor.cpp (+1/-1)
src/platform/graphics/android/android_display.cpp (+4/-2)
src/platform/graphics/android/android_display.h (+2/-2)
src/platform/graphics/android/android_platform.cpp (+1/-3)
src/platform/graphics/android/display_buffer.h (+0/-1)
src/platform/graphics/android/hwc_device.cpp (+4/-7)
src/platform/graphics/android/hwc_device.h (+2/-5)
src/platform/graphics/android/hwc_layers.cpp (+6/-2)
src/platform/graphics/android/internal_client_window.cpp (+6/-1)
src/platform/graphics/android/output_builder.cpp (+8/-12)
src/platform/graphics/android/output_builder.h (+1/-2)
src/platform/graphics/android/resource_factory.cpp (+3/-1)
src/platform/graphics/android/server_render_window.cpp (+6/-1)
src/platform/graphics/mesa/display.cpp (+4/-2)
src/platform/graphics/mesa/display.h (+4/-4)
src/server/CMakeLists.txt (+1/-1)
src/server/compositor/buffer_bundle.h (+1/-1)
src/server/compositor/buffer_stream_surfaces.cpp (+5/-4)
src/server/compositor/buffer_stream_surfaces.h (+1/-1)
src/server/compositor/default_configuration.cpp (+32/-0)
src/server/compositor/switching_bundle.cpp (+2/-2)
src/server/compositor/switching_bundle.h (+1/-1)
src/server/display_server.cpp (+5/-2)
src/server/frontend/default_configuration.cpp (+15/-6)
src/server/frontend/protobuf_ipc_factory.h (+7/-2)
src/server/frontend/protobuf_message_processor.cpp (+81/-5)
src/server/frontend/protobuf_message_processor.h (+3/-1)
src/server/frontend/protobuf_session_creator.cpp (+2/-2)
src/server/frontend/session_mediator.cpp (+144/-81)
src/server/frontend/session_mediator.h (+24/-3)
src/server/frontend/surface.cpp (+25/-1)
src/server/graphics/nested/nested_display.cpp (+6/-2)
src/server/graphics/nested/nested_display.h (+1/-1)
src/server/graphics/offscreen/display.cpp (+4/-2)
src/server/graphics/offscreen/display.h (+3/-3)
src/server/scene/application_session.cpp (+8/-1)
src/server/scene/application_session.h (+4/-1)
src/server/scene/basic_surface.cpp (+3/-3)
src/server/scene/basic_surface.h (+1/-1)
src/server/scene/session_manager.cpp (+6/-4)
src/server/scene/session_manager.h (+5/-2)
src/server/scene/surface_impl.cpp (+2/-2)
src/server/scene/surface_impl.h (+1/-1)
src/utils/CMakeLists.txt (+9/-0)
src/utils/screencast.cpp (+313/-0)
tests/acceptance-tests/test_client_screencast.cpp (+45/-133)
tests/acceptance-tests/test_display_configuration.cpp (+6/-4)
tests/acceptance-tests/test_protobuf.cpp (+1/-1)
tests/acceptance-tests/test_surfaces_with_output_id.cpp (+4/-2)
tests/draw/android_graphics.cpp (+0/-22)
tests/integration-tests/client/CMakeLists.txt (+6/-1)
tests/integration-tests/client/test_screencast.cpp (+191/-0)
tests/integration-tests/compositor/test_buffer_stream.cpp (+47/-21)
tests/integration-tests/compositor/test_swapping_swappers.cpp (+27/-2)
tests/integration-tests/graphics/android/test_buffer_integration.cpp (+25/-1)
tests/integration-tests/graphics/android/test_display_integration.cpp (+12/-37)
tests/integration-tests/graphics/android/test_internal_client.cpp (+3/-2)
tests/integration-tests/test_display_server_main_loop_events.cpp (+4/-2)
tests/integration-tests/test_session.cpp (+3/-2)
tests/integration-tests/test_session_manager.cpp (+6/-6)
tests/integration-tests/test_swapinterval.cpp (+15/-7)
tests/mir_test_framework/stubbed_server_configuration.cpp (+5/-3)
tests/unit-tests/client/test_mir_screencast.cpp (+52/-2)
tests/unit-tests/compositor/test_buffer_stream.cpp (+39/-9)
tests/unit-tests/compositor/test_switching_bundle.cpp (+58/-30)
tests/unit-tests/compositor/test_temporary_buffers.cpp (+2/-2)
tests/unit-tests/frontend/test_session_mediator.cpp (+67/-14)
tests/unit-tests/frontend/test_session_mediator_android.cpp (+3/-2)
tests/unit-tests/frontend/test_session_mediator_mesa.cpp (+4/-3)
tests/unit-tests/frontend/test_socket_session.cpp (+1/-1)
tests/unit-tests/graphics/android/test_android_alloc_adaptor.cpp (+1/-1)
tests/unit-tests/graphics/android/test_buffer_tex_bind.cpp (+14/-7)
tests/unit-tests/graphics/android/test_hwc_common_device.cpp (+3/-1)
tests/unit-tests/graphics/android/test_hwc_device.cpp (+25/-7)
tests/unit-tests/graphics/android/test_output_builder.cpp (+7/-7)
tests/unit-tests/graphics/mesa/test_display_configuration.cpp (+2/-2)
tests/unit-tests/scene/test_application_session.cpp (+91/-34)
tests/unit-tests/scene/test_session_manager.cpp (+8/-8)
tests/unit-tests/scene/test_surface.cpp (+19/-20)
tests/unit-tests/scene/test_surface_impl.cpp (+2/-1)
tests/unit-tests/scene/test_surface_stack.cpp (+1/-1)
tests/unit-tests/shell/test_graphics_display_layout.cpp (+5/-5)
To merge this branch: bzr merge lp:~mir-team/mir/trunk-0.1.5
Reviewer Review Type Date Requested Status
kevin gunn (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Daniel van Vugt Approve
Review via email: mp+205432@code.launchpad.net

Commit message

Latest upstream release of Mir0.1.5 (lp:~mir-team/mir/development-branch r1377)
plus upcoming enhancement:
   https://code.launchpad.net/~alan-griffiths/mir/fix-1276704/+merge/205357

Description of the change

.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

I figured out what this branch is composed of and it's not r1372...

1. Start with dev r1377, but there's still about 1000 lines different.
2. Manually patch in https://code.launchpad.net/~alan-griffiths/mir/fix-1276704/+merge/205357
3. Add an unexplained change to debian/rules
4. debian/changelog additions.

I think we need to do this more cleanly so we know what's actually going in to the merge. Otherwise there's no accurate historical log of what has changed and why.

I suggest starting dropping #2 and proposing it separately, directly to lp:mir with the trunk-0.15 branch as prereq. Unless it lands in development-branch beforehand, which would be cleaner. I also would like to know where #3 (debian/rules change) has come from, and some documentation of that change.

It would reflect badly on mir-team if we review changes to development-branch carefully, but don't do the same for lp:mir and let in undocumented changes.

review: Needs Fixing
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

BTW, if Ubuntu is desperate for it then you can always merge fix-1276704 directly to lp:mir without review. But it could become a major conflict headache if we find it needs fixing before it hits development-branch. So best to let it land in development-branch first.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Oooh, the mysterious debian/rules change #3 comes from the destination lp:mir. We'll have to revisit that...

I'll track issue #2 manually in LP and do an upstream Mir 0.1.5 release from r1377 to keep things as consistent as possible. So approved!

review: Approve
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

I've made major enhancements to the changelog text. Needs review again.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
kevin gunn (kgunn72) wrote :

thanks for the clean up, looks good (i see now how you want to handle tag vs promotion)

review: Approve
Revision history for this message
Kevin DuBois (kdub) wrote :

Please make sure not to pick up rev1383 because it contains a nexus 10 bug: https://bugs.launchpad.net/mir/+bug/1278658. (this has a fix, up for review)

Revision history for this message
Kevin DuBois (kdub) wrote :

> Please make sure not to pick up rev1383 because it contains a nexus 10 bug:
> https://bugs.launchpad.net/mir/+bug/1278658. (this has a fix, up for review)

fixed in lp:mir/devel rev 1388

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2014-01-22 08:32:55 +0000
+++ CMakeLists.txt 2014-02-10 09:00:06 +0000
@@ -28,7 +28,7 @@
2828
29set(MIR_VERSION_MAJOR 0)29set(MIR_VERSION_MAJOR 0)
30set(MIR_VERSION_MINOR 1)30set(MIR_VERSION_MINOR 1)
31set(MIR_VERSION_PATCH 4)31set(MIR_VERSION_PATCH 5)
3232
33set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)33set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
3434
3535
=== modified file 'debian/changelog'
--- debian/changelog 2014-02-04 14:49:07 +0000
+++ debian/changelog 2014-02-10 09:00:06 +0000
@@ -1,3 +1,52 @@
1mir (0.1.5-0ubuntu1) UNRELEASED; urgency=medium
2
3 * Cherry-picked from future release 0.1.6:
4 - frontend, shell: provide the client process ID in the shell::Session
5 interface (LP: #1276704)
6 * New upstream release 0.1.5 (https://launchpad.net/mir/+milestone/0.1.5)
7 - mirclient ABI bumped to 7
8 - mirserver ABI bumped to 15
9 - Refactoring to support client-controled RPC.
10 - Add an translucent server example (use sparingly, this will kill
11 performance!)
12 - Add workaround for Qualcomm Snapdragon 8960 driver bug.
13 - android-input: Improve debug output
14 - Screen rotation support half done (rotation of the screen works but input
15 rotation not implemented yet).
16 - Add groundwork for overlay support to take better advantage of mobile
17 hardware features and optimize composition in future.
18 - Add support for HWC 1.2 (Android 4.4)
19 - Add groundwork for screencasting (screen recording).
20 - Optimized surface resizing, significantly reducing event flooding for
21 some input configurations like touch.
22 - Bugs fixed:
23 . Surfaces no longer visible at all on Nexus 10 (LP: #1271853)
24 . mir nested server failure: what(): error binding buffer to texture
25 (LP: #1272041)
26 . Unity does not process events from evdev device created before unity is
27 restarted (autopilot tests) (LP: #1238417)
28 . mir_unit_tests can't run on touch images any more (missing
29 libumockdev.so.0) (LP: #1271434)
30 . chmod 777 /tmp/mir_socket is no longer sufficient for non-root clients
31 to connect to a root server (LP: #1272143)
32 . Nexus7(2013) flo framerate maxes out at 30fps (LP: #1274189)
33 . libmirserver user is unable to #include
34 <mir/frontend/template_protobuf_message_processor.h> (LP: #1276162)
35 . libmirclient user cannot "#include <mir/client/private.h>"
36 (LP: #1276565)
37 . AndroidInternalClient.internal_client_creation_and_use hangs on Nexus
38 10 (LP: #1270685)
39 . Tests that use the InProcessServer bind the default socket file
40 (LP: #1271604)
41 . BasicConnector threads exit immediately (LP: #1271655)
42 . Integration tests TestClientIPCRender.test_accelerated_render fails on
43 Galaxy Nexus and Nexus4 (LP: #1272597)
44 . Android backend unit-tests FTBS on amd64 (LP: #1276621)
45 . Erroneous use of last_consumed in SwitchingBundle::compositor_acquire
46 (LP: #1270964)
47
48 -- Kevin Gunn <kevin.gunn@canonical.com> Thu, 06 Feb 2014 10:54:17 -0600
49
1mir (0.1.4+14.04.20140204-0ubuntu1) trusty; urgency=medium50mir (0.1.4+14.04.20140204-0ubuntu1) trusty; urgency=medium
251
3 [ Daniel van Vugt ]52 [ Daniel van Vugt ]
453
=== modified file 'debian/control'
--- debian/control 2014-01-23 08:21:21 +0000
+++ debian/control 2014-02-10 09:00:06 +0000
@@ -70,7 +70,7 @@
70 .70 .
71 Contains the protocol's definition files.71 Contains the protocol's definition files.
7272
73Package: libmirserver1473Package: libmirserver15
74Section: libs74Section: libs
75Architecture: i386 amd64 armhf arm6475Architecture: i386 amd64 armhf arm64
76Multi-Arch: same76Multi-Arch: same
@@ -116,7 +116,7 @@
116Architecture: i386 amd64 armhf arm64116Architecture: i386 amd64 armhf arm64
117Multi-Arch: same117Multi-Arch: same
118Pre-Depends: ${misc:Pre-Depends}118Pre-Depends: ${misc:Pre-Depends}
119Depends: libmirserver14 (= ${binary:Version}),119Depends: libmirserver15 (= ${binary:Version}),
120 libmirprotobuf-dev (= ${binary:Version}),120 libmirprotobuf-dev (= ${binary:Version}),
121 mircommon-dev (= ${binary:Version}),121 mircommon-dev (= ${binary:Version}),
122 libglm-dev,122 libglm-dev,
@@ -128,7 +128,7 @@
128 .128 .
129 Contains header files required to build Mir servers.129 Contains header files required to build Mir servers.
130130
131Package: libmirclient6131Package: libmirclient7
132Section: libs132Section: libs
133Architecture: i386 amd64 armhf arm64133Architecture: i386 amd64 armhf arm64
134Multi-Arch: same134Multi-Arch: same
@@ -146,7 +146,7 @@
146Architecture: i386 amd64 armhf arm64146Architecture: i386 amd64 armhf arm64
147Multi-Arch: same147Multi-Arch: same
148Pre-Depends: ${misc:Pre-Depends}148Pre-Depends: ${misc:Pre-Depends}
149Depends: libmirclient6 (= ${binary:Version}),149Depends: libmirclient7 (= ${binary:Version}),
150 libmirprotobuf-dev (= ${binary:Version}),150 libmirprotobuf-dev (= ${binary:Version}),
151 mircommon-dev (= ${binary:Version}),151 mircommon-dev (= ${binary:Version}),
152 ${misc:Depends},152 ${misc:Depends},
153153
=== renamed file 'debian/libmirclient6.install' => 'debian/libmirclient7.install'
--- debian/libmirclient6.install 2014-01-17 06:22:01 +0000
+++ debian/libmirclient7.install 2014-02-10 09:00:06 +0000
@@ -1,1 +1,1 @@
1usr/lib/*/libmirclient.so.61usr/lib/*/libmirclient.so.7
22
=== renamed file 'debian/libmirserver14.install' => 'debian/libmirserver15.install'
--- debian/libmirserver14.install 2014-01-17 06:22:01 +0000
+++ debian/libmirserver15.install 2014-02-10 09:00:06 +0000
@@ -1,1 +1,1 @@
1usr/lib/*/libmirserver.so.141usr/lib/*/libmirserver.so.15
22
=== modified file 'debian/mir-utils.install'
--- debian/mir-utils.install 2014-01-10 05:48:41 +0000
+++ debian/mir-utils.install 2014-02-10 09:00:06 +0000
@@ -1,2 +1,3 @@
1usr/bin/mirping1usr/bin/mirping
2usr/bin/mirout2usr/bin/mirout
3usr/bin/mirscreencast
34
=== modified file 'examples/demo-inprocess-surface-client/inprocess_egl_client.cpp'
--- examples/demo-inprocess-surface-client/inprocess_egl_client.cpp 2014-01-13 06:12:33 +0000
+++ examples/demo-inprocess-surface-client/inprocess_egl_client.cpp 2014-02-10 09:00:06 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright © 2013 Canonical Ltd.2 * Copyright © 2013-2014 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify4 * 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 as5 * it under the terms of the GNU General Public License version 3 as
@@ -41,6 +41,8 @@
4141
42#include <xkbcommon/xkbcommon-keysyms.h>42#include <xkbcommon/xkbcommon-keysyms.h>
4343
44#include <unistd.h>
45
44#include <functional>46#include <functional>
4547
46#include <assert.h>48#include <assert.h>
@@ -93,7 +95,7 @@
93 .of_size(surface_size)95 .of_size(surface_size)
94 .of_buffer_usage(mg::BufferUsage::hardware)96 .of_buffer_usage(mg::BufferUsage::hardware)
95 .of_pixel_format(mir_pixel_format_argb_8888);97 .of_pixel_format(mir_pixel_format_argb_8888);
96 auto session = shell->open_session("Inprocess client", std::make_shared<NullEventSink>());98 auto session = shell->open_session(getpid(), "Inprocess client", std::make_shared<NullEventSink>());
97 // TODO: Why do we get an ID? ~racarr99 // TODO: Why do we get an ID? ~racarr
98 auto surface = session->get_surface(shell->create_surface_for(session, params));100 auto surface = session->get_surface(shell->create_surface_for(session, params));
99101
100102
=== modified file 'examples/render_surfaces.cpp'
--- examples/render_surfaces.cpp 2014-01-29 12:51:30 +0000
+++ examples/render_surfaces.cpp 2014-02-10 09:00:06 +0000
@@ -419,8 +419,9 @@
419 */419 */
420 {420 {
421 mg::Buffer* buffer{nullptr};421 mg::Buffer* buffer{nullptr};
422 s->swap_buffers(buffer);422 auto const complete = [&](mg::Buffer* new_buf){ buffer = new_buf; };
423 s->swap_buffers(buffer);423 s->swap_buffers(buffer, complete);
424 s->swap_buffers(buffer, complete);
424 }425 }
425426
426 /*427 /*
427428
=== modified file 'include/platform/mir/graphics/display.h'
--- include/platform/mir/graphics/display.h 2013-08-28 03:41:48 +0000
+++ include/platform/mir/graphics/display.h 2014-02-10 09:00:06 +0000
@@ -50,9 +50,9 @@
50 virtual void for_each_display_buffer(std::function<void(DisplayBuffer&)> const& f) = 0;50 virtual void for_each_display_buffer(std::function<void(DisplayBuffer&)> const& f) = 0;
5151
52 /**52 /**
53 * Gets the current output configuration.53 * Gets a copy of the current output configuration.
54 */54 */
55 virtual std::shared_ptr<DisplayConfiguration> configuration() = 0;55 virtual std::unique_ptr<DisplayConfiguration> configuration() const = 0;
5656
57 /**57 /**
58 * Sets a new output configuration.58 * Sets a new output configuration.
5959
=== modified file 'include/server/mir/compositor/buffer_stream.h'
--- include/server/mir/compositor/buffer_stream.h 2014-01-13 06:12:33 +0000
+++ include/server/mir/compositor/buffer_stream.h 2014-02-10 09:00:06 +0000
@@ -41,7 +41,7 @@
41public:41public:
42 virtual ~BufferStream() = default;42 virtual ~BufferStream() = default;
4343
44 virtual void swap_client_buffers(graphics::Buffer*& buffer) = 0;44 virtual void swap_client_buffers(graphics::Buffer* old_buffer, std::function<void(graphics::Buffer* new_buffer)> complete) = 0;
45 virtual std::shared_ptr<graphics::Buffer>45 virtual std::shared_ptr<graphics::Buffer>
46 lock_compositor_buffer(unsigned long frameno) = 0;46 lock_compositor_buffer(unsigned long frameno) = 0;
47 virtual std::shared_ptr<graphics::Buffer> lock_snapshot_buffer() = 0;47 virtual std::shared_ptr<graphics::Buffer> lock_snapshot_buffer() = 0;
4848
=== modified file 'include/server/mir/default_server_configuration.h'
--- include/server/mir/default_server_configuration.h 2014-01-27 17:47:06 +0000
+++ include/server/mir/default_server_configuration.h 2014-02-10 09:00:06 +0000
@@ -50,6 +50,7 @@
50class SessionAuthorizer;50class SessionAuthorizer;
51class EventSink;51class EventSink;
52class DisplayChanger;52class DisplayChanger;
53class Screencast;
53}54}
5455
55namespace shell56namespace shell
@@ -171,6 +172,7 @@
171 virtual std::shared_ptr<frontend::Shell> the_frontend_shell();172 virtual std::shared_ptr<frontend::Shell> the_frontend_shell();
172 virtual std::shared_ptr<frontend::EventSink> the_global_event_sink();173 virtual std::shared_ptr<frontend::EventSink> the_global_event_sink();
173 virtual std::shared_ptr<frontend::DisplayChanger> the_frontend_display_changer();174 virtual std::shared_ptr<frontend::DisplayChanger> the_frontend_display_changer();
175 virtual std::shared_ptr<frontend::Screencast> the_screencast();
174 /** @name frontend configuration - internal dependencies176 /** @name frontend configuration - internal dependencies
175 * internal dependencies of frontend177 * internal dependencies of frontend
176 * @{ */178 * @{ */
@@ -266,6 +268,7 @@
266 CachedPtr<frontend::SessionAuthorizer> session_authorizer;268 CachedPtr<frontend::SessionAuthorizer> session_authorizer;
267 CachedPtr<frontend::EventSink> global_event_sink;269 CachedPtr<frontend::EventSink> global_event_sink;
268 CachedPtr<frontend::SessionCreator> session_creator;270 CachedPtr<frontend::SessionCreator> session_creator;
271 CachedPtr<frontend::Screencast> screencast;
269 CachedPtr<compositor::RendererFactory> renderer_factory;272 CachedPtr<compositor::RendererFactory> renderer_factory;
270 CachedPtr<compositor::BufferStreamFactory> buffer_stream_factory;273 CachedPtr<compositor::BufferStreamFactory> buffer_stream_factory;
271 CachedPtr<scene::SurfaceStack> surface_stack;274 CachedPtr<scene::SurfaceStack> surface_stack;
272275
=== modified file 'include/server/mir/frontend/message_processor.h'
--- include/server/mir/frontend/message_processor.h 2014-01-22 15:54:11 +0000
+++ include/server/mir/frontend/message_processor.h 2014-02-10 09:00:06 +0000
@@ -19,6 +19,8 @@
19#ifndef MIR_FRONTEND_MESSAGE_PROCESSOR_H_19#ifndef MIR_FRONTEND_MESSAGE_PROCESSOR_H_
20#define MIR_FRONTEND_MESSAGE_PROCESSOR_H_20#define MIR_FRONTEND_MESSAGE_PROCESSOR_H_
2121
22#include <google/protobuf/service.h>
23
22namespace mir24namespace mir
23{25{
24namespace protobuf26namespace protobuf
@@ -32,11 +34,23 @@
32{34{
33namespace detail35namespace detail
34{36{
37class Invocation
38{
39public:
40 Invocation(mir::protobuf::wire::Invocation const& invocation) :
41 invocation(invocation) {}
42
43 const ::std::string& method_name() const;
44 const ::std::string& parameters() const;
45 ::google::protobuf::uint32 id() const;
46private:
47 mir::protobuf::wire::Invocation const& invocation;
48};
3549
36class MessageProcessor50class MessageProcessor
37{51{
38public:52public:
39 virtual bool dispatch(mir::protobuf::wire::Invocation const& invocation) = 0;53 virtual bool dispatch(Invocation const& invocation) = 0;
4054
41protected:55protected:
42 MessageProcessor() = default;56 MessageProcessor() = default;
4357
=== added file 'include/server/mir/frontend/screencast.h'
--- include/server/mir/frontend/screencast.h 1970-01-01 00:00:00 +0000
+++ include/server/mir/frontend/screencast.h 2014-02-10 09:00:06 +0000
@@ -0,0 +1,55 @@
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#ifndef MIR_FRONTEND_SCREENCAST_H_
20#define MIR_FRONTEND_SCREENCAST_H_
21
22#include "mir/int_wrapper.h"
23#include "mir/graphics/display_configuration.h"
24
25#include <memory>
26
27namespace mir
28{
29namespace graphics { class Buffer; }
30namespace frontend
31{
32namespace detail { struct ScreencastSessionIdTag; }
33
34typedef IntWrapper<detail::ScreencastSessionIdTag,uint32_t> ScreencastSessionId;
35
36class Screencast
37{
38public:
39 virtual ~Screencast() = default;
40
41 virtual ScreencastSessionId create_session(
42 graphics::DisplayConfigurationOutputId output_id) = 0;
43 virtual void destroy_session(ScreencastSessionId id) = 0;
44 virtual std::shared_ptr<graphics::Buffer> capture(ScreencastSessionId id) = 0;
45
46protected:
47 Screencast() = default;
48 Screencast(Screencast const&) = delete;
49 Screencast& operator=(Screencast const&) = delete;
50};
51
52}
53}
54
55#endif /* MIR_FRONTEND_SCREENCAST_H_ */
056
=== modified file 'include/server/mir/frontend/shell.h'
--- include/server/mir/frontend/shell.h 2014-01-13 06:12:33 +0000
+++ include/server/mir/frontend/shell.h 2014-02-10 09:00:06 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright © 2012 Canonical Ltd.2 * Copyright © 2012-2014 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * 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,5 * under the terms of the GNU General Public License version 3,
@@ -20,6 +20,9 @@
20#define MIR_FRONTEND_SHELL_H_20#define MIR_FRONTEND_SHELL_H_
2121
22#include "mir/frontend/surface_id.h"22#include "mir/frontend/surface_id.h"
23
24#include <sys/types.h>
25
23#include <memory>26#include <memory>
2427
25namespace mir28namespace mir
@@ -39,7 +42,10 @@
39 virtual ~Shell() = default;42 virtual ~Shell() = default;
4043
41 virtual std::shared_ptr<Session> open_session(44 virtual std::shared_ptr<Session> open_session(
42 std::string const& name, std::shared_ptr<EventSink> const& sink) = 0;45 pid_t client_pid,
46 std::string const& name,
47 std::shared_ptr<EventSink> const& sink) = 0;
48
43 virtual void close_session(std::shared_ptr<Session> const& session) = 0;49 virtual void close_session(std::shared_ptr<Session> const& session) = 0;
4450
45 virtual SurfaceId create_surface_for(std::shared_ptr<Session> const& session,51 virtual SurfaceId create_surface_for(std::shared_ptr<Session> const& session,
4652
=== modified file 'include/server/mir/frontend/surface.h'
--- include/server/mir/frontend/surface.h 2014-01-13 06:12:33 +0000
+++ include/server/mir/frontend/surface.h 2014-02-10 09:00:06 +0000
@@ -56,13 +56,20 @@
56 virtual geometry::Size size() const = 0;56 virtual geometry::Size size() const = 0;
57 virtual MirPixelFormat pixel_format() const = 0;57 virtual MirPixelFormat pixel_format() const = 0;
5858
59 virtual void swap_buffers(graphics::Buffer*&) = 0;59 virtual void swap_buffers(graphics::Buffer* old_buffer, std::function<void(graphics::Buffer* new_buffer)> complete) = 0;
6060
61 virtual bool supports_input() const = 0;61 virtual bool supports_input() const = 0;
62 virtual int client_input_fd() const = 0;62 virtual int client_input_fd() const = 0;
6363
64 virtual int configure(MirSurfaceAttrib attrib, int value) = 0;64 virtual int configure(MirSurfaceAttrib attrib, int value) = 0;
6565
66 /**
67 * swap_buffers_blocking() is a convenience wrapper around swap_buffers()
68 * it forces the current thread to block until complete() is called.
69 * Use with care!
70 */
71 void swap_buffers_blocking(graphics::Buffer*& buffer);
72
66protected:73protected:
67 Surface() = default;74 Surface() = default;
68 Surface(Surface const&) = delete;75 Surface(Surface const&) = delete;
6976
=== modified file 'include/server/mir/frontend/template_protobuf_message_processor.h'
--- include/server/mir/frontend/template_protobuf_message_processor.h 2014-01-21 12:49:00 +0000
+++ include/server/mir/frontend/template_protobuf_message_processor.h 2014-02-10 09:00:06 +0000
@@ -22,8 +22,6 @@
2222
23#include "mir/frontend/message_processor.h"23#include "mir/frontend/message_processor.h"
2424
25#include "mir_protobuf_wire.pb.h"
26
27#include <google/protobuf/service.h>25#include <google/protobuf/service.h>
2826
29#include <boost/exception/diagnostic_information.hpp>27#include <boost/exception/diagnostic_information.hpp>
@@ -54,7 +52,7 @@
54 const ParameterMessage* request,52 const ParameterMessage* request,
55 ResultMessage* response,53 ResultMessage* response,
56 ::google::protobuf::Closure* done),54 ::google::protobuf::Closure* done),
57 mir::protobuf::wire::Invocation const& invocation)55 Invocation const& invocation)
58{56{
59 ParameterMessage parameter_message;57 ParameterMessage parameter_message;
60 parameter_message.ParseFromString(invocation.parameters());58 parameter_message.ParseFromString(invocation.parameters());
6159
=== modified file 'include/server/mir/shell/session.h'
--- include/server/mir/shell/session.h 2014-01-13 06:12:33 +0000
+++ include/server/mir/shell/session.h 2014-02-10 09:00:06 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright © 2012 Canonical Ltd.2 * Copyright © 2012-2014 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * 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,5 * under the terms of the GNU General Public License version 3,
@@ -7,11 +7,11 @@
7 *7 *
8 * This program is distributed in the hope that it will be useful,8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.11 * GNU General Public License for more details.
12 *12 *
13 * You should have received a copy of the GNU General Public License13 * 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/>.14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *15 *
16 * Authored By: Robert Carr <racarr@canonical.com>16 * Authored By: Robert Carr <racarr@canonical.com>
17 */17 */
@@ -22,9 +22,10 @@
22#include "mir/frontend/session.h"22#include "mir/frontend/session.h"
23#include "mir/shell/snapshot.h"23#include "mir/shell/snapshot.h"
2424
25#include <sys/types.h>
26
25namespace mir27namespace mir
26{28{
27
28namespace shell29namespace shell
29{30{
30class Surface;31class Surface;
@@ -34,12 +35,12 @@
34public:35public:
35 virtual std::string name() const = 0;36 virtual std::string name() const = 0;
36 virtual void force_requests_to_complete() = 0;37 virtual void force_requests_to_complete() = 0;
38 virtual pid_t process_id() const = 0;
3739
38 virtual void take_snapshot(SnapshotCallback const& snapshot_taken) = 0;40 virtual void take_snapshot(SnapshotCallback const& snapshot_taken) = 0;
39 virtual std::shared_ptr<Surface> default_surface() const = 0;41 virtual std::shared_ptr<Surface> default_surface() const = 0;
40 virtual void set_lifecycle_state(MirLifecycleState state) = 0;42 virtual void set_lifecycle_state(MirLifecycleState state) = 0;
41};43};
42
43}44}
44}45}
4546
4647
=== modified file 'include/shared/mir/int_wrapper.h'
--- include/shared/mir/int_wrapper.h 2013-08-28 03:41:48 +0000
+++ include/shared/mir/int_wrapper.h 2014-02-10 09:00:06 +0000
@@ -23,12 +23,10 @@
2323
24namespace mir24namespace mir
25{25{
26template<typename Tag>26template<typename Tag, typename ValueType=int>
27class IntWrapper27class IntWrapper
28{28{
29public:29public:
30 typedef int ValueType;
31
32 IntWrapper() : value(0) {}30 IntWrapper() : value(0) {}
3331
34 explicit IntWrapper(ValueType value) : value(value) {}32 explicit IntWrapper(ValueType value) : value(value) {}
@@ -38,39 +36,39 @@
38 ValueType value;36 ValueType value;
39};37};
4038
41template<typename Tag>39template<typename Tag, typename ValueType>
42std::ostream& operator<<(std::ostream& out, IntWrapper<Tag> const& value)40std::ostream& operator<<(std::ostream& out, IntWrapper<Tag,ValueType> const& value)
43{41{
44 out << value.as_value();42 out << value.as_value();
45 return out;43 return out;
46}44}
4745
48template<typename Tag>46template<typename Tag, typename ValueType>
49inline bool operator == (IntWrapper<Tag> const& lhs, IntWrapper<Tag> const& rhs)47inline bool operator == (IntWrapper<Tag,ValueType> const& lhs, IntWrapper<Tag,ValueType> const& rhs)
50{48{
51 return lhs.as_value() == rhs.as_value();49 return lhs.as_value() == rhs.as_value();
52}50}
5351
54template<typename Tag>52template<typename Tag, typename ValueType>
55inline bool operator != (IntWrapper<Tag> const& lhs, IntWrapper<Tag> const& rhs)53inline bool operator != (IntWrapper<Tag,ValueType> const& lhs, IntWrapper<Tag,ValueType> const& rhs)
56{54{
57 return lhs.as_value() != rhs.as_value();55 return lhs.as_value() != rhs.as_value();
58}56}
5957
60template<typename Tag>58template<typename Tag, typename ValueType>
61inline bool operator <= (IntWrapper<Tag> const& lhs, IntWrapper<Tag> const& rhs)59inline bool operator <= (IntWrapper<Tag,ValueType> const& lhs, IntWrapper<Tag,ValueType> const& rhs)
62{60{
63 return lhs.as_value() <= rhs.as_value();61 return lhs.as_value() <= rhs.as_value();
64}62}
6563
66template<typename Tag>64template<typename Tag, typename ValueType>
67inline bool operator >= (IntWrapper<Tag> const& lhs, IntWrapper<Tag> const& rhs)65inline bool operator >= (IntWrapper<Tag,ValueType> const& lhs, IntWrapper<Tag,ValueType> const& rhs)
68{66{
69 return lhs.as_value() >= rhs.as_value();67 return lhs.as_value() >= rhs.as_value();
70}68}
7169
72template<typename Tag>70template<typename Tag, typename ValueType>
73inline bool operator < (IntWrapper<Tag> const& lhs, IntWrapper<Tag> const& rhs)71inline bool operator < (IntWrapper<Tag,ValueType> const& lhs, IntWrapper<Tag,ValueType> const& rhs)
74{72{
75 return lhs.as_value() < rhs.as_value();73 return lhs.as_value() < rhs.as_value();
76}74}
@@ -79,11 +77,11 @@
79#include <functional>77#include <functional>
80namespace std78namespace std
81{79{
82template<typename Tag>80template<typename Tag, typename ValueType>
83struct hash< ::mir::IntWrapper<Tag> >81struct hash< ::mir::IntWrapper<Tag,ValueType> >
84{82{
85 std::hash<int> self;83 std::hash<int> self;
86 std::size_t operator()(::mir::IntWrapper<Tag> const& id) const84 std::size_t operator()(::mir::IntWrapper<Tag,ValueType> const& id) const
87 {85 {
88 return self(id.as_value());86 return self(id.as_value());
89 }87 }
9088
=== modified file 'include/test/mir_test_doubles/mock_buffer_bundle.h'
--- include/test/mir_test_doubles/mock_buffer_bundle.h 2014-01-13 06:12:33 +0000
+++ include/test/mir_test_doubles/mock_buffer_bundle.h 2014-02-10 09:00:06 +0000
@@ -37,7 +37,7 @@
37 ~MockBufferBundle() noexcept37 ~MockBufferBundle() noexcept
38 {}38 {}
3939
40 MOCK_METHOD0(client_acquire, graphics::Buffer*());40 MOCK_METHOD1(client_acquire, void(std::function<void(graphics::Buffer*)>));
41 MOCK_METHOD1(client_release, void(graphics::Buffer*));41 MOCK_METHOD1(client_release, void(graphics::Buffer*));
42 MOCK_METHOD1(compositor_acquire, std::shared_ptr<graphics::Buffer>(unsigned long));42 MOCK_METHOD1(compositor_acquire, std::shared_ptr<graphics::Buffer>(unsigned long));
43 MOCK_METHOD1(compositor_release, void(std::shared_ptr<graphics::Buffer> const&));43 MOCK_METHOD1(compositor_release, void(std::shared_ptr<graphics::Buffer> const&));
4444
=== modified file 'include/test/mir_test_doubles/mock_buffer_stream.h'
--- include/test/mir_test_doubles/mock_buffer_stream.h 2014-01-13 06:12:33 +0000
+++ include/test/mir_test_doubles/mock_buffer_stream.h 2014-02-10 09:00:06 +0000
@@ -31,7 +31,7 @@
31{31{
32struct MockBufferStream : public compositor::BufferStream32struct MockBufferStream : public compositor::BufferStream
33{33{
34 MOCK_METHOD1(swap_client_buffers, void(graphics::Buffer*&));34 MOCK_METHOD2(swap_client_buffers, void(graphics::Buffer*, std::function<void(graphics::Buffer*)> completee));
35 MOCK_METHOD1(lock_compositor_buffer,35 MOCK_METHOD1(lock_compositor_buffer,
36 std::shared_ptr<graphics::Buffer>(unsigned long));36 std::shared_ptr<graphics::Buffer>(unsigned long));
37 MOCK_METHOD0(lock_snapshot_buffer, std::shared_ptr<graphics::Buffer>());37 MOCK_METHOD0(lock_snapshot_buffer, std::shared_ptr<graphics::Buffer>());
3838
=== modified file 'include/test/mir_test_doubles/mock_display.h'
--- include/test/mir_test_doubles/mock_display.h 2013-08-28 03:41:48 +0000
+++ include/test/mir_test_doubles/mock_display.h 2014-02-10 09:00:06 +0000
@@ -36,7 +36,7 @@
36{36{
37public:37public:
38 MOCK_METHOD1(for_each_display_buffer, void (std::function<void(graphics::DisplayBuffer&)> const&));38 MOCK_METHOD1(for_each_display_buffer, void (std::function<void(graphics::DisplayBuffer&)> const&));
39 MOCK_METHOD0(configuration, std::shared_ptr<graphics::DisplayConfiguration>());39 MOCK_CONST_METHOD0(configuration, std::unique_ptr<graphics::DisplayConfiguration>());
40 MOCK_METHOD1(configure, void(graphics::DisplayConfiguration const&));40 MOCK_METHOD1(configure, void(graphics::DisplayConfiguration const&));
41 MOCK_METHOD2(register_configuration_change_handler,41 MOCK_METHOD2(register_configuration_change_handler,
42 void(graphics::EventHandlerRegister&, graphics::DisplayConfigurationChangeHandler const&));42 void(graphics::EventHandlerRegister&, graphics::DisplayConfigurationChangeHandler const&));
4343
=== modified file 'include/test/mir_test_doubles/mock_fb_hal_device.h'
--- include/test/mir_test_doubles/mock_fb_hal_device.h 2014-01-13 06:12:33 +0000
+++ include/test/mir_test_doubles/mock_fb_hal_device.h 2014-02-10 09:00:06 +0000
@@ -37,7 +37,7 @@
37 MockFBHalDevice(unsigned int const width, unsigned int const height,37 MockFBHalDevice(unsigned int const width, unsigned int const height,
38 int const pf, int const numfbs)38 int const pf, int const numfbs)
39 : framebuffer_device_t({39 : framebuffer_device_t({
40 empty_module,40 hw_device_t(),
41 0,41 0,
42 width,42 width,
43 height,43 height,
@@ -86,8 +86,6 @@
86 MOCK_METHOD2(enableScreen_interface, int(struct framebuffer_device_t*, int));86 MOCK_METHOD2(enableScreen_interface, int(struct framebuffer_device_t*, int));
87 MOCK_METHOD2(post_interface, int(struct framebuffer_device_t*, buffer_handle_t));87 MOCK_METHOD2(post_interface, int(struct framebuffer_device_t*, buffer_handle_t));
88 MOCK_METHOD2(setSwapInterval_interface, int(struct framebuffer_device_t*, int));88 MOCK_METHOD2(setSwapInterval_interface, int(struct framebuffer_device_t*, int));
89
90 hw_device_t empty_module;
91};89};
9290
93}91}
9492
=== modified file 'include/test/mir_test_doubles/mock_frontend_surface.h'
--- include/test/mir_test_doubles/mock_frontend_surface.h 2014-01-13 06:12:33 +0000
+++ include/test/mir_test_doubles/mock_frontend_surface.h 2014-02-10 09:00:06 +0000
@@ -39,7 +39,7 @@
3939
40 MOCK_METHOD0(destroy, void());40 MOCK_METHOD0(destroy, void());
41 MOCK_METHOD0(force_requests_to_complete, void());41 MOCK_METHOD0(force_requests_to_complete, void());
42 MOCK_METHOD1(swap_buffers, void(graphics::Buffer*&));42 MOCK_METHOD2(swap_buffers, void(graphics::Buffer*, std::function<void(graphics::Buffer*)> complete));
4343
44 MOCK_CONST_METHOD0(size, geometry::Size());44 MOCK_CONST_METHOD0(size, geometry::Size());
45 MOCK_CONST_METHOD0(pixel_format, MirPixelFormat());45 MOCK_CONST_METHOD0(pixel_format, MirPixelFormat());
4646
=== modified file 'include/test/mir_test_doubles/mock_hwc_composer_device_1.h'
--- include/test/mir_test_doubles/mock_hwc_composer_device_1.h 2014-01-23 17:26:51 +0000
+++ include/test/mir_test_doubles/mock_hwc_composer_device_1.h 2014-02-10 09:00:06 +0000
@@ -76,6 +76,11 @@
76 fb_fence = fence;76 fb_fence = fence;
77 }77 }
7878
79 void hwc_set_retire_fence(int fence)
80 {
81 retire_fence = fence;
82 }
83
79 int save_last_prepare_arguments(struct hwc_composer_device_1 *, size_t size, hwc_display_contents_1_t** displays)84 int save_last_prepare_arguments(struct hwc_composer_device_1 *, size_t size, hwc_display_contents_1_t** displays)
80 {85 {
81 if ((size == 0) || (!displays)) 86 if ((size == 0) || (!displays))
@@ -122,12 +127,14 @@
122 set_layerlist.back().visibleRegionScreen = {0, nullptr};127 set_layerlist.back().visibleRegionScreen = {0, nullptr};
123 }128 }
124129
130 save_args(&display0_set_content, displays);
131
125 if (displays[0]->numHwLayers >= 2)132 if (displays[0]->numHwLayers >= 2)
126 {133 {
127 displays[0]->hwLayers[1].releaseFenceFd = fb_fence;134 displays[0]->hwLayers[1].releaseFenceFd = fb_fence;
135 displays[0]->retireFenceFd = retire_fence;
128 }136 }
129137
130 save_args(&display0_set_content, displays);
131 default:138 default:
132 break;139 break;
133 }140 }
@@ -186,6 +193,7 @@
186 std::vector<hwc_layer_1> prepare_layerlist;193 std::vector<hwc_layer_1> prepare_layerlist;
187 hwc_display_contents_1_t display0_prepare_content;194 hwc_display_contents_1_t display0_prepare_content;
188 int fb_fence;195 int fb_fence;
196 int retire_fence;
189};197};
190198
191}199}
192200
=== added file 'include/test/mir_test_doubles/mock_screencast.h'
--- include/test/mir_test_doubles/mock_screencast.h 1970-01-01 00:00:00 +0000
+++ include/test/mir_test_doubles/mock_screencast.h 2014-02-10 09:00:06 +0000
@@ -0,0 +1,50 @@
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#ifndef MIR_TEST_DOUBLES_MOCK_SCREENCAST_H_
20#define MIR_TEST_DOUBLES_MOCK_SCREENCAST_H_
21
22#include "mir/frontend/screencast.h"
23
24#include <gmock/gmock.h>
25
26namespace mir
27{
28namespace test
29{
30namespace doubles
31{
32
33class MockScreencast : public frontend::Screencast
34{
35public:
36 MOCK_METHOD1(create_session,
37 frontend::ScreencastSessionId(
38 graphics::DisplayConfigurationOutputId));
39 MOCK_METHOD1(destroy_session, void(frontend::ScreencastSessionId));
40 MOCK_METHOD1(capture,
41 std::shared_ptr<graphics::Buffer>(
42 frontend::ScreencastSessionId));
43};
44
45}
46}
47}
48
49#endif /* MIR_TEST_DOUBLES_NULL_SCREENCAST_H_ */
50
051
=== modified file 'include/test/mir_test_doubles/mock_shell.h'
--- include/test/mir_test_doubles/mock_shell.h 2013-08-28 03:41:48 +0000
+++ include/test/mir_test_doubles/mock_shell.h 2014-02-10 09:00:06 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright © 2013 Canonical Ltd.2 * Copyright © 2013-2014 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify4 * 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 as5 * it under the terms of the GNU General Public License version 3 as
@@ -34,8 +34,11 @@
3434
35struct MockShell : public frontend::Shell35struct MockShell : public frontend::Shell
36{36{
37 MOCK_METHOD2(open_session, std::shared_ptr<frontend::Session>(37 MOCK_METHOD3(open_session, std::shared_ptr<frontend::Session>(
38 std::string const&, std::shared_ptr<frontend::EventSink> const&));38 pid_t client_pid,
39 std::string const&,
40 std::shared_ptr<frontend::EventSink> const&));
41
39 MOCK_METHOD1(close_session, void(std::shared_ptr<frontend::Session> const&));42 MOCK_METHOD1(close_session, void(std::shared_ptr<frontend::Session> const&));
4043
41 MOCK_METHOD2(create_surface_for, frontend::SurfaceId(std::shared_ptr<frontend::Session> const&, shell::SurfaceCreationParameters const&));44 MOCK_METHOD2(create_surface_for, frontend::SurfaceId(std::shared_ptr<frontend::Session> const&, shell::SurfaceCreationParameters const&));
4245
=== modified file 'include/test/mir_test_doubles/mock_shell_session.h'
--- include/test/mir_test_doubles/mock_shell_session.h 2014-01-13 06:12:33 +0000
+++ include/test/mir_test_doubles/mock_shell_session.h 2014-02-10 09:00:06 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright © 2013 Canonical Ltd.2 * Copyright © 2013-2014 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * 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,5 * under the terms of the GNU General Public License version 3,
@@ -42,6 +42,7 @@
42 MOCK_CONST_METHOD0(default_surface, std::shared_ptr<shell::Surface>());42 MOCK_CONST_METHOD0(default_surface, std::shared_ptr<shell::Surface>());
4343
44 MOCK_CONST_METHOD0(name, std::string());44 MOCK_CONST_METHOD0(name, std::string());
45 MOCK_CONST_METHOD0(process_id, pid_t());
45 MOCK_METHOD0(force_requests_to_complete, void());46 MOCK_METHOD0(force_requests_to_complete, void());
4647
47 MOCK_METHOD0(hide, void());48 MOCK_METHOD0(hide, void());
4849
=== modified file 'include/test/mir_test_doubles/null_display.h'
--- include/test/mir_test_doubles/null_display.h 2013-08-28 03:41:48 +0000
+++ include/test/mir_test_doubles/null_display.h 2014-02-10 09:00:06 +0000
@@ -39,9 +39,11 @@
39 /* yield() is needed to ensure reasonable runtime under valgrind for some tests */39 /* yield() is needed to ensure reasonable runtime under valgrind for some tests */
40 std::this_thread::yield();40 std::this_thread::yield();
41 }41 }
42 std::shared_ptr<graphics::DisplayConfiguration> configuration()42 std::unique_ptr<graphics::DisplayConfiguration> configuration() const override
43 {43 {
44 return std::make_shared<NullDisplayConfiguration>();44 return std::unique_ptr<graphics::DisplayConfiguration>(
45 new NullDisplayConfiguration
46 );
45 }47 }
46 void configure(graphics::DisplayConfiguration const&) {}48 void configure(graphics::DisplayConfiguration const&) {}
47 void register_configuration_change_handler(49 void register_configuration_change_handler(
4850
=== added file 'include/test/mir_test_doubles/null_screencast.h'
--- include/test/mir_test_doubles/null_screencast.h 1970-01-01 00:00:00 +0000
+++ include/test/mir_test_doubles/null_screencast.h 2014-02-10 09:00:06 +0000
@@ -0,0 +1,52 @@
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#ifndef MIR_TEST_DOUBLES_NULL_SCREENCAST_H_
20#define MIR_TEST_DOUBLES_NULL_SCREENCAST_H_
21
22#include "mir/frontend/screencast.h"
23
24namespace mir
25{
26namespace test
27{
28namespace doubles
29{
30
31class NullScreencast : public frontend::Screencast
32{
33public:
34 frontend::ScreencastSessionId create_session(
35 graphics::DisplayConfigurationOutputId)
36 {
37 return frontend::ScreencastSessionId{1};
38 }
39
40 void destroy_session(frontend::ScreencastSessionId) {}
41
42 std::shared_ptr<graphics::Buffer> capture(frontend::ScreencastSessionId)
43 {
44 return nullptr;
45 }
46};
47
48}
49}
50}
51
52#endif /* MIR_TEST_DOUBLES_NULL_SCREENCAST_H_ */
053
=== modified file 'include/test/mir_test_doubles/stub_buffer_stream.h'
--- include/test/mir_test_doubles/stub_buffer_stream.h 2014-01-13 06:12:33 +0000
+++ include/test/mir_test_doubles/stub_buffer_stream.h 2014-02-10 09:00:06 +0000
@@ -36,9 +36,9 @@
36 {36 {
37 stub_compositor_buffer = std::make_shared<StubBuffer>();37 stub_compositor_buffer = std::make_shared<StubBuffer>();
38 }38 }
39 void swap_client_buffers(graphics::Buffer*& buffer) override39 void swap_client_buffers(graphics::Buffer*, std::function<void(graphics::Buffer* new_buffer)> complete) override
40 {40 {
41 buffer = &stub_client_buffer;41 complete(&stub_client_buffer);
42 }42 }
43 std::shared_ptr<graphics::Buffer> lock_compositor_buffer(unsigned long) override43 std::shared_ptr<graphics::Buffer> lock_compositor_buffer(unsigned long) override
44 {44 {
4545
=== modified file 'include/test/mir_test_doubles/stub_display_configuration.h'
--- include/test/mir_test_doubles/stub_display_configuration.h 2014-01-28 09:06:46 +0000
+++ include/test/mir_test_doubles/stub_display_configuration.h 2014-02-10 09:00:06 +0000
@@ -40,6 +40,13 @@
40 {40 {
41 }41 }
4242
43 StubDisplayConfig(StubDisplayConfig const& other)
44 : graphics::DisplayConfiguration(),
45 cards(other.cards),
46 outputs(other.outputs)
47 {
48 }
49
43 StubDisplayConfig(unsigned int num_displays)50 StubDisplayConfig(unsigned int num_displays)
44 : StubDisplayConfig(num_displays,51 : StubDisplayConfig(num_displays,
45 {52 {
4653
=== modified file 'include/test/mir_test_doubles/stub_ipc_factory.h'
--- include/test/mir_test_doubles/stub_ipc_factory.h 2014-01-21 06:27:40 +0000
+++ include/test/mir_test_doubles/stub_ipc_factory.h 2014-02-10 09:00:06 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright © 2012 Canonical Ltd.2 * Copyright © 2012-2014 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * 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,5 * under the terms of the GNU General Public License version 3,
@@ -41,7 +41,7 @@
41 }41 }
4242
43 std::shared_ptr<protobuf::DisplayServer> make_ipc_server(43 std::shared_ptr<protobuf::DisplayServer> make_ipc_server(
44 std::shared_ptr<frontend::EventSink> const&, bool) override44 pid_t, std::shared_ptr<frontend::EventSink> const&, bool) override
45 {45 {
46 return server;46 return server;
47 }47 }
4848
=== modified file 'include/test/mir_test_doubles/stub_shell.h'
--- include/test/mir_test_doubles/stub_shell.h 2013-08-28 03:41:48 +0000
+++ include/test/mir_test_doubles/stub_shell.h 2014-02-10 09:00:06 +0000
@@ -34,7 +34,7 @@
34 StubShell() : stub_session(std::make_shared<StubSession>())34 StubShell() : stub_session(std::make_shared<StubSession>())
35 {35 {
36 }36 }
37 std::shared_ptr<frontend::Session> open_session(std::string const& /* name */, std::shared_ptr<frontend::EventSink> const& /* sink */) override37 std::shared_ptr<frontend::Session> open_session(pid_t, std::string const& /* name */, std::shared_ptr<frontend::EventSink> const& /* sink */) override
38 {38 {
39 return stub_session;39 return stub_session;
40 }40 }
4141
=== modified file 'include/test/mir_test_doubles/stub_shell_session.h'
--- include/test/mir_test_doubles/stub_shell_session.h 2014-01-13 06:12:33 +0000
+++ include/test/mir_test_doubles/stub_shell_session.h 2014-02-10 09:00:06 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright © 2013 Canonical Ltd.2 * Copyright © 2013-2014 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * 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,5 * under the terms of the GNU General Public License version 3,
@@ -45,6 +45,11 @@
45 {45 {
46 return std::string();46 return std::string();
47 }47 }
48 pid_t process_id() const override
49 {
50 return -1;
51 }
52
48 void force_requests_to_complete() override53 void force_requests_to_complete() override
49 {54 {
50 }55 }
5156
=== modified file 'src/client/CMakeLists.txt'
--- src/client/CMakeLists.txt 2014-01-28 09:06:46 +0000
+++ src/client/CMakeLists.txt 2014-02-10 09:00:06 +0000
@@ -72,7 +72,7 @@
72 ${CLIENT_SOURCES}72 ${CLIENT_SOURCES}
73)73)
7474
75set(MIRCLIENT_ABI 6)75set(MIRCLIENT_ABI 7)
7676
77set_target_properties(77set_target_properties(
78 mirclient78 mirclient
@@ -117,7 +117,7 @@
117 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})117 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
118118
119install(119install(
120 DIRECTORY ${CMAKE_SOURCE_DIR}/include/client/mir_toolkit120 DIRECTORY ${CMAKE_SOURCE_DIR}/include/client/mir_toolkit ${CMAKE_SOURCE_DIR}/include/client/mir
121 DESTINATION "include/mirclient"121 DESTINATION "include/mirclient"
122)122)
123123
124124
=== modified file 'src/client/mir_screencast.cpp'
--- src/client/mir_screencast.cpp 2014-01-24 18:11:19 +0000
+++ src/client/mir_screencast.cpp 2014-02-10 09:00:06 +0000
@@ -98,6 +98,8 @@
98 egl_native_window_factory{egl_native_window_factory},98 egl_native_window_factory{egl_native_window_factory},
99 buffer_depository{factory, mir::frontend::client_buffer_cache_size}99 buffer_depository{factory, mir::frontend::client_buffer_cache_size}
100{100{
101 protobuf_screencast.set_error("Not initialized");
102
101 mir::protobuf::ScreencastParameters parameters;103 mir::protobuf::ScreencastParameters parameters;
102 parameters.set_output_id(output_id);104 parameters.set_output_id(output_id);
103 parameters.set_width(output_size.width.as_uint32_t());105 parameters.set_width(output_size.width.as_uint32_t());
@@ -117,6 +119,11 @@
117 return &create_screencast_wait_handle;119 return &create_screencast_wait_handle;
118}120}
119121
122bool MirScreencast::valid()
123{
124 return !protobuf_screencast.has_error();
125}
126
120MirSurfaceParameters MirScreencast::get_parameters() const127MirSurfaceParameters MirScreencast::get_parameters() const
121{128{
122 return MirSurfaceParameters{129 return MirSurfaceParameters{
@@ -188,7 +195,7 @@
188 try195 try
189 {196 {
190 buffer_depository.deposit_package(buffer_package,197 buffer_depository.deposit_package(buffer_package,
191 protobuf_buffer.buffer_id(),198 buffer.buffer_id(),
192 output_size, output_format);199 output_size, output_format);
193 }200 }
194 catch (const std::runtime_error& err)201 catch (const std::runtime_error& err)
@@ -200,8 +207,11 @@
200void MirScreencast::screencast_created(207void MirScreencast::screencast_created(
201 mir_screencast_callback callback, void* context)208 mir_screencast_callback callback, void* context)
202{209{
203 egl_native_window_ = egl_native_window_factory->create_egl_native_window(this);210 if (!protobuf_screencast.has_error())
204 process_buffer(protobuf_screencast.buffer());211 {
212 egl_native_window_ = egl_native_window_factory->create_egl_native_window(this);
213 process_buffer(protobuf_screencast.buffer());
214 }
205215
206 callback(this, context);216 callback(this, context);
207 create_screencast_wait_handle.result_received();217 create_screencast_wait_handle.result_received();
208218
=== modified file 'src/client/mir_screencast.h'
--- src/client/mir_screencast.h 2014-01-24 18:11:19 +0000
+++ src/client/mir_screencast.h 2014-02-10 09:00:06 +0000
@@ -49,6 +49,7 @@
49 mir_screencast_callback callback, void* context);49 mir_screencast_callback callback, void* context);
5050
51 MirWaitHandle* creation_wait_handle();51 MirWaitHandle* creation_wait_handle();
52 bool valid();
5253
53 MirWaitHandle* release(54 MirWaitHandle* release(
54 mir_screencast_callback callback, void* context);55 mir_screencast_callback callback, void* context);
5556
=== modified file 'src/client/mir_screencast_api.cpp'
--- src/client/mir_screencast_api.cpp 2014-01-29 09:16:50 +0000
+++ src/client/mir_screencast_api.cpp 2014-02-10 09:00:06 +0000
@@ -64,14 +64,21 @@
6464
65 auto const client_platform = connection->get_client_platform();65 auto const client_platform = connection->get_client_platform();
6666
67 screencast = new MirScreencast{67 std::unique_ptr<MirScreencast> screencast_uptr{
68 find_display_output(*config, parameters->output_id),68 new MirScreencast{
69 connection->display_server(),69 find_display_output(*config, parameters->output_id),
70 client_platform,70 connection->display_server(),
71 client_platform->create_buffer_factory(),71 client_platform,
72 null_callback, nullptr};72 client_platform->create_buffer_factory(),
7373 null_callback, nullptr}};
74 screencast->creation_wait_handle()->wait_for_all();74
75 screencast_uptr->creation_wait_handle()->wait_for_all();
76
77 if (screencast_uptr->valid())
78 {
79 screencast = screencast_uptr.get();
80 screencast_uptr.release();
81 }
75 }82 }
76 catch (std::exception const&)83 catch (std::exception const&)
77 {84 {
7885
=== modified file 'src/client/rpc/mir_socket_rpc_channel.cpp'
--- src/client/rpc/mir_socket_rpc_channel.cpp 2014-01-13 06:12:33 +0000
+++ src/client/rpc/mir_socket_rpc_channel.cpp 2014-02-10 09:00:06 +0000
@@ -143,6 +143,7 @@
143 if (!disconnected.load())143 if (!disconnected.load())
144 {144 {
145 auto surface = dynamic_cast<mir::protobuf::Surface*>(response);145 auto surface = dynamic_cast<mir::protobuf::Surface*>(response);
146 mir::protobuf::Screencast* screencast{nullptr};
146 if (surface)147 if (surface)
147 {148 {
148 surface->clear_fd();149 surface->clear_fd();
@@ -157,12 +158,18 @@
157 rpc_report->file_descriptors_received(*response, fds);158 rpc_report->file_descriptors_received(*response, fds);
158 }159 }
159 }160 }
161 else
162 {
163 screencast = dynamic_cast<mir::protobuf::Screencast*>(response);
164 }
160165
161 auto buffer = dynamic_cast<mir::protobuf::Buffer*>(response);166 auto buffer = dynamic_cast<mir::protobuf::Buffer*>(response);
162 if (!buffer)167 if (!buffer)
163 {168 {
164 if (surface && surface->has_buffer())169 if (surface && surface->has_buffer())
165 buffer = surface->mutable_buffer();170 buffer = surface->mutable_buffer();
171 else if (screencast && screencast->has_buffer())
172 buffer = screencast->mutable_buffer();
166 }173 }
167174
168 if (buffer)175 if (buffer)
169176
=== modified file 'src/platform/graphics/android/android_alloc_adaptor.cpp'
--- src/platform/graphics/android/android_alloc_adaptor.cpp 2014-01-13 06:12:33 +0000
+++ src/platform/graphics/android/android_alloc_adaptor.cpp 2014-02-10 09:00:06 +0000
@@ -69,7 +69,7 @@
69 }69 }
7070
71 AndroidBufferHandleDeleter del1(alloc_dev);71 AndroidBufferHandleDeleter del1(alloc_dev);
72 std::shared_ptr<native_handle_t> handle(buf_handle, del1);72 std::shared_ptr<native_handle_t const> handle(buf_handle, del1);
7373
74 auto ops = std::make_shared<mga::RealSyncFileOps>();74 auto ops = std::make_shared<mga::RealSyncFileOps>();
75 auto fence = std::make_shared<mga::SyncFence>(ops, -1);75 auto fence = std::make_shared<mga::SyncFence>(ops, -1);
7676
=== modified file 'src/platform/graphics/android/android_display.cpp'
--- src/platform/graphics/android/android_display.cpp 2014-01-21 06:27:40 +0000
+++ src/platform/graphics/android/android_display.cpp 2014-02-10 09:00:06 +0000
@@ -52,9 +52,11 @@
52 f(*display_buffer);52 f(*display_buffer);
53}53}
5454
55std::shared_ptr<mg::DisplayConfiguration> mga::AndroidDisplay::configuration()55std::unique_ptr<mg::DisplayConfiguration> mga::AndroidDisplay::configuration() const
56{56{
57 return std::make_shared<mga::AndroidDisplayConfiguration>(current_configuration);57 return std::unique_ptr<mg::DisplayConfiguration>(
58 new mga::AndroidDisplayConfiguration(current_configuration)
59 );
58}60}
5961
60void mga::AndroidDisplay::configure(mg::DisplayConfiguration const& configuration)62void mga::AndroidDisplay::configure(mg::DisplayConfiguration const& configuration)
6163
=== modified file 'src/platform/graphics/android/android_display.h'
--- src/platform/graphics/android/android_display.h 2014-01-13 06:12:33 +0000
+++ src/platform/graphics/android/android_display.h 2014-02-10 09:00:06 +0000
@@ -48,8 +48,8 @@
4848
49 void for_each_display_buffer(std::function<void(graphics::DisplayBuffer&)> const& f);49 void for_each_display_buffer(std::function<void(graphics::DisplayBuffer&)> const& f);
5050
51 std::shared_ptr<DisplayConfiguration> configuration();51 std::unique_ptr<DisplayConfiguration> configuration() const override;
52 void configure(DisplayConfiguration const&);52 void configure(DisplayConfiguration const&) override;
5353
54 void register_configuration_change_handler(54 void register_configuration_change_handler(
55 EventHandlerRegister& handlers,55 EventHandlerRegister& handlers,
5656
=== modified file 'src/platform/graphics/android/android_platform.cpp'
--- src/platform/graphics/android/android_platform.cpp 2014-01-13 06:12:33 +0000
+++ src/platform/graphics/android/android_platform.cpp 2014-02-10 09:00:06 +0000
@@ -107,13 +107,11 @@
107107
108extern "C" std::shared_ptr<mg::Platform> mg::create_platform(std::shared_ptr<mo::Option> const& /*options*/, std::shared_ptr<DisplayReport> const& display_report)108extern "C" std::shared_ptr<mg::Platform> mg::create_platform(std::shared_ptr<mo::Option> const& /*options*/, std::shared_ptr<DisplayReport> const& display_report)
109{109{
110 //todo: could parse an option here
111 auto should_use_fb_fallback = false;
112 auto buffer_initializer = std::make_shared<mg::NullBufferInitializer>();110 auto buffer_initializer = std::make_shared<mg::NullBufferInitializer>();
113 auto display_resource_factory = std::make_shared<mga::ResourceFactory>();111 auto display_resource_factory = std::make_shared<mga::ResourceFactory>();
114 auto fb_allocator = std::make_shared<mga::AndroidGraphicBufferAllocator>(buffer_initializer);112 auto fb_allocator = std::make_shared<mga::AndroidGraphicBufferAllocator>(buffer_initializer);
115 auto display_builder = std::make_shared<mga::OutputBuilder>(113 auto display_builder = std::make_shared<mga::OutputBuilder>(
116 fb_allocator, display_resource_factory, display_report, should_use_fb_fallback);114 fb_allocator, display_resource_factory, display_report);
117 return std::make_shared<mga::AndroidPlatform>(display_builder, display_report);115 return std::make_shared<mga::AndroidPlatform>(display_builder, display_report);
118}116}
119117
120118
=== modified file 'src/platform/graphics/android/display_buffer.h'
--- src/platform/graphics/android/display_buffer.h 2014-01-23 17:26:51 +0000
+++ src/platform/graphics/android/display_buffer.h 2014-02-10 09:00:06 +0000
@@ -61,7 +61,6 @@
61 std::shared_ptr<DisplayDevice> const display_device;61 std::shared_ptr<DisplayDevice> const display_device;
62 std::shared_ptr<ANativeWindow> const native_window;62 std::shared_ptr<ANativeWindow> const native_window;
63 GLContext gl_context;63 GLContext gl_context;
64 bool prepared;
65 MirOrientation rotation;64 MirOrientation rotation;
66};65};
6766
6867
=== modified file 'src/platform/graphics/android/hwc_device.cpp'
--- src/platform/graphics/android/hwc_device.cpp 2014-01-23 18:01:19 +0000
+++ src/platform/graphics/android/hwc_device.cpp 2014-02-10 09:00:06 +0000
@@ -35,10 +35,11 @@
35namespace geom = mir::geometry;35namespace geom = mir::geometry;
3636
37mga::HwcDevice::HwcDevice(std::shared_ptr<hwc_composer_device_1> const& hwc_device,37mga::HwcDevice::HwcDevice(std::shared_ptr<hwc_composer_device_1> const& hwc_device,
38 std::shared_ptr<HWCVsyncCoordinator> const& coordinator)38 std::shared_ptr<HWCVsyncCoordinator> const& coordinator,
39 std::shared_ptr<SyncFileOps> const& sync_ops)
39 : HWCCommonDevice(hwc_device, coordinator),40 : HWCCommonDevice(hwc_device, coordinator),
40 layer_list({mga::ForceGLLayer{}, mga::FramebufferLayer{}}),41 layer_list({mga::ForceGLLayer{}, mga::FramebufferLayer{}}),
41 sync_ops(std::make_shared<mga::RealSyncFileOps>())42 sync_ops(sync_ops)
42{43{
43}44}
4445
@@ -79,12 +80,8 @@
79 BOOST_THROW_EXCEPTION(std::runtime_error("error during hwc set()"));80 BOOST_THROW_EXCEPTION(std::runtime_error("error during hwc set()"));
80 }81 }
8182
82 if (last_display_fence)83 mga::SyncFence retire_fence(sync_ops, displays[HWC_DISPLAY_PRIMARY]->retireFenceFd);
83 last_display_fence->wait();
8484
85 int framebuffer_fence = layer_list.framebuffer_fence();85 int framebuffer_fence = layer_list.framebuffer_fence();
86 native_buffer->update_fence(framebuffer_fence);86 native_buffer->update_fence(framebuffer_fence);
87
88 last_display_fence = std::make_shared<mga::SyncFence>(
89 sync_ops, displays[HWC_DISPLAY_PRIMARY]->retireFenceFd);
90}87}
9188
=== modified file 'src/platform/graphics/android/hwc_device.h'
--- src/platform/graphics/android/hwc_device.h 2014-01-23 18:01:19 +0000
+++ src/platform/graphics/android/hwc_device.h 2014-02-10 09:00:06 +0000
@@ -34,13 +34,13 @@
34{34{
35class HWCVsyncCoordinator;35class HWCVsyncCoordinator;
36class SyncFileOps;36class SyncFileOps;
37class SyncFence;
3837
39class HwcDevice : public HWCCommonDevice38class HwcDevice : public HWCCommonDevice
40{39{
41public:40public:
42 HwcDevice(std::shared_ptr<hwc_composer_device_1> const& hwc_device,41 HwcDevice(std::shared_ptr<hwc_composer_device_1> const& hwc_device,
43 std::shared_ptr<HWCVsyncCoordinator> const& coordinator);42 std::shared_ptr<HWCVsyncCoordinator> const& coordinator,
43 std::shared_ptr<SyncFileOps> const& sync_ops);
4444
45 void prepare_gl();45 void prepare_gl();
46 void prepare_gl_and_overlays(std::list<std::shared_ptr<Renderable>> const& list); 46 void prepare_gl_and_overlays(std::list<std::shared_ptr<Renderable>> const& list);
@@ -50,10 +50,7 @@
50private:50private:
51 LayerList layer_list;51 LayerList layer_list;
5252
53 std::shared_ptr<SyncFence> last_display_fence;
54 std::shared_ptr<SyncFileOps> const sync_ops;53 std::shared_ptr<SyncFileOps> const sync_ops;
55 unsigned int primary_display_config;
56 MirPixelFormat fb_format;
57 static size_t const num_displays{3}; //primary, external, virtual54 static size_t const num_displays{3}; //primary, external, virtual
58};55};
5956
6057
=== modified file 'src/platform/graphics/android/hwc_layers.cpp'
--- src/platform/graphics/android/hwc_layers.cpp 2014-01-24 21:50:21 +0000
+++ src/platform/graphics/android/hwc_layers.cpp 2014-02-10 09:00:06 +0000
@@ -30,14 +30,18 @@
3030
31mga::HWCLayer& mga::HWCLayer::operator=(HWCLayer const& layer)31mga::HWCLayer& mga::HWCLayer::operator=(HWCLayer const& layer)
32{32{
33 memcpy(this, &layer, sizeof(HWCLayer));33 memcpy(static_cast<void*>(this),
34 static_cast<void const*>(&layer),
35 sizeof(HWCLayer));
34 this->visibleRegionScreen = {1, &this->visible_rect};36 this->visibleRegionScreen = {1, &this->visible_rect};
35 return *this;37 return *this;
36}38}
3739
38mga::HWCLayer::HWCLayer(HWCLayer const& layer)40mga::HWCLayer::HWCLayer(HWCLayer const& layer)
39{41{
40 memcpy(this, &layer, sizeof(HWCLayer));42 memcpy(static_cast<void*>(this),
43 static_cast<void const*>(&layer),
44 sizeof(HWCLayer));
41 this->visibleRegionScreen = {1, &this->visible_rect};45 this->visibleRegionScreen = {1, &this->visible_rect};
42}46}
4347
4448
=== modified file 'src/platform/graphics/android/internal_client_window.cpp'
--- src/platform/graphics/android/internal_client_window.cpp 2014-01-13 06:12:33 +0000
+++ src/platform/graphics/android/internal_client_window.cpp 2014-02-10 09:00:06 +0000
@@ -25,6 +25,7 @@
2525
26#include <boost/throw_exception.hpp>26#include <boost/throw_exception.hpp>
27#include <stdexcept>27#include <stdexcept>
28#include <sstream>
2829
29namespace mg=mir::graphics;30namespace mg=mir::graphics;
30namespace mga=mg::android;31namespace mga=mg::android;
@@ -93,7 +94,11 @@
93 case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:94 case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
94 return 1;95 return 1;
95 default:96 default:
96 BOOST_THROW_EXCEPTION(std::runtime_error("driver requests info we dont provide. key: " + key));97 {
98 std::stringstream sstream;
99 sstream << "driver requests info we dont provide. key: " << key;
100 BOOST_THROW_EXCEPTION(std::runtime_error(sstream.str()));
101 }
97 }102 }
98}103}
99104
100105
=== modified file 'src/platform/graphics/android/output_builder.cpp'
--- src/platform/graphics/android/output_builder.cpp 2014-01-21 18:09:35 +0000
+++ src/platform/graphics/android/output_builder.cpp 2014-02-10 09:00:06 +0000
@@ -33,22 +33,18 @@
33mga::OutputBuilder::OutputBuilder(33mga::OutputBuilder::OutputBuilder(
34 std::shared_ptr<mga::GraphicBufferAllocator> const& buffer_allocator,34 std::shared_ptr<mga::GraphicBufferAllocator> const& buffer_allocator,
35 std::shared_ptr<mga::DisplayResourceFactory> const& res_factory,35 std::shared_ptr<mga::DisplayResourceFactory> const& res_factory,
36 std::shared_ptr<mg::DisplayReport> const& display_report,36 std::shared_ptr<mg::DisplayReport> const& display_report)
37 bool should_use_fb_fallback)
38 : buffer_allocator(buffer_allocator),37 : buffer_allocator(buffer_allocator),
39 res_factory(res_factory),38 res_factory(res_factory),
40 display_report(display_report),39 display_report(display_report),
41 force_backup_display(should_use_fb_fallback)40 force_backup_display(false)
42{41{
43 if (!force_backup_display)42 try
44 {43 {
45 try44 hwc_native = res_factory->create_hwc_native_device();
46 {45 } catch (...)
47 hwc_native = res_factory->create_hwc_native_device();46 {
48 } catch (...)47 force_backup_display = true;
49 {
50 force_backup_display = true;
51 }
52 }48 }
5349
54 if (force_backup_display || hwc_native->common.version == HWC_DEVICE_API_VERSION_1_0)50 if (force_backup_display || hwc_native->common.version == HWC_DEVICE_API_VERSION_1_0)
5551
=== modified file 'src/platform/graphics/android/output_builder.h'
--- src/platform/graphics/android/output_builder.h 2014-01-13 06:12:33 +0000
+++ src/platform/graphics/android/output_builder.h 2014-02-10 09:00:06 +0000
@@ -40,8 +40,7 @@
40 OutputBuilder(40 OutputBuilder(
41 std::shared_ptr<GraphicBufferAllocator> const& buffer_allocator,41 std::shared_ptr<GraphicBufferAllocator> const& buffer_allocator,
42 std::shared_ptr<DisplayResourceFactory> const& res_factory,42 std::shared_ptr<DisplayResourceFactory> const& res_factory,
43 std::shared_ptr<DisplayReport> const& display_report,43 std::shared_ptr<DisplayReport> const& display_report);
44 bool should_use_fb_fallback);
4544
46 MirPixelFormat display_format();45 MirPixelFormat display_format();
47 std::shared_ptr<DisplayDevice> create_display_device();46 std::shared_ptr<DisplayDevice> create_display_device();
4847
=== modified file 'src/platform/graphics/android/resource_factory.cpp'
--- src/platform/graphics/android/resource_factory.cpp 2014-01-21 18:09:35 +0000
+++ src/platform/graphics/android/resource_factory.cpp 2014-02-10 09:00:06 +0000
@@ -18,6 +18,7 @@
18 */18 */
1919
20#include "mir/graphics/android/mir_native_window.h"20#include "mir/graphics/android/mir_native_window.h"
21#include "mir/graphics/android/sync_fence.h"
21#include "buffer.h"22#include "buffer.h"
22#include "resource_factory.h"23#include "resource_factory.h"
23#include "fb_device.h"24#include "fb_device.h"
@@ -91,7 +92,8 @@
91 std::shared_ptr<hwc_composer_device_1> const& hwc_native_device) const92 std::shared_ptr<hwc_composer_device_1> const& hwc_native_device) const
92{93{
93 auto syncer = std::make_shared<mga::HWCVsync>();94 auto syncer = std::make_shared<mga::HWCVsync>();
94 return std::make_shared<mga::HwcDevice>(hwc_native_device, syncer);95 auto file_ops = std::make_shared<mga::RealSyncFileOps>();
96 return std::make_shared<mga::HwcDevice>(hwc_native_device, syncer, file_ops);
95}97}
9698
97std::shared_ptr<mga::DisplayDevice> mga::ResourceFactory::create_hwc_fb_device(99std::shared_ptr<mga::DisplayDevice> mga::ResourceFactory::create_hwc_fb_device(
98100
=== modified file 'src/platform/graphics/android/server_render_window.cpp'
--- src/platform/graphics/android/server_render_window.cpp 2014-01-13 06:12:33 +0000
+++ src/platform/graphics/android/server_render_window.cpp 2014-02-10 09:00:06 +0000
@@ -28,6 +28,7 @@
28#include <system/window.h>28#include <system/window.h>
29#include <boost/throw_exception.hpp>29#include <boost/throw_exception.hpp>
30#include <stdexcept>30#include <stdexcept>
31#include <sstream>
3132
32namespace mg=mir::graphics;33namespace mg=mir::graphics;
33namespace mga=mir::graphics::android;34namespace mga=mir::graphics::android;
@@ -81,7 +82,11 @@
81 case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:82 case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
82 return 1;83 return 1;
83 default:84 default:
84 BOOST_THROW_EXCEPTION(std::runtime_error("driver requests info we dont provide. key: " + key));85 {
86 std::stringstream sstream;
87 sstream << "driver requests info we dont provide. key: " << key;
88 BOOST_THROW_EXCEPTION(std::runtime_error(sstream.str()));
89 }
85 }90 }
86}91}
8792
8893
=== modified file 'src/platform/graphics/mesa/display.cpp'
--- src/platform/graphics/mesa/display.cpp 2014-01-22 08:32:55 +0000
+++ src/platform/graphics/mesa/display.cpp 2014-02-10 09:00:06 +0000
@@ -115,13 +115,15 @@
115 f(*db_ptr);115 f(*db_ptr);
116}116}
117117
118std::shared_ptr<mg::DisplayConfiguration> mgm::Display::configuration()118std::unique_ptr<mg::DisplayConfiguration> mgm::Display::configuration() const
119{119{
120 std::lock_guard<std::mutex> lg{configuration_mutex};120 std::lock_guard<std::mutex> lg{configuration_mutex};
121121
122 /* Give back a copy of the latest configuration information */122 /* Give back a copy of the latest configuration information */
123 current_display_configuration.update();123 current_display_configuration.update();
124 return std::make_shared<mgm::RealKMSDisplayConfiguration>(current_display_configuration);124 return std::unique_ptr<mg::DisplayConfiguration>(
125 new mgm::RealKMSDisplayConfiguration(current_display_configuration)
126 );
125}127}
126128
127void mgm::Display::configure(mg::DisplayConfiguration const& conf)129void mgm::Display::configure(mg::DisplayConfiguration const& conf)
128130
=== modified file 'src/platform/graphics/mesa/display.h'
--- src/platform/graphics/mesa/display.h 2014-01-22 08:32:55 +0000
+++ src/platform/graphics/mesa/display.h 2014-02-10 09:00:06 +0000
@@ -62,8 +62,8 @@
62 void for_each_display_buffer(62 void for_each_display_buffer(
63 std::function<void(graphics::DisplayBuffer&)> const& f);63 std::function<void(graphics::DisplayBuffer&)> const& f);
6464
65 std::shared_ptr<DisplayConfiguration> configuration();65 std::unique_ptr<DisplayConfiguration> configuration() const override;
66 void configure(DisplayConfiguration const& conf);66 void configure(DisplayConfiguration const& conf) override;
6767
68 void register_configuration_change_handler(68 void register_configuration_change_handler(
69 EventHandlerRegister& handlers,69 EventHandlerRegister& handlers,
@@ -83,14 +83,14 @@
83private:83private:
84 void clear_connected_unused_outputs();84 void clear_connected_unused_outputs();
8585
86 std::mutex configuration_mutex;86 mutable std::mutex configuration_mutex;
87 std::shared_ptr<Platform> const platform;87 std::shared_ptr<Platform> const platform;
88 std::shared_ptr<DisplayReport> const listener;88 std::shared_ptr<DisplayReport> const listener;
89 mir::udev::Monitor monitor;89 mir::udev::Monitor monitor;
90 helpers::EGLHelper shared_egl;90 helpers::EGLHelper shared_egl;
91 std::vector<std::unique_ptr<DisplayBuffer>> display_buffers;91 std::vector<std::unique_ptr<DisplayBuffer>> display_buffers;
92 RealKMSOutputContainer output_container;92 RealKMSOutputContainer output_container;
93 RealKMSDisplayConfiguration current_display_configuration;93 mutable RealKMSDisplayConfiguration current_display_configuration;
94 std::shared_ptr<Cursor> cursor;94 std::shared_ptr<Cursor> cursor;
95};95};
9696
9797
=== modified file 'src/server/CMakeLists.txt'
--- src/server/CMakeLists.txt 2014-01-22 08:32:55 +0000
+++ src/server/CMakeLists.txt 2014-02-10 09:00:06 +0000
@@ -94,7 +94,7 @@
94 )94 )
95endif()95endif()
9696
97set(MIRSERVER_ABI 14)97set(MIRSERVER_ABI 15)
9898
99set_target_properties(99set_target_properties(
100 mirserver100 mirserver
101101
=== modified file 'src/server/compositor/buffer_bundle.h'
--- src/server/compositor/buffer_bundle.h 2014-01-13 06:12:33 +0000
+++ src/server/compositor/buffer_bundle.h 2014-02-10 09:00:06 +0000
@@ -34,7 +34,7 @@
34{34{
35public:35public:
36 virtual ~BufferBundle() noexcept {}36 virtual ~BufferBundle() noexcept {}
37 virtual graphics::Buffer* client_acquire() = 0;37 virtual void client_acquire(std::function<void(graphics::Buffer* buffer)> complete) = 0;
38 virtual void client_release(graphics::Buffer*) = 0;38 virtual void client_release(graphics::Buffer*) = 0;
39 virtual std::shared_ptr<graphics::Buffer>39 virtual std::shared_ptr<graphics::Buffer>
40 compositor_acquire(unsigned long frameno) = 0;40 compositor_acquire(unsigned long frameno) = 0;
4141
=== modified file 'src/server/compositor/buffer_stream_surfaces.cpp'
--- src/server/compositor/buffer_stream_surfaces.cpp 2014-01-13 06:12:33 +0000
+++ src/server/compositor/buffer_stream_surfaces.cpp 2014-02-10 09:00:06 +0000
@@ -49,13 +49,14 @@
49 return std::make_shared<mc::TemporarySnapshotBuffer>(buffer_bundle);49 return std::make_shared<mc::TemporarySnapshotBuffer>(buffer_bundle);
50}50}
5151
52void mc::BufferStreamSurfaces::swap_client_buffers(mg::Buffer*& buffer)52void mc::BufferStreamSurfaces::swap_client_buffers(graphics::Buffer* old_buffer, std::function<void(graphics::Buffer* new_buffer)> complete)
53{53{
54 if (buffer)54 if (old_buffer)
55 {55 {
56 buffer_bundle->client_release(buffer);56 buffer_bundle->client_release(old_buffer);
57 }57 }
58 buffer = buffer_bundle->client_acquire();58
59 buffer_bundle->client_acquire(complete);
59}60}
6061
61MirPixelFormat mc::BufferStreamSurfaces::get_stream_pixel_format()62MirPixelFormat mc::BufferStreamSurfaces::get_stream_pixel_format()
6263
=== modified file 'src/server/compositor/buffer_stream_surfaces.h'
--- src/server/compositor/buffer_stream_surfaces.h 2014-01-13 06:12:33 +0000
+++ src/server/compositor/buffer_stream_surfaces.h 2014-02-10 09:00:06 +0000
@@ -39,7 +39,7 @@
39 BufferStreamSurfaces(std::shared_ptr<BufferBundle> const& swapper);39 BufferStreamSurfaces(std::shared_ptr<BufferBundle> const& swapper);
40 ~BufferStreamSurfaces();40 ~BufferStreamSurfaces();
4141
42 void swap_client_buffers(graphics::Buffer*& buffer) override;42 void swap_client_buffers(graphics::Buffer* old_buffer, std::function<void(graphics::Buffer* new_buffer)> complete) override;
4343
44 std::shared_ptr<graphics::Buffer>44 std::shared_ptr<graphics::Buffer>
45 lock_compositor_buffer(unsigned long frameno) override;45 lock_compositor_buffer(unsigned long frameno) override;
4646
=== modified file 'src/server/compositor/default_configuration.cpp'
--- src/server/compositor/default_configuration.cpp 2014-01-13 06:12:33 +0000
+++ src/server/compositor/default_configuration.cpp 2014-02-10 09:00:06 +0000
@@ -17,13 +17,17 @@
17 */17 */
1818
19#include "mir/default_server_configuration.h"19#include "mir/default_server_configuration.h"
20#include "mir/frontend/screencast.h"
20#include "buffer_stream_factory.h"21#include "buffer_stream_factory.h"
21#include "default_display_buffer_compositor_factory.h"22#include "default_display_buffer_compositor_factory.h"
22#include "multi_threaded_compositor.h"23#include "multi_threaded_compositor.h"
23#include "gl_renderer_factory.h"24#include "gl_renderer_factory.h"
2425
26#include <boost/throw_exception.hpp>
27
25namespace mc = mir::compositor;28namespace mc = mir::compositor;
26namespace ms = mir::scene;29namespace ms = mir::scene;
30namespace mf = mir::frontend;
2731
28std::shared_ptr<ms::BufferStreamFactory>32std::shared_ptr<ms::BufferStreamFactory>
29mir::DefaultServerConfiguration::the_buffer_stream_factory()33mir::DefaultServerConfiguration::the_buffer_stream_factory()
@@ -67,3 +71,31 @@
67 return std::make_shared<mc::GLRendererFactory>();71 return std::make_shared<mc::GLRendererFactory>();
68 });72 });
69}73}
74
75std::shared_ptr<mf::Screencast> mir::DefaultServerConfiguration::the_screencast()
76{
77 struct NotImplementedScreencast : mf::Screencast
78 {
79 mf::ScreencastSessionId create_session(
80 graphics::DisplayConfigurationOutputId)
81 {
82 BOOST_THROW_EXCEPTION(std::runtime_error("Screencast not implemented"));
83 }
84
85 void destroy_session(mf::ScreencastSessionId)
86 {
87 BOOST_THROW_EXCEPTION(std::runtime_error("Screencast not implemented"));
88 }
89
90 std::shared_ptr<graphics::Buffer> capture(mf::ScreencastSessionId)
91 {
92 BOOST_THROW_EXCEPTION(std::runtime_error("Screencast not implemented"));
93 }
94 };
95
96 return screencast(
97 [this]()
98 {
99 return std::make_shared<NotImplementedScreencast>();
100 });
101}
70102
=== modified file 'src/server/compositor/switching_bundle.cpp'
--- src/server/compositor/switching_bundle.cpp 2014-01-23 18:42:20 +0000
+++ src/server/compositor/switching_bundle.cpp 2014-02-10 09:00:06 +0000
@@ -177,7 +177,7 @@
177 return ring[slot].buf;177 return ring[slot].buf;
178}178}
179179
180mg::Buffer* mc::SwitchingBundle::client_acquire()180void mc::SwitchingBundle::client_acquire(std::function<void(graphics::Buffer* buffer)> complete)
181{181{
182 std::unique_lock<std::mutex> lock(guard);182 std::unique_lock<std::mutex> lock(guard);
183183
@@ -247,7 +247,7 @@
247 ring[client].buf = ret;247 ring[client].buf = ret;
248 }248 }
249249
250 return ret.get();250 complete(ret.get());
251}251}
252252
253void mc::SwitchingBundle::client_release(graphics::Buffer* released_buffer)253void mc::SwitchingBundle::client_release(graphics::Buffer* released_buffer)
254254
=== modified file 'src/server/compositor/switching_bundle.h'
--- src/server/compositor/switching_bundle.h 2014-01-23 18:42:20 +0000
+++ src/server/compositor/switching_bundle.h 2014-02-10 09:00:06 +0000
@@ -49,7 +49,7 @@
4949
50 graphics::BufferProperties properties() const;50 graphics::BufferProperties properties() const;
5151
52 graphics::Buffer* client_acquire();52 void client_acquire(std::function<void(graphics::Buffer* buffer)> complete) override;
53 void client_release(graphics::Buffer* buffer);53 void client_release(graphics::Buffer* buffer);
54 std::shared_ptr<graphics::Buffer>54 std::shared_ptr<graphics::Buffer>
55 compositor_acquire(unsigned long frameno) override;55 compositor_acquire(unsigned long frameno) override;
5656
=== modified file 'src/server/display_server.cpp'
--- src/server/display_server.cpp 2013-10-16 07:34:22 +0000
+++ src/server/display_server.cpp 2014-02-10 09:00:06 +0000
@@ -27,6 +27,7 @@
27#include "mir/compositor/compositor.h"27#include "mir/compositor/compositor.h"
28#include "mir/frontend/connector.h"28#include "mir/frontend/connector.h"
29#include "mir/graphics/display.h"29#include "mir/graphics/display.h"
30#include "mir/graphics/display_configuration.h"
30#include "mir/input/input_manager.h"31#include "mir/input/input_manager.h"
3132
32#include <stdexcept>33#include <stdexcept>
@@ -134,7 +135,8 @@
134135
135 if (configure_display_on_resume)136 if (configure_display_on_resume)
136 {137 {
137 auto conf = display->configuration();138 std::shared_ptr<graphics::DisplayConfiguration> conf =
139 display->configuration();
138 display_changer->configure_for_hardware_change(140 display_changer->configure_for_hardware_change(
139 conf, DisplayChanger::RetainSystemState);141 conf, DisplayChanger::RetainSystemState);
140 configure_display_on_resume = false;142 configure_display_on_resume = false;
@@ -162,7 +164,8 @@
162 {164 {
163 if (!paused)165 if (!paused)
164 {166 {
165 auto conf = display->configuration();167 std::shared_ptr<graphics::DisplayConfiguration> conf =
168 display->configuration();
166 display_changer->configure_for_hardware_change(169 display_changer->configure_for_hardware_change(
167 conf, DisplayChanger::PauseResumeSystem);170 conf, DisplayChanger::PauseResumeSystem);
168 }171 }
169172
=== modified file 'src/server/frontend/default_configuration.cpp'
--- src/server/frontend/default_configuration.cpp 2014-01-29 12:51:30 +0000
+++ src/server/frontend/default_configuration.cpp 2014-02-10 09:00:06 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright © 2012 Canonical Ltd.2 * Copyright © 2012-2014 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * 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,5 * under the terms of the GNU General Public License version 3,
@@ -42,13 +42,15 @@
42 std::shared_ptr<mf::SessionMediatorReport> const& sm_report,42 std::shared_ptr<mf::SessionMediatorReport> const& sm_report,
43 std::shared_ptr<mg::Platform> const& graphics_platform,43 std::shared_ptr<mg::Platform> const& graphics_platform,
44 std::shared_ptr<mf::DisplayChanger> const& display_changer,44 std::shared_ptr<mf::DisplayChanger> const& display_changer,
45 std::shared_ptr<mg::GraphicBufferAllocator> const& buffer_allocator) :45 std::shared_ptr<mg::GraphicBufferAllocator> const& buffer_allocator,
46 std::shared_ptr<mf::Screencast> const& screencast) :
46 shell(shell),47 shell(shell),
47 sm_report(sm_report),48 sm_report(sm_report),
48 cache(std::make_shared<mf::ResourceCache>()),49 cache(std::make_shared<mf::ResourceCache>()),
49 graphics_platform(graphics_platform),50 graphics_platform(graphics_platform),
50 display_changer(display_changer),51 display_changer(display_changer),
51 buffer_allocator(buffer_allocator)52 buffer_allocator(buffer_allocator),
53 screencast(screencast)
52 {54 {
53 }55 }
5456
@@ -59,9 +61,12 @@
59 std::shared_ptr<mg::Platform> const graphics_platform;61 std::shared_ptr<mg::Platform> const graphics_platform;
60 std::shared_ptr<mf::DisplayChanger> const display_changer;62 std::shared_ptr<mf::DisplayChanger> const display_changer;
61 std::shared_ptr<mg::GraphicBufferAllocator> const buffer_allocator;63 std::shared_ptr<mg::GraphicBufferAllocator> const buffer_allocator;
64 std::shared_ptr<mf::Screencast> const screencast;
6265
63 virtual std::shared_ptr<mir::protobuf::DisplayServer> make_ipc_server(66 virtual std::shared_ptr<mir::protobuf::DisplayServer> make_ipc_server(
64 std::shared_ptr<mf::EventSink> const& sink, bool authorized_to_resize_display)67 pid_t client_pid,
68 std::shared_ptr<mf::EventSink> const& sink,
69 bool authorized_to_resize_display) override
65 {70 {
66 std::shared_ptr<mf::DisplayChanger> changer;71 std::shared_ptr<mf::DisplayChanger> changer;
67 if(authorized_to_resize_display)72 if(authorized_to_resize_display)
@@ -74,13 +79,15 @@
74 }79 }
7580
76 return std::make_shared<mf::SessionMediator>(81 return std::make_shared<mf::SessionMediator>(
82 client_pid,
77 shell,83 shell,
78 graphics_platform,84 graphics_platform,
79 changer,85 changer,
80 buffer_allocator->supported_pixel_formats(),86 buffer_allocator->supported_pixel_formats(),
81 sm_report,87 sm_report,
82 sink,88 sink,
83 resource_cache());89 resource_cache(),
90 screencast);
84 }91 }
8592
86 virtual std::shared_ptr<mf::ResourceCache> resource_cache()93 virtual std::shared_ptr<mf::ResourceCache> resource_cache()
@@ -144,6 +151,8 @@
144 shell,151 shell,
145 the_session_mediator_report(),152 the_session_mediator_report(),
146 the_graphics_platform(),153 the_graphics_platform(),
147 the_frontend_display_changer(), allocator);154 the_frontend_display_changer(),
155 allocator,
156 the_screencast());
148 });157 });
149}158}
150159
=== modified file 'src/server/frontend/protobuf_ipc_factory.h'
--- src/server/frontend/protobuf_ipc_factory.h 2014-01-21 06:27:40 +0000
+++ src/server/frontend/protobuf_ipc_factory.h 2014-02-10 09:00:06 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright © 2012 Canonical Ltd.2 * Copyright © 2012-2014 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * 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,5 * under the terms of the GNU General Public License version 3,
@@ -19,6 +19,8 @@
19#ifndef MIR_FRONTEND_PROTOBUF_IPC_FACTORY_H_19#ifndef MIR_FRONTEND_PROTOBUF_IPC_FACTORY_H_
20#define MIR_FRONTEND_PROTOBUF_IPC_FACTORY_H_20#define MIR_FRONTEND_PROTOBUF_IPC_FACTORY_H_
2121
22#include <sys/types.h>
23
22#include <memory>24#include <memory>
2325
24namespace mir26namespace mir
@@ -37,7 +39,10 @@
37{39{
38public:40public:
39 virtual std::shared_ptr<protobuf::DisplayServer> make_ipc_server(41 virtual std::shared_ptr<protobuf::DisplayServer> make_ipc_server(
40 std::shared_ptr<EventSink> const& sink, bool authorized_to_resize_display) = 0;42 pid_t client_pid,
43 std::shared_ptr<EventSink> const& sink,
44 bool authorized_to_resize_display) = 0;
45
41 virtual std::shared_ptr<ResourceCache> resource_cache() = 0;46 virtual std::shared_ptr<ResourceCache> resource_cache() = 0;
4247
43protected:48protected:
4449
=== modified file 'src/server/frontend/protobuf_message_processor.cpp'
--- src/server/frontend/protobuf_message_processor.cpp 2014-01-28 09:06:46 +0000
+++ src/server/frontend/protobuf_message_processor.cpp 2014-02-10 09:00:06 +0000
@@ -21,6 +21,8 @@
21#include "mir/frontend/protobuf_message_sender.h"21#include "mir/frontend/protobuf_message_sender.h"
22#include "mir/frontend/template_protobuf_message_processor.h"22#include "mir/frontend/template_protobuf_message_processor.h"
2323
24#include "mir_protobuf_wire.pb.h"
25
24namespace mfd = mir::frontend::detail;26namespace mfd = mir::frontend::detail;
2527
26namespace28namespace
@@ -54,11 +56,70 @@
54template<> struct result_ptr_t<::mir::protobuf::Buffer> { typedef ::mir::protobuf::Buffer* type; };56template<> struct result_ptr_t<::mir::protobuf::Buffer> { typedef ::mir::protobuf::Buffer* type; };
55template<> struct result_ptr_t<::mir::protobuf::Connection> { typedef ::mir::protobuf::Connection* type; };57template<> struct result_ptr_t<::mir::protobuf::Connection> { typedef ::mir::protobuf::Connection* type; };
56template<> struct result_ptr_t<::mir::protobuf::Surface> { typedef ::mir::protobuf::Surface* type; };58template<> struct result_ptr_t<::mir::protobuf::Surface> { typedef ::mir::protobuf::Surface* type; };
57}59template<> struct result_ptr_t<::mir::protobuf::Screencast> { typedef ::mir::protobuf::Screencast* type; };
58}60
59}61template<>
6062void invoke(
61bool mfd::ProtobufMessageProcessor::dispatch(mir::protobuf::wire::Invocation const& invocation)63 ProtobufMessageProcessor* self,
64 protobuf::DisplayServer* server,
65 void (protobuf::DisplayServer::*function)(
66 ::google::protobuf::RpcController* controller,
67 const protobuf::SurfaceId* request,
68 protobuf::Buffer* response,
69 ::google::protobuf::Closure* done),
70 Invocation const& invocation)
71{
72 protobuf::SurfaceId parameter_message;
73 parameter_message.ParseFromString(invocation.parameters());
74 auto const result_message = std::make_shared<protobuf::Buffer>();
75
76 auto const callback =
77 google::protobuf::NewCallback<
78 ProtobufMessageProcessor,
79 ::google::protobuf::uint32,
80 std::shared_ptr<protobuf::Buffer>>(
81 self,
82 &ProtobufMessageProcessor::send_response,
83 invocation.id(),
84 result_message);
85
86 try
87 {
88 (server->*function)(
89 0,
90 &parameter_message,
91 result_message.get(),
92 callback);
93 }
94 catch (std::exception const& x)
95 {
96 delete callback;
97 result_message->set_error(boost::diagnostic_information(x));
98 self->send_response(invocation.id(), result_message);
99 }
100}
101}
102}
103}
104
105
106const std::string& mfd::Invocation::method_name() const
107{
108 return invocation.method_name();
109}
110
111const std::string& mfd::Invocation::parameters() const
112{
113 return invocation.parameters();
114}
115
116google::protobuf::uint32 mfd::Invocation::id() const
117{
118 return invocation.id();
119}
120
121
122bool mfd::ProtobufMessageProcessor::dispatch(Invocation const& invocation)
62{123{
63 report->received_invocation(display_server.get(), invocation.id(), invocation.method_name());124 report->received_invocation(display_server.get(), invocation.id(), invocation.method_name());
64125
@@ -145,6 +206,11 @@
145 sender->send_response(id, response, {fd});206 sender->send_response(id, response, {fd});
146}207}
147208
209void mfd::ProtobufMessageProcessor::send_response(::google::protobuf::uint32 id, std::shared_ptr<protobuf::Buffer> response)
210{
211 send_response(id, response.get());
212}
213
148void mfd::ProtobufMessageProcessor::send_response(::google::protobuf::uint32 id, mir::protobuf::Connection* response)214void mfd::ProtobufMessageProcessor::send_response(::google::protobuf::uint32 id, mir::protobuf::Connection* response)
149{215{
150 const auto& fd = response->has_platform() ?216 const auto& fd = response->has_platform() ?
@@ -163,3 +229,13 @@
163229
164 sender->send_response(id, response, {surface_fd, buffer_fd});230 sender->send_response(id, response, {surface_fd, buffer_fd});
165}231}
232
233void mfd::ProtobufMessageProcessor::send_response(
234 ::google::protobuf::uint32 id, mir::protobuf::Screencast* response)
235{
236 auto const& buffer_fd = response->has_buffer() ?
237 extract_fds_from(response->mutable_buffer()) :
238 std::vector<int32_t>();
239
240 sender->send_response(id, response, {buffer_fd});
241}
166242
=== modified file 'src/server/frontend/protobuf_message_processor.h'
--- src/server/frontend/protobuf_message_processor.h 2014-01-22 15:54:11 +0000
+++ src/server/frontend/protobuf_message_processor.h 2014-02-10 09:00:06 +0000
@@ -52,9 +52,11 @@
52 void send_response(::google::protobuf::uint32 id, protobuf::Buffer* response);52 void send_response(::google::protobuf::uint32 id, protobuf::Buffer* response);
53 void send_response(::google::protobuf::uint32 id, protobuf::Connection* response);53 void send_response(::google::protobuf::uint32 id, protobuf::Connection* response);
54 void send_response(::google::protobuf::uint32 id, protobuf::Surface* response);54 void send_response(::google::protobuf::uint32 id, protobuf::Surface* response);
55 void send_response(::google::protobuf::uint32 id, std::shared_ptr<protobuf::Buffer> response);
56 void send_response(::google::protobuf::uint32 id, mir::protobuf::Screencast* response);
5557
56private:58private:
57 bool dispatch(mir::protobuf::wire::Invocation const& invocation);59 bool dispatch(Invocation const& invocation);
5860
59 std::shared_ptr<ProtobufMessageSender> const sender;61 std::shared_ptr<ProtobufMessageSender> const sender;
60 std::shared_ptr<protobuf::DisplayServer> const display_server;62 std::shared_ptr<protobuf::DisplayServer> const display_server;
6163
=== modified file 'src/server/frontend/protobuf_session_creator.cpp'
--- src/server/frontend/protobuf_session_creator.cpp 2014-01-22 15:54:11 +0000
+++ src/server/frontend/protobuf_session_creator.cpp 2014-02-10 09:00:06 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright © 2013 Canonical Ltd.2 * Copyright © 2013-2014 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * 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,5 * under the terms of the GNU General Public License version 3,
@@ -69,7 +69,7 @@
69 auto const event_sink = std::make_shared<detail::EventSender>(messenger);69 auto const event_sink = std::make_shared<detail::EventSender>(messenger);
70 auto const msg_processor = create_processor(70 auto const msg_processor = create_processor(
71 message_sender,71 message_sender,
72 ipc_factory->make_ipc_server(event_sink, authorized_to_resize_display),72 ipc_factory->make_ipc_server(client_pid, event_sink, authorized_to_resize_display),
73 report);73 report);
7474
75 const auto& session = std::make_shared<mfd::SocketSession>(messenger, next_id(), connected_sessions, msg_processor);75 const auto& session = std::make_shared<mfd::SocketSession>(messenger, next_id(), connected_sessions, msg_processor);
7676
=== modified file 'src/server/frontend/session_mediator.cpp'
--- src/server/frontend/session_mediator.cpp 2014-01-13 06:12:33 +0000
+++ src/server/frontend/session_mediator.cpp 2014-02-10 09:00:06 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright © 2012 Canonical Ltd.2 * Copyright © 2012-2014 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * 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,5 * under the terms of the GNU General Public License version 3,
@@ -38,6 +38,7 @@
38#include "mir/graphics/platform_ipc_package.h"38#include "mir/graphics/platform_ipc_package.h"
39#include "mir/frontend/client_constants.h"39#include "mir/frontend/client_constants.h"
40#include "mir/frontend/event_sink.h"40#include "mir/frontend/event_sink.h"
41#include "mir/frontend/screencast.h"
4142
42#include "mir/geometry/rectangles.h"43#include "mir/geometry/rectangles.h"
43#include "client_buffer_tracker.h"44#include "client_buffer_tracker.h"
@@ -55,20 +56,24 @@
55namespace geom = mir::geometry;56namespace geom = mir::geometry;
5657
57mf::SessionMediator::SessionMediator(58mf::SessionMediator::SessionMediator(
59 pid_t client_pid,
58 std::shared_ptr<frontend::Shell> const& shell,60 std::shared_ptr<frontend::Shell> const& shell,
59 std::shared_ptr<graphics::Platform> const & graphics_platform,61 std::shared_ptr<graphics::Platform> const & graphics_platform,
60 std::shared_ptr<mf::DisplayChanger> const& display_changer,62 std::shared_ptr<mf::DisplayChanger> const& display_changer,
61 std::vector<MirPixelFormat> const& surface_pixel_formats,63 std::vector<MirPixelFormat> const& surface_pixel_formats,
62 std::shared_ptr<SessionMediatorReport> const& report,64 std::shared_ptr<SessionMediatorReport> const& report,
63 std::shared_ptr<EventSink> const& sender,65 std::shared_ptr<EventSink> const& sender,
64 std::shared_ptr<ResourceCache> const& resource_cache) :66 std::shared_ptr<ResourceCache> const& resource_cache,
67 std::shared_ptr<Screencast> const& screencast) :
68 client_pid(client_pid),
65 shell(shell),69 shell(shell),
66 graphics_platform(graphics_platform),70 graphics_platform(graphics_platform),
67 surface_pixel_formats(surface_pixel_formats),71 surface_pixel_formats(surface_pixel_formats),
68 display_changer(display_changer),72 display_changer(display_changer),
69 report(report),73 report(report),
70 event_sink(sender),74 event_sink(sender),
71 resource_cache(resource_cache)75 resource_cache(resource_cache),
76 screencast(screencast)
72{77{
73}78}
7479
@@ -92,7 +97,7 @@
9297
93 {98 {
94 std::unique_lock<std::mutex> lock(session_mutex);99 std::unique_lock<std::mutex> lock(session_mutex);
95 weak_session = shell->open_session(request->application_name(), event_sink);100 weak_session = shell->open_session(client_pid, request->application_name(), event_sink);
96 }101 }
97102
98 auto ipc_package = graphics_platform->get_ipc_package();103 auto ipc_package = graphics_platform->get_ipc_package();
@@ -116,19 +121,25 @@
116 done->Run();121 done->Run();
117}122}
118123
119std::tuple<mg::Buffer*, bool>124void mf::SessionMediator::advance_buffer(
120mf::SessionMediator::advance_buffer(SurfaceId surf_id, Surface& surface)125 SurfaceId surf_id,
126 Surface& surface,
127 std::function<void(graphics::Buffer*, bool)> complete)
121{128{
122 auto& tracker = client_buffer_tracker[surf_id];129 auto& tracker = client_buffer_tracker[surf_id];
123 if (!tracker) tracker = std::make_shared<ClientBufferTracker>(client_buffer_cache_size);130 if (!tracker) tracker = std::make_shared<ClientBufferTracker>(client_buffer_cache_size);
124131
125 auto& client_buffer = client_buffer_resource[surf_id];132 auto& client_buffer = client_buffer_resource[surf_id];
126 surface.swap_buffers(client_buffer);133 surface.swap_buffers(client_buffer,
127 auto id = client_buffer->id();134 [&tracker, &client_buffer, complete](mg::Buffer* new_buffer)
128 auto need_full_ipc = !tracker->client_has(id);135 {
129 tracker->add(id);136 client_buffer = new_buffer;
137 auto id = client_buffer->id();
138 auto need_full_ipc = !tracker->client_has(id);
139 tracker->add(id);
130140
131 return std::tie(client_buffer, need_full_ipc);141 complete(client_buffer, need_full_ipc);
142 });
132}143}
133144
134145
@@ -138,49 +149,48 @@
138 mir::protobuf::Surface* response,149 mir::protobuf::Surface* response,
139 google::protobuf::Closure* done)150 google::protobuf::Closure* done)
140{151{
141 bool need_full_ipc;152
142 graphics::Buffer* client_buffer{nullptr};153 auto const lock = std::make_shared<std::unique_lock<std::mutex>>(session_mutex);
143 std::shared_ptr<Session> session;154
144155 auto const session = weak_session.lock();
145 {156
146 std::unique_lock<std::mutex> lock(session_mutex);157 if (session.get() == nullptr)
147158 BOOST_THROW_EXCEPTION(std::logic_error("Invalid application session"));
148 session = weak_session.lock();159
149160 report->session_create_surface_called(session->name());
150 if (session.get() == nullptr)161
151 BOOST_THROW_EXCEPTION(std::logic_error("Invalid application session"));162 auto const surf_id = session->create_surface(msh::SurfaceCreationParameters()
152163 .of_name(request->surface_name())
153 report->session_create_surface_called(session->name());164 .of_size(request->width(), request->height())
154165 .of_buffer_usage(static_cast<graphics::BufferUsage>(request->buffer_usage()))
155 auto const surf_id = session->create_surface(msh::SurfaceCreationParameters()166 .of_pixel_format(static_cast<MirPixelFormat>(request->pixel_format()))
156 .of_name(request->surface_name())167 .with_output_id(graphics::DisplayConfigurationOutputId(request->output_id())));
157 .of_size(request->width(), request->height())168
158 .of_buffer_usage(static_cast<graphics::BufferUsage>(request->buffer_usage()))169 auto surface = session->get_surface(surf_id);
159 .of_pixel_format(static_cast<MirPixelFormat>(request->pixel_format()))170 response->mutable_id()->set_value(surf_id.as_value());
160 .with_output_id(graphics::DisplayConfigurationOutputId(request->output_id())));171 response->set_width(surface->size().width.as_uint32_t());
161172 response->set_height(surface->size().height.as_uint32_t());
162 auto surface = session->get_surface(surf_id);173 response->set_pixel_format((int)surface->pixel_format());
163 response->mutable_id()->set_value(surf_id.as_value());174 response->set_buffer_usage(request->buffer_usage());
164 response->set_width(surface->size().width.as_uint32_t());175
165 response->set_height(surface->size().height.as_uint32_t());176 if (surface->supports_input())
166 response->set_pixel_format((int)surface->pixel_format());177 response->add_fd(surface->client_input_fd());
167 response->set_buffer_usage(request->buffer_usage());178
168179 advance_buffer(surf_id, *surface,
169 if (surface->supports_input())180 [lock, this, response, done, session](graphics::Buffer* client_buffer, bool need_full_ipc)
170 response->add_fd(surface->client_input_fd());181 {
171182 lock->unlock();
172 std::tie(client_buffer, need_full_ipc) = advance_buffer(surf_id, *surface);183
173 }184 auto buffer = response->mutable_buffer();
174185 pack_protobuf_buffer(*buffer, client_buffer, need_full_ipc);
175 auto buffer = response->mutable_buffer();186
176 pack_protobuf_buffer(*buffer, client_buffer, need_full_ipc);187 // TODO: NOTE: We use the ordering here to ensure the shell acts on the surface after the surface ID is sent over the wire.
177188 // This guarantees that notifications such as, gained focus, etc, can be correctly interpreted by the client.
178 // TODO: NOTE: We use the ordering here to ensure the shell acts on the surface after the surface ID is sent over the wire.189 // To achieve this order we rely on done->Run() sending messages synchronously. As documented in mfd::SocketMessenger::send.
179 // This guarantees that notifications such as, gained focus, etc, can be correctly interpreted by the client.190 // this will require additional synchronization if mfd::SocketMessenger::send changes.
180 // To achieve this order we rely on done->Run() sending messages synchronously. As documented in mfd::SocketMessenger::send.191 done->Run();
181 // this will require additional synchronization if mfd::SocketMessenger::send changes.192 shell->handle_surface_created(session);
182 done->Run();193 });
183 shell->handle_surface_created(session);
184}194}
185195
186void mf::SessionMediator::next_buffer(196void mf::SessionMediator::next_buffer(
@@ -189,34 +199,34 @@
189 ::mir::protobuf::Buffer* response,199 ::mir::protobuf::Buffer* response,
190 ::google::protobuf::Closure* done)200 ::google::protobuf::Closure* done)
191{201{
192 bool need_full_ipc;
193 SurfaceId const surf_id{request->value()};202 SurfaceId const surf_id{request->value()};
194 graphics::Buffer* client_buffer{nullptr};203
195204 auto const lock = std::make_shared<std::unique_lock<std::mutex>>(session_mutex);
196 {205
197 std::unique_lock<std::mutex> lock(session_mutex);206 auto const session = weak_session.lock();
198207
199 auto session = weak_session.lock();208 if (session.get() == nullptr)
200209 BOOST_THROW_EXCEPTION(std::logic_error("Invalid application session"));
201 if (session.get() == nullptr)210
202 BOOST_THROW_EXCEPTION(std::logic_error("Invalid application session"));211 report->session_next_buffer_called(session->name());
203212
204 report->session_next_buffer_called(session->name());213 // We ensure the client has not powered down the outputs, so that
205214 // swap_buffer will not block indefinitely, leaving the client
206 // We ensure the client has not powered down the outputs, so that215 // in a position where it can not turn back on the
207 // swap_buffer will not block indefinitely, leaving the client216 // outputs.
208 // in a position where it can not turn back on the217 display_changer->ensure_display_powered(session);
209 // outputs.218
210 display_changer->ensure_display_powered(session);219 auto surface = session->get_surface(surf_id);
211220
212 auto surface = session->get_surface(surf_id);221 advance_buffer(surf_id, *surface,
213222 [lock, this, response, done, session](graphics::Buffer* client_buffer, bool need_full_ipc)
214 std::tie(client_buffer, need_full_ipc) = advance_buffer(surf_id, *surface);223 {
215 }224 lock->unlock();
216225
217 pack_protobuf_buffer(*response, client_buffer, need_full_ipc);226 pack_protobuf_buffer(*response, client_buffer, need_full_ipc);
218227
219 done->Run();228 done->Run();
229 });
220}230}
221231
222void mf::SessionMediator::release_surface(232void mf::SessionMediator::release_surface(
@@ -340,6 +350,59 @@
340 done->Run();350 done->Run();
341}351}
342352
353void mf::SessionMediator::create_screencast(
354 google::protobuf::RpcController*,
355 const mir::protobuf::ScreencastParameters* parameters,
356 mir::protobuf::Screencast* protobuf_screencast,
357 google::protobuf::Closure* done)
358{
359 static bool const need_full_ipc{true};
360 mg::DisplayConfigurationOutputId const output_id{
361 static_cast<int>(parameters->output_id())};
362
363 auto screencast_session_id = screencast->create_session(output_id);
364 auto buffer = screencast->capture(screencast_session_id);
365
366 protobuf_screencast->mutable_screencast_id()->set_value(
367 screencast_session_id.as_value());
368 pack_protobuf_buffer(*protobuf_screencast->mutable_buffer(),
369 buffer.get(),
370 need_full_ipc);
371
372 done->Run();
373}
374
375void mf::SessionMediator::release_screencast(
376 google::protobuf::RpcController*,
377 const mir::protobuf::ScreencastId* protobuf_screencast_id,
378 mir::protobuf::Void*,
379 google::protobuf::Closure* done)
380{
381 ScreencastSessionId const screencast_session_id{
382 protobuf_screencast_id->value()};
383 screencast->destroy_session(screencast_session_id);
384 done->Run();
385}
386
387void mf::SessionMediator::screencast_buffer(
388 google::protobuf::RpcController*,
389 const mir::protobuf::ScreencastId* protobuf_screencast_id,
390 mir::protobuf::Buffer* protobuf_buffer,
391 google::protobuf::Closure* done)
392{
393 static bool const does_not_need_full_ipc{false};
394 ScreencastSessionId const screencast_session_id{
395 protobuf_screencast_id->value()};
396
397 auto buffer = screencast->capture(screencast_session_id);
398
399 pack_protobuf_buffer(*protobuf_buffer,
400 buffer.get(),
401 does_not_need_full_ipc);
402
403 done->Run();
404}
405
343void mf::SessionMediator::pack_protobuf_buffer(406void mf::SessionMediator::pack_protobuf_buffer(
344 protobuf::Buffer& protobuf_buffer,407 protobuf::Buffer& protobuf_buffer,
345 graphics::Buffer* graphics_buffer,408 graphics::Buffer* graphics_buffer,
346409
=== modified file 'src/server/frontend/session_mediator.h'
--- src/server/frontend/session_mediator.h 2014-01-13 06:12:33 +0000
+++ src/server/frontend/session_mediator.h 2014-02-10 09:00:06 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright © 2012 Canonical Ltd.2 * Copyright © 2012-2014 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * 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,5 * under the terms of the GNU General Public License version 3,
@@ -24,6 +24,7 @@
24#include "mir/frontend/surface_id.h"24#include "mir/frontend/surface_id.h"
25#include "mir_toolkit/common.h"25#include "mir_toolkit/common.h"
2626
27#include <functional>
27#include <unordered_map>28#include <unordered_map>
28#include <memory>29#include <memory>
29#include <mutex>30#include <mutex>
@@ -52,19 +53,22 @@
52class SessionMediatorReport;53class SessionMediatorReport;
53class EventSink;54class EventSink;
54class DisplayChanger;55class DisplayChanger;
56class Screencast;
5557
56// SessionMediator relays requests from the client process into the server.58// SessionMediator relays requests from the client process into the server.
57class SessionMediator : public mir::protobuf::DisplayServer59class SessionMediator : public mir::protobuf::DisplayServer
58{60{
59public:61public:
60 SessionMediator(62 SessionMediator(
63 pid_t client_pid,
61 std::shared_ptr<Shell> const& shell,64 std::shared_ptr<Shell> const& shell,
62 std::shared_ptr<graphics::Platform> const& graphics_platform,65 std::shared_ptr<graphics::Platform> const& graphics_platform,
63 std::shared_ptr<frontend::DisplayChanger> const& display_changer,66 std::shared_ptr<frontend::DisplayChanger> const& display_changer,
64 std::vector<MirPixelFormat> const& surface_pixel_formats,67 std::vector<MirPixelFormat> const& surface_pixel_formats,
65 std::shared_ptr<SessionMediatorReport> const& report,68 std::shared_ptr<SessionMediatorReport> const& report,
66 std::shared_ptr<EventSink> const& event_sink,69 std::shared_ptr<EventSink> const& event_sink,
67 std::shared_ptr<ResourceCache> const& resource_cache);70 std::shared_ptr<ResourceCache> const& resource_cache,
71 std::shared_ptr<Screencast> const& screencast);
6872
69 ~SessionMediator() noexcept;73 ~SessionMediator() noexcept;
7074
@@ -105,6 +109,21 @@
105 ::mir::protobuf::DisplayConfiguration* response,109 ::mir::protobuf::DisplayConfiguration* response,
106 ::google::protobuf::Closure* done) override;110 ::google::protobuf::Closure* done) override;
107111
112 void create_screencast(google::protobuf::RpcController*,
113 const mir::protobuf::ScreencastParameters*,
114 mir::protobuf::Screencast*,
115 google::protobuf::Closure* done);
116
117 void release_screencast(google::protobuf::RpcController*,
118 const mir::protobuf::ScreencastId*,
119 mir::protobuf::Void*,
120 google::protobuf::Closure* done);
121
122 void screencast_buffer(google::protobuf::RpcController*,
123 const mir::protobuf::ScreencastId*,
124 mir::protobuf::Buffer*,
125 google::protobuf::Closure* done);
126
108 /* Platform specific requests */127 /* Platform specific requests */
109 void drm_auth_magic(google::protobuf::RpcController* controller,128 void drm_auth_magic(google::protobuf::RpcController* controller,
110 const mir::protobuf::DRMMagic* request,129 const mir::protobuf::DRMMagic* request,
@@ -116,7 +135,8 @@
116 graphics::Buffer* graphics_buffer,135 graphics::Buffer* graphics_buffer,
117 bool need_full_ipc);136 bool need_full_ipc);
118137
119 std::tuple<graphics::Buffer*, bool> advance_buffer(SurfaceId surf_id, Surface& surface);138 void advance_buffer(SurfaceId surf_id, Surface& surface, std::function<void(graphics::Buffer*, bool)> complete);
139 pid_t client_pid;
120 std::shared_ptr<Shell> const shell;140 std::shared_ptr<Shell> const shell;
121 std::shared_ptr<graphics::Platform> const graphics_platform;141 std::shared_ptr<graphics::Platform> const graphics_platform;
122142
@@ -126,6 +146,7 @@
126 std::shared_ptr<SessionMediatorReport> const report;146 std::shared_ptr<SessionMediatorReport> const report;
127 std::shared_ptr<EventSink> const event_sink;147 std::shared_ptr<EventSink> const event_sink;
128 std::shared_ptr<ResourceCache> const resource_cache;148 std::shared_ptr<ResourceCache> const resource_cache;
149 std::shared_ptr<Screencast> const screencast;
129150
130 std::unordered_map<SurfaceId,graphics::Buffer*> client_buffer_resource;151 std::unordered_map<SurfaceId,graphics::Buffer*> client_buffer_resource;
131 std::unordered_map<SurfaceId, std::shared_ptr<ClientBufferTracker>> client_buffer_tracker;152 std::unordered_map<SurfaceId, std::shared_ptr<ClientBufferTracker>> client_buffer_tracker;
132153
=== modified file 'src/server/frontend/surface.cpp'
--- src/server/frontend/surface.cpp 2014-01-13 06:12:33 +0000
+++ src/server/frontend/surface.cpp 2014-02-10 09:00:06 +0000
@@ -25,6 +25,10 @@
2525
26#include "client_buffer_tracker.h"26#include "client_buffer_tracker.h"
2727
28#include <condition_variable>
29#include <mutex>
30#include <thread>
31
28namespace mg = mir::graphics;32namespace mg = mir::graphics;
29namespace mf = mir::frontend;33namespace mf = mir::frontend;
3034
@@ -39,7 +43,7 @@
39 private:43 private:
40 void swap_buffers(graphics::Buffer*& buffer)44 void swap_buffers(graphics::Buffer*& buffer)
41 {45 {
42 surface->swap_buffers(buffer);46 surface->swap_buffers_blocking(buffer);
43 }47 }
44 virtual mir::geometry::Size size() const { return surface->size(); }48 virtual mir::geometry::Size size() const { return surface->size(); }
45 virtual MirPixelFormat pixel_format() const { return surface->pixel_format(); }49 virtual MirPixelFormat pixel_format() const { return surface->pixel_format(); }
@@ -49,3 +53,23 @@
4953
50 return std::make_shared<ForwardingInternalSurface>(surface);54 return std::make_shared<ForwardingInternalSurface>(surface);
51}55}
56
57void mf::Surface::swap_buffers_blocking(graphics::Buffer*& buffer)
58{
59 std::mutex mutex;
60 std::condition_variable cv;
61 bool done = false;
62
63 swap_buffers(buffer,
64 [&](mg::Buffer* new_buffer)
65 {
66 std::unique_lock<decltype(mutex)> lock(mutex);
67 buffer = new_buffer;
68 done = true;
69 cv.notify_one();
70 });
71
72 std::unique_lock<decltype(mutex)> lock(mutex);
73
74 cv.wait(lock, [&]{ return done; });
75}
5276
=== modified file 'src/server/graphics/nested/nested_display.cpp'
--- src/server/graphics/nested/nested_display.cpp 2014-01-13 06:12:33 +0000
+++ src/server/graphics/nested/nested_display.cpp 2014-02-10 09:00:06 +0000
@@ -152,9 +152,13 @@
152 f(*i.second);152 f(*i.second);
153}153}
154154
155std::shared_ptr<mg::DisplayConfiguration> mgn::NestedDisplay::configuration()155std::unique_ptr<mg::DisplayConfiguration> mgn::NestedDisplay::configuration() const
156{156{
157 return std::make_shared<NestedDisplayConfiguration>(mir_connection_create_display_config(*connection));157 return std::unique_ptr<mg::DisplayConfiguration>(
158 new NestedDisplayConfiguration(
159 mir_connection_create_display_config(*connection)
160 )
161 );
158}162}
159163
160void mgn::NestedDisplay::complete_display_initialization(MirPixelFormat format)164void mgn::NestedDisplay::complete_display_initialization(MirPixelFormat format)
161165
=== modified file 'src/server/graphics/nested/nested_display.h'
--- src/server/graphics/nested/nested_display.h 2014-01-13 06:12:33 +0000
+++ src/server/graphics/nested/nested_display.h 2014-02-10 09:00:06 +0000
@@ -102,7 +102,7 @@
102102
103 void for_each_display_buffer(std::function<void(DisplayBuffer&)>const& f) override;103 void for_each_display_buffer(std::function<void(DisplayBuffer&)>const& f) override;
104104
105 std::shared_ptr<DisplayConfiguration> configuration() override;105 std::unique_ptr<DisplayConfiguration> configuration() const override;
106 void configure(DisplayConfiguration const&) override;106 void configure(DisplayConfiguration const&) override;
107107
108 void register_configuration_change_handler(108 void register_configuration_change_handler(
109109
=== modified file 'src/server/graphics/offscreen/display.cpp'
--- src/server/graphics/offscreen/display.cpp 2014-01-10 08:51:30 +0000
+++ src/server/graphics/offscreen/display.cpp 2014-02-10 09:00:06 +0000
@@ -108,10 +108,12 @@
108 f(*db_ptr);108 f(*db_ptr);
109}109}
110110
111std::shared_ptr<mg::DisplayConfiguration> mgo::Display::configuration()111std::unique_ptr<mg::DisplayConfiguration> mgo::Display::configuration() const
112{112{
113 std::lock_guard<std::mutex> lock{configuration_mutex};113 std::lock_guard<std::mutex> lock{configuration_mutex};
114 return std::make_shared<mgo::DisplayConfiguration>(current_display_configuration);114 return std::unique_ptr<mg::DisplayConfiguration>(
115 new mgo::DisplayConfiguration(current_display_configuration)
116 );
115}117}
116118
117void mgo::Display::configure(mg::DisplayConfiguration const& conf)119void mgo::Display::configure(mg::DisplayConfiguration const& conf)
118120
=== modified file 'src/server/graphics/offscreen/display.h'
--- src/server/graphics/offscreen/display.h 2013-12-13 05:24:22 +0000
+++ src/server/graphics/offscreen/display.h 2014-02-10 09:00:06 +0000
@@ -71,8 +71,8 @@
7171
72 void for_each_display_buffer(std::function<void(DisplayBuffer&)> const& f);72 void for_each_display_buffer(std::function<void(DisplayBuffer&)> const& f);
7373
74 std::shared_ptr<graphics::DisplayConfiguration> configuration();74 std::unique_ptr<graphics::DisplayConfiguration> configuration() const override;
75 void configure(graphics::DisplayConfiguration const& conf);75 void configure(graphics::DisplayConfiguration const& conf) override;
7676
77 void register_configuration_change_handler(77 void register_configuration_change_handler(
78 EventHandlerRegister& handlers,78 EventHandlerRegister& handlers,
@@ -93,7 +93,7 @@
93 std::shared_ptr<BasicPlatform> const basic_platform;93 std::shared_ptr<BasicPlatform> const basic_platform;
94 detail::EGLDisplayHandle const egl_display;94 detail::EGLDisplayHandle const egl_display;
95 SurfacelessEGLContext const egl_context_shared;95 SurfacelessEGLContext const egl_context_shared;
96 std::mutex configuration_mutex;96 mutable std::mutex configuration_mutex;
97 DisplayConfiguration current_display_configuration;97 DisplayConfiguration current_display_configuration;
98 std::vector<std::unique_ptr<DisplayBuffer>> display_buffers;98 std::vector<std::unique_ptr<DisplayBuffer>> display_buffers;
99};99};
100100
=== modified file 'src/server/scene/application_session.cpp'
--- src/server/scene/application_session.cpp 2014-01-13 06:12:33 +0000
+++ src/server/scene/application_session.cpp 2014-02-10 09:00:06 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright © 2012 Canonical Ltd.2 * Copyright © 2012-2014 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * 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,5 * under the terms of the GNU General Public License version 3,
@@ -37,11 +37,13 @@
3737
38ms::ApplicationSession::ApplicationSession(38ms::ApplicationSession::ApplicationSession(
39 std::shared_ptr<msh::SurfaceFactory> const& surface_factory,39 std::shared_ptr<msh::SurfaceFactory> const& surface_factory,
40 pid_t pid,
40 std::string const& session_name,41 std::string const& session_name,
41 std::shared_ptr<SnapshotStrategy> const& snapshot_strategy,42 std::shared_ptr<SnapshotStrategy> const& snapshot_strategy,
42 std::shared_ptr<msh::SessionListener> const& session_listener,43 std::shared_ptr<msh::SessionListener> const& session_listener,
43 std::shared_ptr<mf::EventSink> const& sink) :44 std::shared_ptr<mf::EventSink> const& sink) :
44 surface_factory(surface_factory),45 surface_factory(surface_factory),
46 pid(pid),
45 session_name(session_name),47 session_name(session_name),
46 snapshot_strategy(snapshot_strategy),48 snapshot_strategy(snapshot_strategy),
47 session_listener(session_listener),49 session_listener(session_listener),
@@ -125,6 +127,11 @@
125 return session_name;127 return session_name;
126}128}
127129
130pid_t ms::ApplicationSession::process_id() const
131{
132 return pid;
133}
134
128void ms::ApplicationSession::force_requests_to_complete()135void ms::ApplicationSession::force_requests_to_complete()
129{136{
130 std::unique_lock<std::mutex> lock(surfaces_mutex);137 std::unique_lock<std::mutex> lock(surfaces_mutex);
131138
=== modified file 'src/server/scene/application_session.h'
--- src/server/scene/application_session.h 2014-01-13 06:12:33 +0000
+++ src/server/scene/application_session.h 2014-02-10 09:00:06 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright © 2013 Canonical Ltd.2 * Copyright © 2013-2014 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * 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,5 * under the terms of the GNU General Public License version 3,
@@ -45,6 +45,7 @@
45public:45public:
46 ApplicationSession(46 ApplicationSession(
47 std::shared_ptr<shell::SurfaceFactory> const& surface_factory,47 std::shared_ptr<shell::SurfaceFactory> const& surface_factory,
48 pid_t pid,
48 std::string const& session_name,49 std::string const& session_name,
49 std::shared_ptr<SnapshotStrategy> const& snapshot_strategy,50 std::shared_ptr<SnapshotStrategy> const& snapshot_strategy,
50 std::shared_ptr<shell::SessionListener> const& session_listener,51 std::shared_ptr<shell::SessionListener> const& session_listener,
@@ -60,6 +61,7 @@
60 std::shared_ptr<shell::Surface> default_surface() const;61 std::shared_ptr<shell::Surface> default_surface() const;
6162
62 std::string name() const;63 std::string name() const;
64 pid_t process_id() const override;
6365
64 void force_requests_to_complete();66 void force_requests_to_complete();
6567
@@ -77,6 +79,7 @@
7779
78private:80private:
79 std::shared_ptr<shell::SurfaceFactory> const surface_factory;81 std::shared_ptr<shell::SurfaceFactory> const surface_factory;
82 pid_t const pid;
80 std::string const session_name;83 std::string const session_name;
81 std::shared_ptr<SnapshotStrategy> const snapshot_strategy;84 std::shared_ptr<SnapshotStrategy> const snapshot_strategy;
82 std::shared_ptr<shell::SessionListener> const session_listener;85 std::shared_ptr<shell::SessionListener> const session_listener;
8386
=== modified file 'src/server/scene/basic_surface.cpp'
--- src/server/scene/basic_surface.cpp 2014-01-24 08:29:36 +0000
+++ src/server/scene/basic_surface.cpp 2014-02-10 09:00:06 +0000
@@ -114,11 +114,11 @@
114 return surface_buffer_stream->get_stream_pixel_format();114 return surface_buffer_stream->get_stream_pixel_format();
115}115}
116116
117void ms::BasicSurface::swap_buffers(graphics::Buffer*& buffer)117void ms::BasicSurface::swap_buffers(mg::Buffer* old_buffer, std::function<void(mg::Buffer* new_buffer)> complete)
118{118{
119 bool const posting{!!buffer};119 bool const posting{!!old_buffer};
120120
121 surface_buffer_stream->swap_client_buffers(buffer);121 surface_buffer_stream->swap_client_buffers(old_buffer, complete);
122122
123 if (posting)123 if (posting)
124 {124 {
125125
=== modified file 'src/server/scene/basic_surface.h'
--- src/server/scene/basic_surface.h 2014-01-24 08:29:36 +0000
+++ src/server/scene/basic_surface.h 2014-02-10 09:00:06 +0000
@@ -73,7 +73,7 @@
73 virtual MirPixelFormat pixel_format() const;73 virtual MirPixelFormat pixel_format() const;
7474
75 virtual std::shared_ptr<graphics::Buffer> snapshot_buffer() const;75 virtual std::shared_ptr<graphics::Buffer> snapshot_buffer() const;
76 virtual void swap_buffers(graphics::Buffer*&);76 virtual void swap_buffers(graphics::Buffer* old_buffer, std::function<void(graphics::Buffer* new_buffer)> complete);
77 virtual void force_requests_to_complete();77 virtual void force_requests_to_complete();
7878
79 virtual bool supports_input() const;79 virtual bool supports_input() const;
8080
=== modified file 'src/server/scene/session_manager.cpp'
--- src/server/scene/session_manager.cpp 2014-01-13 06:12:33 +0000
+++ src/server/scene/session_manager.cpp 2014-02-10 09:00:06 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright © 2012 Canonical Ltd.2 * Copyright © 2012-2014 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * 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,5 * under the terms of the GNU General Public License version 3,
@@ -73,12 +73,14 @@
73 close_session(session);73 close_session(session);
74}74}
7575
76std::shared_ptr<mf::Session> ms::SessionManager::open_session(std::string const& name,76std::shared_ptr<mf::Session> ms::SessionManager::open_session(
77 std::shared_ptr<mf::EventSink> const& sender)77 pid_t client_pid,
78 std::string const& name,
79 std::shared_ptr<mf::EventSink> const& sender)
78{80{
79 std::shared_ptr<msh::Session> new_session =81 std::shared_ptr<msh::Session> new_session =
80 std::make_shared<ApplicationSession>(82 std::make_shared<ApplicationSession>(
81 surface_factory, name, snapshot_strategy, session_listener, sender);83 surface_factory, client_pid, name, snapshot_strategy, session_listener, sender);
8284
83 app_container->insert_session(new_session);85 app_container->insert_session(new_session);
8486
8587
=== modified file 'src/server/scene/session_manager.h'
--- src/server/scene/session_manager.h 2014-01-13 06:12:33 +0000
+++ src/server/scene/session_manager.h 2014-02-10 09:00:06 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright © 2012 Canonical Ltd.2 * Copyright © 2012-2014 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * 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,5 * under the terms of the GNU General Public License version 3,
@@ -55,7 +55,10 @@
55 virtual ~SessionManager();55 virtual ~SessionManager();
5656
57 virtual std::shared_ptr<frontend::Session> open_session(57 virtual std::shared_ptr<frontend::Session> open_session(
58 std::string const& name, std::shared_ptr<frontend::EventSink> const& sink);58 pid_t client_pid,
59 std::string const& name,
60 std::shared_ptr<frontend::EventSink> const& sink);
61
59 virtual void close_session(std::shared_ptr<frontend::Session> const& session);62 virtual void close_session(std::shared_ptr<frontend::Session> const& session);
6063
61 frontend::SurfaceId create_surface_for(std::shared_ptr<frontend::Session> const& session,64 frontend::SurfaceId create_surface_for(std::shared_ptr<frontend::Session> const& session,
6265
=== modified file 'src/server/scene/surface_impl.cpp'
--- src/server/scene/surface_impl.cpp 2014-01-24 08:29:36 +0000
+++ src/server/scene/surface_impl.cpp 2014-02-10 09:00:06 +0000
@@ -103,9 +103,9 @@
103 return surface->pixel_format();103 return surface->pixel_format();
104}104}
105105
106void ms::SurfaceImpl::swap_buffers(graphics::Buffer*& buffer)106void ms::SurfaceImpl::swap_buffers(mg::Buffer* old_buffer, std::function<void(mg::Buffer* new_buffer)> complete)
107{107{
108 surface->swap_buffers(buffer);108 surface->swap_buffers(old_buffer, complete);
109}109}
110110
111void ms::SurfaceImpl::allow_framedropping(bool allow)111void ms::SurfaceImpl::allow_framedropping(bool allow)
112112
=== modified file 'src/server/scene/surface_impl.h'
--- src/server/scene/surface_impl.h 2014-01-13 06:12:33 +0000
+++ src/server/scene/surface_impl.h 2014-02-10 09:00:06 +0000
@@ -70,7 +70,7 @@
7070
71 virtual void with_most_recent_buffer_do(71 virtual void with_most_recent_buffer_do(
72 std::function<void(graphics::Buffer&)> const& exec);72 std::function<void(graphics::Buffer&)> const& exec);
73 virtual void swap_buffers(graphics::Buffer*& buffer);73 virtual void swap_buffers(graphics::Buffer* old_buffer, std::function<void(graphics::Buffer* new_buffer)> complete) override;
7474
75 virtual bool supports_input() const;75 virtual bool supports_input() const;
76 virtual int client_input_fd() const;76 virtual int client_input_fd() const;
7777
=== modified file 'src/utils/CMakeLists.txt'
--- src/utils/CMakeLists.txt 2014-01-10 05:48:41 +0000
+++ src/utils/CMakeLists.txt 2014-02-10 09:00:06 +0000
@@ -13,8 +13,17 @@
13add_executable(mirout out.c)13add_executable(mirout out.c)
14target_link_libraries(mirout mirclient)14target_link_libraries(mirout mirclient)
1515
16add_executable(mirscreencast screencast.cpp)
17
18target_link_libraries(mirscreencast
19 mirclient
20 ${EGL_LIBRARIES}
21 ${GLESv2_LIBRARIES}
22)
23
16install(TARGETS24install(TARGETS
17 mirping25 mirping
18 mirout26 mirout
27 mirscreencast
19 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}28 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
20)29)
2130
=== added file 'src/utils/screencast.cpp'
--- src/utils/screencast.cpp 1970-01-01 00:00:00 +0000
+++ src/utils/screencast.cpp 2014-02-10 09:00:06 +0000
@@ -0,0 +1,313 @@
1/*
2 * Copyright © 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: Alexandros Frantzis <alexandros.frantzis@canonical.com>
17 */
18
19#include "mir_toolkit/mir_client_library.h"
20#include "mir_toolkit/mir_screencast.h"
21#include "mir/geometry/size.h"
22
23#include "mir/raii.h"
24
25#include <getopt.h>
26#include <csignal>
27
28#include <EGL/egl.h>
29#include <GLES2/gl2.h>
30#include <GLES2/gl2ext.h>
31
32#include <fstream>
33#include <sstream>
34#include <thread>
35#include <iostream>
36#include <stdexcept>
37#include <future>
38#include <vector>
39
40namespace
41{
42
43volatile sig_atomic_t running = 1;
44
45void shutdown(int)
46{
47 running = 0;
48}
49
50std::future<void> write_frame_to_file(
51 std::vector<char> const& frame_data, int frame_number, GLenum format)
52{
53 return std::async(
54 std::launch::async,
55 [&frame_data, frame_number, format]
56 {
57 std::stringstream ss;
58 ss << "/tmp/mir_" ;
59 ss.width(5);
60 ss.fill('0');
61 ss << frame_number;
62 ss << (format == GL_BGRA_EXT ? ".bgra" : ".rgba");
63 std::ofstream f(ss.str());
64 f.write(frame_data.data(), frame_data.size());
65 });
66}
67
68GLenum read_pixels(mir::geometry::Size const& size, void* buffer)
69{
70 auto width = size.width.as_uint32_t();
71 auto height = size.height.as_uint32_t();
72
73 GLenum format = GL_BGRA_EXT;
74
75 glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, buffer);
76
77 if (glGetError() != GL_NO_ERROR)
78 {
79 format = GL_RGBA;
80 glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, buffer);
81 }
82
83 return format;
84}
85
86
87uint32_t get_first_valid_output_id(MirConnection* connection)
88{
89 auto const conf = mir::raii::deleter_for(
90 mir_connection_create_display_config(connection),
91 &mir_display_config_destroy);
92
93 if (conf == nullptr)
94 throw std::runtime_error("Failed to get display configuration\n");
95
96 for (unsigned i = 0; i < conf->num_outputs; ++i)
97 {
98 MirDisplayOutput const& output = conf->outputs[i];
99
100 if (output.connected && output.used &&
101 output.current_mode < output.num_modes)
102 {
103 return output.output_id;
104 }
105 }
106
107 throw std::runtime_error("Couldn't find a valid output to screencast");
108}
109
110mir::geometry::Size get_output_size(MirConnection* connection, uint32_t output_id)
111{
112 auto const conf = mir::raii::deleter_for(
113 mir_connection_create_display_config(connection),
114 &mir_display_config_destroy);
115
116 if (conf == nullptr)
117 throw std::runtime_error("Failed to get display configuration\n");
118
119 for (unsigned i = 0; i < conf->num_outputs; ++i)
120 {
121 MirDisplayOutput const& output = conf->outputs[i];
122
123 if (output.output_id == output_id &&
124 output.current_mode < output.num_modes)
125 {
126 MirDisplayMode const& mode = output.modes[output.current_mode];
127 return mir::geometry::Size{mode.horizontal_resolution, mode.vertical_resolution};
128 }
129 }
130
131 throw std::runtime_error("Couldn't get size of specified output");
132}
133
134void print_usage()
135{
136 std::cout << "Usage " << std::endl
137 << " -m <Mir server socket>" << std::endl
138 << " -o <Output id>" << std::endl
139 << " -h: this help text" << std::endl;
140}
141
142struct EGLSetup
143{
144 EGLSetup(MirConnection* connection, MirScreencast* screencast)
145 {
146 static EGLint const attribs[] = {
147 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
148 EGL_RED_SIZE, 8,
149 EGL_GREEN_SIZE, 8,
150 EGL_BLUE_SIZE, 8,
151 EGL_ALPHA_SIZE, 8,
152 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
153 EGL_NONE};
154
155 static EGLint const context_attribs[] = {
156 EGL_CONTEXT_CLIENT_VERSION, 2,
157 EGL_NONE };
158
159 auto native_display =
160 reinterpret_cast<EGLNativeDisplayType>(
161 mir_connection_get_egl_native_display(connection));
162
163 auto native_window =
164 reinterpret_cast<EGLNativeWindowType>(
165 mir_screencast_egl_native_window(screencast));
166
167 egl_display = eglGetDisplay(native_display);
168
169 eglInitialize(egl_display, nullptr, nullptr);
170
171 int n;
172 eglChooseConfig(egl_display, attribs, &egl_config, 1, &n);
173
174 egl_surface = eglCreateWindowSurface(egl_display, egl_config, native_window, NULL);
175 if (egl_surface == EGL_NO_SURFACE)
176 throw std::runtime_error("Failed to create EGL screencast surface");
177
178 egl_context = eglCreateContext(egl_display, egl_config, EGL_NO_CONTEXT, context_attribs);
179 if (egl_context == EGL_NO_CONTEXT)
180 throw std::runtime_error("Failed to create EGL context for screencast");
181
182 if (eglMakeCurrent(egl_display, egl_surface,
183 egl_surface, egl_context) != EGL_TRUE)
184 {
185 throw std::runtime_error("Failed to make screencast surface current");
186 }
187 }
188
189 ~EGLSetup()
190 {
191 eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
192 eglDestroySurface(egl_display, egl_surface);
193 eglDestroyContext(egl_display, egl_context);
194 eglTerminate(egl_display);
195 }
196
197 void swap_buffers()
198 {
199 if (eglSwapBuffers(egl_display, egl_surface) != EGL_TRUE)
200 throw std::runtime_error("Failed to swap screencast surface buffers");
201 }
202
203 EGLDisplay egl_display;
204 EGLContext egl_context;
205 EGLSurface egl_surface;
206 EGLConfig egl_config;
207};
208
209void do_screencast(MirConnection* connection, MirScreencast* screencast,
210 uint32_t output_id)
211{
212 static int const rgba_pixel_size{4};
213
214 auto const frame_size = get_output_size(connection, output_id);
215 auto const frame_size_bytes = rgba_pixel_size *
216 frame_size.width.as_uint32_t() *
217 frame_size.height.as_uint32_t();
218
219 int frame_number{0};
220 std::vector<char> frame_data(frame_size_bytes, 0);
221 std::future<void> frame_written_future =
222 std::async(std::launch::deferred, []{});
223
224 EGLSetup egl_setup{connection, screencast};
225
226 while (running)
227 {
228 frame_written_future.wait();
229
230 auto format = read_pixels(frame_size, frame_data.data());
231 frame_written_future = write_frame_to_file(frame_data, frame_number, format);
232
233 egl_setup.swap_buffers();
234 ++frame_number;
235 }
236}
237
238}
239
240int main(int argc, char* argv[])
241try
242{
243 int arg;
244 opterr = 0;
245 char const* socket_file = nullptr;
246 uint32_t output_id = mir_display_output_id_invalid;
247
248 while ((arg = getopt (argc, argv, "hm:o:")) != -1)
249 {
250 switch (arg)
251 {
252 case 'm':
253 socket_file = optarg;
254 break;
255
256 case 'o':
257 output_id = std::stoul(optarg);
258 break;
259
260 case '?':
261 case 'h':
262 print_usage();
263 return EXIT_SUCCESS;
264
265 default:
266 print_usage();
267 return EXIT_FAILURE;
268 }
269 }
270
271 signal(SIGINT, shutdown);
272 signal(SIGTERM, shutdown);
273
274 auto const connection = mir::raii::deleter_for(
275 mir_connect_sync(socket_file, "mirscreencast"),
276 [](MirConnection* c) { if (c) mir_connection_release(c); });
277
278 if (connection == nullptr || !mir_connection_is_valid(connection.get()))
279 {
280 std::string msg("Failed to connect to server.");
281 if (connection)
282 {
283 msg += " Error was :";
284 msg += mir_connection_get_error_message(connection.get());
285 }
286 throw std::runtime_error(std::string(msg));
287 }
288
289 if (output_id == mir_display_output_id_invalid)
290 output_id = get_first_valid_output_id(connection.get());
291
292 MirScreencastParameters params{
293 output_id, 0, 0, mir_pixel_format_invalid};
294
295 std::cout << "Starting screencast for output id " << params.output_id << std::endl;
296
297 auto const screencast = mir::raii::deleter_for(
298 mir_connection_create_screencast_sync(connection.get(), &params),
299 [](MirScreencast* s) { if (s) mir_screencast_release_sync(s); });
300
301 if (screencast == nullptr)
302 throw std::runtime_error("Failed to create screencast");
303
304 do_screencast(connection.get(), screencast.get(), output_id);
305
306 return EXIT_SUCCESS;
307}
308catch(std::exception const& e)
309{
310 std::cerr << e.what() << std::endl;
311
312 return EXIT_FAILURE;
313}
0314
=== modified file 'tests/acceptance-tests/test_client_screencast.cpp'
--- tests/acceptance-tests/test_client_screencast.cpp 2014-01-29 17:20:51 +0000
+++ tests/acceptance-tests/test_client_screencast.cpp 2014-02-10 09:00:06 +0000
@@ -22,11 +22,11 @@
22#include "mir_test_framework/stubbed_server_configuration.h"22#include "mir_test_framework/stubbed_server_configuration.h"
23#include "mir_test_framework/in_process_server.h"23#include "mir_test_framework/in_process_server.h"
24#include "mir_test_framework/using_stub_client_platform.h"24#include "mir_test_framework/using_stub_client_platform.h"
25#include "src/server/frontend/protobuf_ipc_factory.h"
26#include "mir_protobuf.pb.h"
2725
28#include "mir_test_doubles/null_display_changer.h"26#include "mir_test_doubles/null_display_changer.h"
29#include "mir_test_doubles/stub_display_configuration.h"27#include "mir_test_doubles/stub_display_configuration.h"
28#include "mir_test_doubles/stub_buffer.h"
29#include "mir_test_doubles/mock_screencast.h"
30#include "mir_test/fake_shared.h"30#include "mir_test/fake_shared.h"
3131
32#include <gtest/gtest.h>32#include <gtest/gtest.h>
@@ -41,114 +41,6 @@
41namespace41namespace
42{42{
4343
44ACTION(RunClosure)
45{
46 arg3->Run();
47}
48
49MATCHER_P(WithOutputId, value, "")
50{
51 return arg->output_id() == value;
52}
53
54MATCHER_P(WithScreencastId, value, "")
55{
56 return arg->value() == value;
57}
58
59ACTION_P(SetCreateScreencastId, screencast_id)
60{
61 arg2->mutable_screencast_id()->set_value(screencast_id);
62}
63
64ACTION(FillCreateScreencastBuffer)
65{
66 int fds[2]{-1,-1};
67 if (pipe(fds))
68 FAIL() << "Failed to create FillCreateScreencastBuffer fds";
69 close(fds[1]);
70 arg2->mutable_buffer()->add_fd(fds[0]);
71}
72
73/*
74 * This setup is used temporarily to test MirScreencast, until
75 * we have the server-side implementation of the feature in place.
76 */
77struct MockScreencastServer : mir::protobuf::DisplayServer
78{
79 MockScreencastServer(
80 std::shared_ptr<mir::protobuf::DisplayServer> const& ds)
81 : wrapped_display_server{ds}
82 {
83 using namespace testing;
84 ON_CALL(*this, create_screencast(_,_,_,_))
85 .WillByDefault(DoAll(FillCreateScreencastBuffer(),RunClosure()));
86 ON_CALL(*this, release_screencast(_,_,_,_))
87 .WillByDefault(RunClosure());
88 }
89
90 void connect(
91 ::google::protobuf::RpcController* rpc,
92 const ::mir::protobuf::ConnectParameters* request,
93 ::mir::protobuf::Connection* response,
94 ::google::protobuf::Closure* done) override
95 {
96 wrapped_display_server->connect(rpc, request, response, done);
97 }
98
99 void disconnect(
100 google::protobuf::RpcController* rpc,
101 const mir::protobuf::Void* request,
102 mir::protobuf::Void* response,
103 google::protobuf::Closure* done) override
104 {
105 wrapped_display_server->disconnect(rpc, request, response, done);
106 }
107
108 MOCK_METHOD4(create_screencast,
109 void(google::protobuf::RpcController*,
110 const mir::protobuf::ScreencastParameters*,
111 mir::protobuf::Screencast*,
112 google::protobuf::Closure*));
113
114 MOCK_METHOD4(release_screencast,
115 void(google::protobuf::RpcController*,
116 const mir::protobuf::ScreencastId*,
117 mir::protobuf::Void*,
118 google::protobuf::Closure*));
119
120 std::shared_ptr<mir::protobuf::DisplayServer> const wrapped_display_server;
121};
122
123std::shared_ptr<MockScreencastServer> global_mock_screencast_server;
124
125class WrappingIpcFactory : public mf::ProtobufIpcFactory
126{
127public:
128 WrappingIpcFactory(
129 std::shared_ptr<mf::ProtobufIpcFactory> const& ipc_factory)
130 : wrapped_ipc_factory{ipc_factory}
131 {
132 }
133
134 std::shared_ptr<mir::protobuf::DisplayServer> make_ipc_server(
135 std::shared_ptr<mf::EventSink> const& sink, bool auth) override
136 {
137 auto ipc_server = wrapped_ipc_factory->make_ipc_server(sink, auth);
138 global_mock_screencast_server =
139 std::make_shared<testing::NiceMock<MockScreencastServer>>(ipc_server);
140 return global_mock_screencast_server;
141 }
142
143 std::shared_ptr<mf::ResourceCache> resource_cache() override
144 {
145 return wrapped_ipc_factory->resource_cache();
146 }
147
148private:
149 std::shared_ptr<mf::ProtobufIpcFactory> const wrapped_ipc_factory;
150};
151
152class StubChanger : public mtd::NullDisplayChanger44class StubChanger : public mtd::NullDisplayChanger
153{45{
154public:46public:
@@ -179,27 +71,22 @@
179 return mt::fake_shared(stub_changer);71 return mt::fake_shared(stub_changer);
180 }72 }
18173
182 std::shared_ptr<mf::ProtobufIpcFactory> the_ipc_factory(74 std::shared_ptr<mf::Screencast> the_screencast() override
183 std::shared_ptr<mf::Shell> const& shell,
184 std::shared_ptr<mg::GraphicBufferAllocator> const& alloc) override
185 {75 {
186 auto factory = mtf::StubbedServerConfiguration::the_ipc_factory(shell, alloc);76 return mt::fake_shared(mock_screencast);
187 return std::make_shared<WrappingIpcFactory>(factory);
188 }77 }
18978
190 StubChanger stub_changer;79 StubChanger stub_changer;
80 mtd::MockScreencast mock_screencast;
191};81};
19282
193class MirScreencastTest : public mir_test_framework::InProcessServer83class MirScreencastTest : public mir_test_framework::InProcessServer
194{84{
195public:85public:
196 ~MirScreencastTest()
197 {
198 global_mock_screencast_server.reset();
199 }
200
201 mir::DefaultServerConfiguration& server_config() override { return server_config_; }86 mir::DefaultServerConfiguration& server_config() override { return server_config_; }
20287
88 mtd::MockScreencast& mock_screencast() { return server_config_.mock_screencast; }
89
203 StubServerConfig server_config_;90 StubServerConfig server_config_;
204 mtf::UsingStubClientPlatform using_stub_client_platform;91 mtf::UsingStubClientPlatform using_stub_client_platform;
205};92};
@@ -227,8 +114,7 @@
227 uint32_t const invalid_output_id{33};114 uint32_t const invalid_output_id{33};
228 MirScreencastParameters params{invalid_output_id, 0, 0, mir_pixel_format_invalid};115 MirScreencastParameters params{invalid_output_id, 0, 0, mir_pixel_format_invalid};
229116
230 EXPECT_CALL(*global_mock_screencast_server,117 EXPECT_CALL(mock_screencast(), create_session(_))
231 create_screencast(_,_,_,_))
232 .Times(0);118 .Times(0);
233119
234 auto screencast =120 auto screencast =
@@ -238,28 +124,27 @@
238 mir_connection_release(connection);124 mir_connection_release(connection);
239}125}
240126
241TEST_F(MirScreencastTest, create_and_release_contact_server)127TEST_F(MirScreencastTest, contacts_server_screencast_for_create_and_release)
242{128{
243 using namespace testing;129 using namespace testing;
244130
245 auto const connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);131 auto const connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
246 ASSERT_TRUE(mir_connection_is_valid(connection));132 ASSERT_TRUE(mir_connection_is_valid(connection));
247133
248 uint32_t const screencast_id{99};134 mf::ScreencastSessionId const screencast_session_id{99};
249 uint32_t const output_id{2};135 uint32_t const output_id{2};
250 MirScreencastParameters params{output_id, 0, 0, mir_pixel_format_invalid};136 MirScreencastParameters params{output_id, 0, 0, mir_pixel_format_invalid};
251137
252 InSequence seq;138 InSequence seq;
253139
254 EXPECT_CALL(*global_mock_screencast_server,140 EXPECT_CALL(mock_screencast(),
255 create_screencast(_,WithOutputId(output_id),_,_))141 create_session(mg::DisplayConfigurationOutputId{output_id}))
256 .WillOnce(DoAll(SetCreateScreencastId(screencast_id),142 .WillOnce(Return(screencast_session_id));
257 FillCreateScreencastBuffer(),143
258 RunClosure()));144 EXPECT_CALL(mock_screencast(), capture(screencast_session_id))
259145 .WillOnce(Return(std::make_shared<mtd::StubBuffer>()));
260 EXPECT_CALL(*global_mock_screencast_server,146
261 release_screencast(_,WithScreencastId(screencast_id),_,_))147 EXPECT_CALL(mock_screencast(), destroy_session(screencast_session_id));
262 .WillOnce(RunClosure());
263148
264 auto screencast = mir_connection_create_screencast_sync(connection, &params);149 auto screencast = mir_connection_create_screencast_sync(connection, &params);
265 ASSERT_NE(nullptr, screencast);150 ASSERT_NE(nullptr, screencast);
@@ -275,9 +160,17 @@
275 auto const connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);160 auto const connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
276 ASSERT_TRUE(mir_connection_is_valid(connection));161 ASSERT_TRUE(mir_connection_is_valid(connection));
277162
163 mf::ScreencastSessionId const screencast_session_id{99};
278 uint32_t const output_id{2};164 uint32_t const output_id{2};
279 MirScreencastParameters params{output_id, 0, 0, mir_pixel_format_invalid};165 MirScreencastParameters params{output_id, 0, 0, mir_pixel_format_invalid};
280166
167 InSequence seq;
168 EXPECT_CALL(mock_screencast(), create_session(_))
169 .WillOnce(Return(screencast_session_id));
170 EXPECT_CALL(mock_screencast(), capture(_))
171 .WillOnce(Return(std::make_shared<mtd::StubBuffer>()));
172 EXPECT_CALL(mock_screencast(), destroy_session(_));
173
281 auto screencast = mir_connection_create_screencast_sync(connection, &params);174 auto screencast = mir_connection_create_screencast_sync(connection, &params);
282 ASSERT_NE(nullptr, screencast);175 ASSERT_NE(nullptr, screencast);
283176
@@ -288,3 +181,22 @@
288181
289 mir_connection_release(connection);182 mir_connection_release(connection);
290}183}
184
185TEST_F(MirScreencastTest, fails_on_client_when_server_request_fails)
186{
187 using namespace testing;
188
189 auto const connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
190 ASSERT_TRUE(mir_connection_is_valid(connection));
191
192 uint32_t const output_id{2};
193 MirScreencastParameters params{output_id, 0, 0, mir_pixel_format_invalid};
194
195 EXPECT_CALL(mock_screencast(), create_session(_))
196 .WillOnce(Throw(std::runtime_error("")));
197
198 auto screencast = mir_connection_create_screencast_sync(connection, &params);
199 ASSERT_EQ(nullptr, screencast);
200
201 mir_connection_release(connection);
202}
291203
=== modified file 'tests/acceptance-tests/test_display_configuration.cpp'
--- tests/acceptance-tests/test_display_configuration.cpp 2014-01-13 06:12:33 +0000
+++ tests/acceptance-tests/test_display_configuration.cpp 2014-02-10 09:00:06 +0000
@@ -87,9 +87,11 @@
87 f(display_buffer);87 f(display_buffer);
88 }88 }
8989
90 std::shared_ptr<mg::DisplayConfiguration> configuration()90 std::unique_ptr<mg::DisplayConfiguration> configuration() const override
91 {91 {
92 return config;92 return std::unique_ptr<mg::DisplayConfiguration>(
93 new mtd::StubDisplayConfig(*config)
94 );
93 }95 }
9496
95 void register_configuration_change_handler(97 void register_configuration_change_handler(
@@ -112,7 +114,7 @@
112 MOCK_METHOD1(configure, void(mg::DisplayConfiguration const&));114 MOCK_METHOD1(configure, void(mg::DisplayConfiguration const&));
113115
114 void emit_configuration_change_event(116 void emit_configuration_change_event(
115 std::shared_ptr<mg::DisplayConfiguration> const& new_config)117 std::shared_ptr<mtd::StubDisplayConfig> const& new_config)
116 {118 {
117 config = new_config;119 config = new_config;
118 if (write(p.write_fd(), "a", 1)) {}120 if (write(p.write_fd(), "a", 1)) {}
@@ -125,7 +127,7 @@
125 }127 }
126128
127private:129private:
128 std::shared_ptr<mg::DisplayConfiguration> config;130 std::shared_ptr<mtd::StubDisplayConfig> config;
129 mtd::NullDisplayBuffer display_buffer;131 mtd::NullDisplayBuffer display_buffer;
130 mt::Pipe p;132 mt::Pipe p;
131 std::atomic<bool> handler_called;133 std::atomic<bool> handler_called;
132134
=== modified file 'tests/acceptance-tests/test_protobuf.cpp'
--- tests/acceptance-tests/test_protobuf.cpp 2014-01-21 12:49:00 +0000
+++ tests/acceptance-tests/test_protobuf.cpp 2014-02-10 09:00:06 +0000
@@ -75,7 +75,7 @@
75 sender(sender),75 sender(sender),
76 wrapped(wrapped) {}76 wrapped(wrapped) {}
7777
78 bool dispatch(mir::protobuf::wire::Invocation const& invocation)78 bool dispatch(mfd::Invocation const& invocation)
79 {79 {
80 if ("function" == invocation.method_name())80 if ("function" == invocation.method_name())
81 {81 {
8282
=== modified file 'tests/acceptance-tests/test_surfaces_with_output_id.cpp'
--- tests/acceptance-tests/test_surfaces_with_output_id.cpp 2014-01-13 06:12:33 +0000
+++ tests/acceptance-tests/test_surfaces_with_output_id.cpp 2014-02-10 09:00:06 +0000
@@ -66,9 +66,11 @@
66 f(*db);66 f(*db);
67 }67 }
6868
69 std::shared_ptr<mg::DisplayConfiguration> configuration() override69 std::unique_ptr<mg::DisplayConfiguration> configuration() const override
70 {70 {
71 return std::make_shared<mtd::StubDisplayConfig>(rects);71 return std::unique_ptr<mg::DisplayConfiguration>(
72 new mtd::StubDisplayConfig(rects)
73 );
72 }74 }
7375
74private:76private:
7577
=== modified file 'tests/draw/android_graphics.cpp'
--- tests/draw/android_graphics.cpp 2014-01-13 06:12:33 +0000
+++ tests/draw/android_graphics.cpp 2014-02-10 09:00:06 +0000
@@ -48,28 +48,6 @@
48 gralloc_module_t *grmod;48 gralloc_module_t *grmod;
49 native_handle_t const* handle;49 native_handle_t const* handle;
50};50};
51
52static const char* proc_dir = "/proc";
53static const char* surface_flinger_executable_name = "surfaceflinger";
54int surface_flinger_filter(const struct dirent* d)
55{
56 if (fnmatch("[1-9]*", d->d_name, 0))
57 return 0;
58
59 char path[256];
60 snprintf(path, sizeof(path), "%s/%s/cmdline", proc_dir, d->d_name);
61
62 std::ifstream in(path);
63 std::string line;
64
65 while(std::getline(in, line))
66 {
67 if (line.find(surface_flinger_executable_name) != std::string::npos)
68 return 1;
69 }
70
71 return 0;
72}
73}51}
7452
75mtd::TestGrallocMapper::TestGrallocMapper()53mtd::TestGrallocMapper::TestGrallocMapper()
7654
=== modified file 'tests/integration-tests/client/CMakeLists.txt'
--- tests/integration-tests/client/CMakeLists.txt 2013-10-15 08:53:10 +0000
+++ tests/integration-tests/client/CMakeLists.txt 2014-02-10 09:00:06 +0000
@@ -4,9 +4,14 @@
4 APPEND INTEGRATION_TESTS_SRCS4 APPEND INTEGRATION_TESTS_SRCS
5 ${CMAKE_CURRENT_SOURCE_DIR}/test_client_render.cpp5 ${CMAKE_CURRENT_SOURCE_DIR}/test_client_render.cpp
6)6)
7endif()
8
9list(
10 APPEND INTEGRATION_TESTS_SRCS
11 ${CMAKE_CURRENT_SOURCE_DIR}/test_screencast.cpp
12)
713
8set(14set(
9 INTEGRATION_TESTS_SRCS15 INTEGRATION_TESTS_SRCS
10 ${INTEGRATION_TESTS_SRCS}16 ${INTEGRATION_TESTS_SRCS}
11 PARENT_SCOPE)17 PARENT_SCOPE)
12endif()
1318
=== added file 'tests/integration-tests/client/test_screencast.cpp'
--- tests/integration-tests/client/test_screencast.cpp 1970-01-01 00:00:00 +0000
+++ tests/integration-tests/client/test_screencast.cpp 2014-02-10 09:00:06 +0000
@@ -0,0 +1,191 @@
1/*
2 * Copyright © 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: Alexandros Frantzis <alexandros.frantzis@canonical.com>
17 */
18
19#include "mir_protobuf.pb.h"
20#include "src/client/default_connection_configuration.h"
21
22#include "mir/frontend/connector.h"
23#include "mir_test/test_protobuf_server.h"
24#include "mir_test/stub_server_tool.h"
25#include "mir_test/pipe.h"
26
27#include <gtest/gtest.h>
28
29#include <thread>
30#include <mutex>
31#include <condition_variable>
32#include <boost/throw_exception.hpp>
33
34namespace mcl = mir::client;
35namespace mt = mir::test;
36
37namespace
38{
39
40class WaitObject
41{
42public:
43 void notify_ready()
44 {
45 std::unique_lock<std::mutex> lock{mutex};
46 ready = true;
47 cv.notify_all();
48 }
49
50 void wait_until_ready()
51 {
52 std::unique_lock<std::mutex> lock{mutex};
53 if (!cv.wait_for(lock, std::chrono::seconds{10}, [this] { return ready; }))
54 {
55 BOOST_THROW_EXCEPTION(std::runtime_error("WaitObject timed out"));
56 }
57 }
58
59private:
60 std::mutex mutex;
61 std::condition_variable cv;
62 bool ready = false;
63};
64
65struct StubScreencastServerTool : mt::StubServerTool
66{
67 void create_screencast(
68 google::protobuf::RpcController*,
69 const mir::protobuf::ScreencastParameters*,
70 mir::protobuf::Screencast* response,
71 google::protobuf::Closure* done) override
72 {
73 response->mutable_buffer()->add_fd(pipe.read_fd());
74 done->Run();
75 }
76
77 void screencast_buffer(
78 ::google::protobuf::RpcController*,
79 ::mir::protobuf::ScreencastId const*,
80 ::mir::protobuf::Buffer* response,
81 ::google::protobuf::Closure* done) override
82 {
83 response->add_fd(pipe.read_fd());
84 done->Run();
85 }
86
87 mt::Pipe pipe;
88};
89
90struct MirScreencastTest : public testing::Test
91{
92 MirScreencastTest()
93 : server_tool{std::make_shared<StubScreencastServerTool>()}
94 {
95 std::remove(test_socket);
96 test_server =
97 std::make_shared<mt::TestProtobufServer>(test_socket, server_tool);
98 test_server->comm->start();
99
100 rpc_channel =
101 mcl::DefaultConnectionConfiguration{test_socket}.the_rpc_channel();
102 protobuf_server =
103 std::make_shared<mir::protobuf::DisplayServer::Stub>(rpc_channel.get());
104 }
105
106 char const* const test_socket = "./test_socket_screencast";
107 std::shared_ptr<StubScreencastServerTool> const server_tool;
108 std::shared_ptr<mt::TestProtobufServer> test_server;
109 std::shared_ptr<google::protobuf::RpcChannel> rpc_channel;
110 std::shared_ptr<mir::protobuf::DisplayServer> protobuf_server;
111};
112
113}
114
115TEST_F(MirScreencastTest, gets_buffer_fd_when_creating_screencast)
116{
117 std::vector<char> const cookie{'2','3','l','$'};
118
119 ASSERT_EQ(static_cast<ssize_t>(cookie.size()),
120 write(server_tool->pipe.write_fd(), cookie.data(), cookie.size()));
121
122 mir::protobuf::ScreencastParameters protobuf_parameters;
123 protobuf_parameters.set_output_id(0);
124 protobuf_parameters.set_width(0);
125 protobuf_parameters.set_height(0);
126 mir::protobuf::Screencast protobuf_screencast;
127
128 WaitObject wait_rpc;
129
130 protobuf_server->create_screencast(
131 nullptr,
132 &protobuf_parameters,
133 &protobuf_screencast,
134 google::protobuf::NewCallback(&wait_rpc, &WaitObject::notify_ready));
135
136 wait_rpc.wait_until_ready();
137
138 ASSERT_EQ(1, protobuf_screencast.buffer().fd_size());
139 auto const read_fd = protobuf_screencast.buffer().fd(0);
140
141 // The received FD should be different from the original pipe fd,
142 // since we are sending it over our IPC mechanism, which for
143 // the purposes of this test, lives in the same process.
144 // TODO: Don't depend on IPC implementation details
145 EXPECT_NE(read_fd, server_tool->pipe.read_fd());
146
147 std::vector<char> received(cookie.size(), '\0');
148 EXPECT_EQ(static_cast<ssize_t>(cookie.size()),
149 read(read_fd, received.data(), received.size()));
150 EXPECT_EQ(cookie, received);
151
152 close(read_fd);
153}
154
155TEST_F(MirScreencastTest, gets_buffer_fd_when_getting_screencast_buffer)
156{
157 std::vector<char> const cookie{'X','%','q','S'};
158
159 ASSERT_EQ(static_cast<ssize_t>(cookie.size()),
160 write(server_tool->pipe.write_fd(), cookie.data(), cookie.size()));
161
162 mir::protobuf::ScreencastId protobuf_screencast_id;
163 protobuf_screencast_id.set_value(0);
164 mir::protobuf::Buffer protobuf_buffer;
165
166 WaitObject wait_rpc;
167
168 protobuf_server->screencast_buffer(
169 nullptr,
170 &protobuf_screencast_id,
171 &protobuf_buffer,
172 google::protobuf::NewCallback(&wait_rpc, &WaitObject::notify_ready));
173
174 wait_rpc.wait_until_ready();
175
176 ASSERT_EQ(1, protobuf_buffer.fd_size());
177 auto const read_fd = protobuf_buffer.fd(0);
178
179 // The received FD should be different from the original pipe fd,
180 // since we are sending it over our IPC mechanism, which, for
181 // the purposes of this test, lives in the same process.
182 // TODO: Don't depend on IPC implementation details
183 EXPECT_NE(read_fd, server_tool->pipe.read_fd());
184
185 std::vector<char> received(cookie.size(), '\0');
186 EXPECT_EQ(static_cast<ssize_t>(cookie.size()),
187 read(read_fd, received.data(), received.size()));
188 EXPECT_EQ(cookie, received);
189
190 close(read_fd);
191}
0192
=== modified file 'tests/integration-tests/compositor/test_buffer_stream.cpp'
--- tests/integration-tests/compositor/test_buffer_stream.cpp 2014-01-13 06:12:33 +0000
+++ tests/integration-tests/compositor/test_buffer_stream.cpp 2014-02-10 09:00:06 +0000
@@ -26,6 +26,7 @@
2626
27#include <gmock/gmock.h>27#include <gmock/gmock.h>
2828
29#include <condition_variable>
29#include <thread>30#include <thread>
30#include <chrono>31#include <chrono>
31#include <atomic>32#include <atomic>
@@ -38,6 +39,31 @@
3839
39namespace40namespace
40{41{
42struct BufferStreamSurfaces : mc::BufferStreamSurfaces
43{
44 using mc::BufferStreamSurfaces::BufferStreamSurfaces;
45
46 // Convenient function to allow tests to be written in linear style
47 void swap_client_buffers_blocking(mg::Buffer*& buffer)
48 {
49 std::mutex mutex;
50 std::condition_variable cv;
51 bool done = false;
52
53 swap_client_buffers(buffer,
54 [&](mg::Buffer* new_buffer)
55 {
56 std::unique_lock<decltype(mutex)> lock(mutex);
57 buffer = new_buffer;
58 done = true;
59 cv.notify_one();
60 });
61
62 std::unique_lock<decltype(mutex)> lock(mutex);
63
64 cv.wait(lock, [&]{ return done; });
65 }
66};
4167
42struct BufferStreamTest : public ::testing::Test68struct BufferStreamTest : public ::testing::Test
43{69{
@@ -60,7 +86,7 @@
60 }86 }
6187
62 const int nbuffers;88 const int nbuffers;
63 mc::BufferStreamSurfaces buffer_stream;89 BufferStreamSurfaces buffer_stream;
64};90};
6591
66}92}
@@ -68,9 +94,9 @@
68TEST_F(BufferStreamTest, gives_same_back_buffer_until_more_available)94TEST_F(BufferStreamTest, gives_same_back_buffer_until_more_available)
69{95{
70 mg::Buffer* client1{nullptr};96 mg::Buffer* client1{nullptr};
71 buffer_stream.swap_client_buffers(client1);97 buffer_stream.swap_client_buffers_blocking(client1);
72 auto client1_id = client1->id();98 auto client1_id = client1->id();
73 buffer_stream.swap_client_buffers(client1);99 buffer_stream.swap_client_buffers_blocking(client1);
74100
75 auto comp1 = buffer_stream.lock_compositor_buffer(1);101 auto comp1 = buffer_stream.lock_compositor_buffer(1);
76 auto comp2 = buffer_stream.lock_compositor_buffer(1);102 auto comp2 = buffer_stream.lock_compositor_buffer(1);
@@ -80,7 +106,7 @@
80106
81 comp1.reset();107 comp1.reset();
82108
83 buffer_stream.swap_client_buffers(client1);109 buffer_stream.swap_client_buffers_blocking(client1);
84 auto comp3 = buffer_stream.lock_compositor_buffer(2);110 auto comp3 = buffer_stream.lock_compositor_buffer(2);
85111
86 EXPECT_NE(client1_id, comp3->id());112 EXPECT_NE(client1_id, comp3->id());
@@ -97,7 +123,7 @@
97{123{
98 mg::Buffer* client_buffer{nullptr};124 mg::Buffer* client_buffer{nullptr};
99 for (int i = 0; i != nbuffers; i++)125 for (int i = 0; i != nbuffers; i++)
100 buffer_stream.swap_client_buffers(client_buffer);126 buffer_stream.swap_client_buffers_blocking(client_buffer);
101127
102 auto first_monitor = buffer_stream.lock_compositor_buffer(1);128 auto first_monitor = buffer_stream.lock_compositor_buffer(1);
103 auto first_compositor_id = first_monitor->id();129 auto first_compositor_id = first_monitor->id();
@@ -113,14 +139,14 @@
113TEST_F(BufferStreamTest, gives_different_back_buffer_asap)139TEST_F(BufferStreamTest, gives_different_back_buffer_asap)
114{140{
115 mg::Buffer* client_buffer{nullptr};141 mg::Buffer* client_buffer{nullptr};
116 buffer_stream.swap_client_buffers(client_buffer);142 buffer_stream.swap_client_buffers_blocking(client_buffer);
117143
118 if (nbuffers > 1)144 if (nbuffers > 1)
119 {145 {
120 buffer_stream.swap_client_buffers(client_buffer);146 buffer_stream.swap_client_buffers_blocking(client_buffer);
121 auto comp1 = buffer_stream.lock_compositor_buffer(1);147 auto comp1 = buffer_stream.lock_compositor_buffer(1);
122148
123 buffer_stream.swap_client_buffers(client_buffer);149 buffer_stream.swap_client_buffers_blocking(client_buffer);
124 auto comp2 = buffer_stream.lock_compositor_buffer(2);150 auto comp2 = buffer_stream.lock_compositor_buffer(2);
125151
126 EXPECT_NE(comp1->id(), comp2->id());152 EXPECT_NE(comp1->id(), comp2->id());
@@ -135,7 +161,7 @@
135 auto old_size = buffer_stream.stream_size();161 auto old_size = buffer_stream.stream_size();
136162
137 mg::Buffer* client{nullptr};163 mg::Buffer* client{nullptr};
138 buffer_stream.swap_client_buffers(client);164 buffer_stream.swap_client_buffers_blocking(client);
139 EXPECT_EQ(old_size, client->size());165 EXPECT_EQ(old_size, client->size());
140166
141 geom::Size const new_size167 geom::Size const new_size
@@ -146,13 +172,13 @@
146 buffer_stream.resize(new_size);172 buffer_stream.resize(new_size);
147 EXPECT_EQ(new_size, buffer_stream.stream_size());173 EXPECT_EQ(new_size, buffer_stream.stream_size());
148174
149 buffer_stream.swap_client_buffers(client);175 buffer_stream.swap_client_buffers_blocking(client);
150 EXPECT_EQ(new_size, client->size());176 EXPECT_EQ(new_size, client->size());
151177
152 buffer_stream.resize(old_size);178 buffer_stream.resize(old_size);
153 EXPECT_EQ(old_size, buffer_stream.stream_size());179 EXPECT_EQ(old_size, buffer_stream.stream_size());
154180
155 buffer_stream.swap_client_buffers(client);181 buffer_stream.swap_client_buffers_blocking(client);
156 EXPECT_EQ(old_size, client->size());182 EXPECT_EQ(old_size, client->size());
157}183}
158184
@@ -161,7 +187,7 @@
161 auto old_size = buffer_stream.stream_size();187 auto old_size = buffer_stream.stream_size();
162188
163 mg::Buffer* client{nullptr};189 mg::Buffer* client{nullptr};
164 buffer_stream.swap_client_buffers(client);190 buffer_stream.swap_client_buffers_blocking(client);
165191
166 geom::Size const new_size192 geom::Size const new_size
167 {193 {
@@ -171,8 +197,8 @@
171 buffer_stream.resize(new_size);197 buffer_stream.resize(new_size);
172 EXPECT_EQ(new_size, buffer_stream.stream_size());198 EXPECT_EQ(new_size, buffer_stream.stream_size());
173199
174 buffer_stream.swap_client_buffers(client);200 buffer_stream.swap_client_buffers_blocking(client);
175 buffer_stream.swap_client_buffers(client);201 buffer_stream.swap_client_buffers_blocking(client);
176202
177 auto comp1 = buffer_stream.lock_compositor_buffer(1);203 auto comp1 = buffer_stream.lock_compositor_buffer(1);
178 EXPECT_EQ(old_size, comp1->size());204 EXPECT_EQ(old_size, comp1->size());
@@ -182,7 +208,7 @@
182 EXPECT_EQ(new_size, comp2->size());208 EXPECT_EQ(new_size, comp2->size());
183 comp2.reset();209 comp2.reset();
184210
185 buffer_stream.swap_client_buffers(client);211 buffer_stream.swap_client_buffers_blocking(client);
186212
187 auto comp3 = buffer_stream.lock_compositor_buffer(3);213 auto comp3 = buffer_stream.lock_compositor_buffer(3);
188 EXPECT_EQ(new_size, comp3->size());214 EXPECT_EQ(new_size, comp3->size());
@@ -192,13 +218,13 @@
192 EXPECT_EQ(old_size, buffer_stream.stream_size());218 EXPECT_EQ(old_size, buffer_stream.stream_size());
193219
194 // No client frames "drawn" since resize(old_size), so compositor gets new_size220 // No client frames "drawn" since resize(old_size), so compositor gets new_size
195 buffer_stream.swap_client_buffers(client);221 buffer_stream.swap_client_buffers_blocking(client);
196 auto comp4 = buffer_stream.lock_compositor_buffer(4);222 auto comp4 = buffer_stream.lock_compositor_buffer(4);
197 EXPECT_EQ(new_size, comp4->size());223 EXPECT_EQ(new_size, comp4->size());
198 comp4.reset();224 comp4.reset();
199225
200 // Generate a new frame, which should be back to old_size now226 // Generate a new frame, which should be back to old_size now
201 buffer_stream.swap_client_buffers(client);227 buffer_stream.swap_client_buffers_blocking(client);
202 auto comp5 = buffer_stream.lock_compositor_buffer(5);228 auto comp5 = buffer_stream.lock_compositor_buffer(5);
203 EXPECT_EQ(old_size, comp5->size());229 EXPECT_EQ(old_size, comp5->size());
204 comp5.reset();230 comp5.reset();
@@ -207,8 +233,8 @@
207TEST_F(BufferStreamTest, can_get_partly_released_back_buffer)233TEST_F(BufferStreamTest, can_get_partly_released_back_buffer)
208{234{
209 mg::Buffer* client{nullptr};235 mg::Buffer* client{nullptr};
210 buffer_stream.swap_client_buffers(client);236 buffer_stream.swap_client_buffers_blocking(client);
211 buffer_stream.swap_client_buffers(client);237 buffer_stream.swap_client_buffers_blocking(client);
212238
213 auto comp1 = buffer_stream.lock_compositor_buffer(123);239 auto comp1 = buffer_stream.lock_compositor_buffer(123);
214 auto comp2 = buffer_stream.lock_compositor_buffer(123);240 auto comp2 = buffer_stream.lock_compositor_buffer(123);
@@ -225,12 +251,12 @@
225namespace251namespace
226{252{
227253
228void client_loop(int nframes, mc::BufferStream& stream)254void client_loop(int nframes, BufferStreamSurfaces& stream)
229{255{
230 mg::Buffer* out_buffer{nullptr};256 mg::Buffer* out_buffer{nullptr};
231 for (int f = 0; f < nframes; f++)257 for (int f = 0; f < nframes; f++)
232 {258 {
233 stream.swap_client_buffers(out_buffer);259 stream.swap_client_buffers_blocking(out_buffer);
234 ASSERT_NE(nullptr, out_buffer);260 ASSERT_NE(nullptr, out_buffer);
235 std::this_thread::yield();261 std::this_thread::yield();
236 }262 }
237263
=== modified file 'tests/integration-tests/compositor/test_swapping_swappers.cpp'
--- tests/integration-tests/compositor/test_swapping_swappers.cpp 2014-01-13 06:12:33 +0000
+++ tests/integration-tests/compositor/test_swapping_swappers.cpp 2014-02-10 09:00:06 +0000
@@ -51,6 +51,31 @@
51 std::shared_ptr<mc::SwitchingBundle> switching_bundle;51 std::shared_ptr<mc::SwitchingBundle> switching_bundle;
52 std::atomic<bool> client_thread_done;52 std::atomic<bool> client_thread_done;
53};53};
54
55auto client_acquire_blocking(std::shared_ptr<mc::SwitchingBundle> const& switching_bundle)
56-> mg::Buffer*
57{
58 std::mutex mutex;
59 std::condition_variable cv;
60 bool done = false;
61
62 mg::Buffer* result;
63 switching_bundle->client_acquire(
64 [&](mg::Buffer* new_buffer)
65 {
66 std::unique_lock<decltype(mutex)> lock(mutex);
67
68 result = new_buffer;
69 done = true;
70 cv.notify_one();
71 });
72
73 std::unique_lock<decltype(mutex)> lock(mutex);
74
75 cv.wait(lock, [&]{ return done; });
76
77 return result;
78}
54}79}
5580
56TEST_F(SwapperSwappingStress, swapper)81TEST_F(SwapperSwappingStress, swapper)
@@ -62,7 +87,7 @@
62 {87 {
63 for(auto i=0u; i < 400; i++)88 for(auto i=0u; i < 400; i++)
64 {89 {
65 auto b = switching_bundle->client_acquire();90 auto b = client_acquire_blocking(switching_bundle);
66 std::this_thread::yield();91 std::this_thread::yield();
67 switching_bundle->client_release(b);92 switching_bundle->client_release(b);
68 }93 }
@@ -107,7 +132,7 @@
107 {132 {
108 for(auto i=0u; i < 400; i++)133 for(auto i=0u; i < 400; i++)
109 {134 {
110 auto b = switching_bundle->client_acquire();135 auto b = client_acquire_blocking(switching_bundle);
111 std::this_thread::yield();136 std::this_thread::yield();
112 switching_bundle->client_release(b);137 switching_bundle->client_release(b);
113 }138 }
114139
=== modified file 'tests/integration-tests/graphics/android/test_buffer_integration.cpp'
--- tests/integration-tests/graphics/android/test_buffer_integration.cpp 2014-01-13 06:12:33 +0000
+++ tests/integration-tests/graphics/android/test_buffer_integration.cpp 2014-02-10 09:00:06 +0000
@@ -55,6 +55,30 @@
55 mtd::TestGrallocMapper sw_renderer;55 mtd::TestGrallocMapper sw_renderer;
56};56};
5757
58auto client_acquire_blocking(mc::SwitchingBundle& switching_bundle)
59-> mg::Buffer*
60{
61 std::mutex mutex;
62 std::condition_variable cv;
63 bool done = false;
64
65 mg::Buffer* result;
66 switching_bundle.client_acquire(
67 [&](mg::Buffer* new_buffer)
68 {
69 std::unique_lock<decltype(mutex)> lock(mutex);
70
71 result = new_buffer;
72 done = true;
73 cv.notify_one();
74 });
75
76 std::unique_lock<decltype(mutex)> lock(mutex);
77
78 cv.wait(lock, [&]{ return done; });
79
80 return result;
81}
58}82}
5983
60TEST_F(AndroidBufferIntegration, allocator_can_create_sw_buffer)84TEST_F(AndroidBufferIntegration, allocator_can_create_sw_buffer)
@@ -92,7 +116,7 @@
92116
93 mc::SwitchingBundle swapper(2, allocator, buffer_properties);117 mc::SwitchingBundle swapper(2, allocator, buffer_properties);
94118
95 auto returned_buffer = swapper.client_acquire();119 auto returned_buffer = client_acquire_blocking(swapper);
96120
97 EXPECT_NE(nullptr, returned_buffer);121 EXPECT_NE(nullptr, returned_buffer);
98}122}
99123
=== modified file 'tests/integration-tests/graphics/android/test_display_integration.cpp'
--- tests/integration-tests/graphics/android/test_display_integration.cpp 2014-01-21 06:27:40 +0000
+++ tests/integration-tests/graphics/android/test_display_integration.cpp 2014-02-10 09:00:06 +0000
@@ -38,7 +38,7 @@
3838
39namespace39namespace
40{40{
41class AndroidGPUDisplay : public ::testing::Test41class AndroidDisplay : public ::testing::Test
42{42{
43protected:43protected:
44 static void SetUpTestCase()44 static void SetUpTestCase()
@@ -65,42 +65,17 @@
65 static void (*original_sigterm_handler)(int);65 static void (*original_sigterm_handler)(int);
66};66};
6767
68void (*AndroidGPUDisplay::original_sigterm_handler)(int);68void (*AndroidDisplay::original_sigterm_handler)(int);
69std::shared_ptr<mga::ResourceFactory> AndroidGPUDisplay::display_resource_factory;69std::shared_ptr<mga::ResourceFactory> AndroidDisplay::display_resource_factory;
70}70}
7171
72// disabled to unblock CI - see lp:123995572TEST_F(AndroidDisplay, display_can_post)
73TEST_F(AndroidGPUDisplay, DISABLED_gpu_display_ok_with_gles)73{
74{74 auto mock_display_report = std::make_shared<testing::NiceMock<mtd::MockDisplayReport>>();
75 auto should_use_fb_fallback = true;75 auto buffer_initializer = std::make_shared<mg::NullBufferInitializer>();
76 auto buffer_initializer = std::make_shared<mg::NullBufferInitializer>();76 auto fb_allocator = std::make_shared<mga::AndroidGraphicBufferAllocator>(buffer_initializer);
77 auto fb_allocator = std::make_shared<mga::AndroidGraphicBufferAllocator>(buffer_initializer);77 auto display_buffer_factory = std::make_shared<mga::OutputBuilder>(
78 auto mock_display_report = std::make_shared<testing::NiceMock<mtd::MockDisplayReport>>();78 fb_allocator, display_resource_factory, mock_display_report);
79 auto display_buffer_factory = std::make_shared<mga::OutputBuilder>(
80 fb_allocator, display_resource_factory, mock_display_report, should_use_fb_fallback);
81
82 mga::AndroidDisplay display(display_buffer_factory, mock_display_report);
83 display.for_each_display_buffer([this](mg::DisplayBuffer& buffer)
84 {
85 buffer.make_current();
86 gl_animation.init_gl();
87
88 gl_animation.render_gl();
89 buffer.post_update();
90
91 gl_animation.render_gl();
92 buffer.post_update();
93 });
94}
95
96TEST_F(AndroidGPUDisplay, hwc_display_ok_with_gles)
97{
98 auto should_use_fb_fallback = false;
99 auto mock_display_report = std::make_shared<testing::NiceMock<mtd::MockDisplayReport>>();
100 auto buffer_initializer = std::make_shared<mg::NullBufferInitializer>();
101 auto fb_allocator = std::make_shared<mga::AndroidGraphicBufferAllocator>(buffer_initializer);
102 auto display_buffer_factory = std::make_shared<mga::OutputBuilder>(
103 fb_allocator, display_resource_factory, mock_display_report, should_use_fb_fallback);
10479
105 mga::AndroidDisplay display(display_buffer_factory, mock_display_report);80 mga::AndroidDisplay display(display_buffer_factory, mock_display_report);
106 display.for_each_display_buffer([this](mg::DisplayBuffer& buffer)81 display.for_each_display_buffer([this](mg::DisplayBuffer& buffer)
10782
=== modified file 'tests/integration-tests/graphics/android/test_internal_client.cpp'
--- tests/integration-tests/graphics/android/test_internal_client.cpp 2014-01-13 06:12:33 +0000
+++ tests/integration-tests/graphics/android/test_internal_client.cpp 2014-02-10 09:00:06 +0000
@@ -98,8 +98,9 @@
98 auto ss = std::make_shared<ms::SurfaceStack>(surface_allocator, stub_input_registrar, scene_report);98 auto ss = std::make_shared<ms::SurfaceStack>(surface_allocator, stub_input_registrar, scene_report);
99 auto surface_controller = std::make_shared<ms::SurfaceController>(ss);99 auto surface_controller = std::make_shared<ms::SurfaceController>(ss);
100 auto surface_source = std::make_shared<ms::SurfaceSource>(surface_controller, std::make_shared<mtd::NullSurfaceConfigurator>());100 auto surface_source = std::make_shared<ms::SurfaceSource>(surface_controller, std::make_shared<mtd::NullSurfaceConfigurator>());
101 auto mir_surface = as_internal_surface(101 auto surface = surface_source->create_surface(nullptr, params, id, std::shared_ptr<mf::EventSink>());
102 surface_source->create_surface(nullptr, params, id, std::shared_ptr<mf::EventSink>()));102 surface->allow_framedropping(true);
103 auto mir_surface = as_internal_surface(surface);
103104
104 auto options = std::shared_ptr<mo::ProgramOption>();105 auto options = std::shared_ptr<mo::ProgramOption>();
105 auto report = std::shared_ptr<mg::NullDisplayReport>();106 auto report = std::shared_ptr<mg::NullDisplayReport>();
106107
=== modified file 'tests/integration-tests/test_display_server_main_loop_events.cpp'
--- tests/integration-tests/test_display_server_main_loop_events.cpp 2014-01-13 06:12:33 +0000
+++ tests/integration-tests/test_display_server_main_loop_events.cpp 2014-02-10 09:00:06 +0000
@@ -94,9 +94,11 @@
94 display->for_each_display_buffer(f);94 display->for_each_display_buffer(f);
95 }95 }
9696
97 std::shared_ptr<mg::DisplayConfiguration> configuration() override97 std::unique_ptr<mg::DisplayConfiguration> configuration() const override
98 {98 {
99 return display->configuration();99 return std::unique_ptr<mg::DisplayConfiguration>(
100 new mtd::NullDisplayConfiguration
101 );
100 }102 }
101103
102 MOCK_METHOD1(configure, void(mg::DisplayConfiguration const&));104 MOCK_METHOD1(configure, void(mg::DisplayConfiguration const&));
103105
=== modified file 'tests/integration-tests/test_session.cpp'
--- tests/integration-tests/test_session.cpp 2014-01-14 07:02:27 +0000
+++ tests/integration-tests/test_session.cpp 2014-02-10 09:00:06 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright © 2013 Canonical Ltd.2 * Copyright © 2013-2014 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify4 * 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 as5 * it under the terms of the GNU General Public License version 3 as
@@ -170,6 +170,7 @@
170170
171 ms::ApplicationSession session{171 ms::ApplicationSession session{
172 conf.the_shell_surface_factory(),172 conf.the_shell_surface_factory(),
173 __LINE__,
173 "stress",174 "stress",
174 conf.the_snapshot_strategy(),175 conf.the_snapshot_strategy(),
175 std::make_shared<msh::NullSessionListener>(),176 std::make_shared<msh::NullSessionListener>(),
@@ -189,7 +190,7 @@
189 for (int i = 0; i < 500; ++i)190 for (int i = 0; i < 500; ++i)
190 {191 {
191 auto surface = session.default_surface();192 auto surface = session.default_surface();
192 surface->swap_buffers(buffer);193 surface->swap_buffers_blocking(buffer);
193 std::this_thread::sleep_for(std::chrono::microseconds{50});194 std::this_thread::sleep_for(std::chrono::microseconds{50});
194 }195 }
195 }};196 }};
196197
=== modified file 'tests/integration-tests/test_session_manager.cpp'
--- tests/integration-tests/test_session_manager.cpp 2014-01-13 06:12:33 +0000
+++ tests/integration-tests/test_session_manager.cpp 2014-02-10 09:00:06 +0000
@@ -76,9 +76,9 @@
7676
77 EXPECT_CALL(focus_setter, set_focus_to(_)).Times(3);77 EXPECT_CALL(focus_setter, set_focus_to(_)).Times(3);
7878
79 auto session1 = session_manager.open_session("Visual Basic Studio", std::make_shared<mtd::NullEventSink>());79 auto session1 = session_manager.open_session(__LINE__, "Visual Basic Studio", std::make_shared<mtd::NullEventSink>());
80 auto session2 = session_manager.open_session("Microsoft Access", std::make_shared<mtd::NullEventSink>());80 auto session2 = session_manager.open_session(__LINE__, "Microsoft Access", std::make_shared<mtd::NullEventSink>());
81 auto session3 = session_manager.open_session("WordPerfect", std::make_shared<mtd::NullEventSink>());81 auto session3 = session_manager.open_session(__LINE__, "WordPerfect", std::make_shared<mtd::NullEventSink>());
8282
83 Mock::VerifyAndClearExpectations(&focus_setter);83 Mock::VerifyAndClearExpectations(&focus_setter);
8484
@@ -105,9 +105,9 @@
105105
106 EXPECT_CALL(focus_setter, set_focus_to(_)).Times(3);106 EXPECT_CALL(focus_setter, set_focus_to(_)).Times(3);
107107
108 auto session1 = session_manager.open_session("Visual Basic Studio", std::make_shared<mtd::NullEventSink>());108 auto session1 = session_manager.open_session(__LINE__, "Visual Basic Studio", std::make_shared<mtd::NullEventSink>());
109 auto session2 = session_manager.open_session("Microsoft Access", std::make_shared<mtd::NullEventSink>());109 auto session2 = session_manager.open_session(__LINE__, "Microsoft Access", std::make_shared<mtd::NullEventSink>());
110 auto session3 = session_manager.open_session("WordPerfect", std::make_shared<mtd::NullEventSink>());110 auto session3 = session_manager.open_session(__LINE__, "WordPerfect", std::make_shared<mtd::NullEventSink>());
111111
112 Mock::VerifyAndClearExpectations(&focus_setter);112 Mock::VerifyAndClearExpectations(&focus_setter);
113113
114114
=== modified file 'tests/integration-tests/test_swapinterval.cpp'
--- tests/integration-tests/test_swapinterval.cpp 2014-01-13 06:12:33 +0000
+++ tests/integration-tests/test_swapinterval.cpp 2014-02-10 09:00:06 +0000
@@ -56,14 +56,22 @@
56 {56 {
57 }57 }
5858
59 void swap_client_buffers(mg::Buffer*& buffer) { buffer = &stub_buffer; }59 void swap_client_buffers(mg::Buffer*, std::function<void(mg::Buffer* new_buffer)> complete) override
60 std::shared_ptr<mg::Buffer> lock_compositor_buffer(unsigned long) { return std::make_shared<mtd::StubBuffer>(); }60 { complete(&stub_buffer); }
61 std::shared_ptr<mg::Buffer> lock_snapshot_buffer() { return std::make_shared<mtd::StubBuffer>(); }61
62 MirPixelFormat get_stream_pixel_format() { return mir_pixel_format_abgr_8888; }62 std::shared_ptr<mg::Buffer> lock_compositor_buffer(unsigned long) override
63 geom::Size stream_size() { return geom::Size{}; }63 { return std::make_shared<mtd::StubBuffer>(); }
64
65 std::shared_ptr<mg::Buffer> lock_snapshot_buffer() override
66 { return std::make_shared<mtd::StubBuffer>(); }
67
68 MirPixelFormat get_stream_pixel_format() override
69 { return mir_pixel_format_abgr_8888; }
70
71 geom::Size stream_size() override { return geom::Size{}; }
64 void resize(geom::Size const&) override {}72 void resize(geom::Size const&) override {}
65 void force_requests_to_complete() {}73 void force_requests_to_complete() override {}
66 void allow_framedropping(bool)74 void allow_framedropping(bool) override
67 {75 {
68 while (write(render_operations_fd, "a", 1) != 1) continue;76 while (write(render_operations_fd, "a", 1) != 1) continue;
69 }77 }
7078
=== modified file 'tests/mir_test_framework/stubbed_server_configuration.cpp'
--- tests/mir_test_framework/stubbed_server_configuration.cpp 2014-01-29 12:51:30 +0000
+++ tests/mir_test_framework/stubbed_server_configuration.cpp 2014-02-10 09:00:06 +0000
@@ -120,7 +120,7 @@
120class StubDisplayConfiguration : public mtd::NullDisplayConfiguration120class StubDisplayConfiguration : public mtd::NullDisplayConfiguration
121{121{
122public:122public:
123 StubDisplayConfiguration(geom::Rectangle& rect)123 StubDisplayConfiguration(geom::Rectangle const& rect)
124 : modes{mg::DisplayConfigurationMode{rect.size, 1.0f}}124 : modes{mg::DisplayConfigurationMode{rect.size, 1.0f}}
125 {125 {
126 }126 }
@@ -156,9 +156,11 @@
156 f(display_buffer);156 f(display_buffer);
157 }157 }
158158
159 std::shared_ptr<mg::DisplayConfiguration> configuration() override159 std::unique_ptr<mg::DisplayConfiguration> configuration() const override
160 {160 {
161 return std::make_shared<StubDisplayConfiguration>(rect);161 return std::unique_ptr<mg::DisplayConfiguration>(
162 new StubDisplayConfiguration(rect)
163 );
162 }164 }
163165
164private:166private:
165167
=== modified file 'tests/unit-tests/client/test_mir_screencast.cpp'
--- tests/unit-tests/client/test_mir_screencast.cpp 2014-01-24 18:11:19 +0000
+++ tests/unit-tests/client/test_mir_screencast.cpp 2014-02-10 09:00:06 +0000
@@ -67,12 +67,17 @@
67 void create_screencast(67 void create_screencast(
68 google::protobuf::RpcController* /*controller*/,68 google::protobuf::RpcController* /*controller*/,
69 mp::ScreencastParameters const* /*request*/,69 mp::ScreencastParameters const* /*request*/,
70 mp::Screencast* /*response*/,70 mp::Screencast* response,
71 google::protobuf::Closure* done) override71 google::protobuf::Closure* done) override
72 {72 {
73 if (server_thread.joinable())73 if (server_thread.joinable())
74 server_thread.join();74 server_thread.join();
75 server_thread = std::thread{[done, this] { done->Run(); }};75 server_thread = std::thread{
76 [response, done, this]
77 {
78 response->clear_error();
79 done->Run();
80 }};
76 }81 }
7782
78 void release_screencast(83 void release_screencast(
@@ -151,6 +156,7 @@
151156
152ACTION_P(SetCreateScreencastId, screencast_id)157ACTION_P(SetCreateScreencastId, screencast_id)
153{158{
159 arg2->clear_error();
154 arg2->mutable_screencast_id()->set_value(screencast_id);160 arg2->mutable_screencast_id()->set_value(screencast_id);
155}161}
156162
@@ -166,6 +172,7 @@
166172
167ACTION_P(SetCreateBufferFromPackage, package)173ACTION_P(SetCreateBufferFromPackage, package)
168{174{
175 arg2->clear_error();
169 auto buffer = arg2->mutable_buffer();176 auto buffer = arg2->mutable_buffer();
170 for (int i = 0; i != package.data_items; ++i)177 for (int i = 0; i != package.data_items; ++i)
171 {178 {
@@ -180,6 +187,11 @@
180 buffer->set_stride(package.stride);187 buffer->set_stride(package.stride);
181}188}
182189
190ACTION(SetCreateError)
191{
192 arg2->set_error("Test error");
193}
194
183ACTION(RunClosure)195ACTION(RunClosure)
184{196{
185 arg3->Run();197 arg3->Run();
@@ -521,3 +533,41 @@
521533
522 EXPECT_EQ(StubEGLNativeWindowFactory::egl_native_window, egl_native_window);534 EXPECT_EQ(StubEGLNativeWindowFactory::egl_native_window, egl_native_window);
523}535}
536
537TEST_F(MirScreencastTest, is_invalid_if_server_create_screencast_fails)
538{
539 using namespace testing;
540
541 EXPECT_CALL(mock_server, create_screencast(_,_,_,_))
542 .WillOnce(DoAll(SetCreateError(), RunClosure()));
543
544 MirScreencast screencast{
545 default_mir_output, mock_server,
546 stub_egl_native_window_factory,
547 stub_client_buffer_factory,
548 null_callback_func, nullptr};
549
550 screencast.creation_wait_handle()->wait_for_all();
551
552 EXPECT_FALSE(screencast.valid());
553}
554
555TEST_F(MirScreencastTest, calls_callback_on_creation_failure)
556{
557 using namespace testing;
558
559 MockCallback mock_cb;
560 EXPECT_CALL(mock_server, create_screencast(_,_,_,_))
561 .WillOnce(DoAll(SetCreateError(), RunClosure()));
562 EXPECT_CALL(mock_cb, call(_,&mock_cb));
563
564 MirScreencast screencast{
565 default_mir_output, mock_server,
566 stub_egl_native_window_factory,
567 stub_client_buffer_factory,
568 mock_callback_func, &mock_cb};
569
570 screencast.creation_wait_handle()->wait_for_all();
571
572 EXPECT_FALSE(screencast.valid());
573}
524574
=== modified file 'tests/unit-tests/compositor/test_buffer_stream.cpp'
--- tests/unit-tests/compositor/test_buffer_stream.cpp 2014-01-13 06:12:33 +0000
+++ tests/unit-tests/compositor/test_buffer_stream.cpp 2014-02-10 09:00:06 +0000
@@ -25,6 +25,8 @@
25#include <gmock/gmock.h>25#include <gmock/gmock.h>
26#include <gtest/gtest.h>26#include <gtest/gtest.h>
2727
28#include <condition_variable>
29
28namespace mc = mir::compositor;30namespace mc = mir::compositor;
29namespace mg = mir::graphics;31namespace mg = mir::graphics;
30namespace geom = mir::geometry;32namespace geom = mir::geometry;
@@ -122,22 +124,50 @@
122124
123TEST_F(BufferStreamTest, get_buffer_for_client_releases_resources)125TEST_F(BufferStreamTest, get_buffer_for_client_releases_resources)
124{126{
125 using namespace testing;127 std::mutex mutex;
126 mc::BufferStreamSurfaces buffer_stream(mock_bundle);128 std::condition_variable cv;
127 mg::Buffer* buffer{nullptr};129 mg::Buffer* buffer{nullptr};
130 bool done = false;
131
132 auto const callback =
133 [&](mg::Buffer* new_buffer)
134 {
135 std::unique_lock<decltype(mutex)> lock(mutex);
136 buffer = new_buffer;
137 done = true;
138 cv.notify_one();
139 };
140
141 using namespace testing;
142 mc::BufferStreamSurfaces buffer_stream(mock_bundle);
128143
129 InSequence seq;144 InSequence seq;
130 EXPECT_CALL(*mock_bundle, client_acquire())145 EXPECT_CALL(*mock_bundle, client_acquire(_))
131 .Times(1)146 .Times(1)
132 .WillOnce(Return(mock_buffer.get()));147 .WillOnce(InvokeArgument<0>(mock_buffer.get()));
133 EXPECT_CALL(*mock_bundle, client_release(_))148 EXPECT_CALL(*mock_bundle, client_release(_))
134 .Times(1);149 .Times(1);
135 EXPECT_CALL(*mock_bundle, client_acquire())150 EXPECT_CALL(*mock_bundle, client_acquire(_))
136 .Times(1)151 .Times(1)
137 .WillOnce(Return(mock_buffer.get()));152 .WillOnce(InvokeArgument<0>(mock_buffer.get()));
138153
139 buffer_stream.swap_client_buffers(buffer);154 buffer_stream.swap_client_buffers(buffer, callback);
140 buffer_stream.swap_client_buffers(buffer);155
156 {
157 std::unique_lock<decltype(mutex)> lock(mutex);
158
159 cv.wait(lock, [&]{ return done; });
160 }
161
162 done = false;
163
164 buffer_stream.swap_client_buffers(buffer, callback);
165
166 {
167 std::unique_lock<decltype(mutex)> lock(mutex);
168
169 cv.wait(lock, [&]{ return done; });
170 }
141}171}
142172
143TEST_F(BufferStreamTest, allow_framedropping_device)173TEST_F(BufferStreamTest, allow_framedropping_device)
144174
=== modified file 'tests/unit-tests/compositor/test_switching_bundle.cpp'
--- tests/unit-tests/compositor/test_switching_bundle.cpp 2014-01-22 14:15:29 +0000
+++ tests/unit-tests/compositor/test_switching_bundle.cpp 2014-02-10 09:00:06 +0000
@@ -34,6 +34,8 @@
3434
35using namespace testing;35using namespace testing;
3636
37namespace
38{
37struct SwitchingBundleTest : public ::testing::Test39struct SwitchingBundleTest : public ::testing::Test
38{40{
39 void SetUp()41 void SetUp()
@@ -52,6 +54,32 @@
52 mg::BufferProperties basic_properties;54 mg::BufferProperties basic_properties;
53};55};
5456
57auto client_acquire_blocking(mc::SwitchingBundle& switching_bundle)
58-> mg::Buffer*
59{
60 std::mutex mutex;
61 std::condition_variable cv;
62 bool done = false;
63
64 mg::Buffer* result;
65 switching_bundle.client_acquire(
66 [&](mg::Buffer* new_buffer)
67 {
68 std::unique_lock<decltype(mutex)> lock(mutex);
69
70 result = new_buffer;
71 done = true;
72 cv.notify_one();
73 });
74
75 std::unique_lock<decltype(mutex)> lock(mutex);
76
77 cv.wait(lock, [&]{ return done; });
78
79 return result;
80}
81}
82
55TEST_F(SwitchingBundleTest, sync_swapper_by_default)83TEST_F(SwitchingBundleTest, sync_swapper_by_default)
56{84{
57 mg::BufferProperties properties{geom::Size{7, 8},85 mg::BufferProperties properties{geom::Size{7, 8},
@@ -100,7 +128,7 @@
100 {128 {
101 mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties);129 mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties);
102130
103 auto buffer = bundle.client_acquire();131 auto buffer = client_acquire_blocking(bundle);
104 bundle.client_release(buffer);132 bundle.client_release(buffer);
105 }133 }
106}134}
@@ -132,7 +160,7 @@
132160
133 for (int i = 0; i < 20; i++)161 for (int i = 0; i < 20; i++)
134 {162 {
135 auto client1 = bundle.client_acquire();163 auto client1 = client_acquire_blocking(bundle);
136 mg::BufferID expect_id = client1->id(), composited_id;164 mg::BufferID expect_id = client1->id(), composited_id;
137 bundle.client_release(client1);165 bundle.client_release(client1);
138166
@@ -173,7 +201,7 @@
173 {201 {
174 for (int j = 0; j < 100; j++)202 for (int j = 0; j < 100; j++)
175 {203 {
176 auto client = bundle.client_acquire();204 auto client = client_acquire_blocking(bundle);
177 last_client_id = client->id();205 last_client_id = client->id();
178 bundle.client_release(client);206 bundle.client_release(client);
179 }207 }
@@ -197,11 +225,11 @@
197{ // Regression test for LP: #1210042225{ // Regression test for LP: #1210042
198 mc::SwitchingBundle bundle(3, allocator, basic_properties);226 mc::SwitchingBundle bundle(3, allocator, basic_properties);
199227
200 auto client1 = bundle.client_acquire();228 auto client1 = client_acquire_blocking(bundle);
201 auto client1_id = client1->id();229 auto client1_id = client1->id();
202 bundle.client_release(client1);230 bundle.client_release(client1);
203231
204 auto client2 = bundle.client_acquire();232 auto client2 = client_acquire_blocking(bundle);
205 bundle.client_release(client2);233 bundle.client_release(client2);
206234
207 auto compositor = bundle.compositor_acquire(1);235 auto compositor = bundle.compositor_acquire(1);
@@ -217,8 +245,8 @@
217 {245 {
218 mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties);246 mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties);
219247
220 auto client1 = bundle.client_acquire();248 auto client1 = client_acquire_blocking(bundle);
221 auto client2 = bundle.client_acquire();249 auto client2 = client_acquire_blocking(bundle);
222 EXPECT_THROW(250 EXPECT_THROW(
223 bundle.client_release(client2),251 bundle.client_release(client2),
224 std::logic_error252 std::logic_error
@@ -241,7 +269,7 @@
241 mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties);269 mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties);
242 unsigned long frameno = 0;270 unsigned long frameno = 0;
243271
244 auto client = bundle.client_acquire();272 auto client = client_acquire_blocking(bundle);
245 auto client_id = client->id();273 auto client_id = client->id();
246 bundle.client_release(client);274 bundle.client_release(client);
247275
@@ -291,7 +319,7 @@
291 {319 {
292 if (i % 10 == 0)320 if (i % 10 == 0)
293 {321 {
294 auto client = bundle.client_acquire();322 auto client = client_acquire_blocking(bundle);
295 client_id = client->id();323 client_id = client->id();
296 bundle.client_release(client);324 bundle.client_release(client);
297 }325 }
@@ -317,7 +345,7 @@
317 mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties);345 mc::SwitchingBundle bundle(nbuffers, allocator, basic_properties);
318 unsigned long frameno = 0;346 unsigned long frameno = 0;
319347
320 auto client = bundle.client_acquire();348 auto client = client_acquire_blocking(bundle);
321 bundle.client_release(client);349 bundle.client_release(client);
322350
323 auto compositor1 = bundle.compositor_acquire(++frameno);351 auto compositor1 = bundle.compositor_acquire(++frameno);
@@ -342,11 +370,11 @@
342 mg::Buffer* client_buffer = nullptr;370 mg::Buffer* client_buffer = nullptr;
343 std::shared_ptr<mg::Buffer> compositor_buffer = nullptr;371 std::shared_ptr<mg::Buffer> compositor_buffer = nullptr;
344372
345 client_buffer = bundle.client_acquire();373 client_buffer = client_acquire_blocking(bundle);
346 mg::BufferID first_ready_buffer_id = client_buffer->id();374 mg::BufferID first_ready_buffer_id = client_buffer->id();
347 bundle.client_release(client_buffer);375 bundle.client_release(client_buffer);
348376
349 client_buffer = bundle.client_acquire();377 client_buffer = client_acquire_blocking(bundle);
350378
351 // in the original bug, compositor would be given the wrong buffer here379 // in the original bug, compositor would be given the wrong buffer here
352 compositor_buffer = bundle.compositor_acquire(0 /*frameno*/);380 compositor_buffer = bundle.compositor_acquire(0 /*frameno*/);
@@ -371,11 +399,11 @@
371399
372 std::shared_ptr<mg::Buffer> compositor[2];400 std::shared_ptr<mg::Buffer> compositor[2];
373401
374 bundle.client_release(bundle.client_acquire());402 bundle.client_release(client_acquire_blocking(bundle));
375 compositor[0] = bundle.compositor_acquire(frameno);403 compositor[0] = bundle.compositor_acquire(frameno);
376404
377 frameno++;405 frameno++;
378 bundle.client_release(bundle.client_acquire());406 bundle.client_release(client_acquire_blocking(bundle));
379 compositor[1] = bundle.compositor_acquire(frameno);407 compositor[1] = bundle.compositor_acquire(frameno);
380408
381 for (int i = 0; i < 20; i++)409 for (int i = 0; i < 20; i++)
@@ -386,7 +414,7 @@
386 // One of the compositors (the oldest one) gets a new buffer...414 // One of the compositors (the oldest one) gets a new buffer...
387 int oldest = i & 1;415 int oldest = i & 1;
388 bundle.compositor_release(compositor[oldest]);416 bundle.compositor_release(compositor[oldest]);
389 bundle.client_release(bundle.client_acquire());417 bundle.client_release(client_acquire_blocking(bundle));
390 frameno++;418 frameno++;
391 compositor[oldest] = bundle.compositor_acquire(frameno);419 compositor[oldest] = bundle.compositor_acquire(frameno);
392 }420 }
@@ -445,7 +473,7 @@
445 std::logic_error473 std::logic_error
446 );474 );
447475
448 auto client = bundle.client_acquire();476 auto client = client_acquire_blocking(bundle);
449 auto snapshot = bundle.snapshot_acquire();477 auto snapshot = bundle.snapshot_acquire();
450478
451 EXPECT_EQ(compositor->id(), snapshot->id());479 EXPECT_EQ(compositor->id(), snapshot->id());
@@ -488,7 +516,7 @@
488 {516 {
489 for (int i = 0; i < nframes; i++)517 for (int i = 0; i < nframes; i++)
490 {518 {
491 bundle.client_release(bundle.client_acquire());519 bundle.client_release(client_acquire_blocking(bundle));
492 std::this_thread::yield();520 std::this_thread::yield();
493 }521 }
494 }522 }
@@ -499,12 +527,12 @@
499 {527 {
500 bundle.allow_framedropping(false);528 bundle.allow_framedropping(false);
501 for (int j = 0; j < 5; j++)529 for (int j = 0; j < 5; j++)
502 bundle.client_release(bundle.client_acquire());530 bundle.client_release(client_acquire_blocking(bundle));
503 std::this_thread::yield();531 std::this_thread::yield();
504532
505 bundle.allow_framedropping(true);533 bundle.allow_framedropping(true);
506 for (int j = 0; j < 5; j++)534 for (int j = 0; j < 5; j++)
507 bundle.client_release(bundle.client_acquire());535 bundle.client_release(client_acquire_blocking(bundle));
508 std::this_thread::yield();536 std::this_thread::yield();
509 }537 }
510 }538 }
@@ -602,11 +630,11 @@
602630
603 std::shared_ptr<mg::Buffer> compositor[2];631 std::shared_ptr<mg::Buffer> compositor[2];
604632
605 bundle.client_release(bundle.client_acquire());633 bundle.client_release(client_acquire_blocking(bundle));
606 compositor[0] = bundle.compositor_acquire(frameno);634 compositor[0] = bundle.compositor_acquire(frameno);
607635
608 frameno++;636 frameno++;
609 bundle.client_release(bundle.client_acquire());637 bundle.client_release(client_acquire_blocking(bundle));
610 compositor[1] = bundle.compositor_acquire(frameno);638 compositor[1] = bundle.compositor_acquire(frameno);
611639
612 for (int i = 0; i < 20; i++)640 for (int i = 0; i < 20; i++)
@@ -614,7 +642,7 @@
614 // Two compositors acquired, and they're always different...642 // Two compositors acquired, and they're always different...
615 ASSERT_NE(compositor[0]->id(), compositor[1]->id());643 ASSERT_NE(compositor[0]->id(), compositor[1]->id());
616644
617 auto client = bundle.client_acquire();645 auto client = client_acquire_blocking(bundle);
618 ASSERT_NE(compositor[0]->id(), client->id());646 ASSERT_NE(compositor[0]->id(), client->id());
619 ASSERT_NE(compositor[1]->id(), client->id());647 ASSERT_NE(compositor[1]->id(), client->id());
620 bundle.client_release(client);648 bundle.client_release(client);
@@ -648,7 +676,7 @@
648676
649 for (int b = 0; b < nbuffers; b++)677 for (int b = 0; b < nbuffers; b++)
650 {678 {
651 buf[b] = bundle.client_acquire();679 buf[b] = client_acquire_blocking(bundle);
652 expect[b] = buf[b]->id();680 expect[b] = buf[b]->id();
653681
654 for (int p = 0; p < b; p++)682 for (int p = 0; p < b; p++)
@@ -660,7 +688,7 @@
660688
661 for (int frame = 0; frame < nframes; frame++)689 for (int frame = 0; frame < nframes; frame++)
662 {690 {
663 auto client = bundle.client_acquire();691 auto client = client_acquire_blocking(bundle);
664 ASSERT_EQ(expect[frame % nbuffers], client->id());692 ASSERT_EQ(expect[frame % nbuffers], client->id());
665 bundle.client_release(client);693 bundle.client_release(client);
666 }694 }
@@ -739,11 +767,11 @@
739 }767 }
740 });768 });
741769
742 bundle.client_release(bundle.client_acquire());770 bundle.client_release(client_acquire_blocking(bundle));
743771
744 while (!done.load())772 while (!done.load())
745 {773 {
746 bundle.client_release(bundle.client_acquire());774 bundle.client_release(client_acquire_blocking(bundle));
747 client_frames++;775 client_frames++;
748 }776 }
749777
@@ -789,13 +817,13 @@
789 }817 }
790 });818 });
791819
792 bundle.client_release(bundle.client_acquire());820 bundle.client_release(client_acquire_blocking(bundle));
793821
794 while (!done.load())822 while (!done.load())
795 {823 {
796 sync.lock();824 sync.lock();
797 sync.unlock();825 sync.unlock();
798 auto buf = bundle.client_acquire();826 auto buf = client_acquire_blocking(bundle);
799 std::this_thread::sleep_for(frame_time);827 std::this_thread::sleep_for(frame_time);
800 bundle.client_release(buf);828 bundle.client_release(buf);
801 client_frames++;829 client_frames++;
@@ -825,7 +853,7 @@
825 for (int subframe = 0; subframe < 3; ++subframe)853 for (int subframe = 0; subframe < 3; ++subframe)
826 {854 {
827 bundle.resize(expect_size);855 bundle.resize(expect_size);
828 auto client = bundle.client_acquire();856 auto client = client_acquire_blocking(bundle);
829 ASSERT_EQ(expect_size, client->size());857 ASSERT_EQ(expect_size, client->size());
830 bundle.client_release(client);858 bundle.client_release(client);
831859
@@ -861,7 +889,7 @@
861 height += dy;889 height += dy;
862890
863 bundle.resize(new_size);891 bundle.resize(new_size);
864 auto client = bundle.client_acquire();892 auto client = client_acquire_blocking(bundle);
865 history[produce] = client->id();893 history[produce] = client->id();
866 ASSERT_EQ(new_size, client->size());894 ASSERT_EQ(new_size, client->size());
867 bundle.client_release(client);895 bundle.client_release(client);
868896
=== modified file 'tests/unit-tests/compositor/test_temporary_buffers.cpp'
--- tests/unit-tests/compositor/test_temporary_buffers.cpp 2014-01-13 06:12:33 +0000
+++ tests/unit-tests/compositor/test_temporary_buffers.cpp 2014-02-10 09:00:06 +0000
@@ -52,8 +52,8 @@
52 {52 {
53 using namespace testing;53 using namespace testing;
5454
55 ON_CALL(*mock_bundle, client_acquire())55 ON_CALL(*mock_bundle, client_acquire(_))
56 .WillByDefault(Return(mock_buffer.get()));56 .WillByDefault(InvokeArgument<0>(mock_buffer.get()));
57 ON_CALL(*mock_bundle, compositor_acquire(_))57 ON_CALL(*mock_bundle, compositor_acquire(_))
58 .WillByDefault(Return(mock_buffer));58 .WillByDefault(Return(mock_buffer));
59 }59 }
6060
=== modified file 'tests/unit-tests/frontend/test_session_mediator.cpp'
--- tests/unit-tests/frontend/test_session_mediator.cpp 2014-01-13 06:55:38 +0000
+++ tests/unit-tests/frontend/test_session_mediator.cpp 2014-02-10 09:00:06 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright © 2012 Canonical Ltd.2 * Copyright © 2012-2014 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify4 * 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 as5 * it under the terms of the GNU General Public License version 3 as
@@ -39,6 +39,7 @@
39#include "mir_test_doubles/stub_surface_builder.h"39#include "mir_test_doubles/stub_surface_builder.h"
40#include "mir_test_doubles/stub_display_configuration.h"40#include "mir_test_doubles/stub_display_configuration.h"
41#include "mir_test_doubles/stub_buffer_allocator.h"41#include "mir_test_doubles/stub_buffer_allocator.h"
42#include "mir_test_doubles/null_screencast.h"
42#include "mir_test/display_config_matchers.h"43#include "mir_test/display_config_matchers.h"
43#include "mir_test/fake_shared.h"44#include "mir_test/fake_shared.h"
44#include "mir/frontend/event_sink.h"45#include "mir/frontend/event_sink.h"
@@ -103,7 +104,8 @@
103104
104 EXPECT_CALL(*mock_surface, size()).Times(AnyNumber()).WillRepeatedly(Return(geom::Size()));105 EXPECT_CALL(*mock_surface, size()).Times(AnyNumber()).WillRepeatedly(Return(geom::Size()));
105 EXPECT_CALL(*mock_surface, pixel_format()).Times(AnyNumber()).WillRepeatedly(Return(MirPixelFormat()));106 EXPECT_CALL(*mock_surface, pixel_format()).Times(AnyNumber()).WillRepeatedly(Return(MirPixelFormat()));
106 EXPECT_CALL(*mock_surface, swap_buffers(_)).Times(AnyNumber()).WillRepeatedly(SetArg<0>(mock_buffer.get()));107 EXPECT_CALL(*mock_surface, swap_buffers(_, _)).Times(AnyNumber())
108 .WillRepeatedly(InvokeArgument<1>(mock_buffer.get()));
107109
108 EXPECT_CALL(*mock_surface, supports_input()).Times(AnyNumber()).WillRepeatedly(Return(true));110 EXPECT_CALL(*mock_surface, supports_input()).Times(AnyNumber()).WillRepeatedly(Return(true));
109 EXPECT_CALL(*mock_surface, client_input_fd()).Times(AnyNumber()).WillRepeatedly(Return(testing_client_input_fd));111 EXPECT_CALL(*mock_surface, client_input_fd()).Times(AnyNumber()).WillRepeatedly(Return(testing_client_input_fd));
@@ -123,7 +125,8 @@
123125
124 EXPECT_CALL(*mock_surfaces[id], size()).Times(AnyNumber()).WillRepeatedly(Return(geom::Size()));126 EXPECT_CALL(*mock_surfaces[id], size()).Times(AnyNumber()).WillRepeatedly(Return(geom::Size()));
125 EXPECT_CALL(*mock_surfaces[id], pixel_format()).Times(AnyNumber()).WillRepeatedly(Return(MirPixelFormat()));127 EXPECT_CALL(*mock_surfaces[id], pixel_format()).Times(AnyNumber()).WillRepeatedly(Return(MirPixelFormat()));
126 EXPECT_CALL(*mock_surfaces[id], swap_buffers(_)).Times(AnyNumber()).WillRepeatedly(SetArg<0>(mock_buffer.get()));128 EXPECT_CALL(*mock_surfaces[id], swap_buffers(_, _)).Times(AnyNumber())
129 .WillRepeatedly(InvokeArgument<1>(mock_buffer.get()));
127130
128 EXPECT_CALL(*mock_surfaces[id], supports_input()).Times(AnyNumber()).WillRepeatedly(Return(true));131 EXPECT_CALL(*mock_surfaces[id], supports_input()).Times(AnyNumber()).WillRepeatedly(Return(true));
129 EXPECT_CALL(*mock_surfaces[id], client_input_fd()).Times(AnyNumber()).WillRepeatedly(Return(testing_client_input_fd));132 EXPECT_CALL(*mock_surfaces[id], client_input_fd()).Times(AnyNumber()).WillRepeatedly(Return(testing_client_input_fd));
@@ -183,6 +186,16 @@
183 MOCK_CONST_METHOD0(egl_native_display, EGLNativeDisplayType());186 MOCK_CONST_METHOD0(egl_native_display, EGLNativeDisplayType());
184};187};
185188
189struct StubScreencast : mtd::NullScreencast
190{
191 std::shared_ptr<mg::Buffer> capture(mf::ScreencastSessionId)
192 {
193 return mt::fake_shared(stub_buffer);
194 }
195
196 mtd::StubBuffer stub_buffer;
197};
198
186struct SessionMediatorTest : public ::testing::Test199struct SessionMediatorTest : public ::testing::Test
187{200{
188 SessionMediatorTest()201 SessionMediatorTest()
@@ -192,16 +205,17 @@
192 surface_pixel_formats{mir_pixel_format_argb_8888, mir_pixel_format_xrgb_8888},205 surface_pixel_formats{mir_pixel_format_argb_8888, mir_pixel_format_xrgb_8888},
193 report{std::make_shared<mf::NullSessionMediatorReport>()},206 report{std::make_shared<mf::NullSessionMediatorReport>()},
194 resource_cache{std::make_shared<mf::ResourceCache>()},207 resource_cache{std::make_shared<mf::ResourceCache>()},
195 mediator{shell, graphics_platform, graphics_changer,208 stub_screencast{std::make_shared<StubScreencast>()},
209 mediator{__LINE__, shell, graphics_platform, graphics_changer,
196 surface_pixel_formats, report,210 surface_pixel_formats, report,
197 std::make_shared<mtd::NullEventSink>(),211 std::make_shared<mtd::NullEventSink>(),
198 resource_cache},212 resource_cache, stub_screencast},
199 stubbed_session{std::make_shared<StubbedSession>()},213 stubbed_session{std::make_shared<StubbedSession>()},
200 null_callback{google::protobuf::NewPermanentCallback(google::protobuf::DoNothing)}214 null_callback{google::protobuf::NewPermanentCallback(google::protobuf::DoNothing)}
201 {215 {
202 using namespace ::testing;216 using namespace ::testing;
203217
204 ON_CALL(*shell, open_session(_, _)).WillByDefault(Return(stubbed_session));218 ON_CALL(*shell, open_session(_, _, _)).WillByDefault(Return(stubbed_session));
205 ON_CALL(*shell, create_surface_for(_, _))219 ON_CALL(*shell, create_surface_for(_, _))
206 .WillByDefault(WithArg<1>(Invoke(stubbed_session.get(), &StubbedSession::create_surface)));220 .WillByDefault(WithArg<1>(Invoke(stubbed_session.get(), &StubbedSession::create_surface)));
207 }221 }
@@ -212,6 +226,7 @@
212 std::vector<MirPixelFormat> const surface_pixel_formats;226 std::vector<MirPixelFormat> const surface_pixel_formats;
213 std::shared_ptr<mf::SessionMediatorReport> const report;227 std::shared_ptr<mf::SessionMediatorReport> const report;
214 std::shared_ptr<mf::ResourceCache> const resource_cache;228 std::shared_ptr<mf::ResourceCache> const resource_cache;
229 std::shared_ptr<StubScreencast> const stub_screencast;
215 mf::SessionMediator mediator;230 mf::SessionMediator mediator;
216 std::shared_ptr<StubbedSession> const stubbed_session;231 std::shared_ptr<StubbedSession> const stubbed_session;
217232
@@ -355,10 +370,10 @@
355 .Times(1)370 .Times(1)
356 .WillOnce(Return(mt::fake_shared(config)));371 .WillOnce(Return(mt::fake_shared(config)));
357 mf::SessionMediator mediator(372 mf::SessionMediator mediator(
358 shell, graphics_platform, mock_display,373 __LINE__, shell, graphics_platform, mock_display,
359 surface_pixel_formats, report,374 surface_pixel_formats, report,
360 std::make_shared<mtd::NullEventSink>(),375 std::make_shared<mtd::NullEventSink>(),
361 resource_cache);376 resource_cache, std::make_shared<mtd::NullScreencast>());
362377
363 mp::ConnectParameters connect_parameters;378 mp::ConnectParameters connect_parameters;
364 mp::Connection connection;379 mp::Connection connection;
@@ -461,6 +476,8 @@
461 mediator.connect(nullptr, &connect_parameters, &connection, null_callback.get());476 mediator.connect(nullptr, &connect_parameters, &connection, null_callback.get());
462477
463 {478 {
479 // AFAICS these values are stubs to set up the test condition,
480 // the exact calls here are not a *requirement* on SessionMediator
464 EXPECT_CALL(*stubbed_session->mock_buffer, id())481 EXPECT_CALL(*stubbed_session->mock_buffer, id())
465 .WillOnce(Return(mg::BufferID{4}))482 .WillOnce(Return(mg::BufferID{4}))
466 .WillOnce(Return(mg::BufferID{4}))483 .WillOnce(Return(mg::BufferID{4}))
@@ -519,8 +536,8 @@
519 * the pre-created stubbed_session->mock_surface. Further create_surface()536 * the pre-created stubbed_session->mock_surface. Further create_surface()
520 * invocations create new surfaces in stubbed_session->mock_surfaces[].537 * invocations create new surfaces in stubbed_session->mock_surfaces[].
521 */538 */
522 EXPECT_CALL(*stubbed_session->mock_surface, swap_buffers(_))539 EXPECT_CALL(*stubbed_session->mock_surface, swap_buffers(_, _))
523 .WillOnce(SetArg<0>(&buffer));540 .WillOnce(InvokeArgument<1>(&buffer));
524541
525 mediator.create_surface(nullptr, &surface_request, &surface_response, null_callback.get());542 mediator.create_surface(nullptr, &surface_request, &surface_response, null_callback.get());
526 mp::SurfaceId our_surface{surface_response.id()};543 mp::SurfaceId our_surface{surface_response.id()};
@@ -528,7 +545,7 @@
528 Mock::VerifyAndClearExpectations(stubbed_session->mock_surface.get());545 Mock::VerifyAndClearExpectations(stubbed_session->mock_surface.get());
529546
530 /* Creating a new surface should not affect our surfaces' buffers */547 /* Creating a new surface should not affect our surfaces' buffers */
531 EXPECT_CALL(*stubbed_session->mock_surface, swap_buffers(_)).Times(0);548 EXPECT_CALL(*stubbed_session->mock_surface, swap_buffers(_, _)).Times(0);
532 mediator.create_surface(nullptr, &surface_request, &surface_response, null_callback.get());549 mediator.create_surface(nullptr, &surface_request, &surface_response, null_callback.get());
533550
534 mp::SurfaceId new_surface{surface_response.id()};551 mp::SurfaceId new_surface{surface_response.id()};
@@ -540,7 +557,7 @@
540 Mock::VerifyAndClearExpectations(stubbed_session->mock_surface.get());557 Mock::VerifyAndClearExpectations(stubbed_session->mock_surface.get());
541558
542 /* Getting the next buffer of our surface should post the original */559 /* Getting the next buffer of our surface should post the original */
543 EXPECT_CALL(*stubbed_session->mock_surface, swap_buffers(Eq(&buffer))).Times(1);560 EXPECT_CALL(*stubbed_session->mock_surface, swap_buffers(Eq(&buffer), _)).Times(1);
544561
545 mediator.next_buffer(nullptr, &our_surface, &buffer_response, null_callback.get());562 mediator.next_buffer(nullptr, &our_surface, &buffer_response, null_callback.get());
546 mediator.disconnect(nullptr, nullptr, nullptr, null_callback.get());563 mediator.disconnect(nullptr, nullptr, nullptr, null_callback.get());
@@ -585,9 +602,10 @@
585 .WillOnce(Return(mt::fake_shared(stub_display_config)));602 .WillOnce(Return(mt::fake_shared(stub_display_config)));
586603
587 mf::SessionMediator session_mediator{604 mf::SessionMediator session_mediator{
588 shell, graphics_platform, mock_display_selector,605 __LINE__, shell, graphics_platform, mock_display_selector,
589 surface_pixel_formats, report,606 surface_pixel_formats, report,
590 std::make_shared<mtd::NullEventSink>(), resource_cache};607 std::make_shared<mtd::NullEventSink>(), resource_cache,
608 std::make_shared<mtd::NullScreencast>()};
591609
592 session_mediator.connect(nullptr, &connect_parameters, &connection, null_callback.get());610 session_mediator.connect(nullptr, &connect_parameters, &connection, null_callback.get());
593611
@@ -620,3 +638,38 @@
620638
621 session_mediator.disconnect(nullptr, nullptr, nullptr, null_callback.get());639 session_mediator.disconnect(nullptr, nullptr, nullptr, null_callback.get());
622}640}
641
642TEST_F(SessionMediatorTest, fully_packs_buffer_for_create_screencast)
643{
644 using namespace testing;
645
646 mp::ScreencastParameters screencast_parameters;
647 mp::Screencast screencast;
648 auto const& stub_buffer = stub_screencast->stub_buffer;
649
650 EXPECT_CALL(*graphics_platform, fill_ipc_package(_, &stub_buffer));
651
652 mediator.create_screencast(nullptr, &screencast_parameters,
653 &screencast, null_callback.get());
654
655 EXPECT_EQ(stub_buffer.id().as_uint32_t(),
656 screencast.buffer().buffer_id());
657}
658
659TEST_F(SessionMediatorTest, partially_packs_buffer_for_screencast_buffer)
660{
661 using namespace testing;
662
663 mp::ScreencastId screencast_id;
664 mp::Buffer protobuf_buffer;
665 auto const& stub_buffer = stub_screencast->stub_buffer;
666
667 EXPECT_CALL(*graphics_platform, fill_ipc_package(_, &stub_buffer))
668 .Times(0);
669
670 mediator.screencast_buffer(nullptr, &screencast_id,
671 &protobuf_buffer, null_callback.get());
672
673 EXPECT_EQ(stub_buffer.id().as_uint32_t(),
674 protobuf_buffer.buffer_id());
675}
623676
=== modified file 'tests/unit-tests/frontend/test_session_mediator_android.cpp'
--- tests/unit-tests/frontend/test_session_mediator_android.cpp 2014-01-13 06:12:33 +0000
+++ tests/unit-tests/frontend/test_session_mediator_android.cpp 2014-02-10 09:00:06 +0000
@@ -32,6 +32,7 @@
32#include "mir_test_doubles/null_platform.h"32#include "mir_test_doubles/null_platform.h"
33#include "mir_test_doubles/null_event_sink.h"33#include "mir_test_doubles/null_event_sink.h"
34#include "mir_test_doubles/stub_buffer_allocator.h"34#include "mir_test_doubles/stub_buffer_allocator.h"
35#include "mir_test_doubles/null_screencast.h"
3536
36#include <gtest/gtest.h>37#include <gtest/gtest.h>
3738
@@ -56,10 +57,10 @@
56 surface_pixel_formats{mir_pixel_format_argb_8888, mir_pixel_format_xrgb_8888},57 surface_pixel_formats{mir_pixel_format_argb_8888, mir_pixel_format_xrgb_8888},
57 report{std::make_shared<mf::NullSessionMediatorReport>()},58 report{std::make_shared<mf::NullSessionMediatorReport>()},
58 resource_cache{std::make_shared<mf::ResourceCache>()},59 resource_cache{std::make_shared<mf::ResourceCache>()},
59 mediator{shell, graphics_platform, display_changer,60 mediator{__LINE__, shell, graphics_platform, display_changer,
60 surface_pixel_formats, report,61 surface_pixel_formats, report,
61 std::make_shared<mtd::NullEventSink>(),62 std::make_shared<mtd::NullEventSink>(),
62 resource_cache},63 resource_cache, std::make_shared<mtd::NullScreencast>()},
63 null_callback{google::protobuf::NewPermanentCallback(google::protobuf::DoNothing)}64 null_callback{google::protobuf::NewPermanentCallback(google::protobuf::DoNothing)}
64 {65 {
65 }66 }
6667
=== modified file 'tests/unit-tests/frontend/test_session_mediator_mesa.cpp'
--- tests/unit-tests/frontend/test_session_mediator_mesa.cpp 2014-01-13 06:12:33 +0000
+++ tests/unit-tests/frontend/test_session_mediator_mesa.cpp 2014-02-10 09:00:06 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright © 2012 Canonical Ltd.2 * Copyright © 2012-2014 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify4 * 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 as5 * it under the terms of the GNU General Public License version 3 as
@@ -34,6 +34,7 @@
34#include "mir_test_doubles/null_platform.h"34#include "mir_test_doubles/null_platform.h"
35#include "mir_test_doubles/mock_session.h"35#include "mir_test_doubles/mock_session.h"
36#include "mir_test_doubles/stub_shell.h"36#include "mir_test_doubles/stub_shell.h"
37#include "mir_test_doubles/null_screencast.h"
3738
38#include <gtest/gtest.h>39#include <gtest/gtest.h>
39#include <gmock/gmock.h>40#include <gmock/gmock.h>
@@ -69,10 +70,10 @@
69 surface_pixel_formats{mir_pixel_format_argb_8888, mir_pixel_format_xrgb_8888},70 surface_pixel_formats{mir_pixel_format_argb_8888, mir_pixel_format_xrgb_8888},
70 report{std::make_shared<mf::NullSessionMediatorReport>()},71 report{std::make_shared<mf::NullSessionMediatorReport>()},
71 resource_cache{std::make_shared<mf::ResourceCache>()},72 resource_cache{std::make_shared<mf::ResourceCache>()},
72 mediator{shell, mock_platform, display_changer,73 mediator{__LINE__, shell, mock_platform, display_changer,
73 surface_pixel_formats, report,74 surface_pixel_formats, report,
74 std::make_shared<mtd::NullEventSink>(),75 std::make_shared<mtd::NullEventSink>(),
75 resource_cache},76 resource_cache, std::make_shared<mtd::NullScreencast>()},
76 null_callback{google::protobuf::NewPermanentCallback(google::protobuf::DoNothing)}77 null_callback{google::protobuf::NewPermanentCallback(google::protobuf::DoNothing)}
77 {78 {
78 }79 }
7980
=== modified file 'tests/unit-tests/frontend/test_socket_session.cpp'
--- tests/unit-tests/frontend/test_socket_session.cpp 2014-01-22 15:54:11 +0000
+++ tests/unit-tests/frontend/test_socket_session.cpp 2014-02-10 09:00:06 +0000
@@ -70,7 +70,7 @@
7070
71struct MockProcessor : public mfd::MessageProcessor71struct MockProcessor : public mfd::MessageProcessor
72{72{
73 MOCK_METHOD1(dispatch, bool(mir::protobuf::wire::Invocation const& invocation));73 MOCK_METHOD1(dispatch, bool(mfd::Invocation const& invocation));
74};74};
75}75}
76struct SocketSessionTest : public ::testing::Test76struct SocketSessionTest : public ::testing::Test
7777
=== modified file 'tests/unit-tests/graphics/android/test_android_alloc_adaptor.cpp'
--- tests/unit-tests/graphics/android/test_android_alloc_adaptor.cpp 2014-01-13 06:12:33 +0000
+++ tests/unit-tests/graphics/android/test_android_alloc_adaptor.cpp 2014-02-10 09:00:06 +0000
@@ -236,7 +236,7 @@
236236
237TEST_F(AdaptorICSTest, handle_has_version)237TEST_F(AdaptorICSTest, handle_has_version)
238{238{
239 int version = 96; /* version value shared by JB and ICS */239 int version = sizeof(ANativeWindowBuffer); /* version value shared by JB and ICS */
240 auto native_handle = alloc_adaptor->alloc_buffer(size, pf, usage);240 auto native_handle = alloc_adaptor->alloc_buffer(size, pf, usage);
241 auto anwb = native_handle->anwb();241 auto anwb = native_handle->anwb();
242 EXPECT_EQ(version, anwb->common.version);242 EXPECT_EQ(version, anwb->common.version);
243243
=== modified file 'tests/unit-tests/graphics/android/test_buffer_tex_bind.cpp'
--- tests/unit-tests/graphics/android/test_buffer_tex_bind.cpp 2014-01-13 06:12:33 +0000
+++ tests/unit-tests/graphics/android/test_buffer_tex_bind.cpp 2014-02-10 09:00:06 +0000
@@ -101,7 +101,8 @@
101TEST_F(AndroidBufferBinding, buffer_makes_new_image_with_new_display)101TEST_F(AndroidBufferBinding, buffer_makes_new_image_with_new_display)
102{102{
103 using namespace testing;103 using namespace testing;
104 EGLDisplay second_fake_display = (EGLDisplay) ((int)mock_egl.fake_egl_display +1);104 EGLDisplay second_fake_display =
105 reinterpret_cast<EGLDisplay>(&second_fake_display);
105106
106 /* return 1st fake display */107 /* return 1st fake display */
107 EXPECT_CALL(mock_egl, eglCreateImageKHR(_,_,_,_,_))108 EXPECT_CALL(mock_egl, eglCreateImageKHR(_,_,_,_,_))
@@ -121,7 +122,8 @@
121TEST_F(AndroidBufferBinding, buffer_frees_images_it_makes)122TEST_F(AndroidBufferBinding, buffer_frees_images_it_makes)
122{123{
123 using namespace testing;124 using namespace testing;
124 EGLDisplay second_fake_display = (EGLDisplay) ((int)mock_egl.fake_egl_display +1);125 EGLDisplay second_fake_display =
126 reinterpret_cast<EGLDisplay>(&second_fake_display);
125127
126 EXPECT_CALL(mock_egl, eglDestroyImageKHR(_,_))128 EXPECT_CALL(mock_egl, eglDestroyImageKHR(_,_))
127 .Times(Exactly(2));129 .Times(Exactly(2));
@@ -141,9 +143,12 @@
141 using namespace testing;143 using namespace testing;
142144
143 EGLDisplay first_fake_display = mock_egl.fake_egl_display;145 EGLDisplay first_fake_display = mock_egl.fake_egl_display;
144 EGLImageKHR first_fake_egl_image = (EGLImageKHR) 0x84210;146 EGLImageKHR first_fake_egl_image =
145 EGLDisplay second_fake_display = (EGLDisplay) ((int)mock_egl.fake_egl_display +1);147 reinterpret_cast<EGLImageKHR>(&first_fake_egl_image);
146 EGLImageKHR second_fake_egl_image = (EGLImageKHR) 0x84211;148 EGLDisplay second_fake_display =
149 reinterpret_cast<EGLDisplay>(&second_fake_display);
150 EGLImageKHR second_fake_egl_image =
151 reinterpret_cast<EGLImageKHR>(&second_fake_egl_image);
147152
148 /* actual expectations */153 /* actual expectations */
149 EXPECT_CALL(mock_egl, eglDestroyImageKHR(first_fake_display, first_fake_egl_image))154 EXPECT_CALL(mock_egl, eglDestroyImageKHR(first_fake_display, first_fake_egl_image))
@@ -321,8 +326,10 @@
321TEST_F(AndroidBufferBinding, buffer_binding_uses_right_image_after_display_swap)326TEST_F(AndroidBufferBinding, buffer_binding_uses_right_image_after_display_swap)
322{327{
323 using namespace testing;328 using namespace testing;
324 EGLDisplay second_fake_display = (EGLDisplay) ((int)mock_egl.fake_egl_display +1);329 EGLDisplay second_fake_display =
325 EGLImageKHR second_fake_egl_image = (EGLImageKHR) 0x84211;330 reinterpret_cast<EGLDisplay>(&second_fake_display);
331 EGLImageKHR second_fake_egl_image =
332 reinterpret_cast<EGLImageKHR>(&second_fake_egl_image);
326333
327 EXPECT_CALL(mock_egl, glEGLImageTargetTexture2DOES(_, _))334 EXPECT_CALL(mock_egl, glEGLImageTargetTexture2DOES(_, _))
328 .Times(Exactly(1));335 .Times(Exactly(1));
329336
=== modified file 'tests/unit-tests/graphics/android/test_hwc_common_device.cpp'
--- tests/unit-tests/graphics/android/test_hwc_common_device.cpp 2014-01-21 18:09:35 +0000
+++ tests/unit-tests/graphics/android/test_hwc_common_device.cpp 2014-02-10 09:00:06 +0000
@@ -16,6 +16,7 @@
16 * Authored by: Kevin DuBois <kevin.dubois@canonical.com>16 * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
17 */17 */
1818
19#include "mir/graphics/android/sync_fence.h"
19#include "src/platform/graphics/android/hwc_fb_device.h"20#include "src/platform/graphics/android/hwc_fb_device.h"
20#include "src/platform/graphics/android/hwc_device.h"21#include "src/platform/graphics/android/hwc_device.h"
21#include "src/platform/graphics/android/hwc_layerlist.h"22#include "src/platform/graphics/android/hwc_layerlist.h"
@@ -58,7 +59,8 @@
58 std::shared_ptr<framebuffer_device_t> const&,59 std::shared_ptr<framebuffer_device_t> const&,
59 std::shared_ptr<mga::HWCVsyncCoordinator> const& coordinator)60 std::shared_ptr<mga::HWCVsyncCoordinator> const& coordinator)
60{61{
61 return std::make_shared<mga::HwcDevice>(hwc_device, coordinator);62 auto file_ops = std::make_shared<mga::RealSyncFileOps>();
63 return std::make_shared<mga::HwcDevice>(hwc_device, coordinator, file_ops);
62}64}
6365
64template<typename T>66template<typename T>
6567
=== modified file 'tests/unit-tests/graphics/android/test_hwc_device.cpp'
--- tests/unit-tests/graphics/android/test_hwc_device.cpp 2014-01-23 17:26:51 +0000
+++ tests/unit-tests/graphics/android/test_hwc_device.cpp 2014-02-10 09:00:06 +0000
@@ -16,6 +16,7 @@
16 * Authored by: Kevin DuBois <kevin.dubois@canonical.com>16 * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
17 */17 */
1818
19#include "mir/graphics/android/sync_fence.h"
19#include "src/platform/graphics/android/framebuffer_bundle.h"20#include "src/platform/graphics/android/framebuffer_bundle.h"
20#include "src/platform/graphics/android/hwc_device.h"21#include "src/platform/graphics/android/hwc_device.h"
21#include "src/platform/graphics/android/hwc_layerlist.h"22#include "src/platform/graphics/android/hwc_layerlist.h"
@@ -35,6 +36,16 @@
35namespace mtd=mir::test::doubles;36namespace mtd=mir::test::doubles;
36namespace geom=mir::geometry;37namespace geom=mir::geometry;
3738
39namespace
40{
41struct MockFileOps : public mga::SyncFileOps
42{
43 MOCK_METHOD3(ioctl, int(int,int,void*));
44 MOCK_METHOD1(dup, int(int));
45 MOCK_METHOD1(close, int(int));
46};
47}
48
38class HwcDevice : public ::testing::Test49class HwcDevice : public ::testing::Test
39{50{
40protected:51protected:
@@ -48,10 +59,13 @@
48 mock_buffer = std::make_shared<testing::NiceMock<mtd::MockBuffer>>();59 mock_buffer = std::make_shared<testing::NiceMock<mtd::MockBuffer>>();
49 mock_device = std::make_shared<testing::NiceMock<mtd::MockHWCComposerDevice1>>();60 mock_device = std::make_shared<testing::NiceMock<mtd::MockHWCComposerDevice1>>();
50 mock_vsync = std::make_shared<testing::NiceMock<mtd::MockVsyncCoordinator>>();61 mock_vsync = std::make_shared<testing::NiceMock<mtd::MockVsyncCoordinator>>();
62 mock_file_ops = std::make_shared<MockFileOps>();
5163
52 ON_CALL(*mock_buffer, native_buffer_handle())64 ON_CALL(*mock_buffer, native_buffer_handle())
53 .WillByDefault(Return(mock_native_buffer));65 .WillByDefault(Return(mock_native_buffer));
54 }66 }
67
68 std::shared_ptr<MockFileOps> mock_file_ops;
55 std::shared_ptr<mtd::MockVsyncCoordinator> mock_vsync;69 std::shared_ptr<mtd::MockVsyncCoordinator> mock_vsync;
56 std::shared_ptr<mtd::MockHWCComposerDevice1> mock_device;70 std::shared_ptr<mtd::MockHWCComposerDevice1> mock_device;
57 std::shared_ptr<mtd::MockAndroidNativeBuffer> mock_native_buffer;71 std::shared_ptr<mtd::MockAndroidNativeBuffer> mock_native_buffer;
@@ -69,7 +83,7 @@
69 EXPECT_CALL(*mock_device, set_interface(mock_device.get(),_,_))83 EXPECT_CALL(*mock_device, set_interface(mock_device.get(),_,_))
70 .Times(1);84 .Times(1);
7185
72 mga::HwcDevice device(mock_device, mock_vsync);86 mga::HwcDevice device(mock_device, mock_vsync, mock_file_ops);
73 device.prepare_gl();87 device.prepare_gl();
74 device.post(*mock_buffer);88 device.post(*mock_buffer);
7589
@@ -90,7 +104,7 @@
90 EXPECT_CALL(*mock_device, prepare_interface(mock_device.get(), 1, _))104 EXPECT_CALL(*mock_device, prepare_interface(mock_device.get(), 1, _))
91 .Times(1);105 .Times(1);
92106
93 mga::HwcDevice device(mock_device, mock_vsync);107 mga::HwcDevice device(mock_device, mock_vsync, mock_file_ops);
94 device.prepare_gl();108 device.prepare_gl();
95 EXPECT_EQ(2, mock_device->display0_prepare_content.numHwLayers);109 EXPECT_EQ(2, mock_device->display0_prepare_content.numHwLayers);
96 EXPECT_EQ(-1, mock_device->display0_prepare_content.retireFenceFd);110 EXPECT_EQ(-1, mock_device->display0_prepare_content.retireFenceFd);
@@ -102,7 +116,7 @@
102 EXPECT_CALL(*mock_device, prepare_interface(mock_device.get(), 1, _))116 EXPECT_CALL(*mock_device, prepare_interface(mock_device.get(), 1, _))
103 .Times(1);117 .Times(1);
104118
105 mga::HwcDevice device(mock_device, mock_vsync);119 mga::HwcDevice device(mock_device, mock_vsync, mock_file_ops);
106 std::list<std::shared_ptr<mg::Renderable>> renderlist;120 std::list<std::shared_ptr<mg::Renderable>> renderlist;
107 device.prepare_gl_and_overlays(renderlist);121 device.prepare_gl_and_overlays(renderlist);
108122
@@ -114,7 +128,7 @@
114{128{
115 EXPECT_CALL(mock_egl, eglSwapBuffers(dpy,surf))129 EXPECT_CALL(mock_egl, eglSwapBuffers(dpy,surf))
116 .Times(1);130 .Times(1);
117 mga::HwcDevice device(mock_device, mock_vsync);131 mga::HwcDevice device(mock_device, mock_vsync, mock_file_ops);
118 device.gpu_render(dpy, surf);132 device.gpu_render(dpy, surf);
119}133}
120134
@@ -125,7 +139,7 @@
125 .Times(1)139 .Times(1)
126 .WillOnce(Return(EGL_FALSE));140 .WillOnce(Return(EGL_FALSE));
127141
128 mga::HwcDevice device(mock_device, mock_vsync);142 mga::HwcDevice device(mock_device, mock_vsync, mock_file_ops);
129143
130 EXPECT_THROW({144 EXPECT_THROW({
131 device.gpu_render(dpy, surf);145 device.gpu_render(dpy, surf);
@@ -136,15 +150,19 @@
136{150{
137 using namespace testing;151 using namespace testing;
138 int hwc_return_fence = 94;152 int hwc_return_fence = 94;
153 int hwc_retire_fence = 74;
139 mock_device->hwc_set_return_fence(hwc_return_fence);154 mock_device->hwc_set_return_fence(hwc_return_fence);
155 mock_device->hwc_set_retire_fence(hwc_retire_fence);
140156
141 mga::HwcDevice device(mock_device, mock_vsync);157 mga::HwcDevice device(mock_device, mock_vsync, mock_file_ops);
142158
143 InSequence seq;159 InSequence seq;
144 EXPECT_CALL(*mock_device, set_interface(mock_device.get(), 1, _))160 EXPECT_CALL(*mock_device, set_interface(mock_device.get(), 1, _))
145 .Times(1);161 .Times(1);
146 EXPECT_CALL(*mock_native_buffer, update_fence(hwc_return_fence))162 EXPECT_CALL(*mock_native_buffer, update_fence(hwc_return_fence))
147 .Times(1);163 .Times(1);
164 EXPECT_CALL(*mock_file_ops, close(hwc_retire_fence))
165 .Times(1);
148166
149 device.post(*mock_buffer);167 device.post(*mock_buffer);
150168
@@ -161,7 +179,7 @@
161{179{
162 using namespace testing;180 using namespace testing;
163181
164 mga::HwcDevice device(mock_device, mock_vsync);182 mga::HwcDevice device(mock_device, mock_vsync, mock_file_ops);
165183
166 EXPECT_CALL(*mock_device, set_interface(mock_device.get(), _, _))184 EXPECT_CALL(*mock_device, set_interface(mock_device.get(), _, _))
167 .Times(1)185 .Times(1)
168186
=== modified file 'tests/unit-tests/graphics/android/test_output_builder.cpp'
--- tests/unit-tests/graphics/android/test_output_builder.cpp 2014-01-21 18:09:35 +0000
+++ tests/unit-tests/graphics/android/test_output_builder.cpp 2014-02-10 09:00:06 +0000
@@ -122,7 +122,7 @@
122 .Times(1);122 .Times(1);
123123
124 mga::OutputBuilder factory(124 mga::OutputBuilder factory(
125 mt::fake_shared(mock_buffer_allocator),mock_resource_factory, mock_display_report, false);125 mt::fake_shared(mock_buffer_allocator),mock_resource_factory, mock_display_report);
126 factory.create_display_device();126 factory.create_display_device();
127}127}
128128
@@ -143,7 +143,7 @@
143 .Times(1);143 .Times(1);
144144
145 mga::OutputBuilder factory(145 mga::OutputBuilder factory(
146 mt::fake_shared(mock_buffer_allocator),mock_resource_factory, mock_display_report, false);146 mt::fake_shared(mock_buffer_allocator),mock_resource_factory, mock_display_report);
147 factory.create_display_device();147 factory.create_display_device();
148}148}
149149
@@ -161,7 +161,7 @@
161 .Times(1);161 .Times(1);
162162
163 mga::OutputBuilder factory(163 mga::OutputBuilder factory(
164 mt::fake_shared(mock_buffer_allocator),mock_resource_factory, mock_display_report, false);164 mt::fake_shared(mock_buffer_allocator),mock_resource_factory, mock_display_report);
165 factory.create_display_device();165 factory.create_display_device();
166}166}
167167
@@ -182,7 +182,7 @@
182 .Times(1);182 .Times(1);
183183
184 mga::OutputBuilder factory(184 mga::OutputBuilder factory(
185 mt::fake_shared(mock_buffer_allocator),mock_resource_factory, mock_display_report, false);185 mt::fake_shared(mock_buffer_allocator),mock_resource_factory, mock_display_report);
186 factory.create_display_device();186 factory.create_display_device();
187}187}
188188
@@ -201,7 +201,7 @@
201201
202 EXPECT_THROW({202 EXPECT_THROW({
203 mga::OutputBuilder factory(203 mga::OutputBuilder factory(
204 mt::fake_shared(mock_buffer_allocator),mock_resource_factory, mock_display_report, false);204 mt::fake_shared(mock_buffer_allocator),mock_resource_factory, mock_display_report);
205 }, std::runtime_error);205 }, std::runtime_error);
206}206}
207207
@@ -219,7 +219,7 @@
219 .Times(1);219 .Times(1);
220220
221 mga::OutputBuilder factory(221 mga::OutputBuilder factory(
222 mt::fake_shared(mock_buffer_allocator),mock_resource_factory, mock_display_report, false);222 mt::fake_shared(mock_buffer_allocator),mock_resource_factory, mock_display_report);
223 factory.create_display_device();223 factory.create_display_device();
224}224}
225225
@@ -233,6 +233,6 @@
233 .Times(1);233 .Times(1);
234234
235 mga::OutputBuilder factory(235 mga::OutputBuilder factory(
236 mt::fake_shared(mock_buffer_allocator),mock_resource_factory, mock_display_report, false);236 mt::fake_shared(mock_buffer_allocator),mock_resource_factory, mock_display_report);
237 factory.create_display_buffer(mt::fake_shared(stub_device), gl_context);237 factory.create_display_buffer(mt::fake_shared(stub_device), gl_context);
238}238}
239239
=== modified file 'tests/unit-tests/graphics/mesa/test_display_configuration.cpp'
--- tests/unit-tests/graphics/mesa/test_display_configuration.cpp 2014-01-13 06:12:33 +0000
+++ tests/unit-tests/graphics/mesa/test_display_configuration.cpp 2014-02-10 09:00:06 +0000
@@ -289,7 +289,7 @@
289 /* Test body */289 /* Test body */
290 auto display = create_display(create_platform());290 auto display = create_display(create_platform());
291291
292 auto conf = display->configuration();292 std::shared_ptr<mg::DisplayConfiguration> conf = display->configuration();
293 auto const& kms_conf = std::static_pointer_cast<mgm::KMSDisplayConfiguration>(conf);293 auto const& kms_conf = std::static_pointer_cast<mgm::KMSDisplayConfiguration>(conf);
294294
295 size_t output_count{0};295 size_t output_count{0};
@@ -332,7 +332,7 @@
332 /* Test body */332 /* Test body */
333 auto display = create_display(create_platform());333 auto display = create_display(create_platform());
334334
335 auto conf = display->configuration();335 std::shared_ptr<mg::DisplayConfiguration> conf = display->configuration();
336 auto const& kms_conf = std::static_pointer_cast<mgm::KMSDisplayConfiguration>(conf);336 auto const& kms_conf = std::static_pointer_cast<mgm::KMSDisplayConfiguration>(conf);
337337
338 EXPECT_THROW({338 EXPECT_THROW({
339339
=== modified file 'tests/unit-tests/scene/test_application_session.cpp'
--- tests/unit-tests/scene/test_application_session.cpp 2014-01-13 06:12:33 +0000
+++ tests/unit-tests/scene/test_application_session.cpp 2014-02-10 09:00:06 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright © 2012 Canonical Ltd.2 * Copyright © 2012-2014 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify4 * 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 as5 * it under the terms of the GNU General Public License version 3 as
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches