Mir

Merge lp:~kdub/mir/nested-buffer into lp:mir

Proposed by Kevin DuBois
Status: Superseded
Proposed branch: lp:~kdub/mir/nested-buffer
Merge into: lp:mir
Prerequisite: lp:~kdub/mir/mir-buffer-get-stride
Diff against target: 870 lines (+451/-46)
25 files modified
include/platform/mir/graphics/buffer.h (+0/-1)
include/renderers/sw/mir/renderer/sw/pixel_source.h (+1/-0)
src/platform/symbols.map (+0/-1)
src/platforms/android/server/ipc_operations.cpp (+3/-1)
src/platforms/android/utils/test_android_hardware_sanity.cpp (+5/-5)
src/platforms/eglstream-kms/server/platform.cpp (+1/-1)
src/platforms/mesa/server/gbm_buffer.h (+1/-1)
src/platforms/mesa/server/ipc_operations.cpp (+1/-1)
src/server/compositor/temporary_buffers.cpp (+0/-5)
src/server/compositor/temporary_buffers.h (+0/-1)
src/server/graphics/nested/CMakeLists.txt (+1/-0)
src/server/graphics/nested/buffer.cpp (+122/-0)
src/server/graphics/nested/buffer.h (+57/-0)
src/server/graphics/nested/host_connection.h (+6/-0)
src/server/graphics/nested/mir_client_host_connection.cpp (+17/-0)
src/server/graphics/nested/mir_client_host_connection.h (+4/-0)
tests/include/mir/test/doubles/mock_buffer.h (+3/-1)
tests/include/mir/test/doubles/stub_host_connection.h (+15/-0)
tests/mir_test_framework/stubbed_graphics_platform.cpp (+3/-1)
tests/unit-tests/compositor/test_temporary_buffers.cpp (+0/-11)
tests/unit-tests/platforms/android/server/test_platform.cpp (+14/-13)
tests/unit-tests/platforms/mesa/kms/test_gbm_buffer.cpp (+1/-1)
tests/unit-tests/platforms/mesa/kms/test_ipc_operations.cpp (+1/-2)
tests/unit-tests/platforms/nested/CMakeLists.txt (+3/-0)
tests/unit-tests/platforms/nested/test_buffer.cpp (+192/-0)
To merge this branch: bzr merge lp:~kdub/mir/nested-buffer
Reviewer Review Type Date Requested Status
Mir CI Bot continuous-integration Needs Fixing
Chris Halse Rogers Needs Fixing
Review via email: mp+303251@code.launchpad.net

This proposal supersedes a proposal from 2016-08-15.

This proposal has been superseded by a proposal from 2016-08-23.

Commit message

nested: add mgn::NestedBuffer in preparation for "nested-passthrough" (bypass for clients of nested server).

Description of the change

nested: add mgn::NestedBuffer in preparation for "nested-passthrough" (bypass for clients of nested server). Side-steps choosing mg::NativeBuffer for this type for now, until that situation is sorted out in the other line of work.

To post a comment you must log in.
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:3623
https://mir-jenkins.ubuntu.com/job/mir-ci/1456/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/1798/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/1852
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/1843
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/1843
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/1843
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/1822
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/1822/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/1822
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/1822/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/1822
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/1822/artifact/output/*zip*/output.zip
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/1822/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/1822/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/1822
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/1822/artifact/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote : Posted in a previous version of this proposal

PASSED: Continuous integration, rev:3624
https://mir-jenkins.ubuntu.com/job/mir-ci/1458/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/1800
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/1854
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/1845
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/1845
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/1845
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/1824
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/1824/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/1824
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/1824/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/1824
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/1824/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/1824
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/1824/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/1824
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/1824/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/1824
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/1824/artifact/output/*zip*/output.zip

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

review: Approve (continuous-integration)
Revision history for this message
Chris Halse Rogers (raof) wrote : Posted in a previous version of this proposal

So, this is going to segfault all over the place on mesa. get_graphics_region returns NULL for hardware buffers there, as they can't be mmapped.

It's *probably* fine to just unconditionally throw a logic_error from Buffer::read() and Buffer::write()? (Leading to the obvious question: why are those methods there? GBMBuffer unconditionally throws if either are called)

If we need stride elsewhere (for GL import?) we should indeed add that as an mir_buffer_get_stride() accessor.

review: Needs Fixing
Revision history for this message
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal

I've thought that the read/write should be regrouped into a "NativeBufferBase" sort of thing (like we do for GL).

Would be easier to add a mir_buffer_get_stride() accessor, so will do that.

Revision history for this message
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal

Actually, not sure that mir_buffer_get_stride() to the public api is useful to non-software users of the buffer. Seems like NativeBufferBase for sw is the way to go to resolve.

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

Decided to have mir_buffer_get_stride, and now use that instead of mapping the region and figuring out the stride from there.

Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:3628
https://mir-jenkins.ubuntu.com/job/mir-ci/1483/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/1836
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/1890
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/1881
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/1881
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/1881
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/1860
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/1860/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/1860
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/1860/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/1860
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/1860/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/1860
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/1860/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/1860
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/1860/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/1860
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/1860/artifact/output/*zip*/output.zip

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

review: Approve (continuous-integration)
Revision history for this message
Chris Halse Rogers (raof) wrote :

Needs fixing: Again, mgn::Buffer::write() and mgn::Buffer::read will segfault on Mesa.

Needs info: Hm. Now that I think about it, what's your plan for providing native_buffer_base()? This isn't actually useful at all until we can provide that, and might significantly change the approach?

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

quick sketch:
native_buffer_base() needs to provide gl support so the nested server can use the buffers for GL composition. The different platforms have different EGLImage import methods, still working out how that will work.

native_buffer_handle() needs to provide a mg::NativeBuffer that gives mgn::DisplayBuffer access to the MirBuffer* so it can use MirPresentationChain to forward the MirBuffer* along without composition.

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

re segfault, seems the mesa platform would throw trying to make a ShmRegion, but that should also be caught and give a height of 0. So, it wouldn't segfault, but it should give some indication of error. Will correct.

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

Also, improved the native_buffer_base() so that it read/write are not member functions of mgn::Buffer, but of a member instance. Should be easy to expand with gl access this way.

Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

