Mir

Merge lp:~kdub/mir/interval0-signal into lp:~mir-team/mir/trunk

Proposed by Kevin DuBois
Status: Superseded
Proposed branch: lp:~kdub/mir/interval0-signal
Merge into: lp:~mir-team/mir/trunk
Diff against target: 1401 lines (+687/-108)
43 files modified
include/client/mir_toolkit/mir_client_library.h (+18/-0)
include/server/mir/compositor/buffer_allocation_strategy.h (+1/-1)
include/server/mir/compositor/buffer_stream_surfaces.h (+1/-0)
include/server/mir/compositor/swapper_factory.h (+6/-2)
include/server/mir/graphics/gl_renderer.h (+0/-1)
include/server/mir/graphics/renderer.h (+0/-1)
include/server/mir/shell/surface.h (+1/-0)
include/server/mir/surfaces/buffer_stream.h (+1/-0)
include/server/mir/surfaces/surface.h (+2/-0)
include/shared/mir/graphics/android/mir_native_buffer.h (+59/-0)
include/shared/mir_toolkit/common.h (+7/-0)
include/test/mir_test_doubles/mock_buffer_stream.h (+2/-0)
include/test/mir_test_doubles/mock_surface_renderer.h (+1/-2)
include/test/mir_test_doubles/mock_swapper_factory.h (+2/-2)
include/test/mir_test_doubles/null_buffer_stream.h (+4/-0)
src/client/android/android_client_buffer.cpp (+29/-11)
src/client/mir_client_library.cpp (+32/-0)
src/client/mir_surface.cpp (+2/-0)
src/server/compositor/buffer_stream_surfaces.cpp (+4/-0)
src/server/compositor/rendering_operator.cpp (+0/-1)
src/server/compositor/swapper_factory.cpp (+35/-9)
src/server/compositor/switching_bundle.cpp (+2/-2)
src/server/graphics/android/android_alloc_adaptor.cpp (+8/-19)
src/server/graphics/gl_renderer.cpp (+0/-8)
src/server/shell/surface.cpp (+14/-1)
src/server/surfaces/surface.cpp (+5/-0)
src/shared/graphics/android/CMakeLists.txt (+1/-0)
src/shared/graphics/android/mir_native_buffer.cpp (+73/-0)
tests/acceptance-tests/test_server_shutdown.cpp (+0/-3)
tests/integration-tests/CMakeLists.txt (+1/-0)
tests/integration-tests/test_surface_first_frame_sync.cpp (+0/-2)
tests/integration-tests/test_swapinterval.cpp (+226/-0)
tests/mir_test_framework/testing_server_options.cpp (+0/-4)
tests/unit-tests/client/android/test_client_android_buffer.cpp (+2/-2)
tests/unit-tests/compositor/test_buffer_stream.cpp (+9/-0)
tests/unit-tests/compositor/test_rendering_operator.cpp (+0/-12)
tests/unit-tests/compositor/test_swapper_factory.cpp (+50/-2)
tests/unit-tests/compositor/test_switching_bundle.cpp (+3/-3)
tests/unit-tests/graphics/android/CMakeLists.txt (+1/-0)
tests/unit-tests/graphics/android/test_android_alloc_adaptor.cpp (+3/-10)
tests/unit-tests/graphics/android/test_external_refcount.cpp (+70/-0)
tests/unit-tests/graphics/test_gl_renderer.cpp (+0/-10)
tests/unit-tests/surfaces/test_surface.cpp (+12/-0)
To merge this branch: bzr merge lp:~kdub/mir/interval0-signal
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Mir development team Pending
Review via email: mp+169941@code.launchpad.net

This proposal has been superseded by a proposal from 2013-06-19.

Commit message

Activate sending a "swapinterval" signal over IPC. Add client api for software clients to request different swapintervals. (eglSwapInterval is not glued together just yet). Currently only swapinterval of 0 or 1 is supported.

Description of the change

Activate sending a "swapinterval" signal over IPC. Add client api for software clients to request different swapintervals. (eglSwapInterval is not glued together just yet)
Currently only swapinterval of 0 or 1 is supported.

note that the actual path taken over ipc is via the surface parameters, there is no new protobuf message introduced to support the message.

tests/integration-tests/test_swapinterval.cpp tests from the client's request until the point that the request hits the compositor systems at mc::BufferStream

