Mir

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

Proposed by kevin gunn
Status: Merged
Merged at revision: 1179
Proposed branch: lp:~mir-team/mir/trunk-0.1.7
Merge into: lp:mir/0.1
Diff against target: 12893 lines (+4671/-2634)
200 files modified
3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp (+8/-0)
CMakeLists.txt (+1/-1)
debian/changelog (+56/-0)
debian/control (+2/-2)
debian/libmirserver17.install (+1/-1)
debian/rules (+5/-3)
examples/CMakeLists.txt (+0/-1)
examples/demo-shell/CMakeLists.txt (+1/-0)
examples/demo-shell/demo_renderer.cpp (+33/-0)
examples/demo-shell/demo_renderer.h (+39/-0)
examples/demo-shell/demo_shell.cpp (+21/-2)
examples/demo-shell/window_manager.cpp (+10/-24)
examples/eglplasma.c (+9/-7)
examples/image_renderer.cpp (+1/-0)
examples/pixel_format_selector.cpp (+2/-7)
examples/render_overlays.cpp (+92/-21)
examples/render_surfaces.cpp (+32/-5)
examples/scroll.cpp (+62/-41)
examples/server_configuration.cpp (+15/-26)
include/platform/mir/graphics/display_configuration.h (+27/-7)
include/platform/mir/graphics/overlapping_output_grouping.h (+3/-7)
include/platform/mir/graphics/renderable.h (+39/-1)
include/platform/mir/options/configuration.h (+0/-1)
include/server/mir/compositor/buffer_stream.h (+2/-1)
include/server/mir/compositor/compositing_criteria.h (+0/-52)
include/server/mir/compositor/display_buffer_compositor.h (+4/-2)
include/server/mir/compositor/gl_renderer.h (+32/-6)
include/server/mir/compositor/renderer.h (+6/-2)
include/server/mir/compositor/scene.h (+3/-4)
include/server/mir/frontend/screencast.h (+3/-1)
include/server/mir/shell/session.h (+0/-1)
include/shared/mir_toolkit/client_types.h (+23/-3)
include/shared/testdraw/draw_pattern_checkered-inl.h (+3/-3)
include/shared/testdraw/graphics_region_factory.h (+4/-4)
include/shared/testdraw/patterns.h (+3/-3)
include/test/mir_test_doubles/fake_renderable.h (+39/-17)
include/test/mir_test_doubles/mock_android_native_buffer.h (+9/-0)
include/test/mir_test_doubles/mock_buffer_bundle.h (+1/-0)
include/test/mir_test_doubles/mock_buffer_stream.h (+1/-0)
include/test/mir_test_doubles/mock_compositing_criteria.h (+0/-45)
include/test/mir_test_doubles/mock_display_device.h (+6/-3)
include/test/mir_test_doubles/mock_gl.h (+3/-2)
include/test/mir_test_doubles/mock_render_function.h (+40/-0)
include/test/mir_test_doubles/mock_render_function.h.moved (+40/-0)
include/test/mir_test_doubles/mock_renderable.h (+14/-1)
include/test/mir_test_doubles/mock_renderer.h (+2/-2)
include/test/mir_test_doubles/mock_scene.h (+48/-0)
include/test/mir_test_doubles/mock_screencast.h (+4/-2)
include/test/mir_test_doubles/mock_swapping_gl_context.h (+39/-0)
include/test/mir_test_doubles/null_display_configuration.h (+1/-1)
include/test/mir_test_doubles/null_screencast.h (+3/-1)
include/test/mir_test_doubles/stub_buffer.h (+16/-4)
include/test/mir_test_doubles/stub_buffer_stream.h (+2/-0)
include/test/mir_test_doubles/stub_display_configuration.h (+6/-1)
include/test/mir_test_doubles/stub_display_device.h (+5/-2)
include/test/mir_test_doubles/stub_renderable.h (+27/-2)
include/test/mir_test_doubles/stub_renderer.h (+2/-2)
include/test/mir_test_doubles/stub_swapping_gl_context.h (+39/-0)
src/client/CMakeLists.txt (+1/-0)
src/client/android/CMakeLists.txt (+9/-2)
src/client/mesa/CMakeLists.txt (+9/-2)
src/client/mir_screencast.cpp (+20/-23)
src/client/mir_screencast.h (+4/-2)
src/client/mir_screencast_api.cpp (+9/-19)
src/client/mir_surface.h (+0/-2)
src/platform/graphics/CMakeLists.txt (+1/-0)
src/platform/graphics/android/CMakeLists.txt (+10/-2)
src/platform/graphics/android/android_display.cpp (+8/-0)
src/platform/graphics/android/android_display_configuration.cpp (+4/-5)
src/platform/graphics/android/android_display_configuration.h (+1/-4)
src/platform/graphics/android/display_buffer.cpp (+10/-16)
src/platform/graphics/android/display_buffer.h (+1/-1)
src/platform/graphics/android/display_device.h (+6/-3)
src/platform/graphics/android/fb_device.cpp (+15/-14)
src/platform/graphics/android/fb_device.h (+5/-3)
src/platform/graphics/android/gl_context.cpp (+12/-0)
src/platform/graphics/android/gl_context.h (+15/-12)
src/platform/graphics/android/hwc_device.cpp (+96/-57)
src/platform/graphics/android/hwc_device.h (+27/-5)
src/platform/graphics/android/hwc_fb_device.cpp (+50/-30)
src/platform/graphics/android/hwc_fb_device.h (+7/-3)
src/platform/graphics/android/hwc_layerlist.cpp (+84/-90)
src/platform/graphics/android/hwc_layerlist.h (+21/-30)
src/platform/graphics/android/hwc_layers.cpp (+41/-11)
src/platform/graphics/android/hwc_layers.h (+7/-4)
src/platform/graphics/android/real_hwc_wrapper.cpp (+53/-0)
src/platform/graphics/android/real_hwc_wrapper.h (+48/-0)
src/platform/graphics/android/resource_factory.cpp (+3/-1)
src/platform/graphics/display_configuration.cpp (+50/-0)
src/platform/graphics/mesa/CMakeLists.txt (+9/-3)
src/platform/graphics/mesa/cursor.cpp (+26/-15)
src/platform/graphics/mesa/cursor.h (+2/-1)
src/platform/graphics/mesa/display.cpp (+7/-1)
src/platform/graphics/mesa/linux_virtual_terminal.cpp (+6/-5)
src/platform/graphics/mesa/linux_virtual_terminal.h (+21/-0)
src/platform/graphics/mesa/native_platform.cpp (+48/-1)
src/platform/graphics/mesa/native_platform.h (+10/-0)
src/platform/graphics/mesa/platform.cpp (+39/-2)
src/platform/graphics/mesa/real_kms_display_configuration.cpp (+6/-34)
src/platform/graphics/mesa/real_kms_display_configuration.h (+1/-4)
src/platform/graphics/overlapping_output_grouping.cpp (+7/-8)
src/platform/options/default_configuration.cpp (+2/-5)
src/server/CMakeLists.txt (+1/-1)
src/server/compositor/buffer_bundle.h (+1/-0)
src/server/compositor/buffer_stream_surfaces.cpp (+5/-0)
src/server/compositor/buffer_stream_surfaces.h (+1/-0)
src/server/compositor/bypass.cpp (+13/-52)
src/server/compositor/bypass.h (+5/-9)
src/server/compositor/compositing_screencast.cpp (+14/-37)
src/server/compositor/compositing_screencast.h (+6/-4)
src/server/compositor/default_configuration.cpp (+7/-4)
src/server/compositor/default_display_buffer_compositor.cpp (+25/-8)
src/server/compositor/default_display_buffer_compositor.h (+2/-1)
src/server/compositor/default_display_buffer_compositor_factory.cpp (+2/-2)
src/server/compositor/gl_renderer.cpp (+45/-57)
src/server/compositor/gl_renderer_factory.cpp (+1/-1)
src/server/compositor/gl_renderer_factory.h (+1/-1)
src/server/compositor/multi_threaded_compositor.cpp (+42/-25)
src/server/compositor/multi_threaded_compositor.h (+5/-3)
src/server/compositor/occlusion.cpp (+12/-32)
src/server/compositor/occlusion.h (+4/-6)
src/server/compositor/rendering_operator.cpp (+9/-5)
src/server/compositor/rendering_operator.h (+5/-3)
src/server/compositor/screencast_display_buffer.cpp (+3/-2)
src/server/compositor/switching_bundle.cpp (+32/-19)
src/server/compositor/switching_bundle.h (+2/-0)
src/server/frontend/session_mediator.cpp (+31/-20)
src/server/graphics/default_configuration.cpp (+28/-31)
src/server/graphics/default_display_configuration_policy.cpp (+9/-10)
src/server/graphics/nested/nested_display.cpp (+43/-34)
src/server/graphics/nested/nested_display_configuration.cpp (+59/-39)
src/server/graphics/nested/nested_display_configuration.h (+1/-5)
src/server/graphics/offscreen/display.cpp (+6/-0)
src/server/graphics/offscreen/display_configuration.cpp (+5/-3)
src/server/graphics/offscreen/display_configuration.h (+1/-5)
src/server/input/default_configuration.cpp (+2/-2)
src/server/input/nested_input_relay.cpp (+34/-55)
src/server/scene/basic_surface.cpp (+26/-41)
src/server/scene/basic_surface.h (+9/-6)
src/server/scene/mediating_display_changer.cpp (+2/-7)
src/server/scene/surface_stack.cpp (+9/-11)
src/shared/CMakeLists.txt (+1/-0)
src/shared/protobuf/mir_protobuf.proto (+9/-1)
src/shared/testdraw/CMakeLists.txt (+2/-0)
src/shared/testdraw/android_graphics_region_factory.cpp (+6/-5)
src/shared/testdraw/mesa_graphics_region_factory.cpp (+5/-5)
src/shared/testdraw/patterns.cpp (+4/-4)
src/utils/screencast.cpp (+161/-76)
tests/CMakeLists.txt (+0/-1)
tests/acceptance-tests/test_client_input.cpp (+38/-0)
tests/acceptance-tests/test_client_screencast.cpp (+72/-39)
tests/acceptance-tests/test_server_shutdown.cpp (+2/-2)
tests/acceptance-tests/test_surfaces_with_output_id.cpp (+4/-10)
tests/integration-tests/client/test_client_render.cpp (+2/-2)
tests/integration-tests/client/test_screencast.cpp (+5/-1)
tests/integration-tests/graphics/android/test_buffer_integration.cpp (+2/-2)
tests/integration-tests/input/CMakeLists.txt (+1/-0)
tests/integration-tests/input/test_nested_input.cpp (+124/-0)
tests/integration-tests/test_session.cpp (+2/-2)
tests/integration-tests/test_surface_first_frame_sync.cpp (+3/-3)
tests/integration-tests/test_swapinterval.cpp (+2/-1)
tests/mir_test/display_config_matchers.cpp (+6/-3)
tests/mir_test_doubles/mock_gl.cpp (+6/-0)
tests/mir_test_framework/stubbed_server_configuration.cpp (+2/-2)
tests/unit-tests/client/test_mir_screencast.cpp (+91/-79)
tests/unit-tests/compositor/test_bypass.cpp (+55/-59)
tests/unit-tests/compositor/test_compositing_screencast.cpp (+31/-20)
tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp (+91/-81)
tests/unit-tests/compositor/test_gl_renderer.cpp (+31/-37)
tests/unit-tests/compositor/test_multi_threaded_compositor.cpp (+85/-33)
tests/unit-tests/compositor/test_occlusion.cpp (+24/-27)
tests/unit-tests/compositor/test_rendering_operator.cpp (+13/-13)
tests/unit-tests/compositor/test_screencast_display_buffer.cpp (+17/-0)
tests/unit-tests/draw/test_draw_patterns.cpp (+1/-1)
tests/unit-tests/frontend/test_session_mediator.cpp (+1/-9)
tests/unit-tests/graphics/android/CMakeLists.txt (+1/-0)
tests/unit-tests/graphics/android/hwc_struct_helpers.h (+16/-3)
tests/unit-tests/graphics/android/test_android_fb.cpp (+21/-29)
tests/unit-tests/graphics/android/test_fb_device.cpp (+25/-16)
tests/unit-tests/graphics/android/test_hwc_common_device.cpp (+18/-1)
tests/unit-tests/graphics/android/test_hwc_device.cpp (+528/-117)
tests/unit-tests/graphics/android/test_hwc_display.cpp (+5/-23)
tests/unit-tests/graphics/android/test_hwc_fb_device.cpp (+88/-51)
tests/unit-tests/graphics/android/test_hwc_layerlist.cpp (+36/-196)
tests/unit-tests/graphics/android/test_hwc_layers.cpp (+122/-85)
tests/unit-tests/graphics/android/test_hwc_wrapper.cpp (+119/-0)
tests/unit-tests/graphics/mesa/test_cursor.cpp (+93/-5)
tests/unit-tests/graphics/mesa/test_display_multi_monitor.cpp (+27/-37)
tests/unit-tests/graphics/mesa/test_linux_virtual_terminal.cpp (+175/-11)
tests/unit-tests/graphics/mesa/test_native_platform.cpp (+60/-0)
tests/unit-tests/graphics/mesa/test_overlapping_output_grouping.cpp (+4/-7)
tests/unit-tests/graphics/nested/test_nested_display_configuration.cpp (+20/-68)
tests/unit-tests/graphics/test_default_display_configuration_policy.cpp (+42/-38)
tests/unit-tests/graphics/test_display.cpp (+34/-0)
tests/unit-tests/graphics/test_display_configuration.cpp (+41/-0)
tests/unit-tests/scene/test_basic_surface.cpp (+2/-28)
tests/unit-tests/scene/test_surface.cpp (+0/-1)
tests/unit-tests/scene/test_surface_stack.cpp (+83/-113)
tests/unit-tests/test_udev_wrapper.cpp (+3/-1)
tools/install_on_android.sh (+1/-1)
To merge this branch: bzr merge lp:~mir-team/mir/trunk-0.1.7
Reviewer Review Type Date Requested Status
Daniel van Vugt Approve
PS Jenkins bot (community) continuous-integration Needs Fixing
Mir development team Pending
Review via email: mp+211132@code.launchpad.net

Commit message

Merge latest upstream release 0.1.7 (development-branch r1473)

To post a comment you must log in.
Revision history for this message
kevin gunn (kgunn72) wrote :

Did you test your feature/code change/bug fix ? what device(s) ?
- code has been run through CI testing on lp:mir/devel, running on desktop, n10, n4 & n7

Did you break mir server API or ABI and have the relevant bumps to .so and debian docs been made ?
- ABI for server, so name bumped

Did you break mir client API or ABI and have you followed up with the known clients & announced on mir-devel mailing list ?
- ABI for server broke, relevant MP's are in place

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~mir-team/mir/trunk-0.1.7 updated
1179. By Daniel van Vugt

Merge latest upstream release 0.1.7 (development-branch r1473)

Also fixed a mountain of spurious conflicts whose origin is unknown.

1180. By Daniel van Vugt

Remove orphaned deprecated files that "bzr merge" should have removed,
because they don't exist upstream any more.

1181. By Daniel van Vugt

Fill out debian/changelog

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

Verified the diff to release 0.1.7 is now only debian/changelog. And the conflicts no longer reappear when merging between distro/development.

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

daniel - in the future, if you update the branch especially with updates from devel, make sure to disable the arm integration tests, as those tests will fail on the silo builders

lp:~mir-team/mir/trunk-0.1.7 updated
1182. By kevin gunn