FAILED: Continuous integration, rev:3631
https://mir-jenkins.ubuntu.com/job/mir-ci/1497/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/1860/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/1914
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/1905
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/1905
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/1905
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/1884
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/1884/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/1884
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/1884/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/1884
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/1884/artifact/output/*zip*/output.zip
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/1884/console
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/1884/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/1884
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/1884/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/1884
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/1884/artifact/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Chris Halse Rogers (raof) wrote :

Hm, now that I think of it, this approach in fundamentally unsuited to an EGLStream-based platform, where we can only provide a mg::Buffer abstraction at a performance cost.

To provide an mg::Buffer from a client we need to read out of the EGLStream with an gl_texture_consumer sink; to forward that on to the host server we'd need to blit it to the egl_surface_producer of a separate stream.

I'm not really sure where I'm going with this. Maybe that we shouldn't try to design for it until the necessary EGL extensions are implemented in a driver, presumably nvidia's?

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

> Hm, now that I think of it, this approach in fundamentally unsuited to an
> EGLStream-based platform, where we can only provide a mg::Buffer abstraction
> at a performance cost.

Sure, the eglstream platform needs to provide an abstraction for mc::BufferStream. The mesa and android platforms though need mgn::Buffers so that they can re-use the code in mc::Stream.

> To provide an mg::Buffer from a client we need to read out of the EGLStream
> with an gl_texture_consumer sink; to forward that on to the host server we'd
> need to blit it to the egl_surface_producer of a separate stream.
>
> I'm not really sure where I'm going with this. Maybe that we shouldn't try to
> design for it until the necessary EGL extensions are implemented in a driver,
> presumably nvidia's?

Right, I think that we have to carve out some holes in the platform to accommodate the eglstreams. Namely, we need the platform to provide a mc::BufferStream factory. I don't really expect eglstreams to use mgn::Buffer, because the primary thing it gets us is 'nested passthrough' for mesa+android, and eglstreams are designed around 'nested passthrough'

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

