Mir

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

Proposed by Daniel van Vugt
Status: Merged
Merged at revision: 1183
Proposed branch: lp:~mir-team/mir/trunk-0.1.8
Merge into: lp:mir/0.1
Diff against target: 16448 lines (+6002/-3362)
277 files modified
3rd_party/android-input/android/CMakeLists.txt (+2/-0)
3rd_party/android-input/android/frameworks/base/services/input/EventHub.cpp (+46/-92)
3rd_party/android-input/android/frameworks/base/services/input/EventHub.h (+6/-5)
CMakeLists.txt (+1/-1)
benchmarks/android-input/CMakeLists.txt (+3/-1)
cmake/MirCommon.cmake (+15/-4)
cmake/src/mir/CMakeLists.txt (+5/-0)
cmake/src/mir/fail_on_success.sh (+8/-0)
cmake/src/mir/mir_discover_gtest_tests.cpp (+15/-2)
debian/changelog (+66/-0)
debian/control (+3/-3)
debian/libmirserver18.install (+1/-1)
deploy-and-test.sh (+21/-0)
examples/demo-shell/demo_renderer.cpp (+271/-0)
examples/demo-shell/demo_renderer.h (+15/-0)
examples/render_overlays.cpp (+9/-7)
examples/render_surfaces.cpp (+19/-7)
include/platform/mir/graphics/display_buffer.h (+2/-3)
include/platform/mir/graphics/gl_config.h (+54/-0)
include/platform/mir/graphics/platform.h (+8/-1)
include/platform/mir/graphics/renderable.h (+20/-13)
include/platform/mir/options/default_configuration.h (+1/-0)
include/platform/mir/shared_library_loader.h (+28/-0)
include/server/mir/compositor/buffer_stream.h (+1/-1)
include/server/mir/compositor/gl_renderer.h (+27/-4)
include/server/mir/compositor/renderer.h (+2/-2)
include/server/mir/compositor/scene.h (+7/-4)
include/server/mir/default_server_configuration.h (+12/-8)
include/server/mir/frontend/display_changer.h (+0/-1)
include/server/mir/frontend/session_authorizer.h (+3/-1)
include/server/mir/input/surface.h (+1/-1)
include/server/mir/scene/surface.h (+59/-0)
include/server/mir/scene/surface_configurator.h (+4/-4)
include/server/mir/scene/surface_coordinator.h (+17/-12)
include/server/mir/scene/surface_event_source.h (+49/-0)
include/server/mir/scene/surface_factory.h (+14/-14)
include/server/mir/scene/surface_observer.h (+45/-0)
include/server/mir/scene/surface_ranker.h (+2/-2)
include/server/mir/shell/surface.h (+1/-3)
include/server/mir/shell/surface_factory.h (+6/-8)
include/shared/mir/geometry/length.h (+102/-0)
include/test/mir_test_doubles/fake_renderable.h (+5/-5)
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_buffer.h (+1/-1)
include/test/mir_test_doubles/mock_display_changer.h (+0/-1)
include/test/mir_test_doubles/mock_display_device.h (+1/-1)
include/test/mir_test_doubles/mock_egl.h (+27/-0)
include/test/mir_test_doubles/mock_gl_config.h (+43/-0)
include/test/mir_test_doubles/mock_hwc_composer_device_1.h (+0/-105)
include/test/mir_test_doubles/mock_hwc_device_wrapper.h (+42/-0)
include/test/mir_test_doubles/mock_input_surface.h (+2/-2)
include/test/mir_test_doubles/mock_renderable.h (+12/-3)
include/test/mir_test_doubles/mock_scene.h (+6/-2)
include/test/mir_test_doubles/mock_surface.h (+14/-12)
include/test/mir_test_doubles/mock_surface_configurator.h (+4/-4)
include/test/mir_test_doubles/mock_surface_factory.h (+4/-3)
include/test/mir_test_doubles/mock_surface_ranker.h (+2/-2)
include/test/mir_test_doubles/null_display_buffer.h (+1/-1)
include/test/mir_test_doubles/null_display_changer.h (+0/-3)
include/test/mir_test_doubles/null_platform.h (+2/-1)
include/test/mir_test_doubles/null_surface_configurator.h (+4/-4)
include/test/mir_test_doubles/stub_buffer_stream.h (+1/-1)
include/test/mir_test_doubles/stub_display_builder.h (+1/-1)
include/test/mir_test_doubles/stub_display_device.h (+1/-1)
include/test/mir_test_doubles/stub_gl_config.h (+43/-0)
include/test/mir_test_doubles/stub_ipc_factory.h (+1/-1)
include/test/mir_test_doubles/stub_renderable.h (+2/-2)
include/test/mir_test_doubles/stub_session_authorizer.h (+4/-0)
include/test/mir_test_doubles/stub_surface_builder.h (+0/-69)
include/test/mir_test_doubles/stub_surface_ranker.h (+0/-44)
include/test/mir_test_framework/declarative_placement_strategy.h (+64/-0)
include/test/mir_test_framework/udev_environment.h (+1/-0)
src/client/default_connection_configuration.cpp (+1/-1)
src/client/lttng/input_receiver_report_tp.h (+1/-0)
src/client/lttng/rpc_report_tp.h (+1/-0)
src/client/mir_client_library.cpp (+11/-2)
src/client/rpc/mir_basic_rpc_channel.cpp (+3/-3)
src/client/rpc/mir_basic_rpc_channel.h (+4/-3)
src/client/rpc/mir_socket_rpc_channel.cpp (+41/-32)
src/client/rpc/mir_socket_rpc_channel.h (+3/-1)
src/platform/CMakeLists.txt (+2/-1)
src/platform/graphics/android/CMakeLists.txt (+4/-0)
src/platform/graphics/android/android_display.cpp (+2/-1)
src/platform/graphics/android/android_display.h (+2/-0)
src/platform/graphics/android/android_platform.cpp (+37/-4)
src/platform/graphics/android/android_platform.h (+2/-1)
src/platform/graphics/android/display_buffer.cpp (+1/-1)
src/platform/graphics/android/display_buffer.h (+1/-1)
src/platform/graphics/android/display_device.h (+1/-1)
src/platform/graphics/android/fb_device.cpp (+1/-1)
src/platform/graphics/android/fb_device.h (+1/-1)
src/platform/graphics/android/gl_context.cpp (+17/-10)
src/platform/graphics/android/gl_context.h (+4/-1)
src/platform/graphics/android/hwc_common_device.cpp (+2/-2)
src/platform/graphics/android/hwc_common_device.h (+2/-1)
src/platform/graphics/android/hwc_device.cpp (+2/-1)
src/platform/graphics/android/hwc_device.h (+2/-15)
src/platform/graphics/android/hwc_fb_device.cpp (+12/-17)
src/platform/graphics/android/hwc_fb_device.h (+5/-1)
src/platform/graphics/android/hwc_formatted_logger.cpp (+177/-0)
src/platform/graphics/android/hwc_formatted_logger.h (+41/-0)
src/platform/graphics/android/hwc_layerlist.cpp (+4/-4)
src/platform/graphics/android/hwc_layerlist.h (+2/-2)
src/platform/graphics/android/hwc_logger.h (+46/-0)
src/platform/graphics/android/hwc_wrapper.h (+47/-0)
src/platform/graphics/android/real_hwc_wrapper.cpp (+11/-2)
src/platform/graphics/android/real_hwc_wrapper.h (+6/-3)
src/platform/graphics/android/resource_factory.cpp (+35/-2)
src/platform/graphics/android/resource_factory.h (+4/-0)
src/platform/graphics/mesa/CMakeLists.txt (+1/-0)
src/platform/graphics/mesa/display.cpp (+13/-3)
src/platform/graphics/mesa/display.h (+5/-2)
src/platform/graphics/mesa/display_buffer.cpp (+3/-1)
src/platform/graphics/mesa/display_buffer.h (+3/-1)
src/platform/graphics/mesa/display_helpers.cpp (+15/-3)
src/platform/graphics/mesa/display_helpers.h (+5/-5)
src/platform/graphics/mesa/platform.cpp (+11/-1)
src/platform/graphics/mesa/platform.h (+2/-1)
src/platform/options/default_configuration.cpp (+32/-3)
src/platform/shared_library_loader.cpp (+38/-0)
src/server/CMakeLists.txt (+1/-1)
src/server/compositor/buffer_bundle.h (+13/-1)
src/server/compositor/buffer_stream_surfaces.cpp (+2/-2)
src/server/compositor/buffer_stream_surfaces.h (+1/-1)
src/server/compositor/bypass.cpp (+6/-1)
src/server/compositor/default_display_buffer_compositor.cpp (+32/-57)
src/server/compositor/default_display_buffer_compositor.h (+1/-2)
src/server/compositor/gl_renderer.cpp (+68/-22)
src/server/compositor/occlusion.cpp (+28/-16)
src/server/compositor/occlusion.h (+2/-24)
src/server/compositor/rendering_operator.cpp (+5/-11)
src/server/compositor/rendering_operator.h (+3/-7)
src/server/compositor/screencast_display_buffer.cpp (+1/-1)
src/server/compositor/screencast_display_buffer.h (+1/-1)
src/server/compositor/switching_bundle.cpp (+6/-3)
src/server/compositor/switching_bundle.h (+3/-4)
src/server/compositor/temporary_buffers.cpp (+2/-2)
src/server/compositor/temporary_buffers.h (+1/-1)
src/server/default_server_configuration.cpp (+11/-6)
src/server/frontend/CMakeLists.txt (+1/-0)
src/server/frontend/default_configuration.cpp (+23/-7)
src/server/frontend/event_sender.cpp (+1/-1)
src/server/frontend/message_receiver.h (+3/-1)
src/server/frontend/message_sender.h (+2/-2)
src/server/frontend/protobuf_ipc_factory.h (+1/-2)
src/server/frontend/protobuf_responder.cpp (+9/-8)
src/server/frontend/protobuf_responder.h (+1/-1)
src/server/frontend/protobuf_session_creator.cpp (+1/-2)
src/server/frontend/session_mediator.cpp (+0/-6)
src/server/frontend/socket_messenger.cpp (+29/-14)
src/server/frontend/socket_messenger.h (+4/-3)
src/server/frontend/socket_session.cpp (+16/-9)
src/server/frontend/socket_session.h (+3/-2)
src/server/frontend/unauthorized_display_changer.cpp (+0/-5)
src/server/frontend/unauthorized_display_changer.h (+0/-2)
src/server/frontend/unauthorized_screencast.cpp (+46/-0)
src/server/frontend/unauthorized_screencast.h (+44/-0)
src/server/graphics/default_configuration.cpp (+20/-21)
src/server/graphics/nested/nested_display.cpp (+11/-4)
src/server/graphics/nested/nested_display.h (+6/-2)
src/server/graphics/nested/nested_output.cpp (+1/-1)
src/server/graphics/nested/nested_output.h (+1/-1)
src/server/graphics/nested/nested_platform.cpp (+5/-2)
src/server/graphics/nested/nested_platform.h (+2/-1)
src/server/graphics/offscreen/display_buffer.cpp (+1/-1)
src/server/graphics/offscreen/display_buffer.h (+1/-1)
src/server/mirserver.pc.in (+1/-1)
src/server/scene/CMakeLists.txt (+1/-2)
src/server/scene/application_session.cpp (+10/-2)
src/server/scene/basic_surface.cpp (+193/-27)
src/server/scene/basic_surface.h (+73/-26)
src/server/scene/default_configuration.cpp (+18/-27)
src/server/scene/gl_pixel_buffer.cpp (+7/-0)
src/server/scene/mediating_display_changer.cpp (+0/-23)
src/server/scene/mediating_display_changer.h (+0/-2)
src/server/scene/mutable_surface_state.h (+0/-52)
src/server/scene/surface_allocator.cpp (+8/-4)
src/server/scene/surface_allocator.h (+8/-4)
src/server/scene/surface_controller.cpp (+23/-13)
src/server/scene/surface_controller.h (+16/-15)
src/server/scene/surface_event_source.cpp (+62/-0)
src/server/scene/surface_impl.cpp (+0/-273)
src/server/scene/surface_impl.h (+0/-114)
src/server/scene/surface_source.cpp (+0/-47)
src/server/scene/surface_source.h (+0/-64)
src/server/scene/surface_stack.cpp (+23/-34)
src/server/scene/surface_stack.h (+19/-19)
src/server/scene/surface_stack_model.h (+13/-6)
src/server/shell/default_configuration.cpp (+1/-1)
src/server/shell/default_focus_mechanism.cpp (+3/-1)
src/server/shell/organising_surface_factory.cpp (+29/-10)
src/server/shell/organising_surface_factory.h (+9/-6)
src/shared/sharedlibrary/CMakeLists.txt (+5/-0)
tests/CMakeLists.txt (+3/-10)
tests/acceptance-tests/test_client_authorization.cpp (+3/-0)
tests/acceptance-tests/test_client_input.cpp (+33/-70)
tests/acceptance-tests/test_client_screencast.cpp (+50/-0)
tests/acceptance-tests/test_display_configuration.cpp (+5/-4)
tests/acceptance-tests/test_protobuf.cpp (+5/-0)
tests/acceptance-tests/test_server_disconnect.cpp (+2/-0)
tests/acceptance-tests/test_shell_control_of_surface_configuration.cpp (+6/-6)
tests/acceptance-tests/test_surfaces_with_output_id.cpp (+7/-1)
tests/integration-tests/compositor/test_buffer_stream.cpp (+21/-21)
tests/integration-tests/compositor/test_swapping_swappers.cpp (+2/-4)
tests/integration-tests/graphics/android/test_display_integration.cpp (+9/-6)
tests/integration-tests/graphics/android/test_internal_client.cpp (+7/-7)
tests/integration-tests/graphics/mesa/test_buffer_integration.cpp (+4/-1)
tests/integration-tests/test_display_info.cpp (+2/-1)
tests/integration-tests/test_session_manager.cpp (+1/-1)
tests/integration-tests/test_surfaceloop.cpp (+4/-2)
tests/integration-tests/test_swapinterval.cpp (+1/-1)
tests/mir_test_framework/CMakeLists.txt (+10/-11)
tests/mir_test_framework/declarative_placement_strategy.cpp (+58/-0)
tests/mir_test_framework/stubbed_server_configuration.cpp (+2/-1)
tests/mir_test_framework/udev_environment.cpp (+22/-2)
tests/mir_test_framework/udev_recordings/bluetooth-magic-trackpad.ioctl (+21/-0)
tests/mir_test_framework/udev_recordings/bluetooth-magic-trackpad.umockdev (+222/-0)
tests/mir_test_framework/udev_recordings/laptop-keyboard.ioctl (+12/-0)
tests/mir_test_framework/udev_recordings/laptop-keyboard.umockdev (+74/-0)
tests/mir_test_framework/udev_recordings/synaptics-touchpad.ioctl (+29/-0)
tests/mir_test_framework/udev_recordings/synaptics-touchpad.umockdev (+65/-0)
tests/mir_test_framework/udev_recordings/usb-keyboard.ioctl (+13/-0)
tests/mir_test_framework/udev_recordings/usb-keyboard.umockdev (+244/-0)
tests/mir_test_framework/udev_recordings/usb-mouse.ioctl (+14/-0)
tests/mir_test_framework/udev_recordings/usb-mouse.umockdev (+240/-0)
tests/mir_test_framework/using_stub_client_platform.cpp (+11/-2)
tests/unit-tests/CMakeLists.txt (+5/-14)
tests/unit-tests/android_input/CMakeLists.txt (+1/-0)
tests/unit-tests/android_input/test_eventhub.cpp (+125/-0)
tests/unit-tests/client/test_mir_connection.cpp (+6/-0)
tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp (+348/-444)
tests/unit-tests/compositor/test_gl_renderer.cpp (+21/-2)
tests/unit-tests/compositor/test_multi_threaded_compositor.cpp (+5/-2)
tests/unit-tests/compositor/test_occlusion.cpp (+123/-81)
tests/unit-tests/compositor/test_rendering_operator.cpp (+15/-15)
tests/unit-tests/compositor/test_switching_bundle.cpp (+69/-51)
tests/unit-tests/frontend/test_event_sender.cpp (+7/-7)
tests/unit-tests/frontend/test_session_mediator.cpp (+4/-5)
tests/unit-tests/frontend/test_socket_session.cpp (+43/-14)
tests/unit-tests/geometry/CMakeLists.txt (+1/-0)
tests/unit-tests/geometry/test-length.cpp (+124/-0)
tests/unit-tests/graphics/android/CMakeLists.txt (+1/-0)
tests/unit-tests/graphics/android/hwc_struct_helpers.h (+8/-0)
tests/unit-tests/graphics/android/test_android_fb.cpp (+64/-31)
tests/unit-tests/graphics/android/test_hwc_common_device.cpp (+3/-1)
tests/unit-tests/graphics/android/test_hwc_device.cpp (+5/-9)
tests/unit-tests/graphics/android/test_hwc_display.cpp (+6/-1)
tests/unit-tests/graphics/android/test_hwc_fb_device.cpp (+44/-74)
tests/unit-tests/graphics/android/test_hwc_logger.cpp (+132/-0)
tests/unit-tests/graphics/android/test_hwc_wrapper.cpp (+28/-7)
tests/unit-tests/graphics/android/test_output_builder.cpp (+4/-1)
tests/unit-tests/graphics/android/test_resource_factory.cpp (+5/-4)
tests/unit-tests/graphics/mesa/test_display.cpp (+41/-8)
tests/unit-tests/graphics/mesa/test_display_buffer.cpp (+12/-0)
tests/unit-tests/graphics/mesa/test_display_configuration.cpp (+4/-2)
tests/unit-tests/graphics/mesa/test_display_multi_monitor.cpp (+7/-4)
tests/unit-tests/graphics/mesa/test_internal_native_display.cpp (+0/-4)
tests/unit-tests/graphics/mesa/test_internal_native_surface.cpp (+0/-3)
tests/unit-tests/graphics/nested/CMakeLists.txt (+1/-0)
tests/unit-tests/graphics/nested/test_nested_display.cpp (+27/-0)
tests/unit-tests/graphics/test_display.cpp (+4/-2)
tests/unit-tests/input/android/test_android_input_application_handle.cpp (+1/-1)
tests/unit-tests/input/android/test_android_input_registrar.cpp (+2/-3)
tests/unit-tests/input/android/test_android_input_window_handle.cpp (+18/-11)
tests/unit-tests/scene/test_application_session.cpp (+12/-14)
tests/unit-tests/scene/test_basic_surface.cpp (+124/-106)
tests/unit-tests/scene/test_default_focus_mechanism.cpp (+23/-40)
tests/unit-tests/scene/test_gl_pixel_buffer.cpp (+10/-0)
tests/unit-tests/scene/test_session_manager.cpp (+19/-17)
tests/unit-tests/scene/test_surface.cpp (+73/-31)
tests/unit-tests/scene/test_surface_controller.cpp (+36/-14)
tests/unit-tests/scene/test_surface_impl.cpp (+117/-209)
tests/unit-tests/scene/test_surface_stack.cpp (+143/-317)
tests/unit-tests/shell/test_organising_surface_factory.cpp (+24/-16)
tools/valgrind_suppressions_armhf (+30/-0)
tools/valgrind_suppressions_generic (+7/-0)
To merge this branch: bzr merge lp:~mir-team/mir/trunk-0.1.8
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Daniel van Vugt Approve
kevin gunn (community) Approve
Review via email: mp+213790@code.launchpad.net

Commit message

New upstream Mir release 0.1.8 (development-branch r1523), plus changelog
additions.

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 :

There is arguably one important fix missing from the 0.1.8 release. That is bug 1301040. We might want to add it in here...

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

Yes, the fix for that lp:~mterry/mir/missing-links (in the landing queue at time of this comment) should make it into this release. (would be caught during the silo build)

lp:~mir-team/mir/trunk-0.1.8 updated
1185. By Daniel van Vugt

Merge mterry's fix for LP: #1301040

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

there is one more we should cherry pick for https://bugs.launchpad.net/mir/+bug/1256360
which is proposed to be solved by https://code.launchpad.net/~albaguirre/mir/fix-1256360/+merge/214355

review: Needs Fixing
lp:~mir-team/mir/trunk-0.1.8 updated
1186. By Daniel van Vugt

Merge Alberto's fix for LP: #1256360.

Revision history for this message
kevin gunn (kgunn72) wrote :

Did you test your feature/code change/bug fix ? what device(s) ?
yes - n4, desktop

Did you break mir server API or ABI and have the relevant bumps to .so and debian docs been made ?
yes, server ABI only, bumps have been made

Did you break mir client API or ABI and have you followed up with the known clients & announced on mir-devel mailing list ?
yes, server only, unity-mir/server updates made

review: Approve
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 :

Changelog entry missing for latest commit.

review: Needs Fixing
lp:~mir-team/mir/trunk-0.1.8 updated
1187. By Daniel van Vugt

Remember to mention that last cherrypick in changelog