disable arm integration tests for silo build

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/frameworks/base/services/input/InputDispatcher.cpp'
2--- 3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp 2014-01-22 10:03:11 +0000
3+++ 3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp 2014-03-17 15:02:33 +0000
4@@ -432,6 +432,7 @@
5 sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t x, int32_t y) {
6 sp<InputWindowHandle> foundHandle = NULL;
7 mEnumerator->for_each([&](sp<InputWindowHandle> windowHandle) {
8+ windowHandle->updateInfo();
9 const InputWindowInfo* windowInfo = windowHandle->getInfo();
10 int32_t flags = windowInfo->layoutParamsFlags;
11
12@@ -1151,6 +1152,7 @@
13
14 // Traverse windows from front to back to find touched window and outside targets.
15 mEnumerator->for_each([&](sp<InputWindowHandle> const& windowHandle){
16+ windowHandle->updateInfo();
17 const InputWindowInfo* windowInfo = windowHandle->getInfo();
18 int32_t flags = windowInfo->layoutParamsFlags;
19
20@@ -2742,6 +2744,12 @@
21 c_str(newFocusedWindowHandle->getName()));
22 #endif
23 }
24+
25+ if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_NONE) {
26+ releasePendingEventLocked();
27+ drainInboundQueueLocked();
28+ }
29+
30 mFocusedWindowHandle = newFocusedWindowHandle;
31 }
32 }
33
34=== modified file 'CMakeLists.txt'
35--- CMakeLists.txt 2014-02-28 13:51:43 +0000
36+++ CMakeLists.txt 2014-03-17 15:02:33 +0000
37@@ -28,7 +28,7 @@
38
39 set(MIR_VERSION_MAJOR 0)
40 set(MIR_VERSION_MINOR 1)
41-set(MIR_VERSION_PATCH 6)
42+set(MIR_VERSION_PATCH 7)
43
44 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
45 execute_process(
46
47=== modified file 'debian/changelog'
48--- debian/changelog 2014-03-10 19:28:46 +0000
49+++ debian/changelog 2014-03-17 15:02:33 +0000
50@@ -1,3 +1,59 @@
51+mir (0.1.7-0ubuntu1) UNRELEASED; urgency=medium
52+
53+ * New upstream release 0.1.7 (https://launchpad.net/mir/+milestone/0.1.7)
54+ - mirserver ABI bumped to 17
55+ - mirclient ABI unchanged, still at 7. Clients do not need rebuilding.
56+ - Server API changes (AKA why doesn't my code build any more?):
57+ . Class "CompositingCriteria" has been removed. It's replaced by the more
58+ flexible "Renderable" interface. This also resulted in parameter
59+ changes for the Renderer and scene filtering classes.
60+ . The function "DisplayConfiguration::configure_output()" has been
61+ removed. Instead, please use the new mutable version of
62+ "DisplayConfiguration::for_each_output()" with which you can modify
63+ the output structure passed in on each iteration.
64+ . Exposed formerly private class "GLRenderer" and demonstrated how
65+ to override its behaviour in demo-shell. This area is under
66+ construction and may experience further major changes.
67+ - Added initial support for hardware (HWC) overlays to accelerate
68+ rendering and reduce power consumption. Not complete yet.
69+ - Screen rotation: Added mouse cursor rotation support, so you can now
70+ still control things on a rotated screen. Still missing rotation of
71+ the cursor bitmap itself.
72+ - Lots of fixes to support nested Mir servers (see below).
73+ - Major simplification to how surface size/position/transformation
74+ interact, making transformations much easier to manage and work with.
75+ - Bugs fixed:
76+ . ./cross-compile-chroot.sh: line 83: popd: build-android-arm: invalid
77+ argument popd: usage: popd [-n] [+N | -N] (LP: #1287600)
78+ . Key events sent to the wrong client (and delayed) (LP: #1213804)
79+ . Nested servers never receive input events (in their filters)
80+ (LP: #1260612)
81+ . Software clients crash immediately on nested servers - what(): Failed
82+ to mmap buffer (LP: #1261286)
83+ . MirMotionEvent lacks local coordinates. Reports only screen
84+ coordinates. (LP: #1268819)
85+ . Nested Mir crashes with - what():
86+ MesaNativePlatform::create_internal_client is not implemented yet!
87+ (LP: #1279092)
88+ . clients fail to find some libraries if mir installed via "make install"
89+ (LP: #1285566)
90+ . Nested server hangs with multimonitor and internal clients.
91+ (LP: #1287282)
92+ . [regression] Multi-monitor frame sync no longer works (not
93+ synchronized), and frames skip/jump/stutter (LP: #1288570)
94+ . Mir FTBFS: /usr/bin/ld: cannot find -lmirtestdraw (when cmake ..
95+ -DMIR_ENABLE_TESTS=OFF) (LP: #1283951)
96+ . nested Mir library calls next_buffer() during startup (LP: #1284739)
97+ . Building Mir produces lots of warnings from GLM headers about
98+ deprecated degrees values vs radians (LP: #1286010)
99+ . [enhancement] screencast of a single window (LP: #1288478)
100+ . Nexus4 + mir_demo_client_eglplasma starts to stutter after a while
101+ (LP: #1189753)
102+ . --host-socket documented default argument isn't used as default
103+ (LP: #1262091)
104+
105+ -- Daniel van Vugt <daniel.van.vugt@canonical.com> Wed, 12 Mar 2014 11:05:20 +0800
106+
107 mir (0.1.6+14.04.20140310-0ubuntu1) trusty; urgency=medium
108
109 [ Kevin Gunn ]
110
111=== modified file 'debian/control'
112--- debian/control 2014-03-06 14:18:50 +0000
113+++ debian/control 2014-03-17 15:02:33 +0000
114@@ -70,7 +70,7 @@
115 .
116 Contains the protocol's definition files.
117
118-Package: libmirserver16
119+Package: libmirserver17
120 Section: libs
121 Architecture: i386 amd64 armhf arm64
122 Multi-Arch: same
123@@ -148,7 +148,7 @@
124 Architecture: i386 amd64 armhf arm64
125 Multi-Arch: same
126 Pre-Depends: ${misc:Pre-Depends}
127-Depends: libmirserver16 (= ${binary:Version}),
128+Depends: libmirserver17 (= ${binary:Version}),
129 libmirprotobuf-dev (= ${binary:Version}),
130 mircommon-dev (= ${binary:Version}),
131 libglm-dev,
132
133=== renamed file 'debian/libmirserver16.install' => 'debian/libmirserver17.install'
134--- debian/libmirserver16.install 2014-02-21 03:57:16 +0000
135+++ debian/libmirserver17.install 2014-03-17 15:02:33 +0000
136@@ -1,1 +1,1 @@
137-usr/lib/*/libmirserver.so.16
138+usr/lib/*/libmirserver.so.17
139
140=== modified file 'debian/rules'
141--- debian/rules 2014-03-06 14:18:50 +0000
142+++ debian/rules 2014-03-17 15:02:33 +0000
143@@ -22,8 +22,8 @@
144 dh_auto_configure -- \
145 $(COMMON_CONFIGURE_OPTIONS) \
146 -DMIR_RUN_ACCEPTANCE_TESTS=OFF \
147- -DMIR_RUN_INTEGRATION_TESTS=OFF \
148- -DMIR_PLATFORM=android\;mesa
149+ -DMIR_RUN_INTEGRATION_TESTS=OFF \
150+ -DMIR_PLATFORM=android\;mesa
151 else
152 ifeq ($(DEB_HOST_ARCH),arm64)
153 dh_auto_configure -- \
154@@ -41,7 +41,9 @@
155 dh_makeshlibs -V
156
157 override_dh_install:
158- dh_install --fail-missing
159+ dh_install --fail-missing \
160+ -Xusr/lib/$(DEB_HOST_MULTIARCH)/libmirplatformgraphics.so \
161+ -Xusr/lib/$(DEB_HOST_MULTIARCH)/libmirclientplatform.so
162 sh debian/install_ld_so_conf.sh $(DEB_HOST_MULTIARCH)
163
164 override_dh_installdeb:
165
166=== modified file 'examples/CMakeLists.txt'
167--- examples/CMakeLists.txt 2014-03-04 04:19:26 +0000
168+++ examples/CMakeLists.txt 2014-03-17 15:02:33 +0000
169@@ -93,7 +93,6 @@
170 ${PROJECT_SOURCE_DIR}/include/server
171 ${PROJECT_SOURCE_DIR}/include/client
172 ${PROJECT_SOURCE_DIR}/include/platform
173- ${PROJECT_SOURCE_DIR}/include/test/mir_test/draw
174 ${GLESv2_INCLUDE_DIRS}
175 )
176
177
178=== modified file 'examples/demo-shell/CMakeLists.txt'
179--- examples/demo-shell/CMakeLists.txt 2013-08-28 03:41:48 +0000
180+++ examples/demo-shell/CMakeLists.txt 2014-03-17 15:02:33 +0000
181@@ -1,5 +1,6 @@
182 add_executable(mir_demo_server_shell
183 demo_shell.cpp
184+ demo_renderer.cpp
185 fullscreen_placement_strategy.cpp
186 window_manager.cpp
187 ../server_configuration.cpp
188
189=== added file 'examples/demo-shell/demo_renderer.cpp'
190--- examples/demo-shell/demo_renderer.cpp 1970-01-01 00:00:00 +0000
191+++ examples/demo-shell/demo_renderer.cpp 2014-03-17 15:02:33 +0000
192@@ -0,0 +1,33 @@
193+/*
194+ * Copyright © 2014 Canonical Ltd.
195+ *
196+ * This program is free software: you can redistribute it and/or modify
197+ * it under the terms of the GNU General Public License version 3 as
198+ * published by the Free Software Foundation.
199+ *
200+ * This program is distributed in the hope that it will be useful,
201+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
202+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
203+ * GNU General Public License for more details.
204+ *
205+ * You should have received a copy of the GNU General Public License
206+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
207+ *
208+ * Authored by: Daniel van Vugt <daniel.van.vugt@canonical.com>
209+ */
210+
211+#include "demo_renderer.h"
212+
213+using namespace mir;
214+using namespace mir::examples;
215+
216+DemoRenderer::DemoRenderer(geometry::Rectangle const& display_area)
217+ : GLRenderer(display_area)
218+{
219+}
220+
221+void DemoRenderer::begin() const
222+{
223+ glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
224+ glClear(GL_COLOR_BUFFER_BIT);
225+}
226
227=== added file 'examples/demo-shell/demo_renderer.h'
228--- examples/demo-shell/demo_renderer.h 1970-01-01 00:00:00 +0000
229+++ examples/demo-shell/demo_renderer.h 2014-03-17 15:02:33 +0000
230@@ -0,0 +1,39 @@
231+/*
232+ * Copyright © 2014 Canonical Ltd.
233+ *
234+ * This program is free software: you can redistribute it and/or modify
235+ * it under the terms of the GNU General Public License version 3 as
236+ * published by the Free Software Foundation.
237+ *
238+ * This program is distributed in the hope that it will be useful,
239+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
240+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
241+ * GNU General Public License for more details.
242+ *
243+ * You should have received a copy of the GNU General Public License
244+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
245+ *
246+ * Authored by: Daniel van Vugt <daniel.van.vugt@canonical.com>
247+ */
248+
249+#ifndef MIR_EXAMPLES_DEMO_RENDERER_H_
250+#define MIR_EXAMPLES_DEMO_RENDERER_H_
251+
252+#include "mir/compositor/gl_renderer.h"
253+
254+namespace mir
255+{
256+namespace examples
257+{
258+
259+class DemoRenderer : public compositor::GLRenderer
260+{
261+public:
262+ DemoRenderer(geometry::Rectangle const& display_area);
263+ void begin() const override;
264+};
265+
266+} // namespace examples
267+} // namespace mir
268+
269+#endif // MIR_EXAMPLES_DEMO_RENDERER_H_
270
271=== modified file 'examples/demo-shell/demo_shell.cpp'
272--- examples/demo-shell/demo_shell.cpp 2014-02-28 13:51:43 +0000
273+++ examples/demo-shell/demo_shell.cpp 2014-03-17 15:02:33 +0000
274@@ -18,6 +18,7 @@
275
276 /// \example demo_shell.cpp A simple mir shell
277
278+#include "demo_renderer.h"
279 #include "window_manager.h"
280 #include "fullscreen_placement_strategy.h"
281 #include "../server_configuration.h"
282@@ -27,6 +28,7 @@
283 #include "mir/report_exception.h"
284 #include "mir/graphics/display.h"
285 #include "mir/input/composite_event_filter.h"
286+#include "mir/compositor/renderer_factory.h"
287
288 #include <iostream>
289
290@@ -42,8 +44,19 @@
291 namespace examples
292 {
293
294-struct DemoServerConfiguration : mir::examples::ServerConfiguration
295-{
296+class DemoRendererFactory : public compositor::RendererFactory
297+{
298+public:
299+ std::unique_ptr<compositor::Renderer> create_renderer_for(
300+ geometry::Rectangle const& rect) override
301+ {
302+ return std::unique_ptr<compositor::Renderer>(new DemoRenderer(rect));
303+ }
304+};
305+
306+class DemoServerConfiguration : public mir::examples::ServerConfiguration
307+{
308+public:
309 DemoServerConfiguration(int argc, char const* argv[],
310 std::initializer_list<std::shared_ptr<mi::EventFilter>> const& filter_list)
311 : ServerConfiguration([argc, argv]
312@@ -82,6 +95,12 @@
313 return composite_filter;
314 }
315
316+ std::shared_ptr<compositor::RendererFactory> the_renderer_factory() override
317+ {
318+ return std::make_shared<DemoRendererFactory>();
319+ }
320+
321+private:
322 std::vector<std::shared_ptr<mi::EventFilter>> const filter_list;
323 };
324
325
326=== modified file 'examples/demo-shell/window_manager.cpp'
327--- examples/demo-shell/window_manager.cpp 2014-03-05 02:30:30 +0000
328+++ examples/demo-shell/window_manager.cpp 2014-03-17 15:02:33 +0000
329@@ -140,23 +140,14 @@
330 {
331 compositor->stop();
332 auto conf = display->configuration();
333- conf->for_each_output([&](mg::DisplayConfigurationOutput const& output) -> void
334- {
335- MirPowerMode power_mode;
336- if (!output.used) return;
337-
338- if (display_off == true)
339- power_mode = mir_power_mode_on;
340- else
341- power_mode = mir_power_mode_off;
342-
343- conf->configure_output(output.id, output.used,
344- output.top_left,
345- output.current_mode_index,
346- output.current_format,
347- power_mode,
348- output.orientation);
349- });
350+ MirPowerMode new_power_mode = display_off ?
351+ mir_power_mode_on : mir_power_mode_off;
352+ conf->for_each_output(
353+ [&](mg::UserDisplayConfigurationOutput& output) -> void
354+ {
355+ output.power_mode = new_power_mode;
356+ }
357+ );
358 display_off = !display_off;
359
360 display->configure(*conf.get());
361@@ -184,14 +175,9 @@
362 compositor->stop();
363 auto conf = display->configuration();
364 conf->for_each_output(
365- [&](mg::DisplayConfigurationOutput const& output) -> void
366+ [&](mg::UserDisplayConfigurationOutput& output) -> void
367 {
368- conf->configure_output(output.id, output.used,
369- output.top_left,
370- output.current_mode_index,
371- output.current_format,
372- output.power_mode,
373- orientation);
374+ output.orientation = orientation;
375 }
376 );
377 display->configure(*conf);
378
379=== modified file 'examples/eglplasma.c'
380--- examples/eglplasma.c 2013-09-19 13:24:22 +0000
381+++ examples/eglplasma.c 2014-03-17 15:02:33 +0000
382@@ -85,14 +85,13 @@
383 " const float pi2 = 6.283185308; \n"
384 " float u = texcoord.x * pi2; \n"
385 " float v = texcoord.y * pi2; \n"
386- " float t = mod(theta, pi2); \n"
387- " float us = (cos(1.1 * u + 7.0 * t) + \n"
388- " cos(2.3 * v * cos(1.0 * t)) + \n"
389- " cos(0.3 * u * cos(3.0 * t)) \n"
390+ " float us = (cos(1.1 * u + 7.0 * theta) + \n"
391+ " cos(2.3 * v * cos(1.0 * theta)) + \n"
392+ " cos(0.3 * u * cos(3.0 * theta)) \n"
393 " ) / 3.0; \n"
394- " float vs = (cos(2.3 * v + 8.0 * t) + \n"
395- " cos(1.3 * u * cos(3.0 * t)) + \n"
396- " cos(1.7 * v * cos(2.0 * t)) \n"
397+ " float vs = (cos(2.3 * v + 8.0 * theta) + \n"
398+ " cos(1.3 * u * cos(3.0 * theta)) + \n"
399+ " cos(1.7 * v * cos(2.0 * theta)) \n"
400 " ) / 3.0; \n"
401 " float x = (us * vs + 1.0) / 2.0; \n"
402 " gl_FragColor = vec4(gradient(x), 1.0); \n"
403@@ -105,6 +104,7 @@
404 1.0f,-1.0f,
405 -1.0f,-1.0f,
406 };
407+ const float pi2 = 6.283185308f;
408 GLuint vshader, fshader, prog;
409 GLint linked, low_color, high_color, vpos, theta;
410 unsigned int width = 0, height = 0;
411@@ -151,6 +151,8 @@
412 {
413 glUniform1f(theta, angle);
414 angle += 0.005f;
415+ if (angle > pi2)
416+ angle -= pi2;
417 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
418 mir_eglapp_swap_buffers();
419 }
420
421=== modified file 'examples/image_renderer.cpp'
422--- examples/image_renderer.cpp 2014-01-22 10:03:11 +0000
423+++ examples/image_renderer.cpp 2014-03-17 15:02:33 +0000
424@@ -23,6 +23,7 @@
425 #pragma GCC diagnostic warning "-Wall"
426 #include <glm/glm.hpp>
427 #pragma GCC diagnostic pop
428+#define GLM_FORCE_RADIANS
429 #include <glm/gtc/type_ptr.hpp>
430
431 #include <memory>
432
433=== modified file 'examples/pixel_format_selector.cpp'
434--- examples/pixel_format_selector.cpp 2014-03-05 02:30:30 +0000
435+++ examples/pixel_format_selector.cpp 2014-03-17 15:02:33 +0000
436@@ -40,7 +40,7 @@
437 {
438 base_policy->apply_to(conf);
439 conf.for_each_output(
440- [&](graphics::DisplayConfigurationOutput const& conf_output)
441+ [&](graphics::UserDisplayConfigurationOutput& conf_output)
442 {
443 if (!conf_output.connected || !conf_output.used) return;
444
445@@ -56,12 +56,7 @@
446 if (pos == conf_output.pixel_formats.end())
447 return;
448
449- conf.configure_output(conf_output.id, true, conf_output.top_left,
450- conf_output.current_mode_index,
451- *pos,
452- conf_output.power_mode,
453- conf_output.orientation
454- );
455+ conf_output.current_format = *pos;
456 });
457 }
458
459
460=== modified file 'examples/render_overlays.cpp'
461--- examples/render_overlays.cpp 2014-03-04 04:19:26 +0000
462+++ examples/render_overlays.cpp 2014-03-17 15:02:33 +0000
463@@ -25,9 +25,10 @@
464 #include "mir/graphics/buffer_properties.h"
465 #include "mir/report_exception.h"
466
467-#include "graphics_region_factory.h"
468-#include "patterns.h"
469+#include "testdraw/graphics_region_factory.h"
470+#include "testdraw/patterns.h"
471
472+#include <chrono>
473 #include <csignal>
474 #include <iostream>
475
476@@ -44,20 +45,69 @@
477 {
478 running = false;
479 }
480-}
481+
482+class DemoOverlayClient
483+{
484+public:
485+ DemoOverlayClient(
486+ mg::GraphicBufferAllocator& buffer_allocator,
487+ mg::BufferProperties const& buffer_properties, uint32_t color)
488+ : front_buffer(buffer_allocator.alloc_buffer(buffer_properties)),
489+ back_buffer(buffer_allocator.alloc_buffer(buffer_properties)),
490+ region_factory(mir::test::draw::create_graphics_region_factory()),
491+ color{color},
492+ last_tick{std::chrono::high_resolution_clock::now()}
493+ {
494+ }
495+
496+ void update_green_channel()
497+ {
498+ char green_value = (color >> 8) & 0xFF;
499+ green_value += compute_update_value();
500+ color &= 0xFFFF00FF;
501+ color |= (green_value << 8);
502+
503+ mir::test::draw::DrawPatternSolid fill{color};
504+ fill.draw(*region_factory->graphic_region_from_handle(*back_buffer->native_buffer_handle()));
505+ std::swap(front_buffer, back_buffer);
506+ }
507+
508+ std::shared_ptr<mg::Buffer> last_rendered()
509+ {
510+ return front_buffer;
511+ }
512+
513+private:
514+ int compute_update_value()
515+ {
516+ float const update_ratio{3.90625}; //this will give an update of 256 in 1s
517+ auto current_tick = std::chrono::high_resolution_clock::now();
518+ auto elapsed_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
519+ current_tick - last_tick).count();
520+ float update_value = elapsed_ms / update_ratio;
521+ last_tick = current_tick;
522+ return static_cast<int>(update_value);
523+ }
524+
525+ std::shared_ptr<mg::Buffer> front_buffer;
526+ std::shared_ptr<mg::Buffer> back_buffer;
527+ std::shared_ptr<mir::test::draw::GraphicsRegionFactory> region_factory;
528+ unsigned int color;
529+ std::chrono::time_point<std::chrono::high_resolution_clock> last_tick;
530+};
531
532 class DemoRenderable : public mg::Renderable
533 {
534 public:
535- DemoRenderable(std::shared_ptr<mg::Buffer> const& buffer, geom::Rectangle rect)
536- : renderable_buffer(buffer),
537+ DemoRenderable(std::shared_ptr<DemoOverlayClient> const& client, geom::Rectangle rect)
538+ : client(client),
539 position(rect)
540 {
541 }
542
543- std::shared_ptr<mg::Buffer> buffer() const
544+ std::shared_ptr<mg::Buffer> buffer(unsigned long) const override
545 {
546- return renderable_buffer;
547+ return client->last_rendered();
548 }
549
550 bool alpha_enabled() const
551@@ -70,16 +120,41 @@
552 return position;
553 }
554
555+ float alpha() const override
556+ {
557+ return 1.0f;
558+ }
559+
560+ glm::mat4 transformation() const override
561+ {
562+ return trans;
563+ }
564+
565+ bool shaped() const
566+ {
567+ return false;
568+ }
569+
570+ bool should_be_rendered_in(geom::Rectangle const& rect) const override
571+ {
572+ return rect.overlaps(position);
573+ }
574+
575+ int buffers_ready_for_compositor() const override
576+ {
577+ return 1;
578+ }
579+
580 private:
581- std::shared_ptr<mg::Buffer> const renderable_buffer;
582+ std::shared_ptr<DemoOverlayClient> const client;
583 geom::Rectangle const position;
584+ glm::mat4 const trans;
585 };
586+}
587
588 int main(int argc, char const** argv)
589 try
590 {
591- mir::test::draw::DrawPatternSolid fill_with_green(0x00FF00FF);
592- mir::test::draw::DrawPatternSolid fill_with_blue(0x0000FFFF);
593
594 /* Set up graceful exit on SIGINT and SIGTERM */
595 struct sigaction sa;
596@@ -95,7 +170,6 @@
597 auto platform = conf.the_graphics_platform();
598 auto display = platform->create_display(conf.the_display_configuration_policy());
599 auto buffer_allocator = platform->create_buffer_allocator(conf.the_buffer_initializer());
600- auto region_factory = mir::test::draw::create_graphics_region_factory();
601
602 mg::BufferProperties buffer_properties{
603 geom::Size{512, 512},
604@@ -103,18 +177,13 @@
605 mg::BufferUsage::hardware
606 };
607
608- auto buffer1 = buffer_allocator->alloc_buffer(buffer_properties);
609- auto buffer2 = buffer_allocator->alloc_buffer(buffer_properties);
610-
611- fill_with_green.draw(*region_factory->graphic_region_from_handle(*buffer1->native_buffer_handle()));
612- fill_with_blue.draw(*region_factory->graphic_region_from_handle(*buffer2->native_buffer_handle()));
613-
614- geom::Rectangle screen_pos1{{0,0} , {512, 512}};
615- geom::Rectangle screen_pos2{{80,80} , {592,592}};
616+ auto client1 = std::make_shared<DemoOverlayClient>(*buffer_allocator, buffer_properties,0xFF0000FF);
617+ auto client2 = std::make_shared<DemoOverlayClient>(*buffer_allocator, buffer_properties,0xFFFFFF00);
618+
619 std::list<std::shared_ptr<mg::Renderable>> renderlist
620 {
621- std::make_shared<DemoRenderable>(buffer2, screen_pos2),
622- std::make_shared<DemoRenderable>(buffer1, screen_pos1)
623+ std::make_shared<DemoRenderable>(client1, geom::Rectangle{{0,0} , {512, 512}}),
624+ std::make_shared<DemoRenderable>(client2, geom::Rectangle{{80,80} , {592,592}})
625 };
626
627 while (running)
628@@ -122,6 +191,8 @@
629 display->for_each_display_buffer([&](mg::DisplayBuffer& buffer)
630 {
631 buffer.make_current();
632+ client1->update_green_channel();
633+ client2->update_green_channel();
634 auto render_fn = [](mg::Renderable const&) {};
635 buffer.render_and_post_update(renderlist, render_fn);
636 });
637
638=== modified file 'examples/render_surfaces.cpp'
639--- examples/render_surfaces.cpp 2014-02-28 13:51:43 +0000
640+++ examples/render_surfaces.cpp 2014-03-17 15:02:33 +0000
641@@ -17,6 +17,7 @@
642 */
643
644 #include "mir/compositor/display_buffer_compositor_factory.h"
645+#include "mir/server_status_listener.h"
646 #include "mir/compositor/display_buffer_compositor.h"
647 #include "mir/options/default_configuration.h"
648 #include "mir/graphics/graphic_buffer_allocator.h"
649@@ -48,8 +49,6 @@
650 #include <sstream>
651 #include <vector>
652
653-#include <glm/gtc/matrix_transform.hpp>
654-
655 namespace mg = mir::graphics;
656 namespace mc = mir::compositor;
657 namespace ms = mir::scene;
658@@ -86,6 +85,7 @@
659
660 namespace
661 {
662+std::atomic<bool> created{false};
663 bool input_is_on = false;
664 std::weak_ptr<mg::Cursor> cursor;
665 static const uint32_t bg_color = 0x00000000;
666@@ -326,6 +326,31 @@
667 }
668 ///\internal [RenderResourcesBufferInitializer_tag]
669
670+ // Unless the compositor starts before we create the surfaces it won't respond to
671+ // the change notification that causes.
672+ std::shared_ptr<mir::ServerStatusListener> the_server_status_listener()
673+ {
674+ struct ServerStatusListener : mir::ServerStatusListener
675+ {
676+ ServerStatusListener(std::function<void()> create_surfaces, std::shared_ptr<mir::ServerStatusListener> wrapped) :
677+ create_surfaces(create_surfaces), wrapped(wrapped) {}
678+
679+ virtual void paused() override { wrapped->paused(); }
680+ virtual void resumed() override { wrapped->resumed(); }
681+ virtual void started() override { wrapped->started(); create_surfaces(); create_surfaces = []{}; }
682+
683+ std::function<void()> create_surfaces;
684+ std::shared_ptr<mir::ServerStatusListener> const wrapped;
685+ };
686+
687+ return server_status_listener(
688+ [this]()
689+ {
690+ auto wrapped = ServerConfiguration::the_server_status_listener();
691+ return std::make_shared<ServerStatusListener>([this] { create_surfaces(); }, wrapped);
692+ });
693+ }
694+
695 ///\internal [RenderSurfacesDisplayBufferCompositor_tag]
696 // Decorate the DefaultDisplayBufferCompositor in order to move surfaces.
697 std::shared_ptr<mc::DisplayBufferCompositorFactory> the_display_buffer_compositor_factory() override
698@@ -342,8 +367,9 @@
699 {
700 }
701
702- void composite()
703+ bool composite()
704 {
705+ while (!created) std::this_thread::yield();
706 animate_cursor();
707 stop_watch.stop();
708 if (stop_watch.elapsed_seconds_since_last_restart() >= 1)
709@@ -360,6 +386,7 @@
710 m.step();
711
712 frames++;
713+ return false;
714 }
715
716 private:
717@@ -459,6 +486,8 @@
718 2.0f * M_PI * cos(i));
719 ++i;
720 }
721+
722+ created = true;
723 }
724
725 bool input_is_on()
726@@ -492,8 +521,6 @@
727
728 mir::run_mir(conf, [&](mir::DisplayServer&)
729 {
730- conf.create_surfaces();
731-
732 cursor = conf.the_cursor();
733
734 input_is_on = conf.input_is_on();
735
736=== modified file 'examples/scroll.cpp'
737--- examples/scroll.cpp 2014-03-04 04:19:26 +0000
738+++ examples/scroll.cpp 2014-03-17 15:02:33 +0000
739@@ -23,46 +23,21 @@
740 #include <signal.h>
741 #include <string.h>
742 #include <stdio.h>
743+#include <stdlib.h>
744 #include <unistd.h>
745 #include <getopt.h>
746 #include <EGL/egl.h>
747 #include <GLES2/gl2.h>
748
749+#include <thread>
750+
751 static char const *socket_file = NULL;
752-
753-int main(int argc, char* argv[])
754+static EGLDisplay disp;
755+
756+
757+void create_and_run_scroll_surface(MirConnection *connection)
758 {
759- MirConnection *connection = 0;
760 MirSurface *surface = 0;
761- int arg;
762- opterr = 0;
763- while ((arg = getopt (argc, argv, "hm:")) != -1)
764- {
765- switch (arg)
766- {
767- case 'm':
768- socket_file = optarg;
769- break;
770-
771- case '?':
772- case 'h':
773- default:
774- puts(argv[0]);
775- puts("Usage:");
776- puts(" -m <Mir server socket>");
777- puts(" -h: this help text");
778- return -1;
779- }
780- }
781-
782- puts("Starting");
783-
784- connection = mir_connect_sync(socket_file, __PRETTY_FUNCTION__);
785- assert(connection != NULL);
786- assert(mir_connection_is_valid(connection));
787- assert(strcmp(mir_connection_get_error_message(connection), "") == 0);
788- puts("Connected");
789-
790 MirPixelFormat pixel_format;
791 unsigned int valid_formats;
792 mir_connection_get_available_surface_formats(connection, &pixel_format, 1, &valid_formats);
793@@ -79,7 +54,6 @@
794
795 /* egl setup */
796 int major, minor, n, rc;
797- EGLDisplay disp;
798 EGLContext context;
799 EGLSurface egl_surface;
800 EGLConfig egl_config;
801@@ -93,13 +67,9 @@
802 EGL_NONE };
803 EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
804
805- EGLNativeDisplayType native_display = (EGLNativeDisplayType) mir_connection_get_egl_native_display(connection);
806 EGLNativeWindowType native_window = (EGLNativeWindowType) mir_surface_get_egl_native_window(surface);
807 assert(native_window != (EGLNativeWindowType)NULL);
808
809- disp = eglGetDisplay(native_display);
810- assert(disp != EGL_NO_DISPLAY);
811-
812 rc = eglInitialize(disp, &major, &minor);
813 assert(rc == EGL_TRUE);
814 assert(major == 1);
815@@ -131,16 +101,67 @@
816
817 eglDestroySurface(disp, egl_surface);
818 eglDestroyContext(disp, context);
819- eglTerminate(disp);
820-
821+
822 mir_surface_release_sync(surface);
823 puts("Surface released");
824+}
825+
826+int main(int argc, char* argv[])
827+{
828+ MirConnection *connection = 0;
829+ unsigned num_windows = 1;
830+ int arg;
831+ opterr = 0;
832+ while ((arg = getopt (argc, argv, "hm:w:")) != -1)
833+ {
834+ switch (arg)
835+ {
836+ case 'm':
837+ socket_file = optarg;
838+ break;
839+ case 'w':
840+ num_windows = atoi(optarg);
841+ break;
842+ case '?':
843+ case 'h':
844+ default:
845+ puts(argv[0]);
846+ puts("Usage:");
847+ puts(" -m <Mir server socket>");
848+ puts(" -w <Number of windows to create>:");
849+ puts(" -h: this help text");
850+ return -1;
851+ }
852+ }
853+
854+ puts("Starting");
855+
856+ connection = mir_connect_sync(socket_file, __PRETTY_FUNCTION__);
857+ assert(connection != NULL);
858+ assert(mir_connection_is_valid(connection));
859+ assert(strcmp(mir_connection_get_error_message(connection), "") == 0);
860+ puts("Connected");
861+
862+ EGLNativeDisplayType native_display = (EGLNativeDisplayType) mir_connection_get_egl_native_display(connection);
863+ disp = eglGetDisplay(native_display);
864+ assert(disp != EGL_NO_DISPLAY);
865+
866+ if (num_windows == 1)
867+ {
868+ create_and_run_scroll_surface(connection);
869+ }
870+ else
871+ {
872+ for (unsigned i = 0; i < num_windows; i++) std::thread(create_and_run_scroll_surface, connection).detach();
873+ for(;;) {}
874+ }
875+
876+
877+ eglTerminate(disp);
878
879 mir_connection_release(connection);
880 puts("Connection released");
881
882- (void)rc;
883-
884 return 0;
885 }
886
887
888=== modified file 'examples/server_configuration.cpp'
889--- examples/server_configuration.cpp 2014-03-05 02:30:30 +0000
890+++ examples/server_configuration.cpp 2014-03-17 15:02:33 +0000
891@@ -56,28 +56,23 @@
892 });
893
894 conf.for_each_output(
895- [&](mg::DisplayConfigurationOutput const& conf_output)
896+ [&](mg::UserDisplayConfigurationOutput& conf_output)
897 {
898 if (conf_output.connected && conf_output.modes.size() > 0 &&
899 available_outputs_for_card[conf_output.card_id] > 0)
900 {
901- conf.configure_output(conf_output.id, true,
902- geom::Point{max_x, 0},
903- preferred_mode_index,
904- conf_output.current_format,
905- mir_power_mode_on,
906- mir_orientation_normal);
907+ conf_output.used = true;
908+ conf_output.top_left = geom::Point{max_x, 0};
909+ conf_output.current_mode_index = preferred_mode_index;
910+ conf_output.power_mode = mir_power_mode_on;
911+ conf_output.orientation = mir_orientation_normal;
912 max_x += conf_output.modes[preferred_mode_index].size.width.as_int();
913 --available_outputs_for_card[conf_output.card_id];
914 }
915 else
916 {
917- conf.configure_output(conf_output.id, false,
918- conf_output.top_left,
919- conf_output.current_mode_index,
920- conf_output.current_format,
921- mir_power_mode_on,
922- mir_orientation_normal);
923+ conf_output.used = false;
924+ conf_output.power_mode = mir_power_mode_off;
925 }
926 });
927 }
928@@ -92,26 +87,20 @@
929 bool done{false};
930
931 conf.for_each_output(
932- [&](mg::DisplayConfigurationOutput const& conf_output)
933+ [&](mg::UserDisplayConfigurationOutput& conf_output)
934 {
935 if (!done && conf_output.connected && conf_output.modes.size() > 0)
936 {
937- conf.configure_output(conf_output.id, true,
938- geom::Point{0, 0},
939- preferred_mode_index,
940- conf_output.current_format,
941- mir_power_mode_on,
942- mir_orientation_normal);
943+ conf_output.used = true;
944+ conf_output.top_left = geom::Point{0, 0};
945+ conf_output.current_mode_index = preferred_mode_index;
946+ conf_output.power_mode = mir_power_mode_on;
947 done = true;
948 }
949 else
950 {
951- conf.configure_output(conf_output.id, false,
952- conf_output.top_left,
953- conf_output.current_mode_index,
954- conf_output.current_format,
955- mir_power_mode_on,
956- mir_orientation_normal);
957+ conf_output.used = false;
958+ conf_output.power_mode = mir_power_mode_off;
959 }
960 });
961 }
962
963=== modified file 'include/platform/mir/graphics/display_configuration.h'
964--- include/platform/mir/graphics/display_configuration.h 2014-03-05 02:30:30 +0000
965+++ include/platform/mir/graphics/display_configuration.h 2014-03-17 15:02:33 +0000
966@@ -114,6 +114,31 @@
967 /** The logical rectangle occupied by the output, based on its position,
968 current mode and orientation (rotation) */
969 geometry::Rectangle extents() const;
970+ bool valid() const;
971+};
972+
973+/**
974+ * Mirror of a DisplayConfigurationOutput, with some fields limited to
975+ * being read-only, preventing users from changing things they shouldn't.
976+ */
977+struct UserDisplayConfigurationOutput
978+{
979+ DisplayConfigurationOutputId const& id;
980+ DisplayConfigurationCardId const& card_id;
981+ DisplayConfigurationOutputType const& type;
982+ std::vector<MirPixelFormat> const& pixel_formats;
983+ std::vector<DisplayConfigurationMode> const& modes;
984+ size_t const& preferred_mode_index;
985+ geometry::Size const& physical_size_mm;
986+ bool const& connected;
987+ bool& used;
988+ geometry::Point& top_left;
989+ size_t& current_mode_index;
990+ MirPixelFormat& current_format;
991+ MirPowerMode& power_mode;
992+ MirOrientation& orientation;
993+
994+ UserDisplayConfigurationOutput(DisplayConfigurationOutput& master);
995 };
996
997 std::ostream& operator<<(std::ostream& out, DisplayConfigurationCard const& val);
998@@ -140,13 +165,8 @@
999 virtual void for_each_card(std::function<void(DisplayConfigurationCard const&)> f) const = 0;
1000 /** Executes a function object for each output in the configuration. */
1001 virtual void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const = 0;
1002-
1003- /** Configures an output. */
1004- virtual void configure_output(DisplayConfigurationOutputId id, bool used,
1005- geometry::Point top_left, size_t mode_index,
1006- MirPixelFormat format,
1007- MirPowerMode power_mode,
1008- MirOrientation orientation) = 0;
1009+ virtual void for_each_output(std::function<void(UserDisplayConfigurationOutput&)> f) = 0;
1010+ virtual bool valid() const;
1011
1012 protected:
1013 DisplayConfiguration() = default;
1014
1015=== renamed file 'src/platform/graphics/mesa/overlapping_output_grouping.h' => 'include/platform/mir/graphics/overlapping_output_grouping.h'
1016--- src/platform/graphics/mesa/overlapping_output_grouping.h 2014-01-22 10:03:11 +0000
1017+++ include/platform/mir/graphics/overlapping_output_grouping.h 2014-03-17 15:02:33 +0000
1018@@ -16,8 +16,8 @@
1019 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
1020 */
1021
1022-#ifndef MIR_GRAPHICS_MESA_OVERLAPPING_OUTPUT_GROUPING_H_
1023-#define MIR_GRAPHICS_MESA_OVERLAPPING_OUTPUT_GROUPING_H_
1024+#ifndef MIR_GRAPHICS_OVERLAPPING_OUTPUT_GROUPING_H_
1025+#define MIR_GRAPHICS_OVERLAPPING_OUTPUT_GROUPING_H_
1026
1027 #include <vector>
1028 #include <functional>
1029@@ -34,9 +34,6 @@
1030 class DisplayConfiguration;
1031 struct DisplayConfigurationOutput;
1032
1033-namespace mesa
1034-{
1035-
1036 class OverlappingOutputGroup
1037 {
1038 public:
1039@@ -67,6 +64,5 @@
1040
1041 }
1042 }
1043-}
1044
1045-#endif /* MIR_GRAPHICS_MESA_OVERLAPPING_OUTPUT_GROUPING_H_ */
1046+#endif /* MIR_GRAPHICS_OVERLAPPING_OUTPUT_GROUPING_H_ */
1047
1048=== modified file 'include/platform/mir/graphics/renderable.h'
1049--- include/platform/mir/graphics/renderable.h 2014-03-04 04:19:26 +0000
1050+++ include/platform/mir/graphics/renderable.h 2014-03-17 15:02:33 +0000
1051@@ -20,6 +20,7 @@
1052 #define MIR_GRAPHICS_RENDERABLE_H_
1053
1054 #include <mir/geometry/rectangle.h>
1055+#include <glm/glm.hpp>
1056 #include <memory>
1057
1058 namespace mir
1059@@ -31,10 +32,47 @@
1060 class Renderable
1061 {
1062 public:
1063- virtual std::shared_ptr<Buffer> buffer() const = 0;
1064+ /**
1065+ * Return the next buffer that should be composited/rendered.
1066+ *
1067+ * \param [in] frameno The frameno parameter is important for
1068+ * multi-monitor platforms. Calls with the same frameno
1069+ * will get the same buffer returned. This ensures that
1070+ * a surface visible on multiple outputs does not get
1071+ * its buffers consumed any faster than the refresh
1072+ * rate of a single monitor. Implementations may ignore
1073+ * the value of frameno on single-monitor platforms
1074+ * only. The caller should always ensure the frameno
1075+ * is different to the previous frame. The exact value
1076+ * of frameno is not important but a large range of
1077+ * values is recommended.
1078+ */
1079+ virtual std::shared_ptr<Buffer> buffer(unsigned long frameno) const = 0;
1080+
1081 virtual bool alpha_enabled() const = 0;
1082 virtual geometry::Rectangle screen_position() const = 0;
1083
1084+ // These are from the old CompositingCriteria. There is a little bit
1085+ // of function overlap with the above functions still.
1086+ virtual float alpha() const = 0;
1087+
1088+ /**
1089+ * Transformation returns the transformation matrix that should be applied
1090+ * to the surface. By default when there are no transformations this will
1091+ * be the identity matrix.
1092+ *
1093+ * \warning As this functionality is presently only used by
1094+ * mir_demo_standalone_render_surfaces for rotations it may be
1095+ * deprecated in future. It is expected that real transformations
1096+ * may become more transient things (e.g. applied by animation
1097+ * logic externally instead of being a semi-permanent attribute of
1098+ * the surface itself).
1099+ */
1100+ virtual glm::mat4 transformation() const = 0;
1101+ virtual bool should_be_rendered_in(geometry::Rectangle const& rect) const = 0;
1102+ virtual bool shaped() const = 0; // meaning the pixel format has alpha
1103+ virtual int buffers_ready_for_compositor() const = 0;
1104+
1105 protected:
1106 Renderable() = default;
1107 virtual ~Renderable() = default;
1108
1109=== modified file 'include/platform/mir/options/configuration.h'
1110--- include/platform/mir/options/configuration.h 2014-02-20 17:59:00 +0000
1111+++ include/platform/mir/options/configuration.h 2014-03-17 15:02:33 +0000
1112@@ -39,7 +39,6 @@
1113 extern char const* const scene_report_opt;
1114 extern char const* const input_report_opt;
1115 extern char const* const host_socket_opt;
1116-extern char const* const standalone_opt;
1117 extern char const* const frontend_threads_opt;
1118
1119 extern char const* const name_opt;
1120
1121=== modified file 'include/server/mir/compositor/buffer_stream.h'
1122--- include/server/mir/compositor/buffer_stream.h 2014-02-10 09:07:48 +0000
1123+++ include/server/mir/compositor/buffer_stream.h 2014-03-17 15:02:33 +0000
1124@@ -1,5 +1,5 @@
1125 /*
1126- * Copyright © 2012 Canonical Ltd.
1127+ * Copyright © 2012-2014 Canonical Ltd.
1128 *
1129 * This program is free software: you can redistribute it and/or modify it
1130 * under the terms of the GNU General Public License version 3,
1131@@ -50,6 +50,7 @@
1132 virtual void resize(geometry::Size const& size) = 0;
1133 virtual void allow_framedropping(bool) = 0;
1134 virtual void force_requests_to_complete() = 0;
1135+ virtual int buffers_ready_for_compositor() const = 0;
1136 };
1137
1138 }
1139
1140=== removed file 'include/server/mir/compositor/compositing_criteria.h'
1141--- include/server/mir/compositor/compositing_criteria.h 2014-03-10 19:28:33 +0000
1142+++ include/server/mir/compositor/compositing_criteria.h 1970-01-01 00:00:00 +0000
1143@@ -1,52 +0,0 @@
1144-/*
1145- * Copyright © 2013 Canonical Ltd.
1146- *
1147- * This program is free software: you can redistribute it and/or modify it
1148- * under the terms of the GNU General Public License version 3,
1149- * as published by the Free Software Foundation.
1150- *
1151- * This program is distributed in the hope that it will be useful,
1152- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1153- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1154- * GNU General Public License for more details.
1155- *
1156- * You should have received a copy of the GNU General Public License
1157- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1158- *
1159- * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
1160- */
1161-
1162-#ifndef MIR_COMPOSITOR_COMPOSITING_CRITERIA_H_
1163-#define MIR_COMPOSITOR_COMPOSITING_CRITERIA_H_
1164-
1165-#include <glm/glm.hpp>
1166-
1167-namespace mir
1168-{
1169-namespace geometry
1170-{
1171-struct Rectangle;
1172-}
1173-namespace compositor
1174-{
1175-
1176-class CompositingCriteria
1177-{
1178-public:
1179- virtual float alpha() const = 0;
1180- virtual glm::mat4 const& transformation() const = 0;
1181- virtual bool should_be_rendered_in(geometry::Rectangle const& rect) const = 0;
1182- virtual bool shaped() const = 0; // meaning the pixel format has alpha
1183-
1184- virtual ~CompositingCriteria() = default;
1185-
1186-protected:
1187- CompositingCriteria() = default;
1188- CompositingCriteria(CompositingCriteria const&) = delete;
1189- CompositingCriteria& operator=(CompositingCriteria const&) = delete;
1190-};
1191-
1192-}
1193-}
1194-
1195-#endif /* MIR_COMPOSITOR_COMPOSITING_CRITERIA_H_ */
1196
1197=== modified file 'include/server/mir/compositor/display_buffer_compositor.h'
1198--- include/server/mir/compositor/display_buffer_compositor.h 2013-08-28 03:41:48 +0000
1199+++ include/server/mir/compositor/display_buffer_compositor.h 2014-03-17 15:02:33 +0000
1200@@ -1,5 +1,5 @@
1201 /*
1202- * Copyright © 2012-2013 Canonical Ltd.
1203+ * Copyright © 2012-2014 Canonical Ltd.
1204 *
1205 * This program is free software: you can redistribute it and/or modify it
1206 * under the terms of the GNU General Public License version 3,
1207@@ -30,7 +30,9 @@
1208 public:
1209 virtual ~DisplayBufferCompositor() = default;
1210
1211- virtual void composite() = 0;
1212+ /// Returns true if there is additional work to do. E.g. a composited surface
1213+ /// has additional buffers ready to composite or during animation
1214+ virtual bool composite() = 0;
1215
1216 protected:
1217 DisplayBufferCompositor() = default;
1218
1219=== renamed file 'src/server/compositor/gl_renderer.h' => 'include/server/mir/compositor/gl_renderer.h'
1220--- src/server/compositor/gl_renderer.h 2014-03-04 04:19:26 +0000
1221+++ include/server/mir/compositor/gl_renderer.h 2014-03-17 15:02:33 +0000
1222@@ -19,11 +19,12 @@
1223 #ifndef MIR_COMPOSITOR_GL_RENDERER_H_
1224 #define MIR_COMPOSITOR_GL_RENDERER_H_
1225
1226-#include "renderer.h"
1227-#include "mir/geometry/rectangle.h"
1228-#include "mir/graphics/buffer_id.h"
1229+#include <mir/compositor/renderer.h>
1230+#include <mir/geometry/rectangle.h>
1231+#include <mir/graphics/buffer_id.h>
1232 #include <GLES2/gl2.h>
1233 #include <unordered_map>
1234+#include <vector>
1235
1236 namespace mir
1237 {
1238@@ -40,27 +41,52 @@
1239 void set_viewport(geometry::Rectangle const& rect) override;
1240 void set_rotation(float degrees) override;
1241 void begin() const override;
1242- void render(CompositingCriteria const& info, graphics::Buffer& buffer) const override;
1243+ void render(graphics::Renderable const& renderable,
1244+ graphics::Buffer& buffer) const override;
1245 void end() const override;
1246
1247 // This is called _without_ a GL context:
1248 void suspend() override;
1249
1250+ struct Vertex
1251+ {
1252+ GLfloat position[3];
1253+ GLfloat texcoord[2];
1254+ };
1255+
1256+ /**
1257+ * tessellate defines the list of triangles that will be used to render
1258+ * the surface. By default it just returns 4 vertices for a rectangle.
1259+ * However you can override its behaviour to tessellate more finely and
1260+ * deform freely for effects like wobbly windows.
1261+ *
1262+ * \returns The mode to be passed to glDrawArrays, e.g. GL_TRIANGLE_STRIP,
1263+ * GL_TRIANGLE_FAN or GL_TRIANGLES.
1264+ *
1265+ * \note The cohesion of this function to GLRenderer is quite loose and it
1266+ * does not strictly need to reside here.
1267+ * However it seems a good choice under GLRenderer while this remains
1268+ * the only OpenGL-specific class in the display server, and
1269+ * tessellation is very much OpenGL-specific.
1270+ */
1271+ virtual GLenum tessellate(graphics::Renderable const& renderable,
1272+ std::vector<Vertex>& vertices) const;
1273+
1274 private:
1275 GLuint vertex_shader;
1276 GLuint fragment_shader;
1277 GLuint program;
1278 GLuint position_attr_loc;
1279 GLuint texcoord_attr_loc;
1280+ GLuint centre_uniform_loc;
1281 GLuint display_transform_uniform_loc;
1282 GLuint transform_uniform_loc;
1283 GLuint alpha_uniform_loc;
1284- GLuint vertex_attribs_vbo;
1285 float rotation;
1286
1287 geometry::Rectangle viewport;
1288
1289- typedef CompositingCriteria const* SurfaceID;
1290+ typedef graphics::Renderable const* SurfaceID;
1291 struct Texture
1292 {
1293 GLuint id = 0;
1294
1295=== renamed file 'src/server/compositor/renderer.h' => 'include/server/mir/compositor/renderer.h'
1296--- src/server/compositor/renderer.h 2014-03-04 04:19:26 +0000
1297+++ include/server/mir/compositor/renderer.h 2014-03-17 15:02:33 +0000
1298@@ -26,10 +26,10 @@
1299 namespace graphics
1300 {
1301 class Buffer;
1302+class Renderable;
1303 }
1304 namespace compositor
1305 {
1306-class CompositingCriteria;
1307
1308 class Renderer
1309 {
1310@@ -39,7 +39,11 @@
1311 virtual void set_viewport(geometry::Rectangle const& rect) = 0;
1312 virtual void set_rotation(float degrees) = 0;
1313 virtual void begin() const = 0;
1314- virtual void render(CompositingCriteria const& info, graphics::Buffer& buffer) const = 0;
1315+
1316+ // XXX The buffer parameter here could now be replaced with a "frameno"
1317+ // instead, and use renderable.buffer(frameno). Is that better?
1318+ virtual void render(graphics::Renderable const& renderable,
1319+ graphics::Buffer& buffer) const = 0;
1320 virtual void end() const = 0;
1321
1322 virtual void suspend() = 0; // called when begin/render/end skipped
1323
1324=== renamed file 'src/server/compositor/renderer_factory.h' => 'include/server/mir/compositor/renderer_factory.h'
1325=== modified file 'include/server/mir/compositor/scene.h'
1326--- include/server/mir/compositor/scene.h 2014-03-04 04:19:26 +0000
1327+++ include/server/mir/compositor/scene.h 2014-03-17 15:02:33 +0000
1328@@ -26,17 +26,16 @@
1329
1330 namespace mir
1331 {
1332+namespace graphics { class Renderable; }
1333 namespace compositor
1334 {
1335-class BufferStream;
1336-class CompositingCriteria;
1337
1338 class FilterForScene
1339 {
1340 public:
1341 virtual ~FilterForScene() {}
1342
1343- virtual bool operator()(CompositingCriteria const&) = 0;
1344+ virtual bool operator()(graphics::Renderable const&) = 0;
1345
1346 protected:
1347 FilterForScene() = default;
1348@@ -49,7 +48,7 @@
1349 public:
1350 virtual ~OperatorForScene() {}
1351
1352- virtual void operator()(CompositingCriteria const&, BufferStream&) = 0;
1353+ virtual void operator()(graphics::Renderable const&) = 0;
1354
1355 protected:
1356 OperatorForScene() = default;
1357
1358=== modified file 'include/server/mir/frontend/screencast.h'
1359--- include/server/mir/frontend/screencast.h 2014-01-30 13:08:32 +0000
1360+++ include/server/mir/frontend/screencast.h 2014-03-17 15:02:33 +0000
1361@@ -39,7 +39,9 @@
1362 virtual ~Screencast() = default;
1363
1364 virtual ScreencastSessionId create_session(
1365- graphics::DisplayConfigurationOutputId output_id) = 0;
1366+ mir::geometry::Rectangle const& region,
1367+ mir::geometry::Size const& size,
1368+ MirPixelFormat pixel_format) = 0;
1369 virtual void destroy_session(ScreencastSessionId id) = 0;
1370 virtual std::shared_ptr<graphics::Buffer> capture(ScreencastSessionId id) = 0;
1371
1372
1373=== modified file 'include/server/mir/shell/session.h'
1374--- include/server/mir/shell/session.h 2014-03-04 04:19:26 +0000
1375+++ include/server/mir/shell/session.h 2014-03-17 15:02:33 +0000
1376@@ -33,7 +33,6 @@
1377 class Session : public frontend::Session
1378 {
1379 public:
1380- virtual std::string name() const = 0;
1381 virtual void force_requests_to_complete() = 0;
1382 virtual pid_t process_id() const = 0;
1383
1384
1385=== modified file 'include/shared/mir_toolkit/client_types.h'
1386--- include/shared/mir_toolkit/client_types.h 2014-02-10 09:07:48 +0000
1387+++ include/shared/mir_toolkit/client_types.h 2014-03-17 15:02:33 +0000
1388@@ -267,15 +267,35 @@
1389 void *context;
1390 } MirEventDelegate;
1391
1392+typedef struct MirRectangle
1393+{
1394+ int left;
1395+ int top;
1396+ unsigned int width;
1397+ unsigned int height;
1398+} MirRectangle;
1399+
1400 /**
1401 * MirScreencastParameters is the structure of required information that
1402 * you must provide to Mir in order to create a MirScreencast.
1403+ * The width and height parameters can be used to down-scale the screencast
1404+ * For no scaling set them to the region width and height.
1405 */
1406 typedef struct MirScreencastParameters
1407 {
1408- uint32_t output_id;
1409- uint32_t width;
1410- uint32_t height;
1411+ /**
1412+ * The rectangular region of the screen to capture -
1413+ * The region is specified in virtual screen space hence multiple screens can be captured simultaneously
1414+ */
1415+ MirRectangle region;
1416+ /** The width of the screencast which can be different than the screen region capture width */
1417+ unsigned int width;
1418+ /** The height of the screencast which can be different than the screen region capture height */
1419+ unsigned int height;
1420+ /**
1421+ * The pixel format of the screencast.
1422+ * It must be a supported format obtained from mir_connection_get_available_surface_formats.
1423+ */
1424 MirPixelFormat pixel_format;
1425 } MirScreencastParameters;
1426
1427
1428=== renamed directory 'include/test/mir_test/draw' => 'include/shared/testdraw'
1429=== modified file 'include/shared/testdraw/draw_pattern_checkered-inl.h'
1430--- include/test/mir_test/draw/draw_pattern_checkered-inl.h 2014-03-04 04:19:26 +0000
1431+++ include/shared/testdraw/draw_pattern_checkered-inl.h 2014-03-17 15:02:33 +0000
1432@@ -2,15 +2,15 @@
1433 * Copyright © 2012 Canonical Ltd.
1434 *
1435 * This program is free software: you can redistribute it and/or modify it
1436- * under the terms of the GNU General Public License version 3,
1437+ * under the terms of the GNU Lesser General Public License version 3,
1438 * as published by the Free Software Foundation.
1439 *
1440 * This program is distributed in the hope that it will be useful,
1441 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1442 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1443- * GNU General Public License for more details.
1444+ * GNU Lesser General Public License for more details.
1445 *
1446- * You should have received a copy of the GNU General Public License
1447+ * You should have received a copy of the GNU Lesser General Public License
1448 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1449 *
1450 * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
1451
1452=== modified file 'include/shared/testdraw/graphics_region_factory.h'
1453--- include/test/mir_test/draw/graphics_region_factory.h 2014-03-04 04:19:26 +0000
1454+++ include/shared/testdraw/graphics_region_factory.h 2014-03-17 15:02:33 +0000
1455@@ -2,15 +2,15 @@
1456 * Copyright © 2012 Canonical Ltd.
1457 *
1458 * This program is free software: you can redistribute it and/or modify it
1459- * under the terms of the GNU General Public License version 3,
1460+ * under the terms of the GNU Lesser General Public License version 3,
1461 * as published by the Free Software Foundation.
1462 *
1463 * This program is distributed in the hope that it will be useful,
1464 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1465 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1466- * GNU General Public License for more details.
1467+ * GNU Lesser General Public License for more details.
1468 *
1469- * You should have received a copy of the GNU General Public License
1470+ * You should have received a copy of the GNU Lesser General Public License
1471 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1472 *
1473 * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
1474@@ -34,7 +34,7 @@
1475 public:
1476 virtual ~GraphicsRegionFactory() {}
1477 virtual std::shared_ptr<MirGraphicsRegion> graphic_region_from_handle(
1478- graphics::NativeBuffer const& native_buffer) = 0;
1479+ graphics::NativeBuffer& native_buffer) = 0;
1480
1481 protected:
1482 GraphicsRegionFactory() = default;
1483
1484=== modified file 'include/shared/testdraw/patterns.h'
1485--- include/test/mir_test/draw/patterns.h 2014-03-04 04:19:26 +0000
1486+++ include/shared/testdraw/patterns.h 2014-03-17 15:02:33 +0000
1487@@ -2,15 +2,15 @@
1488 * Copyright © 2012 Canonical Ltd.
1489 *
1490 * This program is free software: you can redistribute it and/or modify it
1491- * under the terms of the GNU General Public License version 3,
1492+ * under the terms of the GNU Lesser General Public License version 3,
1493 * as published by the Free Software Foundation.
1494 *
1495 * This program is distributed in the hope that it will be useful,
1496 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1497 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1498- * GNU General Public License for more details.
1499+ * GNU Lesser General Public License for more details.
1500 *
1501- * You should have received a copy of the GNU General Public License
1502+ * You should have received a copy of the GNU Lesser General Public License
1503 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1504 *
1505 * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
1506
1507=== renamed file 'include/test/mir_test_doubles/stub_compositing_criteria.h' => 'include/test/mir_test_doubles/fake_renderable.h'
1508--- include/test/mir_test_doubles/stub_compositing_criteria.h 2014-03-04 04:19:26 +0000
1509+++ include/test/mir_test_doubles/fake_renderable.h 2014-03-17 15:02:33 +0000
1510@@ -16,10 +16,11 @@
1511 * Authored by: Daniel van Vugt <daniel.van.vugt@canonical.com>
1512 */
1513
1514-#ifndef MIR_TEST_DOUBLES_STUB_COMPOSITING_CRITERIA_H_
1515-#define MIR_TEST_DOUBLES_STUB_COMPOSITING_CRITERIA_H_
1516+#ifndef MIR_TEST_DOUBLES_FAKE_RENDERABLE_H_
1517+#define MIR_TEST_DOUBLES_FAKE_RENDERABLE_H_
1518
1519-#include "mir/compositor/compositing_criteria.h"
1520+#include "mir/graphics/renderable.h"
1521+#define GLM_FORCE_RADIANS
1522 #include <glm/gtc/matrix_transform.hpp>
1523 #include <gmock/gmock.h>
1524
1525@@ -30,24 +31,20 @@
1526 namespace doubles
1527 {
1528
1529-class StubCompositingCriteria : public compositor::CompositingCriteria
1530+class FakeRenderable : public graphics::Renderable
1531 {
1532 public:
1533- StubCompositingCriteria(int x, int y, int width, int height,
1534- float opacity=1.0f,
1535- bool rectangular=true,
1536- bool visible=true,
1537- bool posted=true)
1538+ FakeRenderable(int x, int y, int width, int height,
1539+ float opacity=1.0f,
1540+ bool rectangular=true,
1541+ bool visible=true,
1542+ bool posted=true)
1543 : rect{{x, y}, {width, height}},
1544 opacity(opacity),
1545 rectangular(rectangular),
1546 visible(visible),
1547 posted(posted)
1548 {
1549- const glm::mat4 ident;
1550- glm::vec3 size(width, height, 0.0f);
1551- glm::vec3 pos(x + width / 2, y + height / 2, 0.0f);
1552- trans = glm::scale( glm::translate(ident, pos), size);
1553 }
1554
1555 float alpha() const override
1556@@ -55,9 +52,9 @@
1557 return opacity;
1558 }
1559
1560- glm::mat4 const& transformation() const override
1561+ glm::mat4 transformation() const override
1562 {
1563- return trans;
1564+ return glm::mat4();
1565 }
1566
1567 bool should_be_rendered_in(const mir::geometry::Rectangle &r) const override
1568@@ -70,9 +67,34 @@
1569 return !rectangular;
1570 }
1571
1572+ void set_buffer(std::shared_ptr<graphics::Buffer> b)
1573+ {
1574+ buf = b;
1575+ }
1576+
1577+ std::shared_ptr<graphics::Buffer> buffer(unsigned long) const override
1578+ {
1579+ return buf;
1580+ }
1581+
1582+ bool alpha_enabled() const override
1583+ {
1584+ return shaped() || alpha() < 1.0f;
1585+ }
1586+
1587+ geometry::Rectangle screen_position() const override
1588+ {
1589+ return rect;
1590+ }
1591+
1592+ int buffers_ready_for_compositor() const override
1593+ {
1594+ return 1;
1595+ }
1596+
1597 private:
1598+ std::shared_ptr<graphics::Buffer> buf;
1599 mir::geometry::Rectangle rect;
1600- glm::mat4 trans;
1601 float opacity;
1602 bool rectangular;
1603 bool visible;
1604@@ -82,4 +104,4 @@
1605 } // namespace doubles
1606 } // namespace test
1607 } // namespace mir
1608-#endif // MIR_TEST_DOUBLES_STUB_COMPOSITING_CRITERIA_H_
1609+#endif // MIR_TEST_DOUBLES_FAKE_RENDERABLE_H_
1610
1611=== modified file 'include/test/mir_test_doubles/mock_android_native_buffer.h'
1612--- include/test/mir_test_doubles/mock_android_native_buffer.h 2014-02-10 09:07:48 +0000
1613+++ include/test/mir_test_doubles/mock_android_native_buffer.h 2014-03-17 15:02:33 +0000
1614@@ -20,6 +20,7 @@
1615 #define MIR_TEST_DOUBLES_MOCK_ANDROID_NATIVE_BUFFER_H_
1616
1617 #include "mir/graphics/android/native_buffer.h"
1618+#include "mir/geometry/size.h"
1619 #include <gmock/gmock.h>
1620
1621 namespace mir
1622@@ -41,6 +42,14 @@
1623 ON_CALL(*this, copy_fence())
1624 .WillByDefault(Return(-1));
1625 }
1626+
1627+ MockAndroidNativeBuffer(geometry::Size sz)
1628+ : MockAndroidNativeBuffer()
1629+ {
1630+ stub_anwb.width = sz.width.as_int();
1631+ stub_anwb.height = sz.height.as_int();
1632+ }
1633+
1634 MOCK_CONST_METHOD0(anwb, ANativeWindowBuffer*());
1635 MOCK_CONST_METHOD0(handle, buffer_handle_t());
1636 MOCK_CONST_METHOD0(copy_fence, graphics::android::NativeFence());
1637
1638=== modified file 'include/test/mir_test_doubles/mock_buffer_bundle.h'
1639--- include/test/mir_test_doubles/mock_buffer_bundle.h 2014-02-10 09:07:48 +0000
1640+++ include/test/mir_test_doubles/mock_buffer_bundle.h 2014-03-17 15:02:33 +0000
1641@@ -48,6 +48,7 @@
1642 MOCK_METHOD0(force_client_abort, void());
1643 MOCK_METHOD0(force_requests_to_complete, void());
1644 MOCK_METHOD1(resize, void(const geometry::Size &));
1645+ int buffers_ready_for_compositor() const override { return 1; }
1646 };
1647
1648 }
1649
1650=== modified file 'include/test/mir_test_doubles/mock_buffer_stream.h'
1651--- include/test/mir_test_doubles/mock_buffer_stream.h 2014-02-10 09:07:48 +0000
1652+++ include/test/mir_test_doubles/mock_buffer_stream.h 2014-03-17 15:02:33 +0000
1653@@ -42,6 +42,7 @@
1654 MOCK_METHOD0(force_client_completion, void());
1655 MOCK_METHOD1(allow_framedropping, void(bool));
1656 MOCK_METHOD0(force_requests_to_complete, void());
1657+ int buffers_ready_for_compositor() const override { return 1; }
1658 };
1659 }
1660 }
1661
1662=== removed file 'include/test/mir_test_doubles/mock_compositing_criteria.h'
1663--- include/test/mir_test_doubles/mock_compositing_criteria.h 2014-03-10 19:28:33 +0000
1664+++ include/test/mir_test_doubles/mock_compositing_criteria.h 1970-01-01 00:00:00 +0000
1665@@ -1,45 +0,0 @@
1666-/*
1667- * Copyright © 2013 Canonical Ltd.
1668- *
1669- * This program is free software: you can redistribute it and/or modify it
1670- * under the terms of the GNU General Public License version 3,
1671- * as published by the Free Software Foundation.
1672- *
1673- * This program is distributed in the hope that it will be useful,
1674- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1675- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1676- * GNU General Public License for more details.
1677- *
1678- * You should have received a copy of the GNU General Public License
1679- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1680- *
1681- * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
1682- */
1683-
1684-#ifndef MIR_TEST_DOUBLES_MOCK_COMPOSITING_CRITERIA_H_
1685-#define MIR_TEST_DOUBLES_MOCK_COMPOSITING_CRITERIA_H_
1686-
1687-#include "mir/compositor/compositing_criteria.h"
1688-#include <gmock/gmock.h>
1689-
1690-namespace mir
1691-{
1692-namespace test
1693-{
1694-namespace doubles
1695-{
1696-
1697-class MockCompositingCriteria : public compositor::CompositingCriteria
1698-{
1699-public:
1700- ~MockCompositingCriteria() noexcept {}
1701- MOCK_CONST_METHOD0(alpha, float());
1702- MOCK_CONST_METHOD0(transformation, glm::mat4 const&());
1703- MOCK_CONST_METHOD1(should_be_rendered_in, bool(geometry::Rectangle const&));
1704- MOCK_CONST_METHOD0(shaped, bool());
1705-};
1706-
1707-}
1708-}
1709-}
1710-#endif /* MIR_TEST_DOUBLES_MOCK_COMPOSITING_CRITERIA_H_ */
1711
1712=== modified file 'include/test/mir_test_doubles/mock_display_device.h'
1713--- include/test/mir_test_doubles/mock_display_device.h 2014-02-28 13:51:43 +0000
1714+++ include/test/mir_test_doubles/mock_display_device.h 2014-03-17 15:02:33 +0000
1715@@ -21,6 +21,7 @@
1716
1717 #include "mir/graphics/buffer.h"
1718 #include "src/platform/graphics/android/display_device.h"
1719+#include "src/platform/graphics/android/gl_context.h"
1720 #include <gmock/gmock.h>
1721
1722 namespace mir
1723@@ -34,9 +35,11 @@
1724 public:
1725 ~MockDisplayDevice() noexcept {}
1726 MOCK_METHOD1(mode, void(MirPowerMode));
1727- MOCK_METHOD0(prepare_gl, void());
1728- MOCK_METHOD1(prepare_gl_and_overlays, void(std::list<std::shared_ptr<graphics::Renderable>> const&));
1729- MOCK_METHOD2(gpu_render, void(EGLDisplay, EGLSurface));
1730+ MOCK_METHOD1(render_gl, void(graphics::android::SwappingGLContext const&));
1731+ MOCK_METHOD3(render_gl_and_overlays, void(
1732+ graphics::android::SwappingGLContext const&,
1733+ std::list<std::shared_ptr<graphics::Renderable>> const&,
1734+ std::function<void(graphics::Renderable const&)> const&));
1735 MOCK_METHOD1(post, void(graphics::Buffer const&));
1736 MOCK_CONST_METHOD1(apply_orientation, bool(MirOrientation));
1737 };
1738
1739=== modified file 'include/test/mir_test_doubles/mock_gl.h'
1740--- include/test/mir_test_doubles/mock_gl.h 2014-02-10 09:07:48 +0000
1741+++ include/test/mir_test_doubles/mock_gl.h 2014-03-17 15:02:33 +0000
1742@@ -61,6 +61,7 @@
1743 MOCK_METHOD3(glDrawArrays, void(GLenum, GLint, GLsizei));
1744 MOCK_METHOD1(glEnable, void(GLenum));
1745 MOCK_METHOD1(glEnableVertexAttribArray, void(GLuint));
1746+ MOCK_METHOD0(glFinish, void());
1747 MOCK_METHOD4(glFramebufferRenderbuffer,
1748 void(GLenum, GLenum, GLenum, GLuint));
1749 MOCK_METHOD5(glFramebufferTexture2D,
1750@@ -92,7 +93,8 @@
1751 void(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum,
1752 GLenum,const GLvoid*));
1753 MOCK_METHOD3(glTexParameteri, void(GLenum, GLenum, GLenum));
1754- MOCK_METHOD2(glUniform1f, void(GLuint, GLfloat));
1755+ MOCK_METHOD2(glUniform1f, void(GLint, GLfloat));
1756+ MOCK_METHOD3(glUniform2f, void(GLint, GLfloat, GLfloat));
1757 MOCK_METHOD2(glUniform1i, void(GLint, GLint));
1758 MOCK_METHOD4(glUniformMatrix4fv,
1759 void(GLuint, GLsizei, GLboolean, const GLfloat *));
1760@@ -101,7 +103,6 @@
1761 void(GLuint, GLint, GLenum, GLboolean, GLsizei,
1762 const GLvoid *));
1763 MOCK_METHOD4(glViewport, void(GLint, GLint, GLsizei, GLsizei));
1764- MOCK_METHOD0(glFinish, void());
1765 };
1766
1767 }
1768
1769=== added file 'include/test/mir_test_doubles/mock_render_function.h'
1770--- include/test/mir_test_doubles/mock_render_function.h 1970-01-01 00:00:00 +0000
1771+++ include/test/mir_test_doubles/mock_render_function.h 2014-03-17 15:02:33 +0000
1772@@ -0,0 +1,40 @@
1773+/*
1774+ * Copyright © 2014 Canonical Ltd.
1775+ *
1776+ * This program is free software: you can redistribute it and/or modify it
1777+ * under the terms of the GNU General Public License version 3,
1778+ * as published by the Free Software Foundation.
1779+ *
1780+ * This program is distributed in the hope that it will be useful,
1781+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1782+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1783+ * GNU General Public License for more details.
1784+ *
1785+ * You should have received a copy of the GNU General Public License
1786+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1787+ *
1788+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
1789+ */
1790+
1791+#ifndef MIR_TEST_DOUBLES_MOCK_RENDER_FUNCTION_H_
1792+#define MIR_TEST_DOUBLES_MOCK_RENDER_FUNCTION_H_
1793+
1794+#include <mir/graphics/renderable.h>
1795+
1796+namespace mir
1797+{
1798+namespace test
1799+{
1800+namespace doubles
1801+{
1802+
1803+struct MockRenderFunction
1804+{
1805+ MOCK_METHOD1(called, void(graphics::Renderable const&));
1806+};
1807+
1808+}
1809+}
1810+}
1811+
1812+#endif /* MIR_TEST_DOUBLES_MOCK_RENDER_FUNCTION_H_ */
1813
1814=== added file 'include/test/mir_test_doubles/mock_render_function.h.moved'
1815--- include/test/mir_test_doubles/mock_render_function.h.moved 1970-01-01 00:00:00 +0000
1816+++ include/test/mir_test_doubles/mock_render_function.h.moved 2014-03-17 15:02:33 +0000
1817@@ -0,0 +1,40 @@
1818+/*
1819+ * Copyright © 2014 Canonical Ltd.
1820+ *
1821+ * This program is free software: you can redistribute it and/or modify it
1822+ * under the terms of the GNU General Public License version 3,
1823+ * as published by the Free Software Foundation.
1824+ *
1825+ * This program is distributed in the hope that it will be useful,
1826+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1827+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1828+ * GNU General Public License for more details.
1829+ *
1830+ * You should have received a copy of the GNU General Public License
1831+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1832+ *
1833+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
1834+ */
1835+
1836+#ifndef MIR_TEST_DOUBLES_MOCK_RENDER_FUNCTION_H_
1837+#define MIR_TEST_DOUBLES_MOCK_RENDER_FUNCTION_H_
1838+
1839+#include <mir/graphics/renderable.h>
1840+
1841+namespace mir
1842+{
1843+namespace test
1844+{
1845+namespace doubles
1846+{
1847+
1848+struct MockRenderFunction
1849+{
1850+ MOCK_METHOD1(called, void(graphics::Renderable const&));
1851+};
1852+
1853+}
1854+}
1855+}
1856+
1857+#endif /* MIR_TEST_DOUBLES_MOCK_RENDER_FUNCTION_H_ */
1858
1859=== modified file 'include/test/mir_test_doubles/mock_renderable.h'
1860--- include/test/mir_test_doubles/mock_renderable.h 2014-03-04 04:19:26 +0000
1861+++ include/test/mir_test_doubles/mock_renderable.h 2014-03-17 15:02:33 +0000
1862@@ -19,6 +19,7 @@
1863 #ifndef MIR_TEST_DOUBLES_MOCK_RENDERABLE_H_
1864 #define MIR_TEST_DOUBLES_MOCK_RENDERABLE_H_
1865
1866+#include "mir_test_doubles/stub_buffer.h"
1867 #include <mir/graphics/renderable.h>
1868 #include <gmock/gmock.h>
1869
1870@@ -30,9 +31,21 @@
1871 {
1872 struct MockRenderable : public graphics::Renderable
1873 {
1874- MOCK_CONST_METHOD0(buffer, std::shared_ptr<graphics::Buffer>());
1875+ MockRenderable()
1876+ {
1877+ ON_CALL(*this, screen_position())
1878+ .WillByDefault(testing::Return(geometry::Rectangle{{},{}}));
1879+ ON_CALL(*this, buffer(testing::_))
1880+ .WillByDefault(testing::Return(std::make_shared<StubBuffer>()));
1881+ }
1882+ MOCK_CONST_METHOD1(buffer, std::shared_ptr<graphics::Buffer>(unsigned long));
1883 MOCK_CONST_METHOD0(alpha_enabled, bool());
1884 MOCK_CONST_METHOD0(screen_position, geometry::Rectangle());
1885+ MOCK_CONST_METHOD0(alpha, float());
1886+ MOCK_CONST_METHOD0(transformation, glm::mat4());
1887+ MOCK_CONST_METHOD1(should_be_rendered_in, bool(geometry::Rectangle const& rect));
1888+ MOCK_CONST_METHOD0(shaped, bool());
1889+ int buffers_ready_for_compositor() const override { return 1; }
1890 };
1891 }
1892 }
1893
1894=== modified file 'include/test/mir_test_doubles/mock_renderer.h'
1895--- include/test/mir_test_doubles/mock_renderer.h 2014-03-04 04:19:26 +0000
1896+++ include/test/mir_test_doubles/mock_renderer.h 2014-03-17 15:02:33 +0000
1897@@ -18,7 +18,7 @@
1898 #ifndef MIR_TEST_DOUBLES_MOCK_RENDERER_H_
1899 #define MIR_TEST_DOUBLES_MOCK_RENDERER_H_
1900
1901-#include "src/server/compositor/renderer.h"
1902+#include "mir/compositor/renderer.h"
1903
1904 #include <gmock/gmock.h>
1905
1906@@ -34,7 +34,7 @@
1907 MOCK_METHOD1(set_viewport, void(geometry::Rectangle const&));
1908 MOCK_METHOD1(set_rotation, void(float));
1909 MOCK_CONST_METHOD0(begin, void());
1910- MOCK_CONST_METHOD2(render, void(compositor::CompositingCriteria const&, graphics::Buffer&));
1911+ MOCK_CONST_METHOD2(render, void(graphics::Renderable const&, graphics::Buffer&));
1912 MOCK_CONST_METHOD0(end, void());
1913 MOCK_METHOD0(suspend, void());
1914
1915
1916=== added file 'include/test/mir_test_doubles/mock_scene.h'
1917--- include/test/mir_test_doubles/mock_scene.h 1970-01-01 00:00:00 +0000
1918+++ include/test/mir_test_doubles/mock_scene.h 2014-03-17 15:02:33 +0000
1919@@ -0,0 +1,48 @@
1920+/*
1921+ * Copyright © 2014 Canonical Ltd.
1922+ *
1923+ * This program is free software: you can redistribute it and/or modify it
1924+ * under the terms of the GNU General Public License version 3,
1925+ * as published by the Free Software Foundation.
1926+ *
1927+ * This program is distributed in the hope that it will be useful,
1928+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1929+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1930+ * GNU General Public License for more details.
1931+ *
1932+ * You should have received a copy of the GNU General Public License
1933+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1934+ *
1935+ * Authored by: Daniel van Vugt <daniel.van.vugt@canonical.com>
1936+ */
1937+
1938+#ifndef MIR_TEST_DOUBLES_MOCK_SCENE_H_
1939+#define MIR_TEST_DOUBLES_MOCK_SCENE_H_
1940+
1941+#include "mir/compositor/scene.h"
1942+#include <gmock/gmock.h>
1943+
1944+namespace mir
1945+{
1946+namespace test
1947+{
1948+namespace doubles
1949+{
1950+
1951+class MockScene : public compositor::Scene
1952+{
1953+public:
1954+ MOCK_METHOD2(for_each_if, void(compositor::FilterForScene&,
1955+ compositor::OperatorForScene&));
1956+ MOCK_METHOD2(reverse_for_each_if, void(compositor::FilterForScene&,
1957+ compositor::OperatorForScene&));
1958+ MOCK_METHOD1(set_change_callback, void(std::function<void()> const&));
1959+ MOCK_METHOD0(lock, void());
1960+ MOCK_METHOD0(unlock, void());
1961+};
1962+
1963+} // namespace doubles
1964+} // namespace test
1965+} // namespace mir
1966+
1967+#endif /* MIR_TEST_DOUBLES_MOCK_SCENE_H_ */
1968
1969=== modified file 'include/test/mir_test_doubles/mock_screencast.h'
1970--- include/test/mir_test_doubles/mock_screencast.h 2014-01-29 18:02:33 +0000
1971+++ include/test/mir_test_doubles/mock_screencast.h 2014-03-17 15:02:33 +0000
1972@@ -33,9 +33,11 @@
1973 class MockScreencast : public frontend::Screencast
1974 {
1975 public:
1976- MOCK_METHOD1(create_session,
1977+ MOCK_METHOD3(create_session,
1978 frontend::ScreencastSessionId(
1979- graphics::DisplayConfigurationOutputId));
1980+ geometry::Rectangle const&,
1981+ geometry::Size const&,
1982+ MirPixelFormat));
1983 MOCK_METHOD1(destroy_session, void(frontend::ScreencastSessionId));
1984 MOCK_METHOD1(capture,
1985 std::shared_ptr<graphics::Buffer>(
1986
1987=== added file 'include/test/mir_test_doubles/mock_swapping_gl_context.h'
1988--- include/test/mir_test_doubles/mock_swapping_gl_context.h 1970-01-01 00:00:00 +0000
1989+++ include/test/mir_test_doubles/mock_swapping_gl_context.h 2014-03-17 15:02:33 +0000
1990@@ -0,0 +1,39 @@
1991+/*
1992+ * Copyright © 2014 Canonical Ltd.
1993+ *
1994+ * This program is free software: you can redistribute it and/or modify it
1995+ * under the terms of the GNU General Public License version 3,
1996+ * as published by the Free Software Foundation.
1997+ *
1998+ * This program is distributed in the hope that it will be useful,
1999+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2000+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2001+ * GNU General Public License for more details.
2002+ *
2003+ * You should have received a copy of the GNU General Public License
2004+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2005+ *
2006+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
2007+ */
2008+
2009+#ifndef MIR_TEST_DOUBLES_MOCK_SWAPPING_GL_CONTEXT_H_
2010+#define MIR_TEST_DOUBLES_MOCK_SWAPPING_GL_CONTEXT_H_
2011+
2012+#include "src/platform/graphics/android/gl_context.h"
2013+
2014+namespace mir
2015+{
2016+namespace test
2017+{
2018+namespace doubles
2019+{
2020+
2021+struct MockSwappingGLContext : public graphics::android::SwappingGLContext
2022+{
2023+ MOCK_CONST_METHOD0(swap_buffers, void());
2024+};
2025+
2026+}
2027+}
2028+}
2029+#endif // MIR_TEST_DOUBLES_MOCK_COMPOSITING_CRITERIA_H_
2030
2031=== modified file 'include/test/mir_test_doubles/null_display_configuration.h'
2032--- include/test/mir_test_doubles/null_display_configuration.h 2014-03-05 02:30:30 +0000
2033+++ include/test/mir_test_doubles/null_display_configuration.h 2014-03-17 15:02:33 +0000
2034@@ -35,7 +35,7 @@
2035 void for_each_output(std::function<void(graphics::DisplayConfigurationOutput const&)>) const override
2036 {
2037 }
2038- void configure_output(graphics::DisplayConfigurationOutputId, bool, geometry::Point, size_t, MirPixelFormat, MirPowerMode, MirOrientation) override
2039+ void for_each_output(std::function<void(graphics::UserDisplayConfigurationOutput&)>) override
2040 {
2041 }
2042 };
2043
2044=== modified file 'include/test/mir_test_doubles/null_screencast.h'
2045--- include/test/mir_test_doubles/null_screencast.h 2014-01-29 18:02:33 +0000
2046+++ include/test/mir_test_doubles/null_screencast.h 2014-03-17 15:02:33 +0000
2047@@ -32,7 +32,9 @@
2048 {
2049 public:
2050 frontend::ScreencastSessionId create_session(
2051- graphics::DisplayConfigurationOutputId)
2052+ geometry::Rectangle const&,
2053+ geometry::Size const&,
2054+ MirPixelFormat)
2055 {
2056 return frontend::ScreencastSessionId{1};
2057 }
2058
2059=== modified file 'include/test/mir_test_doubles/stub_buffer.h'
2060--- include/test/mir_test_doubles/stub_buffer.h 2014-03-04 04:19:26 +0000
2061+++ include/test/mir_test_doubles/stub_buffer.h 2014-03-17 15:02:33 +0000
2062@@ -39,20 +39,31 @@
2063 {
2064 public:
2065 StubBuffer()
2066- : buf_size{0, 0},
2067- buf_pixel_format{mir_pixel_format_abgr_8888}
2068+ : StubBuffer{
2069+ graphics::BufferProperties{
2070+ geometry::Size{},
2071+ mir_pixel_format_abgr_8888,
2072+ graphics::BufferUsage::hardware}}
2073+
2074 {
2075 }
2076
2077 StubBuffer(graphics::BufferProperties const& properties)
2078+ : StubBuffer{properties, geometry::Stride{}}
2079+ {
2080+ }
2081+
2082+ StubBuffer(graphics::BufferProperties const& properties,
2083+ geometry::Stride stride)
2084 : buf_size{properties.size},
2085- buf_pixel_format{properties.format}
2086+ buf_pixel_format{properties.format},
2087+ buf_stride{stride}
2088 {
2089 }
2090
2091 virtual geometry::Size size() const { return buf_size; }
2092
2093- virtual geometry::Stride stride() const { return geometry::Stride(); }
2094+ virtual geometry::Stride stride() const { return buf_stride; }
2095
2096 virtual MirPixelFormat pixel_format() const { return buf_pixel_format; }
2097
2098@@ -70,6 +81,7 @@
2099
2100 geometry::Size const buf_size;
2101 MirPixelFormat const buf_pixel_format;
2102+ geometry::Stride const buf_stride;
2103 };
2104 }
2105 }
2106
2107=== modified file 'include/test/mir_test_doubles/stub_buffer_stream.h'
2108--- include/test/mir_test_doubles/stub_buffer_stream.h 2014-02-10 09:07:48 +0000
2109+++ include/test/mir_test_doubles/stub_buffer_stream.h 2014-03-17 15:02:33 +0000
2110@@ -72,6 +72,8 @@
2111 {
2112 }
2113
2114+ int buffers_ready_for_compositor() const override { return 1; }
2115+
2116 StubBuffer stub_client_buffer;
2117 std::shared_ptr<graphics::Buffer> stub_compositor_buffer;
2118 };
2119
2120=== modified file 'include/test/mir_test_doubles/stub_display_configuration.h'
2121--- include/test/mir_test_doubles/stub_display_configuration.h 2014-03-05 02:30:30 +0000
2122+++ include/test/mir_test_doubles/stub_display_configuration.h 2014-03-17 15:02:33 +0000
2123@@ -156,8 +156,13 @@
2124 }
2125 }
2126
2127- void configure_output(graphics::DisplayConfigurationOutputId, bool, geometry::Point, size_t, MirPixelFormat, MirPowerMode, MirOrientation) override
2128+ void for_each_output(std::function<void(graphics::UserDisplayConfigurationOutput&)> f) override
2129 {
2130+ for (auto& disp : outputs)
2131+ {
2132+ graphics::UserDisplayConfigurationOutput user(disp);
2133+ f(user);
2134+ }
2135 }
2136
2137 std::vector<graphics::DisplayConfigurationCard> cards;
2138
2139=== modified file 'include/test/mir_test_doubles/stub_display_device.h'
2140--- include/test/mir_test_doubles/stub_display_device.h 2014-02-11 03:04:50 +0000
2141+++ include/test/mir_test_doubles/stub_display_device.h 2014-03-17 15:02:33 +0000
2142@@ -38,10 +38,13 @@
2143 void mode(MirPowerMode)
2144 {
2145 }
2146- void prepare_gl_and_overlays(std::list<std::shared_ptr<graphics::Renderable>> const&)
2147+ void render_gl_and_overlays(
2148+ graphics::android::SwappingGLContext const&,
2149+ std::list<std::shared_ptr<graphics::Renderable>> const&,
2150+ std::function<void(graphics::Renderable const&)> const&)
2151 {
2152 }
2153- void prepare_gl()
2154+ void render_gl(graphics::android::SwappingGLContext const&)
2155 {
2156 }
2157 void gpu_render(EGLDisplay, EGLSurface)
2158
2159=== modified file 'include/test/mir_test_doubles/stub_renderable.h'
2160--- include/test/mir_test_doubles/stub_renderable.h 2014-03-04 04:19:26 +0000
2161+++ include/test/mir_test_doubles/stub_renderable.h 2014-03-17 15:02:33 +0000
2162@@ -19,6 +19,7 @@
2163 #ifndef MIR_TEST_DOUBLES_STUB_RENDERABLE_H_
2164 #define MIR_TEST_DOUBLES_STUB_RENDERABLE_H_
2165
2166+#include "mir_test_doubles/stub_buffer.h"
2167 #include <mir/graphics/renderable.h>
2168 #include <memory>
2169
2170@@ -32,9 +33,9 @@
2171 class StubRenderable : public graphics::Renderable
2172 {
2173 public:
2174- std::shared_ptr<graphics::Buffer> buffer() const
2175+ std::shared_ptr<graphics::Buffer> buffer(unsigned long) const override
2176 {
2177- return {};
2178+ return std::make_shared<StubBuffer>();
2179 }
2180 bool alpha_enabled() const
2181 {
2182@@ -44,6 +45,30 @@
2183 {
2184 return {{},{}};
2185 }
2186+ float alpha() const override
2187+ {
2188+ return 1.0f;
2189+ }
2190+ glm::mat4 transformation() const override
2191+ {
2192+ return trans;
2193+ }
2194+ bool should_be_rendered_in(geometry::Rectangle const&) const override
2195+ {
2196+ return true;
2197+ }
2198+ bool shaped() const override
2199+ {
2200+ return false;
2201+ }
2202+
2203+ int buffers_ready_for_compositor() const override
2204+ {
2205+ return 1;
2206+ }
2207+
2208+private:
2209+ glm::mat4 trans;
2210 };
2211
2212 }
2213
2214=== modified file 'include/test/mir_test_doubles/stub_renderer.h'
2215--- include/test/mir_test_doubles/stub_renderer.h 2014-03-04 04:19:26 +0000
2216+++ include/test/mir_test_doubles/stub_renderer.h 2014-03-17 15:02:33 +0000
2217@@ -19,7 +19,7 @@
2218 #ifndef MIR_TEST_DOUBLES_STUB_RENDERER_H_
2219 #define MIR_TEST_DOUBLES_STUB_RENDERER_H_
2220
2221-#include "src/server/compositor/renderer.h"
2222+#include "mir/compositor/renderer.h"
2223
2224 namespace mir
2225 {
2226@@ -43,7 +43,7 @@
2227 {
2228 }
2229
2230- void render(compositor::CompositingCriteria const&,
2231+ void render(graphics::Renderable const&,
2232 graphics::Buffer&) const override
2233 {
2234 }
2235
2236=== added file 'include/test/mir_test_doubles/stub_swapping_gl_context.h'
2237--- include/test/mir_test_doubles/stub_swapping_gl_context.h 1970-01-01 00:00:00 +0000
2238+++ include/test/mir_test_doubles/stub_swapping_gl_context.h 2014-03-17 15:02:33 +0000
2239@@ -0,0 +1,39 @@
2240+/*
2241+ * Copyright © 2014 Canonical Ltd.
2242+ *
2243+ * This program is free software: you can redistribute it and/or modify it
2244+ * under the terms of the GNU General Public License version 3,
2245+ * as published by the Free Software Foundation.
2246+ *
2247+ * This program is distributed in the hope that it will be useful,
2248+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2249+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2250+ * GNU General Public License for more details.
2251+ *
2252+ * You should have received a copy of the GNU General Public License
2253+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2254+ *
2255+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
2256+ */
2257+
2258+#ifndef MIR_TEST_DOUBLES_STUB_SWAPPING_GL_CONTEXT_H_
2259+#define MIR_TEST_DOUBLES_STUB_SWAPPING_GL_CONTEXT_H_
2260+
2261+#include "src/platform/graphics/android/gl_context.h"
2262+
2263+namespace mir
2264+{
2265+namespace test
2266+{
2267+namespace doubles
2268+{
2269+
2270+struct StubSwappingGLContext : public graphics::android::SwappingGLContext
2271+{
2272+ void swap_buffers() const {}
2273+};
2274+
2275+}
2276+}
2277+}
2278+#endif // MIR_TEST_DOUBLES_STUB_COMPOSITING_CRITERIA_H_
2279
2280=== modified file 'src/client/CMakeLists.txt'
2281--- src/client/CMakeLists.txt 2014-02-28 13:51:43 +0000
2282+++ src/client/CMakeLists.txt 2014-03-17 15:02:33 +0000
2283@@ -72,6 +72,7 @@
2284 mirsharedinput
2285 mirsharedlogging
2286 mirsharedenv
2287+ mirsharedgeometry
2288 mirsharedsharedlibrary
2289 mirclientrpc
2290 mirclientlttngstatic
2291
2292=== modified file 'src/client/android/CMakeLists.txt'
2293--- src/client/android/CMakeLists.txt 2014-02-28 13:51:43 +0000
2294+++ src/client/android/CMakeLists.txt 2014-03-17 15:02:33 +0000
2295@@ -26,6 +26,8 @@
2296 ${LIBHARDWARE_LIBRARIES}
2297 )
2298
2299+install(TARGETS mirclientplatformandroid LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mir/clientplatform/android)
2300+
2301 if (MIR_TEST_PLATFORM STREQUAL "android")
2302 add_custom_command(TARGET mirclientplatformandroid
2303 POST_BUILD
2304@@ -33,6 +35,11 @@
2305 COMMAND ${CMAKE_COMMAND} -E create_symlink android/$<TARGET_FILE_NAME:mirclientplatformandroid> libmirclientplatform.so
2306 WORKING_DIRECTORY ${LIBRARY_OUTPUT_PATH}
2307 )
2308+
2309+ install(CODE
2310+ "execute_process(
2311+ COMMAND ln -sf mir/clientplatform/android/libmirclientplatform.so
2312+ WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}
2313+ )"
2314+ )
2315 endif()
2316-
2317-install(TARGETS mirclientplatformandroid LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mir/clientplatform/android)
2318
2319=== modified file 'src/client/mesa/CMakeLists.txt'
2320--- src/client/mesa/CMakeLists.txt 2014-02-28 13:51:43 +0000
2321+++ src/client/mesa/CMakeLists.txt 2014-03-17 15:02:33 +0000
2322@@ -27,6 +27,8 @@
2323 ${DRM_LDFLAGS} ${DRM_LIBRARIES}
2324 )
2325
2326+install(TARGETS mirclientplatformmesa LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mir/clientplatform/mesa)
2327+
2328 if (MIR_TEST_PLATFORM STREQUAL "mesa")
2329 add_custom_command(TARGET mirclientplatformmesa
2330 POST_BUILD
2331@@ -34,7 +36,12 @@
2332 COMMAND ${CMAKE_COMMAND} -E create_symlink mesa/$<TARGET_FILE_NAME:mirclientplatformmesa> libmirclientplatform.so
2333 WORKING_DIRECTORY ${LIBRARY_OUTPUT_PATH}
2334 )
2335+
2336+ install(CODE
2337+ "execute_process(
2338+ COMMAND ln -sf mir/clientplatform/mesa/libmirclientplatform.so
2339+ WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}
2340+ )"
2341+ )
2342 endif()
2343
2344-install(TARGETS mirclientplatformmesa LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mir/clientplatform/mesa)
2345-
2346
2347=== modified file 'src/client/mir_screencast.cpp'
2348--- src/client/mir_screencast.cpp 2014-02-10 09:07:48 +0000
2349+++ src/client/mir_screencast.cpp 2014-03-17 15:02:33 +0000
2350@@ -31,23 +31,6 @@
2351
2352 void null_callback(MirScreencast*, void*) {}
2353
2354-geom::Size mir_output_get_size(MirDisplayOutput const& output)
2355-{
2356- if (output.connected && output.used &&
2357- output.current_mode < output.num_modes)
2358- {
2359- auto& current_mode = output.modes[output.current_mode];
2360- return geom::Size{current_mode.horizontal_resolution,
2361- current_mode.vertical_resolution};
2362- }
2363- else
2364- {
2365- BOOST_THROW_EXCEPTION(
2366- std::runtime_error("Couldn't get size from invalid output"));
2367- }
2368-}
2369-
2370-
2371 void populate_buffer_package(
2372 MirBufferPackage& buffer_package,
2373 mir::protobuf::Buffer const& protobuf_buffer)
2374@@ -86,24 +69,38 @@
2375 }
2376
2377 MirScreencast::MirScreencast(
2378- MirDisplayOutput const& output,
2379+ geom::Rectangle const& region,
2380+ geom::Size const& size,
2381+ MirPixelFormat pixel_format,
2382 mir::protobuf::DisplayServer& server,
2383 std::shared_ptr<mcl::EGLNativeWindowFactory> const& egl_native_window_factory,
2384 std::shared_ptr<mcl::ClientBufferFactory> const& factory,
2385 mir_screencast_callback callback, void* context)
2386 : server(server),
2387- output_id{output.output_id},
2388- output_size{mir_output_get_size(output)},
2389- output_format{output.current_format},
2390+ output_size{size},
2391+ output_format{pixel_format},
2392 egl_native_window_factory{egl_native_window_factory},
2393 buffer_depository{factory, mir::frontend::client_buffer_cache_size}
2394 {
2395+ if (output_size.width.as_int() == 0 ||
2396+ output_size.height.as_int() == 0 ||
2397+ region.size.width.as_int() == 0 ||
2398+ region.size.height.as_int() == 0 ||
2399+ pixel_format == mir_pixel_format_invalid)
2400+ {
2401+ BOOST_THROW_EXCEPTION(std::runtime_error("Invalid parameters"));
2402+ }
2403 protobuf_screencast.set_error("Not initialized");
2404
2405 mir::protobuf::ScreencastParameters parameters;
2406- parameters.set_output_id(output_id);
2407+
2408+ parameters.mutable_region()->set_left(region.top_left.x.as_int());
2409+ parameters.mutable_region()->set_top(region.top_left.y.as_int());
2410+ parameters.mutable_region()->set_width(region.size.width.as_uint32_t());
2411+ parameters.mutable_region()->set_height(region.size.height.as_uint32_t());
2412 parameters.set_width(output_size.width.as_uint32_t());
2413 parameters.set_height(output_size.height.as_uint32_t());
2414+ parameters.set_pixel_format(pixel_format);
2415
2416 server.create_screencast(
2417 nullptr,
2418@@ -132,7 +129,7 @@
2419 output_size.height.as_int(),
2420 output_format,
2421 mir_buffer_usage_hardware,
2422- output_id};
2423+ mir_display_output_id_invalid};
2424 }
2425
2426 std::shared_ptr<mcl::ClientBuffer> MirScreencast::get_current_buffer()
2427
2428=== modified file 'src/client/mir_screencast.h'
2429--- src/client/mir_screencast.h 2014-02-10 09:07:48 +0000
2430+++ src/client/mir_screencast.h 2014-03-17 15:02:33 +0000
2431@@ -25,6 +25,7 @@
2432 #include "mir_toolkit/client_types.h"
2433 #include "mir_protobuf.pb.h"
2434 #include "mir/geometry/size.h"
2435+#include "mir/geometry/rectangle.h"
2436
2437 #include <EGL/eglplatform.h>
2438
2439@@ -42,7 +43,9 @@
2440 {
2441 public:
2442 MirScreencast(
2443- MirDisplayOutput const& output,
2444+ mir::geometry::Rectangle const& region,
2445+ mir::geometry::Size const& size,
2446+ MirPixelFormat pixel_format,
2447 mir::protobuf::DisplayServer& server,
2448 std::shared_ptr<mir::client::EGLNativeWindowFactory> const& egl_native_window_factory,
2449 std::shared_ptr<mir::client::ClientBufferFactory> const& factory,
2450@@ -75,7 +78,6 @@
2451 mir_screencast_callback callback, void* context);
2452
2453 mir::protobuf::DisplayServer& server;
2454- uint32_t const output_id;
2455 mir::geometry::Size const output_size;
2456 MirPixelFormat const output_format;
2457 std::shared_ptr<mir::client::EGLNativeWindowFactory> const egl_native_window_factory;
2458
2459=== modified file 'src/client/mir_screencast_api.cpp'
2460--- src/client/mir_screencast_api.cpp 2014-02-18 02:12:21 +0000
2461+++ src/client/mir_screencast_api.cpp 2014-03-17 15:02:33 +0000
2462@@ -26,25 +26,7 @@
2463
2464 namespace
2465 {
2466-
2467 void null_callback(MirScreencast*, void*) {}
2468-
2469-MirDisplayOutput& find_display_output(
2470- MirDisplayConfiguration const& config,
2471- uint32_t output_id)
2472-{
2473- for (decltype(config.num_outputs) i = 0; i != config.num_outputs; ++i)
2474- {
2475- if (config.outputs[i].output_id == output_id)
2476- {
2477- return config.outputs[i];
2478- }
2479- }
2480-
2481- BOOST_THROW_EXCEPTION(
2482- std::runtime_error("Couldn't find output with supplied id"));
2483-}
2484-
2485 }
2486
2487 MirScreencast* mir_connection_create_screencast_sync(
2488@@ -64,9 +46,17 @@
2489
2490 auto const client_platform = connection->get_client_platform();
2491
2492+ mir::geometry::Rectangle const region{
2493+ {parameters->region.left, parameters->region.top},
2494+ {parameters->region.width, parameters->region.height}
2495+ };
2496+ mir::geometry::Size const size{parameters->width, parameters->height};
2497+
2498 std::unique_ptr<MirScreencast> screencast_uptr{
2499 new MirScreencast{
2500- find_display_output(*config, parameters->output_id),
2501+ region,
2502+ size,
2503+ parameters->pixel_format,
2504 connection->display_server(),
2505 client_platform,
2506 client_platform->create_buffer_factory(),
2507
2508=== modified file 'src/client/mir_surface.h'
2509--- src/client/mir_surface.h 2014-02-10 09:07:48 +0000
2510+++ src/client/mir_surface.h 2014-03-17 15:02:33 +0000
2511@@ -106,8 +106,6 @@
2512 MirPixelFormat convert_ipc_pf_to_geometry(google::protobuf::int32 pf);
2513 void release_cpu_region();
2514
2515- /* todo: race condition. protobuf does not guarantee that callbacks will be synchronized. potential
2516- race in surface, last_buffer_id */
2517 mir::protobuf::DisplayServer::Stub & server;
2518 mir::protobuf::Surface surface;
2519 std::string error_message;
2520
2521=== modified file 'src/platform/graphics/CMakeLists.txt'
2522--- src/platform/graphics/CMakeLists.txt 2014-02-28 13:51:43 +0000
2523+++ src/platform/graphics/CMakeLists.txt 2014-03-17 15:02:33 +0000
2524@@ -10,6 +10,7 @@
2525 display_configuration.cpp
2526 buffer_basic.cpp
2527 pixel_format_utils.cpp
2528+ overlapping_output_grouping.cpp
2529 )
2530
2531 add_library(
2532
2533=== modified file 'src/platform/graphics/android/CMakeLists.txt'
2534--- src/platform/graphics/android/CMakeLists.txt 2014-02-28 13:51:43 +0000
2535+++ src/platform/graphics/android/CMakeLists.txt 2014-03-17 15:02:33 +0000
2536@@ -32,6 +32,7 @@
2537 interpreter_cache.cpp
2538 internal_client.cpp
2539 gl_context.cpp
2540+ real_hwc_wrapper.cpp
2541 )
2542
2543 set_target_properties(
2544@@ -51,6 +52,8 @@
2545 ${GLESv2_LDFLAGS} ${GLESv2_LIBRARIES}
2546 )
2547
2548+install(TARGETS mirplatformgraphicsandroid LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mir/platformgraphics/android)
2549+
2550 if (MIR_TEST_PLATFORM STREQUAL "android")
2551 add_custom_command(TARGET mirplatformgraphicsandroid
2552 POST_BUILD
2553@@ -58,6 +61,11 @@
2554 COMMAND ${CMAKE_COMMAND} -E create_symlink android/$<TARGET_FILE_NAME:mirplatformgraphicsandroid> libmirplatformgraphics.so
2555 WORKING_DIRECTORY ${LIBRARY_OUTPUT_PATH}
2556 )
2557+
2558+ install(CODE
2559+ "execute_process(
2560+ COMMAND ln -sf mir/platformgraphics/android/libmirplatformgraphics.so
2561+ WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}
2562+ )"
2563+ )
2564 endif()
2565-
2566-install(TARGETS mirplatformgraphicsandroid LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mir/platformgraphics/android)
2567
2568=== modified file 'src/platform/graphics/android/android_display.cpp'
2569--- src/platform/graphics/android/android_display.cpp 2014-03-05 02:30:30 +0000
2570+++ src/platform/graphics/android/android_display.cpp 2014-03-17 15:02:33 +0000
2571@@ -26,6 +26,8 @@
2572 #include "display_builder.h"
2573 #include "mir/geometry/rectangle.h"
2574
2575+#include <boost/throw_exception.hpp>
2576+
2577 namespace mga=mir::graphics::android;
2578 namespace mg=mir::graphics;
2579 namespace geom=mir::geometry;
2580@@ -57,6 +59,12 @@
2581
2582 void mga::AndroidDisplay::configure(mg::DisplayConfiguration const& configuration)
2583 {
2584+ if (!configuration.valid())
2585+ {
2586+ BOOST_THROW_EXCEPTION(
2587+ std::logic_error("Invalid or inconsistent display configuration"));
2588+ }
2589+
2590 configuration.for_each_output([&](mg::DisplayConfigurationOutput const& output)
2591 {
2592 display_buffer->configure(output);
2593
2594=== modified file 'src/platform/graphics/android/android_display_configuration.cpp'
2595--- src/platform/graphics/android/android_display_configuration.cpp 2014-03-05 02:30:30 +0000
2596+++ src/platform/graphics/android/android_display_configuration.cpp 2014-03-17 15:02:33 +0000
2597@@ -52,10 +52,9 @@
2598 f(configuration);
2599 }
2600
2601-void mga::AndroidDisplayConfiguration::configure_output(
2602- mg::DisplayConfigurationOutputId, bool, geom::Point, size_t,
2603- MirPixelFormat, MirPowerMode power_mode, MirOrientation orientation)
2604+void mga::AndroidDisplayConfiguration::for_each_output(std::function<void(mg::UserDisplayConfigurationOutput&)> f)
2605 {
2606- configuration.power_mode = power_mode;
2607- configuration.orientation = orientation;
2608+ mg::UserDisplayConfigurationOutput user(configuration);
2609+ f(user);
2610 }
2611+
2612
2613=== modified file 'src/platform/graphics/android/android_display_configuration.h'
2614--- src/platform/graphics/android/android_display_configuration.h 2014-03-05 02:30:30 +0000
2615+++ src/platform/graphics/android/android_display_configuration.h 2014-03-17 15:02:33 +0000
2616@@ -37,10 +37,7 @@
2617
2618 void for_each_card(std::function<void(DisplayConfigurationCard const&)> f) const override;
2619 void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const override;
2620- void configure_output(DisplayConfigurationOutputId id, bool used,
2621- geometry::Point top_left, size_t mode_index,
2622- MirPixelFormat format, MirPowerMode power_mode,
2623- MirOrientation) override;
2624+ void for_each_output(std::function<void(UserDisplayConfigurationOutput&)> f) override;
2625
2626 private:
2627 DisplayConfigurationOutput configuration;
2628
2629=== modified file 'src/platform/graphics/android/display_buffer.cpp'
2630--- src/platform/graphics/android/display_buffer.cpp 2014-02-28 13:51:43 +0000
2631+++ src/platform/graphics/android/display_buffer.cpp 2014-03-17 15:02:33 +0000
2632@@ -85,35 +85,29 @@
2633 }
2634
2635 void mga::DisplayBuffer::render_and_post_update(
2636- std::list<std::shared_ptr<Renderable>> const& renderlist,
2637- std::function<void(Renderable const&)> const& render_fn)
2638+ std::list<std::shared_ptr<Renderable>> const& renderlist,
2639+ std::function<void(Renderable const&)> const& render_fn)
2640 {
2641 if (renderlist.empty())
2642 {
2643- display_device->prepare_gl();
2644+ display_device->render_gl(gl_context);
2645 }
2646 else
2647 {
2648- display_device->prepare_gl_and_overlays(renderlist);
2649- }
2650-
2651- for(auto& renderable : renderlist)
2652- {
2653- render_fn(*renderable);
2654- }
2655-
2656- render_and_post();
2657+ display_device->render_gl_and_overlays(gl_context, renderlist, render_fn);
2658+ }
2659+
2660+ post();
2661 }
2662
2663 void mga::DisplayBuffer::post_update()
2664 {
2665- display_device->prepare_gl();
2666- render_and_post();
2667+ display_device->render_gl(gl_context);
2668+ post();
2669 }
2670
2671-void mga::DisplayBuffer::render_and_post()
2672+void mga::DisplayBuffer::post()
2673 {
2674- display_device->gpu_render(gl_context.display(), gl_context.surface());
2675 auto last_rendered = fb_bundle->last_rendered_buffer();
2676 display_device->post(*last_rendered);
2677 }
2678
2679=== modified file 'src/platform/graphics/android/display_buffer.h'
2680--- src/platform/graphics/android/display_buffer.h 2014-02-28 13:51:43 +0000
2681+++ src/platform/graphics/android/display_buffer.h 2014-03-17 15:02:33 +0000
2682@@ -58,7 +58,7 @@
2683 void configure(DisplayConfigurationOutput const&);
2684
2685 private:
2686- void render_and_post();
2687+ void post();
2688
2689 std::shared_ptr<FramebufferBundle> const fb_bundle;
2690 std::shared_ptr<DisplayDevice> const display_device;
2691
2692=== modified file 'src/platform/graphics/android/display_device.h'
2693--- src/platform/graphics/android/display_device.h 2014-02-28 13:51:43 +0000
2694+++ src/platform/graphics/android/display_device.h 2014-03-17 15:02:33 +0000
2695@@ -33,6 +33,7 @@
2696
2697 namespace android
2698 {
2699+class SwappingGLContext;
2700
2701 class DisplayDevice
2702 {
2703@@ -40,9 +41,11 @@
2704 virtual ~DisplayDevice() = default;
2705
2706 virtual void mode(MirPowerMode mode) = 0;
2707- virtual void prepare_gl() = 0;
2708- virtual void prepare_gl_and_overlays(std::list<std::shared_ptr<Renderable>> const& list) = 0;
2709- virtual void gpu_render(EGLDisplay dpy, EGLSurface sur) = 0;
2710+ virtual void render_gl(SwappingGLContext const& context) = 0;
2711+ virtual void render_gl_and_overlays(
2712+ SwappingGLContext const& context,
2713+ std::list<std::shared_ptr<Renderable>> const& list,
2714+ std::function<void(Renderable const&)> const& render_fn) = 0;
2715 virtual void post(Buffer const& buffer) = 0;
2716 virtual bool apply_orientation(MirOrientation orientation) const = 0;
2717
2718
2719=== modified file 'src/platform/graphics/android/fb_device.cpp'
2720--- src/platform/graphics/android/fb_device.cpp 2014-02-28 13:51:43 +0000
2721+++ src/platform/graphics/android/fb_device.cpp 2014-03-17 15:02:33 +0000
2722@@ -19,6 +19,7 @@
2723 #include "mir/graphics/buffer.h"
2724 #include "mir/graphics/android/native_buffer.h"
2725 #include "mir/graphics/android/sync_fence.h"
2726+#include "gl_context.h"
2727 #include "android_format_conversion-inl.h"
2728 #include "fb_device.h"
2729 #include "framebuffer_bundle.h"
2730@@ -43,20 +44,20 @@
2731 mode(mir_power_mode_on);
2732 }
2733
2734-void mga::FBDevice::prepare_gl()
2735-{
2736-}
2737-
2738-void mga::FBDevice::prepare_gl_and_overlays(std::list<std::shared_ptr<Renderable>> const&)
2739-{
2740-}
2741-
2742-void mga::FBDevice::gpu_render(EGLDisplay dpy, EGLSurface sur)
2743-{
2744- if (eglSwapBuffers(dpy, sur) == EGL_FALSE)
2745- {
2746- BOOST_THROW_EXCEPTION(std::runtime_error("eglSwapBuffers failure\n"));
2747- }
2748+void mga::FBDevice::render_gl(SwappingGLContext const& context)
2749+{
2750+ context.swap_buffers();
2751+}
2752+
2753+void mga::FBDevice::render_gl_and_overlays(
2754+ SwappingGLContext const& context,
2755+ std::list<std::shared_ptr<Renderable>> const& renderables,
2756+ std::function<void(Renderable const&)> const& render_fn)
2757+{
2758+ for(auto const& renderable : renderables)
2759+ render_fn(*renderable);
2760+
2761+ context.swap_buffers();
2762 }
2763
2764 void mga::FBDevice::post(mg::Buffer const& buffer)
2765
2766=== modified file 'src/platform/graphics/android/fb_device.h'
2767--- src/platform/graphics/android/fb_device.h 2014-02-28 13:51:43 +0000
2768+++ src/platform/graphics/android/fb_device.h 2014-03-17 15:02:33 +0000
2769@@ -37,9 +37,11 @@
2770
2771 bool apply_orientation(MirOrientation orientation) const;
2772 void mode(MirPowerMode mode);
2773- void prepare_gl();
2774- void prepare_gl_and_overlays(std::list<std::shared_ptr<Renderable>> const& list);
2775- void gpu_render(EGLDisplay dpy, EGLSurface sur);
2776+ virtual void render_gl(SwappingGLContext const& context);
2777+ virtual void render_gl_and_overlays(
2778+ SwappingGLContext const& context,
2779+ std::list<std::shared_ptr<Renderable>> const& list,
2780+ std::function<void(Renderable const&)> const& render_fn);
2781 void post(Buffer const& buffer);
2782
2783 private:
2784
2785=== modified file 'src/platform/graphics/android/gl_context.cpp'
2786--- src/platform/graphics/android/gl_context.cpp 2014-01-22 10:03:11 +0000
2787+++ src/platform/graphics/android/gl_context.cpp 2014-03-17 15:02:33 +0000
2788@@ -23,6 +23,7 @@
2789 #include <algorithm>
2790 #include <boost/throw_exception.hpp>
2791 #include <stdexcept>
2792+#include <sstream>
2793
2794 namespace mg=mir::graphics;
2795 namespace mga=mir::graphics::android;
2796@@ -145,6 +146,17 @@
2797 eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
2798 }
2799
2800+void mga::GLContext::swap_buffers() const
2801+{
2802+ eglGetError();
2803+ if (eglSwapBuffers(egl_display, egl_surface) == EGL_FALSE)
2804+ {
2805+ std::stringstream sstream;
2806+ sstream << "eglSwapBuffers failure: EGL error code " << std::hex << eglGetError();
2807+ BOOST_THROW_EXCEPTION(std::runtime_error(sstream.str()));
2808+ }
2809+}
2810+
2811 mga::GLContext::~GLContext()
2812 {
2813 if (eglGetCurrentContext() == egl_context)
2814
2815=== modified file 'src/platform/graphics/android/gl_context.h'
2816--- src/platform/graphics/android/gl_context.h 2014-01-22 10:03:11 +0000
2817+++ src/platform/graphics/android/gl_context.h 2014-03-17 15:02:33 +0000
2818@@ -36,7 +36,20 @@
2819 EGLSurface create_dummy_pbuffer_surface(EGLDisplay, EGLConfig);
2820 EGLSurface create_window_surface(EGLDisplay, EGLConfig, EGLNativeWindowType);
2821
2822-class GLContext : public graphics::GLContext
2823+class SwappingGLContext
2824+{
2825+public:
2826+ virtual ~SwappingGLContext() = default;
2827+ virtual void swap_buffers() const = 0;
2828+
2829+protected:
2830+ SwappingGLContext() = default;
2831+ SwappingGLContext(SwappingGLContext const&) = delete;
2832+ SwappingGLContext& operator=(SwappingGLContext const&) = delete;
2833+};
2834+
2835+class GLContext : public SwappingGLContext,
2836+ public graphics::GLContext
2837 {
2838 public:
2839 //For creating a gl context
2840@@ -49,19 +62,9 @@
2841 ~GLContext();
2842
2843 void make_current() const override;
2844- void swap_buffers();
2845+ void swap_buffers() const override;
2846 void release_current() const override;
2847
2848- /* TODO: (kdub) remove these two functions once HWC1.0 construction is sorted out. */
2849- EGLDisplay display()
2850- {
2851- return egl_display;
2852- }
2853- EGLSurface surface()
2854- {
2855- return egl_surface;
2856- }
2857-
2858 private:
2859 EGLDisplay const egl_display;
2860 bool const own_display;
2861
2862=== modified file 'src/platform/graphics/android/hwc_device.cpp'
2863--- src/platform/graphics/android/hwc_device.cpp 2014-02-11 03:04:50 +0000
2864+++ src/platform/graphics/android/hwc_device.cpp 2014-03-17 15:02:33 +0000
2865@@ -17,83 +17,122 @@
2866 * Kevin DuBois <kevin.dubois@canonical.com>
2867 */
2868
2869+#include "gl_context.h"
2870 #include "hwc_device.h"
2871 #include "hwc_layerlist.h"
2872 #include "hwc_vsync_coordinator.h"
2873 #include "framebuffer_bundle.h"
2874 #include "buffer.h"
2875-#include "mir/graphics/android/native_buffer.h"
2876 #include "mir/graphics/buffer.h"
2877
2878-#include <EGL/eglext.h>
2879-#include <boost/throw_exception.hpp>
2880-#include <stdexcept>
2881-
2882 namespace mg = mir::graphics;
2883 namespace mga=mir::graphics::android;
2884 namespace geom = mir::geometry;
2885
2886+namespace
2887+{
2888+static const size_t fbtarget_plus_skip_size = 2;
2889+static const size_t fbtarget_size = 1;
2890+}
2891+
2892+void mga::HwcDevice::setup_layer_types()
2893+{
2894+ auto it = hwc_list.additional_layers_begin();
2895+ auto const num_additional_layers = std::distance(it, hwc_list.end());
2896+ switch (num_additional_layers)
2897+ {
2898+ case fbtarget_plus_skip_size:
2899+ it->set_layer_type(mga::LayerType::skip);
2900+ ++it;
2901+ case fbtarget_size:
2902+ it->set_layer_type(mga::LayerType::framebuffer_target);
2903+ default:
2904+ break;
2905+ }
2906+}
2907+
2908+void mga::HwcDevice::set_list_framebuffer(mg::Buffer const& buffer)
2909+{
2910+ geom::Rectangle const disp_frame{{0,0}, {buffer.size()}};
2911+ for(auto it = hwc_list.additional_layers_begin(); it != hwc_list.end(); it++)
2912+ {
2913+ //TODO: the functions on mga::Layer should be consolidated
2914+ it->set_render_parameters(disp_frame, false);
2915+ it->set_buffer(buffer);
2916+ it->prepare_for_draw();
2917+ }
2918+}
2919+
2920 mga::HwcDevice::HwcDevice(std::shared_ptr<hwc_composer_device_1> const& hwc_device,
2921+ std::shared_ptr<HwcWrapper> const& hwc_wrapper,
2922 std::shared_ptr<HWCVsyncCoordinator> const& coordinator,
2923 std::shared_ptr<SyncFileOps> const& sync_ops)
2924 : HWCCommonDevice(hwc_device, coordinator),
2925+ hwc_list{{}, 2},
2926+ hwc_wrapper(hwc_wrapper),
2927 sync_ops(sync_ops)
2928 {
2929-}
2930-
2931-void mga::HwcDevice::prepare_gl()
2932-{
2933- auto rc = 0;
2934- auto display_list = layer_list.native_list().lock();
2935- if (display_list)
2936- {
2937- //note, although we only have a primary display right now,
2938- // set the external and virtual displays to null as some drivers check for that
2939- hwc_display_contents_1_t* displays[num_displays] {display_list.get(), nullptr, nullptr};
2940- rc = hwc_device->prepare(hwc_device.get(), 1, displays);
2941- }
2942-
2943- if ((rc != 0) || (!display_list))
2944- {
2945- BOOST_THROW_EXCEPTION(std::runtime_error("error during hwc prepare()"));
2946- }
2947-}
2948-
2949-void mga::HwcDevice::prepare_gl_and_overlays(std::list<std::shared_ptr<Renderable>> const&)
2950-{
2951- prepare_gl();
2952-}
2953-
2954-void mga::HwcDevice::gpu_render(EGLDisplay dpy, EGLSurface sur)
2955-{
2956- if (eglSwapBuffers(dpy, sur) == EGL_FALSE)
2957- {
2958- BOOST_THROW_EXCEPTION(std::runtime_error("eglSwapBuffers failure\n"));
2959- }
2960+ setup_layer_types();
2961+}
2962+
2963+void mga::HwcDevice::render_gl(SwappingGLContext const& context)
2964+{
2965+ hwc_list.update_list_and_check_if_changed({}, fbtarget_plus_skip_size);
2966+ setup_layer_types();
2967+
2968+ list_needs_commit = true;
2969+
2970+ hwc_wrapper->prepare(*hwc_list.native_list().lock());
2971+
2972+ context.swap_buffers();
2973+}
2974+
2975+void mga::HwcDevice::render_gl_and_overlays(
2976+ SwappingGLContext const& context,
2977+ std::list<std::shared_ptr<Renderable>> const& renderables,
2978+ std::function<void(Renderable const&)> const& render_fn)
2979+{
2980+ if (!(list_needs_commit = hwc_list.update_list_and_check_if_changed(renderables, fbtarget_size)))
2981+ return;
2982+ setup_layer_types();
2983+
2984+ hwc_wrapper->prepare(*hwc_list.native_list().lock());
2985+
2986+ //draw layers that the HWC did not accept for overlays here
2987+ bool needs_swapbuffers = false;
2988+ auto layers_it = hwc_list.begin();
2989+ for(auto const& renderable : renderables)
2990+ {
2991+ //prepare all layers for draw.
2992+ layers_it->prepare_for_draw();
2993+
2994+ //trigger GL on the layers that are not overlays
2995+ if (layers_it->needs_gl_render())
2996+ {
2997+ render_fn(*renderable);
2998+ needs_swapbuffers = true;
2999+ }
3000+ layers_it++;
3001+ }
3002+
3003+ if (needs_swapbuffers)
3004+ context.swap_buffers();
3005 }
3006
3007 void mga::HwcDevice::post(mg::Buffer const& buffer)
3008 {
3009+ if (!list_needs_commit)
3010+ return;
3011+
3012 auto lg = lock_unblanked();
3013-
3014- layer_list.set_fb_target(buffer);
3015-
3016- auto rc = 0;
3017- auto display_list = layer_list.native_list().lock();
3018- if (display_list)
3019- {
3020- hwc_display_contents_1_t* displays[num_displays] {display_list.get(), nullptr, nullptr};
3021- rc = hwc_device->set(hwc_device.get(), 1, displays);
3022-
3023- mga::SyncFence retire_fence(sync_ops, layer_list.retirement_fence());
3024-
3025- int framebuffer_fence = layer_list.fb_target_fence();
3026- auto native_buffer = buffer.native_buffer_handle();
3027- native_buffer->update_fence(framebuffer_fence);
3028- }
3029-
3030- if ((rc != 0) || (!display_list))
3031- {
3032- BOOST_THROW_EXCEPTION(std::runtime_error("error during hwc set()"));
3033- }
3034+ set_list_framebuffer(buffer);
3035+ hwc_wrapper->set(*hwc_list.native_list().lock());
3036+
3037+ for(auto& layer : hwc_list)
3038+ {
3039+ layer.update_fence_and_release_buffer();
3040+ }
3041+
3042+ mga::SyncFence retire_fence(sync_ops, hwc_list.retirement_fence());
3043+ list_needs_commit = false;
3044 }
3045
3046=== modified file 'src/platform/graphics/android/hwc_device.h'
3047--- src/platform/graphics/android/hwc_device.h 2014-02-11 03:04:50 +0000
3048+++ src/platform/graphics/android/hwc_device.h 2014-03-17 15:02:33 +0000
3049@@ -36,23 +36,45 @@
3050 class HWCVsyncCoordinator;
3051 class SyncFileOps;
3052
3053+class HwcWrapper
3054+{
3055+public:
3056+ virtual ~HwcWrapper() = default;
3057+
3058+ virtual void prepare(hwc_display_contents_1_t&) const = 0;
3059+ virtual void set(hwc_display_contents_1_t&) const = 0;
3060+
3061+protected:
3062+ HwcWrapper() = default;
3063+ HwcWrapper& operator=(HwcWrapper const&) = delete;
3064+ HwcWrapper(HwcWrapper const&) = delete;
3065+};
3066+
3067 class HwcDevice : public HWCCommonDevice
3068 {
3069 public:
3070+ //TODO: the first two constructor arguments are redundant. eliminate the 1st one when the 2nd
3071+ // one can be used by the HWCCommonDevice
3072 HwcDevice(std::shared_ptr<hwc_composer_device_1> const& hwc_device,
3073+ std::shared_ptr<HwcWrapper> const& hwc_wrapper,
3074 std::shared_ptr<HWCVsyncCoordinator> const& coordinator,
3075 std::shared_ptr<SyncFileOps> const& sync_ops);
3076
3077- void prepare_gl();
3078- void prepare_gl_and_overlays(std::list<std::shared_ptr<Renderable>> const& list);
3079- void gpu_render(EGLDisplay dpy, EGLSurface sur);
3080+ virtual void render_gl(SwappingGLContext const& context);
3081+ virtual void render_gl_and_overlays(
3082+ SwappingGLContext const& context,
3083+ std::list<std::shared_ptr<Renderable>> const& list,
3084+ std::function<void(Renderable const&)> const& render_fn);
3085 void post(Buffer const& buffer);
3086
3087 private:
3088- FBTargetLayerList layer_list;
3089+ LayerList hwc_list;
3090+ void set_list_framebuffer(Buffer const&);
3091+ void setup_layer_types();
3092
3093+ std::shared_ptr<HwcWrapper> const hwc_wrapper;
3094 std::shared_ptr<SyncFileOps> const sync_ops;
3095- static size_t const num_displays{3}; //primary, external, virtual
3096+ bool list_needs_commit{false};
3097 };
3098
3099 }
3100
3101=== modified file 'src/platform/graphics/android/hwc_fb_device.cpp'
3102--- src/platform/graphics/android/hwc_fb_device.cpp 2014-02-11 03:04:50 +0000
3103+++ src/platform/graphics/android/hwc_fb_device.cpp 2014-03-17 15:02:33 +0000
3104@@ -25,6 +25,7 @@
3105 #include "mir/graphics/android/native_buffer.h"
3106
3107 #include <boost/throw_exception.hpp>
3108+#include <sstream>
3109 #include <stdexcept>
3110
3111 namespace mg = mir::graphics;
3112@@ -35,39 +36,20 @@
3113 std::shared_ptr<framebuffer_device_t> const& fb_device,
3114 std::shared_ptr<HWCVsyncCoordinator> const& coordinator)
3115 : HWCCommonDevice(hwc_device, coordinator),
3116- fb_device(fb_device)
3117-{
3118-}
3119-
3120-void mga::HwcFbDevice::prepare_gl()
3121-{
3122- auto rc = 0;
3123- auto display_list = layer_list.native_list().lock();
3124- if (display_list)
3125- {
3126- hwc_display_contents_1_t* displays[num_displays] {display_list.get()};
3127- rc = hwc_device->prepare(hwc_device.get(), num_displays, displays);
3128- }
3129-
3130- if ((rc != 0) || (!display_list))
3131- {
3132- BOOST_THROW_EXCEPTION(std::runtime_error("error during hwc prepare()"));
3133- }
3134-}
3135-
3136-void mga::HwcFbDevice::prepare_gl_and_overlays(std::list<std::shared_ptr<Renderable>> const&)
3137-{
3138- prepare_gl();
3139-}
3140-
3141-void mga::HwcFbDevice::gpu_render(EGLDisplay dpy, EGLSurface sur)
3142+ fb_device(fb_device),
3143+ layer_list{{},1}
3144+{
3145+ layer_list.additional_layers_begin()->set_layer_type(mga::LayerType::skip);
3146+}
3147+
3148+void mga::HwcFbDevice::gpu_render()
3149 {
3150 auto rc = 0;
3151 auto display_list = layer_list.native_list().lock();
3152 if (display_list)
3153 {
3154- display_list->dpy = dpy;
3155- display_list->sur = sur;
3156+ display_list->dpy = eglGetCurrentDisplay();
3157+ display_list->sur = eglGetCurrentSurface(EGL_DRAW);
3158
3159 //set() may affect EGL state by calling eglSwapBuffers.
3160 //HWC 1.0 is the only version of HWC that can do this.
3161@@ -77,8 +59,46 @@
3162
3163 if ((rc != 0) || (!display_list))
3164 {
3165- BOOST_THROW_EXCEPTION(std::runtime_error("error during hwc set()"));
3166- }
3167+ std::stringstream ss;
3168+ ss << "error during hwc set(). rc = " << std::hex << rc;
3169+ BOOST_THROW_EXCEPTION(std::runtime_error(ss.str()));
3170+ }
3171+}
3172+
3173+void mga::HwcFbDevice::prepare()
3174+{
3175+ auto rc = 0;
3176+ auto display_list = layer_list.native_list().lock();
3177+ if (display_list)
3178+ {
3179+ hwc_display_contents_1_t* displays[num_displays] {display_list.get()};
3180+ rc = hwc_device->prepare(hwc_device.get(), num_displays, displays);
3181+ }
3182+
3183+ if ((rc != 0) || (!display_list))
3184+ {
3185+ std::stringstream ss;
3186+ ss << "error during hwc prepare(). rc = " << std::hex << rc;
3187+ BOOST_THROW_EXCEPTION(std::runtime_error(ss.str()));
3188+ }
3189+}
3190+
3191+void mga::HwcFbDevice::render_gl(SwappingGLContext const&)
3192+{
3193+ prepare();
3194+ gpu_render();
3195+}
3196+
3197+void mga::HwcFbDevice::render_gl_and_overlays(
3198+ SwappingGLContext const&,
3199+ std::list<std::shared_ptr<Renderable>> const& renderables,
3200+ std::function<void(Renderable const&)> const& render_fn)
3201+{
3202+ prepare();
3203+ //TODO: filter this list based on the results of the preparation
3204+ for(auto const& renderable : renderables)
3205+ render_fn(*renderable);
3206+ gpu_render();
3207 }
3208
3209 void mga::HwcFbDevice::post(mg::Buffer const& buffer)
3210
3211=== modified file 'src/platform/graphics/android/hwc_fb_device.h'
3212--- src/platform/graphics/android/hwc_fb_device.h 2014-02-11 03:04:50 +0000
3213+++ src/platform/graphics/android/hwc_fb_device.h 2014-03-17 15:02:33 +0000
3214@@ -38,12 +38,16 @@
3215 std::shared_ptr<framebuffer_device_t> const& fb_device,
3216 std::shared_ptr<HWCVsyncCoordinator> const& coordinator);
3217
3218- void prepare_gl();
3219- void prepare_gl_and_overlays(std::list<std::shared_ptr<Renderable>> const& list);
3220- void gpu_render(EGLDisplay dpy, EGLSurface sur);
3221+ virtual void render_gl(SwappingGLContext const& context);
3222+ virtual void render_gl_and_overlays(
3223+ SwappingGLContext const& context,
3224+ std::list<std::shared_ptr<Renderable>> const& list,
3225+ std::function<void(Renderable const&)> const& render_fn);
3226 void post(Buffer const& buffer);
3227
3228 private:
3229+ void prepare();
3230+ void gpu_render();
3231 std::shared_ptr<framebuffer_device_t> const fb_device;
3232 static int const num_displays{1};
3233 LayerList layer_list;
3234
3235=== modified file 'src/platform/graphics/android/hwc_layerlist.cpp'
3236--- src/platform/graphics/android/hwc_layerlist.cpp 2014-03-04 04:19:26 +0000
3237+++ src/platform/graphics/android/hwc_layerlist.cpp 2014-03-17 15:02:33 +0000
3238@@ -51,101 +51,95 @@
3239 }
3240 }
3241
3242-void mga::LayerListBase::update_representation(size_t needed_size)
3243-{
3244- std::shared_ptr<hwc_display_contents_1_t> new_hwc_representation;
3245- std::list<HWCLayer> new_layers;
3246-
3247- if (hwc_representation->numHwLayers != needed_size)
3248- {
3249- new_hwc_representation = generate_hwc_list(needed_size);
3250- }
3251- else
3252- {
3253- new_hwc_representation = hwc_representation;
3254- }
3255-
3256- for (auto i = 0u; i < needed_size; i++)
3257- {
3258- new_layers.emplace_back(mga::HWCLayer(new_hwc_representation, i));
3259- }
3260-
3261- std::swap(new_layers, layers);
3262- hwc_representation = new_hwc_representation;
3263-}
3264-
3265-std::weak_ptr<hwc_display_contents_1_t> mga::LayerListBase::native_list()
3266+bool mga::LayerList::update_list_and_check_if_changed(
3267+ std::list<std::shared_ptr<mg::Renderable>> const& renderlist,
3268+ size_t additional_layers)
3269+{
3270+ size_t needed_size = renderlist.size() + additional_layers;
3271+
3272+ bool any_buffer_updated = false;
3273+ if ((!hwc_representation) || hwc_representation->numHwLayers != needed_size)
3274+ {
3275+ hwc_representation = generate_hwc_list(needed_size);
3276+ }
3277+
3278+ if (layers.size() == needed_size)
3279+ {
3280+ auto layers_it = layers.begin();
3281+ for(auto renderable : renderlist)
3282+ {
3283+ layers_it->set_render_parameters(
3284+ renderable->screen_position(), renderable->alpha_enabled());
3285+ layers_it->set_buffer(*renderable->buffer(1));// TODO: remove needing to know about frameno
3286+ any_buffer_updated |= layers_it->needs_hwc_commit();
3287+ layers_it++;
3288+ }
3289+ }
3290+ else
3291+ {
3292+ any_buffer_updated = true;
3293+ std::list<HWCLayer> new_layers;
3294+ auto i = 0u;
3295+ for(auto const& renderable : renderlist)
3296+ {
3297+ new_layers.emplace_back(
3298+ mga::HWCLayer(
3299+ mga::LayerType::gl_rendered,
3300+ renderable->screen_position(),
3301+ renderable->alpha_enabled(),
3302+ hwc_representation, i++));
3303+ new_layers.back().set_buffer(*renderable->buffer(1));// TODO: remove needing to know about frameno
3304+ }
3305+
3306+ for(; i < needed_size; i++)
3307+ {
3308+ new_layers.emplace_back(mga::HWCLayer(hwc_representation, i));
3309+ }
3310+ layers = std::move(new_layers);
3311+ }
3312+
3313+ if (additional_layers == 0)
3314+ {
3315+ first_additional_layer = layers.end();
3316+ }
3317+ else
3318+ {
3319+ first_additional_layer = layers.begin();
3320+ std::advance(first_additional_layer, renderlist.size());
3321+ }
3322+
3323+ return any_buffer_updated;
3324+}
3325+
3326+std::list<mga::HWCLayer>::iterator mga::LayerList::begin()
3327+{
3328+ return layers.begin();
3329+}
3330+
3331+std::list<mga::HWCLayer>::iterator mga::LayerList::additional_layers_begin()
3332+{
3333+ return first_additional_layer;
3334+}
3335+
3336+std::list<mga::HWCLayer>::iterator mga::LayerList::end()
3337+{
3338+ return layers.end();
3339+}
3340+
3341+std::weak_ptr<hwc_display_contents_1_t> mga::LayerList::native_list()
3342 {
3343 return hwc_representation;
3344 }
3345
3346-mga::NativeFence mga::LayerListBase::retirement_fence()
3347+mga::NativeFence mga::LayerList::retirement_fence()
3348 {
3349 return hwc_representation->retireFenceFd;
3350 }
3351
3352-mga::LayerListBase::LayerListBase(size_t initial_list_size)
3353- : hwc_representation{generate_hwc_list(initial_list_size)}
3354-{
3355- update_representation(initial_list_size);
3356-}
3357-
3358-mga::LayerList::LayerList()
3359- : LayerListBase{1}
3360-{
3361- layers.back().set_layer_type(mga::LayerType::skip);
3362-}
3363-
3364-mga::FBTargetLayerList::FBTargetLayerList()
3365- : LayerListBase{2}
3366-{
3367- layers.front().set_layer_type(mga::LayerType::skip);
3368- layers.back().set_layer_type(mga::LayerType::framebuffer_target);
3369-}
3370-
3371-void mga::FBTargetLayerList::reset_composition_layers()
3372-{
3373- update_representation(2);
3374-
3375- layers.front().set_layer_type(mga::LayerType::skip);
3376- layers.back().set_layer_type(mga::LayerType::framebuffer_target);
3377-
3378- skip_layers_present = true;
3379-}
3380-
3381-void mga::FBTargetLayerList::set_composition_layers(std::list<std::shared_ptr<graphics::Renderable>> const& list)
3382-{
3383- auto const needed_size = list.size() + 1;
3384- update_representation(needed_size);
3385-
3386- auto layers_it = layers.begin();
3387- for(auto const& renderable : list)
3388- {
3389- layers_it->set_layer_type(mga::LayerType::gl_rendered);
3390- layers_it->set_render_parameters(renderable->screen_position(), renderable->alpha_enabled());
3391- layers_it->set_buffer(*renderable->buffer());
3392- layers_it++;
3393- }
3394-
3395- layers_it->set_layer_type(mga::LayerType::framebuffer_target);
3396- skip_layers_present = false;
3397-}
3398-
3399-
3400-void mga::FBTargetLayerList::set_fb_target(mg::Buffer const& buffer)
3401-{
3402- geom::Rectangle const disp_frame{{0,0}, {buffer.size()}};
3403- if (skip_layers_present)
3404- {
3405- layers.front().set_render_parameters(disp_frame, false);
3406- layers.front().set_buffer(buffer);
3407- }
3408-
3409- layers.back().set_render_parameters(disp_frame, false);
3410- layers.back().set_buffer(buffer);
3411-}
3412-
3413-mga::NativeFence mga::FBTargetLayerList::fb_target_fence()
3414-{
3415- return layers.back().release_fence();
3416-}
3417+mga::LayerList::LayerList(
3418+ std::list<std::shared_ptr<mg::Renderable>> const& renderlist,
3419+ size_t additional_layers)
3420+{
3421+ update_list_and_check_if_changed(renderlist, additional_layers);
3422+}
3423+
3424
3425=== modified file 'src/platform/graphics/android/hwc_layerlist.h'
3426--- src/platform/graphics/android/hwc_layerlist.h 2014-02-11 03:04:50 +0000
3427+++ src/platform/graphics/android/hwc_layerlist.h 2014-03-17 15:02:33 +0000
3428@@ -39,42 +39,33 @@
3429 namespace android
3430 {
3431
3432-class LayerListBase
3433+/* this is a partitioned list. renderlist makes up the first renderlist.size() elements
3434+ of the list, and there are additional_layers added to the end.
3435+ std::distance(begin(), additional_layers_begin()) == renderlist.size()
3436+ std::distance(additional_layers_begin(), end()) == additional_layers
3437+ std::distance(begin(), end()) == renderlist.size() + additional_layers
3438+*/
3439+class LayerList
3440 {
3441 public:
3442+ LayerList(std::list<std::shared_ptr<Renderable>> const& renderlist, size_t additional_layers);
3443+ bool update_list_and_check_if_changed(
3444+ std::list<std::shared_ptr<Renderable>> const& renderlist,
3445+ size_t additional_layers);
3446+
3447+ std::list<HWCLayer>::iterator begin();
3448+ std::list<HWCLayer>::iterator additional_layers_begin();
3449+ std::list<HWCLayer>::iterator end();
3450+
3451 std::weak_ptr<hwc_display_contents_1_t> native_list();
3452 NativeFence retirement_fence();
3453-
3454-protected:
3455- LayerListBase(size_t initial_list_size);
3456-
3457- void update_representation(size_t needed_size);
3458+private:
3459+ LayerList& operator=(LayerList const&) = delete;
3460+ LayerList(LayerList const&) = delete;
3461+
3462 std::list<HWCLayer> layers;
3463-
3464-private:
3465- LayerListBase& operator=(LayerListBase const&) = delete;
3466- LayerListBase(LayerListBase const&) = delete;
3467-
3468 std::shared_ptr<hwc_display_contents_1_t> hwc_representation;
3469-};
3470-
3471-class LayerList : public LayerListBase
3472-{
3473-public:
3474- LayerList();
3475-};
3476-
3477-class FBTargetLayerList : public LayerListBase
3478-{
3479-public:
3480- FBTargetLayerList();
3481- void set_composition_layers(std::list<std::shared_ptr<graphics::Renderable>> const& list);
3482- void reset_composition_layers();
3483- NativeFence fb_target_fence();
3484- void set_fb_target(Buffer const&);
3485-
3486-private:
3487- bool skip_layers_present{true};
3488+ std::list<HWCLayer>::iterator first_additional_layer;
3489 };
3490
3491 }
3492
3493=== modified file 'src/platform/graphics/android/hwc_layers.cpp'
3494--- src/platform/graphics/android/hwc_layers.cpp 2014-02-12 03:14:55 +0000
3495+++ src/platform/graphics/android/hwc_layers.cpp 2014-03-17 15:02:33 +0000
3496@@ -47,7 +47,8 @@
3497
3498 mga::HWCLayer::HWCLayer(std::shared_ptr<hwc_display_contents_1_t> list, size_t layer_index)
3499 : hwc_layer(&list->hwLayers[layer_index]),
3500- hwc_list(list)
3501+ hwc_list(list),
3502+ associated_buffer(nullptr) //todo: take this as a constructor param
3503 {
3504 memset(hwc_layer, 0, sizeof(hwc_layer_1_t));
3505 memset(&visible_rect, 0, sizeof(hwc_rect_t));
3506@@ -79,9 +80,15 @@
3507 return ((hwc_layer->compositionType == HWC_FRAMEBUFFER) || (hwc_layer->flags == HWC_SKIP_LAYER));
3508 }
3509
3510-mga::NativeFence mga::HWCLayer::release_fence() const
3511+void mga::HWCLayer::update_fence_and_release_buffer()
3512 {
3513- return hwc_layer->releaseFenceFd;
3514+ if (hwc_layer->compositionType != HWC_FRAMEBUFFER)
3515+ {
3516+ associated_buffer->update_fence(hwc_layer->releaseFenceFd);
3517+ hwc_layer->releaseFenceFd = -1;
3518+ hwc_layer->acquireFenceFd = -1;
3519+ associated_buffer.reset();
3520+ }
3521 }
3522
3523 void mga::HWCLayer::set_layer_type(LayerType type)
3524@@ -129,16 +136,39 @@
3525
3526 void mga::HWCLayer::set_buffer(Buffer const& buffer)
3527 {
3528- auto size = buffer.size();
3529- auto native_buffer = buffer.native_buffer_handle();
3530- hwc_layer->handle = native_buffer->handle();
3531- if (!needs_gl_render())
3532- hwc_layer->acquireFenceFd = native_buffer->copy_fence();
3533- hwc_layer->releaseFenceFd = -1;
3534+ associated_buffer.reset();
3535+ associated_buffer = buffer.native_buffer_handle();
3536+ updated = (hwc_layer->handle != associated_buffer->handle());
3537+
3538+ hwc_layer->handle = associated_buffer->handle();
3539 hwc_layer->sourceCrop =
3540 {
3541 0, 0,
3542- size.width.as_int(),
3543- size.height.as_int()
3544+ associated_buffer->anwb()->width,
3545+ associated_buffer->anwb()->height
3546 };
3547 }
3548+
3549+void mga::HWCLayer::prepare_for_draw()
3550+{
3551+ //we shouldn't be copying the FD unless the HWC has marked this as a buffer its interested in.
3552+ //we disregard fences that haven't changed, as the hwc will still own the buffer
3553+ if (updated && (((hwc_layer->compositionType == HWC_OVERLAY) ||
3554+ (hwc_layer->compositionType == HWC_FRAMEBUFFER_TARGET))))
3555+ {
3556+ hwc_layer->acquireFenceFd = associated_buffer->copy_fence();
3557+ }
3558+ //the HWC is not interested in this buffer. we can release the buffer.
3559+ else if (hwc_layer->compositionType == HWC_FRAMEBUFFER)
3560+ {
3561+ hwc_layer->acquireFenceFd = -1;
3562+ associated_buffer.reset();
3563+ }
3564+
3565+ hwc_layer->releaseFenceFd = -1;
3566+}
3567+
3568+bool mga::HWCLayer::needs_hwc_commit() const
3569+{
3570+ return (updated || needs_gl_render());
3571+}
3572
3573=== modified file 'src/platform/graphics/android/hwc_layers.h'
3574--- src/platform/graphics/android/hwc_layers.h 2014-02-12 03:14:55 +0000
3575+++ src/platform/graphics/android/hwc_layers.h 2014-03-17 15:02:33 +0000
3576@@ -35,10 +35,10 @@
3577
3578 class Renderable;
3579 class Buffer;
3580+class NativeBuffer;
3581
3582 namespace android
3583 {
3584-
3585 enum LayerType
3586 {
3587 gl_rendered,
3588@@ -64,15 +64,18 @@
3589
3590 void set_layer_type(LayerType type);
3591 void set_render_parameters(geometry::Rectangle screen_position, bool alpha_enabled);
3592- void set_buffer(Buffer const&);
3593+ void set_buffer(Buffer const& buffer);
3594
3595- NativeFence release_fence() const;
3596+ void update_fence_and_release_buffer();
3597 bool needs_gl_render() const;
3598-
3599+ bool needs_hwc_commit() const;
3600+ void prepare_for_draw();
3601 private:
3602 hwc_layer_1_t* hwc_layer;
3603 std::shared_ptr<hwc_display_contents_1_t> hwc_list;
3604 hwc_rect_t visible_rect;
3605+ std::shared_ptr<NativeBuffer> associated_buffer;
3606+ bool updated{false};
3607 };
3608 }
3609 }
3610
3611=== added file 'src/platform/graphics/android/real_hwc_wrapper.cpp'
3612--- src/platform/graphics/android/real_hwc_wrapper.cpp 1970-01-01 00:00:00 +0000
3613+++ src/platform/graphics/android/real_hwc_wrapper.cpp 2014-03-17 15:02:33 +0000
3614@@ -0,0 +1,53 @@
3615+/*
3616+ * Copyright © 2014 Canonical Ltd.
3617+ *
3618+ * This program is free software: you can redistribute it and/or modify it
3619+ * under the terms of the GNU Lesser General Public License version 3,
3620+ * as published by the Free Software Foundation.
3621+ *
3622+ * This program is distributed in the hope that it will be useful,
3623+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3624+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3625+ * GNU Lesser General Public License for more details.
3626+ *
3627+ * You should have received a copy of the GNU Lesser General Public License
3628+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3629+ *
3630+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
3631+ */
3632+
3633+#include "real_hwc_wrapper.h"
3634+#include <boost/throw_exception.hpp>
3635+#include <stdexcept>
3636+#include <sstream>
3637+
3638+namespace mga=mir::graphics::android;
3639+
3640+mga::RealHwcWrapper::RealHwcWrapper(std::shared_ptr<hwc_composer_device_1> const& hwc_device)
3641+ : hwc_device(hwc_device)
3642+{
3643+}
3644+
3645+void mga::RealHwcWrapper::prepare(hwc_display_contents_1_t& display_list) const
3646+{
3647+ //note, although we only have a primary display right now,
3648+ // set the external and virtual displays to null as some drivers check for that
3649+ hwc_display_contents_1_t* displays[num_displays] {&display_list, nullptr, nullptr};
3650+ if (auto rc = hwc_device->prepare(hwc_device.get(), 1, displays))
3651+ {
3652+ std::stringstream ss;
3653+ ss << "error during hwc prepare(). rc = " << std::hex << rc;
3654+ BOOST_THROW_EXCEPTION(std::runtime_error(ss.str()));
3655+ }
3656+}
3657+
3658+void mga::RealHwcWrapper::set(hwc_display_contents_1_t& display_list) const
3659+{
3660+ hwc_display_contents_1_t* displays[num_displays] {&display_list, nullptr, nullptr};
3661+ if (auto rc = hwc_device->set(hwc_device.get(), 1, displays))
3662+ {
3663+ std::stringstream ss;
3664+ ss << "error during hwc prepare(). rc = " << std::hex << rc;
3665+ BOOST_THROW_EXCEPTION(std::runtime_error(ss.str()));
3666+ }
3667+}
3668
3669=== added file 'src/platform/graphics/android/real_hwc_wrapper.h'
3670--- src/platform/graphics/android/real_hwc_wrapper.h 1970-01-01 00:00:00 +0000
3671+++ src/platform/graphics/android/real_hwc_wrapper.h 2014-03-17 15:02:33 +0000
3672@@ -0,0 +1,48 @@
3673+/*
3674+ * Copyright © 2014 Canonical Ltd.
3675+ *
3676+ * This program is free software: you can redistribute it and/or modify it
3677+ * under the terms of the GNU Lesser General Public License version 3,
3678+ * as published by the Free Software Foundation.
3679+ *
3680+ * This program is distributed in the hope that it will be useful,
3681+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3682+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3683+ * GNU Lesser General Public License for more details.
3684+ *
3685+ * You should have received a copy of the GNU Lesser General Public License
3686+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3687+ *
3688+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
3689+ */
3690+
3691+#ifndef MIR_GRAPHICS_ANDROID_REAL_HWC_WRAPPER_H_
3692+#define MIR_GRAPHICS_ANDROID_REAL_HWC_WRAPPER_H_
3693+
3694+#include "hwc_device.h"
3695+#include <memory>
3696+#include <hardware/hwcomposer.h>
3697+
3698+namespace mir
3699+{
3700+namespace graphics
3701+{
3702+namespace android
3703+{
3704+
3705+class RealHwcWrapper : public HwcWrapper
3706+{
3707+public:
3708+ RealHwcWrapper(std::shared_ptr<hwc_composer_device_1> const& hwc_device);
3709+
3710+ void prepare(hwc_display_contents_1_t&) const override;
3711+ void set(hwc_display_contents_1_t&) const override;
3712+private:
3713+ static size_t const num_displays{3}; //primary, external, virtual
3714+ std::shared_ptr<hwc_composer_device_1> const hwc_device;
3715+};
3716+
3717+}
3718+}
3719+}
3720+#endif /* MIR_GRAPHICS_ANDROID_REAL_HWC_WRAPPER_H_ */
3721
3722=== modified file 'src/platform/graphics/android/resource_factory.cpp'
3723--- src/platform/graphics/android/resource_factory.cpp 2014-02-10 09:07:48 +0000
3724+++ src/platform/graphics/android/resource_factory.cpp 2014-03-17 15:02:33 +0000
3725@@ -30,6 +30,7 @@
3726 #include "hwc_layerlist.h"
3727 #include "hwc_vsync.h"
3728 #include "android_display.h"
3729+#include "real_hwc_wrapper.h"
3730
3731 #include <boost/throw_exception.hpp>
3732 #include <stdexcept>
3733@@ -93,7 +94,8 @@
3734 {
3735 auto syncer = std::make_shared<mga::HWCVsync>();
3736 auto file_ops = std::make_shared<mga::RealSyncFileOps>();
3737- return std::make_shared<mga::HwcDevice>(hwc_native_device, syncer, file_ops);
3738+ auto wrapper = std::make_shared<mga::RealHwcWrapper>(hwc_native_device);
3739+ return std::make_shared<mga::HwcDevice>(hwc_native_device, wrapper, syncer, file_ops);
3740 }
3741
3742 std::shared_ptr<mga::DisplayDevice> mga::ResourceFactory::create_hwc_fb_device(
3743
3744=== modified file 'src/platform/graphics/display_configuration.cpp'
3745--- src/platform/graphics/display_configuration.cpp 2014-03-05 02:30:30 +0000
3746+++ src/platform/graphics/display_configuration.cpp 2014-03-17 15:02:33 +0000
3747@@ -19,6 +19,7 @@
3748 #include "mir/graphics/display_configuration.h"
3749
3750 #include <ostream>
3751+#include <algorithm>
3752
3753 namespace mg = mir::graphics;
3754
3755@@ -196,3 +197,52 @@
3756 return {top_left, {size.height.as_int(), size.width.as_int()}};
3757 }
3758 }
3759+
3760+bool mg::DisplayConfigurationOutput::valid() const
3761+{
3762+ if (!connected)
3763+ return !used;
3764+
3765+ auto const& f = std::find(pixel_formats.begin(), pixel_formats.end(),
3766+ current_format);
3767+ if (f == pixel_formats.end())
3768+ return false;
3769+
3770+ auto nmodes = modes.size();
3771+ if (preferred_mode_index >= nmodes || current_mode_index >= nmodes)
3772+ return false;
3773+
3774+ return true;
3775+}
3776+
3777+bool mg::DisplayConfiguration::valid() const
3778+{
3779+ bool all_valid = true;
3780+
3781+ for_each_output([&all_valid](DisplayConfigurationOutput const& out)
3782+ {
3783+ if (!out.valid())
3784+ all_valid = false;
3785+ });
3786+
3787+ return all_valid;
3788+}
3789+
3790+mg::UserDisplayConfigurationOutput::UserDisplayConfigurationOutput(
3791+ DisplayConfigurationOutput& master) :
3792+ id(master.id),
3793+ card_id(master.card_id),
3794+ type(master.type),
3795+ pixel_formats(master.pixel_formats),
3796+ modes(master.modes),
3797+ preferred_mode_index(master.preferred_mode_index),
3798+ physical_size_mm(master.physical_size_mm),
3799+ connected(master.connected),
3800+ used(master.used),
3801+ top_left(master.top_left),
3802+ current_mode_index(master.current_mode_index),
3803+ current_format(master.current_format),
3804+ power_mode(master.power_mode),
3805+ orientation(master.orientation)
3806+{
3807+}
3808
3809=== modified file 'src/platform/graphics/mesa/CMakeLists.txt'
3810--- src/platform/graphics/mesa/CMakeLists.txt 2014-02-28 13:51:43 +0000
3811+++ src/platform/graphics/mesa/CMakeLists.txt 2014-03-17 15:02:33 +0000
3812@@ -32,7 +32,6 @@
3813 internal_native_surface.cpp
3814 internal_client.cpp
3815 drm_close_threadsafe.cpp
3816- overlapping_output_grouping.cpp
3817 native_platform.cpp
3818 anonymous_shm_file.cpp
3819 shm_buffer.cpp
3820@@ -54,6 +53,8 @@
3821 ${GLESv2_LDFLAGS} ${GLESv2_LIBRARIES}
3822 )
3823
3824+install(TARGETS mirplatformgraphicsmesa LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mir/platformgraphics/mesa)
3825+
3826 if (MIR_TEST_PLATFORM STREQUAL "mesa")
3827 add_custom_command(TARGET mirplatformgraphicsmesa
3828 POST_BUILD
3829@@ -61,6 +62,11 @@
3830 COMMAND ${CMAKE_COMMAND} -E create_symlink mesa/$<TARGET_FILE_NAME:mirplatformgraphicsmesa> libmirplatformgraphics.so
3831 WORKING_DIRECTORY ${LIBRARY_OUTPUT_PATH}
3832 )
3833+
3834+ install(CODE
3835+ "execute_process(
3836+ COMMAND ln -sf mir/platformgraphics/mesa/libmirplatformgraphics.so
3837+ WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}
3838+ )"
3839+ )
3840 endif()
3841-
3842-install(TARGETS mirplatformgraphicsmesa LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mir/platformgraphics/mesa)
3843
3844=== modified file 'src/platform/graphics/mesa/cursor.cpp'
3845--- src/platform/graphics/mesa/cursor.cpp 2014-01-22 10:03:11 +0000
3846+++ src/platform/graphics/mesa/cursor.cpp 2014-03-17 15:02:33 +0000
3847@@ -28,15 +28,32 @@
3848 #include <stdexcept>
3849 #include <vector>
3850
3851+namespace mgm = mir::graphics::mesa;
3852+namespace geom = mir::geometry;
3853+
3854 namespace
3855 {
3856 #include "black_arrow.c"
3857 int const width = black_arrow.width;
3858 int const height = black_arrow.height;
3859-}
3860
3861-namespace mgm = mir::graphics::mesa;
3862-namespace geom = mir::geometry;
3863+// Transforms a relative position within the display bounds described by \a rect which is rotated with \a orientation
3864+geom::Displacement transform(geom::Rectangle const& rect, geom::Displacement const& vector, MirOrientation orientation)
3865+{
3866+ switch(orientation)
3867+ {
3868+ case mir_orientation_left:
3869+ return {vector.dy.as_int(), rect.size.width.as_int() -vector.dx.as_int()};
3870+ case mir_orientation_inverted:
3871+ return {rect.size.width.as_int() -vector.dx.as_int(), rect.size.height.as_int() - vector.dy.as_int()};
3872+ case mir_orientation_right:
3873+ return {rect.size.height.as_int() -vector.dy.as_int(), vector.dx.as_int()};
3874+ default:
3875+ case mir_orientation_normal:
3876+ return vector;
3877+ }
3878+}
3879+}
3880
3881 mgm::Cursor::GBMBOWrapper::GBMBOWrapper(gbm_device* gbm) :
3882 buffer(gbm_bo_create(
3883@@ -103,7 +120,7 @@
3884 }
3885
3886 void mgm::Cursor::for_each_used_output(
3887- std::function<void(KMSOutput&, geom::Rectangle const&)> const& f)
3888+ std::function<void(KMSOutput&, geom::Rectangle const&, MirOrientation orientation)> const& f)
3889 {
3890 current_configuration->with_current_configuration_do(
3891 [this,&f](KMSDisplayConfiguration const& kms_conf)
3892@@ -115,13 +132,7 @@
3893 uint32_t const connector_id = kms_conf.get_kms_connector_id(conf_output.id);
3894 auto output = output_container.get_kms_output_for(connector_id);
3895
3896- // TODO: Cursor rotation support (conf_output.extents())
3897- geom::Rectangle output_rect
3898- {
3899- conf_output.top_left,
3900- conf_output.modes[conf_output.current_mode_index].size
3901- };
3902- f(*output, output_rect);
3903+ f(*output, conf_output.extents(), conf_output.orientation);
3904 }
3905 });
3906 });
3907@@ -131,15 +142,15 @@
3908 geometry::Point position,
3909 ForceCursorState force_state)
3910 {
3911- for_each_used_output([&](KMSOutput& output, geom::Rectangle const& output_rect)
3912+ for_each_used_output([&](KMSOutput& output, geom::Rectangle const& output_rect, MirOrientation orientation)
3913 {
3914 if (output_rect.contains(position))
3915 {
3916- auto dp = position - output_rect.top_left;
3917+ auto dp = transform(output_rect, position - output_rect.top_left, orientation);
3918 output.move_cursor({dp.dx.as_int(), dp.dy.as_int()});
3919- if (force_state || !output.has_cursor())
3920+ if (force_state || !output.has_cursor()) // TODO - or if orientation had changed - then set buffer..
3921 {
3922- output.set_cursor(buffer);
3923+ output.set_cursor(buffer);// TODO - select rotated buffer image
3924 }
3925 }
3926 else
3927
3928=== modified file 'src/platform/graphics/mesa/cursor.h'
3929--- src/platform/graphics/mesa/cursor.h 2014-01-22 10:03:11 +0000
3930+++ src/platform/graphics/mesa/cursor.h 2014-03-17 15:02:33 +0000
3931@@ -21,6 +21,7 @@
3932 #define MIR_GRAPHICS_MESA_CURSOR_H_
3933
3934 #include "mir/graphics/cursor.h"
3935+#include "mir_toolkit/common.h"
3936
3937 #include <gbm.h>
3938 #include <memory>
3939@@ -73,7 +74,7 @@
3940
3941 private:
3942 enum ForceCursorState { UpdateState, ForceState };
3943- void for_each_used_output(std::function<void(KMSOutput&, geometry::Rectangle const&)> const& f);
3944+ void for_each_used_output(std::function<void(KMSOutput&, geometry::Rectangle const&, MirOrientation orientation)> const& f);
3945 void place_cursor_at(geometry::Point position, ForceCursorState force_state);
3946
3947 KMSOutputContainer& output_container;
3948
3949=== modified file 'src/platform/graphics/mesa/display.cpp'
3950--- src/platform/graphics/mesa/display.cpp 2014-03-05 02:30:30 +0000
3951+++ src/platform/graphics/mesa/display.cpp 2014-03-17 15:02:33 +0000
3952@@ -24,7 +24,7 @@
3953 #include "kms_output.h"
3954 #include "kms_page_flipper.h"
3955 #include "virtual_terminal.h"
3956-#include "overlapping_output_grouping.h"
3957+#include "mir/graphics/overlapping_output_grouping.h"
3958
3959 #include "mir/graphics/display_report.h"
3960 #include "mir/graphics/gl_context.h"
3961@@ -128,6 +128,12 @@
3962
3963 void mgm::Display::configure(mg::DisplayConfiguration const& conf)
3964 {
3965+ if (!conf.valid())
3966+ {
3967+ BOOST_THROW_EXCEPTION(
3968+ std::logic_error("Invalid or inconsistent display configuration"));
3969+ }
3970+
3971 {
3972 std::lock_guard<std::mutex> lg{configuration_mutex};
3973
3974
3975=== modified file 'src/platform/graphics/mesa/linux_virtual_terminal.cpp'
3976--- src/platform/graphics/mesa/linux_virtual_terminal.cpp 2014-01-22 10:03:11 +0000
3977+++ src/platform/graphics/mesa/linux_virtual_terminal.cpp 2014-03-17 15:02:33 +0000
3978@@ -36,11 +36,12 @@
3979
3980 namespace mgm = mir::graphics::mesa;
3981
3982-mgm::LinuxVirtualTerminal::LinuxVirtualTerminal(
3983- std::shared_ptr<VTFileOperations> const& fops,
3984+mgm::LinuxVirtualTerminal::LinuxVirtualTerminal(std::shared_ptr<VTFileOperations> const& fops,
3985+ std::unique_ptr<PosixProcessOperations> pops,
3986 int vt_number,
3987 std::shared_ptr<DisplayReport> const& report)
3988 : fops{fops},
3989+ pops{std::move(pops)},
3990 report{report},
3991 vt_fd{fops, open_vt(vt_number)},
3992 prev_kd_mode{0},
3993@@ -233,9 +234,9 @@
3994 {
3995 // we should only try to create a new session in order to become the session
3996 // and group leader if we are not already the session leader
3997- if (getpid() != getsid(0))
3998+ if (pops->getpid() != pops->getsid(0))
3999 {
4000- if (getpid() == getpgid(0) && setpgid(0, getpgid(getppid())) < 0)
4001+ if (pops->getpid() == pops->getpgid(0) && pops->setpgid(0, pops->getpgid(pops->getppid())) < 0)
4002 {
4003 BOOST_THROW_EXCEPTION(
4004 boost::enable_error_info(
4005@@ -244,7 +245,7 @@
4006 }
4007
4008 /* become process group leader */
4009- if (setsid() < 0)
4010+ if (pops->setsid() < 0)
4011 {
4012 BOOST_THROW_EXCEPTION(
4013 boost::enable_error_info(
4014
4015=== modified file 'src/platform/graphics/mesa/linux_virtual_terminal.h'
4016--- src/platform/graphics/mesa/linux_virtual_terminal.h 2014-01-22 10:03:11 +0000
4017+++ src/platform/graphics/mesa/linux_virtual_terminal.h 2014-03-17 15:02:33 +0000
4018@@ -55,10 +55,30 @@
4019 VTFileOperations& operator=(VTFileOperations const&) = delete;
4020 };
4021
4022+class PosixProcessOperations
4023+{
4024+public:
4025+ virtual ~PosixProcessOperations() = default;
4026+
4027+ virtual pid_t getpid() const = 0;
4028+ virtual pid_t getppid() const = 0;
4029+ virtual pid_t getpgid(pid_t process) const = 0;
4030+ virtual pid_t getsid(pid_t process) const = 0;
4031+
4032+ virtual int setpgid(pid_t process, pid_t group) = 0;
4033+ virtual pid_t setsid() = 0;
4034+
4035+protected:
4036+ PosixProcessOperations() = default;
4037+ PosixProcessOperations(PosixProcessOperations const&) = delete;
4038+ PosixProcessOperations& operator=(PosixProcessOperations const&) = delete;
4039+};
4040+
4041 class LinuxVirtualTerminal : public VirtualTerminal
4042 {
4043 public:
4044 LinuxVirtualTerminal(std::shared_ptr<VTFileOperations> const& fops,
4045+ std::unique_ptr<PosixProcessOperations> pops,
4046 int vt_number,
4047 std::shared_ptr<DisplayReport> const& report);
4048 ~LinuxVirtualTerminal() noexcept(true);
4049@@ -89,6 +109,7 @@
4050
4051
4052 std::shared_ptr<VTFileOperations> const fops;
4053+ std::unique_ptr<PosixProcessOperations> const pops;
4054 std::shared_ptr<DisplayReport> const report;
4055 FDWrapper const vt_fd;
4056 int prev_kd_mode;
4057
4058=== modified file 'src/platform/graphics/mesa/native_platform.cpp'
4059--- src/platform/graphics/mesa/native_platform.cpp 2014-03-04 04:19:26 +0000
4060+++ src/platform/graphics/mesa/native_platform.cpp 2014-03-17 15:02:33 +0000
4061@@ -25,8 +25,13 @@
4062 #include "mir/graphics/platform_ipc_package.h"
4063 #include "mir/graphics/nested_context.h"
4064
4065+#include "internal_client.h"
4066+#include "internal_native_display.h"
4067+
4068 #include <boost/exception/errinfo_errno.hpp>
4069 #include <boost/throw_exception.hpp>
4070+
4071+#include <mutex>
4072 #include <stdexcept>
4073
4074 namespace mg = mir::graphics;
4075@@ -42,6 +47,11 @@
4076 nested_context->drm_set_gbm_device(gbm.device);
4077 }
4078
4079+mgm::NativePlatform::~NativePlatform()
4080+{
4081+ finish_internal_native_display();
4082+}
4083+
4084 std::shared_ptr<mg::GraphicBufferAllocator> mgm::NativePlatform::create_buffer_allocator(
4085 std::shared_ptr<mg::BufferInitializer> const& buffer_initializer)
4086 {
4087@@ -82,7 +92,8 @@
4088
4089 std::shared_ptr<mg::InternalClient> mgm::NativePlatform::create_internal_client()
4090 {
4091- BOOST_THROW_EXCEPTION(std::runtime_error("MesaNativePlatform::create_internal_client is not implemented yet!"));
4092+ auto nd = ensure_internal_native_display(get_ipc_package());
4093+ return std::make_shared<mgm::InternalClient>(nd);
4094 }
4095
4096 void mgm::NativePlatform::fill_ipc_package(BufferIPCPacker* packer, Buffer const* buffer) const
4097@@ -98,9 +109,45 @@
4098 }
4099
4100 packer->pack_stride(buffer->stride());
4101+ packer->pack_flags(native_handle->flags);
4102+ packer->pack_size(buffer->size());
4103 }
4104
4105 extern "C" std::shared_ptr<mg::NativePlatform> create_native_platform(std::shared_ptr<mg::DisplayReport> const& /*report*/)
4106 {
4107 return std::make_shared<mgm::NativePlatform>();
4108 }
4109+
4110+namespace
4111+{
4112+std::shared_ptr<mgm::InternalNativeDisplay> native_display = nullptr;
4113+std::mutex native_display_guard;
4114+}
4115+
4116+bool mgm::NativePlatform::internal_native_display_in_use()
4117+{
4118+ std::unique_lock<std::mutex> lg(native_display_guard);
4119+ return native_display != nullptr;
4120+}
4121+
4122+std::shared_ptr<mgm::InternalNativeDisplay> mgm::NativePlatform::internal_native_display()
4123+{
4124+ std::unique_lock<std::mutex> lg(native_display_guard);
4125+ return native_display;
4126+}
4127+
4128+std::shared_ptr<mgm::InternalNativeDisplay> mgm::NativePlatform::ensure_internal_native_display(
4129+ std::shared_ptr<mg::PlatformIPCPackage> const& package)
4130+{
4131+ std::unique_lock<std::mutex> lg(native_display_guard);
4132+ if (!native_display)
4133+ native_display = std::make_shared<mgm::InternalNativeDisplay>(package);
4134+ return native_display;
4135+}
4136+
4137+void mgm::NativePlatform::finish_internal_native_display()
4138+{
4139+ std::unique_lock<std::mutex> lg(native_display_guard);
4140+ native_display.reset();
4141+}
4142+
4143
4144=== modified file 'src/platform/graphics/mesa/native_platform.h'
4145--- src/platform/graphics/mesa/native_platform.h 2014-01-22 10:03:11 +0000
4146+++ src/platform/graphics/mesa/native_platform.h 2014-03-17 15:02:33 +0000
4147@@ -30,20 +30,30 @@
4148 {
4149 namespace mesa
4150 {
4151+class InternalNativeDisplay;
4152+
4153 class NativePlatform : public graphics::NativePlatform
4154 {
4155 public:
4156+ virtual ~NativePlatform();
4157+
4158 void initialize(std::shared_ptr<NestedContext> const& nested_context);
4159 std::shared_ptr<GraphicBufferAllocator> create_buffer_allocator(
4160 std::shared_ptr<BufferInitializer> const& buffer_initializer) override;
4161 std::shared_ptr<PlatformIPCPackage> get_ipc_package() override;
4162 std::shared_ptr<InternalClient> create_internal_client() override;
4163 void fill_ipc_package(BufferIPCPacker* packer, Buffer const* buffer) const override;
4164+
4165+ static std::shared_ptr<InternalNativeDisplay> internal_native_display();
4166+ static bool internal_native_display_in_use();
4167
4168 private:
4169 int drm_fd;
4170 std::shared_ptr<NestedContext> nested_context;
4171 helpers::GBMHelper gbm;
4172+
4173+ static std::shared_ptr<InternalNativeDisplay> ensure_internal_native_display(std::shared_ptr<PlatformIPCPackage> const& package);
4174+ static void finish_internal_native_display();
4175 };
4176 }
4177 }
4178
4179=== modified file 'src/platform/graphics/mesa/platform.cpp'
4180--- src/platform/graphics/mesa/platform.cpp 2014-02-12 03:14:55 +0000
4181+++ src/platform/graphics/mesa/platform.cpp 2014-03-17 15:02:33 +0000
4182@@ -17,6 +17,7 @@
4183 */
4184
4185 #include "platform.h"
4186+#include "native_platform.h"
4187 #include "buffer_allocator.h"
4188 #include "display.h"
4189 #include "internal_client.h"
4190@@ -89,6 +90,34 @@
4191 }
4192 };
4193
4194+struct RealPosixProcessOperations : public mgm::PosixProcessOperations
4195+{
4196+ pid_t getpid() const override
4197+ {
4198+ return ::getpid();
4199+ }
4200+ pid_t getppid() const override
4201+ {
4202+ return ::getppid();
4203+ }
4204+ pid_t getpgid(pid_t process) const override
4205+ {
4206+ return ::getpgid(process);
4207+ }
4208+ pid_t getsid(pid_t process) const override
4209+ {
4210+ return ::getsid(process);
4211+ }
4212+ int setpgid(pid_t process, pid_t group) override
4213+ {
4214+ return ::setpgid(process, group);
4215+ }
4216+ pid_t setsid() override
4217+ {
4218+ return ::setsid();
4219+ }
4220+};
4221+
4222 }
4223
4224 std::shared_ptr<mgm::InternalNativeDisplay> mgm::Platform::internal_native_display;
4225@@ -169,8 +198,10 @@
4226 extern "C" std::shared_ptr<mg::Platform> mg::create_platform(std::shared_ptr<mo::Option> const& options, std::shared_ptr<DisplayReport> const& report)
4227 {
4228 auto real_fops = std::make_shared<RealVTFileOperations>();
4229+ auto real_pops = std::unique_ptr<RealPosixProcessOperations>(new RealPosixProcessOperations{});
4230 auto vt = std::make_shared<mgm::LinuxVirtualTerminal>(
4231 real_fops,
4232+ std::move(real_pops),
4233 options->get<int>("vt"), // TODO This option is mesa specific
4234 report);
4235
4236@@ -179,6 +210,12 @@
4237
4238 extern "C" int mir_server_mesa_egl_native_display_is_valid(MirMesaEGLNativeDisplay* display)
4239 {
4240- return ((mgm::Platform::internal_display_clients_present) &&
4241- (display == mgm::Platform::internal_native_display.get()));
4242+ bool nested_internal_display_in_use = mgm::NativePlatform::internal_native_display_in_use();
4243+ bool host_internal_display_in_use = mgm::Platform::internal_display_clients_present;
4244+
4245+ if (host_internal_display_in_use)
4246+ return (display == mgm::Platform::internal_native_display.get());
4247+ else if (nested_internal_display_in_use)
4248+ return (display == mgm::NativePlatform::internal_native_display().get());
4249+ return 0;
4250 }
4251
4252=== modified file 'src/platform/graphics/mesa/real_kms_display_configuration.cpp'
4253--- src/platform/graphics/mesa/real_kms_display_configuration.cpp 2014-03-05 02:30:30 +0000
4254+++ src/platform/graphics/mesa/real_kms_display_configuration.cpp 2014-03-17 15:02:33 +0000
4255@@ -66,11 +66,6 @@
4256 return static_cast<mg::DisplayConfigurationOutputType>(connector_type);
4257 }
4258
4259-bool format_available_in_pixel_formats(MirPixelFormat format, mg::DisplayConfigurationOutput const& output)
4260-{
4261- return output.pixel_formats.end() != find(output.pixel_formats.begin(), output.pixel_formats.end(), format);
4262-}
4263-
4264 }
4265
4266 mgm::RealKMSDisplayConfiguration::RealKMSDisplayConfiguration(int drm_fd)
4267@@ -112,36 +107,13 @@
4268 f(output);
4269 }
4270
4271-void mgm::RealKMSDisplayConfiguration::configure_output(
4272- DisplayConfigurationOutputId id, bool used,
4273- geometry::Point top_left, size_t mode_index,
4274- MirPixelFormat format, MirPowerMode power_mode, MirOrientation orientation)
4275+void mgm::RealKMSDisplayConfiguration::for_each_output(
4276+ std::function<void(UserDisplayConfigurationOutput&)> f)
4277 {
4278- auto iter = find_output_with_id(id);
4279-
4280- if (iter != outputs.end())
4281- {
4282- auto& output = *iter;
4283-
4284- if (used && mode_index >= output.modes.size())
4285- BOOST_THROW_EXCEPTION(std::runtime_error("Invalid mode_index for used output"));
4286-
4287- if (used && !valid_pixel_format(format))
4288- BOOST_THROW_EXCEPTION(std::runtime_error("Invalid format for used output"));
4289-
4290- if (used && !format_available_in_pixel_formats(format, output))
4291- BOOST_THROW_EXCEPTION(std::runtime_error("Format not available for used output"));
4292-
4293- output.used = used;
4294- output.top_left = top_left;
4295- output.current_mode_index = mode_index;
4296- output.current_format = format;
4297- output.power_mode = power_mode;
4298- output.orientation = orientation;
4299- }
4300- else
4301- {
4302- BOOST_THROW_EXCEPTION(std::runtime_error("Trying to configure invalid output"));
4303+ for (auto& output : outputs)
4304+ {
4305+ UserDisplayConfigurationOutput user(output);
4306+ f(user);
4307 }
4308 }
4309
4310
4311=== modified file 'src/platform/graphics/mesa/real_kms_display_configuration.h'
4312--- src/platform/graphics/mesa/real_kms_display_configuration.h 2014-03-05 02:30:30 +0000
4313+++ src/platform/graphics/mesa/real_kms_display_configuration.h 2014-03-17 15:02:33 +0000
4314@@ -39,10 +39,7 @@
4315
4316 void for_each_card(std::function<void(DisplayConfigurationCard const&)> f) const override;
4317 void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const override;
4318- void configure_output(DisplayConfigurationOutputId id, bool used,
4319- geometry::Point top_left, size_t mode_index,
4320- MirPixelFormat format, MirPowerMode power_mode,
4321- MirOrientation orientation) override;
4322+ void for_each_output(std::function<void(UserDisplayConfigurationOutput&)> f) override;
4323
4324 uint32_t get_kms_connector_id(DisplayConfigurationOutputId id) const;
4325 size_t get_kms_mode_index(DisplayConfigurationOutputId id, size_t conf_mode_index) const;
4326
4327=== renamed file 'src/platform/graphics/mesa/overlapping_output_grouping.cpp' => 'src/platform/graphics/overlapping_output_grouping.cpp'
4328--- src/platform/graphics/mesa/overlapping_output_grouping.cpp 2014-01-22 10:03:11 +0000
4329+++ src/platform/graphics/overlapping_output_grouping.cpp 2014-03-17 15:02:33 +0000
4330@@ -16,7 +16,7 @@
4331 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
4332 */
4333
4334-#include "overlapping_output_grouping.h"
4335+#include "mir/graphics/overlapping_output_grouping.h"
4336
4337 #include "mir/graphics/display_configuration.h"
4338 #include "mir/geometry/rectangle.h"
4339@@ -25,7 +25,6 @@
4340 #include <unordered_set>
4341
4342 namespace mg = mir::graphics;
4343-namespace mgm = mir::graphics::mesa;
4344 namespace geom = mir::geometry;
4345
4346 namespace
4347@@ -33,7 +32,7 @@
4348
4349 struct DCOutputHash
4350 {
4351- size_t operator()(mg::DisplayConfigurationOutput const& o) const { return o.id.as_value(); };
4352+ size_t operator()(mg::DisplayConfigurationOutput const& o) const { return o.id.as_value(); }
4353 };
4354
4355 struct DCOutputEqual
4356@@ -51,7 +50,7 @@
4357 * OverlappingOutputGroup *
4358 **************************/
4359
4360-geom::Rectangle mgm::OverlappingOutputGroup::bounding_rectangle() const
4361+geom::Rectangle mg::OverlappingOutputGroup::bounding_rectangle() const
4362 {
4363 geom::Rectangles rectangles;
4364
4365@@ -61,7 +60,7 @@
4366 return rectangles.bounding_rectangle();
4367 }
4368
4369-void mgm::OverlappingOutputGroup::for_each_output(
4370+void mg::OverlappingOutputGroup::for_each_output(
4371 std::function<void(DisplayConfigurationOutput const&)> const& f) const
4372 {
4373 for (auto const& output : outputs)
4374@@ -72,7 +71,7 @@
4375 * OverlappingOutputGrouping *
4376 *****************************/
4377
4378-mgm::OverlappingOutputGrouping::OverlappingOutputGrouping(DisplayConfiguration const& conf)
4379+mg::OverlappingOutputGrouping::OverlappingOutputGrouping(DisplayConfiguration const& conf)
4380 {
4381 conf.for_each_output([&](DisplayConfigurationOutput const& conf_output)
4382 {
4383@@ -85,14 +84,14 @@
4384
4385 }
4386
4387-void mgm::OverlappingOutputGrouping::for_each_group(
4388+void mg::OverlappingOutputGrouping::for_each_group(
4389 std::function<void(OverlappingOutputGroup const& group)> const& f)
4390 {
4391 for (auto const& g : groups)
4392 f(g);
4393 }
4394
4395-void mgm::OverlappingOutputGrouping::add_output(DisplayConfigurationOutput const& conf_output)
4396+void mg::OverlappingOutputGrouping::add_output(DisplayConfigurationOutput const& conf_output)
4397 {
4398 std::vector<size_t> overlapping_groups;
4399
4400
4401=== modified file 'src/platform/options/default_configuration.cpp'
4402--- src/platform/options/default_configuration.cpp 2014-03-04 14:19:36 +0000
4403+++ src/platform/options/default_configuration.cpp 2014-03-17 15:02:33 +0000
4404@@ -34,7 +34,6 @@
4405 char const* const mo::scene_report_opt = "scene-report";
4406 char const* const mo::input_report_opt = "input-report";
4407 char const* const mo::host_socket_opt = "host-socket";
4408-char const* const mo::standalone_opt = "standalone";
4409 char const* const mo::frontend_threads_opt = "ipc-thread-pool";
4410 char const* const mo::name_opt = "name";
4411 char const* const mo::offscreen_opt = "offscreen";
4412@@ -70,12 +69,10 @@
4413 namespace po = boost::program_options;
4414
4415 add_options()
4416- (standalone_opt, po::value<bool>(),
4417- "Run mir in standalone mode. [bool:default=false]")
4418 (host_socket_opt, po::value<std::string>(),
4419- "Host socket filename. [string:default={$MIR_SOCKET,$XDG_RUNTIME_DIR/mir_socket}]")
4420+ "Host socket filename")
4421 (server_socket_opt, po::value<std::string>()->default_value(::mir::default_server_socket),
4422- "Socket filename.")
4423+ "Socket filename [string:default=$XDG_RUNTIME_DIR/mir_socket or /tmp/mir_socket]")
4424 (no_server_socket_opt, "Do not provide a socket filename for client connections")
4425 (platform_graphics_lib, po::value<std::string>()->default_value(default_platform_graphics_lib),
4426 "Library to use for platform graphics support")
4427
4428=== modified file 'src/server/CMakeLists.txt'
4429--- src/server/CMakeLists.txt 2014-02-28 13:51:43 +0000
4430+++ src/server/CMakeLists.txt 2014-03-17 15:02:33 +0000
4431@@ -94,7 +94,7 @@
4432 )
4433 endif()
4434
4435-set(MIRSERVER_ABI 16)
4436+set(MIRSERVER_ABI 17)
4437
4438 set_target_properties(
4439 mirserver
4440
4441=== modified file 'src/server/compositor/buffer_bundle.h'
4442--- src/server/compositor/buffer_bundle.h 2014-02-10 09:07:48 +0000
4443+++ src/server/compositor/buffer_bundle.h 2014-03-17 15:02:33 +0000
4444@@ -46,6 +46,7 @@
4445 virtual void allow_framedropping(bool dropping_allowed) = 0;
4446 virtual void force_requests_to_complete() = 0;
4447 virtual void resize(const geometry::Size &newsize) = 0;
4448+ virtual int buffers_ready_for_compositor() const = 0;
4449 protected:
4450 BufferBundle() = default;
4451 BufferBundle(BufferBundle const&) = delete;
4452
4453=== modified file 'src/server/compositor/buffer_stream_surfaces.cpp'
4454--- src/server/compositor/buffer_stream_surfaces.cpp 2014-02-10 09:07:48 +0000
4455+++ src/server/compositor/buffer_stream_surfaces.cpp 2014-03-17 15:02:33 +0000
4456@@ -83,3 +83,8 @@
4457 {
4458 buffer_bundle->allow_framedropping(allow);
4459 }
4460+
4461+int mc::BufferStreamSurfaces::buffers_ready_for_compositor() const
4462+{
4463+ return buffer_bundle->buffers_ready_for_compositor();
4464+}
4465
4466=== modified file 'src/server/compositor/buffer_stream_surfaces.h'
4467--- src/server/compositor/buffer_stream_surfaces.h 2014-02-10 09:07:48 +0000
4468+++ src/server/compositor/buffer_stream_surfaces.h 2014-03-17 15:02:33 +0000
4469@@ -50,6 +50,7 @@
4470 void resize(geometry::Size const& size) override;
4471 void allow_framedropping(bool) override;
4472 void force_requests_to_complete() override;
4473+ int buffers_ready_for_compositor() const override;
4474
4475 protected:
4476 BufferStreamSurfaces(const BufferStreamSurfaces&) = delete;
4477
4478=== modified file 'src/server/compositor/bypass.cpp'
4479--- src/server/compositor/bypass.cpp 2014-03-04 04:19:26 +0000
4480+++ src/server/compositor/bypass.cpp 2014-03-17 15:02:33 +0000
4481@@ -16,84 +16,46 @@
4482 * Authored by: Daniel van Vugt <daniel.van.vugt@canonical.com>
4483 */
4484
4485-#include "mir/compositor/compositing_criteria.h"
4486+#include "mir/graphics/renderable.h"
4487 #include "mir/graphics/display_buffer.h"
4488 #include "bypass.h"
4489
4490 using namespace mir;
4491 using namespace mir::compositor;
4492+using namespace mir::graphics;
4493
4494 BypassFilter::BypassFilter(const graphics::DisplayBuffer &display_buffer)
4495 : display_buffer(display_buffer)
4496 {
4497- const geometry::Rectangle &rect = display_buffer.view_area();
4498- int width = rect.size.width.as_int();
4499- int height = rect.size.height.as_int();
4500-
4501- /*
4502- * For a surface to exactly fit the display_buffer, its transformation
4503- * will look exactly like this:
4504- */
4505- fullscreen[0][0] = width;
4506- fullscreen[0][1] = 0.0f;
4507- fullscreen[0][2] = 0.0f;
4508- fullscreen[0][3] = 0.0f;
4509-
4510- fullscreen[1][0] = 0.0f;
4511- fullscreen[1][1] = height;
4512- fullscreen[1][2] = 0.0f;
4513- fullscreen[1][3] = 0.0f;
4514-
4515- fullscreen[2][0] = 0.0f;
4516- fullscreen[2][1] = 0.0f;
4517- fullscreen[2][2] = 0.0f;
4518- fullscreen[2][3] = 0.0f;
4519-
4520- fullscreen[3][0] = rect.top_left.x.as_int() + width / 2;
4521- fullscreen[3][1] = rect.top_left.y.as_int() + height / 2;
4522- fullscreen[3][2] = 0.0f;
4523- fullscreen[3][3] = 1.0f;
4524 }
4525
4526-bool BypassFilter::operator()(const CompositingCriteria &criteria)
4527+bool BypassFilter::operator()(const Renderable &renderable)
4528 {
4529 if (!all_orthogonal)
4530 return false;
4531
4532- const glm::mat4 &trans = criteria.transformation();
4533- bool orthogonal =
4534- trans[0][1] == 0.0f &&
4535- trans[0][2] == 0.0f &&
4536- trans[0][3] == 0.0f &&
4537- trans[1][0] == 0.0f &&
4538- trans[1][2] == 0.0f &&
4539- trans[1][3] == 0.0f &&
4540- trans[2][0] == 0.0f &&
4541- trans[2][1] == 0.0f &&
4542- trans[2][2] == 0.0f &&
4543- trans[2][3] == 0.0f &&
4544- trans[3][2] == 0.0f &&
4545- trans[3][3] == 1.0f;
4546-
4547 // Any weird transformations? Then we can't risk any bypass
4548- if (!orthogonal)
4549+ static const glm::mat4 identity;
4550+ if (renderable.transformation() != identity)
4551 {
4552 all_orthogonal = false;
4553 return false;
4554 }
4555
4556+ auto const& view_area = display_buffer.view_area();
4557+
4558 // Not weirdly transformed but also not on this monitor? Don't care...
4559 // This will also check the surface is not hidden and has been posted.
4560- if (!criteria.should_be_rendered_in(display_buffer.view_area()))
4561+ if (!renderable.should_be_rendered_in(view_area))
4562 return false;
4563
4564 topmost_fits = false;
4565
4566- if (criteria.alpha() != 1.0f || criteria.shaped())
4567+ if (renderable.alpha() != 1.0f || renderable.shaped())
4568 return false;
4569
4570 // Transformed perfectly to fit the monitor? Bypass!
4571- topmost_fits = criteria.transformation() == fullscreen;
4572+ topmost_fits = renderable.screen_position() == view_area;
4573 return topmost_fits;
4574 }
4575
4576@@ -102,13 +64,12 @@
4577 return all_orthogonal && topmost_fits;
4578 }
4579
4580-void BypassMatch::operator()(const CompositingCriteria &,
4581- compositor::BufferStream &stream)
4582+void BypassMatch::operator()(const Renderable &r)
4583 {
4584- latest = &stream;
4585+ latest = &r;
4586 }
4587
4588-compositor::BufferStream *BypassMatch::topmost_fullscreen() const
4589+const Renderable *BypassMatch::topmost_fullscreen() const
4590 {
4591 return latest;
4592 }
4593
4594=== modified file 'src/server/compositor/bypass.h'
4595--- src/server/compositor/bypass.h 2014-03-04 04:19:26 +0000
4596+++ src/server/compositor/bypass.h 2014-03-17 15:02:33 +0000
4597@@ -20,7 +20,6 @@
4598 #define MIR_COMPOSITOR_BYPASS_H_
4599
4600 #include "mir/compositor/scene.h"
4601-#include "glm/glm.hpp"
4602
4603 namespace mir
4604 {
4605@@ -30,32 +29,29 @@
4606 }
4607 namespace compositor
4608 {
4609-class CompositingCriteria;
4610
4611 class BypassFilter : public FilterForScene
4612 {
4613 public:
4614 BypassFilter(const graphics::DisplayBuffer &display_buffer);
4615- bool operator()(const CompositingCriteria &criteria) override;
4616+ bool operator()(const graphics::Renderable &) override;
4617 bool fullscreen_on_top() const;
4618
4619 private:
4620 bool all_orthogonal = true;
4621 bool topmost_fits = false;
4622- glm::mat4 fullscreen;
4623 const graphics::DisplayBuffer &display_buffer;
4624 };
4625
4626 class BypassMatch : public OperatorForScene
4627 {
4628 public:
4629- void operator()(const CompositingCriteria &,
4630- compositor::BufferStream &stream) override;
4631- compositor::BufferStream *topmost_fullscreen() const;
4632+ void operator()(const graphics::Renderable &) override;
4633+ const graphics::Renderable *topmost_fullscreen() const;
4634
4635 private:
4636- // This has to be a pointer. We have no control over BufferStream lifetime
4637- compositor::BufferStream *latest = nullptr;
4638+ // This has to be a pointer. We have no control over Renderable lifetime
4639+ const graphics::Renderable *latest = nullptr;
4640 };
4641
4642 } // namespace compositor
4643
4644=== modified file 'src/server/compositor/compositing_screencast.cpp'
4645--- src/server/compositor/compositing_screencast.cpp 2014-02-05 16:32:31 +0000
4646+++ src/server/compositor/compositing_screencast.cpp 2014-03-17 15:02:33 +0000
4647@@ -60,15 +60,21 @@
4648 }
4649
4650 mf::ScreencastSessionId mc::CompositingScreencast::create_session(
4651- graphics::DisplayConfigurationOutputId output_id)
4652+ geom::Rectangle const& region,
4653+ geom::Size const& size,
4654+ MirPixelFormat const pixel_format)
4655 {
4656- geom::Rectangle extents;
4657- MirPixelFormat pixel_format;
4658- std::tie(extents,pixel_format) = output_info_for(output_id);
4659-
4660+ if (size.width.as_int() == 0 ||
4661+ size.height.as_int() == 0 ||
4662+ region.size.width.as_int() == 0 ||
4663+ region.size.height.as_int() == 0 ||
4664+ pixel_format == mir_pixel_format_invalid)
4665+ {
4666+ BOOST_THROW_EXCEPTION(std::runtime_error("Invalid parameters"));
4667+ }
4668 std::lock_guard<decltype(session_mutex)> lock{session_mutex};
4669 auto const id = next_available_session_id();
4670- session_contexts[id] = create_session_context(extents, pixel_format);
4671+ session_contexts[id] = create_session_context(region, size, pixel_format);
4672
4673 return id;
4674 }
4675@@ -115,43 +121,14 @@
4676 BOOST_THROW_EXCEPTION(std::runtime_error("Too many screencast sessions!"));
4677 }
4678
4679-std::pair<geom::Rectangle,MirPixelFormat>
4680-mc::CompositingScreencast::output_info_for(
4681- graphics::DisplayConfigurationOutputId output_id)
4682-{
4683- auto const conf = display->configuration();
4684- geom::Rectangle extents;
4685- MirPixelFormat pixel_format{mir_pixel_format_invalid};
4686-
4687- conf->for_each_output(
4688- [&](mg::DisplayConfigurationOutput const& output)
4689- {
4690- if (output.id == output_id &&
4691- output.connected && output.used &&
4692- output.current_mode_index < output.modes.size())
4693- {
4694- extents = output.extents();
4695- pixel_format = output.current_format;
4696- }
4697- });
4698-
4699- if (extents == geom::Rectangle() ||
4700- pixel_format == mir_pixel_format_invalid)
4701- {
4702- BOOST_THROW_EXCEPTION(
4703- std::runtime_error("Invalid output for screen capture"));
4704- }
4705-
4706- return {extents, pixel_format};
4707-}
4708-
4709 std::shared_ptr<mc::detail::ScreencastSessionContext>
4710 mc::CompositingScreencast::create_session_context(
4711 geometry::Rectangle const& rect,
4712+ geometry::Size const& size,
4713 MirPixelFormat pixel_format)
4714 {
4715 mg::BufferProperties buffer_properties{
4716- rect.size,
4717+ size,
4718 pixel_format,
4719 mg::BufferUsage::hardware};
4720
4721
4722=== modified file 'src/server/compositor/compositing_screencast.h'
4723--- src/server/compositor/compositing_screencast.h 2014-02-05 16:32:31 +0000
4724+++ src/server/compositor/compositing_screencast.h 2014-03-17 15:02:33 +0000
4725@@ -48,16 +48,18 @@
4726 std::shared_ptr<DisplayBufferCompositorFactory> const& db_compositor_factory);
4727
4728 frontend::ScreencastSessionId create_session(
4729- graphics::DisplayConfigurationOutputId output_id);
4730+ geometry::Rectangle const& region,
4731+ geometry::Size const& size,
4732+ MirPixelFormat pixel_format);
4733 void destroy_session(frontend::ScreencastSessionId id);
4734 std::shared_ptr<graphics::Buffer> capture(frontend::ScreencastSessionId id);
4735
4736 private:
4737 frontend::ScreencastSessionId next_available_session_id();
4738- std::pair<geometry::Rectangle,MirPixelFormat> output_info_for(
4739- graphics::DisplayConfigurationOutputId output_id);
4740 std::shared_ptr<detail::ScreencastSessionContext>
4741- create_session_context(geometry::Rectangle const& rect, MirPixelFormat pixel_format);
4742+ create_session_context(geometry::Rectangle const& rect,
4743+ geometry::Size const& size,
4744+ MirPixelFormat pixel_format);
4745
4746 std::mutex session_mutex;
4747 std::shared_ptr<graphics::Display> const display;
4748
4749=== modified file 'src/server/compositor/default_configuration.cpp'
4750--- src/server/compositor/default_configuration.cpp 2014-02-28 13:51:43 +0000
4751+++ src/server/compositor/default_configuration.cpp 2014-03-17 15:02:33 +0000
4752@@ -25,6 +25,7 @@
4753 #include "compositing_screencast.h"
4754
4755 #include "mir/frontend/screencast.h"
4756+#include "mir/options/configuration.h"
4757
4758 #include <boost/throw_exception.hpp>
4759
4760@@ -59,10 +60,12 @@
4761 return compositor(
4762 [this]()
4763 {
4764- return std::make_shared<mc::MultiThreadedCompositor>(the_display(),
4765- the_scene(),
4766- the_display_buffer_compositor_factory(),
4767- the_compositor_report());
4768+ return std::make_shared<mc::MultiThreadedCompositor>(
4769+ the_display(),
4770+ the_scene(),
4771+ the_display_buffer_compositor_factory(),
4772+ the_compositor_report(),
4773+ !the_options()->is_set(options::host_socket_opt));
4774 });
4775 }
4776
4777
4778=== modified file 'src/server/compositor/default_display_buffer_compositor.cpp'
4779--- src/server/compositor/default_display_buffer_compositor.cpp 2014-03-04 04:19:26 +0000
4780+++ src/server/compositor/default_display_buffer_compositor.cpp 2014-03-17 15:02:33 +0000
4781@@ -21,7 +21,7 @@
4782
4783 #include "rendering_operator.h"
4784 #include "mir/compositor/scene.h"
4785-#include "mir/compositor/compositing_criteria.h"
4786+#include "mir/graphics/renderable.h"
4787 #include "mir/graphics/display_buffer.h"
4788 #include "mir/graphics/buffer.h"
4789 #include "mir/compositor/buffer_stream.h"
4790@@ -46,10 +46,10 @@
4791 occlusions(occlusions)
4792 {
4793 }
4794- bool operator()(mc::CompositingCriteria const& info)
4795+ bool operator()(mg::Renderable const& r)
4796 {
4797- return info.should_be_rendered_in(enclosing_region) &&
4798- !occlusions.occluded(info);
4799+ return r.should_be_rendered_in(enclosing_region) &&
4800+ !occlusions.occluded(r);
4801 }
4802
4803 mir::geometry::Rectangle const& enclosing_region;
4804@@ -80,7 +80,7 @@
4805 }
4806
4807
4808-void mc::DefaultDisplayBufferCompositor::composite()
4809+bool mc::DefaultDisplayBufferCompositor::composite()
4810 {
4811 report->began_frame(this);
4812
4813@@ -104,9 +104,15 @@
4814 return !env || env[0] != '0';
4815 }()};
4816 bool bypassed = false;
4817+ bool uncomposited_buffers{false};
4818
4819 if (bypass_env && display_buffer.can_bypass())
4820 {
4821+ // It would be *really* nice not to lock the scene for a composite pass.
4822+ // (C.f. lp:1234018)
4823+ // A compositor shouldn't know anything about navigating the scene,
4824+ // it should be passed a collection of objects to render. (And any
4825+ // locks managed by the scene - which can just lock what is needed.)
4826 std::unique_lock<Scene> lock(*scene);
4827
4828 mc::BypassFilter filter(display_buffer);
4829@@ -118,11 +124,12 @@
4830 if (filter.fullscreen_on_top())
4831 {
4832 auto bypass_buf =
4833- match.topmost_fullscreen()->lock_compositor_buffer(
4834- local_frameno);
4835+ match.topmost_fullscreen()->buffer(local_frameno);
4836
4837 if (bypass_buf->can_bypass())
4838 {
4839+ uncomposited_buffers = match.topmost_fullscreen()->buffers_ready_for_compositor() > 1;
4840+
4841 lock.unlock();
4842 display_buffer.post_update(bypass_buf);
4843 bypassed = true;
4844@@ -150,14 +157,24 @@
4845
4846 renderer->set_rotation(display_buffer.orientation());
4847 renderer->begin();
4848- mc::RenderingOperator applicator(*renderer, save_resource, local_frameno);
4849+ mc::RenderingOperator applicator(*renderer, save_resource, local_frameno, uncomposited_buffers);
4850 FilterForVisibleSceneInRegion selector(view_area, occlusion_match);
4851 scene->for_each_if(selector, applicator);
4852 renderer->end();
4853
4854 display_buffer.post_update();
4855+
4856+ // This is a frig to avoid lp:1286190
4857+ if (size_of_last_pass)
4858+ {
4859+ uncomposited_buffers |= saved_resources.empty();
4860+ }
4861+
4862+ size_of_last_pass = saved_resources.size();
4863+ // End of frig
4864 }
4865
4866 report->finished_frame(bypassed, this);
4867+ return uncomposited_buffers;
4868 }
4869
4870
4871=== modified file 'src/server/compositor/default_display_buffer_compositor.h'
4872--- src/server/compositor/default_display_buffer_compositor.h 2014-01-22 10:03:11 +0000
4873+++ src/server/compositor/default_display_buffer_compositor.h 2014-03-17 15:02:33 +0000
4874@@ -44,7 +44,7 @@
4875 std::shared_ptr<Renderer> const& renderer,
4876 std::shared_ptr<CompositorReport> const& report);
4877
4878- void composite() override;
4879+ bool composite() override;
4880
4881 private:
4882 graphics::DisplayBuffer& display_buffer;
4883@@ -53,6 +53,7 @@
4884 std::shared_ptr<Renderer> const renderer;
4885 std::shared_ptr<CompositorReport> const report;
4886
4887+ int size_of_last_pass = 0;
4888 unsigned long local_frameno;
4889 };
4890
4891
4892=== modified file 'src/server/compositor/default_display_buffer_compositor_factory.cpp'
4893--- src/server/compositor/default_display_buffer_compositor_factory.cpp 2014-01-31 05:10:46 +0000
4894+++ src/server/compositor/default_display_buffer_compositor_factory.cpp 2014-03-17 15:02:33 +0000
4895@@ -17,8 +17,8 @@
4896 */
4897
4898 #include "default_display_buffer_compositor_factory.h"
4899-#include "renderer_factory.h"
4900-#include "renderer.h"
4901+#include "mir/compositor/renderer_factory.h"
4902+#include "mir/compositor/renderer.h"
4903 #include "mir/graphics/display_buffer.h"
4904
4905 #include "default_display_buffer_compositor.h"
4906
4907=== modified file 'src/server/compositor/gl_renderer.cpp'
4908--- src/server/compositor/gl_renderer.cpp 2014-03-04 04:19:26 +0000
4909+++ src/server/compositor/gl_renderer.cpp 2014-03-17 15:02:33 +0000
4910@@ -15,11 +15,12 @@
4911 * Authored By: Alexandros Frantzis <alexandros.frantzis@canonical.com>
4912 */
4913
4914-#include "gl_renderer.h"
4915-#include "mir/compositor/compositing_criteria.h"
4916+#include "mir/compositor/gl_renderer.h"
4917 #include "mir/compositor/buffer_stream.h"
4918+#include "mir/graphics/renderable.h"
4919 #include "mir/graphics/buffer.h"
4920
4921+#define GLM_FORCE_RADIANS
4922 #include <glm/gtc/matrix_transform.hpp>
4923 #include <glm/gtc/type_ptr.hpp>
4924
4925@@ -42,9 +43,13 @@
4926 "uniform mat4 screen_to_gl_coords;\n"
4927 "uniform mat4 display_transform;\n"
4928 "uniform mat4 transform;\n"
4929+ "uniform vec2 centre;\n"
4930 "varying vec2 v_texcoord;\n"
4931 "void main() {\n"
4932- " gl_Position = display_transform * screen_to_gl_coords * transform * vec4(position, 1.0);\n"
4933+ " vec4 mid = vec4(centre, 0.0, 0.0);\n"
4934+ " vec4 transformed = (transform * (vec4(position, 1.0) - mid)) + mid;\n"
4935+ " transformed.z = 0.0;\n" // avoid clipping while we lack depth/perspective
4936+ " gl_Position = display_transform * screen_to_gl_coords * transformed;\n"
4937 " v_texcoord = texcoord;\n"
4938 "}\n"
4939 };
4940@@ -61,39 +66,6 @@
4941 "}\n"
4942 };
4943
4944-struct VertexAttributes
4945-{
4946- glm::vec3 position;
4947- glm::vec2 texcoord;
4948-};
4949-
4950-/*
4951- * The texture coordinates are y-inverted to account for the difference in the
4952- * texture and renderable pixel data row order. In particular, GL textures
4953- * expect pixel data in rows starting from the bottom and moving up the image,
4954- * whereas our renderables provide data in rows starting from the top and
4955- * moving down the image.
4956- */
4957-VertexAttributes vertex_attribs[4] =
4958-{
4959- {
4960- glm::vec3{-0.5f, -0.5f, 0.0f},
4961- glm::vec2{0.0f, 0.0f}
4962- },
4963- {
4964- glm::vec3{-0.5f, 0.5f, 0.0f},
4965- glm::vec2{0.0f, 1.0f},
4966- },
4967- {
4968- glm::vec3{0.5f, -0.5f, 0.0f},
4969- glm::vec2{1.0f, 0.0f},
4970- },
4971- {
4972- glm::vec3{0.5f, 0.5f, 0.0f},
4973- glm::vec2{1.0f, 1.0f}
4974- }
4975-};
4976-
4977 typedef void(*MirGLGetObjectInfoLog)(GLuint, GLsizei, GLsizei *, GLchar *);
4978 typedef void(*MirGLGetObjectiv)(GLuint, GLenum, GLint *);
4979
4980@@ -126,9 +98,9 @@
4981 program(0),
4982 position_attr_loc(0),
4983 texcoord_attr_loc(0),
4984+ centre_uniform_loc(0),
4985 transform_uniform_loc(0),
4986 alpha_uniform_loc(0),
4987- vertex_attribs_vbo(0),
4988 rotation(NAN) // ensure the first set_rotation succeeds
4989 {
4990 /*
4991@@ -189,16 +161,10 @@
4992 alpha_uniform_loc = glGetUniformLocation(program, "alpha");
4993 position_attr_loc = glGetAttribLocation(program, "position");
4994 texcoord_attr_loc = glGetAttribLocation(program, "texcoord");
4995+ centre_uniform_loc = glGetUniformLocation(program, "centre");
4996
4997 glUniform1i(tex_loc, 0);
4998
4999- /* Create VBO */
5000- glGenBuffers(1, &vertex_attribs_vbo);
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches