Mir

Merge lp:~cemil-azizoglu/mir/create-chain-from-render-surface into lp:mir

Proposed by Cemil Azizoglu
Status: Superseded
Proposed branch: lp:~cemil-azizoglu/mir/create-chain-from-render-surface
Merge into: lp:mir
Diff against target: 1317 lines (+711/-263)
16 files modified
playground/mir_demo_client_chain_jumping_buffers.c (+19/-10)
playground/mir_demo_client_prerendered_frames.c (+12/-4)
src/client/error_render_surface.cpp (+5/-0)
src/client/error_render_surface.h (+1/-0)
src/client/mir_connection.cpp (+13/-0)
src/client/mir_connection.h (+4/-0)
src/client/mir_render_surface.h (+1/-0)
src/client/mir_render_surface_api.cpp (+15/-0)
src/client/render_surface.cpp (+19/-0)
src/client/render_surface.h (+3/-0)
src/client/symbols.map (+1/-0)
src/include/client/mir_toolkit/mir_render_surface.h (+8/-0)
tests/acceptance-tests/staging/test_render_surface.cpp (+112/-14)
tests/unit-tests/client/CMakeLists.txt (+1/-0)
tests/unit-tests/client/test_mir_connection.cpp (+3/-235)
tests/unit-tests/client/test_mir_render_surface.cpp (+494/-0)
To merge this branch: bzr merge lp:~cemil-azizoglu/mir/create-chain-from-render-surface
Reviewer Review Type Date Requested Status
Mir development team Pending
Review via email: mp+312187@code.launchpad.net

This proposal has been superseded by a proposal from 2016-11-30.

Commit message

Get presentation chain from a render surface.

Description of the change

Get presentation chain from a render surface.

I also modified the two presentation chain examples in the playground to use render surfaces.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'playground/mir_demo_client_chain_jumping_buffers.c'
2--- playground/mir_demo_client_chain_jumping_buffers.c 2016-11-16 12:50:00 +0000
3+++ playground/mir_demo_client_chain_jumping_buffers.c 2016-11-30 22:47:49 +0000
4@@ -21,6 +21,7 @@
5 #include <mir_toolkit/mir_buffer_stream.h>
6 #include <mir_toolkit/mir_surface.h>
7 #include <mir_toolkit/mir_presentation_chain.h>
8+#include <mir_toolkit/mir_render_surface.h>
9 #include <mir_toolkit/mir_buffer.h>
10 #include <mir_toolkit/version.h>
11 #include <sys/types.h>
12@@ -174,9 +175,17 @@
13 unsigned int spare_buffer = 0;
14
15 MirPresentationChain* chain[num_chains];
16+ MirRenderSurface* render_surface[num_chains];
17 for(unsigned int i = 0u; i < num_chains; i++)
18 {
19- chain[i] = mir_connection_create_presentation_chain_sync(connection);
20+ render_surface[i] = mir_connection_create_render_surface_sync(connection, chain_width, chain_height);
21+ if (!mir_render_surface_is_valid(render_surface[i]))
22+ {
23+ printf("could not create render surface\n");
24+ return -1;
25+ }
26+
27+ chain[i] = mir_render_surface_get_presentation_chain(render_surface[i]);
28 if (!mir_presentation_chain_is_valid(chain[i]))
29 {
30 printf("could not create MirPresentationChain\n");
31@@ -193,14 +202,14 @@
32
33 //Arrange a 2x2 grid of chains within surface
34 MirSurfaceSpec* spec = mir_connection_create_spec_for_normal_surface(connection, width, height, format);
35- mir_surface_spec_add_presentation_chain(
36- spec, chain_width, chain_height, displacement_x, displacement_y, chain[0]);
37- mir_surface_spec_add_presentation_chain(
38- spec, chain_width, chain_height, chain_width, displacement_y, chain[1]);
39- mir_surface_spec_add_presentation_chain(
40- spec, chain_width, chain_height, displacement_x, chain_height, chain[2]);
41- mir_surface_spec_add_presentation_chain(
42- spec, chain_width, chain_height, chain_width, chain_height, chain[3]);
43+ mir_surface_spec_add_render_surface(
44+ spec, render_surface[0], chain_width, chain_height, displacement_x, displacement_y);
45+ mir_surface_spec_add_render_surface(
46+ spec, render_surface[1], chain_width, chain_height, chain_width, displacement_y);
47+ mir_surface_spec_add_render_surface(
48+ spec, render_surface[2], chain_width, chain_height, displacement_x, chain_height);
49+ mir_surface_spec_add_render_surface(
50+ spec, render_surface[3], chain_width, chain_height, chain_width, chain_height);
51 MirSurface* surface = mir_surface_create_sync(spec);
52 mir_surface_spec_release(spec);
53
54@@ -256,7 +265,7 @@
55 for (unsigned int i = 0u; i < num_buffers; i++)
56 mir_buffer_release(buffer_available[i].buffer);
57 for (unsigned int i = 0u; i < num_chains; i++)
58- mir_presentation_chain_release(chain[i]);
59+ mir_render_surface_release(render_surface[i]);
60 mir_surface_release_sync(surface);
61 mir_connection_release(connection);
62 return 0;
63
64=== modified file 'playground/mir_demo_client_prerendered_frames.c'
65--- playground/mir_demo_client_prerendered_frames.c 2016-11-16 12:50:00 +0000
66+++ playground/mir_demo_client_prerendered_frames.c 2016-11-30 22:47:49 +0000
67@@ -21,6 +21,7 @@
68 #include <mir_toolkit/mir_buffer_stream.h>
69 #include <mir_toolkit/mir_surface.h>
70 #include <mir_toolkit/mir_presentation_chain.h>
71+#include <mir_toolkit/mir_render_surface.h>
72 #include <mir_toolkit/mir_buffer.h>
73 #include <mir_toolkit/version.h>
74 #include <sys/types.h>
75@@ -146,7 +147,14 @@
76 return -1;
77 }
78
79- MirPresentationChain* chain = mir_connection_create_presentation_chain_sync(connection);
80+ MirRenderSurface* render_surface = mir_connection_create_render_surface_sync(connection, width, height);
81+ if (!mir_render_surface_is_valid(render_surface))
82+ {
83+ printf("could not create a render surface\n");
84+ return -1;
85+ }
86+
87+ MirPresentationChain* chain = mir_render_surface_get_presentation_chain(render_surface);
88 if (!mir_presentation_chain_is_valid(chain))
89 {
90 printf("could not create MirPresentationChain\n");
91@@ -161,8 +169,8 @@
92 }
93
94 MirSurfaceSpec* spec = mir_connection_create_spec_for_normal_surface(connection, width, height, format);
95- mir_surface_spec_add_presentation_chain(
96- spec, width, height, displacement_x, displacement_y, chain);
97+ mir_surface_spec_add_render_surface(
98+ spec, render_surface, width, height, displacement_x, displacement_y);
99 MirSurface* surface = mir_surface_create_sync(spec);
100 if (!mir_surface_is_valid(surface))
101 {
102@@ -224,7 +232,7 @@
103
104 for (i = 0u; i < num_prerendered_frames; i++)
105 mir_buffer_release(buffer_available[i].buffer);
106- mir_presentation_chain_release(chain);
107+ mir_render_surface_release(render_surface);
108 mir_surface_release_sync(surface);
109 mir_connection_release(connection);
110 return 0;
111
112=== modified file 'src/client/error_render_surface.cpp'
113--- src/client/error_render_surface.cpp 2016-11-22 18:44:52 +0000
114+++ src/client/error_render_surface.cpp 2016-11-30 22:47:49 +0000
115@@ -60,6 +60,11 @@
116 throw std::runtime_error(error);
117 }
118
119+MirPresentationChain* mcl::ErrorRenderSurface::get_presentation_chain()
120+{
121+ throw std::runtime_error(error);
122+}
123+
124 char const* mcl::ErrorRenderSurface::get_error_message() const
125 {
126 return error.c_str();
127
128=== modified file 'src/client/error_render_surface.h'
129--- src/client/error_render_surface.h 2016-11-22 18:44:52 +0000
130+++ src/client/error_render_surface.h 2016-11-30 22:47:49 +0000
131@@ -41,6 +41,7 @@
132 int width, int height,
133 MirPixelFormat format,
134 MirBufferUsage buffer_usage) override;
135+ MirPresentationChain* get_presentation_chain() override;
136 private:
137 std::string const error;
138 MirConnection* const connection_;
139
140=== modified file 'src/client/mir_connection.cpp'
141--- src/client/mir_connection.cpp 2016-11-22 18:18:59 +0000
142+++ src/client/mir_connection.cpp 2016-11-30 22:47:49 +0000
143@@ -1177,6 +1177,19 @@
144 return display_configuration->take_snapshot();
145 }
146
147+std::shared_ptr<mcl::PresentationChain> MirConnection::create_presentation_chain_with_id(
148+ MirRenderSurface* render_surface,
149+ mir::protobuf::BufferStream const& a_protobuf_bs)
150+{
151+ if (!client_buffer_factory)
152+ client_buffer_factory = platform->create_buffer_factory();
153+ auto chain = std::make_shared<mcl::PresentationChain>(
154+ this, a_protobuf_bs.id().value(), server, client_buffer_factory, buffer_factory);
155+
156+ surface_map->insert(render_surface->stream_id(), chain);
157+ return chain;
158+}
159+
160 void MirConnection::create_presentation_chain(
161 mir_presentation_chain_callback callback,
162 void *context)
163
164=== modified file 'src/client/mir_connection.h'
165--- src/client/mir_connection.h 2016-11-14 21:59:19 +0000
166+++ src/client/mir_connection.h 2016-11-30 22:47:49 +0000
167@@ -67,6 +67,7 @@
168 class AsyncBufferFactory;
169 class MirBuffer;
170 class BufferStream;
171+class PresentationChain;
172
173 namespace rpc
174 {
175@@ -170,6 +171,9 @@
176 void create_presentation_chain(
177 mir_presentation_chain_callback callback,
178 void *context);
179+ std::shared_ptr<mir::client::PresentationChain> create_presentation_chain_with_id(
180+ MirRenderSurface* render_surface,
181+ mir::protobuf::BufferStream const& a_protobuf_bs);
182 void release_presentation_chain(MirPresentationChain* context);
183
184 void release_consumer_stream(mir::client::ClientBufferStream*);
185
186=== modified file 'src/client/mir_render_surface.h'
187--- src/client/mir_render_surface.h 2016-11-22 18:44:52 +0000
188+++ src/client/mir_render_surface.h 2016-11-30 22:47:49 +0000
189@@ -36,6 +36,7 @@
190 int width, int height,
191 MirPixelFormat format,
192 MirBufferUsage buffer_usage) = 0;
193+ virtual MirPresentationChain* get_presentation_chain() = 0;
194 virtual char const* get_error_message() const = 0;
195 virtual ~MirRenderSurface() = default;
196 protected:
197
198=== modified file 'src/client/mir_render_surface_api.cpp'
199--- src/client/mir_render_surface_api.cpp 2016-11-22 18:44:52 +0000
200+++ src/client/mir_render_surface_api.cpp 2016-11-30 22:47:49 +0000
201@@ -189,6 +189,21 @@
202 return nullptr;
203 }
204
205+MirPresentationChain* mir_render_surface_get_presentation_chain(
206+ MirRenderSurface* render_surface)
207+try
208+{
209+ mir::require(render_surface);
210+ auto connection = connection_map.connection(static_cast<void*>(render_surface));
211+ auto rs = connection->connection_surface_map()->render_surface(render_surface);
212+ return rs->get_presentation_chain();
213+}
214+catch (std::exception const& ex)
215+{
216+ MIR_LOG_UNCAUGHT_EXCEPTION(ex);
217+ return nullptr;
218+}
219+
220 void mir_render_surface_get_size(MirRenderSurface* render_surface, int* width, int* height)
221 {
222 mir::require(render_surface && width && height);
223
224=== modified file 'src/client/render_surface.cpp'
225--- src/client/render_surface.cpp 2016-11-22 18:44:52 +0000
226+++ src/client/render_surface.cpp 2016-11-30 22:47:49 +0000
227@@ -61,6 +61,9 @@
228 MirPixelFormat format,
229 MirBufferUsage buffer_usage)
230 {
231+ if (chain_from_id)
232+ BOOST_THROW_EXCEPTION(std::logic_error("Already contains a presentation chain"));
233+
234 if (!stream_from_id)
235 {
236 protobuf_bs->set_pixel_format(format);
237@@ -80,6 +83,22 @@
238 dynamic_cast<ClientBufferStream*>(stream_from_id.get()));
239 }
240
241+MirPresentationChain* mcl::RenderSurface::get_presentation_chain()
242+{
243+ if (stream_from_id)
244+ BOOST_THROW_EXCEPTION(std::logic_error("Already contains a buffer stream"));
245+
246+ if (!chain_from_id)
247+ {
248+ chain_from_id = connection_->create_presentation_chain_with_id(this,
249+ *protobuf_bs);
250+ //TODO: Figure out how to handle mir_buffer_usage_hardware once
251+ // EGL is made to support RSs.
252+ }
253+
254+ return reinterpret_cast<MirPresentationChain*>(chain_from_id.get());
255+}
256+
257 geom::Size mcl::RenderSurface::size() const
258 {
259 std::lock_guard<decltype(size_mutex)> lk(size_mutex);
260
261=== modified file 'src/client/render_surface.h'
262--- src/client/render_surface.h 2016-11-22 18:44:52 +0000
263+++ src/client/render_surface.h 2016-11-30 22:47:49 +0000
264@@ -39,6 +39,7 @@
265 {
266 class ClientPlatform;
267 class BufferStream;
268+class PresentationChain;
269 class RenderSurface : public MirRenderSurface
270 {
271 public:
272@@ -57,6 +58,7 @@
273 int width, int height,
274 MirPixelFormat format,
275 MirBufferUsage buffer_usage) override;
276+ MirPresentationChain* get_presentation_chain() override;
277
278 private:
279 MirConnection* const connection_;
280@@ -64,6 +66,7 @@
281 std::shared_ptr<ClientPlatform> platform;
282 std::shared_ptr<mir::protobuf::BufferStream> protobuf_bs;
283 std::shared_ptr<mir::client::BufferStream> stream_from_id;
284+ std::shared_ptr<mir::client::PresentationChain> chain_from_id;
285
286 std::mutex mutable size_mutex;
287 geometry::Size desired_size;
288
289=== modified file 'src/client/symbols.map'
290--- src/client/symbols.map 2016-11-30 11:38:41 +0000
291+++ src/client/symbols.map 2016-11-30 22:47:49 +0000
292@@ -388,6 +388,7 @@
293 mir_connection_create_render_surface;
294 mir_connection_create_render_surface_sync;
295 mir_render_surface_get_buffer_stream;
296+ mir_render_surface_get_presentation_chain;
297 mir_render_surface_is_valid;
298 mir_render_surface_get_error_message;
299 mir_render_surface_get_size;
300
301=== modified file 'src/include/client/mir_toolkit/mir_render_surface.h'
302--- src/include/client/mir_toolkit/mir_render_surface.h 2016-11-14 22:39:13 +0000
303+++ src/include/client/mir_toolkit/mir_render_surface.h 2016-11-30 22:47:49 +0000
304@@ -133,6 +133,14 @@
305 MirBufferUsage usage);
306
307 /**
308+ * Obtain the presentation chain backing a given render surface
309+ *
310+ * \return The chain contained in the given render surface
311+ */
312+MirPresentationChain* mir_render_surface_get_presentation_chain(
313+ MirRenderSurface* render_surface);
314+
315+/**
316 * Set the MirSurfaceSpec to display content contained in a render surface
317 *
318 * \warning: The initial call to mir_surface_spec_add_render_surface will set
319
320=== modified file 'tests/acceptance-tests/staging/test_render_surface.cpp'
321--- tests/acceptance-tests/staging/test_render_surface.cpp 2016-11-23 00:09:04 +0000
322+++ tests/acceptance-tests/staging/test_render_surface.cpp 2016-11-30 22:47:49 +0000
323@@ -18,6 +18,7 @@
324
325 #include "mir_toolkit/mir_client_library.h"
326 #include "mir_toolkit/mir_render_surface.h"
327+#include "mir_toolkit/mir_presentation_chain.h"
328
329 #include "mir/geometry/size.h"
330 #include "mir_test_framework/headless_in_process_server.h"
331@@ -57,7 +58,7 @@
332 mir_connection_release(connection);
333 }
334
335-TEST_F(RenderSurfaceTest, can_hand_out_buffer_streams)
336+TEST_F(RenderSurfaceTest, can_hand_out_buffer_stream)
337 {
338 auto connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
339
340@@ -98,6 +99,7 @@
341 physical_size.width.as_int(), physical_size.height.as_int(),
342 mir_pixel_format_abgr_8888,
343 mir_buffer_usage_hardware);
344+
345 ASSERT_THAT(bs, NotNull());
346 EXPECT_TRUE(mir_buffer_stream_is_valid(bs));
347 EXPECT_THAT(mir_buffer_stream_get_error_message(bs), StrEq(""));
348@@ -109,32 +111,28 @@
349 TEST_F(RenderSurfaceTest, render_surfaces_without_content_can_be_added_to_spec)
350 {
351 auto physical_size = logical_size;
352-
353 auto connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
354
355 auto rs = mir_connection_create_render_surface_sync(
356 connection, logical_size.width.as_int(), logical_size.height.as_int());
357-
358 auto spec = mir_connection_create_spec_for_normal_surface(
359 connection,
360 physical_size.width.as_int(), physical_size.height.as_int(),
361 mir_pixel_format_invalid);
362-
363 mir_surface_spec_add_render_surface(
364 spec, rs, logical_size.width.as_int(), logical_size.height.as_int(), 0, 0);
365-
366 auto surface = mir_surface_create_sync(spec);
367 mir_surface_spec_release(spec);
368
369 EXPECT_THAT(surface, IsValid());
370-
371 EXPECT_THAT(mir_surface_get_buffer_stream(surface), Eq(nullptr));
372+
373 mir_render_surface_release(rs);
374 mir_surface_release_sync(surface);
375 mir_connection_release(connection);
376 }
377
378-TEST_F(RenderSurfaceTest, content_can_be_constructed_after_surface_creation)
379+TEST_F(RenderSurfaceTest, stream_can_be_constructed_after_surface_creation)
380 {
381 int const width{800}, height{600};
382 MirPixelFormat const format{mir_pixel_format_abgr_8888};
383@@ -143,26 +141,126 @@
384 auto connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
385
386 auto rs = mir_connection_create_render_surface_sync(
387- connection, logical_size.width.as_int(), logical_size.height.as_int());
388+ connection, logical_size.width.as_int(), logical_size.height.as_int());
389 auto spec = mir_connection_create_spec_for_normal_surface(connection,
390 width, height,
391 format);
392-
393 mir_surface_spec_add_render_surface(spec, rs, width, height, 0, 0);
394-
395 auto surface = mir_surface_create_sync(spec);
396 mir_surface_spec_release(spec);
397-
398 auto bs = mir_render_surface_get_buffer_stream(rs,
399 640, 480,
400 format,
401 usage);
402
403 EXPECT_THAT(surface, IsValid());
404-
405 EXPECT_THAT(mir_surface_get_buffer_stream(surface), Eq(nullptr));
406 EXPECT_TRUE(mir_buffer_stream_is_valid(bs));
407- mir_render_surface_release(rs);
408- mir_surface_release_sync(surface);
409+
410+ mir_render_surface_release(rs);
411+ mir_surface_release_sync(surface);
412+ mir_connection_release(connection);
413+}
414+
415+TEST_F(RenderSurfaceTest, can_hand_out_presentation_chain)
416+{
417+ auto connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
418+
419+ auto rs = mir_connection_create_render_surface_sync(
420+ connection, logical_size.width.as_int(), logical_size.height.as_int());
421+
422+ auto pc = mir_render_surface_get_presentation_chain(rs);
423+
424+ ASSERT_THAT(pc, NotNull());
425+ EXPECT_TRUE(mir_presentation_chain_is_valid(pc));
426+
427+ mir_render_surface_release(rs);
428+ mir_connection_release(connection);
429+}
430+
431+TEST_F(RenderSurfaceTest, chain_can_be_constructed_after_surface_creation)
432+{
433+ int const width{800}, height{600};
434+ MirPixelFormat const format{mir_pixel_format_abgr_8888};
435+
436+ auto connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
437+
438+ auto rs = mir_connection_create_render_surface_sync(
439+ connection, logical_size.width.as_int(), logical_size.height.as_int());
440+ auto spec = mir_connection_create_spec_for_normal_surface(connection,
441+ width, height,
442+ format);
443+ mir_surface_spec_add_render_surface(spec, rs, width, height, 0, 0);
444+ auto surface = mir_surface_create_sync(spec);
445+ mir_surface_spec_release(spec);
446+ auto pc = mir_render_surface_get_presentation_chain(rs);
447+
448+ EXPECT_THAT(surface, IsValid());
449+ EXPECT_THAT(mir_surface_get_buffer_stream(surface), Eq(nullptr));
450+ EXPECT_TRUE(mir_presentation_chain_is_valid(pc));
451+
452+ mir_render_surface_release(rs);
453+ mir_surface_release_sync(surface);
454+ mir_connection_release(connection);
455+}
456+
457+TEST_F(RenderSurfaceTest, dont_have_to_release_presentation_chain)
458+{
459+ auto connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
460+
461+ auto rs = mir_connection_create_render_surface_sync(
462+ connection, logical_size.width.as_int(), logical_size.height.as_int());
463+ auto pc = mir_render_surface_get_presentation_chain(rs);
464+
465+ ASSERT_THAT(pc, NotNull());
466+ EXPECT_TRUE(mir_presentation_chain_is_valid(pc));
467+
468+ mir_render_surface_release(rs);
469+ mir_connection_release(connection);
470+}
471+
472+TEST_F(RenderSurfaceTest, can_hand_out_stream_or_chain_but_not_both)
473+{
474+ auto physical_size = logical_size;
475+ auto connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
476+
477+ {
478+ auto rs = mir_connection_create_render_surface_sync(
479+ connection, logical_size.width.as_int(), logical_size.height.as_int());
480+ auto pc = mir_render_surface_get_presentation_chain(rs);
481+
482+ ASSERT_THAT(pc, NotNull());
483+ EXPECT_TRUE(mir_presentation_chain_is_valid(pc));
484+
485+ auto bs = mir_render_surface_get_buffer_stream(
486+ rs,
487+ physical_size.width.as_int(), physical_size.height.as_int(),
488+ mir_pixel_format_abgr_8888,
489+ mir_buffer_usage_hardware);
490+
491+ EXPECT_THAT(bs, Eq(nullptr));
492+
493+ mir_render_surface_release(rs);
494+ }
495+
496+ {
497+ auto rs = mir_connection_create_render_surface_sync(
498+ connection, logical_size.width.as_int(), logical_size.height.as_int());
499+ auto bs = mir_render_surface_get_buffer_stream(
500+ rs,
501+ physical_size.width.as_int(), physical_size.height.as_int(),
502+ mir_pixel_format_abgr_8888,
503+ mir_buffer_usage_hardware);
504+
505+ ASSERT_THAT(bs, NotNull());
506+ EXPECT_TRUE(mir_buffer_stream_is_valid(bs));
507+
508+ auto pc = mir_render_surface_get_presentation_chain(rs);
509+
510+ EXPECT_THAT(pc, Eq(nullptr));
511+
512+ mir_render_surface_release(rs);
513+ }
514+
515 mir_connection_release(connection);
516 }
517
518=== modified file 'tests/unit-tests/client/CMakeLists.txt'
519--- tests/unit-tests/client/CMakeLists.txt 2016-10-26 05:15:38 +0000
520+++ tests/unit-tests/client/CMakeLists.txt 2016-11-30 22:47:49 +0000
521@@ -23,6 +23,7 @@
522 ${CMAKE_CURRENT_SOURCE_DIR}/test_error_buffer.cpp
523 ${CMAKE_CURRENT_SOURCE_DIR}/test_client_mir_error.cpp
524 ${CMAKE_CURRENT_SOURCE_DIR}/test_no_tls_future.cpp
525+ ${CMAKE_CURRENT_SOURCE_DIR}/test_mir_render_surface.cpp
526 )
527
528 if (NOT MIR_DISABLE_INPUT)
529
530=== modified file 'tests/unit-tests/client/test_mir_connection.cpp'
531--- tests/unit-tests/client/test_mir_connection.cpp 2016-11-23 00:09:04 +0000
532+++ tests/unit-tests/client/test_mir_connection.cpp 2016-11-30 22:47:49 +0000
533@@ -23,8 +23,6 @@
534 #include "src/client/mir_surface.h"
535 #include "src/client/buffer_factory.h"
536 #include "src/client/presentation_chain.h"
537-#include "src/client/render_surface.h"
538-#include "src/client/connection_surface_map.h"
539
540 #include "mir/client_platform.h"
541 #include "mir/client_platform_factory.h"
542@@ -36,7 +34,6 @@
543 #include "mir_toolkit/mir_presentation_chain.h"
544
545 #include "src/server/frontend/resource_cache.h" /* needed by test_server.h */
546-#include "mir/test/fake_shared.h"
547 #include "mir/test/test_protobuf_server.h"
548 #include "mir/test/stub_server_tool.h"
549 #include "mir/test/doubles/mock_mir_buffer.h"
550@@ -57,31 +54,11 @@
551 namespace mev = mir::events;
552 namespace md = mir::dispatch;
553 namespace geom = mir::geometry;
554-namespace mt = mir::test;
555-namespace mtd = mt::doubles;
556+namespace mtd = mir::test::doubles;
557 using namespace testing;
558
559 namespace
560 {
561-
562-void assign_result(void* result, void** context)
563-{
564- if (context)
565- *context = result;
566-}
567-
568-struct RenderSurfaceCallback
569-{
570- static void created(MirRenderSurface* render_surface, void *client_context)
571- {
572- auto const context = reinterpret_cast<RenderSurfaceCallback*>(client_context);
573- context->invoked = true;
574- context->resulting_render_surface = render_surface;
575- }
576- bool invoked = false;
577- MirRenderSurface* resulting_render_surface = nullptr;
578-};
579-
580 struct BufferStreamCallback
581 {
582 static void created(MirBufferStream* stream, void *client_context)
583@@ -202,15 +179,12 @@
584 auto native_display = std::make_shared<EGLNativeDisplayType>();
585 *native_display = reinterpret_cast<EGLNativeDisplayType>(0x0);
586
587- auto native_window = std::make_shared<EGLNativeWindowType>();
588- *native_window = reinterpret_cast<EGLNativeWindowType>(0x12345678);
589-
590 ON_CALL(*this, create_egl_native_display())
591 .WillByDefault(Return(native_display));
592 ON_CALL(*this, create_buffer_factory())
593 .WillByDefault(Return(std::make_shared<mtd::StubClientBufferFactory>()));
594 ON_CALL(*this, create_egl_native_window(_))
595- .WillByDefault(Return(native_window));
596+ .WillByDefault(Return(std::shared_ptr<EGLNativeWindowType>()));
597 ON_CALL(*this, platform_operation(_))
598 .WillByDefault(Return(nullptr));
599 }
600@@ -232,8 +206,7 @@
601 MOCK_METHOD2(use_egl_native_window, void(std::shared_ptr<void>, mcl::EGLNativeSurface*));
602 MOCK_METHOD1(create_egl_native_window, std::shared_ptr<void>(mcl::EGLNativeSurface*));
603 MOCK_METHOD0(create_egl_native_display, std::shared_ptr<EGLNativeDisplayType>());
604- MOCK_CONST_METHOD2(get_egl_pixel_format,
605- MirPixelFormat(EGLDisplay, EGLConfig));
606+ MOCK_CONST_METHOD2(get_egl_pixel_format, MirPixelFormat(EGLDisplay, EGLConfig));
607 MOCK_METHOD2(request_interface, void*(char const*, int));
608
609 mcl::ClientContext* client_context = nullptr;
610@@ -877,208 +850,3 @@
611
612 connection->release_buffer(&mock_buffer);
613 }
614-
615-TEST_F(MirConnectionTest, render_surface_can_be_created_and_released)
616-{
617- EXPECT_CALL(*mock_channel, on_buffer_stream_create(_,_))
618- .WillOnce(Invoke([](mp::BufferStream& stream, google::protobuf::Closure*)
619- {
620- stream.mutable_id()->set_value(1);
621- }));
622-
623- connection->connect("MirConnectionTest", connected_callback, 0)->wait_for_all();
624-
625- void* nw = nullptr;
626- MirRenderSurface* render_surface = nullptr;
627- connection->create_render_surface_with_content(
628- {10, 10},
629- reinterpret_cast<mir_render_surface_callback>(assign_result),
630- &render_surface,
631- &nw);
632- EXPECT_THAT(render_surface, NotNull());
633- EXPECT_THAT(nw, NotNull());
634- EXPECT_THAT(render_surface, Eq(nw));
635- EXPECT_NO_THROW(connection->release_render_surface_with_content(nw));
636-
637- connection->disconnect();
638-}
639-
640-TEST_F(MirConnectionTest, creation_of_render_surface_creates_egl_native_window)
641-{
642- RenderSurfaceCallback callback;
643-
644- connection->connect("MirConnectionTest", connected_callback, 0)->wait_for_all();
645-
646- EXPECT_CALL(*mock_platform, create_egl_native_window(nullptr));
647- EXPECT_CALL(*mock_channel, on_buffer_stream_create(_,_))
648- .WillOnce(Invoke([](mp::BufferStream& stream, google::protobuf::Closure*)
649- {
650- stream.mutable_id()->set_value(1);
651- }));
652-
653- void* nw = nullptr;
654- connection->create_render_surface_with_content(
655- {10, 10},
656- &RenderSurfaceCallback::created,
657- &callback,
658- &nw);
659- EXPECT_THAT(nw, NotNull());
660- EXPECT_TRUE(callback.invoked);
661- EXPECT_THAT(callback.resulting_render_surface, NotNull());
662- auto rs = connection->connection_surface_map()->render_surface(
663- static_cast<void*>(callback.resulting_render_surface));
664- EXPECT_TRUE(reinterpret_cast<mcl::RenderSurface*>(rs->valid()));
665-}
666-
667-TEST_F(MirConnectionTest, render_surface_returns_connection)
668-{
669- MirConnection* conn{ reinterpret_cast<MirConnection*>(0x12345678) };
670-
671- mcl::RenderSurface rs(
672- conn, nullptr, nullptr, nullptr, {});
673- EXPECT_THAT(rs.connection(), Eq(conn));
674-}
675-
676-TEST_F(MirConnectionTest, render_surface_has_correct_id_before_content_creation)
677-{
678- MirConnection* conn{ reinterpret_cast<MirConnection*>(0x12345678) };
679- auto id = 123;
680-
681- mp::BufferStream protobuf_bs;
682- mp::BufferStreamId bs_id;
683-
684- bs_id.set_value(id);
685- *protobuf_bs.mutable_id() = bs_id;
686-
687- mcl::RenderSurface rs(
688- conn, nullptr, nullptr, mt::fake_shared(protobuf_bs), {});
689- EXPECT_THAT(rs.stream_id().as_value(), Eq(id));
690-}
691-
692-TEST_F(MirConnectionTest, render_surface_can_create_buffer_stream)
693-{
694- connection->connect("MirConnectionTest", connected_callback, 0)->wait_for_all();
695- auto id = 123;
696-
697- mp::BufferStream protobuf_bs;
698- mp::BufferStreamId bs_id;
699-
700- bs_id.set_value(id);
701- *protobuf_bs.mutable_id() = bs_id;
702-
703- auto native_window = mock_platform->create_egl_native_window(nullptr);
704-
705- mcl::RenderSurface rs(
706- connection.get(), native_window, nullptr, mt::fake_shared(protobuf_bs), {});
707-
708- auto bs = rs.get_buffer_stream(2, 2, mir_pixel_format_abgr_8888,
709- mir_buffer_usage_software);
710-
711- EXPECT_THAT(bs, NotNull());
712-}
713-
714-TEST_F(MirConnectionTest, render_surface_creation_of_buffer_stream_more_than_once_returns_same_object)
715-{
716- connection->connect("MirConnectionTest", connected_callback, 0)->wait_for_all();
717- auto id = 123;
718-
719- mp::BufferStream protobuf_bs;
720- mp::BufferStreamId bs_id;
721-
722- bs_id.set_value(id);
723- *protobuf_bs.mutable_id() = bs_id;
724-
725- auto native_window = mock_platform->create_egl_native_window(nullptr);
726-
727- mcl::RenderSurface rs(
728- connection.get(), native_window, mock_platform, mt::fake_shared(protobuf_bs), {});
729-
730- EXPECT_CALL(*mock_platform, use_egl_native_window(native_window,_));
731-
732- auto bs1 = rs.get_buffer_stream(2, 2, mir_pixel_format_abgr_8888,
733- mir_buffer_usage_hardware);
734-
735- auto bs2 = rs.get_buffer_stream(2, 2, mir_pixel_format_abgr_8888,
736- mir_buffer_usage_hardware);
737-
738- EXPECT_THAT(bs1, NotNull());
739- EXPECT_THAT(bs2, NotNull());
740- EXPECT_THAT(bs1, Eq(bs2));
741-}
742-
743-TEST_F(MirConnectionTest, render_surface_creation_of_buffer_stream_with_hardware_usage_installs_new_native_window)
744-{
745- connection->connect("MirConnectionTest", connected_callback, 0)->wait_for_all();
746- auto id = 123;
747-
748- mp::BufferStream protobuf_bs;
749- mp::BufferStreamId bs_id;
750-
751- bs_id.set_value(id);
752- *protobuf_bs.mutable_id() = bs_id;
753-
754- auto native_window = mock_platform->create_egl_native_window(nullptr);
755-
756- mcl::RenderSurface rs(
757- connection.get(), native_window, mock_platform, mt::fake_shared(protobuf_bs), {});
758-
759- EXPECT_CALL(*mock_platform, use_egl_native_window(native_window,_));
760-
761- auto bs = rs.get_buffer_stream(2, 2, mir_pixel_format_abgr_8888,
762- mir_buffer_usage_hardware);
763-
764- EXPECT_THAT(bs, NotNull());
765-}
766-
767-TEST_F(MirConnectionTest, render_surface_creation_of_buffer_stream_with_software_usage_does_not_install_new_native_window)
768-{
769- connection->connect("MirConnectionTest", connected_callback, 0)->wait_for_all();
770- auto id = 123;
771-
772- mp::BufferStream protobuf_bs;
773- mp::BufferStreamId bs_id;
774-
775- bs_id.set_value(id);
776- *protobuf_bs.mutable_id() = bs_id;
777-
778- auto native_window = mock_platform->create_egl_native_window(nullptr);
779-
780- mcl::RenderSurface rs(
781- connection.get(), native_window, mock_platform, mt::fake_shared(protobuf_bs), {});
782-
783- EXPECT_CALL(*mock_platform, use_egl_native_window(_,_)).Times(0);
784-
785- auto bs = rs.get_buffer_stream(2, 2, mir_pixel_format_abgr_8888,
786- mir_buffer_usage_software);
787-
788- EXPECT_THAT(bs, NotNull());
789-}
790-
791-TEST_F(MirConnectionTest, render_surface_object_is_invalid_after_creation_exception)
792-{
793- RenderSurfaceCallback callback;
794-
795- connection->connect("MirConnectionTest", connected_callback, 0)->wait_for_all();
796-
797- EXPECT_CALL(*mock_channel, on_buffer_stream_create(_,_))
798- .WillOnce(DoAll(
799- Invoke([](mp::BufferStream&, google::protobuf::Closure* c){ c->Run(); }),
800- Throw(std::runtime_error("Eeek!"))));
801-
802- void* nw = nullptr;
803- connection->create_render_surface_with_content(
804- {10, 10},
805- &RenderSurfaceCallback::created,
806- &callback,
807- &nw);
808-
809- EXPECT_TRUE(callback.invoked);
810- EXPECT_THAT(callback.resulting_render_surface, NotNull());
811- auto rs = connection->connection_surface_map()->render_surface(
812- static_cast<void*>(callback.resulting_render_surface));
813-
814- EXPECT_THAT(rs->get_error_message(),
815- StrEq("Error processing buffer stream response during render "
816- "surface creation: no ID in response (disconnected?)"));
817- EXPECT_FALSE(reinterpret_cast<mcl::RenderSurface*>(rs->valid()));
818-}
819
820=== added file 'tests/unit-tests/client/test_mir_render_surface.cpp'
821--- tests/unit-tests/client/test_mir_render_surface.cpp 1970-01-01 00:00:00 +0000
822+++ tests/unit-tests/client/test_mir_render_surface.cpp 2016-11-30 22:47:49 +0000
823@@ -0,0 +1,494 @@
824+/*
825+ * Copyright © 2016 Canonical Ltd.
826+ *
827+ * This program is free software: you can redistribute it and/or modify
828+ * it under the terms of the GNU General Public License version 3 as
829+ * published by the Free Software Foundation.
830+ *
831+ * This program is distributed in the hope that it will be useful,
832+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
833+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
834+ * GNU General Public License for more details.
835+ *
836+ * You should have received a copy of the GNU General Public License
837+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
838+ *
839+ * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com>
840+ */
841+
842+#include "src/client/mir_connection.h"
843+#include "src/client/default_connection_configuration.h"
844+#include "src/client/rpc/mir_basic_rpc_channel.h"
845+#include "src/client/render_surface.h"
846+#include "src/client/connection_surface_map.h"
847+
848+#include "mir/client_platform_factory.h"
849+#include "mir/dispatch/dispatchable.h"
850+
851+#include "mir/test/fake_shared.h"
852+#include "mir/test/doubles/stub_client_buffer_factory.h"
853+
854+#include <sys/eventfd.h>
855+
856+#include <gtest/gtest.h>
857+#include <gmock/gmock.h>
858+
859+namespace mcl = mir::client;
860+namespace mclr = mcl::rpc;
861+namespace mp = mir::protobuf;
862+namespace md = mir::dispatch;
863+namespace mt = mir::test;
864+namespace mtd = mt::doubles;
865+
866+using namespace testing;
867+
868+namespace
869+{
870+void assign_result(void* result, void** context)
871+{
872+ if (context)
873+ *context = result;
874+}
875+
876+struct RenderSurfaceCallback
877+{
878+ static void created(MirRenderSurface* render_surface, void *client_context)
879+ {
880+ auto const context = reinterpret_cast<RenderSurfaceCallback*>(client_context);
881+ context->invoked = true;
882+ context->resulting_render_surface = render_surface;
883+ }
884+ bool invoked = false;
885+ MirRenderSurface* resulting_render_surface = nullptr;
886+};
887+
888+struct MockRpcChannel : public mir::client::rpc::MirBasicRpcChannel,
889+ public mir::dispatch::Dispatchable
890+{
891+ MockRpcChannel()
892+ : pollable_fd{eventfd(0, EFD_CLOEXEC)}
893+ {
894+ ON_CALL(*this, watch_fd()).WillByDefault(testing::Return(pollable_fd));
895+ }
896+
897+ virtual void call_method(std::string const& name,
898+ google::protobuf::MessageLite const* /*parameters*/,
899+ google::protobuf::MessageLite* response,
900+ google::protobuf::Closure* complete)
901+ {
902+ if (name == "create_buffer_stream")
903+ {
904+ auto response_message = static_cast<mp::BufferStream*>(response);
905+ on_buffer_stream_create(*response_message, complete);
906+ }
907+
908+ complete->Run();
909+ }
910+
911+ MOCK_METHOD2(on_buffer_stream_create, void(mp::BufferStream&, google::protobuf::Closure* complete));
912+
913+ MOCK_CONST_METHOD0(watch_fd, mir::Fd());
914+ MOCK_METHOD1(dispatch, bool(md::FdEvents));
915+ MOCK_CONST_METHOD0(relevant_events, md::FdEvents());
916+private:
917+ mir::Fd pollable_fd;
918+};
919+
920+struct MockClientPlatform : public mcl::ClientPlatform
921+{
922+ MockClientPlatform()
923+ {
924+ auto native_window = std::make_shared<EGLNativeWindowType>();
925+ *native_window = reinterpret_cast<EGLNativeWindowType>(0x12345678);
926+
927+ ON_CALL(*this, create_buffer_factory())
928+ .WillByDefault(Return(std::make_shared<mtd::StubClientBufferFactory>()));
929+ ON_CALL(*this, create_egl_native_window(_))
930+ .WillByDefault(Return(native_window));
931+ }
932+
933+ void set_client_context(mcl::ClientContext* ctx)
934+ {
935+ client_context = ctx;
936+ }
937+
938+ void populate(MirPlatformPackage& pkg) const override
939+ {
940+ client_context->populate_server_package(pkg);
941+ }
942+
943+ MOCK_CONST_METHOD1(convert_native_buffer, MirNativeBuffer*(mir::graphics::NativeBuffer*));
944+ MOCK_CONST_METHOD0(platform_type, MirPlatformType());
945+ MOCK_METHOD1(platform_operation, MirPlatformMessage*(MirPlatformMessage const*));
946+ MOCK_METHOD0(create_buffer_factory, std::shared_ptr<mcl::ClientBufferFactory>());
947+ MOCK_METHOD2(use_egl_native_window, void(std::shared_ptr<void>, mcl::EGLNativeSurface*));
948+ MOCK_METHOD1(create_egl_native_window, std::shared_ptr<void>(mcl::EGLNativeSurface*));
949+ MOCK_METHOD0(create_egl_native_display, std::shared_ptr<EGLNativeDisplayType>());
950+ MOCK_CONST_METHOD2(get_egl_pixel_format, MirPixelFormat(EGLDisplay, EGLConfig));
951+ MOCK_METHOD2(request_interface, void*(char const*, int));
952+
953+ mcl::ClientContext* client_context = nullptr;
954+};
955+
956+struct StubClientPlatformFactory : public mcl::ClientPlatformFactory
957+{
958+ StubClientPlatformFactory(std::shared_ptr<mcl::ClientPlatform> const& platform)
959+ : platform{platform}
960+ {
961+ }
962+
963+ std::shared_ptr<mcl::ClientPlatform> create_client_platform(mcl::ClientContext*)
964+ {
965+ return platform;
966+ }
967+
968+ std::shared_ptr<mcl::ClientPlatform> platform;
969+};
970+
971+void connected_callback(MirConnection* /*connection*/, void* /*client_context*/)
972+{
973+}
974+
975+class TestConnectionConfiguration : public mcl::DefaultConnectionConfiguration
976+{
977+public:
978+ TestConnectionConfiguration(
979+ std::shared_ptr<mcl::ClientPlatform> const& platform,
980+ std::shared_ptr<mclr::MirBasicRpcChannel> const& channel)
981+ : DefaultConnectionConfiguration(""),
982+ platform{platform},
983+ channel{channel}
984+ {
985+ }
986+
987+ std::shared_ptr<mclr::MirBasicRpcChannel> the_rpc_channel() override
988+ {
989+ return channel;
990+ }
991+
992+ std::shared_ptr<mcl::ClientPlatformFactory> the_client_platform_factory() override
993+ {
994+ return std::make_shared<StubClientPlatformFactory>(platform);
995+ }
996+
997+private:
998+ std::shared_ptr<mcl::ClientPlatform> const platform;
999+ std::shared_ptr<mclr::MirBasicRpcChannel> const channel;
1000+};
1001+}
1002+
1003+struct MirRenderSurfaceTest : public testing::Test
1004+{
1005+ MirRenderSurfaceTest()
1006+ : mock_platform{std::make_shared<testing::NiceMock<MockClientPlatform>>()},
1007+ mock_channel{std::make_shared<testing::NiceMock<MockRpcChannel>>()},
1008+ conf{mock_platform, mock_channel},
1009+ connection{std::make_shared<MirConnection>(conf)}
1010+ {
1011+ mock_platform->set_client_context(connection.get());
1012+ }
1013+
1014+ std::shared_ptr<testing::NiceMock<MockClientPlatform>> const mock_platform;
1015+ std::shared_ptr<testing::NiceMock<MockRpcChannel>> const mock_channel;
1016+ TestConnectionConfiguration conf;
1017+ std::shared_ptr<MirConnection> const connection;
1018+};
1019+
1020+TEST_F(MirRenderSurfaceTest, render_surface_can_be_created_and_released)
1021+{
1022+ EXPECT_CALL(*mock_channel, on_buffer_stream_create(_,_))
1023+ .WillOnce(Invoke([](mp::BufferStream& stream, google::protobuf::Closure*)
1024+ {
1025+ stream.mutable_id()->set_value(1);
1026+ }));
1027+
1028+ connection->connect("MirRenderSurfaceTest", connected_callback, 0)->wait_for_all();
1029+
1030+ void* nw = nullptr;
1031+ MirRenderSurface* render_surface = nullptr;
1032+ connection->create_render_surface_with_content(
1033+ {10, 10},
1034+ reinterpret_cast<mir_render_surface_callback>(assign_result),
1035+ &render_surface,
1036+ &nw);
1037+
1038+ EXPECT_THAT(render_surface, NotNull());
1039+ EXPECT_THAT(nw, NotNull());
1040+ EXPECT_THAT(render_surface, Eq(nw));
1041+ EXPECT_NO_THROW(connection->release_render_surface_with_content(nw));
1042+
1043+ connection->disconnect();
1044+}
1045+
1046+TEST_F(MirRenderSurfaceTest, creation_of_render_surface_creates_egl_native_window)
1047+{
1048+ RenderSurfaceCallback callback;
1049+
1050+ connection->connect("MirRenderSurfaceTest", connected_callback, 0)->wait_for_all();
1051+
1052+ EXPECT_CALL(*mock_platform, create_egl_native_window(nullptr));
1053+ EXPECT_CALL(*mock_channel, on_buffer_stream_create(_,_))
1054+ .WillOnce(Invoke([](mp::BufferStream& stream, google::protobuf::Closure*)
1055+ {
1056+ stream.mutable_id()->set_value(1);
1057+ }));
1058+
1059+ void* nw = nullptr;
1060+ connection->create_render_surface_with_content({10, 10},
1061+ &RenderSurfaceCallback::created,
1062+ &callback,
1063+ &nw);
1064+
1065+ EXPECT_THAT(nw, NotNull());
1066+ EXPECT_TRUE(callback.invoked);
1067+ EXPECT_THAT(callback.resulting_render_surface, NotNull());
1068+
1069+ auto rs = connection->connection_surface_map()->render_surface(
1070+ static_cast<void*>(callback.resulting_render_surface));
1071+
1072+ EXPECT_TRUE(reinterpret_cast<mcl::RenderSurface*>(rs->valid()));
1073+}
1074+
1075+TEST_F(MirRenderSurfaceTest, render_surface_returns_connection)
1076+{
1077+ MirConnection* conn{ reinterpret_cast<MirConnection*>(0x12345678) };
1078+
1079+ mcl::RenderSurface rs(
1080+ conn, nullptr, nullptr, nullptr, {});
1081+
1082+ EXPECT_THAT(rs.connection(), Eq(conn));
1083+}
1084+
1085+TEST_F(MirRenderSurfaceTest, render_surface_has_correct_id_before_content_creation)
1086+{
1087+ MirConnection* conn{ reinterpret_cast<MirConnection*>(0x12345678) };
1088+ auto id = 123;
1089+
1090+ mp::BufferStream protobuf_bs;
1091+ mp::BufferStreamId bs_id;
1092+
1093+ bs_id.set_value(id);
1094+ *protobuf_bs.mutable_id() = bs_id;
1095+
1096+ mcl::RenderSurface rs(
1097+ conn, nullptr, nullptr, mt::fake_shared(protobuf_bs), {});
1098+
1099+ EXPECT_THAT(rs.stream_id().as_value(), Eq(id));
1100+}
1101+
1102+TEST_F(MirRenderSurfaceTest, render_surface_can_create_buffer_stream)
1103+{
1104+ connection->connect("MirRenderSurfaceTest", connected_callback, 0)->wait_for_all();
1105+ auto id = 123;
1106+
1107+ mp::BufferStream protobuf_bs;
1108+ mp::BufferStreamId bs_id;
1109+
1110+ bs_id.set_value(id);
1111+ *protobuf_bs.mutable_id() = bs_id;
1112+
1113+ auto native_window = mock_platform->create_egl_native_window(nullptr);
1114+
1115+ mcl::RenderSurface rs(
1116+ connection.get(), native_window, nullptr, mt::fake_shared(protobuf_bs), {});
1117+
1118+ auto bs = rs.get_buffer_stream(2, 2, mir_pixel_format_abgr_8888,
1119+ mir_buffer_usage_software);
1120+
1121+ EXPECT_THAT(bs, NotNull());
1122+}
1123+
1124+TEST_F(MirRenderSurfaceTest, render_surface_creation_of_buffer_stream_more_than_once_returns_same_object)
1125+{
1126+ connection->connect("MirRenderSurfaceTest", connected_callback, 0)->wait_for_all();
1127+ auto id = 123;
1128+
1129+ mp::BufferStream protobuf_bs;
1130+ mp::BufferStreamId bs_id;
1131+
1132+ bs_id.set_value(id);
1133+ *protobuf_bs.mutable_id() = bs_id;
1134+
1135+ auto native_window = mock_platform->create_egl_native_window(nullptr);
1136+
1137+ mcl::RenderSurface rs(
1138+ connection.get(), native_window, mock_platform, mt::fake_shared(protobuf_bs), {});
1139+
1140+ EXPECT_CALL(*mock_platform, use_egl_native_window(native_window,_));
1141+
1142+ auto bs1 = rs.get_buffer_stream(2, 2, mir_pixel_format_abgr_8888,
1143+ mir_buffer_usage_hardware);
1144+ auto bs2 = rs.get_buffer_stream(2, 2, mir_pixel_format_abgr_8888,
1145+ mir_buffer_usage_hardware);
1146+
1147+ EXPECT_THAT(bs1, NotNull());
1148+ EXPECT_THAT(bs2, NotNull());
1149+ EXPECT_THAT(bs1, Eq(bs2));
1150+}
1151+
1152+TEST_F(MirRenderSurfaceTest, render_surface_creation_of_buffer_stream_with_hardware_usage_installs_new_native_window)
1153+{
1154+ connection->connect("MirRenderSurfaceTest", connected_callback, 0)->wait_for_all();
1155+ auto id = 123;
1156+
1157+ mp::BufferStream protobuf_bs;
1158+ mp::BufferStreamId bs_id;
1159+
1160+ bs_id.set_value(id);
1161+ *protobuf_bs.mutable_id() = bs_id;
1162+
1163+ auto native_window = mock_platform->create_egl_native_window(nullptr);
1164+
1165+ mcl::RenderSurface rs(
1166+ connection.get(), native_window, mock_platform, mt::fake_shared(protobuf_bs), {});
1167+
1168+ EXPECT_CALL(*mock_platform, use_egl_native_window(native_window,_));
1169+
1170+ auto bs = rs.get_buffer_stream(2, 2, mir_pixel_format_abgr_8888,
1171+ mir_buffer_usage_hardware);
1172+
1173+ EXPECT_THAT(bs, NotNull());
1174+}
1175+
1176+TEST_F(MirRenderSurfaceTest, render_surface_creation_of_buffer_stream_with_software_usage_does_not_install_new_native_window)
1177+{
1178+ connection->connect("MirRenderSurfaceTest", connected_callback, 0)->wait_for_all();
1179+ auto id = 123;
1180+
1181+ mp::BufferStream protobuf_bs;
1182+ mp::BufferStreamId bs_id;
1183+
1184+ bs_id.set_value(id);
1185+ *protobuf_bs.mutable_id() = bs_id;
1186+
1187+ auto native_window = mock_platform->create_egl_native_window(nullptr);
1188+
1189+ mcl::RenderSurface rs(
1190+ connection.get(), native_window, mock_platform, mt::fake_shared(protobuf_bs), {});
1191+
1192+ EXPECT_CALL(*mock_platform, use_egl_native_window(_,_)).Times(0);
1193+
1194+ auto bs = rs.get_buffer_stream(2, 2, mir_pixel_format_abgr_8888,
1195+ mir_buffer_usage_software);
1196+
1197+ EXPECT_THAT(bs, NotNull());
1198+}
1199+
1200+TEST_F(MirRenderSurfaceTest, render_surface_object_is_invalid_after_creation_exception)
1201+{
1202+ RenderSurfaceCallback callback;
1203+
1204+ connection->connect("MirRenderSurfaceTest", connected_callback, 0)->wait_for_all();
1205+
1206+ EXPECT_CALL(*mock_channel, on_buffer_stream_create(_,_))
1207+ .WillOnce(DoAll(
1208+ Invoke([](mp::BufferStream&, google::protobuf::Closure* c){ c->Run(); }),
1209+ Throw(std::runtime_error("Eeek!"))));
1210+
1211+ void* nw = nullptr;
1212+ connection->create_render_surface_with_content({10, 10},
1213+ &RenderSurfaceCallback::created,
1214+ &callback,
1215+ &nw);
1216+
1217+ EXPECT_TRUE(callback.invoked);
1218+ EXPECT_THAT(callback.resulting_render_surface, NotNull());
1219+ auto rs = connection->connection_surface_map()->render_surface(
1220+ static_cast<void*>(callback.resulting_render_surface));
1221+ EXPECT_THAT(rs->get_error_message(),
1222+ StrEq("Error processing buffer stream response during render "
1223+ "surface creation: no ID in response (disconnected?)"));
1224+ EXPECT_FALSE(reinterpret_cast<mcl::RenderSurface*>(rs->valid()));
1225+}
1226+
1227+TEST_F(MirRenderSurfaceTest, render_surface_can_create_presentation_chain)
1228+{
1229+ connection->connect("MirRenderSurfaceTest", connected_callback, 0)->wait_for_all();
1230+ auto id = 123;
1231+
1232+ mp::BufferStream protobuf_bs;
1233+ mp::BufferStreamId bs_id;
1234+
1235+ bs_id.set_value(id);
1236+ *protobuf_bs.mutable_id() = bs_id;
1237+
1238+ auto native_window = mock_platform->create_egl_native_window(nullptr);
1239+
1240+ mcl::RenderSurface rs(
1241+ connection.get(), native_window, nullptr, mt::fake_shared(protobuf_bs), {});
1242+
1243+ auto pc = rs.get_presentation_chain();
1244+
1245+ EXPECT_THAT(pc, NotNull());
1246+}
1247+
1248+TEST_F(MirRenderSurfaceTest, render_surface_creation_of_presentation_chain_more_than_once_returns_same_object)
1249+{
1250+ connection->connect("MirRenderSurfaceTest", connected_callback, 0)->wait_for_all();
1251+ auto id = 123;
1252+
1253+ mp::BufferStream protobuf_bs;
1254+ mp::BufferStreamId bs_id;
1255+
1256+ bs_id.set_value(id);
1257+ *protobuf_bs.mutable_id() = bs_id;
1258+
1259+ auto native_window = mock_platform->create_egl_native_window(nullptr);
1260+
1261+ mcl::RenderSurface rs(
1262+ connection.get(), native_window, mock_platform, mt::fake_shared(protobuf_bs), {});
1263+
1264+ auto pc1 = rs.get_presentation_chain();
1265+ auto pc2 = rs.get_presentation_chain();
1266+
1267+ EXPECT_THAT(pc1, NotNull());
1268+ EXPECT_THAT(pc2, NotNull());
1269+ EXPECT_THAT(pc1, Eq(pc2));
1270+}
1271+
1272+TEST_F(MirRenderSurfaceTest, can_create_chain_or_stream_but_not_both)
1273+{
1274+ connection->connect("MirRenderSurfaceTest", connected_callback, 0)->wait_for_all();
1275+ auto id = 123;
1276+
1277+ mp::BufferStream protobuf_bs;
1278+ mp::BufferStreamId bs_id;
1279+
1280+ bs_id.set_value(id);
1281+ *protobuf_bs.mutable_id() = bs_id;
1282+
1283+ auto native_window = mock_platform->create_egl_native_window(nullptr);
1284+
1285+ {
1286+ mcl::RenderSurface rs(connection.get(),
1287+ native_window,
1288+ mock_platform,
1289+ mt::fake_shared(protobuf_bs),
1290+ {});
1291+
1292+ auto bs = rs.get_buffer_stream(2, 2, mir_pixel_format_abgr_8888,
1293+ mir_buffer_usage_hardware);
1294+
1295+ EXPECT_THAT(bs, NotNull());
1296+ EXPECT_THROW(
1297+ { rs.get_presentation_chain(); },
1298+ std::logic_error);
1299+ }
1300+
1301+ {
1302+ mcl::RenderSurface rs(connection.get(),
1303+ native_window,
1304+ mock_platform,
1305+ mt::fake_shared(protobuf_bs),
1306+ {});
1307+
1308+ auto pc = rs.get_presentation_chain();
1309+
1310+ EXPECT_THAT(pc, NotNull());
1311+ EXPECT_THROW(
1312+ { rs.get_buffer_stream(2, 2,
1313+ mir_pixel_format_abgr_8888,
1314+ mir_buffer_usage_hardware); },
1315+ std::logic_error);
1316+ }
1317+}

Subscribers

People subscribed via source and target branches