Mir

Merge lp:~alan-griffiths/mir/fix-1706718 into lp:mir

Proposed by Alan Griffiths on 2017-07-27
Status: Merged
Approved by: Gerry Boland on 2017-07-28
Approved revision: 4225
Merged at revision: 4216
Proposed branch: lp:~alan-griffiths/mir/fix-1706718
Merge into: lp:mir
Diff against target: 419 lines (+146/-69)
4 files modified
src/platforms/mesa/server/kms/cursor.cpp (+109/-47)
src/platforms/mesa/server/kms/cursor.h (+11/-4)
src/platforms/mesa/server/kms/display.cpp (+11/-5)
tests/unit-tests/platforms/mesa/kms/test_cursor.cpp (+15/-13)
To merge this branch: bzr merge lp:~alan-griffiths/mir/fix-1706718
Reviewer Review Type Date Requested Status
Mir CI Bot continuous-integration Approve on 2017-07-28
Gerry Boland (community) 2017-07-27 Approve on 2017-07-28
Review via email: mp+328171@code.launchpad.net

Commit message

[mesa-kms] Respect display orientation when painting cursor. (LP: #1610078)

Description of the change

[mesa-kms] Respect display orientation when painting cursor

The test changes are for three reasons:

1. they can no longer assume that the image data is not referenced and the pointer passed "straight through".

2. Throwing for "oversized image" isn't useful behaviour.

3. the hotspot should also rotate, so the expectations were wrong by the image size (64) in assorted directions.

To post a comment you must log in.
Mir CI Bot (mir-ci-bot) wrote :

FAILED: Continuous integration, rev:4219
https://mir-jenkins.ubuntu.com/job/mir-ci/3513/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/4808/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4996
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=artful/4985
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/4985
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4985
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4845/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4845/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4845/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4845/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4845/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4845
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4845/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4845
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4845/artifact/output/*zip*/output.zip
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4845/console

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/3513/rebuild

review: Needs Fixing (continuous-integration)
Alan Griffiths (alan-griffiths) wrote :

Guess who forgot to run the tests. :(

Mir CI Bot (mir-ci-bot) wrote :

FAILED: Continuous integration, rev:4221
https://mir-jenkins.ubuntu.com/job/mir-ci/3514/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/4809/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4997
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=artful/4986
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/4986
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4986
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4846/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4846/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4846/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4846/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4846/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4846
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4846/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4846
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4846/artifact/output/*zip*/output.zip
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4846/console

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/3514/rebuild

review: Needs Fixing (continuous-integration)
lp:~alan-griffiths/mir/fix-1706718 updated on 2017-07-28
4222. By Alan Griffiths on 2017-07-28

Correct tests for hotpoint rotation

4223. By Alan Griffiths on 2017-07-28

merge :parent

Mir CI Bot (mir-ci-bot) wrote :

FAILED: Continuous integration, rev:4223
https://mir-jenkins.ubuntu.com/job/mir-ci/3515/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/4810/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4998
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=artful/4987
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/4987
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4987
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4847/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4847/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4847/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4847/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4847/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4847
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4847/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4847
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4847/artifact/output/*zip*/output.zip
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4847/console

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/3515/rebuild

review: Needs Fixing (continuous-integration)
lp:~alan-griffiths/mir/fix-1706718 updated on 2017-07-28
4224. By Alan Griffiths on 2017-07-28

Correct mgm::Cursor::GBMBOWrapper move constructor

Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:4224
https://mir-jenkins.ubuntu.com/job/mir-ci/3516/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/4811
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/5000
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=artful/4989
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/4989
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4989
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4848
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4848/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4848
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4848/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4848
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4848/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4848
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4848/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4848
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4848/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4848
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4848/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4848
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4848/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4848
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4848/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/3516/rebuild

review: Approve (continuous-integration)
Gerry Boland (gerboland) wrote :

Bug: changing display orientation doesn't cause cursor redraw (but does redraw scene). Only moving the mouse triggers the cursor redraw.

Testing directly on hardware, mir_demo_server and mir_demo_client_displayconfiguration

review: Needs Fixing
lp:~alan-griffiths/mir/fix-1706718 updated on 2017-07-28
4225. By Alan Griffiths on 2017-07-28

Refresh cursor on orientation change

Alan Griffiths (alan-griffiths) wrote :

> Bug: changing display orientation doesn't cause cursor redraw (but does redraw
> scene). Only moving the mouse triggers the cursor redraw.
>
> Testing directly on hardware, mir_demo_server and
> mir_demo_client_displayconfiguration

Fixed

Gerry Boland (gerboland) wrote :

LGTM

Though the --x-cursor-theme arg doesn't seem to be doing anything when I try it..

review: Approve
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:4225
https://mir-jenkins.ubuntu.com/job/mir-ci/3517/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/4812
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/5010
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=artful/4999
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/4999
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4999
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4849
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=artful/4849/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4849
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4849/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4849
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=artful/4849/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4849
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/4849/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4849
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4849/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4849
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=artful/4849/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4849
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=mesa,release=zesty/4849/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4849
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/4849/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/3517/rebuild

review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/platforms/mesa/server/kms/cursor.cpp'
2--- src/platforms/mesa/server/kms/cursor.cpp 2017-07-20 14:11:27 +0000
3+++ src/platforms/mesa/server/kms/cursor.cpp 2017-07-28 15:12:01 +0000
4@@ -100,7 +100,7 @@
5 }
6 }
7
8-mgm::Cursor::GBMBOWrapper::GBMBOWrapper(int fd) :
9+mgm::Cursor::GBMBOWrapper::GBMBOWrapper(int fd, MirOrientation orientation) :
10 device{gbm_create_device_checked(fd)},
11 buffer{
12 gbm_bo_create(
13@@ -108,7 +108,8 @@
14 get_drm_cursor_width(fd),
15 get_drm_cursor_height(fd),
16 GBM_FORMAT_ARGB8888,
17- GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE)}
18+ GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE)},
19+ current_orientation{orientation}
20 {
21 if (!buffer) BOOST_THROW_EXCEPTION(std::runtime_error("failed to create gbm buffer"));
22 }
23@@ -128,12 +129,22 @@
24
25 mgm::Cursor::GBMBOWrapper::GBMBOWrapper(GBMBOWrapper&& from)
26 : device{from.device},
27- buffer{from.buffer}
28+ buffer{from.buffer},
29+ current_orientation{from.current_orientation}
30 {
31 from.buffer = nullptr;
32 from.device = nullptr;
33 }
34
35+auto mir::graphics::mesa::Cursor::GBMBOWrapper::change_orientation(MirOrientation new_orientation) -> bool
36+{
37+ if (current_orientation == new_orientation)
38+ return false;
39+
40+ current_orientation = new_orientation;
41+ return true;
42+}
43+
44 mgm::Cursor::Cursor(
45 KMSOutputContainer& output_container,
46 std::shared_ptr<CurrentConfiguration> const& current_configuration) :
47@@ -182,37 +193,86 @@
48
49 void mgm::Cursor::pad_and_write_image_data_locked(
50 std::lock_guard<std::mutex> const& lg,
51- gbm_bo* buffer,
52- CursorImage const& image)
53+ GBMBOWrapper& buffer)
54 {
55- auto image_argb = static_cast<uint8_t const*>(image.as_argb_8888());
56- auto image_width = image.size().width.as_uint32_t();
57- auto image_height = image.size().height.as_uint32_t();
58- auto image_stride = image_width * 4;
59-
60- if (image_width > min_buffer_width || image_height > min_buffer_height)
61- {
62- BOOST_THROW_EXCEPTION(std::logic_error("Image is too big for GBM cursor buffer"));
63- }
64-
65- size_t buffer_stride = gbm_bo_get_stride(buffer); // in bytes
66- size_t padded_size = buffer_stride * gbm_bo_get_height(buffer);
67+ auto const orientation = buffer.orientation();
68+ bool const sideways = orientation == mir_orientation_left || orientation == mir_orientation_right;
69+
70+ auto const min_width = sideways ? min_buffer_width : min_buffer_height;
71+ auto const min_height = sideways ? min_buffer_height : min_buffer_width;
72+
73+ auto const image_width = std::min(min_width, size.width.as_uint32_t());
74+ auto const image_height = std::min(min_height, size.height.as_uint32_t());
75+ auto const image_stride = size.width.as_uint32_t() * 4;
76+
77+ auto const buffer_stride = std::max(min_width*4, gbm_bo_get_stride(buffer)); // in bytes
78+ auto const buffer_height = std::max(min_height, gbm_bo_get_height(buffer));
79+ size_t const padded_size = buffer_stride * buffer_height;
80+
81 auto padded = std::unique_ptr<uint8_t[]>(new uint8_t[padded_size]);
82- size_t rhs_padding = buffer_stride - image_stride;
83+ size_t rhs_padding = buffer_stride - 4*image_width;
84
85+ auto const filler = 0; // 0x3f; is useful to make buffer visible for debugging
86+ uint8_t const* src = argb8888.data();
87 uint8_t* dest = &padded[0];
88- uint8_t const* src = image_argb;
89
90- for (unsigned int y = 0; y < image_height; y++)
91+ switch (orientation)
92 {
93- memcpy(dest, src, image_stride);
94- memset(dest + image_stride, 0, rhs_padding);
95- dest += buffer_stride;
96- src += image_stride;
97+ case mir_orientation_normal:
98+ for (unsigned int y = 0; y < image_height; y++)
99+ {
100+ memcpy(dest, src, 4*image_width);
101+ memset(dest + 4*image_width, filler, rhs_padding);
102+ dest += buffer_stride;
103+ src += image_stride;
104+ }
105+
106+ memset(dest, 0, buffer_stride * (buffer_height - image_height));
107+ break;
108+
109+ case mir_orientation_inverted:
110+ for (unsigned int row = 0; row != image_height; ++row)
111+ {
112+ memset(dest+row*buffer_stride+4*image_width, filler, rhs_padding);
113+
114+ for (unsigned int col = 0; col != image_width; ++col)
115+ {
116+ memcpy(dest+row*buffer_stride+4*col, src + ((image_height-1)-row)*image_stride + 4*((image_width-1)-col), 4);
117+ }
118+ }
119+
120+ memset(dest+image_height*buffer_stride, filler, buffer_stride * (buffer_height - image_height));
121+ break;
122+
123+ case mir_orientation_left:
124+ for (unsigned int row = 0; row != image_width; ++row)
125+ {
126+ memset(dest+row*buffer_stride+4*image_height, filler, rhs_padding);
127+
128+ for (unsigned int col = 0; col != image_height; ++col)
129+ {
130+ memcpy(dest+row*buffer_stride+4*col, src + ((image_width-1)-row)*4 + image_stride*col, 4);
131+ }
132+ }
133+
134+ memset(dest+image_width*buffer_stride, filler, buffer_stride * (buffer_height - image_width));
135+ break;
136+
137+ case mir_orientation_right:
138+ for (unsigned int row = 0; row != image_width; ++row)
139+ {
140+ memset(dest+row*buffer_stride+4*image_height, filler, rhs_padding);
141+
142+ for (unsigned int col = 0; col != image_height; ++col)
143+ {
144+ memcpy(dest+row*buffer_stride+4*col, src + row*4 + image_stride*((image_height-1)-col), 4);
145+ }
146+ }
147+
148+ memset(dest+image_width*buffer_stride, filler, buffer_stride * (buffer_height - image_width));
149+ break;
150 }
151
152- memset(dest, 0, buffer_stride * (gbm_bo_get_height(buffer) - image_height));
153-
154 write_buffer_data_locked(lg, buffer, &padded[0], padded_size);
155 }
156
157@@ -231,23 +291,17 @@
158 {
159 std::lock_guard<std::mutex> lg(guard);
160
161- auto const& size = cursor_image.size();
162+ size = cursor_image.size();
163+
164+ argb8888.resize(size.width.as_uint32_t() * size.height.as_uint32_t() * 4);
165+ memcpy(argb8888.data(), cursor_image.as_argb_8888(), argb8888.size());
166
167 hotspot = cursor_image.hotspot();
168 {
169 auto locked_buffers = buffers.lock();
170 for (auto& pair : *locked_buffers)
171 {
172- auto& buffer = pair.second;
173- if (size != geometry::Size{gbm_bo_get_width(buffer), gbm_bo_get_height(buffer)})
174- {
175- pad_and_write_image_data_locked(lg, buffer, cursor_image);
176- }
177- else
178- {
179- auto const count = size.width.as_uint32_t() * size.height.as_uint32_t() * sizeof(uint32_t);
180- write_buffer_data_locked(lg, buffer, cursor_image.as_argb_8888(), count);
181- }
182+ pad_and_write_image_data_locked(lg, pair.second);
183 }
184 }
185
186@@ -317,7 +371,7 @@
187 }
188
189 void mgm::Cursor::place_cursor_at_locked(
190- std::lock_guard<std::mutex> const&,
191+ std::lock_guard<std::mutex> const& lg,
192 geometry::Point position,
193 ForceCursorState force_state)
194 {
195@@ -334,15 +388,23 @@
196 if (output_rect.contains(position))
197 {
198 auto dp = transform(output_rect, position - output_rect.top_left, orientation);
199+ auto hs = transform(geom::Rectangle{{0,0}, size}, hotspot, orientation);
200
201 // It's a little strange that we implement hotspot this way as there is
202 // drmModeSetCursor2 with hotspot support. However it appears to not actually
203 // work on radeon and intel. There also seems to be precedent in weston for
204 // implementing hotspot in this fashion.
205- output.move_cursor(geom::Point{} + dp - hotspot);
206- if (force_state || !output.has_cursor()) // TODO - or if orientation had changed - then set buffer..
207+ output.move_cursor(geom::Point{} + dp - hs);
208+ auto& buffer = buffer_for_output(output);
209+
210+ auto const changed_orientation = buffer.change_orientation(orientation);
211+
212+ if (changed_orientation)
213+ pad_and_write_image_data_locked(lg, buffer);
214+
215+ if (force_state || !output.has_cursor() || changed_orientation)
216 {
217- if (!output.set_cursor(buffer_for_output(output)) || !output.has_cursor())
218+ if (!output.set_cursor(buffer) || !output.has_cursor())
219 set_on_all_outputs = false;
220 }
221 }
222@@ -358,7 +420,7 @@
223 last_set_failed = !set_on_all_outputs;
224 }
225
226-gbm_bo* mgm::Cursor::buffer_for_output(KMSOutput const& output)
227+mgm::Cursor::GBMBOWrapper& mgm::Cursor::buffer_for_output(KMSOutput const& output)
228 {
229 auto locked_buffers = buffers.lock();
230
231@@ -366,18 +428,18 @@
232 locked_buffers->begin(),
233 locked_buffers->end(),
234 [&output](auto const& candidate)
235- {
236- return candidate.first == output.drm_fd();
237- });
238+ {
239+ return candidate.first == output.drm_fd();
240+ });
241
242 if (buffer_it != locked_buffers->end())
243 {
244 return buffer_it->second;
245 }
246
247- locked_buffers->push_back(std::make_pair(output.drm_fd(), GBMBOWrapper(output.drm_fd())));
248+ locked_buffers->push_back(std::make_pair(output.drm_fd(), GBMBOWrapper(output.drm_fd(), mir_orientation_normal)));
249
250- gbm_bo* bo = locked_buffers->back().second;
251+ GBMBOWrapper& bo = locked_buffers->back().second;
252 if (gbm_bo_get_width(bo) < min_buffer_width)
253 {
254 min_buffer_width = gbm_bo_get_width(bo);
255
256=== modified file 'src/platforms/mesa/server/kms/cursor.h'
257--- src/platforms/mesa/server/kms/cursor.h 2017-06-08 08:34:56 +0000
258+++ src/platforms/mesa/server/kms/cursor.h 2017-07-28 15:12:01 +0000
259@@ -85,6 +85,7 @@
260
261 private:
262 enum ForceCursorState { UpdateState, ForceState };
263+ struct GBMBOWrapper;
264 void for_each_used_output(std::function<void(KMSOutput&, geometry::Rectangle const&, MirOrientation orientation)> const& f);
265 void place_cursor_at(geometry::Point position, ForceCursorState force_state);
266 void place_cursor_at_locked(std::lock_guard<std::mutex> const&, geometry::Point position, ForceCursorState force_state);
267@@ -95,31 +96,37 @@
268 size_t count);
269 void pad_and_write_image_data_locked(
270 std::lock_guard<std::mutex> const&,
271- gbm_bo* buffer,
272- CursorImage const& image);
273+ GBMBOWrapper& buffer);
274 void clear(std::lock_guard<std::mutex> const&);
275
276- gbm_bo* buffer_for_output(KMSOutput const& output);
277+ GBMBOWrapper& buffer_for_output(KMSOutput const& output);
278
279 std::mutex guard;
280
281 KMSOutputContainer& output_container;
282 geometry::Point current_position;
283 geometry::Displacement hotspot;
284+ geometry::Size size;
285+ std::vector<uint8_t> argb8888;
286
287 bool visible;
288 bool last_set_failed;
289
290 struct GBMBOWrapper
291 {
292- GBMBOWrapper(int fd);
293+ GBMBOWrapper(int fd, MirOrientation orientation);
294 operator gbm_bo*();
295+
296+ auto orientation() const -> MirOrientation { return current_orientation; }
297+ auto change_orientation(MirOrientation new_orientation) -> bool;
298+
299 ~GBMBOWrapper();
300
301 GBMBOWrapper(GBMBOWrapper&& from);
302 private:
303 gbm_device* device;
304 gbm_bo* buffer;
305+ MirOrientation current_orientation;
306 GBMBOWrapper(GBMBOWrapper const&) = delete;
307 GBMBOWrapper& operator=(GBMBOWrapper const&) = delete;
308 };
309
310=== modified file 'src/platforms/mesa/server/kms/display.cpp'
311--- src/platforms/mesa/server/kms/display.cpp 2017-06-07 08:29:04 +0000
312+++ src/platforms/mesa/server/kms/display.cpp 2017-07-28 15:12:01 +0000
313@@ -420,14 +420,20 @@
314 bool mgm::Display::apply_if_configuration_preserves_display_buffers(
315 mg::DisplayConfiguration const& conf)
316 {
317+ bool result = false;
318 auto const& new_kms_conf = dynamic_cast<RealKMSDisplayConfiguration const&>(conf);
319- std::lock_guard<decltype(configuration_mutex)> lock{configuration_mutex};
320- if (compatible(current_display_configuration, new_kms_conf))
321+
322 {
323- configure_locked(new_kms_conf, lock);
324- return true;
325+ std::lock_guard<decltype(configuration_mutex)> lock{configuration_mutex};
326+ if (compatible(current_display_configuration, new_kms_conf))
327+ {
328+ configure_locked(new_kms_conf, lock);
329+ result = true;
330+ }
331 }
332- return false;
333+
334+ if (auto c = cursor.lock()) c->resume();
335+ return result;
336 }
337
338 mg::Frame mgm::Display::last_frame_on(unsigned output_id) const
339
340=== modified file 'tests/unit-tests/platforms/mesa/kms/test_cursor.cpp'
341--- tests/unit-tests/platforms/mesa/kms/test_cursor.cpp 2017-06-07 08:29:04 +0000
342+++ tests/unit-tests/platforms/mesa/kms/test_cursor.cpp 2017-07-28 15:12:01 +0000
343@@ -272,7 +272,9 @@
344
345 static void const* image_data;
346 };
347-void const* StubCursorImage::image_data = reinterpret_cast<void*>(&StubCursorImage::image_data);
348+
349+char const stub_data[128*128*4] = { 0 };
350+void const* StubCursorImage::image_data = stub_data;
351
352 // Those new cap flags are currently only available in drm/drm.h but not in
353 // libdrm/drm.h nor in xf86drm.h. Additionally drm/drm.h is current c++ unfriendly
354@@ -407,7 +409,7 @@
355 geom::Size const cursor_size{cursor_side, cursor_side};
356 size_t const cursor_size_bytes{cursor_side * cursor_side * sizeof(uint32_t)};
357
358- EXPECT_CALL(mock_gbm, gbm_bo_write(mock_gbm.fake_gbm.bo, StubCursorImage::image_data, cursor_size_bytes));
359+ EXPECT_CALL(mock_gbm, gbm_bo_write(mock_gbm.fake_gbm.bo, NotNull(), cursor_size_bytes));
360
361 cursor.show(image);
362 }
363@@ -464,7 +466,7 @@
364 cursor_tmp.show(SinglePixelCursorImage());
365 }
366
367-TEST_F(MesaCursorTest, throws_when_images_are_too_large)
368+TEST_F(MesaCursorTest, does_not_throw_when_images_are_too_large)
369 {
370 using namespace testing;
371
372@@ -478,9 +480,7 @@
373 geom::Size const large_cursor_size{cursor_side, cursor_side};
374 };
375
376- EXPECT_THROW({
377- cursor.show(LargeCursorImage());
378- }, std::logic_error);
379+ cursor.show(LargeCursorImage());
380 }
381
382 TEST_F(MesaCursorTest, clears_cursor_state_on_construction)
383@@ -607,8 +607,9 @@
384
385 current_configuration.conf.set_orentation_of_output(mg::DisplayConfigurationOutputId{2}, mir_orientation_left);
386
387- EXPECT_CALL(*output_container.outputs[2], move_cursor(geom::Point{112,100}));
388- EXPECT_CALL(*output_container.outputs[2], move_cursor(geom::Point{150,96}));
389+ InSequence seq;
390+ EXPECT_CALL(*output_container.outputs[2], move_cursor(geom::Point{112, 36}));
391+ EXPECT_CALL(*output_container.outputs[2], move_cursor(geom::Point{150, 32}));
392
393 cursor.move_to({766, 112});
394 cursor.move_to({770, 150});
395@@ -625,9 +626,9 @@
396
397 current_configuration.conf.set_orentation_of_output(mg::DisplayConfigurationOutputId{2}, mir_orientation_right);
398
399-
400- EXPECT_CALL(*output_container.outputs[2], move_cursor(geom::Point{688,100}));
401- EXPECT_CALL(*output_container.outputs[2], move_cursor(geom::Point{650,104}));
402+ InSequence seq;
403+ EXPECT_CALL(*output_container.outputs[2], move_cursor(geom::Point{624, 100}));
404+ EXPECT_CALL(*output_container.outputs[2], move_cursor(geom::Point{586, 104}));
405
406 cursor.move_to({766, 112});
407 cursor.move_to({770, 150});
408@@ -643,8 +644,9 @@
409
410 current_configuration.conf.set_orentation_of_output(mg::DisplayConfigurationOutputId{2}, mir_orientation_inverted);
411
412- EXPECT_CALL(*output_container.outputs[2], move_cursor(geom::Point{700,88}));
413- EXPECT_CALL(*output_container.outputs[2], move_cursor(geom::Point{696,50}));
414+ InSequence seq;
415+ EXPECT_CALL(*output_container.outputs[2], move_cursor(geom::Point{636, 24}));
416+ EXPECT_CALL(*output_container.outputs[2], move_cursor(geom::Point{632,-14}));
417
418 cursor.move_to({766, 112});
419 cursor.move_to({770, 150});

Subscribers

People subscribed via source and target branches