Mir

Merge lp:~kdub/mir/send-client-fences-to-server into lp:mir

Proposed by Kevin DuBois
Status: Work in progress
Proposed branch: lp:~kdub/mir/send-client-fences-to-server
Merge into: lp:mir
Diff against target: 903 lines (+428/-259)
11 files modified
src/client/android/client_surface_interpreter.cpp (+2/-3)
src/client/mir_surface.cpp (+13/-0)
src/platform/graphics/android/ipc_operations.cpp (+12/-3)
tests/include/mir_test_doubles/mock_android_alloc_device.h (+11/-50)
tests/mir_test_doubles/mock_android_hw.cpp (+11/-0)
tests/unit-tests/client/android/test_client_surface_interpreter.cpp (+15/-7)
tests/unit-tests/client/test_client_mir_surface.cpp (+125/-5)
tests/unit-tests/graphics/android/CMakeLists.txt (+1/-0)
tests/unit-tests/graphics/android/test_android_alloc_adaptor.cpp (+4/-4)
tests/unit-tests/graphics/android/test_ipc_operations.cpp (+192/-0)
tests/unit-tests/graphics/android/test_platform.cpp (+42/-187)
To merge this branch: bzr merge lp:~kdub/mir/send-client-fences-to-server
Reviewer Review Type Date Requested Status
Mir development team Pending
Review via email: mp+241449@code.launchpad.net

Commit message

android: frontend:
send client fences back to the server. This is the complement of lp:~kdub/mir/send-server-fences-to-client. We will start processing the buffer that the client returns at an earlier point. HWC guarantees to wait for the fence before using the buffer, and we ensure that it is waited for in GLES composition in mg::Buffer::bind_to_texture.

Description of the change

android: frontend:
send client fences back to the server. This is the complement of lp:~kdub/mir/send-server-fences-to-client. We will start processing the buffer that the client returns at an earlier point. HWC guarantees to wait for the fence before using the buffer, and we ensure that it is waited for in GLES composition in mg::Buffer::bind_to_texture.

note: I split the ipc functions from test_platform.cpp into test_ipc_operations, as the platform test suite was really testing two objects. I did a bit of cleanup of the test in this area too.

currently testing with the full stack.

To post a comment you must log in.

Unmerged revisions

2007. By Kevin DuBois

merge in mir

2006. By Kevin DuBois

further test cleanups

2005. By Kevin DuBois

merge in mir

2004. By Kevin DuBois

some test cleanups

2003. By Kevin DuBois

adjust for loop spacings

2002. By Kevin DuBois

merge mir

2001. By Kevin DuBois

merge in base

2000. By Kevin DuBois

merge in lp:mir

1999. By Kevin DuBois

correct problematic mirsurface test

1998. By Kevin DuBois