Revision history for this message
Daniel van Vugt (vanvugt) :
review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '3rd_party/android-input/android/CMakeLists.txt'
2--- 3rd_party/android-input/android/CMakeLists.txt 2014-03-06 06:05:17 +0000
3+++ 3rd_party/android-input/android/CMakeLists.txt 2014-04-07 13:29:13 +0000
4@@ -7,6 +7,7 @@
5 system/extras/ext4_utils
6
7 ${PROJECT_SOURCE_DIR}/include/server
8+ ${PROJECT_SOURCE_DIR}/include/platform
9 )
10
11 add_definitions(
12@@ -64,6 +65,7 @@
13 target_link_libraries(
14 android-input
15
16+ mirplatform
17 ${Boost_LIBRARIES}
18 )
19
20
21=== modified file '3rd_party/android-input/android/frameworks/base/services/input/EventHub.cpp'
22--- 3rd_party/android-input/android/frameworks/base/services/input/EventHub.cpp 2013-10-03 05:12:59 +0000
23+++ 3rd_party/android-input/android/frameworks/base/services/input/EventHub.cpp 2014-04-07 13:29:13 +0000
24@@ -205,34 +205,34 @@
25
26 // --- EventHub ---
27
28-const uint32_t EventHub::EPOLL_ID_INOTIFY;
29+const uint32_t EventHub::EPOLL_ID_UDEV;
30 const uint32_t EventHub::EPOLL_ID_WAKE;
31 const int EventHub::EPOLL_SIZE_HINT;
32 const int EventHub::EPOLL_MAX_EVENTS;
33
34 EventHub::EventHub(std::shared_ptr<mi::InputReport> const& input_report) :
35 input_report(input_report),
36+ device_listener{mir::udev::Context()},
37 mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD), mNextDeviceId(1),
38 mOpeningDevices(0), mClosingDevices(0),
39 mNeedToSendFinishedDeviceScan(false),
40 mNeedToReopenDevices(false), mNeedToScanDevices(true),
41- mPendingEventCount(0), mPendingEventIndex(0), mPendingINotify(false) {
42+ mPendingEventCount(0), mPendingEventIndex(0), mPendingUdevEvent(false) {
43 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
44
45 mEpollFd = epoll_create(EPOLL_SIZE_HINT);
46 LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance. errno=%d", errno);
47
48- mINotifyFd = inotify_init();
49- int result = inotify_add_watch(mINotifyFd, DEVICE_PATH, IN_DELETE | IN_CREATE | IN_ATTRIB);
50- LOG_ALWAYS_FATAL_IF(result < 0, "Could not register INotify for %s. errno=%d",
51- DEVICE_PATH, errno);
52+ device_listener.filter_by_subsystem("input");
53+ device_listener.enable();
54+
55
56 struct epoll_event eventItem;
57 memset(&eventItem, 0, sizeof(eventItem));
58 eventItem.events = EPOLLIN;
59- eventItem.data.u32 = EPOLL_ID_INOTIFY;
60- result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &eventItem);
61- LOG_ALWAYS_FATAL_IF(result != 0, "Could not add INotify to epoll instance. errno=%d", errno);
62+ eventItem.data.u32 = EPOLL_ID_UDEV;
63+ int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, device_listener.fd(), &eventItem);
64+ LOG_ALWAYS_FATAL_IF(result != 0, "Could not add Udev monitor to epoll instance. errno=%d", errno);
65
66 int wakeFds[2];
67 result = pipe(wakeFds);
68@@ -265,7 +265,6 @@
69 }
70
71 ::close(mEpollFd);
72- ::close(mINotifyFd);
73 ::close(mWakeReadPipeFd);
74 ::close(mWakeWritePipeFd);
75
76@@ -730,9 +729,9 @@
77 bool deviceChanged = false;
78 while (mPendingEventIndex < mPendingEventCount) {
79 const struct epoll_event& eventItem = mPendingEventItems[mPendingEventIndex++];
80- if (eventItem.data.u32 == EPOLL_ID_INOTIFY) {
81+ if (eventItem.data.u32 == EPOLL_ID_UDEV) {
82 if (eventItem.events & EPOLLIN) {
83- mPendingINotify = true;
84+ mPendingUdevEvent = true;
85 } else {
86 ALOGW("Received unexpected epoll event 0x%08x for INotify.", eventItem.events);
87 }
88@@ -839,9 +838,9 @@
89 // readNotify() will modify the list of devices so this must be done after
90 // processing all other events to ensure that we read all remaining events
91 // before closing the devices.
92- if (mPendingINotify && mPendingEventIndex >= mPendingEventCount) {
93- mPendingINotify = false;
94- readNotifyLocked();
95+ if (mPendingUdevEvent && mPendingEventIndex >= mPendingEventCount) {
96+ mPendingUdevEvent = false;
97+ handleUdevEventsLocked();
98 deviceChanged = true;
99 }
100
101@@ -916,15 +915,44 @@
102 }
103
104 void EventHub::scanDevicesLocked() {
105- status_t res = scanDirLocked(DEVICE_PATH);
106- if(res < 0) {
107- ALOGE("scan dir failed for %s\n", DEVICE_PATH);
108+ mir::udev::Enumerator input_enumerator{std::make_shared<mir::udev::Context>()};
109+
110+ input_enumerator.match_subsystem("input");
111+ input_enumerator.scan_devices();
112+
113+ for (auto& device : input_enumerator)
114+ {
115+ if (device.devnode() != nullptr)
116+ {
117+ openDeviceLocked(device.devnode());
118+ }
119 }
120+
121 if (mDevices.indexOfKey(VIRTUAL_KEYBOARD_ID) < 0) {
122 createVirtualKeyboardLocked();
123 }
124 }
125
126+void EventHub::handleUdevEventsLocked()
127+{
128+ device_listener.process_events([this](mir::udev::Monitor::EventType type, mir::udev::Device const& dev){
129+ if (type == mir::udev::Monitor::ADDED)
130+ {
131+ if (dev.devnode() != nullptr)
132+ {
133+ openDeviceLocked(dev.devnode());
134+ }
135+ }
136+ else if (type == mir::udev::Monitor::REMOVED)
137+ {
138+ if (dev.devnode() != nullptr)
139+ {
140+ closeDeviceByPathLocked(dev.devnode());
141+ }
142+ }
143+ });
144+}
145+
146 // ----------------------------------------------------------------------------
147
148 static bool containsNonZeroByte(const uint8_t* array, uint32_t startIndex, uint32_t endIndex) {
149@@ -1391,80 +1419,6 @@
150 }
151 }
152
153-status_t EventHub::readNotifyLocked() {
154- int res;
155- char devname[PATH_MAX];
156- char *filename;
157- char event_buf[512];
158- int event_size;
159- int event_pos = 0;
160- struct inotify_event *event;
161-
162- ALOGV("EventHub::readNotify nfd: %d\n", mINotifyFd);
163- res = read(mINotifyFd, event_buf, sizeof(event_buf));
164- if(res < (int)sizeof(*event)) {
165- if(errno == EINTR)
166- return 0;
167- ALOGW("could not get event, %s\n", strerror(errno));
168- return -1;
169- }
170- //printf("got %d bytes of event information\n", res);
171-
172- strcpy(devname, DEVICE_PATH);
173- filename = devname + strlen(devname);
174- *filename++ = '/';
175-
176- while(res >= (int)sizeof(*event)) {
177- event = (struct inotify_event *)(event_buf + event_pos);
178- //printf("%d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : "");
179- if(event->len) {
180- strcpy(filename, event->name);
181- if(event->mask & IN_CREATE) {
182- openDeviceLocked(devname);
183- } else if (event->mask & IN_ATTRIB) {
184- Device* device = getDeviceByPathLocked(devname);
185- if (!device) {
186- ALOGI("Retry opening device file %s", devname);
187- // file permissions might have changed, making the device readable now
188- // let's retry opening it
189- openDeviceLocked(devname);
190- }
191- } else {
192- ALOGI("Removing device '%s' due to inotify event\n", devname);
193- closeDeviceByPathLocked(devname);
194- }
195- }
196- event_size = sizeof(*event) + event->len;
197- res -= event_size;
198- event_pos += event_size;
199- }
200- return 0;
201-}
202-
203-status_t EventHub::scanDirLocked(const char *dirname)
204-{
205- char devname[PATH_MAX];
206- char *filename;
207- DIR *dir;
208- struct dirent *de;
209- dir = opendir(dirname);
210- if(dir == NULL)
211- return -1;
212- strcpy(devname, dirname);
213- filename = devname + strlen(devname);
214- *filename++ = '/';
215- while((de = readdir(dir))) {
216- if(de->d_name[0] == '.' &&
217- (de->d_name[1] == '\0' ||
218- (de->d_name[1] == '.' && de->d_name[2] == '\0')))
219- continue;
220- strcpy(filename, de->d_name);
221- openDeviceLocked(devname);
222- }
223- closedir(dir);
224- return 0;
225-}
226-
227 void EventHub::requestReopenDevices() {
228 ALOGV("requestReopenDevices() called");
229
230
231=== modified file '3rd_party/android-input/android/frameworks/base/services/input/EventHub.h'
232--- 3rd_party/android-input/android/frameworks/base/services/input/EventHub.h 2013-10-03 05:12:59 +0000
233+++ 3rd_party/android-input/android/frameworks/base/services/input/EventHub.h 2014-04-07 13:29:13 +0000
234@@ -18,6 +18,8 @@
235 #ifndef _RUNTIME_EVENT_HUB_H
236 #define _RUNTIME_EVENT_HUB_H
237
238+#include "mir/udev/wrapper.h"
239+
240 #include <androidfw/Input.h>
241 #include <androidfw/InputDevice.h>
242 #include <androidfw/Keyboard.h>
243@@ -366,9 +368,8 @@
244 void closeDeviceLocked(Device* device);
245 void closeAllDevicesLocked();
246
247- status_t scanDirLocked(const char *dirname);
248 void scanDevicesLocked();
249- status_t readNotifyLocked();
250+ void handleUdevEventsLocked();
251
252 Device* getDeviceLocked(int32_t deviceId) const;
253 Device* getDeviceByPathLocked(const char* devicePath) const;
254@@ -407,12 +408,12 @@
255 Vector<String8> mExcludedDevices;
256
257 int mEpollFd;
258- int mINotifyFd;
259+ mir::udev::Monitor device_listener;
260 int mWakeReadPipeFd;
261 int mWakeWritePipeFd;
262
263 // Ids used for epoll notifications not associated with devices.
264- static const uint32_t EPOLL_ID_INOTIFY = 0x80000001;
265+ static const uint32_t EPOLL_ID_UDEV = 0x80000001;
266 static const uint32_t EPOLL_ID_WAKE = 0x80000002;
267
268 // Epoll FD list size hint.
269@@ -425,7 +426,7 @@
270 struct epoll_event mPendingEventItems[EPOLL_MAX_EVENTS];
271 size_t mPendingEventCount;
272 size_t mPendingEventIndex;
273- bool mPendingINotify;
274+ bool mPendingUdevEvent;
275 };
276
277 // Made available to test
278
279=== modified file 'CMakeLists.txt'
280--- CMakeLists.txt 2014-03-06 06:05:17 +0000
281+++ CMakeLists.txt 2014-04-07 13:29:13 +0000
282@@ -28,7 +28,7 @@
283
284 set(MIR_VERSION_MAJOR 0)
285 set(MIR_VERSION_MINOR 1)
286-set(MIR_VERSION_PATCH 7)
287+set(MIR_VERSION_PATCH 8)
288
289 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
290 execute_process(
291
292=== modified file 'benchmarks/android-input/CMakeLists.txt'
293--- benchmarks/android-input/CMakeLists.txt 2013-10-15 10:10:05 +0000
294+++ benchmarks/android-input/CMakeLists.txt 2014-04-07 13:29:13 +0000
295@@ -5,7 +5,9 @@
296 )
297
298 include_directories(
299- ${Mir_SOURCE_DIR}/include/test)
300+ ${Mir_SOURCE_DIR}/include/test
301+ ${Mir_SOURCE_DIR}/include/platform
302+)
303
304 add_executable(input-reader-perf ${SOURCES})
305
306
307=== modified file 'cmake/MirCommon.cmake'
308--- cmake/MirCommon.cmake 2014-03-06 06:05:17 +0000
309+++ cmake/MirCommon.cmake 2014-04-07 13:29:13 +0000
310@@ -22,8 +22,10 @@
311 valgrind)
312
313 if(VALGRIND_EXECUTABLE)
314- set(VALGRIND_ARGS "--error-exitcode=1" "--trace-children=yes")
315+ set(VALGRIND_ARGS "--error-exitcode=1" "--trace-children=yes" "--leak-check=full" "--show-leak-kinds=definite" "--errors-for-leak-kinds=definite")
316+ set(VALGRIND_ARGS ${VALGRIND_ARGS} "--suppressions=${CMAKE_SOURCE_DIR}/tools/valgrind_suppressions_generic")
317 set(DISCOVER_FLAGS "--enable-memcheck")
318+ set(DISCOVER_FLAGS ${DISCOVER_FLAGS} "--suppressions=${CMAKE_SOURCE_DIR}/tools/valgrind_suppressions_generic")
319 if (TARGET_ARCH STREQUAL "arm-linux-gnueabihf")
320 set(VALGRIND_ARGS ${VALGRIND_ARGS} "--suppressions=${CMAKE_SOURCE_DIR}/tools/valgrind_suppressions_armhf")
321 set(DISCOVER_FLAGS ${DISCOVER_FLAGS} "--suppressions=${CMAKE_SOURCE_DIR}/tools/valgrind_suppressions_armhf")
322@@ -35,10 +37,11 @@
323
324 function (mir_discover_tests EXECUTABLE)
325 if(DISABLE_GTEST_TEST_DISCOVERY)
326- add_test(${EXECUTABLE} ${VALGRIND_EXECUTABLE} ${VALGRIND_ARGS} "${EXECUTABLE_OUTPUT_PATH}/${EXECUTABLE}")
327-
328+ add_test(${EXECUTABLE} ${VALGRIND_EXECUTABLE} ${VALGRIND_ARGS} ${EXECUTABLE_OUTPUT_PATH}/${EXECUTABLE} "--gtest_filter=-*DeathTest.*")
329+ add_test(${EXECUTABLE}_death_tests ${EXECUTABLE_OUTPUT_PATH}/${EXECUTABLE} "--gtest_filter=*DeathTest.*")
330 if (${ARGC} GREATER 1)
331 set_property(TEST ${EXECUTABLE} PROPERTY ENVIRONMENT ${ARGN})
332+ set_property(TEST ${EXECUTABLE}_death_tests PROPERTY ENVIRONMENT ${ARGN})
333 endif()
334 else()
335 set(CHECK_TEST_DISCOVERY_TARGET_NAME "check_discover_tests_in_${EXECUTABLE}")
336@@ -82,7 +85,15 @@
337 function (mir_add_memcheck_test)
338 if (ENABLE_MEMCHECK_OPTION)
339 if(DISABLE_GTEST_TEST_DISCOVERY)
340- ADD_TEST("memcheck-test" "sh" "-c" "${VALGRIND_EXECUTABLE} ${VALGRIND_ARGS} ${CMAKE_BINARY_DIR}/mir_gtest/mir_test_memory_error; if [ $? != 0 ]; then exit 0; else exit 1; fi")
341+ add_custom_target(
342+ memcheck_test ALL
343+ )
344+ ADD_TEST("memcheck-test" ${CMAKE_BINARY_DIR}/mir_gtest/fail_on_success.sh ${VALGRIND_EXECUTABLE} ${VALGRIND_ARGS} ${CMAKE_BINARY_DIR}/mir_gtest/mir_test_memory_error)
345+ add_dependencies(
346+ memcheck_test
347+
348+ mir_test_memory_error
349+ )
350 else()
351 add_custom_target(
352 memcheck_test ALL
353
354=== modified file 'cmake/src/mir/CMakeLists.txt'
355--- cmake/src/mir/CMakeLists.txt 2013-03-13 04:54:15 +0000
356+++ cmake/src/mir/CMakeLists.txt 2014-04-07 13:29:13 +0000
357@@ -17,3 +17,8 @@
358 mir_test_memory_error PROPERTIES
359 RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/mir_gtest
360 )
361+
362+file(INSTALL ${CMAKE_CURRENT_SOURCE_DIR}/fail_on_success.sh
363+ DESTINATION ${CMAKE_BINARY_DIR}/mir_gtest
364+ USE_SOURCE_PERMISSIONS
365+)
366
367=== added file 'cmake/src/mir/fail_on_success.sh'
368--- cmake/src/mir/fail_on_success.sh 1970-01-01 00:00:00 +0000
369+++ cmake/src/mir/fail_on_success.sh 2014-04-07 13:29:13 +0000
370@@ -0,0 +1,8 @@
371+#!/bin/sh
372+
373+$@
374+
375+if [ $? -eq 0 ] ; then
376+ exit 1;
377+fi
378+exit 0;
379
380=== modified file 'cmake/src/mir/mir_discover_gtest_tests.cpp'
381--- cmake/src/mir/mir_discover_gtest_tests.cpp 2014-03-06 06:05:17 +0000
382+++ cmake/src/mir/mir_discover_gtest_tests.cpp 2014-04-07 13:29:13 +0000
383@@ -234,6 +234,18 @@
384 }
385 }
386
387+bool is_death_test(string const& test)
388+{
389+ // precondition: test will match Foo.*
390+ // assumption: death tests will match FooDeathTest.*
391+ bool death_test = false;
392+ if (test.size() > strlen("DeathTest.*"))
393+ death_test = test.substr(test.size() - strlen("DeathTest.*"),
394+ strlen("DeathTest")) == "DeathTest";
395+
396+ return death_test;
397+}
398+
399 int main (int argc, char **argv)
400 {
401 int output_width = get_output_width();
402@@ -291,8 +303,9 @@
403 snprintf(
404 cmd_line,
405 sizeof(cmd_line),
406- config.enable_memcheck ? memcheck_cmd_line_pattern(config.suppressions).c_str() :
407- ordinary_cmd_line_pattern().c_str(),
408+ (config.enable_memcheck && !is_death_test(*test)) ?
409+ memcheck_cmd_line_pattern(config.suppressions).c_str() :
410+ ordinary_cmd_line_pattern().c_str(),
411 test_suite.c_str(),
412 elide_string_left(*test, output_width/2).c_str(),
413 config.executable,
414
415=== modified file 'debian/changelog'
416--- debian/changelog 2014-03-18 18:38:01 +0000
417+++ debian/changelog 2014-04-07 13:29:13 +0000
418@@ -1,3 +1,69 @@
419+mir (0.1.8-0ubuntu1) UNRELEASED; urgency=medium
420+
421+ * New upstream release 0.1.8 (https://launchpad.net/mir/+milestone/0.1.8)
422+ - mirclient ABI unchanged, still at 7. Clients do not need rebuilding.
423+ - mirserver ABI bumped to 18. Shells need rebuilding.
424+ - Server API changes affecting shells:
425+ . GLRenderer::tessellate() changed syntax.
426+ . graphics::Platform::create_display() has a new parameter allowing you
427+ to customize the compositor's (E)GL configutation.
428+ . Renderable::buffer(unsigned long frameno) is now:
429+ Renderable::buffer(void const* user_id). See below.
430+ . Renderable::should_be_rendered_in() is replaced by a more natural:
431+ Renderable::visble()
432+ . input::Surface::name() returns by value instead of reference now,
433+ to ensure future thread safety.
434+ - Switched EventHub device enumeration and hotplug to Udev. NOTE! This
435+ means mir_test_* can't run natively on touch devices any more without
436+ some setup first:
437+ sudo mount -o remount,rw /
438+ sudo apt-get update
439+ sudo apt-get install -y umockdev
440+ umockdev-run -- bin/mir_unit_tests
441+ - Added logging for HWC events.
442+ - Continued consolidation of Surface classes toward a simpler architecture.
443+ - Introduced "RenderableList" as the way to sample the Scene contents,
444+ and started using that in the default compositor.
445+ - Introduced physical length units and conversion (geometry::Length) in
446+ preparation for arbitrary DPI rendering.
447+ - Added some decorations to demo-shell; shadows and basic title bars, all
448+ anti-aliased and high-DPI scalable.
449+ - Multi-monitor frame sync has been redesigned to eliminate the need for
450+ frame number tracking.
451+ - Bugs (and enhancements) resolved:
452+ . [enhancement] Please move input detection to libudev (LP: #1237784)
453+ . [enhancement] Add a clamping resize mode to GLRenderer (LP: #1259887)
454+ . [regression] Intermittent loss of multimonitor frame sync
455+ (LP: #1290306)
456+ . [enhancement] Make GL config options configurable (LP: #1290780)
457+ . memcheck-test doesn't test anything when DISABLED_GTEST_DISCOVERY is
458+ enabled (LP: #1291876)
459+ . "Error opening DRM device" is always followed by "Unknown error -(some
460+ negative number)" (LP: #1292384)
461+ . Rendering/composition gets stopped early (LP: #1293896)
462+ . Ubuntu Touch Settings and terminal apps are not rendering correctly on
463+ rotate. (LP: #1294048)
464+ . [regression] Apps are much slower to open (LP: #1294051)
465+ . Settings app opens to a blank screen unless given enough time to render
466+ or the app is touched (LP: #1294053)
467+ . TestClientInput/DemoPrivateProtobuf memory leak is causing regular CI
468+ test failures (LP: #1295231)
469+ . OSK touch events "fall through" and hit surface behind them
470+ (LP: #1297878)
471+ . [enhancement] add a test for composite of last client post
472+ (LP: #1298596)
473+ . [regression] Surfaces vanish as soon as their edges touch the edge of
474+ screen (LP: #1301115)
475+ * Cherry-picked from future release 0.1.9:
476+ - Bug fix: mirplatformgraphics does not have boost program options in its
477+ symbol table (LP: #1301040)
478+ - Bug fix: unity8 crashed with SIGSEGV in glDeleteTextures() from
479+ mir::scene::GLPixelBuffer::~GLPixelBuffer() from
480+ mir::scene::ThreadedSnapshotStrategy::~ThreadedSnapshotStrategy()
481+ (LP: #1256360)
482+
483+ -- Daniel van Vugt <daniel.van.vugt@canonical.com> Thu, 20 Mar 2014 14:05:25 +0800
484+
485 mir (0.1.7+14.04.20140318-0ubuntu1) trusty; urgency=low
486
487 [ Alberto Aguirre ]
488
489=== modified file 'debian/control'
490--- debian/control 2014-03-17 07:35:22 +0000
491+++ debian/control 2014-04-07 13:29:13 +0000
492@@ -31,7 +31,7 @@
493 libgoogle-glog-dev,
494 liblttng-ust-dev,
495 libxkbcommon-dev,
496- libumockdev-dev,
497+ libumockdev-dev (>= 0.6),
498 umockdev,
499 libudev-dev,
500 google-mock (>= 1.6.0+svn437),
501@@ -70,7 +70,7 @@
502 .
503 Contains the protocol's definition files.
504
505-Package: libmirserver17
506+Package: libmirserver18
507 Section: libs
508 Architecture: i386 amd64 armhf arm64
509 Multi-Arch: same
510@@ -148,7 +148,7 @@
511 Architecture: i386 amd64 armhf arm64
512 Multi-Arch: same
513 Pre-Depends: ${misc:Pre-Depends}
514-Depends: libmirserver17 (= ${binary:Version}),
515+Depends: libmirserver18 (= ${binary:Version}),
516 libmirprotobuf-dev (= ${binary:Version}),
517 mircommon-dev (= ${binary:Version}),
518 libglm-dev,
519
520=== renamed file 'debian/libmirserver17.install' => 'debian/libmirserver18.install'
521--- debian/libmirserver17.install 2014-03-12 06:41:13 +0000
522+++ debian/libmirserver18.install 2014-04-07 13:29:13 +0000
523@@ -1,1 +1,1 @@
524-usr/lib/*/libmirserver.so.17
525+usr/lib/*/libmirserver.so.18
526
527=== added file 'deploy-and-test.sh'
528--- deploy-and-test.sh 1970-01-01 00:00:00 +0000
529+++ deploy-and-test.sh 2014-04-07 13:29:13 +0000
530@@ -0,0 +1,21 @@
531+#!/bin/sh
532+
533+if [ ! -d build-android-arm ] ; then
534+ echo "Built tree not found in $(pwd)/build-android-arm"
535+ exit 1
536+fi
537+
538+# Unpack umockdev requirements
539+( cd build-android-arm ;
540+ apt-get download umockdev:armhf libumockdev0:armhf ;
541+ dpkg -x umockdev_*armhf*.deb . ;
542+ dpkg -x libumockdev0_*armhf*.deb .
543+)
544+
545+adb push build-android-arm/bin /home/phablet/mir/bin
546+adb push build-android-arm/lib /home/phablet/mir/lib
547+adb push build-android-arm/usr /home/phablet/mir/usr
548+
549+adb shell "LD_LIBRARY_PATH=/home/phablet/mir/usr/lib/arm-linux-gnueabihf/:/home/phablet/mir/lib PATH=$PATH:/home/phablet/mir/usr/bin bash -c \"cd /home/phablet/mir/usr/bin ; umockdev-run /home/phablet/mir/bin/mir_unit_tests\""
550+adb shell "LD_LIBRARY_PATH=/home/phablet/mir/usr/lib/arm-linux-gnueabihf/:/home/phablet/mir/lib PATH=$PATH:/home/phablet/mir/usr/bin bash -c \"cd /home/phablet/mir/usr/bin ; umockdev-run /home/phablet/mir/bin/mir_integration_tests\""
551+adb shell "LD_LIBRARY_PATH=/home/phablet/mir/usr/lib/arm-linux-gnueabihf/:/home/phablet/mir/lib PATH=$PATH:/home/phablet/mir/usr/bin bash -c \"cd /home/phablet/mir/usr/bin ; umockdev-run /home/phablet/mir/bin/mir_acceptance_tests\""
552
553=== modified file 'examples/demo-shell/demo_renderer.cpp'
554--- examples/demo-shell/demo_renderer.cpp 2014-03-05 04:13:32 +0000
555+++ examples/demo-shell/demo_renderer.cpp 2014-04-07 13:29:13 +0000
556@@ -17,13 +17,131 @@
557 */
558
559 #include "demo_renderer.h"
560+#include <mir/graphics/renderable.h>
561+#include <cmath>
562
563 using namespace mir;
564 using namespace mir::examples;
565
566+namespace
567+{
568+
569+float penumbra_curve(float x)
570+{
571+ return 1.0f - std::sin(x * M_PI / 2.0f);
572+}
573+
574+GLuint generate_shadow_corner_texture(float opacity)
575+{
576+ struct Texel
577+ {
578+ GLubyte luminance;
579+ GLubyte alpha;
580+ };
581+
582+ int const width = 256;
583+ Texel image[width][width];
584+
585+ int const max = width - 1;
586+ for (int y = 0; y < width; ++y)
587+ {
588+ float curve_y = opacity * 255.0f *
589+ penumbra_curve(static_cast<float>(y) / max);
590+ for (int x = 0; x < width; ++x)
591+ {
592+ Texel *t = &image[y][x];
593+ t->luminance = 0;
594+ t->alpha = curve_y * penumbra_curve(static_cast<float>(x) / max);
595+ }
596+ }
597+
598+ GLuint corner;
599+ glGenTextures(1, &corner);
600+ glBindTexture(GL_TEXTURE_2D, corner);
601+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
602+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
603+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
604+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
605+ glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA,
606+ width, width, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
607+ image);
608+
609+ return corner;
610+}
611+
612+GLuint generate_frame_corner_texture()
613+{
614+ struct Texel
615+ {
616+ GLubyte r, g, b, a;
617+ };
618+
619+ int const width = 256;
620+ Texel image[width][width];
621+
622+ int cx = width / 2;
623+ int cy = width / 2;
624+ int radius_sqr = cx * cx;
625+
626+ for (int y = 0; y < width; ++y)
627+ {
628+ for (int x = 0; x < width; ++x)
629+ {
630+ GLubyte lum = 128;
631+ GLubyte alpha = 255;
632+
633+ // Cut out the corner in a circular shape.
634+ if (x < cx && y < cy)
635+ {
636+ int dx = cx - x;
637+ int dy = cy - y;
638+ if (dx * dx + dy * dy >= radius_sqr)
639+ alpha = 0;
640+ }
641+
642+ // Set gradient
643+ if (y < cy)
644+ {
645+ float brighten = (1.0f - (static_cast<float>(y) / cy));
646+ if (x < cx)
647+ brighten *= std::sin(x * M_PI / width);
648+
649+ lum += (255 - lum) * brighten;
650+ }
651+
652+ image[y][x] = {lum, lum, lum, alpha};
653+ }
654+ }
655+
656+ GLuint corner;
657+ glGenTextures(1, &corner);
658+ glBindTexture(GL_TEXTURE_2D, corner);
659+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
660+ GL_LINEAR_MIPMAP_LINEAR);
661+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
662+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
663+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
664+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
665+ width, width, 0, GL_RGBA, GL_UNSIGNED_BYTE,
666+ image);
667+ glGenerateMipmap(GL_TEXTURE_2D); // Antialiasing please
668+
669+ return corner;
670+}
671+
672+} // namespace
673+
674 DemoRenderer::DemoRenderer(geometry::Rectangle const& display_area)
675 : GLRenderer(display_area)
676 {
677+ shadow_corner_tex = generate_shadow_corner_texture(0.4f);
678+ titlebar_corner_tex = generate_frame_corner_texture();
679+}
680+
681+DemoRenderer::~DemoRenderer()
682+{
683+ glDeleteTextures(1, &shadow_corner_tex);
684+ glDeleteTextures(1, &titlebar_corner_tex);
685 }
686
687 void DemoRenderer::begin() const
688@@ -31,3 +149,156 @@
689 glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
690 glClear(GL_COLOR_BUFFER_BIT);
691 }
692+
693+void DemoRenderer::tessellate(std::vector<Primitive>& primitives,
694+ graphics::Renderable const& renderable,
695+ geometry::Size const& buf_size) const
696+{
697+ GLRenderer::tessellate(primitives, renderable, buf_size);
698+ tessellate_shadow(primitives, renderable, 80.0f);
699+ tessellate_frame(primitives, renderable, 30.0f);
700+}
701+
702+void DemoRenderer::tessellate_shadow(std::vector<Primitive>& primitives,
703+ graphics::Renderable const& renderable,
704+ float radius) const
705+{
706+ auto const& rect = renderable.screen_position();
707+ GLfloat left = rect.top_left.x.as_int();
708+ GLfloat right = left + rect.size.width.as_int();
709+ GLfloat top = rect.top_left.y.as_int();
710+ GLfloat bottom = top + rect.size.height.as_int();
711+
712+ auto n = primitives.size();
713+ primitives.resize(n + 8);
714+
715+ GLfloat rightr = right + radius;
716+ GLfloat leftr = left - radius;
717+ GLfloat topr = top - radius;
718+ GLfloat bottomr = bottom + radius;
719+
720+ auto& right_shadow = primitives[n++];
721+ right_shadow.tex_id = shadow_corner_tex;
722+ right_shadow.type = GL_TRIANGLE_FAN;
723+ right_shadow.vertices.resize(4);
724+ right_shadow.vertices[0] = {{right, top, 0.0f}, {0.0f, 0.0f}};
725+ right_shadow.vertices[1] = {{rightr, top, 0.0f}, {1.0f, 0.0f}};
726+ right_shadow.vertices[2] = {{rightr, bottom, 0.0f}, {1.0f, 0.0f}};
727+ right_shadow.vertices[3] = {{right, bottom, 0.0f}, {0.0f, 0.0f}};
728+
729+ auto& left_shadow = primitives[n++];
730+ left_shadow.tex_id = shadow_corner_tex;
731+ left_shadow.type = GL_TRIANGLE_FAN;
732+ left_shadow.vertices.resize(4);
733+ left_shadow.vertices[0] = {{leftr, top, 0.0f}, {1.0f, 0.0f}};
734+ left_shadow.vertices[1] = {{left, top, 0.0f}, {0.0f, 0.0f}};
735+ left_shadow.vertices[2] = {{left, bottom, 0.0f}, {0.0f, 0.0f}};
736+ left_shadow.vertices[3] = {{leftr, bottom, 0.0f}, {1.0f, 0.0f}};
737+
738+ auto& top_shadow = primitives[n++];
739+ top_shadow.tex_id = shadow_corner_tex;
740+ top_shadow.type = GL_TRIANGLE_FAN;
741+ top_shadow.vertices.resize(4);
742+ top_shadow.vertices[0] = {{left, topr, 0.0f}, {1.0f, 0.0f}};
743+ top_shadow.vertices[1] = {{right, topr, 0.0f}, {1.0f, 0.0f}};
744+ top_shadow.vertices[2] = {{right, top, 0.0f}, {0.0f, 0.0f}};
745+ top_shadow.vertices[3] = {{left, top, 0.0f}, {0.0f, 0.0f}};
746+
747+ auto& bottom_shadow = primitives[n++];
748+ bottom_shadow.tex_id = shadow_corner_tex;
749+ bottom_shadow.type = GL_TRIANGLE_FAN;
750+ bottom_shadow.vertices.resize(4);
751+ bottom_shadow.vertices[0] = {{left, bottom, 0.0f}, {0.0f, 0.0f}};
752+ bottom_shadow.vertices[1] = {{right, bottom, 0.0f}, {0.0f, 0.0f}};
753+ bottom_shadow.vertices[2] = {{right, bottomr, 0.0f}, {1.0f, 0.0f}};
754+ bottom_shadow.vertices[3] = {{left, bottomr, 0.0f}, {1.0f, 0.0f}};
755+
756+ auto& tr_shadow = primitives[n++];
757+ tr_shadow.tex_id = shadow_corner_tex;
758+ tr_shadow.type = GL_TRIANGLE_FAN;
759+ tr_shadow.vertices.resize(4);
760+ tr_shadow.vertices[0] = {{right, top, 0.0f}, {0.0f, 0.0f}};
761+ tr_shadow.vertices[1] = {{right, topr, 0.0f}, {1.0f, 0.0f}};
762+ tr_shadow.vertices[2] = {{rightr, topr, 0.0f}, {1.0f, 1.0f}};
763+ tr_shadow.vertices[3] = {{rightr, top, 0.0f}, {0.0f, 1.0f}};
764+
765+ auto& br_shadow = primitives[n++];
766+ br_shadow.tex_id = shadow_corner_tex;
767+ br_shadow.type = GL_TRIANGLE_FAN;
768+ br_shadow.vertices.resize(4);
769+ br_shadow.vertices[0] = {{right, bottom, 0.0f}, {0.0f, 0.0f}};
770+ br_shadow.vertices[1] = {{rightr, bottom, 0.0f}, {1.0f, 0.0f}};
771+ br_shadow.vertices[2] = {{rightr, bottomr, 0.0f}, {1.0f, 1.0f}};
772+ br_shadow.vertices[3] = {{right, bottomr, 0.0f}, {0.0f, 1.0f}};
773+
774+ auto& bl_shadow = primitives[n++];
775+ bl_shadow.tex_id = shadow_corner_tex;
776+ bl_shadow.type = GL_TRIANGLE_FAN;
777+ bl_shadow.vertices.resize(4);
778+ bl_shadow.vertices[0] = {{left, bottom, 0.0f}, {0.0f, 0.0f}};
779+ bl_shadow.vertices[1] = {{left, bottomr, 0.0f}, {1.0f, 0.0f}};
780+ bl_shadow.vertices[2] = {{leftr, bottomr, 0.0f}, {1.0f, 1.0f}};
781+ bl_shadow.vertices[3] = {{leftr, bottom, 0.0f}, {0.0f, 1.0f}};
782+
783+ auto& tl_shadow = primitives[n++];
784+ tl_shadow.tex_id = shadow_corner_tex;
785+ tl_shadow.type = GL_TRIANGLE_FAN;
786+ tl_shadow.vertices.resize(4);
787+ tl_shadow.vertices[0] = {{left, top, 0.0f}, {0.0f, 0.0f}};
788+ tl_shadow.vertices[1] = {{leftr, top, 0.0f}, {1.0f, 0.0f}};
789+ tl_shadow.vertices[2] = {{leftr, topr, 0.0f}, {1.0f, 1.0f}};
790+ tl_shadow.vertices[3] = {{left, topr, 0.0f}, {0.0f, 1.0f}};
791+
792+ // Shadows always need blending...
793+ glEnable(GL_BLEND);
794+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
795+}
796+
797+void DemoRenderer::tessellate_frame(std::vector<Primitive>& primitives,
798+ graphics::Renderable const& renderable,
799+ float titlebar_height) const
800+{
801+ auto const& rect = renderable.screen_position();
802+ GLfloat left = rect.top_left.x.as_int();
803+ GLfloat right = left + rect.size.width.as_int();
804+ GLfloat top = rect.top_left.y.as_int();
805+
806+ auto n = primitives.size();
807+ primitives.resize(n + 3);
808+
809+ GLfloat htop = top - titlebar_height;
810+ GLfloat inleft = left + titlebar_height; // Square proportions for corners
811+ GLfloat inright = right - titlebar_height;
812+
813+ GLfloat mid = (left + right) / 2.0f;
814+ if (inleft > mid) inleft = mid;
815+ if (inright < mid) inright = mid;
816+
817+ auto& top_left_corner = primitives[n++];
818+ top_left_corner.tex_id = titlebar_corner_tex;
819+ top_left_corner.type = GL_TRIANGLE_FAN;
820+ top_left_corner.vertices.resize(4);
821+ top_left_corner.vertices[0] = {{left, htop, 0.0f}, {0.0f, 0.0f}};
822+ top_left_corner.vertices[1] = {{inleft, htop, 0.0f}, {1.0f, 0.0f}};
823+ top_left_corner.vertices[2] = {{inleft, top, 0.0f}, {1.0f, 1.0f}};
824+ top_left_corner.vertices[3] = {{left, top, 0.0f}, {0.0f, 1.0f}};
825+
826+ auto& top_right_corner = primitives[n++];
827+ top_right_corner.tex_id = titlebar_corner_tex;
828+ top_right_corner.type = GL_TRIANGLE_FAN;
829+ top_right_corner.vertices.resize(4);
830+ top_right_corner.vertices[0] = {{inright, htop, 0.0f}, {1.0f, 0.0f}};
831+ top_right_corner.vertices[1] = {{right, htop, 0.0f}, {0.0f, 0.0f}};
832+ top_right_corner.vertices[2] = {{right, top, 0.0f}, {0.0f, 1.0f}};
833+ top_right_corner.vertices[3] = {{inright, top, 0.0f}, {1.0f, 1.0f}};
834+
835+ auto& titlebar = primitives[n++];
836+ titlebar.tex_id = titlebar_corner_tex;
837+ titlebar.type = GL_TRIANGLE_FAN;
838+ titlebar.vertices.resize(4);
839+ titlebar.vertices[0] = {{inleft, htop, 0.0f}, {1.0f, 0.0f}};
840+ titlebar.vertices[1] = {{inright, htop, 0.0f}, {1.0f, 0.0f}};
841+ titlebar.vertices[2] = {{inright, top, 0.0f}, {1.0f, 1.0f}};
842+ titlebar.vertices[3] = {{inleft, top, 0.0f}, {1.0f, 1.0f}};
843+}
844+
845
846=== modified file 'examples/demo-shell/demo_renderer.h'
847--- examples/demo-shell/demo_renderer.h 2014-02-14 09:58:06 +0000
848+++ examples/demo-shell/demo_renderer.h 2014-04-07 13:29:13 +0000
849@@ -30,7 +30,22 @@
850 {
851 public:
852 DemoRenderer(geometry::Rectangle const& display_area);
853+ ~DemoRenderer();
854+
855 void begin() const override;
856+ void tessellate(std::vector<Primitive>& primitives,
857+ graphics::Renderable const& renderable,
858+ geometry::Size const& buf_size) const override;
859+ void tessellate_shadow(std::vector<Primitive>& primitives,
860+ graphics::Renderable const& renderable,
861+ float radius) const;
862+ void tessellate_frame(std::vector<Primitive>& primitives,
863+ graphics::Renderable const& renderable,
864+ float titlebar_height) const;
865+
866+private:
867+ GLuint shadow_corner_tex;
868+ GLuint titlebar_corner_tex;
869 };
870
871 } // namespace examples
872
873=== modified file 'examples/render_overlays.cpp'
874--- examples/render_overlays.cpp 2014-03-17 07:35:22 +0000
875+++ examples/render_overlays.cpp 2014-04-07 13:29:13 +0000
876@@ -105,17 +105,17 @@
877 {
878 }
879
880- std::shared_ptr<mg::Buffer> buffer(unsigned long) const override
881+ std::shared_ptr<mg::Buffer> buffer(void const*) const override
882 {
883 return client->last_rendered();
884 }
885
886- bool alpha_enabled() const
887+ bool alpha_enabled() const override
888 {
889 return false;
890 }
891
892- geom::Rectangle screen_position() const
893+ geom::Rectangle screen_position() const override
894 {
895 return position;
896 }
897@@ -130,14 +130,14 @@
898 return trans;
899 }
900
901- bool shaped() const
902+ bool shaped() const override
903 {
904 return false;
905 }
906
907- bool should_be_rendered_in(geom::Rectangle const& rect) const override
908+ bool visible() const override
909 {
910- return rect.overlaps(position);
911+ return true;
912 }
913
914 int buffers_ready_for_compositor() const override
915@@ -168,7 +168,9 @@
916 mir::DefaultServerConfiguration conf{argc, argv};
917
918 auto platform = conf.the_graphics_platform();
919- auto display = platform->create_display(conf.the_display_configuration_policy());
920+ auto display = platform->create_display(
921+ conf.the_display_configuration_policy(),
922+ conf.the_gl_config());
923 auto buffer_allocator = platform->create_buffer_allocator(conf.the_buffer_initializer());
924
925 mg::BufferProperties buffer_properties{
926
927=== modified file 'examples/render_surfaces.cpp'
928--- examples/render_surfaces.cpp 2014-03-11 04:03:54 +0000
929+++ examples/render_surfaces.cpp 2014-04-07 13:29:13 +0000
930@@ -31,7 +31,8 @@
931 #include "mir/graphics/display_buffer.h"
932 #include "mir/graphics/gl_context.h"
933 #include "mir/shell/surface_factory.h"
934-#include "mir/shell/surface.h"
935+#include "mir/scene/surface.h"
936+#include "mir/scene/surface_coordinator.h"
937 #include "mir/run_mir.h"
938 #include "mir/report_exception.h"
939 #include "mir/raii.h"
940@@ -41,6 +42,9 @@
941 #include "image_renderer.h"
942 #include "server_configuration.h"
943
944+#define GLM_FORCE_RADIANS
945+#include <glm/gtc/matrix_transform.hpp>
946+
947 #include <thread>
948 #include <atomic>
949 #include <chrono>
950@@ -90,6 +94,7 @@
951 std::weak_ptr<mg::Cursor> cursor;
952 static const uint32_t bg_color = 0x00000000;
953 static const uint32_t fg_color = 0xffdd4814;
954+static const float min_alpha = 0.3f;
955
956 void update_cursor(uint32_t bg_color, uint32_t fg_color)
957 {
958@@ -233,8 +238,16 @@
959 y = new_y;
960 }
961
962- surface->set_rotation(total_elapsed_sec * 120.0f, rotation_axis);
963- surface->set_alpha(0.5 + 0.5 * sin(alpha_offset + 2 * M_PI * total_elapsed_sec / 3.0));
964+ glm::mat4 trans = glm::rotate(glm::mat4(1.0f),
965+ glm::radians(total_elapsed_sec * 120.0f),
966+ rotation_axis);
967+ surface->set_transformation(trans);
968+
969+ float const alpha_amplitude = (1.0f - min_alpha) / 2.0f;
970+ surface->set_alpha(min_alpha + alpha_amplitude +
971+ alpha_amplitude *
972+ sin(alpha_offset + 2 * M_PI * total_elapsed_sec /
973+ 3.0));
974 }
975
976 private:
977@@ -433,7 +446,7 @@
978 std::cout << "Rendering " << moveables.size() << " surfaces" << std::endl;
979
980 auto const display = the_display();
981- auto const surface_factory = the_scene_surface_factory();
982+ auto const surface_coordinator = the_surface_coordinator();
983 /* TODO: Get proper configuration */
984 geom::Rectangles view_area;
985 display->for_each_display_buffer([&view_area](mg::DisplayBuffer const& db)
986@@ -452,12 +465,11 @@
987 int i = 0;
988 for (auto& m : moveables)
989 {
990- auto const s = surface_factory->create_surface(
991- nullptr,
992+ auto const s = surface_coordinator->add_surface(
993 msh::a_surface().of_size(surface_size)
994 .of_pixel_format(surface_pf)
995 .of_buffer_usage(mg::BufferUsage::hardware),
996- mf::SurfaceId(), {});
997+ {});
998
999 /*
1000 * We call swap_buffers() twice so that the surface is
1001
1002=== modified file 'include/platform/mir/graphics/display_buffer.h'
1003--- include/platform/mir/graphics/display_buffer.h 2014-03-06 06:05:17 +0000
1004+++ include/platform/mir/graphics/display_buffer.h 2014-04-07 13:29:13 +0000
1005@@ -20,11 +20,11 @@
1006 #define MIR_GRAPHICS_DISPLAY_BUFFER_H_
1007
1008 #include <mir/geometry/rectangle.h>
1009+#include <mir/graphics/renderable.h>
1010 #include <mir_toolkit/common.h>
1011
1012 #include <memory>
1013 #include <functional>
1014-#include <list>
1015
1016 namespace mir
1017 {
1018@@ -32,7 +32,6 @@
1019 {
1020
1021 class Buffer;
1022-class Renderable;
1023
1024 /**
1025 * Interface to an output framebuffer.
1026@@ -57,7 +56,7 @@
1027 that Renderable via OpenGL, or via another method. If the Renderable is to be rendered
1028 via OpenGL, render_fn will be invoked on that Renderable. */
1029 virtual void render_and_post_update(
1030- std::list<std::shared_ptr<Renderable>> const& renderlist,
1031+ RenderableList const& renderlist,
1032 std::function<void(Renderable const&)> const& render_fn) = 0;
1033
1034 /** to be deprecated */
1035
1036=== added file 'include/platform/mir/graphics/gl_config.h'
1037--- include/platform/mir/graphics/gl_config.h 1970-01-01 00:00:00 +0000
1038+++ include/platform/mir/graphics/gl_config.h 2014-04-07 13:29:13 +0000
1039@@ -0,0 +1,54 @@
1040+/*
1041+ * Copyright © 2014 Canonical Ltd.
1042+ *
1043+ * This program is free software: you can redistribute it and/or modify it
1044+ * under the terms of the GNU Lesser General Public License version 3,
1045+ * as published by the Free Software Foundation.
1046+ *
1047+ * This program is distributed in the hope that it will be useful,
1048+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1049+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1050+ * GNU Lesser General Public License for more details.
1051+ *
1052+ * You should have received a copy of the GNU Lesser General Public License
1053+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1054+ *
1055+ * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
1056+ */
1057+
1058+#ifndef MIR_GRAPHICS_GL_CONFIG_H_
1059+#define MIR_GRAPHICS_GL_CONFIG_H_
1060+
1061+namespace mir
1062+{
1063+namespace graphics
1064+{
1065+
1066+/**
1067+ * Interface for customizing aspects of the GL config used by the server.
1068+ */
1069+class GLConfig
1070+{
1071+public:
1072+ virtual ~GLConfig() = default;
1073+
1074+ /**
1075+ * Gets the bits to use for each pixel in the depth buffer.
1076+ */
1077+ virtual int depth_buffer_bits() const = 0;
1078+
1079+ /**
1080+ * Gets the bits to use for each pixel in the stencil buffer.
1081+ */
1082+ virtual int stencil_buffer_bits() const = 0;
1083+
1084+protected:
1085+ GLConfig() = default;
1086+ GLConfig(GLConfig const&) = delete;
1087+ GLConfig& operator=(GLConfig const&) = delete;
1088+};
1089+
1090+}
1091+}
1092+
1093+#endif /* MIR_GRAPHICS_GL_CONFIG_H_ */
1094
1095=== modified file 'include/platform/mir/graphics/platform.h'
1096--- include/platform/mir/graphics/platform.h 2014-03-06 06:05:17 +0000
1097+++ include/platform/mir/graphics/platform.h 2014-04-07 13:29:13 +0000
1098@@ -22,6 +22,7 @@
1099
1100 #include "basic_platform.h"
1101
1102+#include <boost/program_options/options_description.hpp>
1103 #include <memory>
1104
1105 namespace mir
1106@@ -48,6 +49,7 @@
1107 class DisplayReport;
1108 class DisplayConfigurationPolicy;
1109 class GraphicBufferAllocator;
1110+class GLConfig;
1111
1112 /**
1113 * \defgroup platform_enablement Mir platform enablement
1114@@ -81,7 +83,8 @@
1115 * Creates the display subsystem.
1116 */
1117 virtual std::shared_ptr<Display> create_display(
1118- std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy) = 0;
1119+ std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy,
1120+ std::shared_ptr<GLConfig> const& gl_config) = 0;
1121
1122 /**
1123 * Gets the IPC package for the platform.
1124@@ -119,6 +122,10 @@
1125 */
1126 extern "C" typedef std::shared_ptr<Platform>(*CreatePlatform)(std::shared_ptr<options::Option> const& options, std::shared_ptr<DisplayReport> const& report);
1127 extern "C" std::shared_ptr<Platform> create_platform (std::shared_ptr<options::Option> const& options, std::shared_ptr<DisplayReport> const& report);
1128+extern "C" typedef void(*AddPlatformOptions)(
1129+ boost::program_options::options_description& config);
1130+extern "C" void add_platform_options(
1131+ boost::program_options::options_description& config);
1132 }
1133 }
1134
1135
1136=== modified file 'include/platform/mir/graphics/renderable.h'
1137--- include/platform/mir/graphics/renderable.h 2014-03-17 07:35:22 +0000
1138+++ include/platform/mir/graphics/renderable.h 2014-04-07 13:29:13 +0000
1139@@ -22,6 +22,7 @@
1140 #include <mir/geometry/rectangle.h>
1141 #include <glm/glm.hpp>
1142 #include <memory>
1143+#include <list>
1144
1145 namespace mir
1146 {
1147@@ -35,19 +36,15 @@
1148 /**
1149 * Return the next buffer that should be composited/rendered.
1150 *
1151- * \param [in] frameno The frameno parameter is important for
1152- * multi-monitor platforms. Calls with the same frameno
1153- * will get the same buffer returned. This ensures that
1154- * a surface visible on multiple outputs does not get
1155- * its buffers consumed any faster than the refresh
1156- * rate of a single monitor. Implementations may ignore
1157- * the value of frameno on single-monitor platforms
1158- * only. The caller should always ensure the frameno
1159- * is different to the previous frame. The exact value
1160- * of frameno is not important but a large range of
1161- * values is recommended.
1162+ * \param [in] user_id An arbitrary unique identifier used to distinguish
1163+ * separate threads/monitors/components which need
1164+ * to concurrently receive the same buffer. Calling
1165+ * with the same user_id will return a new (different)
1166+ * buffer to that user each time. For consistency,
1167+ * all callers need to determine their user_id in the
1168+ * same way (e.g. always use "this" pointer).
1169 */
1170- virtual std::shared_ptr<Buffer> buffer(unsigned long frameno) const = 0;
1171+ virtual std::shared_ptr<Buffer> buffer(void const* user_id) const = 0;
1172
1173 virtual bool alpha_enabled() const = 0;
1174 virtual geometry::Rectangle screen_position() const = 0;
1175@@ -69,7 +66,14 @@
1176 * the surface itself).
1177 */
1178 virtual glm::mat4 transformation() const = 0;
1179- virtual bool should_be_rendered_in(geometry::Rectangle const& rect) const = 0;
1180+
1181+ /**
1182+ * TODO: Its a bit questionable that we have this member function, why not
1183+ * just trim the renderable from the RenderableList? Its convenient
1184+ * to have this function temporarily while refactoring --kdub
1185+ */
1186+ virtual bool visible() const = 0;
1187+
1188 virtual bool shaped() const = 0; // meaning the pixel format has alpha
1189 virtual int buffers_ready_for_compositor() const = 0;
1190
1191@@ -80,6 +84,9 @@
1192 Renderable& operator=(Renderable const&) = delete;
1193 };
1194
1195+// XXX Would performance be better with a vector?
1196+typedef std::list<std::shared_ptr<Renderable>> RenderableList;
1197+
1198 }
1199 }
1200
1201
1202=== modified file 'include/platform/mir/options/default_configuration.h'
1203--- include/platform/mir/options/default_configuration.h 2014-03-17 07:35:22 +0000
1204+++ include/platform/mir/options/default_configuration.h 2014-04-07 13:29:13 +0000
1205@@ -37,6 +37,7 @@
1206 boost::program_options::options_description_easy_init add_options();
1207
1208 private:
1209+ void add_platform_options();
1210 // accessed via the base interface, when access to add_options() has been "lost"
1211 std::shared_ptr<options::Option> the_options() const override;
1212
1213
1214=== added file 'include/platform/mir/shared_library_loader.h'
1215--- include/platform/mir/shared_library_loader.h 1970-01-01 00:00:00 +0000
1216+++ include/platform/mir/shared_library_loader.h 2014-04-07 13:29:13 +0000
1217@@ -0,0 +1,28 @@
1218+/*
1219+ * Copyright © 2013 Canonical Ltd.
1220+ *
1221+ * This program is free software: you can redistribute it and/or modify it
1222+ * under the terms of the GNU Lesser General Public License version 3,
1223+ * as published by the Free Software Foundation.
1224+ *
1225+ * This program is distributed in the hope that it will be useful,
1226+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1227+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1228+ * GNU Lesser General Public License for more details.
1229+ *
1230+ * You should have received a copy of the GNU Lesser General Public License
1231+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1232+ *
1233+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
1234+ */
1235+
1236+#ifndef MIR_SHARED_LIBRARY_LOADER_H_
1237+#define MIR_SHARED_LIBRARY_LOADER_H_
1238+
1239+#include <string>
1240+namespace mir
1241+{
1242+class SharedLibrary;
1243+SharedLibrary const* load_library(std::string const& libname);
1244+}
1245+#endif
1246
1247=== modified file 'include/server/mir/compositor/buffer_stream.h'
1248--- include/server/mir/compositor/buffer_stream.h 2014-03-07 03:15:55 +0000
1249+++ include/server/mir/compositor/buffer_stream.h 2014-04-07 13:29:13 +0000
1250@@ -43,7 +43,7 @@
1251
1252 virtual void swap_client_buffers(graphics::Buffer* old_buffer, std::function<void(graphics::Buffer* new_buffer)> complete) = 0;
1253 virtual std::shared_ptr<graphics::Buffer>
1254- lock_compositor_buffer(unsigned long frameno) = 0;
1255+ lock_compositor_buffer(void const* user_id) = 0;
1256 virtual std::shared_ptr<graphics::Buffer> lock_snapshot_buffer() = 0;
1257 virtual MirPixelFormat get_stream_pixel_format() = 0;
1258 virtual geometry::Size stream_size() = 0;
1259
1260=== modified file 'include/server/mir/compositor/gl_renderer.h'
1261--- include/server/mir/compositor/gl_renderer.h 2014-03-17 07:35:22 +0000
1262+++ include/server/mir/compositor/gl_renderer.h 2014-04-07 13:29:13 +0000
1263@@ -54,14 +54,27 @@
1264 GLfloat texcoord[2];
1265 };
1266
1267+ struct Primitive
1268+ {
1269+ GLenum type; // GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_TRIANGLES etc
1270+ GLuint tex_id; // GL texture ID (or 0 to represent the surface itself)
1271+ std::vector<Vertex> vertices;
1272+ };
1273+
1274 /**
1275 * tessellate defines the list of triangles that will be used to render
1276 * the surface. By default it just returns 4 vertices for a rectangle.
1277 * However you can override its behaviour to tessellate more finely and
1278 * deform freely for effects like wobbly windows.
1279 *
1280- * \returns The mode to be passed to glDrawArrays, e.g. GL_TRIANGLE_STRIP,
1281- * GL_TRIANGLE_FAN or GL_TRIANGLES.
1282+ * \param [in,out] primitives The list of rendering primitives to be
1283+ * grown and/or modified.
1284+ * \param [in] renderable The renderable surface being tessellated.
1285+ * \param [in] buf_size The dimensions of the buffer being rendered,
1286+ * which can be particularly useful in
1287+ * calculating texcoords for a surface being
1288+ * actively resized (as the buf_size doesn't
1289+ * yet match renderable.size()).
1290 *
1291 * \note The cohesion of this function to GLRenderer is quite loose and it
1292 * does not strictly need to reside here.
1293@@ -69,8 +82,18 @@
1294 * the only OpenGL-specific class in the display server, and
1295 * tessellation is very much OpenGL-specific.
1296 */
1297- virtual GLenum tessellate(graphics::Renderable const& renderable,
1298- std::vector<Vertex>& vertices) const;
1299+ virtual void tessellate(std::vector<Primitive>& primitives,
1300+ graphics::Renderable const& renderable,
1301+ geometry::Size const& buf_size) const;
1302+
1303+ /**
1304+ * Load the texture for a surface any which way you like. The default
1305+ * implementation does so with efficient GPU-side caching built in.
1306+ *
1307+ * \returns The OpenGL texture name for the surface.
1308+ */
1309+ virtual GLuint load_texture(graphics::Renderable const& renderable,
1310+ graphics::Buffer& buffer) const;
1311
1312 private:
1313 GLuint vertex_shader;
1314
1315=== modified file 'include/server/mir/compositor/renderer.h'
1316--- include/server/mir/compositor/renderer.h 2014-03-17 07:35:22 +0000
1317+++ include/server/mir/compositor/renderer.h 2014-04-07 13:29:13 +0000
1318@@ -40,8 +40,8 @@
1319 virtual void set_rotation(float degrees) = 0;
1320 virtual void begin() const = 0;
1321
1322- // XXX The buffer parameter here could now be replaced with a "frameno"
1323- // instead, and use renderable.buffer(frameno). Is that better?
1324+ // XXX The buffer parameter here could now be replaced with
1325+ // renderable::buffer().
1326 virtual void render(graphics::Renderable const& renderable,
1327 graphics::Buffer& buffer) const = 0;
1328 virtual void end() const = 0;
1329
1330=== modified file 'include/server/mir/compositor/scene.h'
1331--- include/server/mir/compositor/scene.h 2014-03-17 07:35:22 +0000
1332+++ include/server/mir/compositor/scene.h 2014-04-07 13:29:13 +0000
1333@@ -20,6 +20,7 @@
1334 #define MIR_COMPOSITOR_SCENE_H_
1335
1336 #include "mir/geometry/forward.h"
1337+#include "mir/graphics/renderable.h"
1338
1339 #include <memory>
1340 #include <functional>
1341@@ -62,13 +63,15 @@
1342 public:
1343 virtual ~Scene() {}
1344
1345+ /**
1346+ * Generate a valid list of renderables based on the current state of the Scene.
1347+ * \returns a list of mg::Renderables. The list is in stacking order from back to front.
1348+ */
1349+ virtual graphics::RenderableList generate_renderable_list() const = 0;
1350+
1351 // Back to front; normal rendering order
1352 virtual void for_each_if(FilterForScene& filter, OperatorForScene& op) = 0;
1353
1354- // Front to back; as used when scanning for occlusions
1355- virtual void reverse_for_each_if(FilterForScene& filter,
1356- OperatorForScene& op) = 0;
1357-
1358 /**
1359 * Sets a callback to be called whenever the state of the
1360 * Scene changes.
1361
1362=== modified file 'include/server/mir/default_server_configuration.h'
1363--- include/server/mir/default_server_configuration.h 2014-03-06 06:05:17 +0000
1364+++ include/server/mir/default_server_configuration.h 2014-04-07 13:29:13 +0000
1365@@ -61,7 +61,6 @@
1366 class SessionListener;
1367 class FocusController;
1368 class DisplayLayout;
1369-class SurfaceConfigurator;
1370 }
1371 namespace time
1372 {
1373@@ -69,6 +68,7 @@
1374 }
1375 namespace scene
1376 {
1377+class SurfaceFactory;
1378 class BroadcastingSessionEventSink;
1379 class BufferStreamFactory;
1380 class MediatingDisplayChanger;
1381@@ -78,7 +78,8 @@
1382 class SessionEventHandlerRegister;
1383 class SessionManager;
1384 class SnapshotStrategy;
1385-class SurfaceBuilder;
1386+class SurfaceCoordinator;
1387+class SurfaceConfigurator;
1388 class SurfaceStackModel;
1389 class SurfaceStack;
1390 class SurfaceRanker;
1391@@ -93,6 +94,7 @@
1392 class BufferInitializer;
1393 class DisplayReport;
1394 class GraphicBufferAllocator;
1395+class GLConfig;
1396 namespace nested { class HostConnection; }
1397 }
1398 namespace input
1399@@ -152,6 +154,7 @@
1400 virtual std::shared_ptr<graphics::DisplayConfigurationPolicy> the_display_configuration_policy();
1401 virtual std::shared_ptr<graphics::nested::HostConnection> the_host_connection();
1402 virtual std::shared_ptr<input::EventFilter> the_nested_event_filter();
1403+ virtual std::shared_ptr<graphics::GLConfig> the_gl_config();
1404 /** @} */
1405
1406 /** @name graphics configuration - dependencies
1407@@ -198,12 +201,10 @@
1408 * configurable interfaces for modifying shell
1409 * @{ */
1410 virtual std::shared_ptr<shell::SurfaceFactory> the_shell_surface_factory();
1411- virtual std::shared_ptr<shell::SurfaceFactory> the_scene_surface_factory();
1412 virtual std::shared_ptr<shell::FocusSetter> the_shell_focus_setter();
1413 virtual std::shared_ptr<shell::PlacementStrategy> the_shell_placement_strategy();
1414 virtual std::shared_ptr<shell::SessionListener> the_shell_session_listener();
1415 virtual std::shared_ptr<shell::DisplayLayout> the_shell_display_layout();
1416- virtual std::shared_ptr<shell::SurfaceConfigurator> the_shell_surface_configurator();
1417 /** @} */
1418
1419 /** @name internal scene configuration
1420@@ -216,7 +217,10 @@
1421 virtual std::shared_ptr<scene::SessionEventSink> the_session_event_sink();
1422 virtual std::shared_ptr<scene::SessionEventHandlerRegister> the_session_event_handler_register();
1423 virtual std::shared_ptr<scene::SurfaceStackModel> the_surface_stack_model();
1424- virtual std::shared_ptr<scene::SurfaceRanker> the_surface_ranker();
1425+ virtual std::shared_ptr<scene::SurfaceRanker> the_surface_ranker();
1426+ virtual std::shared_ptr<scene::SurfaceFactory> the_surface_factory();
1427+ virtual std::shared_ptr<scene::SurfaceCoordinator>the_surface_coordinator();
1428+ virtual std::shared_ptr<scene::SurfaceConfigurator> the_surface_configurator();
1429 /** @} */
1430
1431 /** @name scene configuration - dependencies
1432@@ -284,7 +288,7 @@
1433 CachedPtr<scene::SceneReport> scene_report;
1434
1435 CachedPtr<shell::SurfaceFactory> shell_surface_factory;
1436- CachedPtr<shell::SurfaceFactory> scene_surface_factory;
1437+ CachedPtr<scene::SurfaceFactory> surface_factory;
1438 CachedPtr<scene::SessionContainer> session_container;
1439 CachedPtr<shell::FocusSetter> shell_focus_setter;
1440 CachedPtr<shell::PlacementStrategy> shell_placement_strategy;
1441@@ -292,7 +296,7 @@
1442 CachedPtr<scene::PixelBuffer> pixel_buffer;
1443 CachedPtr<scene::SnapshotStrategy> snapshot_strategy;
1444 CachedPtr<shell::DisplayLayout> shell_display_layout;
1445- CachedPtr<shell::SurfaceConfigurator> shell_surface_configurator;
1446+ CachedPtr<scene::SurfaceConfigurator> surface_configurator;
1447 CachedPtr<compositor::DisplayBufferCompositorFactory> display_buffer_compositor_factory;
1448 CachedPtr<compositor::Compositor> compositor;
1449 CachedPtr<compositor::CompositorReport> compositor_report;
1450@@ -304,6 +308,7 @@
1451 CachedPtr<graphics::DisplayConfigurationPolicy> display_configuration_policy;
1452 CachedPtr<graphics::nested::HostConnection> host_connection;
1453 CachedPtr<scene::MediatingDisplayChanger> mediating_display_changer;
1454+ CachedPtr<graphics::GLConfig> gl_config;
1455
1456 private:
1457 std::shared_ptr<options::Configuration> const configuration_options;
1458@@ -321,7 +326,6 @@
1459 std::shared_ptr<scene::BroadcastingSessionEventSink> the_broadcasting_session_event_sink();
1460 std::shared_ptr<input::NestedInputRelay> the_nested_input_relay();
1461 std::shared_ptr<scene::SessionManager> the_session_manager();
1462- std::shared_ptr<scene::SurfaceBuilder> the_surface_builder();
1463 std::shared_ptr<scene::SurfaceController> the_surface_controller();
1464
1465 auto report_factory(char const* report_opt) -> std::unique_ptr<report::ReportFactory>;
1466
1467=== modified file 'include/server/mir/frontend/display_changer.h'
1468--- include/server/mir/frontend/display_changer.h 2013-09-17 20:03:16 +0000
1469+++ include/server/mir/frontend/display_changer.h 2014-04-07 13:29:13 +0000
1470@@ -38,7 +38,6 @@
1471
1472 virtual std::shared_ptr<graphics::DisplayConfiguration> active_configuration() = 0;
1473 virtual void configure(std::shared_ptr<Session> const&, std::shared_ptr<graphics::DisplayConfiguration> const&) = 0;
1474- virtual void ensure_display_powered(std::shared_ptr<Session> const& session) = 0;
1475
1476 protected:
1477 DisplayChanger() = default;
1478
1479=== modified file 'include/server/mir/frontend/session_authorizer.h'
1480--- include/server/mir/frontend/session_authorizer.h 2014-03-06 06:05:17 +0000
1481+++ include/server/mir/frontend/session_authorizer.h 2014-04-07 13:29:13 +0000
1482@@ -29,10 +29,12 @@
1483 class SessionAuthorizer
1484 {
1485 public:
1486- virtual ~SessionAuthorizer() {}
1487+ virtual ~SessionAuthorizer() = default;
1488
1489 virtual bool connection_is_allowed(pid_t pid) = 0;
1490 virtual bool configure_display_is_allowed(pid_t pid) = 0;
1491+ virtual bool screencast_is_allowed(pid_t pid) = 0;
1492+
1493 protected:
1494 SessionAuthorizer() = default;
1495 SessionAuthorizer(SessionAuthorizer const&) = delete;
1496
1497=== modified file 'include/server/mir/input/surface.h'
1498--- include/server/mir/input/surface.h 2014-03-06 06:05:17 +0000
1499+++ include/server/mir/input/surface.h 2014-04-07 13:29:13 +0000
1500@@ -30,7 +30,7 @@
1501 class Surface
1502 {
1503 public:
1504- virtual std::string const& name() const = 0;
1505+ virtual std::string name() const = 0;
1506 virtual geometry::Point top_left() const = 0;
1507 virtual geometry::Size size() const = 0;
1508 virtual bool contains(geometry::Point const& point) const = 0;
1509
1510=== added file 'include/server/mir/scene/surface.h'
1511--- include/server/mir/scene/surface.h 1970-01-01 00:00:00 +0000
1512+++ include/server/mir/scene/surface.h 2014-04-07 13:29:13 +0000
1513@@ -0,0 +1,59 @@
1514+/*
1515+ * Copyright © 2014 Canonical Ltd.
1516+ *
1517+ * This program is free software: you can redistribute it and/or modify it
1518+ * under the terms of the GNU General Public License version 3,
1519+ * as published by the Free Software Foundation.
1520+ *
1521+ * This program is distributed in the hope that it will be useful,
1522+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1523+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1524+ * GNU General Public License for more details.
1525+ *
1526+ * You should have received a copy of the GNU General Public License
1527+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1528+ *
1529+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
1530+ */
1531+
1532+#ifndef MIR_SCENE_SURFACE_H_
1533+#define MIR_SCENE_SURFACE_H_
1534+
1535+#include "mir/graphics/renderable.h"
1536+#include "mir/input/surface.h"
1537+#include "mir/shell/surface.h"
1538+
1539+namespace mir
1540+{
1541+namespace input { class InputChannel; }
1542+
1543+namespace scene
1544+{
1545+class SurfaceObserver;
1546+
1547+class Surface :
1548+ public graphics::Renderable,
1549+ public input::Surface,
1550+ public shell::Surface
1551+{
1552+public:
1553+ // resolve ambiguous member function names
1554+ std::string name() const = 0;
1555+ geometry::Size size() const = 0;
1556+ geometry::Point top_left() const = 0;
1557+ float alpha() const = 0;
1558+
1559+ // member functions that don't exist in base classes
1560+ // TODO input_channel() and on_change() relate to
1561+ // TODO adding and removing the surface from the scene and are probably not
1562+ // TODO cleanest interface for this.
1563+ virtual std::shared_ptr<input::InputChannel> input_channel() const = 0;
1564+ virtual void on_change(std::function<void()> change_notification) = 0;
1565+
1566+ virtual void add_observer(std::shared_ptr<SurfaceObserver> const& observer) = 0;
1567+ virtual void remove_observer(std::shared_ptr<SurfaceObserver> const& observer) = 0;
1568+};
1569+}
1570+}
1571+
1572+#endif // MIR_SCENE_SURFACE_H_
1573
1574=== renamed file 'include/server/mir/shell/surface_configurator.h' => 'include/server/mir/scene/surface_configurator.h'
1575--- include/server/mir/shell/surface_configurator.h 2014-03-06 06:05:17 +0000
1576+++ include/server/mir/scene/surface_configurator.h 2014-04-07 13:29:13 +0000
1577@@ -16,8 +16,8 @@
1578 * Authored by: Robert Carr <robert.carr@canonical.com>
1579 */
1580
1581-#ifndef MIR_SHELL_SURFACE_CONFIGURATOR_H_
1582-#define MIR_SHELL_SURFACE_CONFIGURATOR_H_
1583+#ifndef MIR_SCENE_SURFACE_CONFIGURATOR_H_
1584+#define MIR_SCENE_SURFACE_CONFIGURATOR_H_
1585
1586 #include "mir_toolkit/common.h"
1587
1588@@ -26,7 +26,7 @@
1589 namespace mir
1590 {
1591
1592-namespace shell
1593+namespace scene
1594 {
1595 class Surface;
1596
1597@@ -51,4 +51,4 @@
1598 }
1599 } // namespace mir
1600
1601-#endif // MIR_SHELL_SURFACE_CONFIGURATOR_H_
1602+#endif // MIR_SCENE_SURFACE_CONFIGURATOR_H_
1603
1604=== renamed file 'src/server/scene/surface_builder.h' => 'include/server/mir/scene/surface_coordinator.h'
1605--- src/server/scene/surface_builder.h 2014-03-06 06:05:17 +0000
1606+++ include/server/mir/scene/surface_coordinator.h 2014-04-07 13:29:13 +0000
1607@@ -1,5 +1,5 @@
1608 /*
1609- * Copyright © 2013 Canonical Ltd.
1610+ * Copyright © 2013-14 Canonical Ltd.
1611 *
1612 * This program is free software: you can redistribute it and/or modify it
1613 * under the terms of the GNU General Public License version 3,
1614@@ -17,8 +17,10 @@
1615 */
1616
1617
1618-#ifndef MIR_SCENE_SURFACE_BUILDER_H_
1619-#define MIR_SCENE_SURFACE_BUILDER_H_
1620+#ifndef MIR_SCENE_SURFACE_COORDINATOR_H_
1621+#define MIR_SCENE_SURFACE_COORDINATOR_H_
1622+
1623+#include "mir/scene/surface_ranker.h"
1624
1625 #include <memory>
1626
1627@@ -31,22 +33,25 @@
1628
1629 namespace scene
1630 {
1631-class BasicSurface;
1632+class Surface;
1633+class SurfaceObserver;
1634
1635-class SurfaceBuilder
1636+class SurfaceCoordinator : public SurfaceRanker
1637 {
1638 public:
1639- virtual std::weak_ptr<BasicSurface> create_surface(shell::SurfaceCreationParameters const& params) = 0;
1640+ virtual std::shared_ptr<Surface> add_surface(
1641+ shell::SurfaceCreationParameters const& params,
1642+ std::shared_ptr<SurfaceObserver> const& observer) = 0;
1643
1644- virtual void destroy_surface(std::weak_ptr<BasicSurface> const& surface) = 0;
1645+ virtual void remove_surface(std::weak_ptr<Surface> const& surface) = 0;
1646 protected:
1647- SurfaceBuilder() = default;
1648- virtual ~SurfaceBuilder() = default;
1649- SurfaceBuilder(SurfaceBuilder const&) = delete;
1650- SurfaceBuilder& operator=(SurfaceBuilder const&) = delete;
1651+ SurfaceCoordinator() = default;
1652+ virtual ~SurfaceCoordinator() = default;
1653+ SurfaceCoordinator(SurfaceCoordinator const&) = delete;
1654+ SurfaceCoordinator& operator=(SurfaceCoordinator const&) = delete;
1655 };
1656 }
1657 }
1658
1659
1660-#endif /* MIR_SCENE_SURFACE_BUILDER_H_ */
1661+#endif /* MIR_SCENE_SURFACE_COORDINATOR_H_ */
1662
1663=== added file 'include/server/mir/scene/surface_event_source.h'
1664--- include/server/mir/scene/surface_event_source.h 1970-01-01 00:00:00 +0000
1665+++ include/server/mir/scene/surface_event_source.h 2014-04-07 13:29:13 +0000
1666@@ -0,0 +1,49 @@
1667+/*
1668+ * Copyright © 2014 Canonical Ltd.
1669+ *
1670+ * This program is free software: you can redistribute it and/or modify it
1671+ * under the terms of the GNU General Public License version 3,
1672+ * as published by the Free Software Foundation.
1673+ *
1674+ * This program is distributed in the hope that it will be useful,
1675+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1676+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1677+ * GNU General Public License for more details.
1678+ *
1679+ * You should have received a copy of the GNU General Public License
1680+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1681+ *
1682+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
1683+ */
1684+
1685+#ifndef MIR_SCENE_SURFACE_EVENT_SOURCE_H_
1686+#define MIR_SCENE_SURFACE_EVENT_SOURCE_H_
1687+
1688+#include "mir/scene/surface_observer.h"
1689+#include "mir/frontend/surface_id.h"
1690+#include "mir/frontend/event_sink.h"
1691+
1692+#include <memory>
1693+
1694+namespace mir
1695+{
1696+namespace scene
1697+{
1698+class SurfaceEventSource : public SurfaceObserver
1699+{
1700+public:
1701+ SurfaceEventSource(
1702+ frontend::SurfaceId id,
1703+ std::shared_ptr<frontend::EventSink> const& event_sink);
1704+
1705+ void attrib_change(MirSurfaceAttrib attrib, int value);
1706+ void resize(geometry::Size const& size);
1707+
1708+private:
1709+ frontend::SurfaceId const id;
1710+ std::shared_ptr<frontend::EventSink> const event_sink;
1711+};
1712+}
1713+}
1714+
1715+#endif // MIR_SCENE_SURFACE_EVENT_SOURCE_H_
1716
1717=== renamed file 'src/server/scene/basic_surface_factory.h' => 'include/server/mir/scene/surface_factory.h'
1718--- src/server/scene/basic_surface_factory.h 2014-03-06 06:05:17 +0000
1719+++ include/server/mir/scene/surface_factory.h 2014-04-07 13:29:13 +0000
1720@@ -1,5 +1,5 @@
1721 /*
1722- * Copyright © 2013 Canonical Ltd.
1723+ * Copyright © 2013-2014 Canonical Ltd.
1724 *
1725 * This program is free software: you can redistribute it and/or modify it
1726 * under the terms of the GNU General Public License version 3,
1727@@ -16,33 +16,33 @@
1728 * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
1729 */
1730
1731-#ifndef MIR_SCENE_BASIC_SURFACE_FACTORY_H_
1732-#define MIR_SCENE_BASIC_SURFACE_FACTORY_H_
1733+#ifndef MIR_SCENE_SURFACE_FACTORY_H_
1734+#define MIR_SCENE_SURFACE_FACTORY_H_
1735
1736 #include "mir/shell/surface_creation_parameters.h"
1737 #include <memory>
1738-#include <functional>
1739
1740 namespace mir
1741 {
1742 namespace scene
1743 {
1744+class Surface;
1745
1746-class BasicSurface;
1747-class BasicSurfaceFactory
1748+class SurfaceFactory
1749 {
1750 public:
1751- BasicSurfaceFactory() = default;
1752- virtual ~BasicSurfaceFactory() = default;
1753-
1754- virtual std::shared_ptr<BasicSurface> create_surface(
1755- shell::SurfaceCreationParameters const&, std::function<void()> const&) = 0;
1756+ SurfaceFactory() = default;
1757+ virtual ~SurfaceFactory() = default;
1758+
1759+ virtual std::shared_ptr<Surface> create_surface(
1760+ shell::SurfaceCreationParameters const& params) = 0;
1761+
1762 private:
1763- BasicSurfaceFactory(const BasicSurfaceFactory&) = delete;
1764- BasicSurfaceFactory& operator=(const BasicSurfaceFactory&) = delete;
1765+ SurfaceFactory(const SurfaceFactory&) = delete;
1766+ SurfaceFactory& operator=(const SurfaceFactory&) = delete;
1767 };
1768
1769 }
1770 }
1771
1772-#endif /* MIR_SCENE_BASIC_SURFACE_FACTORY_H_ */
1773+#endif /* MIR_SCENE_SURFACE_FACTORY_H_ */
1774
1775=== added file 'include/server/mir/scene/surface_observer.h'
1776--- include/server/mir/scene/surface_observer.h 1970-01-01 00:00:00 +0000
1777+++ include/server/mir/scene/surface_observer.h 2014-04-07 13:29:13 +0000
1778@@ -0,0 +1,45 @@
1779+/*
1780+ * Copyright © 2014 Canonical Ltd.
1781+ *
1782+ * This program is free software: you can redistribute it and/or modify it
1783+ * under the terms of the GNU General Public License version 3,
1784+ * as published by the Free Software Foundation.
1785+ *
1786+ * This program is distributed in the hope that it will be useful,
1787+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1788+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1789+ * GNU General Public License for more details.
1790+ *
1791+ * You should have received a copy of the GNU General Public License
1792+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1793+ *
1794+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
1795+ */
1796+
1797+#ifndef MIR_SCENE_SURFACE_OBSERVER_H_
1798+#define MIR_SCENE_SURFACE_OBSERVER_H_
1799+
1800+#include "mir/geometry/size.h"
1801+#include "mir_toolkit/common.h"
1802+
1803+namespace mir
1804+{
1805+namespace scene
1806+{
1807+// Initial cut - supporting the frontend requirement, more will follow
1808+class SurfaceObserver
1809+{
1810+public:
1811+ virtual void attrib_change(MirSurfaceAttrib attrib, int value) = 0;
1812+ virtual void resize(geometry::Size const& size) = 0;
1813+
1814+protected:
1815+ SurfaceObserver() = default;
1816+ virtual ~SurfaceObserver() = default;
1817+ SurfaceObserver(SurfaceObserver const&) = delete;
1818+ SurfaceObserver& operator=(SurfaceObserver const&) = delete;
1819+};
1820+}
1821+}
1822+
1823+#endif // MIR_SCENE_SURFACE_OBSERVER_H_
1824
1825=== renamed file 'src/server/scene/surface_ranker.h' => 'include/server/mir/scene/surface_ranker.h'
1826--- src/server/scene/surface_ranker.h 2014-03-06 06:05:17 +0000
1827+++ include/server/mir/scene/surface_ranker.h 2014-04-07 13:29:13 +0000
1828@@ -26,12 +26,12 @@
1829 {
1830 namespace scene
1831 {
1832-class BasicSurface;
1833+class Surface;
1834
1835 class SurfaceRanker
1836 {
1837 public:
1838- virtual void raise(std::weak_ptr<BasicSurface> const& surface) = 0;
1839+ virtual void raise(std::weak_ptr<Surface> const& surface) = 0;
1840
1841 protected:
1842 SurfaceRanker() = default;
1843
1844=== modified file 'include/server/mir/shell/surface.h'
1845--- include/server/mir/shell/surface.h 2014-03-06 06:05:17 +0000
1846+++ include/server/mir/shell/surface.h 2014-04-07 13:29:13 +0000
1847@@ -50,10 +50,8 @@
1848
1849 virtual void allow_framedropping(bool) = 0;
1850
1851- virtual void raise(std::shared_ptr<scene::SurfaceRanker> const& controller) = 0;
1852-
1853 virtual void resize(geometry::Size const& size) = 0;
1854- virtual void set_rotation(float degrees, glm::vec3 const& axis) = 0;
1855+ virtual void set_transformation(glm::mat4 const& t) = 0;
1856
1857 virtual float alpha() const = 0;
1858 virtual void set_alpha(float alpha) = 0;
1859
1860=== modified file 'include/server/mir/shell/surface_factory.h'
1861--- include/server/mir/shell/surface_factory.h 2013-08-28 03:41:48 +0000
1862+++ include/server/mir/shell/surface_factory.h 2014-04-07 13:29:13 +0000
1863@@ -1,5 +1,5 @@
1864 /*
1865- * Copyright © 2012 Canonical Ltd.
1866+ * Copyright © 2012-2014 Canonical Ltd.
1867 *
1868 * This program is free software: you can redistribute it and/or modify it
1869 * under the terms of the GNU General Public License version 3,
1870@@ -19,15 +19,12 @@
1871 #ifndef MIR_SHELL_SURFACE_FACTORY_H_
1872 #define MIR_SHELL_SURFACE_FACTORY_H_
1873
1874-#include "mir/frontend/surface_id.h"
1875 #include <memory>
1876
1877 namespace mir
1878 {
1879-namespace frontend
1880-{
1881-class EventSink;
1882-}
1883+namespace scene { class SurfaceObserver; }
1884+
1885 namespace shell
1886 {
1887 class Session;
1888@@ -40,8 +37,9 @@
1889 virtual std::shared_ptr<Surface> create_surface(
1890 Session* session,
1891 SurfaceCreationParameters const& params,
1892- frontend::SurfaceId id,
1893- std::shared_ptr<frontend::EventSink> const& sink) = 0;
1894+ std::shared_ptr<scene::SurfaceObserver> const& observer) = 0;
1895+
1896+ virtual void destroy_surface(std::shared_ptr<Surface> const& surface) = 0;
1897
1898 protected:
1899 virtual ~SurfaceFactory() {}
1900
1901=== added file 'include/shared/mir/geometry/length.h'
1902--- include/shared/mir/geometry/length.h 1970-01-01 00:00:00 +0000
1903+++ include/shared/mir/geometry/length.h 2014-04-07 13:29:13 +0000
1904@@ -0,0 +1,102 @@
1905+/*
1906+ * Copyright © 2014 Canonical Ltd.
1907+ *
1908+ * This program is free software: you can redistribute it and/or modify it
1909+ * under the terms of the GNU Lesser General Public License version 3,
1910+ * as published by the Free Software Foundation.
1911+ *
1912+ * This program is distributed in the hope that it will be useful,
1913+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1914+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1915+ * GNU Lesser General Public License for more details.
1916+ *
1917+ * You should have received a copy of the GNU Lesser General Public License
1918+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1919+ *
1920+ * Authored by: Daniel van Vugt <daniel.van.vugt@canonical.com>
1921+ */
1922+
1923+#ifndef MIR_GEOMETRY_LENGTH_H_
1924+#define MIR_GEOMETRY_LENGTH_H_
1925+
1926+namespace mir
1927+{
1928+namespace geometry
1929+{
1930+
1931+/// Length represents a physical length in the real world. The number of pixels
1932+/// this equates to can then be calculated based on a given DPI.
1933+class Length
1934+{
1935+public:
1936+ enum Units
1937+ {
1938+ micrometres = 1,
1939+ millimetres = 1000,
1940+ centimetres = 10000,
1941+ inches = 25400
1942+ };
1943+
1944+ Length() : magnitude(0) {}
1945+ Length(Length const&) = default;
1946+ Length& operator=(Length const&) = default;
1947+ Length(float mag, Units units) : magnitude(mag * units) {}
1948+
1949+ float as(Units units) const
1950+ {
1951+ return static_cast<float>(magnitude) / units;
1952+ }
1953+
1954+ float as_pixels(float dpi) const
1955+ {
1956+ return as(inches) * dpi;
1957+ }
1958+
1959+ bool operator==(Length const& rhs) const
1960+ {
1961+ return magnitude == rhs.magnitude;
1962+ }
1963+
1964+ bool operator!=(Length const& rhs) const
1965+ {
1966+ return magnitude != rhs.magnitude;
1967+ }
1968+
1969+private:
1970+ float magnitude;
1971+};
1972+
1973+inline Length operator"" _mm(long double mag)
1974+{
1975+ return Length(mag, Length::millimetres);
1976+}
1977+
1978+inline Length operator"" _mm(unsigned long long mag)
1979+{
1980+ return Length(mag, Length::millimetres);
1981+}
1982+
1983+inline Length operator"" _cm(long double mag)
1984+{
1985+ return Length(mag, Length::centimetres);
1986+}
1987+
1988+inline Length operator"" _cm(unsigned long long mag)
1989+{
1990+ return Length(mag, Length::centimetres);
1991+}
1992+
1993+inline Length operator"" _in(long double mag)
1994+{
1995+ return Length(mag, Length::inches);
1996+}
1997+
1998+inline Length operator"" _in(unsigned long long mag)
1999+{
2000+ return Length(mag, Length::inches);
2001+}
2002+
2003+} // namespace geometry
2004+} // namespace mir
2005+
2006+#endif // MIR_GEOMETRY_LENGTH_H_
2007
2008=== modified file 'include/test/mir_test_doubles/fake_renderable.h'
2009--- include/test/mir_test_doubles/fake_renderable.h 2014-03-17 07:35:22 +0000
2010+++ include/test/mir_test_doubles/fake_renderable.h 2014-04-07 13:29:13 +0000
2011@@ -42,7 +42,7 @@
2012 : rect{{x, y}, {width, height}},
2013 opacity(opacity),
2014 rectangular(rectangular),
2015- visible(visible),
2016+ visible_(visible),
2017 posted(posted)
2018 {
2019 }
2020@@ -57,9 +57,9 @@
2021 return glm::mat4();
2022 }
2023
2024- bool should_be_rendered_in(const mir::geometry::Rectangle &r) const override
2025+ bool visible() const override
2026 {
2027- return visible && posted && rect.overlaps(r);
2028+ return visible_ && posted;
2029 }
2030
2031 bool shaped() const override
2032@@ -72,7 +72,7 @@
2033 buf = b;
2034 }
2035
2036- std::shared_ptr<graphics::Buffer> buffer(unsigned long) const override
2037+ std::shared_ptr<graphics::Buffer> buffer(void const*) const override
2038 {
2039 return buf;
2040 }
2041@@ -97,7 +97,7 @@
2042 mir::geometry::Rectangle rect;
2043 float opacity;
2044 bool rectangular;
2045- bool visible;
2046+ bool visible_;
2047 bool posted;
2048 };
2049
2050
2051=== modified file 'include/test/mir_test_doubles/mock_buffer_bundle.h'
2052--- include/test/mir_test_doubles/mock_buffer_bundle.h 2014-03-07 03:15:55 +0000
2053+++ include/test/mir_test_doubles/mock_buffer_bundle.h 2014-04-07 13:29:13 +0000
2054@@ -39,7 +39,7 @@
2055
2056 MOCK_METHOD1(client_acquire, void(std::function<void(graphics::Buffer*)>));
2057 MOCK_METHOD1(client_release, void(graphics::Buffer*));
2058- MOCK_METHOD1(compositor_acquire, std::shared_ptr<graphics::Buffer>(unsigned long));
2059+ MOCK_METHOD1(compositor_acquire, std::shared_ptr<graphics::Buffer>(void const*));
2060 MOCK_METHOD1(compositor_release, void(std::shared_ptr<graphics::Buffer> const&));
2061 MOCK_METHOD0(snapshot_acquire, std::shared_ptr<graphics::Buffer>());
2062 MOCK_METHOD1(snapshot_release, void(std::shared_ptr<graphics::Buffer> const&));
2063
2064=== modified file 'include/test/mir_test_doubles/mock_buffer_stream.h'
2065--- include/test/mir_test_doubles/mock_buffer_stream.h 2014-03-07 03:15:55 +0000
2066+++ include/test/mir_test_doubles/mock_buffer_stream.h 2014-04-07 13:29:13 +0000
2067@@ -33,7 +33,7 @@
2068 {
2069 MOCK_METHOD2(swap_client_buffers, void(graphics::Buffer*, std::function<void(graphics::Buffer*)> completee));
2070 MOCK_METHOD1(lock_compositor_buffer,
2071- std::shared_ptr<graphics::Buffer>(unsigned long));
2072+ std::shared_ptr<graphics::Buffer>(void const*));
2073 MOCK_METHOD0(lock_snapshot_buffer, std::shared_ptr<graphics::Buffer>());
2074
2075 MOCK_METHOD0(get_stream_pixel_format, MirPixelFormat());
2076
2077=== modified file 'include/test/mir_test_doubles/mock_display_buffer.h'
2078--- include/test/mir_test_doubles/mock_display_buffer.h 2014-03-06 06:05:17 +0000
2079+++ include/test/mir_test_doubles/mock_display_buffer.h 2014-04-07 13:29:13 +0000
2080@@ -46,7 +46,7 @@
2081 MOCK_METHOD0(release_current, void());
2082 MOCK_METHOD0(post_update, void());
2083 MOCK_CONST_METHOD0(can_bypass, bool());
2084- MOCK_METHOD2(render_and_post_update, void(std::list<std::shared_ptr<graphics::Renderable>> const&,
2085+ MOCK_METHOD2(render_and_post_update, void(graphics::RenderableList const&,
2086 std::function<void(graphics::Renderable const&)> const&));
2087 MOCK_CONST_METHOD0(orientation, MirOrientation());
2088 };
2089
2090=== modified file 'include/test/mir_test_doubles/mock_display_changer.h'
2091--- include/test/mir_test_doubles/mock_display_changer.h 2013-09-17 20:03:16 +0000
2092+++ include/test/mir_test_doubles/mock_display_changer.h 2014-04-07 13:29:13 +0000
2093@@ -35,7 +35,6 @@
2094 MOCK_METHOD0(active_configuration, std::shared_ptr<graphics::DisplayConfiguration>());
2095 MOCK_METHOD2(configure,
2096 void(std::shared_ptr<frontend::Session> const&, std::shared_ptr<graphics::DisplayConfiguration> const&));
2097- MOCK_METHOD1(ensure_display_powered, void(std::shared_ptr<frontend::Session> const&));
2098 };
2099
2100 }
2101
2102=== modified file 'include/test/mir_test_doubles/mock_display_device.h'
2103--- include/test/mir_test_doubles/mock_display_device.h 2014-03-11 13:44:57 +0000
2104+++ include/test/mir_test_doubles/mock_display_device.h 2014-04-07 13:29:13 +0000
2105@@ -38,7 +38,7 @@
2106 MOCK_METHOD1(render_gl, void(graphics::android::SwappingGLContext const&));
2107 MOCK_METHOD3(render_gl_and_overlays, void(
2108 graphics::android::SwappingGLContext const&,
2109- std::list<std::shared_ptr<graphics::Renderable>> const&,
2110+ graphics::RenderableList const&,
2111 std::function<void(graphics::Renderable const&)> const&));
2112 MOCK_METHOD1(post, void(graphics::Buffer const&));
2113 MOCK_CONST_METHOD1(apply_orientation, bool(MirOrientation));
2114
2115=== modified file 'include/test/mir_test_doubles/mock_egl.h'
2116--- include/test/mir_test_doubles/mock_egl.h 2014-03-06 06:05:17 +0000
2117+++ include/test/mir_test_doubles/mock_egl.h 2014-04-07 13:29:13 +0000
2118@@ -53,6 +53,33 @@
2119 return false;
2120 }
2121
2122+MATCHER_P2(EGLConfigContainsAttrib, attrib, value, "")
2123+{
2124+ bool attrib_position = true;
2125+ bool attrib_found = false;
2126+
2127+ while (!attrib_position || *arg != EGL_NONE)
2128+ {
2129+ if (attrib_position && *arg == attrib)
2130+ {
2131+ attrib_found = true;
2132+ }
2133+ else if (!attrib_position)
2134+ {
2135+ if (attrib_found && *arg == value)
2136+ {
2137+ return true;
2138+ }
2139+
2140+ attrib_found = false;
2141+ }
2142+ attrib_position = !attrib_position;
2143+ ++arg;
2144+ }
2145+
2146+ return false;
2147+}
2148+
2149 class MockEGL
2150 {
2151 public:
2152
2153=== added file 'include/test/mir_test_doubles/mock_gl_config.h'
2154--- include/test/mir_test_doubles/mock_gl_config.h 1970-01-01 00:00:00 +0000
2155+++ include/test/mir_test_doubles/mock_gl_config.h 2014-04-07 13:29:13 +0000
2156@@ -0,0 +1,43 @@
2157+/*
2158+ * Copyright © 2014 Canonical Ltd.
2159+ *
2160+ * This program is free software: you can redistribute it and/or modify it
2161+ * under the terms of the GNU General Public License version 3,
2162+ * as published by the Free Software Foundation.
2163+ *
2164+ * This program is distributed in the hope that it will be useful,
2165+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2166+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2167+ * GNU General Public License for more details.
2168+ *
2169+ * You should have received a copy of the GNU General Public License
2170+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2171+ *
2172+ * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
2173+ */
2174+
2175+#ifndef MIR_TEST_DOUBLES_MOCK_GL_CONFIG_H_
2176+#define MIR_TEST_DOUBLES_MOCK_GL_CONFIG_H_
2177+
2178+#include "mir/graphics/gl_config.h"
2179+
2180+#include <gmock/gmock.h>
2181+
2182+namespace mir
2183+{
2184+namespace test
2185+{
2186+namespace doubles
2187+{
2188+
2189+struct MockGLConfig : public graphics::GLConfig
2190+{
2191+ MOCK_CONST_METHOD0(depth_buffer_bits, int());
2192+ MOCK_CONST_METHOD0(stencil_buffer_bits, int());
2193+};
2194+
2195+}
2196+}
2197+}
2198+
2199+#endif /* MIR_TEST_DOUBLES_MOCK_GL_CONFIG_H_ */
2200
2201=== modified file 'include/test/mir_test_doubles/mock_hwc_composer_device_1.h'
2202--- include/test/mir_test_doubles/mock_hwc_composer_device_1.h 2014-03-06 06:05:17 +0000
2203+++ include/test/mir_test_doubles/mock_hwc_composer_device_1.h 2014-04-07 13:29:13 +0000
2204@@ -21,8 +21,6 @@
2205
2206 #include <hardware/hwcomposer.h>
2207 #include <gmock/gmock.h>
2208-#include <vector>
2209-#include <memory>
2210
2211 namespace mir
2212 {
2213@@ -37,16 +35,6 @@
2214 MockHWCComposerDevice1()
2215 {
2216 using namespace testing;
2217-
2218- primary_prepare = false;
2219- primary_set = false;
2220- external_prepare = false;
2221- external_set = false;
2222- virtual_prepare = false;
2223- virtual_set = false;
2224- fb_fence = -1;
2225- retire_fence = -1;
2226-
2227 common.version = HWC_DEVICE_API_VERSION_1_1;
2228
2229 registerProcs = hook_registerProcs;
2230@@ -56,91 +44,6 @@
2231 blank = hook_blank;
2232 getDisplayConfigs = hook_getDisplayConfigs;
2233 getDisplayAttributes = hook_getDisplayAttributes;
2234-
2235- ON_CALL(*this, set_interface(_,_,_))
2236- .WillByDefault(Invoke(this, &MockHWCComposerDevice1::save_last_set_arguments));
2237- ON_CALL(*this, prepare_interface(_,_,_))
2238- .WillByDefault(Invoke(this, &MockHWCComposerDevice1::save_last_prepare_arguments));
2239- }
2240-
2241- int save_args(hwc_display_contents_1_t* out, hwc_display_contents_1_t** in)
2242- {
2243- if ((nullptr == in) || (nullptr == *in))
2244- return -1;
2245-
2246- hwc_display_contents_1_t* primary_display = *in;
2247- memcpy(out, primary_display, sizeof(hwc_display_contents_1_t));
2248- return 0;
2249- }
2250-
2251- void hwc_set_return_fence(int fence)
2252- {
2253- fb_fence = fence;
2254- }
2255-
2256- void hwc_set_retire_fence(int fence)
2257- {
2258- retire_fence = fence;
2259- }
2260-
2261- int save_last_prepare_arguments(struct hwc_composer_device_1 *, size_t size, hwc_display_contents_1_t** displays)
2262- {
2263- if ((size == 0) || (!displays))
2264- return -1;
2265-
2266- switch (size)
2267- {
2268- case 3:
2269- virtual_prepare = (!!displays[2]);
2270- case 2:
2271- external_prepare = (!!displays[1]);
2272- case 1:
2273- primary_prepare = (!!displays[0]);
2274- for(auto i = 0u; i < displays[0]->numHwLayers; i++)
2275- {
2276- prepare_layerlist.push_back(displays[0]->hwLayers[i]);
2277- prepare_layerlist.back().visibleRegionScreen = {0, nullptr};
2278- }
2279- save_args(&display0_prepare_content, displays);
2280- default:
2281- break;
2282- }
2283- return 0;
2284- }
2285-
2286- int save_last_set_arguments(
2287- struct hwc_composer_device_1 *, size_t size, hwc_display_contents_1_t** displays)
2288- {
2289-
2290- if ((size == 0) || (!displays))
2291- return -1;
2292-
2293- switch (size)
2294- {
2295- case 3:
2296- virtual_set = (!!displays[2]);
2297- case 2:
2298- external_set = (!!displays[1]);
2299- case 1:
2300- primary_set = (!!displays[0]);
2301- for(auto i = 0u; i < displays[0]->numHwLayers; i++)
2302- {
2303- set_layerlist.push_back(displays[0]->hwLayers[i]);
2304- set_layerlist.back().visibleRegionScreen = {0, nullptr};
2305- }
2306-
2307- save_args(&display0_set_content, displays);
2308-
2309- if (displays[0]->numHwLayers >= 2)
2310- {
2311- displays[0]->hwLayers[1].releaseFenceFd = fb_fence;
2312- displays[0]->retireFenceFd = retire_fence;
2313- }
2314-
2315- default:
2316- break;
2317- }
2318- return 0;
2319 }
2320
2321 static void hook_registerProcs(struct hwc_composer_device_1* mock_hwc, hwc_procs_t const* procs)
2322@@ -188,14 +91,6 @@
2323 MOCK_METHOD3(blank_interface, int(struct hwc_composer_device_1 *, int, int));
2324 MOCK_METHOD4(getDisplayConfigs_interface, int(struct hwc_composer_device_1*, int, uint32_t*, size_t*));
2325 MOCK_METHOD5(getDisplayAttributes_interface, int(struct hwc_composer_device_1*, int, uint32_t, const uint32_t*, int32_t*));
2326-
2327- bool primary_prepare, primary_set, external_prepare, external_set, virtual_prepare, virtual_set;
2328- hwc_display_contents_1_t display0_set_content;
2329- std::vector<hwc_layer_1> set_layerlist;
2330- std::vector<hwc_layer_1> prepare_layerlist;
2331- hwc_display_contents_1_t display0_prepare_content;
2332- int fb_fence;
2333- int retire_fence;
2334 };
2335
2336 }
2337
2338=== added file 'include/test/mir_test_doubles/mock_hwc_device_wrapper.h'
2339--- include/test/mir_test_doubles/mock_hwc_device_wrapper.h 1970-01-01 00:00:00 +0000
2340+++ include/test/mir_test_doubles/mock_hwc_device_wrapper.h 2014-04-07 13:29:13 +0000
2341@@ -0,0 +1,42 @@
2342+/*
2343+ * Copyright © 2014 Canonical Ltd.
2344+ *
2345+ * This program is free software: you can redistribute it and/or modify it
2346+ * under the terms of the GNU General Public License version 3,
2347+ * as published by the Free Software Foundation.
2348+ *
2349+ * This program is distributed in the hope that it will be useful,
2350+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2351+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2352+ * GNU General Public License for more details.
2353+ *
2354+ * You should have received a copy of the GNU General Public License
2355+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2356+ *
2357+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
2358+ */
2359+
2360+#ifndef MIR_TEST_DOUBLES_MOCK_HWC_DEVICE_WRAPPER_H_
2361+#define MIR_TEST_DOUBLES_MOCK_HWC_DEVICE_WRAPPER_H_
2362+
2363+#include "src/platform/graphics/android/hwc_wrapper.h"
2364+
2365+#include <gmock/gmock.h>
2366+
2367+namespace mir
2368+{
2369+namespace test
2370+{
2371+namespace doubles
2372+{
2373+
2374+struct MockHWCDeviceWrapper : public graphics::android::HwcWrapper
2375+{
2376+ MOCK_CONST_METHOD1(prepare, void(hwc_display_contents_1_t&));
2377+ MOCK_CONST_METHOD1(set, void(hwc_display_contents_1_t&));
2378+};
2379+
2380+}
2381+}
2382+}
2383+#endif /* MIR_TEST_DOUBLES_MOCK_HWC_DEVICE_WRAPPER_H_ */
2384
2385=== modified file 'include/test/mir_test_doubles/mock_input_surface.h'
2386--- include/test/mir_test_doubles/mock_input_surface.h 2014-03-06 06:05:17 +0000
2387+++ include/test/mir_test_doubles/mock_input_surface.h 2014-04-07 13:29:13 +0000
2388@@ -43,12 +43,12 @@
2389 Return(geometry::Size{}));
2390 static std::string n;
2391 ON_CALL(*this, name())
2392- .WillByDefault(testing::ReturnRef(n));
2393+ .WillByDefault(testing::Return(n));
2394 }
2395 ~MockInputSurface() noexcept {}
2396 MOCK_CONST_METHOD0(top_left, geometry::Point());
2397 MOCK_CONST_METHOD0(size, geometry::Size());
2398- MOCK_CONST_METHOD0(name, std::string const&());
2399+ MOCK_CONST_METHOD0(name, std::string());
2400 MOCK_CONST_METHOD1(contains, bool(geometry::Point const&));
2401 };
2402
2403
2404=== modified file 'include/test/mir_test_doubles/mock_renderable.h'
2405--- include/test/mir_test_doubles/mock_renderable.h 2014-03-17 07:35:22 +0000
2406+++ include/test/mir_test_doubles/mock_renderable.h 2014-04-07 13:29:13 +0000
2407@@ -37,15 +37,24 @@
2408 .WillByDefault(testing::Return(geometry::Rectangle{{},{}}));
2409 ON_CALL(*this, buffer(testing::_))
2410 .WillByDefault(testing::Return(std::make_shared<StubBuffer>()));
2411+ ON_CALL(*this, buffers_ready_for_compositor())
2412+ .WillByDefault(testing::Return(1));
2413+ ON_CALL(*this, alpha())
2414+ .WillByDefault(testing::Return(1.0f));
2415+ ON_CALL(*this, transformation())
2416+ .WillByDefault(testing::Return(glm::mat4{}));
2417+ ON_CALL(*this, visible())
2418+ .WillByDefault(testing::Return(true));
2419 }
2420- MOCK_CONST_METHOD1(buffer, std::shared_ptr<graphics::Buffer>(unsigned long));
2421+
2422+ MOCK_CONST_METHOD1(buffer, std::shared_ptr<graphics::Buffer>(void const*));
2423 MOCK_CONST_METHOD0(alpha_enabled, bool());
2424 MOCK_CONST_METHOD0(screen_position, geometry::Rectangle());
2425 MOCK_CONST_METHOD0(alpha, float());
2426 MOCK_CONST_METHOD0(transformation, glm::mat4());
2427- MOCK_CONST_METHOD1(should_be_rendered_in, bool(geometry::Rectangle const& rect));
2428+ MOCK_CONST_METHOD0(visible, bool());
2429 MOCK_CONST_METHOD0(shaped, bool());
2430- int buffers_ready_for_compositor() const override { return 1; }
2431+ MOCK_CONST_METHOD0(buffers_ready_for_compositor, int());
2432 };
2433 }
2434 }
2435
2436=== modified file 'include/test/mir_test_doubles/mock_scene.h'
2437--- include/test/mir_test_doubles/mock_scene.h 2014-03-13 09:22:13 +0000
2438+++ include/test/mir_test_doubles/mock_scene.h 2014-04-07 13:29:13 +0000
2439@@ -32,10 +32,14 @@
2440 class MockScene : public compositor::Scene
2441 {
2442 public:
2443+ MockScene()
2444+ {
2445+ ON_CALL(*this, generate_renderable_list())
2446+ .WillByDefault(testing::Return(graphics::RenderableList{}));
2447+ }
2448+ MOCK_CONST_METHOD0(generate_renderable_list, graphics::RenderableList());
2449 MOCK_METHOD2(for_each_if, void(compositor::FilterForScene&,
2450 compositor::OperatorForScene&));
2451- MOCK_METHOD2(reverse_for_each_if, void(compositor::FilterForScene&,
2452- compositor::OperatorForScene&));
2453 MOCK_METHOD1(set_change_callback, void(std::function<void()> const&));
2454 MOCK_METHOD0(lock, void());
2455 MOCK_METHOD0(unlock, void());
2456
2457=== modified file 'include/test/mir_test_doubles/mock_surface.h'
2458--- include/test/mir_test_doubles/mock_surface.h 2014-03-06 06:05:17 +0000
2459+++ include/test/mir_test_doubles/mock_surface.h 2014-04-07 13:29:13 +0000
2460@@ -1,5 +1,5 @@
2461 /*
2462- * Copyright © 2013 Canonical Ltd.
2463+ * Copyright © 2013-2014 Canonical Ltd.
2464 *
2465 * This program is free software: you can redistribute it and/or modify it
2466 * under the terms of the GNU General Public License version 3,
2467@@ -19,16 +19,11 @@
2468 #ifndef MIR_TEST_DOUBLES_MOCK_SURFACE_H_
2469 #define MIR_TEST_DOUBLES_MOCK_SURFACE_H_
2470
2471-#include "src/server/scene/surface_impl.h"
2472-
2473-#include "mir/shell/surface_creation_parameters.h"
2474-#include "null_event_sink.h"
2475-#include "null_surface_configurator.h"
2476+#include "src/server/scene/basic_surface.h"
2477+#include "src/server/report/null_report_factory.h"
2478
2479 #include <gmock/gmock.h>
2480
2481-#include <memory>
2482-
2483 namespace mir
2484 {
2485 namespace test
2486@@ -36,10 +31,17 @@
2487 namespace doubles
2488 {
2489
2490-struct MockSurface : public scene::SurfaceImpl
2491+struct MockSurface : public scene::BasicSurface
2492 {
2493- MockSurface(std::shared_ptr<scene::SurfaceBuilder> const& builder) :
2494- scene::SurfaceImpl(builder, std::make_shared<NullSurfaceConfigurator>(), shell::a_surface(), frontend::SurfaceId{}, std::make_shared<NullEventSink>())
2495+ MockSurface() :
2496+ scene::BasicSurface(
2497+ {},
2498+ {{},{}},
2499+ true,
2500+ {},
2501+ {},
2502+ {},
2503+ mir::report::null_scene_report())
2504 {
2505 }
2506
2507@@ -53,7 +55,6 @@
2508 MOCK_METHOD0(force_requests_to_complete, void());
2509 MOCK_METHOD0(advance_client_buffer, std::shared_ptr<graphics::Buffer>());
2510
2511- MOCK_CONST_METHOD0(name, std::string());
2512 MOCK_CONST_METHOD0(size, geometry::Size());
2513 MOCK_CONST_METHOD0(pixel_format, MirPixelFormat());
2514
2515@@ -62,6 +63,7 @@
2516
2517 MOCK_METHOD2(configure, int(MirSurfaceAttrib, int));
2518 MOCK_METHOD1(take_input_focus, void(std::shared_ptr<shell::InputTargeter> const&));
2519+ MOCK_METHOD1(add_observer, void(std::shared_ptr<scene::SurfaceObserver> const&));
2520 };
2521
2522 }
2523
2524=== modified file 'include/test/mir_test_doubles/mock_surface_configurator.h'
2525--- include/test/mir_test_doubles/mock_surface_configurator.h 2013-07-31 23:09:53 +0000
2526+++ include/test/mir_test_doubles/mock_surface_configurator.h 2014-04-07 13:29:13 +0000
2527@@ -19,7 +19,7 @@
2528 #ifndef MIR_TEST_DOUBLES_MOCK_SURFACE_CONFIGURATOR_H_
2529 #define MIR_TEST_DOUBLES_MOCK_SURFACE_CONFIGURATOR_H_
2530
2531-#include "mir/shell/surface_configurator.h"
2532+#include "mir/scene/surface_configurator.h"
2533
2534 #include <gmock/gmock.h>
2535
2536@@ -30,10 +30,10 @@
2537 namespace doubles
2538 {
2539
2540-struct MockSurfaceConfigurator : public shell::SurfaceConfigurator
2541+struct MockSurfaceConfigurator : public scene::SurfaceConfigurator
2542 {
2543- MOCK_METHOD3(select_attribute_value, int(shell::Surface const&, MirSurfaceAttrib, int));
2544- MOCK_METHOD3(attribute_set, void(shell::Surface const&, MirSurfaceAttrib, int));
2545+ MOCK_METHOD3(select_attribute_value, int(scene::Surface const&, MirSurfaceAttrib, int));
2546+ MOCK_METHOD3(attribute_set, void(scene::Surface const&, MirSurfaceAttrib, int));
2547 };
2548
2549 }
2550
2551=== modified file 'include/test/mir_test_doubles/mock_surface_factory.h'
2552--- include/test/mir_test_doubles/mock_surface_factory.h 2013-08-28 03:41:48 +0000
2553+++ include/test/mir_test_doubles/mock_surface_factory.h 2014-04-07 13:29:13 +0000
2554@@ -33,11 +33,12 @@
2555
2556 struct MockSurfaceFactory : public shell::SurfaceFactory
2557 {
2558- MOCK_METHOD4(create_surface, std::shared_ptr<shell::Surface>(
2559+ MOCK_METHOD3(create_surface, std::shared_ptr<shell::Surface>(
2560 shell::Session*,
2561 const shell::SurfaceCreationParameters&,
2562- frontend::SurfaceId,
2563- std::shared_ptr<frontend::EventSink> const&));
2564+ std::shared_ptr<scene::SurfaceObserver> const&));
2565+
2566+ void destroy_surface(std::shared_ptr<shell::Surface> const& /*surface*/) override {}
2567 };
2568
2569 }
2570
2571=== modified file 'include/test/mir_test_doubles/mock_surface_ranker.h'
2572--- include/test/mir_test_doubles/mock_surface_ranker.h 2014-03-06 06:05:17 +0000
2573+++ include/test/mir_test_doubles/mock_surface_ranker.h 2014-04-07 13:29:13 +0000
2574@@ -20,7 +20,7 @@
2575 #ifndef MIR_TEST_DOUBLES_MOCK_SURFACE_RANKER_H_
2576 #define MIR_TEST_DOUBLES_MOCK_SURFACE_RANKER_H_
2577
2578-#include "src/server/scene/surface_ranker.h"
2579+#include "mir/scene/surface_ranker.h"
2580
2581 #include <gmock/gmock.h>
2582
2583@@ -33,7 +33,7 @@
2584
2585 struct MockSurfaceRanker : public scene::SurfaceRanker
2586 {
2587- MOCK_METHOD1(raise, void(std::weak_ptr<scene::BasicSurface> const&));
2588+ MOCK_METHOD1(raise, void(std::weak_ptr<scene::Surface> const&));
2589 };
2590
2591 }
2592
2593=== modified file 'include/test/mir_test_doubles/null_display_buffer.h'
2594--- include/test/mir_test_doubles/null_display_buffer.h 2014-03-06 06:05:17 +0000
2595+++ include/test/mir_test_doubles/null_display_buffer.h 2014-04-07 13:29:13 +0000
2596@@ -37,7 +37,7 @@
2597 void post_update() {}
2598 bool can_bypass() const override { return false; }
2599 void render_and_post_update(
2600- std::list<std::shared_ptr<graphics::Renderable>> const&,
2601+ graphics::RenderableList const&,
2602 std::function<void(graphics::Renderable const&)> const&) {}
2603 MirOrientation orientation() const override { return mir_orientation_normal; }
2604 };
2605
2606=== modified file 'include/test/mir_test_doubles/null_display_changer.h'
2607--- include/test/mir_test_doubles/null_display_changer.h 2013-09-17 20:03:16 +0000
2608+++ include/test/mir_test_doubles/null_display_changer.h 2014-04-07 13:29:13 +0000
2609@@ -39,9 +39,6 @@
2610 virtual void configure(std::shared_ptr<frontend::Session> const&, std::shared_ptr<graphics::DisplayConfiguration> const&)
2611 {
2612 }
2613- virtual void ensure_display_powered(std::shared_ptr<frontend::Session> const&)
2614- {
2615- }
2616 };
2617 }
2618 }
2619
2620=== modified file 'include/test/mir_test_doubles/null_platform.h'
2621--- include/test/mir_test_doubles/null_platform.h 2014-03-06 06:05:17 +0000
2622+++ include/test/mir_test_doubles/null_platform.h 2014-04-07 13:29:13 +0000
2623@@ -39,7 +39,8 @@
2624 }
2625
2626 std::shared_ptr<graphics::Display> create_display(
2627- std::shared_ptr<graphics::DisplayConfigurationPolicy> const&)
2628+ std::shared_ptr<graphics::DisplayConfigurationPolicy> const&,
2629+ std::shared_ptr<graphics::GLConfig> const&)
2630 {
2631 return std::make_shared<NullDisplay>();
2632 }
2633
2634=== modified file 'include/test/mir_test_doubles/null_surface_configurator.h'
2635--- include/test/mir_test_doubles/null_surface_configurator.h 2013-07-29 22:55:20 +0000
2636+++ include/test/mir_test_doubles/null_surface_configurator.h 2014-04-07 13:29:13 +0000
2637@@ -19,7 +19,7 @@
2638 #ifndef MIR_TEST_DOUBLES_NULL_SURFACE_CONFIGURATOR_H_
2639 #define MIR_TEST_DOUBLES_NULL_SURFACE_CONFIGURATOR_H_
2640
2641-#include "mir/shell/surface_configurator.h"
2642+#include "mir/scene/surface_configurator.h"
2643
2644 namespace mir
2645 {
2646@@ -28,14 +28,14 @@
2647 namespace doubles
2648 {
2649
2650-struct NullSurfaceConfigurator : public shell::SurfaceConfigurator
2651+struct NullSurfaceConfigurator : public scene::SurfaceConfigurator
2652 {
2653- int select_attribute_value(shell::Surface const&,
2654+ int select_attribute_value(scene::Surface const&,
2655 MirSurfaceAttrib, int requested_value)
2656 {
2657 return requested_value;
2658 }
2659- void attribute_set(shell::Surface const&,
2660+ void attribute_set(scene::Surface const&,
2661 MirSurfaceAttrib, int)
2662 {
2663 }
2664
2665=== modified file 'include/test/mir_test_doubles/stub_buffer_stream.h'
2666--- include/test/mir_test_doubles/stub_buffer_stream.h 2014-03-07 03:15:55 +0000
2667+++ include/test/mir_test_doubles/stub_buffer_stream.h 2014-04-07 13:29:13 +0000
2668@@ -40,7 +40,7 @@
2669 {
2670 complete(&stub_client_buffer);
2671 }
2672- std::shared_ptr<graphics::Buffer> lock_compositor_buffer(unsigned long) override
2673+ std::shared_ptr<graphics::Buffer> lock_compositor_buffer(void const*) override
2674 {
2675 return stub_compositor_buffer;
2676 }
2677
2678=== modified file 'include/test/mir_test_doubles/stub_display_builder.h'
2679--- include/test/mir_test_doubles/stub_display_builder.h 2014-03-06 06:05:17 +0000
2680+++ include/test/mir_test_doubles/stub_display_builder.h 2014-04-07 13:29:13 +0000
2681@@ -43,7 +43,7 @@
2682 void post_update() {}
2683 bool can_bypass() const override { return false; }
2684 void render_and_post_update(
2685- std::list<std::shared_ptr<graphics::Renderable>> const&,
2686+ graphics::RenderableList const&,
2687 std::function<void(graphics::Renderable const&)> const&) {}
2688 MirOrientation orientation() const override { return mir_orientation_normal; }
2689 void configure(graphics::DisplayConfigurationOutput const&) {}
2690
2691=== modified file 'include/test/mir_test_doubles/stub_display_device.h'
2692--- include/test/mir_test_doubles/stub_display_device.h 2014-03-11 13:44:57 +0000
2693+++ include/test/mir_test_doubles/stub_display_device.h 2014-04-07 13:29:13 +0000
2694@@ -40,7 +40,7 @@
2695 }
2696 void render_gl_and_overlays(
2697 graphics::android::SwappingGLContext const&,
2698- std::list<std::shared_ptr<graphics::Renderable>> const&,
2699+ graphics::RenderableList const&,
2700 std::function<void(graphics::Renderable const&)> const&)
2701 {
2702 }
2703
2704=== added file 'include/test/mir_test_doubles/stub_gl_config.h'
2705--- include/test/mir_test_doubles/stub_gl_config.h 1970-01-01 00:00:00 +0000
2706+++ include/test/mir_test_doubles/stub_gl_config.h 2014-04-07 13:29:13 +0000
2707@@ -0,0 +1,43 @@
2708+/*
2709+ * Copyright © 2014 Canonical Ltd.
2710+ *
2711+ * This program is free software: you can redistribute it and/or modify it
2712+ * under the terms of the GNU General Public License version 3,
2713+ * as published by the Free Software Foundation.
2714+ *
2715+ * This program is distributed in the hope that it will be useful,
2716+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2717+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2718+ * GNU General Public License for more details.
2719+ *
2720+ * You should have received a copy of the GNU General Public License
2721+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2722+ *
2723+ * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
2724+ */
2725+
2726+#ifndef MIR_TEST_DOUBLES_STUB_GL_CONFIG_H_
2727+#define MIR_TEST_DOUBLES_STUB_GL_CONFIG_H_
2728+
2729+#include "mir/graphics/gl_config.h"
2730+
2731+#include <gmock/gmock.h>
2732+
2733+namespace mir
2734+{
2735+namespace test
2736+{
2737+namespace doubles
2738+{
2739+
2740+struct StubGLConfig : public graphics::GLConfig
2741+{
2742+ int depth_buffer_bits() const override { return 0; }
2743+ int stencil_buffer_bits() const override { return 0; }
2744+};
2745+
2746+}
2747+}
2748+}
2749+
2750+#endif /* MIR_TEST_DOUBLES_STUB_GL_CONFIG_H_ */
2751
2752=== modified file 'include/test/mir_test_doubles/stub_ipc_factory.h'
2753--- include/test/mir_test_doubles/stub_ipc_factory.h 2014-03-06 06:05:17 +0000
2754+++ include/test/mir_test_doubles/stub_ipc_factory.h 2014-04-07 13:29:13 +0000
2755@@ -41,7 +41,7 @@
2756 }
2757
2758 std::shared_ptr<protobuf::DisplayServer> make_ipc_server(
2759- pid_t, std::shared_ptr<frontend::EventSink> const&, bool) override
2760+ pid_t, std::shared_ptr<frontend::EventSink> const&) override
2761 {
2762 return server;
2763 }
2764
2765=== modified file 'include/test/mir_test_doubles/stub_renderable.h'
2766--- include/test/mir_test_doubles/stub_renderable.h 2014-03-17 07:35:22 +0000
2767+++ include/test/mir_test_doubles/stub_renderable.h 2014-04-07 13:29:13 +0000
2768@@ -33,7 +33,7 @@
2769 class StubRenderable : public graphics::Renderable
2770 {
2771 public:
2772- std::shared_ptr<graphics::Buffer> buffer(unsigned long) const override
2773+ std::shared_ptr<graphics::Buffer> buffer(void const*) const override
2774 {
2775 return std::make_shared<StubBuffer>();
2776 }
2777@@ -53,7 +53,7 @@
2778 {
2779 return trans;
2780 }
2781- bool should_be_rendered_in(geometry::Rectangle const&) const override
2782+ bool visible() const
2783 {
2784 return true;
2785 }
2786
2787=== modified file 'include/test/mir_test_doubles/stub_session_authorizer.h'
2788--- include/test/mir_test_doubles/stub_session_authorizer.h 2013-08-28 03:41:48 +0000
2789+++ include/test/mir_test_doubles/stub_session_authorizer.h 2014-04-07 13:29:13 +0000
2790@@ -38,6 +38,10 @@
2791 {
2792 return true;
2793 }
2794+ bool screencast_is_allowed(pid_t)
2795+ {
2796+ return true;
2797+ }
2798 };
2799
2800 }
2801
2802=== removed file 'include/test/mir_test_doubles/stub_surface_builder.h'
2803--- include/test/mir_test_doubles/stub_surface_builder.h 2014-03-06 06:05:17 +0000
2804+++ include/test/mir_test_doubles/stub_surface_builder.h 1970-01-01 00:00:00 +0000
2805@@ -1,69 +0,0 @@
2806-/*
2807- * Copyright © 2013-2014 Canonical Ltd.
2808- *
2809- * This program is free software: you can redistribute it and/or modify it
2810- * under the terms of the GNU General Public License version 3,
2811- * as published by the Free Software Foundation.
2812- *
2813- * This program is distributed in the hope that it will be useful,
2814- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2815- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2816- * GNU General Public License for more details.
2817- *
2818- * You should have received a copy of the GNU General Public License
2819- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2820- *
2821- * Authored by: Alan Griffiths <alan@octopull.co.uk>
2822- */
2823-
2824-
2825-#ifndef MIR_TEST_DOUBLES_STUB_SURFACE_BUILDER_H_
2826-#define MIR_TEST_DOUBLES_STUB_SURFACE_BUILDER_H_
2827-
2828-#include "src/server/scene/surface_builder.h"
2829-#include "src/server/scene/basic_surface.h"
2830-#include "src/server/report/null_report_factory.h"
2831-#include "mir/shell/surface_creation_parameters.h"
2832-
2833-#include "mir_test_doubles/stub_buffer_stream.h"
2834-#include <memory>
2835-namespace mir
2836-{
2837-namespace test
2838-{
2839-namespace doubles
2840-{
2841-
2842-class StubSurfaceBuilder : public scene::SurfaceBuilder
2843-{
2844-public:
2845- StubSurfaceBuilder() :
2846- dummy_surface(std::make_shared<scene::BasicSurface>(
2847- std::string("stub"),
2848- geometry::Rectangle{{},{}},
2849- [](){},
2850- false,
2851- std::make_shared<StubBufferStream>(),
2852- std::shared_ptr<input::InputChannel>(),
2853- mir::report::null_scene_report()))
2854- {
2855- }
2856-
2857- std::weak_ptr<scene::BasicSurface> create_surface(shell::SurfaceCreationParameters const&)
2858- {
2859- return dummy_surface;
2860- }
2861-
2862- void destroy_surface(std::weak_ptr<scene::BasicSurface> const& )
2863- {
2864- }
2865-
2866-private:
2867- std::shared_ptr<scene::BasicSurface> dummy_surface;
2868-};
2869-}
2870-}
2871-}
2872-
2873-
2874-#endif /* MIR_TEST_DOUBLES_STUB_SURFACE_BUILDER_H_ */
2875
2876=== removed file 'include/test/mir_test_doubles/stub_surface_ranker.h'
2877--- include/test/mir_test_doubles/stub_surface_ranker.h 2014-03-06 06:05:17 +0000
2878+++ include/test/mir_test_doubles/stub_surface_ranker.h 1970-01-01 00:00:00 +0000
2879@@ -1,44 +0,0 @@
2880-/*
2881- * Copyright © 2013 Canonical Ltd.
2882- *
2883- * This program is free software: you can redistribute it and/or modify it
2884- * under the terms of the GNU General Public License version 3,
2885- * as published by the Free Software Foundation.
2886- *
2887- * This program is distributed in the hope that it will be useful,
2888- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2889- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2890- * GNU General Public License for more details.
2891- *
2892- * You should have received a copy of the GNU General Public License
2893- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2894- *
2895- * Authored by: Robert Carr <robert.carr@canonical.com>
2896- */
2897-
2898-
2899-#ifndef MIR_TEST_DOUBLES_STUB_SURFACE_RANKER_H_
2900-#define MIR_TEST_DOUBLES_STUB_SURFACE_RANKER_H_
2901-
2902-#include "src/server/scene/surface_ranker.h"
2903-
2904-namespace mir
2905-{
2906-namespace test
2907-{
2908-namespace doubles
2909-{
2910-
2911-struct StubSurfaceRanker : public scene::SurfaceRanker
2912-{
2913- void raise(std::weak_ptr<scene::BasicSurface> const&) override
2914- {
2915- }
2916-};
2917-
2918-}
2919-}
2920-}
2921-
2922-
2923-#endif /* MIR_TEST_DOUBLES_STUB_SURFACE_RANKER_H_ */
2924
2925=== added file 'include/test/mir_test_framework/declarative_placement_strategy.h'
2926--- include/test/mir_test_framework/declarative_placement_strategy.h 1970-01-01 00:00:00 +0000
2927+++ include/test/mir_test_framework/declarative_placement_strategy.h 2014-04-07 13:29:13 +0000
2928@@ -0,0 +1,64 @@
2929+/*
2930+ * Copyright © 2014 Canonical Ltd.
2931+ *
2932+ * This program is free software: you can redistribute it and/or modify it
2933+ * under the terms of the GNU General Public License version 3,
2934+ * as published by the Free Software Foundation.
2935+ *
2936+ * This program is distributed in the hope that it will be useful,
2937+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2938+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2939+ * GNU General Public License for more details.
2940+ *
2941+ * You should have received a copy of the GNU General Public License
2942+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2943+ *
2944+ * Authored by: Robert Carr <robert.carr@canonical.com>
2945+ */
2946+
2947+#ifndef MIR_TEST_FRAMEWORK_DECLARATIVE_PLACEMENT_STRATEGY_H_
2948+#define MIR_TEST_FRAMEWORK_DECLARATIVE_PLACEMENT_STRATEGY_H_
2949+
2950+#include "mir/shell/placement_strategy.h"
2951+#include "mir/geometry/rectangle.h"
2952+#include "mir/scene/depth_id.h"
2953+
2954+#include <memory>
2955+#include <map>
2956+#include <string>
2957+
2958+namespace mir_test_framework
2959+{
2960+typedef std::map<std::string, mir::geometry::Rectangle> SurfaceGeometries;
2961+typedef std::map<std::string, mir::scene::DepthId> SurfaceDepths;
2962+
2963+/// DeclarativePlacementStrategy is a test utility server component for specifying
2964+/// a static list of surface geometries and relative depths. Used, for example,
2965+/// in input tests where it is necessary to set up scenarios depending on
2966+/// multiple surfaces geometry and stacking.
2967+class DeclarativePlacementStrategy : public mir::shell::PlacementStrategy
2968+{
2969+ public:
2970+ // Placement requests will be passed through to default strategy, and then overriden if the surface appears
2971+ // in the geometry or depth map. This allows for the convenience of leaving some surfaces geometries unspecified
2972+ // and receiving the default behavior.
2973+ DeclarativePlacementStrategy(std::shared_ptr<mir::shell::PlacementStrategy> const& default_strategy,
2974+ SurfaceGeometries const& positions_by_name, SurfaceDepths const& depths_by_name);
2975+
2976+ virtual ~DeclarativePlacementStrategy() = default;
2977+
2978+ mir::shell::SurfaceCreationParameters place(mir::shell::Session const& session, mir::shell::SurfaceCreationParameters const& request_parameters) override;
2979+
2980+protected:
2981+ DeclarativePlacementStrategy(const DeclarativePlacementStrategy&) = delete;
2982+ DeclarativePlacementStrategy& operator=(const DeclarativePlacementStrategy&) = delete;
2983+
2984+private:
2985+ std::shared_ptr<mir::shell::PlacementStrategy> const default_strategy;
2986+
2987+ SurfaceGeometries surface_geometries_by_name;
2988+ SurfaceDepths surface_depths_by_name;
2989+};
2990+}
2991+
2992+#endif // MIR_TEST_FRAMEWORK_DECLARATIVE_PLACEMENT_STRATEGY_H_
2993
2994=== modified file 'include/test/mir_test_framework/udev_environment.h'
2995--- include/test/mir_test_framework/udev_environment.h 2014-03-06 06:05:17 +0000
2996+++ include/test/mir_test_framework/udev_environment.h 2014-04-07 13:29:13 +0000
2997@@ -56,6 +56,7 @@
2998 void add_standard_device(std::string const& name);
2999
3000 UMockdevTestbed *testbed;
3001+ std::string const recordings_path;
3002 };
3003
3004 }
3005
3006=== modified file 'src/client/default_connection_configuration.cpp'
3007--- src/client/default_connection_configuration.cpp 2014-03-06 06:05:17 +0000
3008+++ src/client/default_connection_configuration.cpp 2014-04-07 13:29:13 +0000
3009@@ -103,7 +103,7 @@
3010 {
3011 auto const val_raw = getenv("MIR_CLIENT_PLATFORM_LIB");
3012 std::string const val{val_raw ? val_raw : default_platform_lib};
3013- auto const platform_lib = load_library(val);
3014+ auto const platform_lib = ::load_library(val);
3015
3016 auto const create_client_platform_factory =
3017 platform_lib->load_function<mcl::CreateClientPlatformFactory>(
3018
3019=== modified file 'src/client/lttng/input_receiver_report_tp.h'
3020--- src/client/lttng/input_receiver_report_tp.h 2014-02-03 11:44:32 +0000
3021+++ src/client/lttng/input_receiver_report_tp.h 2014-04-07 13:29:13 +0000
3022@@ -26,6 +26,7 @@
3023 #define MIR_CLIENT_LTTNG_INPUT_RECEIVER_REPORT_TP_H_
3024
3025 #include <lttng/tracepoint.h>
3026+#include <stdint.h>
3027
3028 #ifdef __clang__
3029 /*
3030
3031=== modified file 'src/client/lttng/rpc_report_tp.h'
3032--- src/client/lttng/rpc_report_tp.h 2014-03-06 06:05:17 +0000
3033+++ src/client/lttng/rpc_report_tp.h 2014-04-07 13:29:13 +0000
3034@@ -26,6 +26,7 @@
3035 #define MIR_CLIENT_LTTNG_RPC_REPORT_TP_H_
3036
3037 #include <lttng/tracepoint.h>
3038+#include <stdint.h>
3039
3040 #ifdef __clang__
3041 /*
3042
3043=== modified file 'src/client/mir_client_library.cpp'
3044--- src/client/mir_client_library.cpp 2014-03-06 06:05:17 +0000
3045+++ src/client/mir_client_library.cpp 2014-04-07 13:29:13 +0000
3046@@ -120,8 +120,17 @@
3047 {
3048 if (!error_connections.contains(connection))
3049 {
3050- auto wait_handle = connection->disconnect();
3051- wait_handle->wait_for_all();
3052+ try
3053+ {
3054+ auto wait_handle = connection->disconnect();
3055+ wait_handle->wait_for_all();
3056+ }
3057+ catch (std::exception const&)
3058+ {
3059+ // We're implementing a C API so no exceptions are to be
3060+ // propagated. And that's OK because if disconnect() fails,
3061+ // we don't care why. We're finished with the connection anyway.
3062+ }
3063 }
3064 else
3065 {
3066
3067=== modified file 'src/client/rpc/mir_basic_rpc_channel.cpp'
3068--- src/client/rpc/mir_basic_rpc_channel.cpp 2014-03-06 06:05:17 +0000
3069+++ src/client/rpc/mir_basic_rpc_channel.cpp 2014-04-07 13:29:13 +0000
3070@@ -34,7 +34,7 @@
3071 }
3072
3073 void mclrd::PendingCallCache::save_completion_details(
3074- mir::protobuf::wire::Invocation& invoke,
3075+ mir::protobuf::wire::Invocation const& invoke,
3076 google::protobuf::Message* response,
3077 std::shared_ptr<google::protobuf::Closure> const& complete)
3078 {
3079@@ -102,8 +102,8 @@
3080
3081
3082 mir::protobuf::wire::Invocation mclr::MirBasicRpcChannel::invocation_for(
3083- const google::protobuf::MethodDescriptor* method,
3084- const google::protobuf::Message* request)
3085+ google::protobuf::MethodDescriptor const* method,
3086+ google::protobuf::Message const* request)
3087 {
3088 char buffer[mir::frontend::serialization_buffer_size];
3089
3090
3091=== modified file 'src/client/rpc/mir_basic_rpc_channel.h'
3092--- src/client/rpc/mir_basic_rpc_channel.h 2014-03-06 06:05:17 +0000
3093+++ src/client/rpc/mir_basic_rpc_channel.h 2014-04-07 13:29:13 +0000
3094@@ -55,7 +55,7 @@
3095 PendingCallCache(std::shared_ptr<RpcReport> const& rpc_report);
3096
3097 void save_completion_details(
3098- mir::protobuf::wire::Invocation& invoke,
3099+ mir::protobuf::wire::Invocation const& invoke,
3100 google::protobuf::Message* response,
3101 std::shared_ptr<google::protobuf::Closure> const& complete);
3102
3103@@ -95,8 +95,9 @@
3104 ~MirBasicRpcChannel();
3105
3106 protected:
3107- mir::protobuf::wire::Invocation invocation_for(const google::protobuf::MethodDescriptor* method,
3108- const google::protobuf::Message* request);
3109+ mir::protobuf::wire::Invocation invocation_for(
3110+ google::protobuf::MethodDescriptor const* method,
3111+ google::protobuf::Message const* request);
3112 int next_id();
3113
3114 private:
3115
3116=== modified file 'src/client/rpc/mir_socket_rpc_channel.cpp'
3117--- src/client/rpc/mir_socket_rpc_channel.cpp 2014-03-06 06:05:17 +0000
3118+++ src/client/rpc/mir_socket_rpc_channel.cpp 2014-04-07 13:29:13 +0000
3119@@ -142,8 +142,39 @@
3120 {
3121 if (!disconnected.load())
3122 {
3123- auto surface = dynamic_cast<mir::protobuf::Surface*>(response);
3124- mir::protobuf::Screencast* screencast{nullptr};
3125+ auto const message_type = response->GetTypeName();
3126+
3127+ mir::protobuf::Surface* surface = nullptr;
3128+ mir::protobuf::Buffer* buffer = nullptr;
3129+ mir::protobuf::Platform* platform = nullptr;
3130+
3131+ if (message_type == "mir.protobuf.Buffer")
3132+ {
3133+ buffer = static_cast<mir::protobuf::Buffer*>(response);
3134+ }
3135+ else if (message_type == "mir.protobuf.Surface")
3136+ {
3137+ surface = static_cast<mir::protobuf::Surface*>(response);
3138+ if (surface && surface->has_buffer())
3139+ buffer = surface->mutable_buffer();
3140+ }
3141+ else if (message_type == "mir.protobuf.Screencast")
3142+ {
3143+ auto screencast = static_cast<mir::protobuf::Screencast*>(response);
3144+ if (screencast && screencast->has_buffer())
3145+ buffer = screencast->mutable_buffer();
3146+ }
3147+ else if (message_type == "mir.protobuf.Platform")
3148+ {
3149+ platform = static_cast<mir::protobuf::Platform*>(response);
3150+ }
3151+ else if (message_type == "mir.protobuf.Connection")
3152+ {
3153+ auto connection = static_cast<mir::protobuf::Connection*>(response);
3154+ if (connection && connection->has_platform())
3155+ platform = connection->mutable_platform();
3156+ }
3157+
3158 if (surface)
3159 {
3160 surface->clear_fd();
3161@@ -158,19 +189,6 @@
3162 rpc_report->file_descriptors_received(*response, fds);
3163 }
3164 }
3165- else
3166- {
3167- screencast = dynamic_cast<mir::protobuf::Screencast*>(response);
3168- }
3169-
3170- auto buffer = dynamic_cast<mir::protobuf::Buffer*>(response);
3171- if (!buffer)
3172- {
3173- if (surface && surface->has_buffer())
3174- buffer = surface->mutable_buffer();
3175- else if (screencast && screencast->has_buffer())
3176- buffer = screencast->mutable_buffer();
3177- }
3178
3179 if (buffer)
3180 {
3181@@ -187,14 +205,6 @@
3182 }
3183 }
3184
3185- auto platform = dynamic_cast<mir::protobuf::Platform*>(response);
3186- if (!platform)
3187- {
3188- auto connection = dynamic_cast<mir::protobuf::Connection*>(response);
3189- if (connection && connection->has_platform())
3190- platform = connection->mutable_platform();
3191- }
3192-
3193 if (platform)
3194 {
3195 platform->clear_fd();
3196@@ -266,7 +276,7 @@
3197 google::protobuf::Message* response,
3198 google::protobuf::Closure* complete)
3199 {
3200- mir::protobuf::wire::Invocation invocation = invocation_for(method, parameters);
3201+ auto const& invocation = invocation_for(method, parameters);
3202
3203 rpc_report->invocation_requested(invocation);
3204
3205@@ -345,7 +355,7 @@
3206 {
3207 const size_t body_size = read_message_header();
3208
3209- result = read_message_body(body_size);
3210+ read_message_body(result, body_size);
3211
3212 rpc_report->result_receipt_succeeded(result);
3213 }
3214@@ -431,18 +441,17 @@
3215 return body_size;
3216 }
3217
3218-mir::protobuf::wire::Result mclr::MirSocketRpcChannel::read_message_body(const size_t body_size)
3219+void mclr::MirSocketRpcChannel::read_message_body(
3220+ mir::protobuf::wire::Result& result,
3221+ size_t const body_size)
3222 {
3223 boost::system::error_code error;
3224- boost::asio::streambuf message;
3225- boost::asio::read(socket, message, boost::asio::transfer_exactly(body_size), error);
3226+ body_bytes.resize(body_size);
3227+ boost::asio::read(socket, boost::asio::buffer(body_bytes), error);
3228 if (error)
3229 {
3230 BOOST_THROW_EXCEPTION(std::runtime_error("Failed to read message body: " + error.message()));
3231 }
3232
3233- std::istream in(&message);
3234- mir::protobuf::wire::Result result;
3235- result.ParseFromIstream(&in);
3236- return result;
3237+ result.ParseFromArray(body_bytes.data(), body_size);
3238 }
3239
3240=== modified file 'src/client/rpc/mir_socket_rpc_channel.h'
3241--- src/client/rpc/mir_socket_rpc_channel.h 2014-03-06 06:05:17 +0000
3242+++ src/client/rpc/mir_socket_rpc_channel.h 2014-04-07 13:29:13 +0000
3243@@ -80,6 +80,7 @@
3244
3245 static size_t const size_of_header = 2;
3246 unsigned char header_bytes[size_of_header];
3247+ std::vector<char> body_bytes;
3248
3249 void receive_file_descriptors(google::protobuf::Message* response, google::protobuf::Closure* complete);
3250 void receive_file_descriptors(std::vector<int> &fds);
3251@@ -92,7 +93,8 @@
3252
3253 size_t read_message_header();
3254
3255- mir::protobuf::wire::Result read_message_body(const size_t body_size);
3256+ void read_message_body(mir::protobuf::wire::Result& result,
3257+ size_t const body_size);
3258 void notify_disconnected();
3259
3260 std::shared_ptr<SurfaceMap> surface_map;
3261
3262=== modified file 'src/platform/CMakeLists.txt'
3263--- src/platform/CMakeLists.txt 2014-03-06 06:05:17 +0000
3264+++ src/platform/CMakeLists.txt 2014-04-07 13:29:13 +0000
3265@@ -3,13 +3,14 @@
3266
3267 add_library(
3268 mirplatform SHARED
3269-
3270+ shared_library_loader.cpp
3271 udev_wrapper.cpp
3272 )
3273
3274 target_link_libraries(
3275 mirplatform
3276 mirplatformgraphicscommon
3277+ mirsharedsharedlibrary
3278
3279 ${UDEV_LDFLAGS} ${UDEV_LIBRARIES}
3280 )
3281
3282=== modified file 'src/platform/graphics/android/CMakeLists.txt'
3283--- src/platform/graphics/android/CMakeLists.txt 2014-03-11 13:44:57 +0000
3284+++ src/platform/graphics/android/CMakeLists.txt 2014-04-07 13:29:13 +0000
3285@@ -20,6 +20,7 @@
3286 hwc_layerlist.cpp
3287 hwc_layers.cpp
3288 hwc_fb_device.cpp
3289+ hwc_formatted_logger.cpp
3290 hwc_device.cpp
3291 hwc_common_device.cpp
3292 hwc_vsync.cpp
3293@@ -44,9 +45,12 @@
3294 target_link_libraries(
3295 mirplatformgraphicsandroid
3296
3297+ miroptions
3298 mirplatform
3299 mirsharedandroid
3300+ mirsharedenv
3301
3302+ ${Boost_PROGRAM_OPTIONS_LIBRARY}
3303 ${LIBHARDWARE_LIBRARIES}
3304 ${EGL_LDFLAGS} ${EGL_LIBRARIES}
3305 ${GLESv2_LDFLAGS} ${GLESv2_LIBRARIES}
3306
3307=== modified file 'src/platform/graphics/android/android_display.cpp'
3308--- src/platform/graphics/android/android_display.cpp 2014-03-17 07:35:22 +0000
3309+++ src/platform/graphics/android/android_display.cpp 2014-04-07 13:29:13 +0000
3310@@ -33,9 +33,10 @@
3311 namespace geom=mir::geometry;
3312
3313 mga::AndroidDisplay::AndroidDisplay(std::shared_ptr<mga::DisplayBuilder> const& display_builder,
3314+ std::shared_ptr<GLConfig> const& gl_config,
3315 std::shared_ptr<DisplayReport> const& display_report)
3316 : display_builder{display_builder},
3317- gl_context{display_builder->display_format(), *display_report},
3318+ gl_context{display_builder->display_format(), *gl_config, *display_report},
3319 display_buffer{display_builder->create_display_buffer(gl_context)}
3320 {
3321 display_report->report_successful_setup_of_native_resources();
3322
3323=== modified file 'src/platform/graphics/android/android_display.h'
3324--- src/platform/graphics/android/android_display.h 2014-03-06 06:05:17 +0000
3325+++ src/platform/graphics/android/android_display.h 2014-04-07 13:29:13 +0000
3326@@ -30,6 +30,7 @@
3327 {
3328
3329 class DisplayReport;
3330+class GLConfig;
3331
3332 namespace android
3333 {
3334@@ -41,6 +42,7 @@
3335 {
3336 public:
3337 explicit AndroidDisplay(std::shared_ptr<DisplayBuilder> const& display_builder,
3338+ std::shared_ptr<GLConfig> const& gl_config,
3339 std::shared_ptr<DisplayReport> const& display_report);
3340
3341 void for_each_display_buffer(std::function<void(graphics::DisplayBuffer&)> const& f);
3342
3343=== modified file 'src/platform/graphics/android/android_platform.cpp'
3344--- src/platform/graphics/android/android_platform.cpp 2014-03-06 06:05:17 +0000
3345+++ src/platform/graphics/android/android_platform.cpp 2014-04-07 13:29:13 +0000
3346@@ -31,6 +31,8 @@
3347 #include "mir/graphics/buffer_ipc_packer.h"
3348 #include "mir/graphics/display_report.h"
3349 #include "mir/options/option.h"
3350+#include "mir/options/configuration.h"
3351+#include "mir/abnormal_exit.h"
3352
3353 #include <boost/throw_exception.hpp>
3354 #include <stdexcept>
3355@@ -40,6 +42,26 @@
3356 namespace mf=mir::frontend;
3357 namespace mo = mir::options;
3358
3359+namespace
3360+{
3361+char const* const hwc_log_opt = "hwc-report";
3362+bool should_log_hwc(mo::Option const& options)
3363+{
3364+ if (!options.is_set(hwc_log_opt))
3365+ return false;
3366+
3367+ auto opt = options.get<std::string>(hwc_log_opt);
3368+ if (opt == mo::log_opt_value)
3369+ return true;
3370+ else if (opt == mo::off_opt_value)
3371+ return false;
3372+ else
3373+ throw mir::AbnormalExit(
3374+ std::string("Invalid hwc-report option: " + opt + " (valid options are: \"" +
3375+ mo::off_opt_value + "\" and \"" + mo::log_opt_value + "\")"));
3376+}
3377+}
3378+
3379 mga::AndroidPlatform::AndroidPlatform(
3380 std::shared_ptr<mga::DisplayBuilder> const& display_builder,
3381 std::shared_ptr<mg::DisplayReport> const& display_report)
3382@@ -61,9 +83,11 @@
3383 }
3384
3385 std::shared_ptr<mg::Display> mga::AndroidPlatform::create_display(
3386- std::shared_ptr<graphics::DisplayConfigurationPolicy> const&)
3387+ std::shared_ptr<graphics::DisplayConfigurationPolicy> const&,
3388+ std::shared_ptr<mg::GLConfig> const& gl_config)
3389 {
3390- return std::make_shared<mga::AndroidDisplay>(display_builder, display_report);
3391+ return std::make_shared<mga::AndroidDisplay>(
3392+ display_builder, gl_config, display_report);
3393 }
3394
3395 std::shared_ptr<mg::PlatformIPCPackage> mga::AndroidPlatform::get_ipc_package()
3396@@ -105,10 +129,10 @@
3397 return std::make_shared<mga::InternalClient>();
3398 }
3399
3400-extern "C" std::shared_ptr<mg::Platform> mg::create_platform(std::shared_ptr<mo::Option> const& /*options*/, std::shared_ptr<DisplayReport> const& display_report)
3401+extern "C" std::shared_ptr<mg::Platform> mg::create_platform(std::shared_ptr<mo::Option> const& options, std::shared_ptr<DisplayReport> const& display_report)
3402 {
3403 auto buffer_initializer = std::make_shared<mg::NullBufferInitializer>();
3404- auto display_resource_factory = std::make_shared<mga::ResourceFactory>();
3405+ auto display_resource_factory = std::make_shared<mga::ResourceFactory>(should_log_hwc(*options));
3406 auto fb_allocator = std::make_shared<mga::AndroidGraphicBufferAllocator>(buffer_initializer);
3407 auto display_builder = std::make_shared<mga::OutputBuilder>(
3408 fb_allocator, display_resource_factory, display_report);
3409@@ -121,3 +145,12 @@
3410 // mg::NativePlatform cannot create a display anyways, so it doesnt need a display builder
3411 return std::make_shared<mga::AndroidPlatform>(nullptr, display_report);
3412 }
3413+
3414+extern "C" void add_platform_options(
3415+ boost::program_options::options_description& config)
3416+{
3417+ config.add_options()
3418+ (hwc_log_opt,
3419+ boost::program_options::value<std::string>()->default_value(std::string{mo::off_opt_value}),
3420+ "[platform-specific] How to handle the HWC logging report. [{log,off}]");
3421+}
3422
3423=== modified file 'src/platform/graphics/android/android_platform.h'
3424--- src/platform/graphics/android/android_platform.h 2014-03-06 06:05:17 +0000
3425+++ src/platform/graphics/android/android_platform.h 2014-04-07 13:29:13 +0000
3426@@ -44,7 +44,8 @@
3427 std::shared_ptr<graphics::GraphicBufferAllocator> create_buffer_allocator(
3428 std::shared_ptr<BufferInitializer> const& buffer_initializer);
3429 std::shared_ptr<Display> create_display(
3430- std::shared_ptr<graphics::DisplayConfigurationPolicy> const&);
3431+ std::shared_ptr<graphics::DisplayConfigurationPolicy> const&,
3432+ std::shared_ptr<graphics::GLConfig> const& /*gl_config*/);
3433 std::shared_ptr<PlatformIPCPackage> get_ipc_package();
3434 std::shared_ptr<InternalClient> create_internal_client();
3435 void fill_ipc_package(BufferIPCPacker* packer, graphics::Buffer const* buffer) const;
3436
3437=== modified file 'src/platform/graphics/android/display_buffer.cpp'
3438--- src/platform/graphics/android/display_buffer.cpp 2014-03-11 13:44:57 +0000
3439+++ src/platform/graphics/android/display_buffer.cpp 2014-04-07 13:29:13 +0000
3440@@ -85,7 +85,7 @@
3441 }
3442
3443 void mga::DisplayBuffer::render_and_post_update(
3444- std::list<std::shared_ptr<Renderable>> const& renderlist,
3445+ RenderableList const& renderlist,
3446 std::function<void(Renderable const&)> const& render_fn)
3447 {
3448 if (renderlist.empty())
3449
3450=== modified file 'src/platform/graphics/android/display_buffer.h'
3451--- src/platform/graphics/android/display_buffer.h 2014-03-11 13:44:57 +0000
3452+++ src/platform/graphics/android/display_buffer.h 2014-04-07 13:29:13 +0000
3453@@ -50,7 +50,7 @@
3454 bool can_bypass() const override;
3455
3456 void render_and_post_update(
3457- std::list<std::shared_ptr<Renderable>> const& renderlist,
3458+ RenderableList const& renderlist,
3459 std::function<void(Renderable const&)> const& render_fn);
3460 MirOrientation orientation() const override;
3461
3462
3463=== modified file 'src/platform/graphics/android/display_device.h'
3464--- src/platform/graphics/android/display_device.h 2014-03-11 13:44:57 +0000
3465+++ src/platform/graphics/android/display_device.h 2014-04-07 13:29:13 +0000
3466@@ -44,7 +44,7 @@
3467 virtual void render_gl(SwappingGLContext const& context) = 0;
3468 virtual void render_gl_and_overlays(
3469 SwappingGLContext const& context,
3470- std::list<std::shared_ptr<Renderable>> const& list,
3471+ RenderableList const& list,
3472 std::function<void(Renderable const&)> const& render_fn) = 0;
3473 virtual void post(Buffer const& buffer) = 0;
3474 virtual bool apply_orientation(MirOrientation orientation) const = 0;
3475
3476=== modified file 'src/platform/graphics/android/fb_device.cpp'
3477--- src/platform/graphics/android/fb_device.cpp 2014-03-11 13:44:57 +0000
3478+++ src/platform/graphics/android/fb_device.cpp 2014-04-07 13:29:13 +0000
3479@@ -51,7 +51,7 @@
3480
3481 void mga::FBDevice::render_gl_and_overlays(
3482 SwappingGLContext const& context,
3483- std::list<std::shared_ptr<Renderable>> const& renderables,
3484+ RenderableList const& renderables,
3485 std::function<void(Renderable const&)> const& render_fn)
3486 {
3487 for(auto const& renderable : renderables)
3488
3489=== modified file 'src/platform/graphics/android/fb_device.h'
3490--- src/platform/graphics/android/fb_device.h 2014-03-11 13:44:57 +0000
3491+++ src/platform/graphics/android/fb_device.h 2014-04-07 13:29:13 +0000
3492@@ -40,7 +40,7 @@
3493 virtual void render_gl(SwappingGLContext const& context);
3494 virtual void render_gl_and_overlays(
3495 SwappingGLContext const& context,
3496- std::list<std::shared_ptr<Renderable>> const& list,
3497+ RenderableList const& list,
3498 std::function<void(Renderable const&)> const& render_fn);
3499 void post(Buffer const& buffer);
3500
3501
3502=== modified file 'src/platform/graphics/android/gl_context.cpp'
3503--- src/platform/graphics/android/gl_context.cpp 2014-03-12 02:46:58 +0000
3504+++ src/platform/graphics/android/gl_context.cpp 2014-04-07 13:29:13 +0000
3505@@ -19,6 +19,7 @@
3506 #include "gl_context.h"
3507 #include "android_format_conversion-inl.h"
3508 #include "mir/graphics/display_report.h"
3509+#include "mir/graphics/gl_config.h"
3510
3511 #include <algorithm>
3512 #include <boost/throw_exception.hpp>
3513@@ -31,13 +32,6 @@
3514 namespace
3515 {
3516
3517-static EGLint const required_egl_config_attr [] =
3518-{
3519- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
3520- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
3521- EGL_NONE
3522-};
3523-
3524 static EGLint const default_egl_context_attr[] =
3525 {
3526 EGL_CONTEXT_CLIENT_VERSION, 2,
3527@@ -69,8 +63,19 @@
3528
3529 /* the minimum requirement is to have EGL_WINDOW_BIT and EGL_OPENGL_ES2_BIT, and to select a config
3530 whose pixel format matches that of the framebuffer. */
3531-static EGLConfig select_egl_config_with_format(EGLDisplay egl_display, MirPixelFormat display_format)
3532+EGLConfig select_egl_config_with_format(
3533+ EGLDisplay egl_display, MirPixelFormat display_format,
3534+ mg::GLConfig const& gl_config)
3535 {
3536+ EGLint const required_egl_config_attr [] =
3537+ {
3538+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
3539+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
3540+ EGL_DEPTH_SIZE, gl_config.depth_buffer_bits(),
3541+ EGL_STENCIL_SIZE, gl_config.stencil_buffer_bits(),
3542+ EGL_NONE
3543+ };
3544+
3545 int required_visual_id = mga::to_android_format(display_format);
3546 int num_potential_configs;
3547 EGLint num_match_configs;
3548@@ -107,10 +112,12 @@
3549 return eglCreateWindowSurface(disp, config, native, NULL);
3550 }
3551
3552-mga::GLContext::GLContext(MirPixelFormat display_format, mg::DisplayReport& report)
3553+mga::GLContext::GLContext(MirPixelFormat display_format,
3554+ mg::GLConfig const& gl_config,
3555+ mg::DisplayReport& report)
3556 : egl_display(create_and_initialize_display()),
3557 own_display(true),
3558- egl_config(select_egl_config_with_format(egl_display, display_format)),
3559+ egl_config(select_egl_config_with_format(egl_display, display_format, gl_config)),
3560 egl_context{egl_display,
3561 eglCreateContext(egl_display, egl_config, EGL_NO_CONTEXT, default_egl_context_attr)},
3562 egl_surface{egl_display,
3563
3564=== modified file 'src/platform/graphics/android/gl_context.h'
3565--- src/platform/graphics/android/gl_context.h 2014-03-12 02:46:58 +0000
3566+++ src/platform/graphics/android/gl_context.h 2014-04-07 13:29:13 +0000
3567@@ -29,6 +29,7 @@
3568 namespace graphics
3569 {
3570 class DisplayReport;
3571+class GLConfig;
3572 namespace android
3573 {
3574
3575@@ -53,7 +54,9 @@
3576 {
3577 public:
3578 //For creating a gl context
3579- GLContext(MirPixelFormat display_format, DisplayReport& report);
3580+ GLContext(MirPixelFormat display_format,
3581+ GLConfig const& gl_config,
3582+ DisplayReport& report);
3583
3584 //For creating a gl context shared with another GLContext
3585 GLContext(GLContext const& shared_gl_context,
3586
3587=== modified file 'src/platform/graphics/android/hwc_common_device.cpp'
3588--- src/platform/graphics/android/hwc_common_device.cpp 2014-03-11 13:44:57 +0000
3589+++ src/platform/graphics/android/hwc_common_device.cpp 2014-04-07 13:29:13 +0000
3590@@ -44,8 +44,8 @@
3591
3592 mga::HWCCommonDevice::HWCCommonDevice(std::shared_ptr<hwc_composer_device_1> const& hwc_device,
3593 std::shared_ptr<mga::HWCVsyncCoordinator> const& coordinator)
3594- : hwc_device(hwc_device),
3595- coordinator(coordinator),
3596+ : coordinator(coordinator),
3597+ hwc_device(hwc_device),
3598 current_mode(mir_power_mode_on)
3599 {
3600 callbacks.hooks.invalidate = invalidate_hook;
3601
3602=== modified file 'src/platform/graphics/android/hwc_common_device.h'
3603--- src/platform/graphics/android/hwc_common_device.h 2014-03-06 06:05:17 +0000
3604+++ src/platform/graphics/android/hwc_common_device.h 2014-04-07 13:29:13 +0000
3605@@ -54,7 +54,6 @@
3606 HWCCommonDevice(std::shared_ptr<hwc_composer_device_1> const& hwc_device,
3607 std::shared_ptr<HWCVsyncCoordinator> const& coordinator);
3608
3609- std::shared_ptr<hwc_composer_device_1> const hwc_device;
3610 std::shared_ptr<HWCVsyncCoordinator> const coordinator;
3611 std::unique_lock<std::mutex> lock_unblanked();
3612
3613@@ -64,6 +63,8 @@
3614
3615 HWCCallbacks callbacks;
3616
3617+ std::shared_ptr<hwc_composer_device_1> const hwc_device;
3618+
3619 std::mutex blanked_mutex;
3620 std::condition_variable blanked_cond;
3621 MirPowerMode current_mode;
3622
3623=== modified file 'src/platform/graphics/android/hwc_device.cpp'
3624--- src/platform/graphics/android/hwc_device.cpp 2014-03-11 13:44:57 +0000
3625+++ src/platform/graphics/android/hwc_device.cpp 2014-04-07 13:29:13 +0000
3626@@ -21,6 +21,7 @@
3627 #include "hwc_device.h"
3628 #include "hwc_layerlist.h"
3629 #include "hwc_vsync_coordinator.h"
3630+#include "hwc_wrapper.h"
3631 #include "framebuffer_bundle.h"
3632 #include "buffer.h"
3633 #include "mir/graphics/buffer.h"
3634@@ -89,7 +90,7 @@
3635
3636 void mga::HwcDevice::render_gl_and_overlays(
3637 SwappingGLContext const& context,
3638- std::list<std::shared_ptr<Renderable>> const& renderables,
3639+ RenderableList const& renderables,
3640 std::function<void(Renderable const&)> const& render_fn)
3641 {
3642 if (!(list_needs_commit = hwc_list.update_list_and_check_if_changed(renderables, fbtarget_size)))
3643
3644=== modified file 'src/platform/graphics/android/hwc_device.h'
3645--- src/platform/graphics/android/hwc_device.h 2014-03-11 13:44:57 +0000
3646+++ src/platform/graphics/android/hwc_device.h 2014-04-07 13:29:13 +0000
3647@@ -35,20 +35,7 @@
3648 {
3649 class HWCVsyncCoordinator;
3650 class SyncFileOps;
3651-
3652-class HwcWrapper
3653-{
3654-public:
3655- virtual ~HwcWrapper() = default;
3656-
3657- virtual void prepare(hwc_display_contents_1_t&) const = 0;
3658- virtual void set(hwc_display_contents_1_t&) const = 0;
3659-
3660-protected:
3661- HwcWrapper() = default;
3662- HwcWrapper& operator=(HwcWrapper const&) = delete;
3663- HwcWrapper(HwcWrapper const&) = delete;
3664-};
3665+class HwcWrapper;
3666
3667 class HwcDevice : public HWCCommonDevice
3668 {
3669@@ -63,7 +50,7 @@
3670 virtual void render_gl(SwappingGLContext const& context);
3671 virtual void render_gl_and_overlays(
3672 SwappingGLContext const& context,
3673- std::list<std::shared_ptr<Renderable>> const& list,
3674+ RenderableList const& list,
3675 std::function<void(Renderable const&)> const& render_fn);
3676 void post(Buffer const& buffer);
3677
3678
3679=== modified file 'src/platform/graphics/android/hwc_fb_device.cpp'
3680--- src/platform/graphics/android/hwc_fb_device.cpp 2014-03-11 13:44:57 +0000
3681+++ src/platform/graphics/android/hwc_fb_device.cpp 2014-04-07 13:29:13 +0000
3682@@ -21,6 +21,7 @@
3683 #include "hwc_vsync_coordinator.h"
3684 #include "framebuffer_bundle.h"
3685 #include "android_format_conversion-inl.h"
3686+#include "hwc_wrapper.h"
3687 #include "mir/graphics/buffer.h"
3688 #include "mir/graphics/android/native_buffer.h"
3689
3690@@ -33,9 +34,11 @@
3691 namespace geom = mir::geometry;
3692
3693 mga::HwcFbDevice::HwcFbDevice(std::shared_ptr<hwc_composer_device_1> const& hwc_device,
3694+ std::shared_ptr<HwcWrapper> const& hwc_wrapper,
3695 std::shared_ptr<framebuffer_device_t> const& fb_device,
3696 std::shared_ptr<HWCVsyncCoordinator> const& coordinator)
3697 : HWCCommonDevice(hwc_device, coordinator),
3698+ hwc_wrapper(hwc_wrapper),
3699 fb_device(fb_device),
3700 layer_list{{},1}
3701 {
3702@@ -44,41 +47,33 @@
3703
3704 void mga::HwcFbDevice::gpu_render()
3705 {
3706- auto rc = 0;
3707- auto display_list = layer_list.native_list().lock();
3708- if (display_list)
3709+ if (auto display_list = layer_list.native_list().lock())
3710 {
3711 display_list->dpy = eglGetCurrentDisplay();
3712 display_list->sur = eglGetCurrentSurface(EGL_DRAW);
3713
3714 //set() may affect EGL state by calling eglSwapBuffers.
3715 //HWC 1.0 is the only version of HWC that can do this.
3716- hwc_display_contents_1_t* displays[num_displays] {display_list.get()};
3717- rc = hwc_device->set(hwc_device.get(), num_displays, displays);
3718+ hwc_wrapper->set(*display_list);
3719 }
3720-
3721- if ((rc != 0) || (!display_list))
3722+ else
3723 {
3724 std::stringstream ss;
3725- ss << "error during hwc set(). rc = " << std::hex << rc;
3726+ ss << "error locking list during hwc set()";
3727 BOOST_THROW_EXCEPTION(std::runtime_error(ss.str()));
3728 }
3729 }
3730
3731 void mga::HwcFbDevice::prepare()
3732 {
3733- auto rc = 0;
3734- auto display_list = layer_list.native_list().lock();
3735- if (display_list)
3736+ if (auto display_list = layer_list.native_list().lock())
3737 {
3738- hwc_display_contents_1_t* displays[num_displays] {display_list.get()};
3739- rc = hwc_device->prepare(hwc_device.get(), num_displays, displays);
3740+ hwc_wrapper->prepare(*display_list);
3741 }
3742-
3743- if ((rc != 0) || (!display_list))
3744+ else
3745 {
3746 std::stringstream ss;
3747- ss << "error during hwc prepare(). rc = " << std::hex << rc;
3748+ ss << "error accessing list during hwc prepare()";
3749 BOOST_THROW_EXCEPTION(std::runtime_error(ss.str()));
3750 }
3751 }
3752@@ -91,7 +86,7 @@
3753
3754 void mga::HwcFbDevice::render_gl_and_overlays(
3755 SwappingGLContext const&,
3756- std::list<std::shared_ptr<Renderable>> const& renderables,
3757+ RenderableList const& renderables,
3758 std::function<void(Renderable const&)> const& render_fn)
3759 {
3760 prepare();
3761
3762=== modified file 'src/platform/graphics/android/hwc_fb_device.h'
3763--- src/platform/graphics/android/hwc_fb_device.h 2014-03-11 13:44:57 +0000
3764+++ src/platform/graphics/android/hwc_fb_device.h 2014-04-07 13:29:13 +0000
3765@@ -30,24 +30,28 @@
3766 {
3767 namespace android
3768 {
3769+class HwcWrapper;
3770
3771 class HwcFbDevice : public HWCCommonDevice
3772 {
3773 public:
3774 HwcFbDevice(std::shared_ptr<hwc_composer_device_1> const& hwc_device,
3775+ std::shared_ptr<HwcWrapper> const& hwc_wrapper,
3776 std::shared_ptr<framebuffer_device_t> const& fb_device,
3777 std::shared_ptr<HWCVsyncCoordinator> const& coordinator);
3778
3779 virtual void render_gl(SwappingGLContext const& context);
3780 virtual void render_gl_and_overlays(
3781 SwappingGLContext const& context,
3782- std::list<std::shared_ptr<Renderable>> const& list,
3783+ RenderableList const& list,
3784 std::function<void(Renderable const&)> const& render_fn);
3785 void post(Buffer const& buffer);
3786
3787 private:
3788 void prepare();
3789 void gpu_render();
3790+
3791+ std::shared_ptr<HwcWrapper> const hwc_wrapper;
3792 std::shared_ptr<framebuffer_device_t> const fb_device;
3793 static int const num_displays{1};
3794 LayerList layer_list;
3795
3796=== added file 'src/platform/graphics/android/hwc_formatted_logger.cpp'
3797--- src/platform/graphics/android/hwc_formatted_logger.cpp 1970-01-01 00:00:00 +0000
3798+++ src/platform/graphics/android/hwc_formatted_logger.cpp 2014-04-07 13:29:13 +0000
3799@@ -0,0 +1,177 @@
3800+/*
3801+ * Copyright © 2014 Canonical Ltd.
3802+ *
3803+ * This program is free software: you can redistribute it and/or modify it
3804+ * under the terms of the GNU Lesser General Public License version 3,
3805+ * as published by the Free Software Foundation.
3806+ *
3807+ * This program is distributed in the hope that it will be useful,
3808+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3809+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3810+ * GNU Lesser General Public License for more details.
3811+ *
3812+ * You should have received a copy of the GNU Lesser General Public License
3813+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3814+ *
3815+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
3816+ */
3817+
3818+#include "hwc_formatted_logger.h"
3819+#include <iostream>
3820+#include <iomanip>
3821+
3822+namespace mga=mir::graphics::android;
3823+
3824+namespace
3825+{
3826+std::string const separator{" | "};
3827+int const layer_num_column_size{2};
3828+int const blending_column_size{8};
3829+int const rotation_column_size{9};
3830+int const rect_entry_column_size{4};
3831+int const type_column_size{9};
3832+
3833+class StreamFormatter
3834+{
3835+public:
3836+ StreamFormatter(std::ostream& str, unsigned int const width, std::ios_base::fmtflags flags)
3837+ : stream(str),
3838+ old_width(stream.width(width)),
3839+ old_flags(stream.setf(flags,std::ios::adjustfield))
3840+ {
3841+ }
3842+
3843+ ~StreamFormatter()
3844+ {
3845+ stream.setf(old_flags, std::ios::adjustfield);
3846+ stream.width(old_width);
3847+ }
3848+private:
3849+ std::ostream& stream;
3850+ unsigned int const old_width;
3851+ std::ios_base::fmtflags const old_flags;
3852+};
3853+
3854+struct LayerNumber{ unsigned int const num; };
3855+std::ostream& operator<<(std::ostream& str, LayerNumber l)
3856+{
3857+ StreamFormatter stream_format(str, layer_num_column_size, std::ios_base::right);
3858+ return str << l.num % 100;
3859+}
3860+
3861+struct HwcRotation{ unsigned int const key; };
3862+std::ostream& operator<<(std::ostream& str, HwcRotation rotation_key)
3863+{
3864+ StreamFormatter stream_format(str, rotation_column_size, std::ios_base::left);
3865+ switch(rotation_key.key)
3866+ {
3867+ case 0:
3868+ return str << std::string{"NONE"};
3869+ case HWC_TRANSFORM_ROT_90:
3870+ return str << std::string{"ROT_90"};
3871+ case HWC_TRANSFORM_ROT_180:
3872+ return str << std::string{"ROT_180"};
3873+ case HWC_TRANSFORM_ROT_270:
3874+ return str << std::string{"ROT_270"};
3875+ default:
3876+ return str << std::string{"UNKNOWN"};
3877+ }
3878+}
3879+
3880+struct HwcBlending{ int const key; };
3881+std::ostream& operator<<(std::ostream& str, HwcBlending blending_key)
3882+{
3883+ StreamFormatter stream_format(str, blending_column_size, std::ios_base::left);
3884+ switch(blending_key.key)
3885+ {
3886+ case HWC_BLENDING_NONE:
3887+ return str << std::string{"NONE"};
3888+ case HWC_BLENDING_PREMULT:
3889+ return str << std::string{"PREMULT"};
3890+ case HWC_BLENDING_COVERAGE:
3891+ return str << std::string{"COVERAGE"};
3892+ default:
3893+ return str << std::string{"UNKNOWN"};
3894+ }
3895+}
3896+
3897+struct HwcType{ int const type; unsigned int const flags; };
3898+std::ostream& operator<<(std::ostream& str, HwcType type)
3899+{
3900+ StreamFormatter stream_format(str, type_column_size, std::ios_base::left);
3901+ switch(type.type)
3902+ {
3903+ case HWC_OVERLAY:
3904+ return str << std::string{"OVERLAY"};
3905+ case HWC_FRAMEBUFFER:
3906+ if (type.flags == HWC_SKIP_LAYER)
3907+ return str << std::string{"FORCE_GL"};
3908+ else
3909+ return str << std::string{"GL_RENDER"};
3910+ case HWC_FRAMEBUFFER_TARGET:
3911+ return str << std::string{"FB_TARGET"};
3912+ default:
3913+ return str << std::string{"UNKNOWN"};
3914+ }
3915+}
3916+
3917+struct HwcRectMember { int member; };
3918+std::ostream& operator<<(std::ostream& str, HwcRectMember rect)
3919+{
3920+ StreamFormatter stream_format(str, rect_entry_column_size, std::ios_base::right);
3921+ return str << rect.member;
3922+}
3923+
3924+struct HwcRect { hwc_rect_t const& rect; };
3925+std::ostream& operator<<(std::ostream& str, HwcRect r)
3926+{
3927+ return str << "{"
3928+ << HwcRectMember{r.rect.left} << ","
3929+ << HwcRectMember{r.rect.top} << ","
3930+ << HwcRectMember{r.rect.right} << ","
3931+ << HwcRectMember{r.rect.bottom} << "}";
3932+}
3933+}
3934+
3935+void mga::HwcFormattedLogger::log_list_submitted_to_prepare(hwc_display_contents_1_t const& list) const
3936+{
3937+ std::cout << "before prepare():" << std::endl
3938+ << " # | pos {l,t,r,b} | crop {l,t,r,b} | transform | blending | "
3939+ << std::endl;
3940+ for(auto i = 0u; i < list.numHwLayers; i++)
3941+ std::cout << LayerNumber{i}
3942+ << separator
3943+ << HwcRect{list.hwLayers[i].displayFrame}
3944+ << separator
3945+ << HwcRect{list.hwLayers[i].sourceCrop}
3946+ << separator
3947+ << HwcRotation{list.hwLayers[i].transform}
3948+ << separator
3949+ << HwcBlending{list.hwLayers[i].blending}
3950+ << separator
3951+ << std::endl;
3952+}
3953+
3954+void mga::HwcFormattedLogger::log_prepare_done(hwc_display_contents_1_t const& list) const
3955+{
3956+ std::cout << "after prepare():" << std::endl
3957+ << " # | Type | " << std::endl;
3958+ for(auto i = 0u; i < list.numHwLayers; i++)
3959+ std::cout << LayerNumber{i}
3960+ << separator
3961+ << HwcType{list.hwLayers[i].compositionType,list.hwLayers[i].flags}
3962+ << separator
3963+ << std::endl;
3964+}
3965+
3966+void mga::HwcFormattedLogger::log_set_list(hwc_display_contents_1_t const& list) const
3967+{
3968+ std::cout << "set list():" << std::endl
3969+ << " # | handle" << std::endl;
3970+
3971+ for(auto i = 0u; i < list.numHwLayers; i++)
3972+ std::cout << LayerNumber{i}
3973+ << separator
3974+ << list.hwLayers[i].handle
3975+ << std::endl;
3976+}
3977
3978=== added file 'src/platform/graphics/android/hwc_formatted_logger.h'
3979--- src/platform/graphics/android/hwc_formatted_logger.h 1970-01-01 00:00:00 +0000
3980+++ src/platform/graphics/android/hwc_formatted_logger.h 2014-04-07 13:29:13 +0000
3981@@ -0,0 +1,41 @@
3982+/*
3983+ * Copyright © 2014 Canonical Ltd.
3984+ *
3985+ * This program is free software: you can redistribute it and/or modify it
3986+ * under the terms of the GNU Lesser General Public License version 3,
3987+ * as published by the Free Software Foundation.
3988+ *
3989+ * This program is distributed in the hope that it will be useful,
3990+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3991+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3992+ * GNU Lesser General Public License for more details.
3993+ *
3994+ * You should have received a copy of the GNU Lesser General Public License
3995+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3996+ *
3997+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
3998+ */
3999+
4000+#ifndef MIR_GRAPHICS_ANDROID_HWC_FORMATTED_LOGGER_H_
4001+#define MIR_GRAPHICS_ANDROID_HWC_FORMATTED_LOGGER_H_
4002+
4003+#include "hwc_logger.h"
4004+
4005+namespace mir
4006+{
4007+namespace graphics
4008+{
4009+namespace android
4010+{
4011+class HwcFormattedLogger : public HwcLogger
4012+{
4013+public:
4014+ HwcFormattedLogger() = default;
4015+ void log_list_submitted_to_prepare(hwc_display_contents_1_t const& list) const override;
4016+ void log_prepare_done(hwc_display_contents_1_t const& list) const override;
4017+ void log_set_list(hwc_display_contents_1_t const& list) const override;
4018+};
4019+}
4020+}
4021+}
4022+#endif /* MIR_GRAPHICS_ANDROID_HWC_FORMATTED_LOGGER_H_ */
4023
4024=== modified file 'src/platform/graphics/android/hwc_layerlist.cpp'
4025--- src/platform/graphics/android/hwc_layerlist.cpp 2014-03-17 07:35:22 +0000
4026+++ src/platform/graphics/android/hwc_layerlist.cpp 2014-04-07 13:29:13 +0000
4027@@ -52,7 +52,7 @@
4028 }
4029
4030 bool mga::LayerList::update_list_and_check_if_changed(
4031- std::list<std::shared_ptr<mg::Renderable>> const& renderlist,
4032+ RenderableList const& renderlist,
4033 size_t additional_layers)
4034 {
4035 size_t needed_size = renderlist.size() + additional_layers;
4036@@ -70,7 +70,7 @@
4037 {
4038 layers_it->set_render_parameters(
4039 renderable->screen_position(), renderable->alpha_enabled());
4040- layers_it->set_buffer(*renderable->buffer(1));// TODO: remove needing to know about frameno
4041+ layers_it->set_buffer(*renderable->buffer(this));
4042 any_buffer_updated |= layers_it->needs_hwc_commit();
4043 layers_it++;
4044 }
4045@@ -88,7 +88,7 @@
4046 renderable->screen_position(),
4047 renderable->alpha_enabled(),
4048 hwc_representation, i++));
4049- new_layers.back().set_buffer(*renderable->buffer(1));// TODO: remove needing to know about frameno
4050+ new_layers.back().set_buffer(*renderable->buffer(this));
4051 }
4052
4053 for(; i < needed_size; i++)
4054@@ -137,7 +137,7 @@
4055 }
4056
4057 mga::LayerList::LayerList(
4058- std::list<std::shared_ptr<mg::Renderable>> const& renderlist,
4059+ RenderableList const& renderlist,
4060 size_t additional_layers)
4061 {
4062 update_list_and_check_if_changed(renderlist, additional_layers);
4063
4064=== modified file 'src/platform/graphics/android/hwc_layerlist.h'
4065--- src/platform/graphics/android/hwc_layerlist.h 2014-03-11 13:44:57 +0000
4066+++ src/platform/graphics/android/hwc_layerlist.h 2014-04-07 13:29:13 +0000
4067@@ -48,9 +48,9 @@
4068 class LayerList
4069 {
4070 public:
4071- LayerList(std::list<std::shared_ptr<Renderable>> const& renderlist, size_t additional_layers);
4072+ LayerList(RenderableList const& renderlist, size_t additional_layers);
4073 bool update_list_and_check_if_changed(
4074- std::list<std::shared_ptr<Renderable>> const& renderlist,
4075+ RenderableList const& renderlist,
4076 size_t additional_layers);
4077
4078 std::list<HWCLayer>::iterator begin();
4079
4080=== added file 'src/platform/graphics/android/hwc_logger.h'
4081--- src/platform/graphics/android/hwc_logger.h 1970-01-01 00:00:00 +0000
4082+++ src/platform/graphics/android/hwc_logger.h 2014-04-07 13:29:13 +0000
4083@@ -0,0 +1,46 @@
4084+/*
4085+ * Copyright © 2014 Canonical Ltd.
4086+ *
4087+ * This program is free software: you can redistribute it and/or modify it
4088+ * under the terms of the GNU Lesser General Public License version 3,
4089+ * as published by the Free Software Foundation.
4090+ *
4091+ * This program is distributed in the hope that it will be useful,
4092+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4093+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4094+ * GNU Lesser General Public License for more details.
4095+ *
4096+ * You should have received a copy of the GNU Lesser General Public License
4097+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4098+ *
4099+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
4100+ */
4101+
4102+#ifndef MIR_GRAPHICS_ANDROID_HWC_LOGGER_H_
4103+#define MIR_GRAPHICS_ANDROID_HWC_LOGGER_H_
4104+
4105+#include <hardware/hwcomposer.h>
4106+
4107+namespace mir
4108+{
4109+namespace graphics
4110+{
4111+namespace android
4112+{
4113+class HwcLogger
4114+{
4115+public:
4116+ virtual ~HwcLogger() = default;
4117+
4118+ virtual void log_list_submitted_to_prepare(hwc_display_contents_1_t const& list) const = 0;
4119+ virtual void log_prepare_done(hwc_display_contents_1_t const& list) const = 0;
4120+ virtual void log_set_list(hwc_display_contents_1_t const& list) const = 0;
4121+protected:
4122+ HwcLogger() = default;
4123+ HwcLogger& operator=(HwcLogger const&) = delete;
4124+ HwcLogger(HwcLogger const&) = delete;
4125+};
4126+}
4127+}
4128+}
4129+#endif /* MIR_GRAPHICS_ANDROID_HWC_LOGGER_H_ */
4130
4131=== added file 'src/platform/graphics/android/hwc_wrapper.h'
4132--- src/platform/graphics/android/hwc_wrapper.h 1970-01-01 00:00:00 +0000
4133+++ src/platform/graphics/android/hwc_wrapper.h 2014-04-07 13:29:13 +0000
4134@@ -0,0 +1,47 @@
4135+/*
4136+ * Copyright © 2014 Canonical Ltd.
4137+ *
4138+ * This program is free software: you can redistribute it and/or modify it
4139+ * under the terms of the GNU Lesser General Public License version 3,
4140+ * as published by the Free Software Foundation.
4141+ *
4142+ * This program is distributed in the hope that it will be useful,
4143+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4144+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4145+ * GNU Lesser General Public License for more details.
4146+ *
4147+ * You should have received a copy of the GNU Lesser General Public License
4148+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4149+ *
4150+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
4151+ */
4152+
4153+#ifndef MIR_GRAPHICS_ANDROID_HWC_WRAPPER_H_
4154+#define MIR_GRAPHICS_ANDROID_HWC_WRAPPER_H_
4155+
4156+#include <hardware/hwcomposer.h>
4157+
4158+namespace mir
4159+{
4160+namespace graphics
4161+{
4162+namespace android
4163+{
4164+class HwcWrapper
4165+{
4166+public:
4167+ virtual ~HwcWrapper() = default;
4168+
4169+ virtual void prepare(hwc_display_contents_1_t&) const = 0;
4170+ virtual void set(hwc_display_contents_1_t&) const = 0;
4171+
4172+protected:
4173+ HwcWrapper() = default;
4174+ HwcWrapper& operator=(HwcWrapper const&) = delete;
4175+ HwcWrapper(HwcWrapper const&) = delete;
4176+};
4177+}
4178+}
4179+}
4180+
4181+#endif /* MIR_GRAPHICS_ANDROID_HWC_WRAPPER_H_ */
4182
4183=== modified file 'src/platform/graphics/android/real_hwc_wrapper.cpp'
4184--- src/platform/graphics/android/real_hwc_wrapper.cpp 2014-02-26 22:22:15 +0000
4185+++ src/platform/graphics/android/real_hwc_wrapper.cpp 2014-04-07 13:29:13 +0000
4186@@ -17,14 +17,18 @@
4187 */
4188
4189 #include "real_hwc_wrapper.h"
4190+#include "hwc_logger.h"
4191 #include <boost/throw_exception.hpp>
4192 #include <stdexcept>
4193 #include <sstream>
4194
4195 namespace mga=mir::graphics::android;
4196
4197-mga::RealHwcWrapper::RealHwcWrapper(std::shared_ptr<hwc_composer_device_1> const& hwc_device)
4198- : hwc_device(hwc_device)
4199+mga::RealHwcWrapper::RealHwcWrapper(
4200+ std::shared_ptr<hwc_composer_device_1> const& hwc_device,
4201+ std::shared_ptr<mga::HwcLogger> const& logger)
4202+ : hwc_device(hwc_device),
4203+ logger(logger)
4204 {
4205 }
4206
4207@@ -33,17 +37,22 @@
4208 //note, although we only have a primary display right now,
4209 // set the external and virtual displays to null as some drivers check for that
4210 hwc_display_contents_1_t* displays[num_displays] {&display_list, nullptr, nullptr};
4211+
4212+ logger->log_list_submitted_to_prepare(display_list);
4213 if (auto rc = hwc_device->prepare(hwc_device.get(), 1, displays))
4214 {
4215 std::stringstream ss;
4216 ss << "error during hwc prepare(). rc = " << std::hex << rc;
4217 BOOST_THROW_EXCEPTION(std::runtime_error(ss.str()));
4218 }
4219+ logger->log_prepare_done(display_list);
4220 }
4221
4222 void mga::RealHwcWrapper::set(hwc_display_contents_1_t& display_list) const
4223 {
4224 hwc_display_contents_1_t* displays[num_displays] {&display_list, nullptr, nullptr};
4225+
4226+ logger->log_set_list(display_list);
4227 if (auto rc = hwc_device->set(hwc_device.get(), 1, displays))
4228 {
4229 std::stringstream ss;
4230
4231=== modified file 'src/platform/graphics/android/real_hwc_wrapper.h'
4232--- src/platform/graphics/android/real_hwc_wrapper.h 2014-02-20 22:20:34 +0000
4233+++ src/platform/graphics/android/real_hwc_wrapper.h 2014-04-07 13:29:13 +0000
4234@@ -19,7 +19,7 @@
4235 #ifndef MIR_GRAPHICS_ANDROID_REAL_HWC_WRAPPER_H_
4236 #define MIR_GRAPHICS_ANDROID_REAL_HWC_WRAPPER_H_
4237
4238-#include "hwc_device.h"
4239+#include "hwc_wrapper.h"
4240 #include <memory>
4241 #include <hardware/hwcomposer.h>
4242
4243@@ -29,17 +29,20 @@
4244 {
4245 namespace android
4246 {
4247-
4248+class HwcLogger;
4249 class RealHwcWrapper : public HwcWrapper
4250 {
4251 public:
4252- RealHwcWrapper(std::shared_ptr<hwc_composer_device_1> const& hwc_device);
4253+ RealHwcWrapper(
4254+ std::shared_ptr<hwc_composer_device_1> const& hwc_device,
4255+ std::shared_ptr<HwcLogger> const& logger);
4256
4257 void prepare(hwc_display_contents_1_t&) const override;
4258 void set(hwc_display_contents_1_t&) const override;
4259 private:
4260 static size_t const num_displays{3}; //primary, external, virtual
4261 std::shared_ptr<hwc_composer_device_1> const hwc_device;
4262+ std::shared_ptr<HwcLogger> const logger;
4263 };
4264
4265 }
4266
4267=== modified file 'src/platform/graphics/android/resource_factory.cpp'
4268--- src/platform/graphics/android/resource_factory.cpp 2014-03-11 13:44:57 +0000
4269+++ src/platform/graphics/android/resource_factory.cpp 2014-04-07 13:29:13 +0000
4270@@ -31,6 +31,7 @@
4271 #include "hwc_vsync.h"
4272 #include "android_display.h"
4273 #include "real_hwc_wrapper.h"
4274+#include "hwc_formatted_logger.h"
4275
4276 #include <boost/throw_exception.hpp>
4277 #include <stdexcept>
4278@@ -39,6 +40,11 @@
4279 namespace mg = mir::graphics;
4280 namespace mga=mir::graphics::android;
4281
4282+mga::ResourceFactory::ResourceFactory(bool should_log_hwc)
4283+ : should_log_hwc{should_log_hwc}
4284+{
4285+}
4286+
4287 std::shared_ptr<framebuffer_device_t> mga::ResourceFactory::create_fb_native_device() const
4288 {
4289 hw_module_t const* module;
4290@@ -89,12 +95,37 @@
4291 return std::make_shared<mga::FBDevice>(fb_native_device);
4292 }
4293
4294+namespace
4295+{
4296+struct NullHwcLogger : public mga::HwcLogger
4297+{
4298+ void log_list_submitted_to_prepare(hwc_display_contents_1_t const&) const override
4299+ {
4300+ }
4301+ void log_prepare_done(hwc_display_contents_1_t const&) const override
4302+ {
4303+ }
4304+ void log_set_list(hwc_display_contents_1_t const&) const override
4305+ {
4306+ }
4307+};
4308+
4309+std::shared_ptr<mga::HwcLogger> make_logger(bool should_log)
4310+{
4311+ if (should_log)
4312+ return std::make_shared<mga::HwcFormattedLogger>();
4313+ else
4314+ return std::make_shared<NullHwcLogger>();
4315+}
4316+
4317+}
4318+
4319 std::shared_ptr<mga::DisplayDevice> mga::ResourceFactory::create_hwc_device(
4320 std::shared_ptr<hwc_composer_device_1> const& hwc_native_device) const
4321 {
4322 auto syncer = std::make_shared<mga::HWCVsync>();
4323 auto file_ops = std::make_shared<mga::RealSyncFileOps>();
4324- auto wrapper = std::make_shared<mga::RealHwcWrapper>(hwc_native_device);
4325+ auto wrapper = std::make_shared<mga::RealHwcWrapper>(hwc_native_device, make_logger(should_log_hwc));
4326 return std::make_shared<mga::HwcDevice>(hwc_native_device, wrapper, syncer, file_ops);
4327 }
4328
4329@@ -103,5 +134,7 @@
4330 std::shared_ptr<framebuffer_device_t> const& fb_native_device) const
4331 {
4332 auto syncer = std::make_shared<mga::HWCVsync>();
4333- return std::make_shared<mga::HwcFbDevice>(hwc_native_device, fb_native_device, syncer);
4334+ auto logger = std::make_shared<NullHwcLogger>();
4335+ auto wrapper = std::make_shared<mga::RealHwcWrapper>(hwc_native_device, make_logger(should_log_hwc));
4336+ return std::make_shared<mga::HwcFbDevice>(hwc_native_device, wrapper, fb_native_device, syncer);
4337 }
4338
4339=== modified file 'src/platform/graphics/android/resource_factory.h'
4340--- src/platform/graphics/android/resource_factory.h 2014-03-06 06:05:17 +0000
4341+++ src/platform/graphics/android/resource_factory.h 2014-04-07 13:29:13 +0000
4342@@ -31,6 +31,8 @@
4343 class ResourceFactory : public DisplayResourceFactory
4344 {
4345 public:
4346+ ResourceFactory(bool should_log_hwc);
4347+
4348 //native allocations
4349 std::shared_ptr<hwc_composer_device_1> create_hwc_native_device() const;
4350 std::shared_ptr<framebuffer_device_t> create_fb_native_device() const;
4351@@ -46,6 +48,8 @@
4352
4353 std::shared_ptr<ANativeWindow> create_native_window(
4354 std::shared_ptr<FramebufferBundle> const& fb_bundle) const;
4355+private:
4356+ bool const should_log_hwc;
4357 };
4358
4359 }
4360
4361=== modified file 'src/platform/graphics/mesa/CMakeLists.txt'
4362--- src/platform/graphics/mesa/CMakeLists.txt 2014-03-10 03:02:32 +0000
4363+++ src/platform/graphics/mesa/CMakeLists.txt 2014-04-07 13:29:13 +0000
4364@@ -47,6 +47,7 @@
4365 mirplatformgraphicsmesa
4366 mirplatform
4367
4368+ ${Boost_PROGRAM_OPTIONS_LIBRARY}
4369 ${DRM_LDFLAGS} ${DRM_LIBRARIES}
4370 ${GBM_LDFLAGS} ${GBM_LIBRARIES}
4371 ${EGL_LDFLAGS} ${EGL_LIBRARIES}
4372
4373=== modified file 'src/platform/graphics/mesa/display.cpp'
4374--- src/platform/graphics/mesa/display.cpp 2014-03-17 07:35:22 +0000
4375+++ src/platform/graphics/mesa/display.cpp 2014-04-07 13:29:13 +0000
4376@@ -54,7 +54,10 @@
4377 class GBMGLContext : public mg::GLContext
4378 {
4379 public:
4380- GBMGLContext(mgm::helpers::GBMHelper const& gbm, EGLContext shared_context)
4381+ GBMGLContext(mgm::helpers::GBMHelper const& gbm,
4382+ mg::GLConfig const& gl_config,
4383+ EGLContext shared_context)
4384+ : egl{gl_config}
4385 {
4386 egl.setup(gbm, shared_context);
4387 }
4388@@ -77,13 +80,16 @@
4389
4390 mgm::Display::Display(std::shared_ptr<Platform> const& platform,
4391 std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy,
4392+ std::shared_ptr<GLConfig> const& gl_config,
4393 std::shared_ptr<DisplayReport> const& listener)
4394 : platform(platform),
4395 listener(listener),
4396 monitor(mir::udev::Context()),
4397+ shared_egl{*gl_config},
4398 output_container{platform->drm.fd,
4399 std::make_shared<KMSPageFlipper>(platform->drm.fd)},
4400- current_display_configuration{platform->drm.fd}
4401+ current_display_configuration{platform->drm.fd},
4402+ gl_config{gl_config}
4403 {
4404 platform->vt->set_graphics_mode();
4405
4406@@ -203,6 +209,7 @@
4407 std::move(surface),
4408 bounding_rect,
4409 orientation,
4410+ *gl_config,
4411 shared_egl.context()}};
4412
4413 display_buffers_new.push_back(std::move(db));
4414@@ -320,7 +327,10 @@
4415 std::unique_ptr<mg::GLContext> mgm::Display::create_gl_context()
4416 {
4417 return std::unique_ptr<GBMGLContext>{
4418- new GBMGLContext{platform->gbm, shared_egl.context()}};
4419+ new GBMGLContext{
4420+ platform->gbm,
4421+ *gl_config,
4422+ shared_egl.context()}};
4423 }
4424
4425 void mgm::Display::clear_connected_unused_outputs()
4426
4427=== modified file 'src/platform/graphics/mesa/display.h'
4428--- src/platform/graphics/mesa/display.h 2014-03-06 06:05:17 +0000
4429+++ src/platform/graphics/mesa/display.h 2014-04-07 13:29:13 +0000
4430@@ -41,6 +41,7 @@
4431 class DisplayBuffer;
4432 class DisplayConfigurationPolicy;
4433 class EventHandlerRegister;
4434+class GLConfig;
4435
4436 namespace mesa
4437 {
4438@@ -54,8 +55,9 @@
4439 {
4440 public:
4441 Display(std::shared_ptr<Platform> const& platform,
4442- std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy,
4443- std::shared_ptr<DisplayReport> const& listener);
4444+ std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy,
4445+ std::shared_ptr<GLConfig> const& gl_config,
4446+ std::shared_ptr<DisplayReport> const& listener);
4447 ~Display();
4448
4449 geometry::Rectangle view_area() const;
4450@@ -92,6 +94,7 @@
4451 RealKMSOutputContainer output_container;
4452 mutable RealKMSDisplayConfiguration current_display_configuration;
4453 std::shared_ptr<Cursor> cursor;
4454+ std::shared_ptr<GLConfig> const gl_config;
4455 };
4456
4457 }
4458
4459=== modified file 'src/platform/graphics/mesa/display_buffer.cpp'
4460--- src/platform/graphics/mesa/display_buffer.cpp 2014-03-06 06:05:17 +0000
4461+++ src/platform/graphics/mesa/display_buffer.cpp 2014-04-07 13:29:13 +0000
4462@@ -101,6 +101,7 @@
4463 GBMSurfaceUPtr surface_gbm_param,
4464 geom::Rectangle const& area,
4465 MirOrientation rot,
4466+ GLConfig const& gl_config,
4467 EGLContext shared_context)
4468 : last_flipped_bufobj{nullptr},
4469 scheduled_bufobj{nullptr},
4470@@ -109,6 +110,7 @@
4471 drm(platform->drm),
4472 outputs(outputs),
4473 surface_gbm{std::move(surface_gbm_param)},
4474+ egl{gl_config},
4475 area(area),
4476 rotation(rot),
4477 needs_set_crtc{false},
4478@@ -196,7 +198,7 @@
4479 }
4480
4481 void mgm::DisplayBuffer::render_and_post_update(
4482- std::list<std::shared_ptr<Renderable>> const&,
4483+ RenderableList const&,
4484 std::function<void(Renderable const&)> const&)
4485 {
4486 post_update(nullptr);
4487
4488=== modified file 'src/platform/graphics/mesa/display_buffer.h'
4489--- src/platform/graphics/mesa/display_buffer.h 2014-03-06 06:05:17 +0000
4490+++ src/platform/graphics/mesa/display_buffer.h 2014-04-07 13:29:13 +0000
4491@@ -32,6 +32,7 @@
4492 {
4493
4494 class DisplayReport;
4495+class GLConfig;
4496
4497 namespace mesa
4498 {
4499@@ -49,6 +50,7 @@
4500 GBMSurfaceUPtr surface_gbm,
4501 geometry::Rectangle const& area,
4502 MirOrientation rot,
4503+ GLConfig const& gl_config,
4504 EGLContext shared_context);
4505 ~DisplayBuffer();
4506
4507@@ -59,7 +61,7 @@
4508
4509 bool can_bypass() const override;
4510 void post_update(std::shared_ptr<graphics::Buffer> bypass_buf) override;
4511- void render_and_post_update(std::list<std::shared_ptr<Renderable>> const& renderlist,
4512+ void render_and_post_update(RenderableList const& renderlist,
4513 std::function<void(Renderable const&)> const& render_fn);
4514 MirOrientation orientation() const override;
4515 void schedule_set_crtc();
4516
4517=== modified file 'src/platform/graphics/mesa/display_helpers.cpp'
4518--- src/platform/graphics/mesa/display_helpers.cpp 2014-03-12 02:46:58 +0000
4519+++ src/platform/graphics/mesa/display_helpers.cpp 2014-04-07 13:29:13 +0000
4520@@ -19,6 +19,7 @@
4521 #include "display_helpers.h"
4522 #include "drm_close_threadsafe.h"
4523
4524+#include "mir/graphics/gl_config.h"
4525 #include "mir/udev/wrapper.h"
4526
4527 #include <boost/exception/errinfo_errno.hpp>
4528@@ -219,7 +220,7 @@
4529 sv.drm_dd_major = -1; /* Don't care */
4530 sv.drm_dd_minor = -1; /* Don't care */
4531
4532- if ((error = drmSetInterfaceVersion(tmp_fd, &sv)))
4533+ if ((error = -drmSetInterfaceVersion(tmp_fd, &sv)))
4534 {
4535 close(tmp_fd);
4536 tmp_fd = -1;
4537@@ -238,7 +239,7 @@
4538 {
4539 BOOST_THROW_EXCEPTION(
4540 boost::enable_error_info(
4541- std::runtime_error("Error opening DRM device")) << boost::errinfo_errno(-error));
4542+ std::runtime_error("Error opening DRM device")) << boost::errinfo_errno(error));
4543 }
4544
4545 return tmp_fd;
4546@@ -295,6 +296,15 @@
4547 * EGLHelper *
4548 *************/
4549
4550+mgmh::EGLHelper::EGLHelper(GLConfig const& gl_config)
4551+ : depth_buffer_bits{gl_config.depth_buffer_bits()},
4552+ stencil_buffer_bits{gl_config.stencil_buffer_bits()},
4553+ egl_display{EGL_NO_DISPLAY}, egl_config{0},
4554+ egl_context{EGL_NO_CONTEXT}, egl_surface{EGL_NO_SURFACE},
4555+ should_terminate_egl{false}
4556+{
4557+}
4558+
4559 void mgmh::EGLHelper::setup(GBMHelper const& gbm)
4560 {
4561 static const EGLint context_attr[] = {
4562@@ -378,12 +388,14 @@
4563
4564 void mgmh::EGLHelper::setup_internal(GBMHelper const& gbm, bool initialize)
4565 {
4566- static const EGLint config_attr[] = {
4567+ EGLint const config_attr[] = {
4568 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
4569 EGL_RED_SIZE, 8,
4570 EGL_GREEN_SIZE, 8,
4571 EGL_BLUE_SIZE, 8,
4572 EGL_ALPHA_SIZE, 0,
4573+ EGL_DEPTH_SIZE, depth_buffer_bits,
4574+ EGL_STENCIL_SIZE, stencil_buffer_bits,
4575 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
4576 EGL_NONE
4577 };
4578
4579=== modified file 'src/platform/graphics/mesa/display_helpers.h'
4580--- src/platform/graphics/mesa/display_helpers.h 2014-03-12 02:46:58 +0000
4581+++ src/platform/graphics/mesa/display_helpers.h 2014-04-07 13:29:13 +0000
4582@@ -37,6 +37,8 @@
4583 {
4584 namespace graphics
4585 {
4586+class GLConfig;
4587+
4588 namespace mesa
4589 {
4590
4591@@ -92,11 +94,7 @@
4592 class EGLHelper
4593 {
4594 public:
4595- EGLHelper()
4596- : egl_display{EGL_NO_DISPLAY}, egl_config{0},
4597- egl_context{EGL_NO_CONTEXT}, egl_surface{EGL_NO_SURFACE},
4598- should_terminate_egl{false} {}
4599-
4600+ EGLHelper(GLConfig const& gl_config);
4601 ~EGLHelper() noexcept;
4602
4603 EGLHelper(const EGLHelper&) = delete;
4604@@ -117,6 +115,8 @@
4605 private:
4606 void setup_internal(GBMHelper const& gbm, bool initialize);
4607
4608+ EGLint const depth_buffer_bits;
4609+ EGLint const stencil_buffer_bits;
4610 EGLDisplay egl_display;
4611 EGLConfig egl_config;
4612 EGLContext egl_context;
4613
4614=== modified file 'src/platform/graphics/mesa/platform.cpp'
4615--- src/platform/graphics/mesa/platform.cpp 2014-03-13 07:47:55 +0000
4616+++ src/platform/graphics/mesa/platform.cpp 2014-04-07 13:29:13 +0000
4617@@ -147,11 +147,13 @@
4618 }
4619
4620 std::shared_ptr<mg::Display> mgm::Platform::create_display(
4621- std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy)
4622+ std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy,
4623+ std::shared_ptr<GLConfig> const& gl_config)
4624 {
4625 return std::make_shared<mgm::Display>(
4626 this->shared_from_this(),
4627 initial_conf_policy,
4628+ gl_config,
4629 listener);
4630 }
4631
4632@@ -219,3 +221,11 @@
4633 return (display == mgm::NativePlatform::internal_native_display().get());
4634 return 0;
4635 }
4636+
4637+extern "C" void add_platform_options(boost::program_options::options_description& config)
4638+{
4639+ config.add_options()
4640+ ("vt",
4641+ boost::program_options::value<int>()->default_value(0),
4642+ "[platform-specific] VT to run on or 0 to use current.");
4643+}
4644
4645=== modified file 'src/platform/graphics/mesa/platform.h'
4646--- src/platform/graphics/mesa/platform.h 2014-03-06 06:05:17 +0000
4647+++ src/platform/graphics/mesa/platform.h 2014-04-07 13:29:13 +0000
4648@@ -47,7 +47,8 @@
4649 std::shared_ptr<graphics::GraphicBufferAllocator> create_buffer_allocator(
4650 const std::shared_ptr<BufferInitializer>& buffer_initializer);
4651 std::shared_ptr<graphics::Display> create_display(
4652- std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy);
4653+ std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy,
4654+ std::shared_ptr<GLConfig> const& gl_config);
4655 std::shared_ptr<PlatformIPCPackage> get_ipc_package();
4656 std::shared_ptr<InternalClient> create_internal_client();
4657
4658
4659=== modified file 'src/platform/options/default_configuration.cpp'
4660--- src/platform/options/default_configuration.cpp 2014-03-17 07:35:22 +0000
4661+++ src/platform/options/default_configuration.cpp 2014-04-07 13:29:13 +0000
4662@@ -16,7 +16,10 @@
4663 * Authored by: Alan Griffiths <alan@octopull.co.uk>
4664 */
4665
4666+#include "mir/shared_library.h"
4667+#include "mir/shared_library_loader.h"
4668 #include "mir/options/default_configuration.h"
4669+#include "mir/graphics/platform.h"
4670 #include "mir/default_configuration.h"
4671 #include "mir/abnormal_exit.h"
4672
4673@@ -114,9 +117,35 @@
4674 (name_opt, po::value<std::string>(),
4675 "When nested, the name Mir uses when registering with the host.")
4676 (offscreen_opt,
4677- "Render to offscreen buffers instead of the real outputs.")
4678- ("vt", po::value<int>()->default_value(0), // TODO this not applicable on all graphics platforms
4679- "VT to run on or 0 to use current.");
4680+ "Render to offscreen buffers instead of the real outputs.");
4681+
4682+ add_platform_options();
4683+}
4684+
4685+void mo::DefaultConfiguration::add_platform_options()
4686+{
4687+ namespace po = boost::program_options;
4688+ po::options_description program_options;
4689+ program_options.add_options()
4690+ (platform_graphics_lib,
4691+ po::value<std::string>()->default_value(default_platform_graphics_lib), "");
4692+ mo::ProgramOption options;
4693+ options.parse_arguments(program_options, argc, argv);
4694+
4695+ std::string graphics_libname;
4696+ auto env_libname = ::getenv("MIR_SERVER_PLATFORM_GRAPHICS_LIB");
4697+ if (!options.is_set(platform_graphics_lib) && env_libname)
4698+ {
4699+ graphics_libname = std::string{env_libname};
4700+ }
4701+ else
4702+ {
4703+ graphics_libname = options.get<std::string>(platform_graphics_lib);
4704+ }
4705+
4706+ auto graphics_lib = load_library(graphics_libname);
4707+ auto add_platform_options = graphics_lib->load_function<mir::graphics::AddPlatformOptions>(std::string("add_platform_options"));
4708+ add_platform_options(*this->program_options);
4709 }
4710
4711 boost::program_options::options_description_easy_init mo::DefaultConfiguration::add_options()
4712
4713=== added file 'src/platform/shared_library_loader.cpp'
4714--- src/platform/shared_library_loader.cpp 1970-01-01 00:00:00 +0000
4715+++ src/platform/shared_library_loader.cpp 2014-04-07 13:29:13 +0000
4716@@ -0,0 +1,38 @@
4717+/*
4718+ * Copyright © 2013 Canonical Ltd.
4719+ *
4720+ * This program is free software: you can redistribute it and/or modify it
4721+ * under the terms of the GNU Lesser General Public License version 3,
4722+ * as published by the Free Software Foundation.
4723+ *
4724+ * This program is distributed in the hope that it will be useful,
4725+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4726+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4727+ * GNU Lesser General Public License for more details.
4728+ *
4729+ * You should have received a copy of the GNU Lesser General Public License
4730+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4731+ *
4732+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
4733+ */
4734+
4735+#include "mir/shared_library_loader.h"
4736+#include "mir/shared_library.h"
4737+#include <memory>
4738+#include <map>
4739+
4740+mir::SharedLibrary const* mir::load_library(std::string const& libname)
4741+{
4742+ // There's no point in loading twice, and it isn't safe to unload...
4743+ static std::map<std::string, std::shared_ptr<mir::SharedLibrary>> libraries_cache;
4744+
4745+ if (auto& ptr = libraries_cache[libname])
4746+ {
4747+ return ptr.get();
4748+ }
4749+ else
4750+ {
4751+ ptr = std::make_shared<mir::SharedLibrary>(libname);
4752+ return ptr.get();
4753+ }
4754+}
4755
4756=== modified file 'src/server/CMakeLists.txt'
4757--- src/server/CMakeLists.txt 2014-03-12 06:41:13 +0000
4758+++ src/server/CMakeLists.txt 2014-04-07 13:29:13 +0000
4759@@ -94,7 +94,7 @@
4760 )
4761 endif()
4762
4763-set(MIRSERVER_ABI 17)
4764+set(MIRSERVER_ABI 18)
4765
4766 set_target_properties(
4767 mirserver
4768
4769=== modified file 'src/server/compositor/buffer_bundle.h'
4770--- src/server/compositor/buffer_bundle.h 2014-03-07 03:15:55 +0000
4771+++ src/server/compositor/buffer_bundle.h 2014-04-07 13:29:13 +0000
4772@@ -36,8 +36,20 @@
4773 virtual ~BufferBundle() noexcept {}
4774 virtual void client_acquire(std::function<void(graphics::Buffer* buffer)> complete) = 0;
4775 virtual void client_release(graphics::Buffer*) = 0;
4776+
4777+ /**
4778+ * Acquire the next buffer that's ready to display/composite.
4779+ *
4780+ * \param [in] user_id A unique identifier of who is going to use the
4781+ * buffer, to ensure that separate users representing
4782+ * separate monitors who need the same frame will get
4783+ * the same buffer. However consecutive calls for the
4784+ * same user will get different buffers. To avoid
4785+ * collisions, all callers should determine user_id
4786+ * in the same way (e.g. always use "this" pointer).
4787+ */
4788 virtual std::shared_ptr<graphics::Buffer>
4789- compositor_acquire(unsigned long frameno) = 0;
4790+ compositor_acquire(void const* user_id) = 0;
4791 virtual void compositor_release(std::shared_ptr<graphics::Buffer> const&) = 0;
4792 virtual std::shared_ptr<graphics::Buffer> snapshot_acquire() = 0;
4793 virtual void snapshot_release(std::shared_ptr<graphics::Buffer> const&) = 0;
4794
4795=== modified file 'src/server/compositor/buffer_stream_surfaces.cpp'
4796--- src/server/compositor/buffer_stream_surfaces.cpp 2014-03-07 03:15:55 +0000
4797+++ src/server/compositor/buffer_stream_surfaces.cpp 2014-04-07 13:29:13 +0000
4798@@ -38,10 +38,10 @@
4799 }
4800
4801 std::shared_ptr<mg::Buffer> mc::BufferStreamSurfaces::lock_compositor_buffer(
4802- unsigned long frameno)
4803+ void const* user_id)
4804 {
4805 return std::make_shared<mc::TemporaryCompositorBuffer>(
4806- buffer_bundle, frameno);
4807+ buffer_bundle, user_id);
4808 }
4809
4810 std::shared_ptr<mg::Buffer> mc::BufferStreamSurfaces::lock_snapshot_buffer()
4811
4812=== modified file 'src/server/compositor/buffer_stream_surfaces.h'
4813--- src/server/compositor/buffer_stream_surfaces.h 2014-03-07 03:15:55 +0000
4814+++ src/server/compositor/buffer_stream_surfaces.h 2014-04-07 13:29:13 +0000
4815@@ -42,7 +42,7 @@
4816 void swap_client_buffers(graphics::Buffer* old_buffer, std::function<void(graphics::Buffer* new_buffer)> complete) override;
4817
4818 std::shared_ptr<graphics::Buffer>
4819- lock_compositor_buffer(unsigned long frameno) override;
4820+ lock_compositor_buffer(void const* user_id) override;
4821 std::shared_ptr<graphics::Buffer> lock_snapshot_buffer() override;
4822
4823 MirPixelFormat get_stream_pixel_format() override;
4824
4825=== modified file 'src/server/compositor/bypass.cpp'
4826--- src/server/compositor/bypass.cpp 2014-03-17 07:35:22 +0000
4827+++ src/server/compositor/bypass.cpp 2014-04-07 13:29:13 +0000
4828@@ -44,9 +44,14 @@
4829
4830 auto const& view_area = display_buffer.view_area();
4831
4832+ //TODO: remove this check, why are we getting a non visible renderable
4833+ // in the list of surfaces?
4834+ if (!renderable.visible())
4835+ return false;
4836+
4837 // Not weirdly transformed but also not on this monitor? Don't care...
4838 // This will also check the surface is not hidden and has been posted.
4839- if (!renderable.should_be_rendered_in(view_area))
4840+ if (!view_area.contains(renderable.screen_position()))
4841 return false;
4842
4843 topmost_fits = false;
4844
4845=== modified file 'src/server/compositor/default_display_buffer_compositor.cpp'
4846--- src/server/compositor/default_display_buffer_compositor.cpp 2014-03-17 07:35:22 +0000
4847+++ src/server/compositor/default_display_buffer_compositor.cpp 2014-04-07 13:29:13 +0000
4848@@ -29,41 +29,35 @@
4849 #include "occlusion.h"
4850 #include <mutex>
4851 #include <cstdlib>
4852-#include <vector>
4853+#include <algorithm>
4854
4855 namespace mc = mir::compositor;
4856 namespace mg = mir::graphics;
4857
4858+//TODO remove VisibilityFilter once we don't need filters/operators for rendering
4859 namespace
4860 {
4861-
4862-struct FilterForVisibleSceneInRegion : public mc::FilterForScene
4863+struct VisibilityFilter : public mc::FilterForScene
4864 {
4865- FilterForVisibleSceneInRegion(
4866- mir::geometry::Rectangle const& enclosing_region,
4867- mc::OcclusionMatch const& occlusions)
4868- : enclosing_region(enclosing_region),
4869- occlusions(occlusions)
4870+public:
4871+ VisibilityFilter(
4872+ mg::RenderableList const& renderable_list)
4873+ : list(renderable_list)
4874 {
4875 }
4876+
4877 bool operator()(mg::Renderable const& r)
4878 {
4879- return r.should_be_rendered_in(enclosing_region) &&
4880- !occlusions.occluded(r);
4881+ auto matcher = [&r](std::shared_ptr<mg::Renderable> const& renderable)
4882+ {
4883+ return (renderable.get() == &r);
4884+ };
4885+ return (std::find_if(list.begin(), list.end(), matcher) != list.end());
4886 }
4887
4888- mir::geometry::Rectangle const& enclosing_region;
4889- mc::OcclusionMatch const& occlusions;
4890+private:
4891+ mg::RenderableList const& list;
4892 };
4893-
4894-std::mutex global_frameno_lock;
4895-unsigned long global_frameno = 0;
4896-
4897-bool wrapped_greater_or_equal(unsigned long a, unsigned long b)
4898-{
4899- return (a - b) < (~0UL / 2UL);
4900-}
4901-
4902 }
4903
4904 mc::DefaultDisplayBufferCompositor::DefaultDisplayBufferCompositor(
4905@@ -75,29 +69,14 @@
4906 scene{scene},
4907 renderer{renderer},
4908 report{report},
4909- local_frameno{global_frameno}
4910+ last_pass_rendered_anything{false}
4911 {
4912 }
4913
4914-
4915 bool mc::DefaultDisplayBufferCompositor::composite()
4916 {
4917 report->began_frame(this);
4918
4919- /*
4920- * Increment frame counts for each tick of the fastest instance of
4921- * DefaultDisplayBufferCompositor. This means for the fastest refresh
4922- * rate of all attached outputs.
4923- */
4924- local_frameno++;
4925- {
4926- std::lock_guard<std::mutex> lock(global_frameno_lock);
4927- if (wrapped_greater_or_equal(local_frameno, global_frameno))
4928- global_frameno = local_frameno;
4929- else
4930- local_frameno = global_frameno;
4931- }
4932-
4933 static bool const bypass_env{[]
4934 {
4935 auto const env = getenv("MIR_BYPASS");
4936@@ -123,8 +102,13 @@
4937
4938 if (filter.fullscreen_on_top())
4939 {
4940- auto bypass_buf =
4941- match.topmost_fullscreen()->buffer(local_frameno);
4942+ /*
4943+ * Notice the user_id we pass to buffer() here has to be
4944+ * different to the one used in the Renderer. This is in case
4945+ * the below if() fails we want to complete the frame using the
4946+ * same buffer (different user_id required).
4947+ */
4948+ auto bypass_buf = match.topmost_fullscreen()->buffer(this);
4949
4950 if (bypass_buf->can_bypass())
4951 {
4952@@ -140,41 +124,32 @@
4953
4954 if (!bypassed)
4955 {
4956- // preserves buffers used in rendering until after post_update()
4957- std::vector<std::shared_ptr<void>> saved_resources;
4958- auto save_resource = [&](std::shared_ptr<void> const& r)
4959- {
4960- saved_resources.push_back(r);
4961- };
4962-
4963 display_buffer.make_current();
4964
4965 auto const& view_area = display_buffer.view_area();
4966+ auto renderable_list = scene->generate_renderable_list();
4967+ mc::filter_occlusions_from(renderable_list, view_area);
4968
4969- mc::OcclusionFilter occlusion_search(view_area);
4970- mc::OcclusionMatch occlusion_match;
4971- scene->reverse_for_each_if(occlusion_search, occlusion_match);
4972+ for(auto const& renderable : renderable_list)
4973+ uncomposited_buffers |= (renderable->buffers_ready_for_compositor() > 1);
4974
4975 renderer->set_rotation(display_buffer.orientation());
4976 renderer->begin();
4977- mc::RenderingOperator applicator(*renderer, save_resource, local_frameno, uncomposited_buffers);
4978- FilterForVisibleSceneInRegion selector(view_area, occlusion_match);
4979+ mc::RenderingOperator applicator(*renderer);
4980+ VisibilityFilter selector(renderable_list);
4981 scene->for_each_if(selector, applicator);
4982 renderer->end();
4983
4984 display_buffer.post_update();
4985
4986 // This is a frig to avoid lp:1286190
4987- if (size_of_last_pass)
4988- {
4989- uncomposited_buffers |= saved_resources.empty();
4990- }
4991+ if (last_pass_rendered_anything && renderable_list.empty())
4992+ uncomposited_buffers = true;
4993
4994- size_of_last_pass = saved_resources.size();
4995+ last_pass_rendered_anything = !renderable_list.empty();
4996 // End of frig
4997 }
4998
4999 report->finished_frame(bypassed, this);
5000 return uncomposited_buffers;
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches