Mir

Merge lp:~vanvugt/mir/nonprime-server-support into lp:mir

Proposed by Daniel van Vugt
Status: Superseded
Proposed branch: lp:~vanvugt/mir/nonprime-server-support
Merge into: lp:mir
Diff against target: 221 lines (+126/-17)
3 files modified
src/platforms/mesa/server/gbm_buffer.cpp (+37/-8)
src/platforms/mesa/server/gbm_buffer.h (+2/-0)
tests/unit-tests/platforms/mesa/kms/test_gbm_buffer.cpp (+87/-9)
To merge this branch: bzr merge lp:~vanvugt/mir/nonprime-server-support
Reviewer Review Type Date Requested Status
Mir CI Bot continuous-integration Needs Fixing
Mir development team Pending
Review via email: mp+310267@code.launchpad.net

Commit message

Add server-side support for non-PRIME DRM drivers like VirtualBox.

This is enough to get mir_demo_standalone_render_surfaces working
(very nicely) but more work would be required to support clients
(Mesa patch) and nesting.

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

FAILED: Continuous integration, rev:3811
https://mir-jenkins.ubuntu.com/job/mir-ci/2124/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/2744/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/2807
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/2799
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/2799
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/2799
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/2773/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/2773
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/2773/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/2773
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/2773/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/2773
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/2773/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/2773
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/2773/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/2773
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/2773/artifact/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :
3812. By Daniel van Vugt

Try again

Unmerged revisions

3812. By Daniel van Vugt

Try again

3811. By Daniel van Vugt

Prototype

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/platforms/mesa/server/gbm_buffer.cpp'
2--- src/platforms/mesa/server/gbm_buffer.cpp 2016-10-11 07:12:33 +0000
3+++ src/platforms/mesa/server/gbm_buffer.cpp 2016-11-08 10:32:43 +0000
4@@ -41,18 +41,39 @@
5 : gbm_handle{handle},
6 bo_flags{bo_flags},
7 texture_binder{std::move(texture_binder)},
8- prime_fd{-1}
9+ prime_fd{-1},
10+ gem_flink_name{0}
11 {
12 auto device = gbm_bo_get_device(gbm_handle.get());
13 auto gem_handle = gbm_bo_get_handle(gbm_handle.get()).u32;
14 auto drm_fd = gbm_device_get_fd(device);
15
16- auto ret = drmPrimeHandleToFD(drm_fd, gem_handle, DRM_CLOEXEC, &prime_fd);
17+ uint64_t has_prime = 0;
18+ if (0 != drmGetCap(drm_fd, DRM_CAP_PRIME, &has_prime))
19+ has_prime = 0;
20+ supports_prime = !!has_prime;
21
22- if (ret)
23- {
24- std::string const msg("Failed to get PRIME fd from gbm bo");
25- BOOST_THROW_EXCEPTION((std::system_error{errno, std::system_category(), msg}));
26+ // If we have PRIME support, use it exclusively (greatest security)
27+ if (supports_prime)
28+ {
29+ auto ret = drmPrimeHandleToFD(drm_fd, gem_handle, DRM_CLOEXEC, &prime_fd);
30+ if (ret)
31+ {
32+ std::string const msg("Failed to get PRIME fd from gbm bo");
33+ BOOST_THROW_EXCEPTION((std::system_error{errno, std::system_category(), msg}));
34+ }
35+ }
36+ else // use what works, in the absence of PRIME support
37+ {
38+ struct drm_gem_flink flink;
39+ flink.handle = gem_handle;
40+ auto ret = drmIoctl(drm_fd, DRM_IOCTL_GEM_FLINK, &flink);
41+ if (ret)
42+ {
43+ std::string const msg("Failed to get GEM flink name");
44+ BOOST_THROW_EXCEPTION((std::system_error{errno, std::system_category(), msg}));
45+ }
46+ gem_flink_name = flink.name;
47 }
48 }
49
50@@ -86,8 +107,16 @@
51 {
52 auto temp = std::make_shared<NativeBuffer>();
53
54- temp->fd_items = 1;
55- temp->fd[0] = prime_fd;
56+ if (supports_prime)
57+ {
58+ temp->fd_items = 1;
59+ temp->fd[0] = prime_fd;
60+ }
61+ else
62+ {
63+ temp->data_items = 1;
64+ temp->data[0] = gem_flink_name;
65+ }
66 temp->stride = stride().as_uint32_t();
67 temp->flags = (bo_flags & GBM_BO_USE_SCANOUT) ? mir_buffer_flag_can_scanout : 0;
68 temp->bo = gbm_handle.get();
69
70=== modified file 'src/platforms/mesa/server/gbm_buffer.h'
71--- src/platforms/mesa/server/gbm_buffer.h 2016-10-12 13:31:04 +0000
72+++ src/platforms/mesa/server/gbm_buffer.h 2016-11-08 10:32:43 +0000
73@@ -70,7 +70,9 @@
74 std::shared_ptr<gbm_bo> const gbm_handle;
75 uint32_t bo_flags;
76 std::unique_ptr<common::BufferTextureBinder> const texture_binder;
77+ bool supports_prime;
78 int prime_fd;
79+ uint32_t gem_flink_name;
80 };
81
82 }
83
84=== modified file 'tests/unit-tests/platforms/mesa/kms/test_gbm_buffer.cpp'
85--- tests/unit-tests/platforms/mesa/kms/test_gbm_buffer.cpp 2016-10-12 13:31:04 +0000
86+++ tests/unit-tests/platforms/mesa/kms/test_gbm_buffer.cpp 2016-11-08 10:32:43 +0000
87@@ -61,6 +61,9 @@
88 usage = mg::BufferUsage::hardware;
89 buffer_properties = mg::BufferProperties{size, pf, usage};
90
91+ ON_CALL(mock_drm, drmGetCap(_,DRM_CAP_PRIME,_))
92+ .WillByDefault(DoAll(SetArgPointee<2>(1),Return(0)));
93+
94 ON_CALL(mock_gbm, gbm_bo_get_width(_))
95 .WillByDefault(Return(size.width.as_uint32_t()));
96
97@@ -144,7 +147,7 @@
98 ASSERT_LE(minimum, geom::Stride{native->stride});
99 }
100
101-TEST_F(GBMBufferTest, buffer_native_handle_has_correct_size)
102+TEST_F(GBMBufferTest, prime_native_buffer_handle_has_correct_size)
103 {
104 using namespace testing;
105
106@@ -155,6 +158,20 @@
107 EXPECT_EQ(0, native_handle->data_items);
108 }
109
110+TEST_F(GBMBufferTest, nonprime_native_buffer_handle_has_correct_size)
111+{
112+ using namespace testing;
113+
114+ EXPECT_CALL(mock_drm, drmGetCap(_,DRM_CAP_PRIME,_))
115+ .WillOnce(DoAll(SetArgPointee<2>(0),Return(0)));
116+
117+ auto buffer = allocator->alloc_buffer(buffer_properties);
118+ auto native_handle = std::dynamic_pointer_cast<mgm::NativeBuffer>(buffer->native_buffer_handle());
119+ ASSERT_THAT(native_handle, Ne(nullptr));
120+ EXPECT_EQ(0, native_handle->fd_items);
121+ EXPECT_EQ(1, native_handle->data_items);
122+}
123+
124 MATCHER_P(GEMFlinkHandleIs, value, "")
125 {
126 auto flink = reinterpret_cast<struct drm_gem_flink*>(arg);
127@@ -167,7 +184,7 @@
128 flink->name = value;
129 }
130
131-TEST_F(GBMBufferTest, buffer_native_handle_contains_correct_data)
132+TEST_F(GBMBufferTest, prime_native_buffer_handle_contains_correct_data)
133 {
134 using namespace testing;
135
136@@ -190,17 +207,78 @@
137 EXPECT_EQ(stride.as_uint32_t(), static_cast<unsigned int>(handle->stride));
138 }
139
140+TEST_F(GBMBufferTest, nonprime_native_buffer_handle_contains_correct_data)
141+{
142+ using namespace testing;
143+
144+ EXPECT_CALL(mock_drm, drmGetCap(_,DRM_CAP_PRIME,_))
145+ .WillOnce(DoAll(SetArgPointee<2>(0),Return(0)));
146+
147+ uint32_t const flink_name{0xf000baaa};
148+
149+ EXPECT_CALL(mock_drm, drmIoctl(_,DRM_IOCTL_GEM_FLINK,_))
150+ .Times(Exactly(1))
151+ .WillOnce(DoAll(SetGEMFlinkName(flink_name), Return(0)));
152+
153+ auto buffer = allocator->alloc_buffer(buffer_properties);
154+ auto handle = std::dynamic_pointer_cast<mgm::NativeBuffer>(buffer->native_buffer_handle());
155+ ASSERT_THAT(handle, Ne(nullptr));
156+ EXPECT_EQ(0, handle->fd_items);
157+ EXPECT_EQ(1, handle->data_items);
158+ EXPECT_EQ(flink_name, static_cast<uint32_t>(handle->data[0]));
159+ EXPECT_EQ(stride.as_uint32_t(), static_cast<unsigned int>(handle->stride));
160+}
161+
162 TEST_F(GBMBufferTest, buffer_creation_throws_on_prime_fd_failure)
163 {
164 using namespace testing;
165
166- EXPECT_CALL(mock_drm, drmPrimeHandleToFD(_,_,_,_))
167- .Times(Exactly(1))
168- .WillOnce(Return(-1));
169-
170- EXPECT_THROW({
171- auto buffer = allocator->alloc_buffer(buffer_properties);
172- }, std::runtime_error);
173+ EXPECT_CALL(mock_drm, drmGetCap(_,DRM_CAP_PRIME,_))
174+ .Times(Exactly(1))
175+ .WillOnce(DoAll(SetArgPointee<2>(1),Return(0)));
176+ EXPECT_CALL(mock_drm, drmPrimeHandleToFD(_,_,_,_))
177+ .Times(Exactly(1))
178+ .WillOnce(Return(-1));
179+
180+ EXPECT_THROW({
181+ auto buffer = allocator->alloc_buffer(buffer_properties);
182+ }, std::runtime_error);
183+}
184+
185+TEST_F(GBMBufferTest, buffer_creation_throws_on_flink_failure)
186+{
187+ using namespace testing;
188+
189+ EXPECT_CALL(mock_drm, drmGetCap(_,DRM_CAP_PRIME,_))
190+ .Times(Exactly(1))
191+ .WillOnce(DoAll(SetArgPointee<2>(0),Return(0)));
192+ EXPECT_CALL(mock_drm, drmIoctl(_,DRM_IOCTL_GEM_FLINK,_))
193+ .Times(Exactly(1))
194+ .WillOnce(Return(-1));
195+ EXPECT_CALL(mock_drm, drmPrimeHandleToFD(_,_,_,_))
196+ .Times(0);
197+
198+ EXPECT_THROW({
199+ auto buffer = allocator->alloc_buffer(buffer_properties);
200+ }, std::runtime_error);
201+}
202+
203+TEST_F(GBMBufferTest, buffer_creation_falls_back_without_throwing)
204+{
205+ using namespace testing;
206+
207+ EXPECT_CALL(mock_drm, drmGetCap(_,DRM_CAP_PRIME,_))
208+ .Times(Exactly(1))
209+ .WillOnce(DoAll(SetArgPointee<2>(0),Return(0)));
210+ EXPECT_CALL(mock_drm, drmIoctl(_,DRM_IOCTL_GEM_FLINK,_))
211+ .Times(Exactly(1))
212+ .WillOnce(Return(0));
213+ EXPECT_CALL(mock_drm, drmPrimeHandleToFD(_,_,_,_))
214+ .Times(0);
215+
216+ EXPECT_NO_THROW({
217+ auto buffer = allocator->alloc_buffer(buffer_properties);
218+ });
219 }
220
221 TEST_F(GBMBufferTest, gl_bind_to_texture_egl_image_creation_failed)

Subscribers

People subscribed via source and target branches