merge base

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/client/android/client_surface_interpreter.cpp'
--- src/client/android/client_surface_interpreter.cpp 2014-10-01 06:25:56 +0000
+++ src/client/android/client_surface_interpreter.cpp 2014-11-11 18:48:42 +0000
@@ -45,9 +45,8 @@
4545
46void mcla::ClientSurfaceInterpreter::driver_returns_buffer(ANativeWindowBuffer*, int fence_fd)46void mcla::ClientSurfaceInterpreter::driver_returns_buffer(ANativeWindowBuffer*, int fence_fd)
47{47{
48 //TODO: pass fence to server instead of waiting here48 auto buffer = surface.get_current_buffer()->native_buffer_handle();
49 mga::SyncFence sync_fence(sync_ops, mir::Fd(fence_fd));49 buffer->update_usage(fence_fd, mga::BufferAccess::write);
50 sync_fence.wait();
5150
52 surface.request_and_wait_for_next_buffer();51 surface.request_and_wait_for_next_buffer();
53}52}
5453
=== modified file 'src/client/mir_surface.cpp'
--- src/client/mir_surface.cpp 2014-11-11 15:50:11 +0000
+++ src/client/mir_surface.cpp 2014-11-11 18:48:42 +0000
@@ -208,6 +208,15 @@
208 //TODO: we have extract the per-message information from the buffer208 //TODO: we have extract the per-message information from the buffer
209 *buffer_request.mutable_id() = surface.id();209 *buffer_request.mutable_id() = surface.id();
210 buffer_request.mutable_buffer()->set_buffer_id(surface.buffer().buffer_id());210 buffer_request.mutable_buffer()->set_buffer_id(surface.buffer().buffer_id());
211
212 MirNativeBuffer update_msg;
213 memset(&update_msg, 0, sizeof(update_msg));
214 auto client_buffer = buffer_depository->current_buffer();
215 client_buffer->fill_update_msg(update_msg);
216 for (auto i = 0; i < update_msg.data_items; i++)
217 buffer_request.mutable_buffer()->add_data(update_msg.fd[i]);
218 for (auto i = 0; i < update_msg.fd_items; i++)
219 buffer_request.mutable_buffer()->add_fd(update_msg.fd[i]);
211 perf_report->end_frame(surface.buffer().buffer_id());220 perf_report->end_frame(surface.buffer().buffer_id());
212 lock.unlock();221 lock.unlock();
213222
@@ -302,6 +311,10 @@
302{311{
303 {312 {
304 std::lock_guard<decltype(mutex)> lock(mutex);313 std::lock_guard<decltype(mutex)> lock(mutex);
314 for (auto fd : buffer_request.buffer().fd())
315 ::close(fd);
316 buffer_request.mutable_buffer()->clear_fd();
317 buffer_request.mutable_buffer()->clear_data();
305 process_incoming_buffer();318 process_incoming_buffer();
306 }319 }
307320
308321
=== modified file 'src/platform/graphics/android/ipc_operations.cpp'
--- src/platform/graphics/android/ipc_operations.cpp 2014-10-16 19:07:47 +0000
+++ src/platform/graphics/android/ipc_operations.cpp 2014-11-11 18:48:42 +0000
@@ -45,11 +45,11 @@
45 auto buffer_handle = native_buffer->handle();45 auto buffer_handle = native_buffer->handle();
46 int offset = 0;46 int offset = 0;
4747
48 for(auto i = 0; i < buffer_handle->numFds; i++)48 for (auto i = 0; i < buffer_handle->numFds; i++)
49 {49 {
50 msg.pack_fd(mir::Fd(IntOwnedFd{buffer_handle->data[offset++]}));50 msg.pack_fd(mir::Fd(IntOwnedFd{buffer_handle->data[offset++]}));
51 }51 }
52 for(auto i = 0; i < buffer_handle->numInts; i++)52 for (auto i = 0; i < buffer_handle->numInts; i++)
53 {53 {
54 msg.pack_data(buffer_handle->data[offset++]);54 msg.pack_data(buffer_handle->data[offset++]);
55 }55 }
@@ -59,8 +59,17 @@
59 }59 }
60}60}
6161
62void mga::IpcOperations::unpack_buffer(BufferIpcMessage&, Buffer const&) const62void mga::IpcOperations::unpack_buffer(BufferIpcMessage& msg, Buffer const& buffer) const
63{63{
64 auto const& fds = msg.fds();
65 auto const& data = msg.data();
66 auto native_buffer = buffer.native_buffer_handle();
67 if ((data.size() >= 1) && (fds.size() >= 1) &&
68 (data[0] == static_cast<int>(mga::BufferFlag::fenced)))
69 {
70 int fence = fds[0];
71 native_buffer->update_usage(fence, mga::BufferAccess::write);
72 }
64}73}
6574
66std::shared_ptr<mg::PlatformIPCPackage> mga::IpcOperations::connection_ipc_package()75std::shared_ptr<mg::PlatformIPCPackage> mga::IpcOperations::connection_ipc_package()
6776
=== modified file 'tests/include/mir_test_doubles/mock_android_alloc_device.h'
--- tests/include/mir_test_doubles/mock_android_alloc_device.h 2013-06-18 08:00:49 +0000
+++ tests/include/mir_test_doubles/mock_android_alloc_device.h 2014-11-11 18:48:42 +0000
@@ -18,6 +18,7 @@
18#ifndef MIR_TEST_DOUBLES_MOCK_ANDROID_ALLOC_DEVICE_H_18#ifndef MIR_TEST_DOUBLES_MOCK_ANDROID_ALLOC_DEVICE_H_
19#define MIR_TEST_DOUBLES_MOCK_ANDROID_ALLOC_DEVICE_H_19#define MIR_TEST_DOUBLES_MOCK_ANDROID_ALLOC_DEVICE_H_
2020
21#include <memory>
21#include <gmock/gmock.h>22#include <gmock/gmock.h>
22#include <hardware/gralloc.h>23#include <hardware/gralloc.h>
2324
@@ -25,49 +26,27 @@
25{26{
26namespace test27namespace test
27{28{
28namespace android
29{
30class ICSAllocInterface
31{
32public:
33 virtual ~ICSAllocInterface() {/* TODO: make nothrow */}
34 virtual int alloc_interface(alloc_device_t* dev, int w, int h,
35 int format, int usage, buffer_handle_t* handle, int* stride) = 0;
36 virtual int free_interface(alloc_device_t* dev, buffer_handle_t handle) = 0;
37 virtual int dump_interface(alloc_device_t* dev, char *buf, int len) = 0;
38
39};
40}
41namespace doubles29namespace doubles
42{30{
43class MockAllocDevice : public android::ICSAllocInterface,31std::shared_ptr<native_handle_t> generate_native_handle(size_t num_ints, size_t num_fds);
44 public alloc_device_t32struct MockAllocDevice : alloc_device_t
45{33{
46public:34 MockAllocDevice() :
4735 buffer_handle{generate_native_handle(43, 22)},
48 MockAllocDevice()36 fake_stride{300}
49 {37 {
50 using namespace testing;38 using namespace testing;
51
52 buffer_handle = mock_generate_sane_android_handle(43, 22);
53 fake_stride = 300;
54
55 alloc = hook_alloc;39 alloc = hook_alloc;
56 free = hook_free;40 free = hook_free;
57 dump = hook_dump;41 dump = hook_dump;
58 ON_CALL(*this, alloc_interface(_,_,_,_,_,_,_))42 ON_CALL(*this, alloc_interface(_,_,_,_,_,_,_))
59 .WillByDefault(DoAll(43 .WillByDefault(DoAll(
60 SetArgPointee<5>(buffer_handle),44 SetArgPointee<5>(buffer_handle.get()),
61 SetArgPointee<6>(fake_stride),45 SetArgPointee<6>(fake_stride),
62 Return(0)));46 Return(0)));
63 ON_CALL(*this, free_interface(_,_))47 ON_CALL(*this, free_interface(_,_))
64 .WillByDefault(Return(0));48 .WillByDefault(Return(0));
6549
66 }
67
68 ~MockAllocDevice()
69 {
70 ::free((void*)buffer_handle);
71 }50 }
7251
73 static int hook_alloc(alloc_device_t* mock_alloc,52 static int hook_alloc(alloc_device_t* mock_alloc,
@@ -90,29 +69,11 @@
90 mocker->dump_interface(mock_alloc, buf, buf_len);69 mocker->dump_interface(mock_alloc, buf, buf_len);
91 }70 }
9271
93 native_handle_t* mock_generate_sane_android_handle(int numFd, int numInt)
94 {
95 native_handle_t *handle;
96 int total=numFd + numInt;
97 int header_offset=3;
98
99 handle = (native_handle_t*) malloc(sizeof(int) * (header_offset+ total));
100 handle->version = 0x389;
101 handle->numFds = numFd;
102 handle->numInts = numInt;
103 for(int i=0; i<total; i++)
104 {
105 handle->data[i] = i*3;
106 }
107
108 return handle;
109 }
110
111 MOCK_METHOD7(alloc_interface, int(alloc_device_t*, int, int, int, int, buffer_handle_t*, int*));72 MOCK_METHOD7(alloc_interface, int(alloc_device_t*, int, int, int, int, buffer_handle_t*, int*));
112 MOCK_METHOD2(free_interface, int(alloc_device_t*, buffer_handle_t));73 MOCK_METHOD2(free_interface, int(alloc_device_t*, buffer_handle_t));
113 MOCK_METHOD3(dump_interface, int(alloc_device_t*, char*, int));74 MOCK_METHOD3(dump_interface, int(alloc_device_t*, char*, int));
11475
115 native_handle_t* buffer_handle;76 std::shared_ptr<native_handle_t> const buffer_handle;
116 unsigned int fake_stride;77 unsigned int fake_stride;
117};78};
118}79}
11980
=== modified file 'tests/mir_test_doubles/mock_android_hw.cpp'
--- tests/mir_test_doubles/mock_android_hw.cpp 2014-03-06 06:05:17 +0000
+++ tests/mir_test_doubles/mock_android_hw.cpp 2014-11-11 18:48:42 +0000
@@ -111,3 +111,14 @@
111 int rc = global_mock_android_hw->hw_get_module(id, module);111 int rc = global_mock_android_hw->hw_get_module(id, module);
112 return rc;112 return rc;
113}113}
114
115std::shared_ptr<native_handle_t> mtd::generate_native_handle(size_t num_ints, size_t num_fds)
116{
117 auto handle_size = sizeof(native_handle_t) + (sizeof(int)*(num_ints + num_fds));
118 auto native_buffer_handle = std::shared_ptr<native_handle_t>(reinterpret_cast<native_handle_t*>(::operator new(handle_size)));
119 native_buffer_handle->numInts = num_ints;
120 native_buffer_handle->numFds = num_fds;
121 for (auto i = 0u; i < (num_ints+num_fds); i++)
122 native_buffer_handle->data[i] = i;
123 return native_buffer_handle;
124}
114125
=== modified file 'tests/unit-tests/client/android/test_client_surface_interpreter.cpp'
--- tests/unit-tests/client/android/test_client_surface_interpreter.cpp 2014-10-27 20:20:10 +0000
+++ tests/unit-tests/client/android/test_client_surface_interpreter.cpp 2014-11-11 18:48:42 +0000
@@ -22,6 +22,7 @@
22#include "src/client/client_buffer.h"22#include "src/client/client_buffer.h"
23#include "src/client/android/client_surface_interpreter.h"23#include "src/client/android/client_surface_interpreter.h"
24#include "mir_test_doubles/stub_android_native_buffer.h"24#include "mir_test_doubles/stub_android_native_buffer.h"
25#include "mir_test_doubles/mock_android_native_buffer.h"
25#include "mir_test/fake_shared.h"26#include "mir_test/fake_shared.h"
26#include <system/window.h>27#include <system/window.h>
27#include <gmock/gmock.h>28#include <gmock/gmock.h>
@@ -131,18 +132,25 @@
131 EXPECT_EQ(buffer.get(), returned_buffer);132 EXPECT_EQ(buffer.get(), returned_buffer);
132}133}
133134
134TEST_F(AndroidInterpreter, advances_surface_on_buffer_return)135TEST_F(AndroidInterpreter, updates_fence_and_advances_surface_on_buffer_plus_fence_return)
135{136{
136 using namespace testing;137 using namespace testing;
137 ANativeWindowBuffer buffer;138 int fake_fence{45};
138139 auto buffer = std::make_shared<NiceMock<mtd::MockAndroidNativeBuffer>>();
139 testing::NiceMock<MockMirSurface> mock_surface{surf_params};140 testing::NiceMock<MockMirSurface> mock_surface{surf_params};
140 mcla::ClientSurfaceInterpreter interpreter(mock_surface);
141141
142 EXPECT_CALL(mock_surface, request_and_wait_for_next_buffer())142 EXPECT_CALL(*mock_client_buffer, native_buffer_handle())
143 .Times(1)
144 .WillOnce(Return(buffer));
145 EXPECT_CALL(*buffer, update_usage(fake_fence, mga::BufferAccess::write))
143 .Times(1);146 .Times(1);
144147 EXPECT_CALL(mock_surface, get_current_buffer())
145 interpreter.driver_returns_buffer(&buffer, -1);148 .Times(1)
149 .WillOnce(Return(mock_client_buffer));
150
151 mcla::ClientSurfaceInterpreter interpreter(mock_surface);
152
153 interpreter.driver_returns_buffer(buffer->anwb(), fake_fence);
146}154}
147155
148/* format is an int that is set by the driver. these are not the HAL_PIXEL_FORMATS in android */156/* format is an int that is set by the driver. these are not the HAL_PIXEL_FORMATS in android */
149157
=== modified file 'tests/unit-tests/client/test_client_mir_surface.cpp'
--- tests/unit-tests/client/test_client_mir_surface.cpp 2014-10-28 13:59:51 +0000
+++ tests/unit-tests/client/test_client_mir_surface.cpp 2014-11-11 18:48:42 +0000
@@ -31,6 +31,7 @@
31#include "mir/input/input_platform.h"31#include "mir/input/input_platform.h"
32#include "mir/input/input_receiver_thread.h"32#include "mir/input/input_receiver_thread.h"
3333
34#include "mir_test_doubles/fd_matcher.h"
34#include "mir_test/test_protobuf_server.h"35#include "mir_test/test_protobuf_server.h"
35#include "mir_test/stub_server_tool.h"36#include "mir_test/stub_server_tool.h"
36#include "mir_test/gmock_fixes.h"37#include "mir_test/gmock_fixes.h"
@@ -49,7 +50,7 @@
49namespace mg = mir::graphics;50namespace mg = mir::graphics;
50namespace geom = mir::geometry;51namespace geom = mir::geometry;
51namespace mt = mir::test;52namespace mt = mir::test;
5253namespace mtd = mir::test::doubles;
53namespace54namespace
54{55{
5556
@@ -538,10 +539,28 @@
538{539{
539 using namespace testing;540 using namespace testing;
540541
541 FakeRpcChannel fake_channel;542 struct UnresponsiveExchangeServer : public mir::protobuf::DisplayServer::Stub
542 mir::protobuf::DisplayServer::Stub unresponsive_server{&fake_channel};543 {
543544 UnresponsiveExchangeServer(::google::protobuf::RpcChannel* fake_channel) :
544 auto const surface = create_surface_with(unresponsive_server, stub_buffer_factory);545 mir::protobuf::DisplayServer::Stub{fake_channel}
546 {
547 }
548
549 void exchange_buffer(
550 ::google::protobuf::RpcController*,
551 const ::mir::protobuf::BufferRequest*,
552 ::mir::protobuf::Buffer*,
553 ::google::protobuf::Closure*) override
554 {
555 }
556 };
557
558 TestConnectionConfiguration conf;
559 connection = std::make_shared<MirConnection>(conf);
560 connection->connect("MirClientSurfaceTest", null_connected_callback, 0)->wait_for_all();
561 UnresponsiveExchangeServer unresponsive_server{conf.the_rpc_channel().get()};
562
563 auto const surface = create_and_wait_for_surface_with(unresponsive_server, stub_buffer_factory);
545564
546 auto buffer_wait_handle = surface->next_buffer(&null_surface_callback, nullptr);565 auto buffer_wait_handle = surface->next_buffer(&null_surface_callback, nullptr);
547566
@@ -759,3 +778,104 @@
759778
760 EXPECT_GE(std::chrono::steady_clock::now(), expected_end);779 EXPECT_GE(std::chrono::steady_clock::now(), expected_end);
761}780}
781
782struct FdGeneratingBuffer : public mcl::ClientBuffer
783{
784 FdGeneratingBuffer(mir::Fd fd) :
785 fd{std::move(fd)}
786 {
787 }
788 std::shared_ptr<mcl::MemoryRegion> secure_for_cpu_write()
789 {
790 return std::shared_ptr<mcl::MemoryRegion>();
791 }
792 geom::Size size() const { return size_; }
793 geom::Stride stride() const { return geom::Stride{0};}
794 MirPixelFormat pixel_format() const { return pf_; }
795 uint32_t age() const { return 0; }
796 void increment_age() {}
797 void mark_as_submitted() {}
798 std::shared_ptr<mg::NativeBuffer> native_buffer_handle() const
799 {
800 return std::shared_ptr<mg::NativeBuffer>();
801 }
802 void update_from(MirBufferPackage const&) {}
803 void fill_update_msg(MirBufferPackage& package)
804 {
805 package.data_items = 0;
806 package.fd_items = 1;
807 package.fd[0] = dup(fd);
808 }
809private:
810 mir::Fd const fd;
811 geom::Size size_;
812 MirPixelFormat pf_;
813};
814
815struct StubFdBufferFactory : public mcl::ClientBufferFactory
816{
817 StubFdBufferFactory(mir::Fd fd) :
818 fd{std::move(fd)}
819 {
820 }
821
822 std::shared_ptr<mcl::ClientBuffer> create_buffer(
823 std::shared_ptr<MirBufferPackage> const&,
824 geom::Size, MirPixelFormat)
825 {
826 return std::make_shared<FdGeneratingBuffer>(fd);
827 }
828 mir::Fd const fd;
829};
830
831struct ExchangeMonitoringRpcServer : mir::protobuf::DisplayServer::Stub
832{
833 ExchangeMonitoringRpcServer(::google::protobuf::RpcChannel* fake_channel) :
834 mir::protobuf::DisplayServer::Stub{fake_channel}
835 {
836 }
837
838 virtual void exchange_buffer(
839 ::google::protobuf::RpcController*,
840 const ::mir::protobuf::BufferRequest* request,
841 ::mir::protobuf::Buffer*,
842 ::google::protobuf::Closure* closure) override
843 {
844 last_exchange_buffer_request = *request;
845 last_exchange_buffer_closure = closure;
846 }
847
848 void complete_exchange_buffer()
849 {
850 if (last_exchange_buffer_closure)
851 last_exchange_buffer_closure->Run();
852 }
853 ::mir::protobuf::BufferRequest last_exchange_buffer_request;
854 ::google::protobuf::Closure* last_exchange_buffer_closure;
855};
856
857TEST_F(MirClientSurfaceTest, sends_fd_that_the_buffer_provides_and_closes_after_call_completes)
858{
859 using namespace testing;
860 mir::Fd fd{fileno(tmpfile())};
861 auto stub_fd_buffer_factory = std::make_shared<StubFdBufferFactory>(fd);
862
863 mir::protobuf::ConnectParameters connect_parameters;
864 connect_parameters.set_application_name("test");
865
866 TestConnectionConfiguration conf;
867 connection = std::make_shared<MirConnection>(conf);
868 MirWaitHandle* wait_handle = connection->connect("MirClientSurfaceTest",
869 null_connected_callback, 0);
870 wait_handle->wait_for_all();
871 ExchangeMonitoringRpcServer server(conf.the_rpc_channel().get());
872 auto const surface = create_and_wait_for_surface_with(server, stub_fd_buffer_factory);
873
874 auto buffer_wait_handle = surface->next_buffer(&null_surface_callback, nullptr);
875 auto& buffer_request = server.last_exchange_buffer_request.buffer();
876 ASSERT_THAT(buffer_request.fd().size(), (Eq(1)));
877 EXPECT_THAT(buffer_request.fd(0), mtd::RawFdIsValid());
878 server.complete_exchange_buffer();
879 buffer_wait_handle->wait_for_all();
880 EXPECT_THAT(buffer_request.fd(0), Not(mtd::RawFdIsValid()));
881}
762882
=== modified file 'tests/unit-tests/graphics/android/CMakeLists.txt'
--- tests/unit-tests/graphics/android/CMakeLists.txt 2014-10-01 06:25:56 +0000
+++ tests/unit-tests/graphics/android/CMakeLists.txt 2014-11-11 18:48:42 +0000
@@ -28,6 +28,7 @@
28 ${CMAKE_CURRENT_SOURCE_DIR}/test_device_detection.cpp28 ${CMAKE_CURRENT_SOURCE_DIR}/test_device_detection.cpp
29 ${CMAKE_CURRENT_SOURCE_DIR}/test_hwc_wrapper.cpp29 ${CMAKE_CURRENT_SOURCE_DIR}/test_hwc_wrapper.cpp
30 ${CMAKE_CURRENT_SOURCE_DIR}/test_hwc_fallback_gl_renderer.cpp30 ${CMAKE_CURRENT_SOURCE_DIR}/test_hwc_fallback_gl_renderer.cpp
31 ${CMAKE_CURRENT_SOURCE_DIR}/test_ipc_operations.cpp
31 $<TARGET_OBJECTS:mirplatformgraphicsandroidobjects>32 $<TARGET_OBJECTS:mirplatformgraphicsandroidobjects>
32)33)
3334
3435
=== modified file 'tests/unit-tests/graphics/android/test_android_alloc_adaptor.cpp'
--- tests/unit-tests/graphics/android/test_android_alloc_adaptor.cpp 2014-03-06 06:05:17 +0000
+++ tests/unit-tests/graphics/android/test_android_alloc_adaptor.cpp 2014-11-11 18:48:42 +0000
@@ -69,7 +69,7 @@
69 using namespace testing;69 using namespace testing;
70 EXPECT_CALL(*mock_alloc_device, alloc_interface(_,_,_,_,_,_,_))70 EXPECT_CALL(*mock_alloc_device, alloc_interface(_,_,_,_,_,_,_))
71 .WillOnce(DoAll(71 .WillOnce(DoAll(
72 SetArgPointee<5>(mock_alloc_device->buffer_handle),72 SetArgPointee<5>(mock_alloc_device->buffer_handle.get()),
73 SetArgPointee<6>(size.width.as_uint32_t()*4),73 SetArgPointee<6>(size.width.as_uint32_t()*4),
74 Return(-1)));74 Return(-1)));
7575
@@ -83,7 +83,7 @@
83 using namespace testing;83 using namespace testing;
84 EXPECT_CALL(*mock_alloc_device, alloc_interface(_,_,_,_,_,_,_))84 EXPECT_CALL(*mock_alloc_device, alloc_interface(_,_,_,_,_,_,_))
85 .WillOnce(DoAll(85 .WillOnce(DoAll(
86 SetArgPointee<5>(mock_alloc_device->buffer_handle),86 SetArgPointee<5>(mock_alloc_device->buffer_handle.get()),
87 SetArgPointee<6>(0),87 SetArgPointee<6>(0),
88 Return(0)));88 Return(0)));
8989
@@ -122,10 +122,10 @@
122122
123 EXPECT_CALL(*mock_alloc_device, alloc_interface(_,_,_,_,_,_,_))123 EXPECT_CALL(*mock_alloc_device, alloc_interface(_,_,_,_,_,_,_))
124 .WillOnce(DoAll(124 .WillOnce(DoAll(
125 SetArgPointee<5>(mock_alloc_device->buffer_handle),125 SetArgPointee<5>(mock_alloc_device->buffer_handle.get()),
126 SetArgPointee<6>(size.width.as_uint32_t()*4),126 SetArgPointee<6>(size.width.as_uint32_t()*4),
127 Return(0)));127 Return(0)));
128 EXPECT_CALL(*mock_alloc_device, free_interface(_,mock_alloc_device->buffer_handle));128 EXPECT_CALL(*mock_alloc_device, free_interface(_,mock_alloc_device->buffer_handle.get()));
129129
130 alloc_adaptor->alloc_buffer(size, pf, usage);130 alloc_adaptor->alloc_buffer(size, pf, usage);
131}131}
132132
=== added file 'tests/unit-tests/graphics/android/test_ipc_operations.cpp'
--- tests/unit-tests/graphics/android/test_ipc_operations.cpp 1970-01-01 00:00:00 +0000
+++ tests/unit-tests/graphics/android/test_ipc_operations.cpp 2014-11-11 18:48:42 +0000
@@ -0,0 +1,192 @@
1/*
2
3 * Copyright © 2012-2014 Canonical Ltd.
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
18 */
19
20#include "src/server/report/null_report_factory.h"
21#include "mir/graphics/native_platform.h"
22#include "mir/graphics/platform_ipc_operations.h"
23#include "mir/options/program_option.h"
24#include "src/platform/graphics/android/platform.h"
25#include "src/platform/graphics/android/ipc_operations.h"
26#include "mir_test_doubles/mock_buffer.h"
27#include "mir_test_doubles/mock_android_hw.h"
28#include "mir_test_doubles/mock_buffer_ipc_message.h"
29#include "mir_test_doubles/mock_display_report.h"
30#include "mir_test_doubles/stub_display_builder.h"
31#include "mir_test_doubles/mock_android_native_buffer.h"
32#include "mir_test_doubles/stub_android_native_buffer.h"
33#include "mir_test_doubles/fd_matcher.h"
34#include "mir_test/fake_shared.h"
35#include "mir_test_doubles/mock_android_native_buffer.h"
36#include "mir_test_doubles/mock_android_alloc_device.h"
37#include <gtest/gtest.h>
38
39namespace mg=mir::graphics;
40namespace mga=mir::graphics::android;
41namespace mt=mir::test;
42namespace mtd=mir::test::doubles;
43namespace mr=mir::report;
44namespace geom=mir::geometry;
45namespace mo=mir::options;
46
47struct IpcOperations : testing::Test
48{
49 IpcOperations() :
50 stride{300*4},
51 num_ints{30},
52 num_fds{12},
53 native_buffer{std::make_shared<mtd::MockAndroidNativeBuffer>()},
54 native_buffer_handle{mtd::generate_native_handle(num_ints, num_fds)},
55 mock_buffer{std::make_shared<testing::NiceMock<mtd::MockBuffer>>()}
56 {
57 using namespace testing;
58 ON_CALL(*native_buffer, handle())
59 .WillByDefault(Return(native_buffer_handle.get()));
60 ON_CALL(*mock_buffer, native_buffer_handle())
61 .WillByDefault(Return(native_buffer));
62 ON_CALL(*mock_buffer, stride())
63 .WillByDefault(Return(stride));
64 }
65
66 geom::Stride stride;
67 size_t num_ints;
68 size_t num_fds;
69 std::shared_ptr<mtd::MockAndroidNativeBuffer> native_buffer;
70 std::shared_ptr<native_handle_t> native_buffer_handle;
71 std::shared_ptr<mtd::MockBuffer> mock_buffer;
72 std::shared_ptr<mg::DisplayReport> stub_display_report;
73 mga::IpcOperations ipc_operations;
74};
75
76/* ipc packaging tests */
77TEST_F(IpcOperations, test_ipc_data_packed_correctly_for_full_ipc_with_fence)
78{
79 using namespace ::testing;
80 int fake_fence{333};
81 EXPECT_CALL(*native_buffer, copy_fence())
82 .WillOnce(Return(fake_fence));
83
84 mtd::MockBufferIpcMessage mock_ipc_msg;
85 int offset = 0;
86 EXPECT_CALL(mock_ipc_msg, pack_data(static_cast<int>(mga::BufferFlag::fenced)));
87 EXPECT_CALL(mock_ipc_msg, pack_fd(mtd::RawFdMatcher(fake_fence)));
88 for (auto i = 0u; i < num_fds; i++)
89 EXPECT_CALL(mock_ipc_msg, pack_fd(mtd::RawFdMatcher(native_buffer_handle->data[offset++])));
90 for (auto i = 0u; i < num_ints; i++)
91 EXPECT_CALL(mock_ipc_msg, pack_data(native_buffer_handle->data[offset++]));
92
93 EXPECT_CALL(*mock_buffer, stride())
94 .WillOnce(Return(stride));
95 EXPECT_CALL(mock_ipc_msg, pack_stride(stride))
96 .Times(1);
97
98 EXPECT_CALL(*mock_buffer, size())
99 .WillOnce(Return(mir::geometry::Size{123, 456}));
100 EXPECT_CALL(mock_ipc_msg, pack_size(_))
101 .Times(1);
102
103 ipc_operations.pack_buffer(mock_ipc_msg, *mock_buffer, mg::BufferIpcMsgType::full_msg);
104}
105
106TEST_F(IpcOperations, test_ipc_data_packed_correctly_for_full_ipc_without_fence)
107{
108 using namespace ::testing;
109 EXPECT_CALL(*native_buffer, copy_fence())
110 .WillOnce(Return(-1));
111
112 mtd::MockBufferIpcMessage mock_ipc_msg;
113 int offset = 0;
114 EXPECT_CALL(mock_ipc_msg, pack_data(static_cast<int>(mga::BufferFlag::unfenced)));
115 EXPECT_CALL(mock_ipc_msg, pack_fd(mtd::RawFdMatcher(-1)))
116 .Times(0);
117
118 for (auto i = 0u; i < num_fds; i++)
119 {
120 EXPECT_CALL(mock_ipc_msg, pack_fd(mtd::RawFdMatcher(native_buffer_handle->data[offset++])))
121 .Times(1);
122 }
123 for (auto i = 0u; i < num_ints; i++)
124 {
125 EXPECT_CALL(mock_ipc_msg, pack_data(native_buffer_handle->data[offset++]))
126 .Times(1);
127 }
128
129 EXPECT_CALL(*mock_buffer, stride())
130 .WillOnce(Return(stride));
131 EXPECT_CALL(mock_ipc_msg, pack_stride(stride))
132 .Times(1);
133
134 EXPECT_CALL(*mock_buffer, size())
135 .WillOnce(Return(mir::geometry::Size{123, 456}));
136 EXPECT_CALL(mock_ipc_msg, pack_size(_))
137 .Times(1);
138
139 ipc_operations.pack_buffer(mock_ipc_msg, *mock_buffer, mg::BufferIpcMsgType::full_msg);
140}
141
142TEST_F(IpcOperations, test_ipc_data_packed_correctly_for_partial_ipc)
143{
144 using namespace ::testing;
145
146 int fake_fence{33};
147 mtd::MockBufferIpcMessage mock_ipc_msg;
148
149 Sequence seq;
150 EXPECT_CALL(mock_ipc_msg, pack_data(static_cast<int>(mga::BufferFlag::fenced)))
151 .InSequence(seq);
152 EXPECT_CALL(mock_ipc_msg, pack_fd(mtd::RawFdMatcher(fake_fence)))
153 .InSequence(seq);
154 EXPECT_CALL(mock_ipc_msg, pack_data(static_cast<int>(mga::BufferFlag::unfenced)))
155 .InSequence(seq);
156
157 EXPECT_CALL(*native_buffer, copy_fence())
158 .Times(2)
159 .WillOnce(Return(fake_fence))
160 .WillOnce(Return(-1));
161
162 ipc_operations.pack_buffer(mock_ipc_msg, *mock_buffer, mg::BufferIpcMsgType::update_msg);
163 ipc_operations.pack_buffer(mock_ipc_msg, *mock_buffer, mg::BufferIpcMsgType::update_msg);
164}
165
166TEST_F(IpcOperations, unpacks_fenced_buffer_update)
167{
168 using namespace ::testing;
169 mtd::MockBufferIpcMessage mock_ipc_msg;
170 mir::Fd stub_fd{fileno(tmpfile())};
171
172 EXPECT_CALL(mock_ipc_msg, data())
173 .WillOnce(Return(std::vector<int>{static_cast<int>(mga::BufferFlag::fenced)}));
174 EXPECT_CALL(mock_ipc_msg, fds())
175 .WillOnce(Return(std::vector<mir::Fd>{stub_fd}));
176 EXPECT_CALL(*native_buffer, update_usage(_, mga::BufferAccess::write))
177 .Times(1);
178 ipc_operations.unpack_buffer(mock_ipc_msg, *mock_buffer);
179}
180
181TEST_F(IpcOperations, unpacks_unfenced_buffer)
182{
183 using namespace ::testing;
184 mtd::MockBufferIpcMessage mock_ipc_msg;
185 EXPECT_CALL(mock_ipc_msg, data())
186 .WillOnce(Return(std::vector<int>{static_cast<int>(mga::BufferFlag::unfenced)}));
187 EXPECT_CALL(mock_ipc_msg, fds())
188 .WillOnce(Return(std::vector<mir::Fd>{}));
189 EXPECT_CALL(*native_buffer, update_usage(_, _))
190 .Times(0);
191 ipc_operations.unpack_buffer(mock_ipc_msg, *mock_buffer);
192}
0193
=== modified file 'tests/unit-tests/graphics/android/test_platform.cpp'
--- tests/unit-tests/graphics/android/test_platform.cpp 2014-10-27 19:49:37 +0000
+++ tests/unit-tests/graphics/android/test_platform.cpp 2014-11-11 18:48:42 +0000
@@ -17,19 +17,16 @@
17 */17 */
1818
19#include "src/server/report/null_report_factory.h"19#include "src/server/report/null_report_factory.h"
20#include "mir/graphics/native_platform.h"20#include "mir_test_doubles/mock_display_report.h"
21#include "mir/graphics/platform_ipc_operations.h"
22#include "mir/options/program_option.h"
23#include "src/platform/graphics/android/platform.h"21#include "src/platform/graphics/android/platform.h"
24#include "mir_test_doubles/mock_buffer.h"22#include "mir_test_doubles/mock_buffer_ipc_message.h"
25#include "mir_test_doubles/mock_android_hw.h"23#include "mir_test_doubles/mock_android_hw.h"
26#include "mir_test_doubles/mock_buffer_ipc_message.h"24#include "mir_test_doubles/fd_matcher.h"
27#include "mir_test_doubles/mock_display_report.h"
28#include "mir_test_doubles/stub_display_builder.h"25#include "mir_test_doubles/stub_display_builder.h"
29#include "mir_test_doubles/fd_matcher.h"26#include "mir_test_doubles/mock_android_native_buffer.h"
27#include "mir_test_doubles/mock_buffer.h"
28#include "mir_test_doubles/mock_android_alloc_device.h"
30#include "mir_test/fake_shared.h"29#include "mir_test/fake_shared.h"
31#include "mir_test_doubles/mock_android_native_buffer.h"
32#include <system/window.h>
33#include <gtest/gtest.h>30#include <gtest/gtest.h>
3431
35namespace mg=mir::graphics;32namespace mg=mir::graphics;
@@ -38,184 +35,42 @@
38namespace mtd=mir::test::doubles;35namespace mtd=mir::test::doubles;
39namespace mr=mir::report;36namespace mr=mir::report;
40namespace geom=mir::geometry;37namespace geom=mir::geometry;
41namespace mo=mir::options;38
4239TEST(PlatformBufferIPCPackaging, test_ipc_data_packed_correctly_for_nested)
43class PlatformBufferIPCPackaging : public ::testing::Test40{
44{41 using namespace ::testing;
45protected:42 unsigned int num_ints{43};
46 virtual void SetUp()43 unsigned int num_fds{55};
47 {44 int offset = 0;
48 using namespace testing;45 geom::Stride stride{300*4};
4946 geom::Size size{123, 456};
50 stub_display_builder = std::make_shared<mtd::StubDisplayBuilder>();47 mtd::MockBuffer mock_buffer;
51 stub_display_report = mr::null_display_report();48 mtd::MockBufferIpcMessage mock_ipc_msg;
52 stride = geom::Stride(300*4);49
5350 auto native_buffer = std::make_shared<mtd::MockAndroidNativeBuffer>();
54 num_ints = 43;51 auto native = mtd::generate_native_handle(num_ints, num_fds);
55 num_fds = 55;52 ON_CALL(*native_buffer, handle())
56 auto handle_size = sizeof(native_handle_t) + (sizeof(int)*(num_ints + num_fds));53 .WillByDefault(Return(native.get()));
57 auto native_buffer_raw = (native_handle_t*) ::operator new(handle_size);54 ON_CALL(mock_buffer, native_buffer_handle())
58 native_buffer_handle = std::shared_ptr<native_handle_t>(native_buffer_raw);55 .WillByDefault(Return(native_buffer));
5956 ON_CALL(mock_buffer, stride())
60 native_buffer_handle->numInts = num_ints;57 .WillByDefault(Return(stride));
61 native_buffer_handle->numFds = num_fds;58 ON_CALL(mock_buffer, size())
62 for (auto i = 0u; i < (num_ints+num_fds); i++)59 .WillByDefault(Return(size));
63 {60
64 native_buffer_handle->data[i] = i;61 mga::Platform platform(std::make_shared<mtd::StubDisplayBuilder>(), mr::null_display_report());
65 }62
6663 EXPECT_CALL(*native_buffer, copy_fence())
67 native_buffer = std::make_shared<mtd::MockAndroidNativeBuffer>();64 .WillOnce(Return(-1));
68 mock_buffer = std::make_shared<NiceMock<mtd::MockBuffer>>();65 EXPECT_CALL(mock_ipc_msg, pack_data(static_cast<int>(mga::BufferFlag::unfenced)));
6966 for (auto i = 0u; i < num_fds; i++)
70 ON_CALL(*native_buffer, handle())67 EXPECT_CALL(mock_ipc_msg, pack_fd(mtd::RawFdMatcher(native->data[offset++])));
71 .WillByDefault(Return(native_buffer_handle.get()));68 for (auto i = 0u; i < num_ints; i++)
72 ON_CALL(*mock_buffer, native_buffer_handle())69 EXPECT_CALL(mock_ipc_msg, pack_data(native->data[offset++]));
73 .WillByDefault(Return(native_buffer));70 EXPECT_CALL(mock_ipc_msg, pack_stride(stride));
74 ON_CALL(*mock_buffer, stride())71 EXPECT_CALL(mock_ipc_msg, pack_size(size));
75 .WillByDefault(Return(stride));72
76 }73 platform.fill_buffer_package(&mock_ipc_msg, &mock_buffer, mg::BufferIpcMsgType::full_msg);
77
78 std::shared_ptr<mtd::MockAndroidNativeBuffer> native_buffer;
79 std::shared_ptr<mtd::StubDisplayBuilder> stub_display_builder;
80 std::shared_ptr<mtd::MockBuffer> mock_buffer;
81 std::shared_ptr<native_handle_t> native_buffer_handle;
82 std::shared_ptr<mg::DisplayReport> stub_display_report;
83 geom::Stride stride;
84 unsigned int num_ints, num_fds;
85};
86
87/* ipc packaging tests */
88TEST_F(PlatformBufferIPCPackaging, test_ipc_data_packed_correctly_for_full_ipc_with_fence)
89{
90 using namespace ::testing;
91 int fake_fence{333};
92 EXPECT_CALL(*native_buffer, copy_fence())
93 .WillOnce(Return(fake_fence));
94
95 mga::Platform platform(stub_display_builder, stub_display_report);
96
97 mtd::MockBufferIpcMessage mock_ipc_msg;
98 int offset = 0;
99 EXPECT_CALL(mock_ipc_msg, pack_data(static_cast<int>(mga::BufferFlag::fenced)));
100 EXPECT_CALL(mock_ipc_msg, pack_fd(mtd::RawFdMatcher(fake_fence)));
101 for (auto i = 0u; i < num_fds; i++)
102 EXPECT_CALL(mock_ipc_msg, pack_fd(mtd::RawFdMatcher(native_buffer_handle->data[offset++])));
103 for (auto i = 0u; i < num_ints; i++)
104 EXPECT_CALL(mock_ipc_msg, pack_data(native_buffer_handle->data[offset++]));
105
106 EXPECT_CALL(*mock_buffer, stride())
107 .WillOnce(Return(stride));
108 EXPECT_CALL(mock_ipc_msg, pack_stride(stride))
109 .Times(1);
110
111 EXPECT_CALL(*mock_buffer, size())
112 .WillOnce(Return(mir::geometry::Size{123, 456}));
113 EXPECT_CALL(mock_ipc_msg, pack_size(_))
114 .Times(1);
115
116 platform.fill_buffer_package(
117 &mock_ipc_msg, mock_buffer.get(), mg::BufferIpcMsgType::full_msg);
118}
119
120TEST_F(PlatformBufferIPCPackaging, test_ipc_data_packed_correctly_for_full_ipc_without_fence)
121{
122 using namespace ::testing;
123 EXPECT_CALL(*native_buffer, copy_fence())
124 .WillOnce(Return(-1));
125
126 mga::Platform platform(stub_display_builder, stub_display_report);
127
128 mtd::MockBufferIpcMessage mock_ipc_msg;
129 int offset = 0;
130 EXPECT_CALL(mock_ipc_msg, pack_data(static_cast<int>(mga::BufferFlag::unfenced)));
131 EXPECT_CALL(mock_ipc_msg, pack_fd(mtd::RawFdMatcher(-1)))
132 .Times(0);
133
134 for (auto i = 0u; i < num_fds; i++)
135 {
136 EXPECT_CALL(mock_ipc_msg, pack_fd(mtd::RawFdMatcher(native_buffer_handle->data[offset++])))
137 .Times(1);
138 }
139 for (auto i = 0u; i < num_ints; i++)
140 {
141 EXPECT_CALL(mock_ipc_msg, pack_data(native_buffer_handle->data[offset++]))
142 .Times(1);
143 }
144
145 EXPECT_CALL(*mock_buffer, stride())
146 .WillOnce(Return(stride));
147 EXPECT_CALL(mock_ipc_msg, pack_stride(stride))
148 .Times(1);
149
150 EXPECT_CALL(*mock_buffer, size())
151 .WillOnce(Return(mir::geometry::Size{123, 456}));
152 EXPECT_CALL(mock_ipc_msg, pack_size(_))
153 .Times(1);
154
155 platform.fill_buffer_package(
156 &mock_ipc_msg, mock_buffer.get(), mg::BufferIpcMsgType::full_msg);
157}
158
159TEST_F(PlatformBufferIPCPackaging, test_ipc_data_packed_correctly_for_nested)
160{
161 using namespace ::testing;
162 EXPECT_CALL(*native_buffer, copy_fence())
163 .WillOnce(Return(-1));
164
165 mga::Platform platform(stub_display_builder, stub_display_report);
166
167 mtd::MockBufferIpcMessage mock_ipc_msg;
168 int offset = 0;
169 for (auto i = 0u; i < num_fds; i++)
170 {
171 EXPECT_CALL(mock_ipc_msg, pack_fd(mtd::RawFdMatcher(native_buffer_handle->data[offset++])))
172 .Times(1);
173 }
174 EXPECT_CALL(mock_ipc_msg, pack_data(static_cast<int>(mga::BufferFlag::unfenced)));
175 for (auto i = 0u; i < num_ints; i++)
176 {
177 EXPECT_CALL(mock_ipc_msg, pack_data(native_buffer_handle->data[offset++]))
178 .Times(1);
179 }
180
181 EXPECT_CALL(*mock_buffer, stride())
182 .WillOnce(Return(stride));
183 EXPECT_CALL(mock_ipc_msg, pack_stride(stride))
184 .Times(1);
185
186 EXPECT_CALL(*mock_buffer, size())
187 .WillOnce(Return(mir::geometry::Size{123, 456}));
188 EXPECT_CALL(mock_ipc_msg, pack_size(_))
189 .Times(1);
190
191 platform.fill_buffer_package(&mock_ipc_msg, mock_buffer.get(), mg::BufferIpcMsgType::full_msg);
192}
193
194TEST_F(PlatformBufferIPCPackaging, test_ipc_data_packed_correctly_for_partial_ipc)
195{
196 using namespace ::testing;
197
198 int fake_fence{33};
199 mga::Platform platform(stub_display_builder, stub_display_report);
200 auto ipc_ops = platform.make_ipc_operations();
201
202 mtd::MockBufferIpcMessage mock_ipc_msg;
203
204 Sequence seq;
205 EXPECT_CALL(mock_ipc_msg, pack_data(static_cast<int>(mga::BufferFlag::fenced)))
206 .InSequence(seq);
207 EXPECT_CALL(mock_ipc_msg, pack_fd(mtd::RawFdMatcher(fake_fence)))
208 .InSequence(seq);
209 EXPECT_CALL(mock_ipc_msg, pack_data(static_cast<int>(mga::BufferFlag::unfenced)))
210 .InSequence(seq);
211
212 EXPECT_CALL(*native_buffer, copy_fence())
213 .Times(2)
214 .WillOnce(Return(fake_fence))
215 .WillOnce(Return(-1));
216
217 ipc_ops->pack_buffer(mock_ipc_msg, *mock_buffer, mg::BufferIpcMsgType::update_msg);
218 ipc_ops->pack_buffer(mock_ipc_msg, *mock_buffer, mg::BufferIpcMsgType::update_msg);
219}74}
22075
221TEST(AndroidGraphicsPlatform, egl_native_display_is_egl_default_display)76TEST(AndroidGraphicsPlatform, egl_native_display_is_egl_default_display)

Subscribers

People subscribed via source and target branches