still in pre-review, dependent on anativewindow-external-refcount

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'include/client/mir_toolkit/mir_client_library.h'
--- include/client/mir_toolkit/mir_client_library.h 2013-06-06 08:36:17 +0000
+++ include/client/mir_toolkit/mir_client_library.h 2013-06-19 18:36:29 +0000
@@ -293,6 +293,24 @@
293 */293 */
294MirSurfaceState mir_surface_get_state(MirSurface *surface);294MirSurfaceState mir_surface_get_state(MirSurface *surface);
295295
296/**
297 * Set the swapinterval for mir_surface_swap_buffers. EGL users should use
298 * eglSwapInterval directly.
299 * \param [in] surface The surface to operate on
300 * \param [in] interval The number of vblank signals that
301 * mir_surface_swap_buffers will wait for
302 * \return A wait handle that can be passed to mir_wait_for
303 */
304MirWaitHandle* mir_surface_set_swapinterval(MirSurface* surface, int interval);
305
306/**
307 * Query the swapinterval that the surface is operating with.
308 * The default interval is 1.
309 * \param [in] surface The surface to operate on
310 * \return The swapinterval value that the client is operating with
311 */
312int mir_surface_get_swapinterval(MirSurface* surface);
313
296#ifdef __cplusplus314#ifdef __cplusplus
297}315}
298/**@}*/316/**@}*/
299317
=== modified file 'include/server/mir/compositor/buffer_allocation_strategy.h'
--- include/server/mir/compositor/buffer_allocation_strategy.h 2013-06-11 14:27:33 +0000
+++ include/server/mir/compositor/buffer_allocation_strategy.h 2013-06-19 18:36:29 +0000
@@ -45,7 +45,7 @@
45class BufferAllocationStrategy45class BufferAllocationStrategy
46{46{
47public:47public:
48 virtual std::shared_ptr<BufferSwapper> create_swapper_reuse_buffers(48 virtual std::shared_ptr<BufferSwapper> create_swapper_reuse_buffers(BufferProperties const&,
49 std::vector<std::shared_ptr<Buffer>>&, size_t, SwapperType) const = 0;49 std::vector<std::shared_ptr<Buffer>>&, size_t, SwapperType) const = 0;
50 virtual std::shared_ptr<BufferSwapper> create_swapper_new_buffers(50 virtual std::shared_ptr<BufferSwapper> create_swapper_new_buffers(
51 BufferProperties& actual_properties, BufferProperties const& requested_properties, SwapperType) const = 0;51 BufferProperties& actual_properties, BufferProperties const& requested_properties, SwapperType) const = 0;
5252
=== modified file 'include/server/mir/compositor/buffer_stream_surfaces.h'
--- include/server/mir/compositor/buffer_stream_surfaces.h 2013-06-18 09:44:11 +0000
+++ include/server/mir/compositor/buffer_stream_surfaces.h 2013-06-19 18:36:29 +0000
@@ -47,6 +47,7 @@
4747
48 geometry::PixelFormat get_stream_pixel_format();48 geometry::PixelFormat get_stream_pixel_format();
49 geometry::Size stream_size();49 geometry::Size stream_size();
50 void allow_framedropping(bool);
50 void force_requests_to_complete();51 void force_requests_to_complete();
5152
52protected:53protected:
5354
=== modified file 'include/server/mir/compositor/swapper_factory.h'
--- include/server/mir/compositor/swapper_factory.h 2013-06-11 15:05:27 +0000
+++ include/server/mir/compositor/swapper_factory.h 2013-06-19 18:36:29 +0000
@@ -38,14 +38,18 @@
38 std::shared_ptr<GraphicBufferAllocator> const& gr_alloc,38 std::shared_ptr<GraphicBufferAllocator> const& gr_alloc,
39 int number_of_buffers);39 int number_of_buffers);
4040
41 std::shared_ptr<BufferSwapper> create_swapper_reuse_buffers(41 std::shared_ptr<BufferSwapper> create_swapper_reuse_buffers(BufferProperties const&,
42 std::vector<std::shared_ptr<Buffer>>&, size_t, SwapperType) const;42 std::vector<std::shared_ptr<Buffer>>&, size_t, SwapperType) const;
43 std::shared_ptr<BufferSwapper> create_swapper_new_buffers(43 std::shared_ptr<BufferSwapper> create_swapper_new_buffers(
44 BufferProperties& actual_properties, BufferProperties const& requested_properties, SwapperType) const;44 BufferProperties& actual_properties, BufferProperties const& requested_properties, SwapperType) const;
4545
46private:46private:
47 void change_swapper_size(
48 std::vector<std::shared_ptr<Buffer>>&, size_t const, size_t, BufferProperties const&) const;
49
47 std::shared_ptr<GraphicBufferAllocator> const gr_allocator;50 std::shared_ptr<GraphicBufferAllocator> const gr_allocator;
48 int const number_of_buffers;51 unsigned int const synchronous_number_of_buffers;
52 unsigned int const spin_number_of_buffers;
49};53};
50}54}
51}55}
5256
=== modified file 'include/server/mir/graphics/gl_renderer.h'
--- include/server/mir/graphics/gl_renderer.h 2013-05-21 15:11:41 +0000
+++ include/server/mir/graphics/gl_renderer.h 2013-06-19 18:36:29 +0000
@@ -37,7 +37,6 @@
3737
38 /* From renderer */38 /* From renderer */
39 void render(std::function<void(std::shared_ptr<void> const&)> save_resource, Renderable& renderable);39 void render(std::function<void(std::shared_ptr<void> const&)> save_resource, Renderable& renderable);
40 void ensure_no_live_buffers_bound();
41 void clear();40 void clear();
4241
43 ~GLRenderer() noexcept {}42 ~GLRenderer() noexcept {}
4443
=== modified file 'include/server/mir/graphics/renderer.h'
--- include/server/mir/graphics/renderer.h 2013-05-21 15:11:41 +0000
+++ include/server/mir/graphics/renderer.h 2013-06-19 18:36:29 +0000
@@ -36,7 +36,6 @@
3636
37 virtual void clear() = 0;37 virtual void clear() = 0;
38 virtual void render(std::function<void(std::shared_ptr<void> const&)> save_resource, Renderable& renderable) = 0;38 virtual void render(std::function<void(std::shared_ptr<void> const&)> save_resource, Renderable& renderable) = 0;
39 virtual void ensure_no_live_buffers_bound() = 0;
4039
41protected:40protected:
42 Renderer() = default;41 Renderer() = default;
4342
=== modified file 'include/server/mir/shell/surface.h'
--- include/server/mir/shell/surface.h 2013-06-17 19:47:07 +0000
+++ include/server/mir/shell/surface.h 2013-06-19 18:36:29 +0000
@@ -87,6 +87,7 @@
8787
88 virtual void take_input_focus(std::shared_ptr<InputTargeter> const& targeter);88 virtual void take_input_focus(std::shared_ptr<InputTargeter> const& targeter);
8989
90 virtual void allow_framedropping(bool);
90private:91private:
91 bool set_type(MirSurfaceType t); // Use configure() to make public changes92 bool set_type(MirSurfaceType t); // Use configure() to make public changes
92 bool set_state(MirSurfaceState s);93 bool set_state(MirSurfaceState s);
9394
=== modified file 'include/server/mir/surfaces/buffer_stream.h'
--- include/server/mir/surfaces/buffer_stream.h 2013-06-13 10:40:42 +0000
+++ include/server/mir/surfaces/buffer_stream.h 2013-06-19 18:36:29 +0000
@@ -44,6 +44,7 @@
44 virtual std::shared_ptr<surfaces::GraphicRegion> lock_back_buffer() = 0;44 virtual std::shared_ptr<surfaces::GraphicRegion> lock_back_buffer() = 0;
45 virtual geometry::PixelFormat get_stream_pixel_format() = 0;45 virtual geometry::PixelFormat get_stream_pixel_format() = 0;
46 virtual geometry::Size stream_size() = 0;46 virtual geometry::Size stream_size() = 0;
47 virtual void allow_framedropping(bool) = 0;
47 virtual void force_requests_to_complete() = 0;48 virtual void force_requests_to_complete() = 0;
48};49};
4950
5051
=== modified file 'include/server/mir/surfaces/surface.h'
--- include/server/mir/surfaces/surface.h 2013-06-12 15:36:31 +0000
+++ include/server/mir/surfaces/surface.h 2013-06-19 18:36:29 +0000
@@ -83,6 +83,8 @@
83 bool supports_input() const;83 bool supports_input() const;
84 int client_input_fd() const;84 int client_input_fd() const;
85 int server_input_fd() const;85 int server_input_fd() const;
86
87 void allow_framedropping(bool);
86private:88private:
87 std::string surface_name;89 std::string surface_name;
88 geometry::Point top_left_point;90 geometry::Point top_left_point;
8991
=== added file 'include/shared/mir/graphics/android/mir_native_buffer.h'
--- include/shared/mir/graphics/android/mir_native_buffer.h 1970-01-01 00:00:00 +0000
+++ include/shared/mir/graphics/android/mir_native_buffer.h 2013-06-19 18:36:29 +0000
@@ -0,0 +1,59 @@
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
17 */
18
19#ifndef MIR_GRAPHICS_ANDROID_MIR_NATIVE_BUFFER_H_
20#define MIR_GRAPHICS_ANDROID_MIR_NATIVE_BUFFER_H_
21
22#include <system/window.h>
23#include <functional>
24#include <atomic>
25
26namespace mir
27{
28namespace graphics
29{
30namespace android
31{
32struct MirNativeBuffer : public ANativeWindowBuffer
33{
34 MirNativeBuffer(std::function<void(MirNativeBuffer*)> free);
35 void driver_reference();
36 void driver_dereference();
37 void mir_dereference();
38
39private:
40 ~MirNativeBuffer();
41
42 std::function<void(MirNativeBuffer*)> free_fn;
43 std::atomic<bool> mir_reference;
44 std::atomic<int> driver_references;
45
46};
47
48struct MirNativeBufferDeleter
49{
50 void operator()(MirNativeBuffer* a)
51 {
52 a->mir_dereference();
53 }
54};
55}
56}
57}
58
59#endif /* MIR_GRAPHICS_ANDROID_MIR_NATIVE_BUFFER_H_ */
060
=== modified file 'include/shared/mir_toolkit/common.h'
--- include/shared/mir_toolkit/common.h 2013-05-03 22:53:42 +0000
+++ include/shared/mir_toolkit/common.h 2013-06-19 18:36:29 +0000
@@ -35,6 +35,7 @@
35{35{
36 mir_surface_attrib_type,36 mir_surface_attrib_type,
37 mir_surface_attrib_state,37 mir_surface_attrib_state,
38 mir_surface_attrib_performance_hint,
38 mir_surface_attrib_arraysize_39 mir_surface_attrib_arraysize_
39} MirSurfaceAttrib;40} MirSurfaceAttrib;
4041
@@ -63,6 +64,12 @@
63 mir_surface_state_arraysize_64 mir_surface_state_arraysize_
64} MirSurfaceState;65} MirSurfaceState;
6566
67typedef enum MirSurfacePerformanceHint
68{
69 mir_surface_hint_synchronous,
70 mir_surface_hint_drop_frames,
71 mir_surface_hint_arraysize_
72} MirSurfacePerformanceHint;
66/**@}*/73/**@}*/
6774
68#endif75#endif
6976
=== modified file 'include/test/mir_test_doubles/mock_buffer_stream.h'
--- include/test/mir_test_doubles/mock_buffer_stream.h 2013-06-13 10:40:42 +0000
+++ include/test/mir_test_doubles/mock_buffer_stream.h 2013-06-19 18:36:29 +0000
@@ -36,6 +36,8 @@
3636
37 MOCK_METHOD0(get_stream_pixel_format, geometry::PixelFormat());37 MOCK_METHOD0(get_stream_pixel_format, geometry::PixelFormat());
38 MOCK_METHOD0(stream_size, geometry::Size());38 MOCK_METHOD0(stream_size, geometry::Size());
39 MOCK_METHOD0(force_client_completion, void());
40 MOCK_METHOD1(allow_framedropping, void(bool));
39 MOCK_METHOD0(force_requests_to_complete, void());41 MOCK_METHOD0(force_requests_to_complete, void());
40};42};
41}43}
4244
=== modified file 'include/test/mir_test_doubles/mock_surface_renderer.h'
--- include/test/mir_test_doubles/mock_surface_renderer.h 2013-05-21 15:11:41 +0000
+++ include/test/mir_test_doubles/mock_surface_renderer.h 2013-06-19 18:36:29 +0000
@@ -32,8 +32,7 @@
32struct MockSurfaceRenderer : public graphics::Renderer32struct MockSurfaceRenderer : public graphics::Renderer
33{33{
34 MOCK_METHOD2(render, void(std::function<void(std::shared_ptr<void> const&)>, graphics::Renderable&));34 MOCK_METHOD2(render, void(std::function<void(std::shared_ptr<void> const&)>, graphics::Renderable&));
35 MOCK_METHOD0(ensure_no_live_buffers_bound, void());35 MOCK_METHOD0(clear, void());
36 MOCK_METHOD0(clear, void ());
3736
38 ~MockSurfaceRenderer() noexcept {}37 ~MockSurfaceRenderer() noexcept {}
39};38};
4039
=== modified file 'include/test/mir_test_doubles/mock_swapper_factory.h'
--- include/test/mir_test_doubles/mock_swapper_factory.h 2013-06-11 14:27:33 +0000
+++ include/test/mir_test_doubles/mock_swapper_factory.h 2013-06-19 18:36:29 +0000
@@ -33,8 +33,8 @@
33public:33public:
34 ~MockSwapperFactory() noexcept {}34 ~MockSwapperFactory() noexcept {}
3535
36 MOCK_CONST_METHOD3(create_swapper_reuse_buffers,36 MOCK_CONST_METHOD4(create_swapper_reuse_buffers,
37 std::shared_ptr<compositor::BufferSwapper>(37 std::shared_ptr<compositor::BufferSwapper>(compositor::BufferProperties const&,
38 std::vector<std::shared_ptr<compositor::Buffer>>&, size_t, compositor::SwapperType));38 std::vector<std::shared_ptr<compositor::Buffer>>&, size_t, compositor::SwapperType));
39 MOCK_CONST_METHOD3(create_swapper_new_buffers,39 MOCK_CONST_METHOD3(create_swapper_new_buffers,
40 std::shared_ptr<compositor::BufferSwapper>(40 std::shared_ptr<compositor::BufferSwapper>(
4141
=== modified file 'include/test/mir_test_doubles/null_buffer_stream.h'
--- include/test/mir_test_doubles/null_buffer_stream.h 2013-06-13 10:40:42 +0000
+++ include/test/mir_test_doubles/null_buffer_stream.h 2013-06-19 18:36:29 +0000
@@ -60,6 +60,10 @@
60 {60 {
61 }61 }
6262
63 void allow_framedropping(bool)
64 {
65 }
66
63 std::shared_ptr<compositor::Buffer> stub_buffer;67 std::shared_ptr<compositor::Buffer> stub_buffer;
64};68};
6569
6670
=== modified file 'src/client/android/android_client_buffer.cpp'
--- src/client/android/android_client_buffer.cpp 2013-06-12 09:36:20 +0000
+++ src/client/android/android_client_buffer.cpp 2013-06-19 18:36:29 +0000
@@ -16,6 +16,7 @@
16 * Authored by: Kevin DuBois<kevin.dubois@canonical.com>16 * Authored by: Kevin DuBois<kevin.dubois@canonical.com>
17 */17 */
1818
19#include "mir/graphics/android/mir_native_buffer.h"
19#include "mir_toolkit/mir_client_library.h"20#include "mir_toolkit/mir_client_library.h"
20#include "android_client_buffer.h"21#include "android_client_buffer.h"
2122
@@ -23,6 +24,23 @@
23namespace mcl=mir::client;24namespace mcl=mir::client;
24namespace mcla=mir::client::android;25namespace mcla=mir::client::android;
25namespace geom=mir::geometry;26namespace geom=mir::geometry;
27namespace mga=mir::graphics::android;
28namespace
29{
30struct AndroidBufferHandleDeleter
31{
32 AndroidBufferHandleDeleter(std::shared_ptr<mcla::AndroidRegistrar> const& alloc_dev)
33 : buffer_registrar(alloc_dev)
34 {}
35
36 void operator()(mga::MirNativeBuffer* t)
37 {
38 buffer_registrar->unregister_buffer(t->handle);
39 }
40private:
41 std::shared_ptr<mcla::AndroidRegistrar> const buffer_registrar;
42};
43}
2644
27mcla::AndroidClientBuffer::AndroidClientBuffer(std::shared_ptr<AndroidRegistrar> const& registrar,45mcla::AndroidClientBuffer::AndroidClientBuffer(std::shared_ptr<AndroidRegistrar> const& registrar,
28 std::shared_ptr<MirBufferPackage> const& package,46 std::shared_ptr<MirBufferPackage> const& package,
@@ -30,20 +48,24 @@
30 : creation_package(package),48 : creation_package(package),
31 buffer_registrar(registrar),49 buffer_registrar(registrar),
32 rect({{geom::X(0),geom::Y(0)}, size}),50 rect({{geom::X(0),geom::Y(0)}, size}),
33 buffer_pf(pf),51 buffer_pf(pf)
34 native_window_buffer(std::make_shared<ANativeWindowBuffer>())
35{52{
36 creation_package = std::move(package);53 AndroidBufferHandleDeleter del1(registrar);
54 auto tmp = new mga::MirNativeBuffer(del1);
55 mga::MirNativeBufferDeleter del;
56 native_window_buffer = std::shared_ptr<mga::MirNativeBuffer>(tmp, del);
37 native_handle = std::shared_ptr<const native_handle_t> (convert_to_native_handle(creation_package));57 native_handle = std::shared_ptr<const native_handle_t> (convert_to_native_handle(creation_package));
3858
39 buffer_registrar->register_buffer(native_handle.get());59 try{
60 buffer_registrar->register_buffer(native_handle.get());
61 } catch (...)
62 {
63 //TODO: log failure
64 }
4065
41 pack_native_window_buffer();66 pack_native_window_buffer();
42}67}
4368
44static void incRef(android_native_base_t*)
45{
46}
47void mcla::AndroidClientBuffer::pack_native_window_buffer()69void mcla::AndroidClientBuffer::pack_native_window_buffer()
48{70{
49 native_window_buffer->height = static_cast<int32_t>(rect.size.height.as_uint32_t());71 native_window_buffer->height = static_cast<int32_t>(rect.size.height.as_uint32_t());
@@ -51,15 +73,11 @@
51 native_window_buffer->stride = creation_package->stride /73 native_window_buffer->stride = creation_package->stride /
52 geom::bytes_per_pixel(buffer_pf);74 geom::bytes_per_pixel(buffer_pf);
53 native_window_buffer->usage = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER;75 native_window_buffer->usage = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER;
54
55 native_window_buffer->handle = native_handle.get();76 native_window_buffer->handle = native_handle.get();
56 native_window_buffer->common.incRef = &incRef;
57 native_window_buffer->common.decRef = &incRef;
58}77}
5978
60mcla::AndroidClientBuffer::~AndroidClientBuffer() noexcept79mcla::AndroidClientBuffer::~AndroidClientBuffer() noexcept
61{80{
62 buffer_registrar->unregister_buffer(native_handle.get());
63}81}
6482
65const native_handle_t* mcla::AndroidClientBuffer::convert_to_native_handle(const std::shared_ptr<MirBufferPackage>& package)83const native_handle_t* mcla::AndroidClientBuffer::convert_to_native_handle(const std::shared_ptr<MirBufferPackage>& package)
6684
=== modified file 'src/client/mir_client_library.cpp'
--- src/client/mir_client_library.cpp 2013-06-06 08:36:17 +0000
+++ src/client/mir_client_library.cpp 2013-06-19 18:36:29 +0000
@@ -316,3 +316,35 @@
316316
317 return state;317 return state;
318}318}
319
320MirWaitHandle* mir_surface_set_swapinterval(MirSurface* surf, int interval)
321{
322 int hint = mir_surface_hint_synchronous;
323 switch (interval)
324 {
325 case 0:
326 hint = mir_surface_hint_drop_frames;
327 break;
328 case 1:
329 hint = mir_surface_hint_synchronous;
330 break;
331 default:
332 return NULL;
333 }
334
335 return surf ? surf->configure(mir_surface_attrib_performance_hint, hint) : NULL;
336}
337
338int mir_surface_get_swapinterval(MirSurface* surf)
339{
340 if (!surf)
341 return -1;
342
343 int s = surf->attrib(mir_surface_attrib_performance_hint);
344 if (s == mir_surface_hint_synchronous)
345 return 1;
346 if (s == mir_surface_hint_drop_frames)
347 return 0;
348
349 return -1;
350}
319351
=== modified file 'src/client/mir_surface.cpp'
--- src/client/mir_surface.cpp 2013-06-07 10:38:34 +0000
+++ src/client/mir_surface.cpp 2013-06-19 18:36:29 +0000
@@ -58,6 +58,7 @@
58 attrib_cache[i] = -1;58 attrib_cache[i] = -1;
59 attrib_cache[mir_surface_attrib_type] = mir_surface_type_normal;59 attrib_cache[mir_surface_attrib_type] = mir_surface_type_normal;
60 attrib_cache[mir_surface_attrib_state] = mir_surface_state_unknown;60 attrib_cache[mir_surface_attrib_state] = mir_surface_state_unknown;
61 attrib_cache[mir_surface_attrib_performance_hint] = mir_surface_hint_synchronous;
61}62}
6263
63MirSurface::~MirSurface()64MirSurface::~MirSurface()
@@ -269,6 +270,7 @@
269 {270 {
270 case mir_surface_attrib_type:271 case mir_surface_attrib_type:
271 case mir_surface_attrib_state:272 case mir_surface_attrib_state:
273 case mir_surface_attrib_performance_hint:
272 if (configure_result.has_ivalue())274 if (configure_result.has_ivalue())
273 attrib_cache[a] = configure_result.ivalue();275 attrib_cache[a] = configure_result.ivalue();
274 else276 else
275277
=== modified file 'src/server/compositor/buffer_stream_surfaces.cpp'
--- src/server/compositor/buffer_stream_surfaces.cpp 2013-06-18 09:44:11 +0000
+++ src/server/compositor/buffer_stream_surfaces.cpp 2013-06-19 18:36:29 +0000
@@ -64,3 +64,7 @@
64 buffer_bundle->force_requests_to_complete();64 buffer_bundle->force_requests_to_complete();
65}65}
6666
67void mc::BufferStreamSurfaces::allow_framedropping(bool allow)
68{
69 buffer_bundle->allow_framedropping(allow);
70}
6771
=== modified file 'src/server/compositor/rendering_operator.cpp'
--- src/server/compositor/rendering_operator.cpp 2013-05-22 09:56:40 +0000
+++ src/server/compositor/rendering_operator.cpp 2013-06-19 18:36:29 +0000
@@ -30,7 +30,6 @@
3030
31mc::RenderingOperator::~RenderingOperator()31mc::RenderingOperator::~RenderingOperator()
32{32{
33 renderer.ensure_no_live_buffers_bound();
34}33}
3534
36void mc::RenderingOperator::operator()(graphics::Renderable& renderable)35void mc::RenderingOperator::operator()(graphics::Renderable& renderable)
3736
=== modified file 'src/server/compositor/swapper_factory.cpp'
--- src/server/compositor/swapper_factory.cpp 2013-06-11 19:55:10 +0000
+++ src/server/compositor/swapper_factory.cpp 2013-06-19 18:36:29 +0000
@@ -36,7 +36,8 @@
36 std::shared_ptr<GraphicBufferAllocator> const& gr_alloc,36 std::shared_ptr<GraphicBufferAllocator> const& gr_alloc,
37 int number_of_buffers)37 int number_of_buffers)
38 : gr_allocator(gr_alloc),38 : gr_allocator(gr_alloc),
39 number_of_buffers(number_of_buffers)39 synchronous_number_of_buffers(number_of_buffers),
40 spin_number_of_buffers(3) //spin algorithm always takes 3 buffers
40{41{
41}42}
4243
@@ -46,16 +47,42 @@
46{47{
47}48}
4849
50void mc::SwapperFactory::change_swapper_size(
51 std::vector<std::shared_ptr<mc::Buffer>>& list,
52 size_t const desired_size, size_t current_size, BufferProperties const& buffer_properties) const
53{
54 while (current_size < desired_size)
55 {
56 list.push_back(gr_allocator->alloc_buffer(buffer_properties));
57 current_size++;
58 }
59
60 while (current_size > desired_size)
61 {
62 if (list.empty())
63 {
64 BOOST_THROW_EXCEPTION(std::logic_error("SwapperFactory could not change algorithm"));
65 } else
66 {
67 list.pop_back();
68 current_size--;
69 }
70 }
71}
72
49std::shared_ptr<mc::BufferSwapper> mc::SwapperFactory::create_swapper_reuse_buffers(73std::shared_ptr<mc::BufferSwapper> mc::SwapperFactory::create_swapper_reuse_buffers(
50 std::vector<std::shared_ptr<Buffer>>& list, size_t buffer_num, SwapperType type) const74 BufferProperties const& buffer_properties, std::vector<std::shared_ptr<Buffer>>& list,
75 size_t buffer_num, SwapperType type) const
51{76{
52 if (type == mc::SwapperType::synchronous)77 if (type == mc::SwapperType::synchronous)
53 {78 {
54 return std::make_shared<mc::BufferSwapperMulti>(list, buffer_num); 79 change_swapper_size(list, synchronous_number_of_buffers, buffer_num, buffer_properties);
80 return std::make_shared<mc::BufferSwapperMulti>(list, synchronous_number_of_buffers);
55 }81 }
56 else82 else
57 {83 {
58 return std::make_shared<mc::BufferSwapperSpin>(list, buffer_num);84 change_swapper_size(list, spin_number_of_buffers, buffer_num, buffer_properties);
85 return std::make_shared<mc::BufferSwapperSpin>(list, spin_number_of_buffers);
59 }86 }
60}87}
6188
@@ -68,20 +95,19 @@
6895
69 if (type == mc::SwapperType::synchronous)96 if (type == mc::SwapperType::synchronous)
70 {97 {
71 for(auto i=0; i< number_of_buffers; i++)98 for(auto i=0u; i< synchronous_number_of_buffers; i++)
72 {99 {
73 list.push_back(gr_allocator->alloc_buffer(requested_buffer_properties));100 list.push_back(gr_allocator->alloc_buffer(requested_buffer_properties));
74 }101 }
75 new_swapper = std::make_shared<mc::BufferSwapperMulti>(list, number_of_buffers);102 new_swapper = std::make_shared<mc::BufferSwapperMulti>(list, synchronous_number_of_buffers);
76 }103 }
77 else104 else
78 {105 {
79 int const async_buffer_count = 3; //async only can accept 3 buffers, so ignore constructor request106 for(auto i=0u; i < spin_number_of_buffers; i++)
80 for(auto i=0; i < async_buffer_count; i++)
81 {107 {
82 list.push_back(gr_allocator->alloc_buffer(requested_buffer_properties));108 list.push_back(gr_allocator->alloc_buffer(requested_buffer_properties));
83 }109 }
84 new_swapper = std::make_shared<mc::BufferSwapperSpin>(list, async_buffer_count);110 new_swapper = std::make_shared<mc::BufferSwapperSpin>(list, spin_number_of_buffers);
85 }111 }
86112
87 actual_buffer_properties = BufferProperties{113 actual_buffer_properties = BufferProperties{
88114
=== modified file 'src/server/compositor/switching_bundle.cpp'
--- src/server/compositor/switching_bundle.cpp 2013-06-15 11:09:16 +0000
+++ src/server/compositor/switching_bundle.cpp 2013-06-19 18:36:29 +0000
@@ -92,9 +92,9 @@
92 swapper->end_responsibility(list, size);92 swapper->end_responsibility(list, size);
9393
94 if (allow_dropping)94 if (allow_dropping)
95 swapper = swapper_factory->create_swapper_reuse_buffers(list, size, mc::SwapperType::framedropping); 95 swapper = swapper_factory->create_swapper_reuse_buffers(bundle_properties, list, size, mc::SwapperType::framedropping);
96 else96 else
97 swapper = swapper_factory->create_swapper_reuse_buffers(list, size, mc::SwapperType::synchronous); 97 swapper = swapper_factory->create_swapper_reuse_buffers(bundle_properties, list, size, mc::SwapperType::synchronous);
9898
99 cv.notify_all();99 cv.notify_all();
100}100}
101101
=== modified file 'src/server/graphics/android/android_alloc_adaptor.cpp'
--- src/server/graphics/android/android_alloc_adaptor.cpp 2013-05-22 15:33:21 +0000
+++ src/server/graphics/android/android_alloc_adaptor.cpp 2013-06-19 18:36:29 +0000
@@ -17,6 +17,7 @@
17 * Kevin DuBois <kevin.dubois@canonical.com>17 * Kevin DuBois <kevin.dubois@canonical.com>
18 */18 */
1919
20#include "mir/graphics/android/mir_native_buffer.h"
20#include "android_alloc_adaptor.h"21#include "android_alloc_adaptor.h"
21#include "android_format_conversion-inl.h"22#include "android_format_conversion-inl.h"
2223
@@ -35,18 +36,13 @@
35 : alloc_device(alloc_dev)36 : alloc_device(alloc_dev)
36 {}37 {}
3738
38 void operator()(ANativeWindowBuffer* t)39 void operator()(mga::MirNativeBuffer* t)
39 {40 {
40 alloc_device->free(alloc_device.get(), t->handle);41 alloc_device->free(alloc_device.get(), t->handle);
41 delete t;
42 }42 }
43private:43private:
44 std::shared_ptr<alloc_device_t> const alloc_device;44 std::shared_ptr<alloc_device_t> const alloc_device;
45};45};
46
47static void incRef(android_native_base_t*)
48{
49}
50}46}
5147
52mga::AndroidAllocAdaptor::AndroidAllocAdaptor(const std::shared_ptr<struct alloc_device_t>& alloc_device)48mga::AndroidAllocAdaptor::AndroidAllocAdaptor(const std::shared_ptr<struct alloc_device_t>& alloc_device)
@@ -71,8 +67,11 @@
71 BOOST_THROW_EXCEPTION(std::runtime_error("buffer allocation failed\n"));67 BOOST_THROW_EXCEPTION(std::runtime_error("buffer allocation failed\n"));
72 }68 }
7369
74 /* pack ANativeWindow buffer for the handle */70 AndroidBufferHandleDeleter del1(alloc_dev);
75 auto buffer = new ANativeWindowBuffer;71 auto tmp = new mga::MirNativeBuffer(del1);
72 mga::MirNativeBufferDeleter del;
73 std::shared_ptr<mga::MirNativeBuffer> buffer(tmp, del);
74
76 buffer->width = width;75 buffer->width = width;
77 buffer->height = height;76 buffer->height = height;
78 buffer->stride = stride;77 buffer->stride = stride;
@@ -80,17 +79,7 @@
80 buffer->format = format;79 buffer->format = format;
81 buffer->usage = usage_flag;80 buffer->usage = usage_flag;
8281
83 /* we don't use these for refcounting buffers. however, drivers still expect to be82 return buffer;
84 able to call them */
85 buffer->common.incRef = &incRef;
86 buffer->common.decRef = &incRef;
87 buffer->common.magic = ANDROID_NATIVE_BUFFER_MAGIC;
88 buffer->common.version = sizeof(ANativeWindowBuffer);
89
90 AndroidBufferHandleDeleter del(alloc_dev);
91 auto handle = std::shared_ptr<ANativeWindowBuffer>(buffer, del);
92
93 return handle;
94}83}
9584
96int mga::AndroidAllocAdaptor::convert_to_android_usage(BufferUsage usage)85int mga::AndroidAllocAdaptor::convert_to_android_usage(BufferUsage usage)
9786
=== modified file 'src/server/graphics/gl_renderer.cpp'
--- src/server/graphics/gl_renderer.cpp 2013-05-21 15:11:41 +0000
+++ src/server/graphics/gl_renderer.cpp 2013-06-19 18:36:29 +0000
@@ -248,14 +248,6 @@
248 glDisableVertexAttribArray(resources.position_attr_loc);248 glDisableVertexAttribArray(resources.position_attr_loc);
249}249}
250250
251void mg::GLRenderer::ensure_no_live_buffers_bound()
252{
253 /* before the system can delete buffers that back OES_EGL_image textures, it
254 must make sure that none of these textures are bound in the GLContext*/
255 static int emptytexture;
256 glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,1,1,0,GL_RGBA,GL_UNSIGNED_BYTE, &emptytexture);
257}
258
259void mg::GLRenderer::clear()251void mg::GLRenderer::clear()
260{252{
261 glClear(GL_COLOR_BUFFER_BIT);253 glClear(GL_COLOR_BUFFER_BIT);
262254
=== modified file 'src/server/shell/surface.cpp'
--- src/server/shell/surface.cpp 2013-06-17 19:47:07 +0000
+++ src/server/shell/surface.cpp 2013-06-19 18:36:29 +0000
@@ -185,6 +185,14 @@
185 }185 }
186}186}
187187
188void msh::Surface::allow_framedropping(bool allow)
189{
190 if (auto const& s = surface.lock())
191 {
192 s->allow_framedropping(allow);
193 }
194}
195
188std::shared_ptr<mc::Buffer> msh::Surface::client_buffer() const196std::shared_ptr<mc::Buffer> msh::Surface::client_buffer() const
189{197{
190 if (auto const& s = surface.lock())198 if (auto const& s = surface.lock())
@@ -236,7 +244,7 @@
236int msh::Surface::configure(MirSurfaceAttrib attrib, int value)244int msh::Surface::configure(MirSurfaceAttrib attrib, int value)
237{245{
238 int result = 0;246 int result = 0;
239247 bool allow_dropping = false;
240 /*248 /*
241 * TODO: In future, query the shell implementation for the subset of249 * TODO: In future, query the shell implementation for the subset of
242 * attributes/types it implements.250 * attributes/types it implements.
@@ -255,6 +263,11 @@
255 BOOST_THROW_EXCEPTION(std::logic_error("Invalid surface state."));263 BOOST_THROW_EXCEPTION(std::logic_error("Invalid surface state."));
256 result = state();264 result = state();
257 break;265 break;
266 case mir_surface_attrib_performance_hint:
267 allow_dropping = (value == mir_surface_hint_drop_frames);
268 allow_framedropping(allow_dropping);
269 result = value;
270 break;
258 default:271 default:
259 BOOST_THROW_EXCEPTION(std::logic_error("Invalid surface "272 BOOST_THROW_EXCEPTION(std::logic_error("Invalid surface "
260 "attribute."));273 "attribute."));
261274
=== modified file 'src/server/surfaces/surface.cpp'
--- src/server/surfaces/surface.cpp 2013-06-13 10:40:42 +0000
+++ src/server/surfaces/surface.cpp 2013-06-19 18:36:29 +0000
@@ -177,6 +177,11 @@
177 return client_buffer_resource;177 return client_buffer_resource;
178}178}
179179
180void ms::Surface::allow_framedropping(bool allow)
181{
182 buffer_stream->allow_framedropping(allow);
183}
184
180void ms::Surface::flag_for_render()185void ms::Surface::flag_for_render()
181{186{
182 buffer_is_valid = true;187 buffer_is_valid = true;
183188
=== modified file 'src/shared/graphics/android/CMakeLists.txt'
--- src/shared/graphics/android/CMakeLists.txt 2013-03-29 22:30:35 +0000
+++ src/shared/graphics/android/CMakeLists.txt 2013-06-19 18:36:29 +0000
@@ -2,6 +2,7 @@
2 mirsharedandroid STATIC2 mirsharedandroid STATIC
33
4 mir_native_window.cpp4 mir_native_window.cpp
5 mir_native_buffer.cpp
5 syncfence.cpp6 syncfence.cpp
6)7)
78
89
=== added file 'src/shared/graphics/android/mir_native_buffer.cpp'
--- src/shared/graphics/android/mir_native_buffer.cpp 1970-01-01 00:00:00 +0000
+++ src/shared/graphics/android/mir_native_buffer.cpp 2013-06-19 18:36:29 +0000
@@ -0,0 +1,73 @@
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
17 */
18
19#include "mir/graphics/android/mir_native_buffer.h"
20
21namespace mga=mir::graphics::android;
22
23namespace
24{
25static void incref_hook(struct android_native_base_t* base)
26{
27 auto buffer = reinterpret_cast<mga::MirNativeBuffer*>(base);
28 buffer->driver_reference();
29}
30static void decref_hook(struct android_native_base_t* base)
31{
32 auto buffer = reinterpret_cast<mga::MirNativeBuffer*>(base);
33 buffer->driver_dereference();
34}
35}
36
37mga::MirNativeBuffer::MirNativeBuffer(std::function<void(MirNativeBuffer*)> free)
38 : free_fn(free),
39 mir_reference(true),
40 driver_references(0)
41{
42 common.incRef = incref_hook;
43 common.decRef = decref_hook;
44}
45
46
47void mga::MirNativeBuffer::driver_reference()
48{
49 driver_references++;
50}
51
52void mga::MirNativeBuffer::driver_dereference()
53{
54 driver_references--;
55 if ((!mir_reference) && (driver_references ==0))
56 {
57 delete this;
58 }
59}
60
61void mga::MirNativeBuffer::mir_dereference()
62{
63 mir_reference = false;
64 if ((!mir_reference) && (driver_references ==0))
65 {
66 delete this;
67 }
68}
69
70mga::MirNativeBuffer::~MirNativeBuffer()
71{
72 free_fn(this);
73}
074
=== modified file 'tests/acceptance-tests/test_server_shutdown.cpp'
--- tests/acceptance-tests/test_server_shutdown.cpp 2013-06-06 08:36:17 +0000
+++ tests/acceptance-tests/test_server_shutdown.cpp 2013-06-19 18:36:29 +0000
@@ -51,9 +51,6 @@
51 */51 */
52 std::this_thread::yield();52 std::this_thread::yield();
53 }53 }
54 void ensure_no_live_buffers_bound()
55 {
56 }
5754
58 void clear() {}55 void clear() {}
59};56};
6057
=== modified file 'tests/integration-tests/CMakeLists.txt'
--- tests/integration-tests/CMakeLists.txt 2013-05-30 03:50:54 +0000
+++ tests/integration-tests/CMakeLists.txt 2013-06-19 18:36:29 +0000
@@ -7,6 +7,7 @@
7 test_display_info.cpp7 test_display_info.cpp
8 test_display_server_main_loop_events.cpp8 test_display_server_main_loop_events.cpp
9 test_surface_first_frame_sync.cpp9 test_surface_first_frame_sync.cpp
10 test_swapinterval.cpp
10)11)
1112
12add_subdirectory(client/)13add_subdirectory(client/)
1314
=== modified file 'tests/integration-tests/test_surface_first_frame_sync.cpp'
--- tests/integration-tests/test_surface_first_frame_sync.cpp 2013-06-12 10:27:50 +0000
+++ tests/integration-tests/test_surface_first_frame_sync.cpp 2013-06-19 18:36:29 +0000
@@ -96,8 +96,6 @@
96 while (write(render_operations_fd, "a", 1) != 1) continue;96 while (write(render_operations_fd, "a", 1) != 1) continue;
97 }97 }
9898
99 void ensure_no_live_buffers_bound() {}
100
101private:99private:
102 int render_operations_fd;100 int render_operations_fd;
103};101};
104102
=== added file 'tests/integration-tests/test_swapinterval.cpp'
--- tests/integration-tests/test_swapinterval.cpp 1970-01-01 00:00:00 +0000
+++ tests/integration-tests/test_swapinterval.cpp 2013-06-19 18:36:29 +0000
@@ -0,0 +1,226 @@
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
17 */
18
19#include "mir/geometry/rectangle.h"
20#include "mir/graphics/display.h"
21#include "mir/graphics/display_buffer.h"
22#include "mir/graphics/renderer.h"
23#include "mir/graphics/renderable.h"
24#include "mir/compositor/compositor.h"
25#include "mir/compositor/compositing_strategy.h"
26#include "mir/compositor/renderables.h"
27#include "mir/surfaces/buffer_stream.h"
28#include "mir/surfaces/buffer_stream_factory.h"
29
30#include "mir_test_framework/display_server_test_fixture.h"
31#include "mir_test_doubles/stub_buffer.h"
32
33#include "mir_toolkit/mir_client_library.h"
34
35#include <gtest/gtest.h>
36
37#include <thread>
38#include <unistd.h>
39#include <fcntl.h>
40
41namespace geom = mir::geometry;
42namespace mg = mir::graphics;
43namespace mc = mir::compositor;
44namespace mtf = mir_test_framework;
45namespace ms = mir::surfaces;
46namespace mtd = mir::test::doubles;
47
48namespace
49{
50char const* const mir_test_socket = mtf::test_socket_file().c_str();
51
52class CountingBufferStream : public ms::BufferStream
53{
54public:
55 CountingBufferStream(int render_operations_fd)
56 : render_operations_fd(render_operations_fd)
57 {
58 }
59
60 std::shared_ptr<mc::Buffer> secure_client_buffer() { return std::make_shared<mtd::StubBuffer>(); }
61 std::shared_ptr<ms::GraphicRegion> lock_back_buffer() { return std::make_shared<mtd::StubBuffer>(); }
62 geom::PixelFormat get_stream_pixel_format() { return geom::PixelFormat::abgr_8888; }
63 geom::Size stream_size() { return geom::Size{}; }
64 void force_requests_to_complete() {}
65 void allow_framedropping(bool)
66 {
67 while (write(render_operations_fd, "a", 1) != 1) continue;
68 }
69
70private:
71 int render_operations_fd;
72};
73
74class StubStreamFactory : public ms::BufferStreamFactory
75{
76public:
77 StubStreamFactory(int render_operations_fd)
78 : render_operations_fd(render_operations_fd)
79 {
80 }
81
82 std::shared_ptr<ms::BufferStream> create_buffer_stream(mc::BufferProperties const&)
83 {
84 return std::make_shared<CountingBufferStream>(render_operations_fd);
85 }
86private:
87 int render_operations_fd;
88};
89
90}
91
92using SwapIntervalSignalTest = BespokeDisplayServerTestFixture;
93TEST_F(SwapIntervalSignalTest, swapinterval_test)
94{
95 static std::string const swapinterval_set{"swapinterval_set_952f3f10.tmp"};
96 static std::string const do_client_finish{"do_client_finish_952f3f10.tmp"};
97
98 std::remove(swapinterval_set.c_str());
99 std::remove(do_client_finish.c_str());
100
101 struct ServerConfig : TestingServerConfiguration
102 {
103 ServerConfig()
104 {
105 if (pipe(rendering_ops_pipe) != 0)
106 {
107 BOOST_THROW_EXCEPTION(
108 std::runtime_error("Failed to create pipe"));
109 }
110
111 if (fcntl(rendering_ops_pipe[0], F_SETFL, O_NONBLOCK) != 0)
112 {
113 BOOST_THROW_EXCEPTION(
114 std::runtime_error("Failed to make the read end of the pipe non-blocking"));
115 }
116 }
117
118 ~ServerConfig()
119 {
120 if (rendering_ops_pipe[0] >= 0)
121 close(rendering_ops_pipe[0]);
122 if (rendering_ops_pipe[1] >= 0)
123 close(rendering_ops_pipe[1]);
124 }
125
126 std::shared_ptr<ms::BufferStreamFactory> the_buffer_stream_factory() override
127 {
128 if (!stub_stream_factory)
129 stub_stream_factory = std::make_shared<StubStreamFactory>(rendering_ops_pipe[1]);
130 return stub_stream_factory;
131 }
132
133 int num_of_swapinterval_commands()
134 {
135 char c;
136 int ops{0};
137
138 while (read(rendering_ops_pipe[0], &c, 1) == 1)
139 ops++;
140
141 return ops;
142 }
143
144 int rendering_ops_pipe[2];
145 std::shared_ptr<StubStreamFactory> stub_stream_factory;
146 } server_config;
147
148 launch_server_process(server_config);
149
150 struct ClientConfig : TestingClientConfiguration
151 {
152 ClientConfig(std::string const& swapinterval_set,
153 std::string const& do_client_finish)
154 : swapinterval_set{swapinterval_set},
155 do_client_finish{do_client_finish}
156 {
157 }
158
159 static void surface_callback(MirSurface*, void*)
160 {
161 }
162
163 void exec()
164 {
165 MirSurfaceParameters request_params =
166 {
167 __PRETTY_FUNCTION__,
168 640, 480,
169 mir_pixel_format_abgr_8888,
170 mir_buffer_usage_hardware
171 };
172
173 MirConnection* connection = mir_connect_sync(mir_test_socket, "testapp");
174 MirSurface* surface = mir_connection_create_surface_sync(connection, &request_params);
175
176 //1 is the default swapinterval
177 EXPECT_EQ(1, mir_surface_get_swapinterval(surface));
178
179 mir_wait_for(mir_surface_set_swapinterval(surface, 0));
180 EXPECT_EQ(0, mir_surface_get_swapinterval(surface));
181
182 mir_wait_for(mir_surface_set_swapinterval(surface, 1));
183 EXPECT_EQ(1, mir_surface_get_swapinterval(surface));
184
185 //swapinterval 2 not supported
186 EXPECT_EQ(NULL, mir_surface_set_swapinterval(surface, 2));
187 EXPECT_EQ(1, mir_surface_get_swapinterval(surface));
188
189 set_flag(swapinterval_set);
190 wait_for(do_client_finish);
191
192 mir_surface_release_sync(surface);
193 mir_connection_release(connection);
194 }
195
196 /* TODO: Extract this flag mechanism and make it reusable */
197 void set_flag(std::string const& flag_file)
198 {
199 close(open(flag_file.c_str(), O_CREAT, S_IWUSR | S_IRUSR));
200 }
201
202 void wait_for(std::string const& flag_file)
203 {
204 int fd = -1;
205 while ((fd = open(flag_file.c_str(), O_RDONLY, S_IWUSR | S_IRUSR)) == -1)
206 {
207 std::this_thread::sleep_for(std::chrono::milliseconds(1));
208 }
209 close(fd);
210 }
211
212 std::string const swapinterval_set;
213 std::string const do_client_finish;
214 } client_config{swapinterval_set, do_client_finish};
215
216 launch_client_process(client_config);
217
218 run_in_test_process([&]
219 {
220 client_config.wait_for(swapinterval_set);
221
222 EXPECT_EQ(2, server_config.num_of_swapinterval_commands());
223
224 client_config.set_flag(do_client_finish);
225 });
226}
0227
=== modified file 'tests/mir_test_framework/testing_server_options.cpp'
--- tests/mir_test_framework/testing_server_options.cpp 2013-06-12 10:27:50 +0000
+++ tests/mir_test_framework/testing_server_options.cpp 2013-06-19 18:36:29 +0000
@@ -141,10 +141,6 @@
141 r.graphic_region();141 r.graphic_region();
142 }142 }
143143
144 void ensure_no_live_buffers_bound()
145 {
146 }
147
148 void clear() {}144 void clear() {}
149};145};
150146
151147
=== modified file 'tests/unit-tests/client/android/test_client_android_buffer.cpp'
--- tests/unit-tests/client/android/test_client_android_buffer.cpp 2013-06-12 09:36:20 +0000
+++ tests/unit-tests/client/android/test_client_android_buffer.cpp 2013-06-19 18:36:29 +0000
@@ -335,6 +335,6 @@
335 ASSERT_NE(nullptr, native_handle->common.incRef);335 ASSERT_NE(nullptr, native_handle->common.incRef);
336 ASSERT_NE(nullptr, native_handle->common.decRef);336 ASSERT_NE(nullptr, native_handle->common.decRef);
337337
338 native_handle->common.incRef(NULL);338 native_handle->common.incRef(&native_handle->common);
339 native_handle->common.decRef(NULL);339 native_handle->common.decRef(&native_handle->common);
340}340}
341341
=== modified file 'tests/unit-tests/compositor/test_buffer_stream.cpp'
--- tests/unit-tests/compositor/test_buffer_stream.cpp 2013-06-17 15:55:04 +0000
+++ tests/unit-tests/compositor/test_buffer_stream.cpp 2013-06-19 18:36:29 +0000
@@ -122,3 +122,12 @@
122122
123 buffer_stream.secure_client_buffer();123 buffer_stream.secure_client_buffer();
124}124}
125
126TEST_F(BufferStreamTest, allow_framedropping_command)
127{
128 EXPECT_CALL(*mock_bundle, allow_framedropping(true))
129 .Times(1);
130
131 mc::BufferStreamSurfaces buffer_stream(mock_bundle);
132 buffer_stream.allow_framedropping(true);
133}
125134
=== modified file 'tests/unit-tests/compositor/test_rendering_operator.cpp'
--- tests/unit-tests/compositor/test_rendering_operator.cpp 2013-05-22 09:56:40 +0000
+++ tests/unit-tests/compositor/test_rendering_operator.cpp 2013-06-19 18:36:29 +0000
@@ -45,9 +45,6 @@
4545
46 void clear() {}46 void clear() {}
4747
48 void ensure_no_live_buffers_bound()
49 {
50 }
51 void render(std::function<void(std::shared_ptr<void> const&)> save_resource, mg::Renderable&)48 void render(std::function<void(std::shared_ptr<void> const&)> save_resource, mg::Renderable&)
52 {49 {
53 std::shared_ptr<void> tmp;50 std::shared_ptr<void> tmp;
@@ -81,7 +78,6 @@
81{78{
82public:79public:
83 MOCK_METHOD2(render, void(std::function<void(std::shared_ptr<void> const&)>, mg::Renderable&));80 MOCK_METHOD2(render, void(std::function<void(std::shared_ptr<void> const&)>, mg::Renderable&));
84 MOCK_METHOD0(ensure_no_live_buffers_bound, void());
85 MOCK_METHOD0(clear, void ());81 MOCK_METHOD0(clear, void ());
8682
87 ~MockRenderer() noexcept {}83 ~MockRenderer() noexcept {}
@@ -122,11 +118,3 @@
122 EXPECT_EQ(use_count_before1, stub_renderer.resource1.use_count());118 EXPECT_EQ(use_count_before1, stub_renderer.resource1.use_count());
123 EXPECT_EQ(use_count_before2, stub_renderer.resource2.use_count());119 EXPECT_EQ(use_count_before2, stub_renderer.resource2.use_count());
124}120}
125
126TEST(RenderingOperator, render_operator_ensures_no_live_texture_bound)
127{
128 MockRenderer mock_renderer;
129 EXPECT_CALL(mock_renderer, ensure_no_live_buffers_bound())
130 .Times(1);
131 mc::RenderingOperator rendering_operator(mock_renderer, [](std::shared_ptr<void> const&) {});
132}
133121
=== modified file 'tests/unit-tests/compositor/test_swapper_factory.cpp'
--- tests/unit-tests/compositor/test_swapper_factory.cpp 2013-06-11 19:55:10 +0000
+++ tests/unit-tests/compositor/test_swapper_factory.cpp 2013-06-19 18:36:29 +0000
@@ -147,6 +147,7 @@
147{147{
148 using namespace testing;148 using namespace testing;
149149
150 mc::BufferProperties properties;
150 std::vector<std::shared_ptr<mc::Buffer>> list {};151 std::vector<std::shared_ptr<mc::Buffer>> list {};
151 size_t size = 3;152 size_t size = 3;
152153
@@ -154,19 +155,66 @@
154 .Times(0);155 .Times(0);
155156
156 mc::SwapperFactory strategy(mock_buffer_allocator);157 mc::SwapperFactory strategy(mock_buffer_allocator);
157 auto swapper = strategy.create_swapper_reuse_buffers(list, size, mc::SwapperType::framedropping);158 auto swapper = strategy.create_swapper_reuse_buffers(properties, list, size, mc::SwapperType::framedropping);
158}159}
159160
160TEST_F(SwapperFactoryTest, create_sync_reuse)161TEST_F(SwapperFactoryTest, create_sync_reuse)
161{162{
162 using namespace testing;163 using namespace testing;
163164
165 mc::BufferProperties properties;
164 std::vector<std::shared_ptr<mc::Buffer>> list;166 std::vector<std::shared_ptr<mc::Buffer>> list;
165 size_t size = 3;167 size_t size = 3;
166168
167 EXPECT_CALL(*mock_buffer_allocator, alloc_buffer(properties))169 EXPECT_CALL(*mock_buffer_allocator, alloc_buffer(properties))
168 .Times(0);170 .Times(0);
169171
172 mc::SwapperFactory strategy(mock_buffer_allocator, 3);
173 auto swapper = strategy.create_swapper_reuse_buffers(properties, list, size, mc::SwapperType::synchronous);
174}
175
176TEST_F(SwapperFactoryTest, reuse_drop_unneeded_buffer)
177{
178 using namespace testing;
179
180 mc::SwapperFactory strategy(mock_buffer_allocator, 2);
181
182 auto buffer = std::make_shared<mtd::StubBuffer>();
183 {
184 size_t size = 3;
185 std::vector<std::shared_ptr<mc::Buffer>> list{buffer};
186
187 auto swapper = strategy.create_swapper_reuse_buffers(
188 properties, list, size, mc::SwapperType::synchronous);
189 }
190 EXPECT_EQ(1, buffer.use_count());
191}
192
193TEST_F(SwapperFactoryTest, reuse_drop_unneeded_buffer_error)
194{
195 using namespace testing;
196
197 mc::SwapperFactory strategy(mock_buffer_allocator, 2);
198
199 size_t size = 3;
200 std::vector<std::shared_ptr<mc::Buffer>> list{};
201
202 EXPECT_THROW({
203 strategy.create_swapper_reuse_buffers(
204 properties, list, size, mc::SwapperType::synchronous);
205 }, std::logic_error);
206}
207
208TEST_F(SwapperFactoryTest, reuse_alloc_additional_buffer_for_framedropping)
209{
210 using namespace testing;
211
212 EXPECT_CALL(*mock_buffer_allocator, alloc_buffer(_))
213 .Times(1);
170 mc::SwapperFactory strategy(mock_buffer_allocator);214 mc::SwapperFactory strategy(mock_buffer_allocator);
171 auto swapper = strategy.create_swapper_reuse_buffers(list, size, mc::SwapperType::synchronous);215
216 size_t size = 2;
217 std::vector<std::shared_ptr<mc::Buffer>> list{};
218 auto swapper = strategy.create_swapper_reuse_buffers(
219 properties, list, size, mc::SwapperType::framedropping);
172}220}
173221
=== modified file 'tests/unit-tests/compositor/test_switching_bundle.cpp'
--- tests/unit-tests/compositor/test_switching_bundle.cpp 2013-06-13 08:59:25 +0000
+++ tests/unit-tests/compositor/test_switching_bundle.cpp 2013-06-19 18:36:29 +0000
@@ -90,7 +90,7 @@
90 .WillOnce(Return(stub_buffer));90 .WillOnce(Return(stub_buffer));
91 EXPECT_CALL(*mock_secondary_swapper, client_release(stub_buffer))91 EXPECT_CALL(*mock_secondary_swapper, client_release(stub_buffer))
92 .Times(1);92 .Times(1);
93 EXPECT_CALL(*mock_swapper_factory, create_swapper_reuse_buffers(_,_,_))93 EXPECT_CALL(*mock_swapper_factory, create_swapper_reuse_buffers(_,_,_,_))
94 .Times(1)94 .Times(1)
95 .WillOnce(Return(mock_secondary_swapper));95 .WillOnce(Return(mock_secondary_swapper));
9696
@@ -126,7 +126,7 @@
126 .WillOnce(Return(stub_buffer));126 .WillOnce(Return(stub_buffer));
127 EXPECT_CALL(*mock_secondary_swapper, compositor_release(stub_buffer))127 EXPECT_CALL(*mock_secondary_swapper, compositor_release(stub_buffer))
128 .Times(1);128 .Times(1);
129 EXPECT_CALL(*mock_swapper_factory, create_swapper_reuse_buffers(_,_,_))129 EXPECT_CALL(*mock_swapper_factory, create_swapper_reuse_buffers(_,_,_,_))
130 .Times(1)130 .Times(1)
131 .WillOnce(Return(mock_secondary_swapper));131 .WillOnce(Return(mock_secondary_swapper));
132132
@@ -147,7 +147,7 @@
147 .Times(1);147 .Times(1);
148 EXPECT_CALL(*mock_default_swapper, end_responsibility(_,_))148 EXPECT_CALL(*mock_default_swapper, end_responsibility(_,_))
149 .Times(1);149 .Times(1);
150 EXPECT_CALL(*mock_swapper_factory, create_swapper_reuse_buffers(_,_,mc::SwapperType::framedropping))150 EXPECT_CALL(*mock_swapper_factory, create_swapper_reuse_buffers(_,_,_,mc::SwapperType::framedropping))
151 .Times(1)151 .Times(1)
152 .WillOnce(Return(mock_secondary_swapper));152 .WillOnce(Return(mock_secondary_swapper));
153153
154154
=== modified file 'tests/unit-tests/graphics/android/CMakeLists.txt'
--- tests/unit-tests/graphics/android/CMakeLists.txt 2013-05-21 20:58:15 +0000
+++ tests/unit-tests/graphics/android/CMakeLists.txt 2013-06-19 18:36:29 +0000
@@ -22,6 +22,7 @@
22 ${CMAKE_CURRENT_SOURCE_DIR}/test_pixel_format.cpp22 ${CMAKE_CURRENT_SOURCE_DIR}/test_pixel_format.cpp
23 ${CMAKE_CURRENT_SOURCE_DIR}/test_android_platform.cpp23 ${CMAKE_CURRENT_SOURCE_DIR}/test_android_platform.cpp
24 ${CMAKE_CURRENT_SOURCE_DIR}/test_interpreter_buffer_cache.cpp24 ${CMAKE_CURRENT_SOURCE_DIR}/test_interpreter_buffer_cache.cpp
25 ${CMAKE_CURRENT_SOURCE_DIR}/test_external_refcount.cpp
25)26)
2627
27set(UNIT_TEST_SOURCES ${UNIT_TEST_SOURCES} PARENT_SCOPE)28set(UNIT_TEST_SOURCES ${UNIT_TEST_SOURCES} PARENT_SCOPE)
2829
=== modified file 'tests/unit-tests/graphics/android/test_android_alloc_adaptor.cpp'
--- tests/unit-tests/graphics/android/test_android_alloc_adaptor.cpp 2013-05-21 21:43:25 +0000
+++ tests/unit-tests/graphics/android/test_android_alloc_adaptor.cpp 2013-06-19 18:36:29 +0000
@@ -217,20 +217,13 @@
217 EXPECT_EQ(fb_usage_flags, handle->usage);217 EXPECT_EQ(fb_usage_flags, handle->usage);
218}218}
219219
220TEST_F(AdaptorICSTest, handle_has_reffable_incref)220TEST_F(AdaptorICSTest, handle_has_strong_reference_for_c_drivers)
221{221{
222 struct android_native_base_t *native_base = nullptr;
223 auto handle = alloc_adaptor->alloc_buffer(size, pf, usage);222 auto handle = alloc_adaptor->alloc_buffer(size, pf, usage);
224 ASSERT_NE(nullptr, handle->common.incRef);223 ASSERT_NE(nullptr, handle->common.incRef);
225 handle->common.incRef(native_base);
226}
227
228TEST_F(AdaptorICSTest, handle_has_reffable_decref)
229{
230 struct android_native_base_t *native_base = nullptr;
231 auto handle = alloc_adaptor->alloc_buffer(size, pf, usage);
232 ASSERT_NE(nullptr, handle->common.decRef);224 ASSERT_NE(nullptr, handle->common.decRef);
233 handle->common.decRef(native_base);225 handle->common.incRef(&handle->common);
226 handle->common.decRef(&handle->common);
234}227}
235228
236TEST_F(AdaptorICSTest, handle_has_right_magic)229TEST_F(AdaptorICSTest, handle_has_right_magic)
237230
=== added file 'tests/unit-tests/graphics/android/test_external_refcount.cpp'
--- tests/unit-tests/graphics/android/test_external_refcount.cpp 1970-01-01 00:00:00 +0000
+++ tests/unit-tests/graphics/android/test_external_refcount.cpp 2013-06-19 18:36:29 +0000
@@ -0,0 +1,70 @@
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
17 */
18
19#include "mir/graphics/android/mir_native_buffer.h"
20#include <memory>
21#include <gtest/gtest.h>
22
23namespace mga=mir::graphics::android;
24
25TEST(AndroidRefcount, driver_hooks)
26{
27 int call_count = 0;
28 mga::MirNativeBuffer* driver_reference = nullptr;
29 {
30 auto tmp = new mga::MirNativeBuffer(
31 [&](mga::MirNativeBuffer*)
32 {
33 call_count++;
34 });
35 mga::MirNativeBufferDeleter del;
36 std::shared_ptr<mga::MirNativeBuffer> buffer(tmp, del);
37 driver_reference = buffer.get();
38 driver_reference->common.incRef(&driver_reference->common);
39 //Mir loses its reference
40 }
41
42 EXPECT_EQ(0, call_count);
43 driver_reference->common.decRef(&driver_reference->common);
44 EXPECT_EQ(1, call_count);
45}
46
47TEST(AndroidRefcount, driver_hooks_mir_ref)
48{
49 int call_count = 0;
50 {
51 std::shared_ptr<mga::MirNativeBuffer> mir_reference;
52 mga::MirNativeBuffer* driver_reference = nullptr;
53 {
54 auto tmp = new mga::MirNativeBuffer(
55 [&](mga::MirNativeBuffer*)
56 {
57 call_count++;
58 });
59 mga::MirNativeBufferDeleter del;
60 mir_reference = std::shared_ptr<mga::MirNativeBuffer>(tmp, del);
61 driver_reference = mir_reference.get();
62 driver_reference->common.incRef(&driver_reference->common);
63 }
64
65 //driver loses its reference
66 driver_reference->common.decRef(&driver_reference->common);
67 EXPECT_EQ(0, call_count);
68 }
69 EXPECT_EQ(1, call_count);
70}
071
=== modified file 'tests/unit-tests/graphics/test_gl_renderer.cpp'
--- tests/unit-tests/graphics/test_gl_renderer.cpp 2013-06-12 15:36:31 +0000
+++ tests/unit-tests/graphics/test_gl_renderer.cpp 2013-06-19 18:36:29 +0000
@@ -349,13 +349,3 @@
349 auto result = std::find(saved_resources.begin(), saved_resources.end(), gr_ptr);349 auto result = std::find(saved_resources.begin(), saved_resources.end(), gr_ptr);
350 EXPECT_NE(saved_resources.end(), result);350 EXPECT_NE(saved_resources.end(), result);
351}351}
352
353TEST_F(GLRenderer, TestRenderEnsureNoBind)
354{
355 using namespace std::placeholders;
356
357 mtd::MockRenderable rd;
358 EXPECT_CALL(mock_gl, glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,1,1,0,GL_RGBA,GL_UNSIGNED_BYTE,_));
359
360 renderer->ensure_no_live_buffers_bound();
361}
362352
=== modified file 'tests/unit-tests/surfaces/test_surface.cpp'
--- tests/unit-tests/surfaces/test_surface.cpp 2013-06-13 10:40:42 +0000
+++ tests/unit-tests/surfaces/test_surface.cpp 2013-06-19 18:36:29 +0000
@@ -420,6 +420,18 @@
420 surf.force_requests_to_complete();420 surf.force_requests_to_complete();
421}421}
422422
423TEST_F(SurfaceCreation, test_surface_allow_framedropping)
424{
425 using namespace testing;
426
427 EXPECT_CALL(*mock_buffer_stream, allow_framedropping(true))
428 .Times(1);
429
430 ms::Surface surf{surface_name, geom::Point(), mock_buffer_stream,
431 std::shared_ptr<mi::InputChannel>(), mock_change_cb};
432 surf.allow_framedropping(true);
433}
434
423TEST_F(SurfaceCreation, input_fds)435TEST_F(SurfaceCreation, input_fds)
424{436{
425 using namespace testing;437 using namespace testing;

Subscribers

People subscribed via source and target branches