branch needs restacking, WIP

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/platform/mir/graphics/buffer.h'
2--- include/platform/mir/graphics/buffer.h 2016-08-16 19:34:28 +0000
3+++ include/platform/mir/graphics/buffer.h 2016-08-23 11:55:27 +0000
4@@ -49,7 +49,6 @@
5 virtual std::shared_ptr<NativeBuffer> native_buffer_handle() const = 0;
6 virtual BufferID id() const = 0;
7 virtual geometry::Size size() const = 0;
8- virtual geometry::Stride stride() const = 0;
9 virtual MirPixelFormat pixel_format() const = 0;
10
11 virtual NativeBufferBase* native_buffer_base() = 0;
12
13=== modified file 'include/renderers/sw/mir/renderer/sw/pixel_source.h'
14--- include/renderers/sw/mir/renderer/sw/pixel_source.h 2016-08-16 19:34:28 +0000
15+++ include/renderers/sw/mir/renderer/sw/pixel_source.h 2016-08-23 11:55:27 +0000
16@@ -38,6 +38,7 @@
17 virtual void write(unsigned char const* pixels, size_t size) = 0;
18 //FIXME: correct read, it doesn't give size or format information about the pixels.
19 virtual void read(std::function<void(unsigned char const*)> const& do_with_pixels) = 0;
20+ virtual geometry::Stride stride() const = 0;
21
22 protected:
23 PixelSource() = default;
24
25=== modified file 'src/platform/symbols.map'
26--- src/platform/symbols.map 2016-08-17 11:55:42 +0000
27+++ src/platform/symbols.map 2016-08-23 11:55:27 +0000
28@@ -10,7 +10,6 @@
29 mir::graphics::Buffer::native_buffer_handle*;
30 mir::graphics::Buffer::pixel_format*;
31 mir::graphics::Buffer::size*;
32- mir::graphics::Buffer::stride*;
33 mir::graphics::Cursor::?Cursor*;
34 mir::graphics::Cursor::Cursor*;
35 mir::graphics::Cursor::hide*;
36
37=== modified file 'src/platforms/android/server/ipc_operations.cpp'
38--- src/platforms/android/server/ipc_operations.cpp 2016-05-03 06:55:25 +0000
39+++ src/platforms/android/server/ipc_operations.cpp 2016-08-23 11:55:27 +0000
40@@ -62,7 +62,9 @@
41 msg.pack_data(buffer_handle->data[offset++]);
42 }
43
44- msg.pack_stride(buffer.stride());
45+ mir::geometry::Stride byte_stride{
46+ native_buffer->anwb()->stride * MIR_BYTES_PER_PIXEL(buffer.pixel_format())};
47+ msg.pack_stride(byte_stride);
48 msg.pack_size(buffer.size());
49 }
50 }
51
52=== modified file 'src/platforms/android/utils/test_android_hardware_sanity.cpp'
53--- src/platforms/android/utils/test_android_hardware_sanity.cpp 2016-08-16 19:34:28 +0000
54+++ src/platforms/android/utils/test_android_hardware_sanity.cpp 2016-08-23 11:55:27 +0000
55@@ -136,10 +136,10 @@
56 auto pixel_source = dynamic_cast<mrs::PixelSource*>(buffer->native_buffer_base());
57 ASSERT_THAT(pixel_source, testing::Ne(nullptr));
58
59- pixel_source->read([&valid_content, &buffer](unsigned char const* data){
60+ pixel_source->read([&](unsigned char const* data){
61 MirGraphicsRegion region{
62 buffer->size().width.as_int(), buffer->size().height.as_int(),
63- buffer->stride().as_int(), buffer->pixel_format(),
64+ pixel_source->stride().as_int(), buffer->pixel_format(),
65 reinterpret_cast<char*>(const_cast<unsigned char*>(data))};
66 valid_content = draw_pattern.check(region);
67 });
68@@ -196,10 +196,10 @@
69 auto valid_content = false;
70 auto pixel_source = dynamic_cast<mrs::PixelSource*>(buffer->native_buffer_base());
71 ASSERT_THAT(pixel_source, testing::Ne(nullptr));
72- pixel_source->read([&valid_content, &buffer](unsigned char const* data){
73+ pixel_source->read([&](unsigned char const* data){
74 MirGraphicsRegion region{
75 buffer->size().width.as_int(), buffer->size().height.as_int(),
76- buffer->stride().as_int(), buffer->pixel_format(),
77+ pixel_source->stride().as_int(), buffer->pixel_format(),
78 reinterpret_cast<char*>(const_cast<unsigned char*>(data))};
79 mt::DrawPatternSolid green_pattern(0xFF00FF00);
80 valid_content = green_pattern.check(region);
81@@ -310,7 +310,7 @@
82 pixel_source->read([&](unsigned char const* data){
83 MirGraphicsRegion region{
84 buffer->size().width.as_int(), buffer->size().height.as_int(),
85- buffer->stride().as_int(), buffer->pixel_format(),
86+ pixel_source->stride().as_int(), buffer->pixel_format(),
87 reinterpret_cast<char*>(const_cast<unsigned char*>(data))};
88 valid_content = green_pattern.check(region);
89 });
90
91=== modified file 'src/platforms/eglstream-kms/server/platform.cpp'
92--- src/platforms/eglstream-kms/server/platform.cpp 2016-08-03 12:27:57 +0000
93+++ src/platforms/eglstream-kms/server/platform.cpp 2016-08-23 11:55:27 +0000
94@@ -130,7 +130,7 @@
95 packer.pack_fd(mir::Fd(IntOwnedFd{native_handle->fd[i]}));
96 }
97
98- packer.pack_stride(buffer.stride());
99+ packer.pack_stride(mir::geometry::Stride{native_handle->stride});
100 packer.pack_flags(native_handle->flags);
101 packer.pack_size(buffer.size());
102 }
103
104=== modified file 'src/platforms/mesa/server/gbm_buffer.h'
105--- src/platforms/mesa/server/gbm_buffer.h 2016-08-19 13:38:31 +0000
106+++ src/platforms/mesa/server/gbm_buffer.h 2016-08-23 11:55:27 +0000
107@@ -58,7 +58,7 @@
108
109 virtual geometry::Size size() const override;
110
111- virtual geometry::Stride stride() const override;
112+ virtual geometry::Stride stride() const;
113
114 virtual MirPixelFormat pixel_format() const override;
115
116
117=== modified file 'src/platforms/mesa/server/ipc_operations.cpp'
118--- src/platforms/mesa/server/ipc_operations.cpp 2016-08-02 18:30:00 +0000
119+++ src/platforms/mesa/server/ipc_operations.cpp 2016-08-23 11:55:27 +0000
120@@ -84,7 +84,7 @@
121 packer.pack_fd(mir::Fd(IntOwnedFd{native_handle->fd[i]}));
122 }
123
124- packer.pack_stride(buffer.stride());
125+ packer.pack_stride(mir::geometry::Stride{native_handle->stride});
126 packer.pack_flags(native_handle->flags);
127 packer.pack_size(buffer.size());
128 }
129
130=== modified file 'src/server/compositor/temporary_buffers.cpp'
131--- src/server/compositor/temporary_buffers.cpp 2016-08-16 19:34:28 +0000
132+++ src/server/compositor/temporary_buffers.cpp 2016-08-23 11:55:27 +0000
133@@ -60,11 +60,6 @@
134 return buffer->size();
135 }
136
137-geom::Stride mc::TemporaryBuffer::stride() const
138-{
139- return buffer->stride();
140-}
141-
142 MirPixelFormat mc::TemporaryBuffer::pixel_format() const
143 {
144 return buffer->pixel_format();
145
146=== modified file 'src/server/compositor/temporary_buffers.h'
147--- src/server/compositor/temporary_buffers.h 2016-08-16 19:34:28 +0000
148+++ src/server/compositor/temporary_buffers.h 2016-08-23 11:55:27 +0000
149@@ -36,7 +36,6 @@
150 {
151 public:
152 geometry::Size size() const override;
153- geometry::Stride stride() const override;
154 MirPixelFormat pixel_format() const override;
155 mg::BufferID id() const override;
156 std::shared_ptr<mg::NativeBuffer> native_buffer_handle() const override;
157
158=== modified file 'src/server/graphics/nested/CMakeLists.txt'
159--- src/server/graphics/nested/CMakeLists.txt 2016-07-26 03:56:14 +0000
160+++ src/server/graphics/nested/CMakeLists.txt 2016-08-23 11:55:27 +0000
161@@ -12,4 +12,5 @@
162 mir_client_host_connection.cpp
163 cursor.cpp
164 platform.cpp
165+ buffer.cpp
166 )
167
168=== added file 'src/server/graphics/nested/buffer.cpp'
169--- src/server/graphics/nested/buffer.cpp 1970-01-01 00:00:00 +0000
170+++ src/server/graphics/nested/buffer.cpp 2016-08-23 11:55:27 +0000
171@@ -0,0 +1,122 @@
172+/*
173+ * Copyright © 2016 Canonical Ltd.
174+ *
175+ * This program is free software: you can redistribute it and/or modify it
176+ * under the terms of the GNU General Public License version 3,
177+ * as published by the Free Software Foundation.
178+ *
179+ * This program is distributed in the hope that it will be useful,
180+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
181+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
182+ * GNU General Public License for more details.
183+ *
184+ * You should have received a copy of the GNU General Public License
185+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
186+ *
187+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
188+ */
189+
190+#include "host_connection.h"
191+#include "mir_toolkit/mir_buffer.h"
192+#include "mir/renderer/sw/pixel_source.h"
193+#include "buffer.h"
194+#include <string.h>
195+#include <boost/throw_exception.hpp>
196+#include <stdexcept>
197+
198+namespace mg = mir::graphics;
199+namespace mgn = mir::graphics::nested;
200+namespace mrs = mir::renderer::software;
201+namespace geom = mir::geometry;
202+
203+namespace
204+{
205+class PixelAccess : public mg::NativeBufferBase,
206+ public mrs::PixelSource
207+{
208+public:
209+ PixelAccess(
210+ mgn::Buffer& buffer,
211+ std::shared_ptr<MirBuffer> const& native_buffer,
212+ std::shared_ptr<mgn::HostConnection> const& connection) :
213+ buffer(buffer),
214+ native_buffer(native_buffer),
215+ connection(connection),
216+ stride_(geom::Stride{connection->get_graphics_region(native_buffer.get()).stride})
217+ {
218+ }
219+
220+ void write(unsigned char const* pixels, size_t pixel_size) override
221+ {
222+ auto bpp = MIR_BYTES_PER_PIXEL(buffer.pixel_format());
223+ size_t buffer_size_bytes = buffer.size().height.as_int() * buffer.size().width.as_int() * bpp;
224+ if (buffer_size_bytes != pixel_size)
225+ BOOST_THROW_EXCEPTION(std::logic_error("Size of pixels is not equal to size of buffer"));
226+
227+ auto region = connection->get_graphics_region(native_buffer.get());
228+ if (!region.vaddr)
229+ BOOST_THROW_EXCEPTION(std::logic_error("could not map buffer"));
230+
231+ for (int i = 0; i < region.height; i++)
232+ {
233+ int line_offset_in_buffer = stride().as_uint32_t() * i;
234+ int line_offset_in_source = bpp * region.width * i;
235+ memcpy(region.vaddr + line_offset_in_buffer, pixels + line_offset_in_source, region.width * bpp);
236+ }
237+ }
238+
239+ void read(std::function<void(unsigned char const*)> const& do_with_pixels) override
240+ {
241+ auto region = connection->get_graphics_region(native_buffer.get());
242+ do_with_pixels(reinterpret_cast<unsigned char*>(region.vaddr));
243+ }
244+
245+ geom::Stride stride() const override
246+ {
247+ return stride_;
248+ }
249+
250+private:
251+ mgn::Buffer& buffer;
252+ std::shared_ptr<MirBuffer> const native_buffer;
253+ std::shared_ptr<mgn::HostConnection> const connection;
254+ geom::Stride const stride_;
255+};
256+}
257+
258+std::shared_ptr<mg::NativeBufferBase> mgn::Buffer::create_native_base(mg::BufferUsage const usage)
259+{
260+ if (usage == mg::BufferUsage::software)
261+ return std::make_shared<PixelAccess>(*this, buffer, connection);
262+ else
263+ return nullptr;
264+}
265+
266+mgn::Buffer::Buffer(
267+ std::shared_ptr<HostConnection> const& connection,
268+ mg::BufferProperties const& properties) :
269+ connection(connection),
270+ buffer(connection->create_buffer(properties)),
271+ native_base(create_native_base(properties.usage))
272+{
273+}
274+
275+std::shared_ptr<mg::NativeBuffer> mgn::Buffer::native_buffer_handle() const
276+{
277+ return nullptr;
278+}
279+
280+geom::Size mgn::Buffer::size() const
281+{
282+ return geom::Size{ mir_buffer_get_width(buffer.get()), mir_buffer_get_height(buffer.get()) };
283+}
284+
285+MirPixelFormat mgn::Buffer::pixel_format() const
286+{
287+ return mir_buffer_get_pixel_format(buffer.get());
288+}
289+
290+mg::NativeBufferBase* mgn::Buffer::native_buffer_base()
291+{
292+ return native_base.get();
293+}
294
295=== added file 'src/server/graphics/nested/buffer.h'
296--- src/server/graphics/nested/buffer.h 1970-01-01 00:00:00 +0000
297+++ src/server/graphics/nested/buffer.h 2016-08-23 11:55:27 +0000
298@@ -0,0 +1,57 @@
299+/*
300+ * Copyright © 2016 Canonical Ltd.
301+ *
302+ * This program is free software: you can redistribute it and/or modify it
303+ * under the terms of the GNU General Public License version 3,
304+ * as published by the Free Software Foundation.
305+ *
306+ * This program is distributed in the hope that it will be useful,
307+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
308+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
309+ * GNU General Public License for more details.
310+ *
311+ * You should have received a copy of the GNU General Public License
312+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
313+ *
314+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
315+ */
316+
317+#ifndef MIR_GRAPHICS_NESTED_BUFFER_H_
318+#define MIR_GRAPHICS_NESTED_BUFFER_H_
319+
320+#include "mir_toolkit/client_types_nbs.h"
321+#include "mir/graphics/buffer_basic.h"
322+#include "mir/graphics/buffer_properties.h"
323+#include "mir/renderer/sw/pixel_source.h"
324+#include <memory>
325+
326+namespace mir
327+{
328+namespace graphics
329+{
330+class BufferProperties;
331+namespace nested
332+{
333+class HostConnection;
334+class Buffer : public BufferBasic
335+{
336+public:
337+ Buffer(std::shared_ptr<HostConnection> const& connection, BufferProperties const& properties);
338+
339+ std::shared_ptr<NativeBuffer> native_buffer_handle() const override;
340+ geometry::Size size() const override;
341+ MirPixelFormat pixel_format() const override;
342+ NativeBufferBase* native_buffer_base() override;
343+
344+private:
345+ std::shared_ptr<NativeBufferBase> create_native_base(BufferUsage const usage);
346+
347+ std::shared_ptr<HostConnection> const connection;
348+ std::shared_ptr<MirBuffer> buffer;
349+ geometry::Stride const stride_;
350+ std::shared_ptr<NativeBufferBase> const native_base;
351+};
352+}
353+}
354+}
355+#endif /* MIR_GRAPHICS_NESTED_BUFFERH_H_ */
356
357=== modified file 'src/server/graphics/nested/host_connection.h'
358--- src/server/graphics/nested/host_connection.h 2016-06-07 16:20:53 +0000
359+++ src/server/graphics/nested/host_connection.h 2016-08-23 11:55:27 +0000
360@@ -20,8 +20,11 @@
361 #define MIR_GRAPHICS_NESTED_HOST_CONNECTION_H_
362
363 #include "mir_toolkit/client_types.h"
364+#include "mir_toolkit/client_types_nbs.h"
365+#include "mir_toolkit/mir_native_buffer.h"
366 #include "mir/graphics/nested_context.h"
367 #include "mir/geometry/rectangle.h"
368+#include "mir/graphics/buffer_properties.h"
369
370 #include <memory>
371 #include <vector>
372@@ -61,6 +64,9 @@
373 virtual void set_input_device_change_callback(std::function<void(UniqueInputConfig)> const& cb) = 0;
374 virtual void set_input_event_callback(std::function<void(MirEvent const&, mir::geometry::Rectangle const&)> const& cb) = 0;
375 virtual void emit_input_event(MirEvent const& event, mir::geometry::Rectangle const& source_frame) = 0;
376+ virtual std::shared_ptr<MirBuffer> create_buffer(graphics::BufferProperties const&) = 0;
377+ virtual MirNativeBuffer* get_native_handle(MirBuffer*) = 0;
378+ virtual MirGraphicsRegion get_graphics_region(MirBuffer*) = 0;
379
380 protected:
381 HostConnection() = default;
382
383=== modified file 'src/server/graphics/nested/mir_client_host_connection.cpp'
384--- src/server/graphics/nested/mir_client_host_connection.cpp 2016-07-07 09:54:02 +0000
385+++ src/server/graphics/nested/mir_client_host_connection.cpp 2016-08-23 11:55:27 +0000
386@@ -19,6 +19,7 @@
387 #include "mir_client_host_connection.h"
388 #include "host_surface.h"
389 #include "mir_toolkit/mir_client_library.h"
390+#include "mir_toolkit/mir_buffer.h"
391 #include "mir/raii.h"
392 #include "mir/graphics/platform_operation_message.h"
393 #include "mir/graphics/cursor_image.h"
394@@ -418,3 +419,19 @@
395 {
396 event_callback(event, source_frame);
397 }
398+
399+std::shared_ptr<MirBuffer> mgn::MirClientHostConnection::create_buffer(
400+ mg::BufferProperties const&)
401+{
402+ BOOST_THROW_EXCEPTION(std::runtime_error("not implemented yet"));
403+}
404+
405+MirNativeBuffer* mgn::MirClientHostConnection::get_native_handle(MirBuffer*)
406+{
407+ BOOST_THROW_EXCEPTION(std::runtime_error("not implemented yet"));
408+}
409+
410+MirGraphicsRegion mgn::MirClientHostConnection::get_graphics_region(MirBuffer*)
411+{
412+ BOOST_THROW_EXCEPTION(std::runtime_error("not implemented yet"));
413+}
414
415=== modified file 'src/server/graphics/nested/mir_client_host_connection.h'
416--- src/server/graphics/nested/mir_client_host_connection.h 2016-06-07 20:53:08 +0000
417+++ src/server/graphics/nested/mir_client_host_connection.h 2016-08-23 11:55:27 +0000
418@@ -29,6 +29,7 @@
419 #include <string>
420 #include <vector>
421 #include <mutex>
422+#include <condition_variable>
423
424 struct MirConnection;
425
426@@ -79,6 +80,9 @@
427 void set_input_device_change_callback(std::function<void(UniqueInputConfig)> const& cb) override;
428 void set_input_event_callback(std::function<void(MirEvent const&, mir::geometry::Rectangle const&)> const& cb) override;
429 void emit_input_event(MirEvent const& cb, mir::geometry::Rectangle const& source_frame) override;
430+ std::shared_ptr<MirBuffer> create_buffer(graphics::BufferProperties const&) override;
431+ MirNativeBuffer* get_native_handle(MirBuffer*) override;
432+ MirGraphicsRegion get_graphics_region(MirBuffer*) override;
433
434 private:
435 void update_input_config(UniqueInputConfig input_config);
436
437=== modified file 'tests/include/mir/test/doubles/mock_buffer.h'
438--- tests/include/mir/test/doubles/mock_buffer.h 2016-05-03 06:55:25 +0000
439+++ tests/include/mir/test/doubles/mock_buffer.h 2016-08-23 11:55:27 +0000
440@@ -22,6 +22,7 @@
441 #include "mir/graphics/buffer_basic.h"
442 #include "mir/geometry/size.h"
443 #include "mir/graphics/buffer_id.h"
444+#include "mir/renderer/sw/pixel_source.h"
445
446 #include <gmock/gmock.h>
447 #include <gtest/gtest.h>
448@@ -33,7 +34,8 @@
449 namespace doubles
450 {
451
452-struct MockBuffer : public graphics::Buffer, public graphics::NativeBufferBase
453+struct MockBuffer : public graphics::Buffer, public graphics::NativeBufferBase,
454+ public renderer::software::PixelSource
455 {
456 public:
457 MockBuffer()
458
459=== modified file 'tests/include/mir/test/doubles/stub_host_connection.h'
460--- tests/include/mir/test/doubles/stub_host_connection.h 2016-08-10 10:43:39 +0000
461+++ tests/include/mir/test/doubles/stub_host_connection.h 2016-08-23 11:55:27 +0000
462@@ -97,6 +97,21 @@
463 void emit_input_event(MirEvent const&, mir::geometry::Rectangle const&) override
464 {
465 }
466+
467+ std::shared_ptr<MirBuffer> create_buffer(graphics::BufferProperties const&)
468+ {
469+ return nullptr;
470+ }
471+
472+ MirNativeBuffer* get_native_handle(MirBuffer*)
473+ {
474+ return nullptr;
475+ }
476+
477+ MirGraphicsRegion get_graphics_region(MirBuffer*)
478+ {
479+ return MirGraphicsRegion{ 0, 0, 0, mir_pixel_format_invalid, nullptr } ;
480+ }
481 };
482
483
484
485=== modified file 'tests/mir_test_framework/stubbed_graphics_platform.cpp'
486--- tests/mir_test_framework/stubbed_graphics_platform.cpp 2016-08-12 18:41:07 +0000
487+++ tests/mir_test_framework/stubbed_graphics_platform.cpp 2016-08-23 11:55:27 +0000
488@@ -24,6 +24,7 @@
489 #include "mir_test_framework/stub_platform_helpers.h"
490 #include "mir_test_framework/stub_platform_native_buffer.h"
491
492+#include "mir_toolkit/common.h"
493 #include "mir/test/doubles/stub_buffer_allocator.h"
494 #include "mir/test/doubles/stub_display.h"
495 #include "mir/fd.h"
496@@ -136,7 +137,8 @@
497 message.pack_data(static_cast<int>(native_handle->properties.usage));
498 message.pack_data(native_handle->data);
499 message.pack_fd(native_handle->fd);
500- message.pack_stride(buffer.stride());
501+ message.pack_stride(
502+ geom::Stride{buffer.size().width.as_int() * MIR_BYTES_PER_PIXEL(buffer.pixel_format())});
503 message.pack_size(buffer.size());
504 }
505 }
506
507=== modified file 'tests/unit-tests/compositor/test_temporary_buffers.cpp'
508--- tests/unit-tests/compositor/test_temporary_buffers.cpp 2016-05-03 06:55:25 +0000
509+++ tests/unit-tests/compositor/test_temporary_buffers.cpp 2016-08-23 11:55:27 +0000
510@@ -105,17 +105,6 @@
511 EXPECT_EQ(buffer_size, size);
512 }
513
514-TEST_F(TemporaryBuffersTest, base_test_stride)
515-{
516- TemporaryTestBuffer proxy_buffer(mock_buffer);
517- EXPECT_CALL(*mock_buffer, stride())
518- .Times(1);
519-
520- geom::Stride stride;
521- stride = proxy_buffer.stride();
522- EXPECT_EQ(buffer_stride, stride);
523-}
524-
525 TEST_F(TemporaryBuffersTest, base_test_pixel_format)
526 {
527 TemporaryTestBuffer proxy_buffer(mock_buffer);
528
529=== modified file 'tests/unit-tests/platforms/android/server/test_platform.cpp'
530--- tests/unit-tests/platforms/android/server/test_platform.cpp 2016-08-23 08:09:17 +0000
531+++ tests/unit-tests/platforms/android/server/test_platform.cpp 2016-08-23 11:55:27 +0000
532@@ -57,7 +57,6 @@
533
534 stub_display_builder = std::make_shared<mtd::StubDisplayBuilder>();
535 stub_display_report = mr::null_display_report();
536- stride = geom::Stride(300*4);
537
538 num_ints = 43;
539 num_fds = 55;
540@@ -72,19 +71,25 @@
541 native_buffer_handle->data[i] = i;
542 }
543
544- native_buffer = std::make_shared<mtd::MockAndroidNativeBuffer>();
545+ native_buffer = std::make_shared<NiceMock<mtd::MockAndroidNativeBuffer>>();
546 mock_buffer = std::make_shared<NiceMock<mtd::MockBuffer>>();
547
548+ anwb.stride = pixel_stride.as_int();
549 ON_CALL(*native_buffer, handle())
550 .WillByDefault(Return(native_buffer_handle.get()));
551+ ON_CALL(*native_buffer, anwb())
552+ .WillByDefault(Return(&anwb));
553 ON_CALL(*mock_buffer, native_buffer_handle())
554 .WillByDefault(Return(native_buffer));
555 ON_CALL(*mock_buffer, stride())
556- .WillByDefault(Return(stride));
557+ .WillByDefault(Return(byte_stride));
558+ ON_CALL(*mock_buffer, pixel_format())
559+ .WillByDefault(Return(format));
560
561 quirks = std::make_shared<mga::DeviceQuirks>(mga::PropertiesOps{}, context);
562 }
563
564+ ANativeWindowBuffer anwb;
565 std::shared_ptr<mtd::MockAndroidNativeBuffer> native_buffer;
566 std::shared_ptr<mtd::StubBufferAllocator> stub_buffer_allocator;
567 std::shared_ptr<mtd::StubDisplayBuilder> stub_display_builder;
568@@ -95,7 +100,9 @@
569 testing::NiceMock<mtd::MockEGL> mock_egl;
570 mtd::NullGLContext context;
571 std::shared_ptr<mga::DeviceQuirks> quirks;
572- geom::Stride stride;
573+ MirPixelFormat const format = mir_pixel_format_abgr_8888;
574+ geom::Stride const pixel_stride { 300 };
575+ geom::Stride const byte_stride { 300 * MIR_BYTES_PER_PIXEL(format) };
576 unsigned int num_ints, num_fds;
577 };
578
579@@ -120,12 +127,10 @@
580 for (auto i = 0u; i < num_ints; i++)
581 EXPECT_CALL(mock_ipc_msg, pack_data(native_buffer_handle->data[offset++]));
582
583- EXPECT_CALL(*mock_buffer, stride())
584- .WillOnce(Return(stride));
585 #ifndef __clang__
586 // FIXME: Why can't clang compile this on yakkety (with the
587 // gcc6 headers)? (LP: #1609612)
588- EXPECT_CALL(mock_ipc_msg, pack_stride(stride))
589+ EXPECT_CALL(mock_ipc_msg, pack_stride(byte_stride))
590 .Times(1);
591 #endif
592
593@@ -165,12 +170,10 @@
594 .Times(1);
595 }
596
597- EXPECT_CALL(*mock_buffer, stride())
598- .WillOnce(Return(stride));
599 #ifndef __clang__
600 // FIXME: Why can't clang compile this on yakkety (with the
601 // gcc6 headers)? (LP: #1609612)
602- EXPECT_CALL(mock_ipc_msg, pack_stride(stride))
603+ EXPECT_CALL(mock_ipc_msg, pack_stride(byte_stride))
604 .Times(1);
605 #endif
606
607@@ -207,12 +210,10 @@
608 .Times(1);
609 }
610
611- EXPECT_CALL(*mock_buffer, stride())
612- .WillOnce(Return(stride));
613 #ifndef __clang__
614 // FIXME: Why can't clang compile this on yakkety (with the
615 // gcc6 headers)? (LP: #1609612)
616- EXPECT_CALL(mock_ipc_msg, pack_stride(stride))
617+ EXPECT_CALL(mock_ipc_msg, pack_stride(byte_stride))
618 .Times(1);
619 #endif
620
621
622=== modified file 'tests/unit-tests/platforms/mesa/kms/test_gbm_buffer.cpp'
623--- tests/unit-tests/platforms/mesa/kms/test_gbm_buffer.cpp 2016-08-03 13:09:13 +0000
624+++ tests/unit-tests/platforms/mesa/kms/test_gbm_buffer.cpp 2016-08-23 11:55:27 +0000
625@@ -139,7 +139,7 @@
626
627 auto buffer(allocator->alloc_buffer(buffer_properties));
628
629- ASSERT_LE(minimum, buffer->stride());
630+ ASSERT_LE(minimum, geom::Stride{buffer->native_buffer_handle()->stride});
631 }
632
633 TEST_F(GBMBufferTest, buffer_native_handle_has_correct_size)
634
635=== modified file 'tests/unit-tests/platforms/mesa/kms/test_ipc_operations.cpp'
636--- tests/unit-tests/platforms/mesa/kms/test_ipc_operations.cpp 2016-08-23 08:09:17 +0000
637+++ tests/unit-tests/platforms/mesa/kms/test_ipc_operations.cpp 2016-08-23 11:55:27 +0000
638@@ -55,13 +55,12 @@
639 using namespace testing;
640 ON_CALL(mock_buffer, native_buffer_handle())
641 .WillByDefault(Return(mt::fake_shared(native_handle)));
642- ON_CALL(mock_buffer, stride())
643- .WillByDefault(Return(dummy_stride));
644 ON_CALL(mock_buffer, size())
645 .WillByDefault(Return(dummy_size));
646
647 native_handle.data_items = 4;
648 native_handle.fd_items = 2;
649+ native_handle.stride = dummy_stride.as_int();
650 for(auto i=0; i < mir_buffer_package_max; i++)
651 {
652 native_handle.fd[i] = i;
653
654=== modified file 'tests/unit-tests/platforms/nested/CMakeLists.txt'
655--- tests/unit-tests/platforms/nested/CMakeLists.txt 2016-08-23 08:09:17 +0000
656+++ tests/unit-tests/platforms/nested/CMakeLists.txt 2016-08-23 11:55:27 +0000
657@@ -3,6 +3,7 @@
658 ${CMAKE_CURRENT_SOURCE_DIR}/test_nested_display.cpp
659 ${CMAKE_CURRENT_SOURCE_DIR}/mir_display_configuration_builder.cpp
660 ${CMAKE_CURRENT_SOURCE_DIR}/test_nested_cursor.cpp
661+ ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer.cpp
662 ${CMAKE_CURRENT_SOURCE_DIR}/test_nested_display_buffer.cpp
663 $<TARGET_OBJECTS:mir-test-doubles-udev>
664 ${MIR_PLATFORM_OBJECTS}
665@@ -18,6 +19,8 @@
666
667 client_platform_common
668 server_platform_common
669+ mirclient-static
670+ mirclientlttng-static
671 )
672
673 if (MIR_RUN_UNIT_TESTS)
674
675=== added file 'tests/unit-tests/platforms/nested/test_buffer.cpp'
676--- tests/unit-tests/platforms/nested/test_buffer.cpp 1970-01-01 00:00:00 +0000
677+++ tests/unit-tests/platforms/nested/test_buffer.cpp 2016-08-23 11:55:27 +0000
678@@ -0,0 +1,192 @@
679+/*
680+ * Copyright © 2016 Canonical Ltd.
681+ *
682+ * This program is free software: you can redistribute it and/or modify
683+ * it under the terms of the GNU General Public License version 3 as
684+ * published by the Free Software Foundation.
685+ *
686+ * This program is distributed in the hope that it will be useful,
687+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
688+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
689+ * GNU General Public License for more details.
690+ *
691+ * You should have received a copy of the GNU General Public License
692+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
693+ *
694+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
695+ */
696+
697+#include "src/server/graphics/nested/buffer.h"
698+#include "src/client/buffer.h"
699+#include "mir/graphics/buffer_properties.h"
700+#include "mir/test/doubles/stub_host_connection.h"
701+#include "mir/test/doubles/mock_client_buffer.h"
702+#include "mir/test/fake_shared.h"
703+#include "mir/renderer/gl/texture_source.h"
704+#include "mir_toolkit/client_types_nbs.h"
705+
706+#include <gtest/gtest.h>
707+#include <gmock/gmock.h>
708+
709+namespace mt = mir::test;
710+namespace mtd = mir::test::doubles;
711+namespace mg = mir::graphics;
712+namespace mgn = mir::graphics::nested;
713+namespace geom = mir::geometry;
714+namespace mrs = mir::renderer::software;
715+
716+using namespace testing;
717+namespace
718+{
719+struct MockHostConnection : mtd::StubHostConnection
720+{
721+ MOCK_METHOD1(create_buffer, std::shared_ptr<MirBuffer>(mg::BufferProperties const&));
722+ MOCK_METHOD1(get_native_handle, MirNativeBuffer*(MirBuffer*));
723+ MOCK_METHOD1(get_graphics_region, MirGraphicsRegion(MirBuffer*));
724+};
725+
726+struct NestedBuffer : Test
727+{
728+ NestedBuffer()
729+ {
730+ ON_CALL(mock_connection, create_buffer(_))
731+ .WillByDefault(Return(mirbuffer));
732+ ON_CALL(*client_buffer, stride())
733+ .WillByDefault(Return(geom::Stride{stride_with_padding}));
734+ ON_CALL(*client_buffer, size())
735+ .WillByDefault(Return(properties.size));
736+ ON_CALL(*client_buffer, pixel_format())
737+ .WillByDefault(Return(properties.format));
738+ ON_CALL(mock_connection, get_graphics_region(_))
739+ .WillByDefault(Return(region));
740+ }
741+ NiceMock<MockHostConnection> mock_connection;
742+ mg::BufferProperties properties{{1, 1}, mir_pixel_format_abgr_8888, mg::BufferUsage::software};
743+
744+ std::shared_ptr<mtd::MockClientBuffer> client_buffer = std::make_shared<NiceMock<mtd::MockClientBuffer>>();
745+ std::shared_ptr<mir::client::MirBuffer> buffer = std::make_shared<mir::client::Buffer>(
746+ nullptr, nullptr, 0, client_buffer, nullptr, mir_buffer_usage_software);
747+ std::shared_ptr<MirBuffer> mirbuffer { reinterpret_cast<MirBuffer*>(buffer.get()), [](auto){}};
748+
749+ unsigned int data = 0x11111111;
750+ int stride_with_padding = properties.size.width.as_int() * MIR_BYTES_PER_PIXEL(properties.format) + 4;
751+ MirGraphicsRegion region {
752+ properties.size.width.as_int(), properties.size.height.as_int(),
753+ stride_with_padding, properties.format, reinterpret_cast<char*>(&data)
754+ };
755+};
756+}
757+
758+TEST_F(NestedBuffer, creates_buffer_when_constructed)
759+{
760+ EXPECT_CALL(mock_connection, create_buffer(properties))
761+ .WillOnce(Return(mirbuffer));
762+ mgn::Buffer buffer(mt::fake_shared(mock_connection), properties);
763+}
764+
765+TEST_F(NestedBuffer, generates_valid_id)
766+{
767+ mgn::Buffer buffer(mt::fake_shared(mock_connection), properties);
768+ EXPECT_THAT(buffer.id().as_value(), Gt(0));
769+}
770+
771+TEST_F(NestedBuffer, has_correct_properties)
772+{
773+ mgn::Buffer buffer(mt::fake_shared(mock_connection), properties);
774+ EXPECT_THAT(buffer.size(), Eq(properties.size));
775+ EXPECT_THAT(buffer.pixel_format(), Eq(properties.format));
776+}
777+
778+TEST_F(NestedBuffer, no_gl_support_for_now)
779+{
780+ mgn::Buffer buffer(mt::fake_shared(mock_connection), properties);
781+ auto native_base = buffer.native_buffer_base();
782+ EXPECT_THAT(dynamic_cast<mir::renderer::gl::TextureSource*>(native_base), Eq(nullptr));
783+}
784+
785+TEST_F(NestedBuffer, sw_support_if_requested)
786+{
787+ mg::BufferProperties sw_properties{{1, 1}, mir_pixel_format_abgr_8888, mg::BufferUsage::software};
788+ mg::BufferProperties hw_properties{{1, 1}, mir_pixel_format_abgr_8888, mg::BufferUsage::hardware};
789+
790+ {
791+ mgn::Buffer buffer(mt::fake_shared(mock_connection), sw_properties);
792+ EXPECT_THAT(dynamic_cast<mrs::PixelSource*>(buffer.native_buffer_base()), Ne(nullptr));
793+ }
794+
795+ {
796+ mgn::Buffer buffer(mt::fake_shared(mock_connection), hw_properties);
797+ EXPECT_THAT(dynamic_cast<mrs::PixelSource*>(buffer.native_buffer_base()), Eq(nullptr));
798+ }
799+}
800+
801+TEST_F(NestedBuffer, writes_to_region)
802+{
803+ unsigned int data = 0x11223344;
804+ MirGraphicsRegion region {
805+ properties.size.width.as_int(), properties.size.height.as_int(),
806+ properties.size.width.as_int() * MIR_BYTES_PER_PIXEL(properties.format),
807+ properties.format, reinterpret_cast<char*>(&data)
808+ };
809+
810+ unsigned int new_data = 0x11111111;
811+ mgn::Buffer buffer(mt::fake_shared(mock_connection), properties);
812+
813+ EXPECT_CALL(mock_connection, get_graphics_region(_))
814+ .WillOnce(Return(region));
815+ auto pixel_source = dynamic_cast<mir::renderer::software::PixelSource*>(buffer.native_buffer_base());
816+ ASSERT_THAT(pixel_source, Ne(nullptr));
817+ pixel_source->write(reinterpret_cast<unsigned char*>(&new_data), sizeof(new_data));
818+ EXPECT_THAT(data, Eq(new_data));
819+}
820+
821+TEST_F(NestedBuffer, checks_for_null_vaddr)
822+{
823+ mgn::Buffer buffer(mt::fake_shared(mock_connection), properties);
824+
825+ MirGraphicsRegion region { 1, 1, 1, properties.format, nullptr };
826+ EXPECT_CALL(mock_connection, get_graphics_region(_))
827+ .WillOnce(Return(region));
828+ auto pixel_source = dynamic_cast<mir::renderer::software::PixelSource*>(buffer.native_buffer_base());
829+ ASSERT_THAT(pixel_source, Ne(nullptr));
830+
831+ unsigned int new_data = 0x11111111;
832+ EXPECT_THROW({
833+ pixel_source->write(reinterpret_cast<unsigned char*>(&new_data), sizeof(new_data));
834+ }, std::logic_error);
835+}
836+
837+//mg::Buffer::write could be improved so that the user doesn't have to generate potentially large buffers.
838+TEST_F(NestedBuffer, throws_if_incorrect_sizing)
839+{
840+ auto too_large_size = 4 * sizeof(data);
841+ mgn::Buffer buffer(mt::fake_shared(mock_connection), properties);
842+ auto pixel_source = dynamic_cast<mir::renderer::software::PixelSource*>(buffer.native_buffer_base());
843+ ASSERT_THAT(pixel_source, Ne(nullptr));
844+ EXPECT_THROW({
845+ pixel_source->write(reinterpret_cast<unsigned char*>(&data), too_large_size);
846+ }, std::logic_error);
847+}
848+
849+TEST_F(NestedBuffer, reads_from_region)
850+{
851+ unsigned int read_data = 0x11111111;
852+ mgn::Buffer buffer(mt::fake_shared(mock_connection), properties);
853+
854+ EXPECT_CALL(mock_connection, get_graphics_region(_))
855+ .WillOnce(Return(region));
856+ auto pixel_source = dynamic_cast<mir::renderer::software::PixelSource*>(buffer.native_buffer_base());
857+ ASSERT_THAT(pixel_source, Ne(nullptr));
858+ pixel_source->read([&] (auto pix) {
859+ read_data = *reinterpret_cast<decltype(data) const*>(pix);
860+ } );
861+ EXPECT_THAT(read_data, Eq(data));
862+}
863+
864+TEST_F(NestedBuffer, has_correct_stride)
865+{
866+ mgn::Buffer buffer(mt::fake_shared(mock_connection), properties);
867+ auto pixel_source = dynamic_cast<mir::renderer::software::PixelSource*>(buffer.native_buffer_base());
868+ ASSERT_THAT(pixel_source, Ne(nullptr));
869+ EXPECT_THAT(pixel_source->stride().as_int(), Eq(stride_with_padding));
870+}

Subscribers

People subscribed via source and target branches