Mir

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

Proposed by kevin gunn on 2014-03-14
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 2014-03-14 Approve on 2014-03-17
PS Jenkins bot (community) continuous-integration Needs Fixing on 2014-03-14
Mir development team 2014-03-17 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.
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

lp:~mir-team/mir/trunk-0.1.7 updated on 2014-03-17
1179. By Daniel van Vugt on 2014-03-17

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 on 2014-03-17

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

1181. By Daniel van Vugt on 2014-03-17

Fill out debian/changelog

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
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 on 2014-03-17
1182. By kevin gunn on 2014-03-17

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