Mir

Merge lp:~kdub/mir/mali-client-render-support into lp:~mir-team/mir/trunk

Proposed by Kevin DuBois on 2013-09-13
Status: Superseded
Proposed branch: lp:~kdub/mir/mali-client-render-support
Merge into: lp:~mir-team/mir/trunk
Diff against target: 734 lines (+209/-238)
7 files modified
include/shared/mir/graphics/android/mir_native_window.h (+1/-0)
src/client/android/android_client_buffer.cpp (+1/-2)
src/client/android/client_surface_interpreter.cpp (+3/-0)
src/shared/graphics/android/mir_native_window.cpp (+18/-7)
tests/integration-tests/client/test_client_render.cpp (+156/-229)
tests/unit-tests/client/android/test_android_native_window.cpp (+14/-0)
tests/unit-tests/client/android/test_client_surface_interpreter.cpp (+16/-0)
To merge this branch: bzr merge lp:~kdub/mir/mali-client-render-support
Reviewer Review Type Date Requested Status
Robert Carr (community) Needs Information on 2013-09-23
Alan Griffiths 2013-09-13 Needs Fixing on 2013-09-16
PS Jenkins bot (community) continuous-integration Approve on 2013-09-13
Review via email: mp+185603@code.launchpad.net

This proposal has been superseded by a proposal from 2013-09-24.

Commit message

android: support driver hooks for the Mali T604 (present in nexus 10)

Description of the change

android: support driver hooks for the Mali T604 (present in nexus 10)

The exynos driver needed some function hooks implemented. This change implements those hooks and gets the TestClientIPCRender test to pass. This test sends buffers over IPC to a client, and the client then establishes an egl context, renders to the buffer, and checks the buffer content back on the server side.

Please note: the nexus 10 display is still broken (so running a demo server won't go well), but supporting the hooks for the driver is the first step.

To post a comment you must log in.
Alan Griffiths (alan-griffiths) wrote :

On android (N4) I get:
./unit-tests
...
[ PASSED ] 730 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] ClientAndroidBufferTest.buffer_packs_anativewindowbuffer_info

(But it fixes a hang in SwitchingBundleTest.client_framerate_matches_compositor - so I guess it doesn't make anything worse.)

Alan Griffiths (alan-griffiths) wrote :

SwitchingBundleTest.client_framerate_matches_compositor is racy (and not fixed after all)

But this definitely breaks:

# ./unit-tests --gtest_filter=ClientAndroidBufferTest.buffer_packs_anativewindowbuffer_info
/home/alan/display_server/trunk-mir/tests/unit-tests/client/android/test_client_android_buffer.cpp:151: Failure
Value of: native_handle->stride
  Actual: 66
Expected: expected_stride_in_pixels
Which is: 16
[ FAILED ] ClientAndroidBufferTest.buffer_packs_anativewindowbuffer_info (2 ms)
[----------] 1 test from ClientAndroidBufferTest (2 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (4 ms total)
[ PASSED ] 0 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] ClientAndroidBufferTest.buffer_packs_anativewindowbuffer_info

 1 FAILED TEST

review: Needs Fixing
Kevin DuBois (kdub) wrote :

will have to take a look at stride on android again

Robert Carr (robertcarr) wrote :

121 + static MirPixelFormat select_format_for_visual_id(int visual_id)
122 + {
123 + if (visual_id == 5)
124 + return mir_pixel_format_argb_8888;

It would be nice to see some constants for visual_id.

Haven't tested on nexus 4. Let me know if it needs some runs.

==
+ case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
43 + return 2;
===

Wondering if this has implications on existing hardware support (n4, etc...)

review: Needs Information
1076. By Kevin DuBois on 2013-10-15

merge in dev branch

1077. By Kevin DuBois on 2013-10-15

merge in fix for integration test

1078. By Kevin DuBois on 2013-10-28

merge in dev branch

1079. By Kevin DuBois on 2013-11-05

merge dev branch

1080. By Kevin DuBois on 2013-11-05

corret unit test so it passes

1081. By Kevin DuBois on 2013-11-05

remove commented code

1082. By Kevin DuBois on 2013-11-11

temporary commit

1083. By Kevin DuBois on 2013-11-11

merge trunk

1084. By Kevin DuBois on 2013-11-11

1more test

1085. By Kevin DuBois on 2013-11-11

all tests to pass, no stride changes, just test fixes

Unmerged revisions

1085. By Kevin DuBois on 2013-11-11

all tests to pass, no stride changes, just test fixes

1084. By Kevin DuBois on 2013-11-11

1more test

1083. By Kevin DuBois on 2013-11-11

merge trunk

1082. By Kevin DuBois on 2013-11-11

temporary commit

1081. By Kevin DuBois on 2013-11-05

remove commented code

1080. By Kevin DuBois on 2013-11-05

corret unit test so it passes

1079. By Kevin DuBois on 2013-11-05

merge dev branch

1078. By Kevin DuBois on 2013-10-28

merge in dev branch

1077. By Kevin DuBois on 2013-10-15

merge in fix for integration test

1076. By Kevin DuBois on 2013-10-15

merge in dev branch

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/shared/mir/graphics/android/mir_native_window.h'
2--- include/shared/mir/graphics/android/mir_native_window.h 2013-05-16 20:19:12 +0000
3+++ include/shared/mir/graphics/android/mir_native_window.h 2013-09-13 21:49:43 +0000
4@@ -41,6 +41,7 @@
5 int perform(int key, va_list args );
6 int dequeueBuffer(struct ANativeWindowBuffer** buffer);
7 int queueBuffer(struct ANativeWindowBuffer* buffer, std::shared_ptr<SyncObject> const& fence);
8+ int cancelBuffer(struct ANativeWindowBuffer* buffer, std::shared_ptr<SyncObject> const& fence);
9 int setSwapInterval(int interval);
10 private:
11
12
13=== modified file 'src/client/android/android_client_buffer.cpp'
14--- src/client/android/android_client_buffer.cpp 2013-08-28 03:41:48 +0000
15+++ src/client/android/android_client_buffer.cpp 2013-09-13 21:49:43 +0000
16@@ -41,8 +41,7 @@
17
18 native_window_buffer->height = static_cast<int32_t>(size.height.as_uint32_t());
19 native_window_buffer->width = static_cast<int32_t>(size.width.as_uint32_t());
20- native_window_buffer->stride = stride.as_uint32_t() /
21- geom::bytes_per_pixel(buffer_pf);
22+ native_window_buffer->stride = stride.as_uint32_t();
23 native_window_buffer->usage = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER;
24 native_window_buffer->handle = native_handle.get();
25 }
26
27=== modified file 'src/client/android/client_surface_interpreter.cpp'
28--- src/client/android/client_surface_interpreter.cpp 2013-05-16 20:19:12 +0000
29+++ src/client/android/client_surface_interpreter.cpp 2013-09-13 21:49:43 +0000
30@@ -33,6 +33,7 @@
31 {
32 auto buffer = surface.get_current_buffer();
33 auto buffer_to_driver = buffer->native_buffer_handle();
34+
35 buffer_to_driver->format = driver_pixel_format;
36
37 return buffer_to_driver.get();
38@@ -65,6 +66,8 @@
39 return driver_pixel_format;
40 case NATIVE_WINDOW_TRANSFORM_HINT:
41 return 0;
42+ case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
43+ return 2;
44 default:
45 throw std::runtime_error("driver requested unsupported query");
46 }
47
48=== modified file 'src/shared/graphics/android/mir_native_window.cpp'
49--- src/shared/graphics/android/mir_native_window.cpp 2013-05-20 15:29:28 +0000
50+++ src/shared/graphics/android/mir_native_window.cpp 2013-09-13 21:49:43 +0000
51@@ -128,16 +128,19 @@
52 return 0;
53 }
54
55-int cancelBuffer_deprecated_static(struct ANativeWindow* /*window*/,
56- struct ANativeWindowBuffer* /*buffer*/)
57+int cancelBuffer_deprecated_static(struct ANativeWindow* window,
58+ struct ANativeWindowBuffer* buffer)
59 {
60- return 0;
61+ return cancelBuffer_static(window, buffer, -1);
62 }
63
64-int cancelBuffer_static(struct ANativeWindow* /*window*/,
65- struct ANativeWindowBuffer* /*buffer*/, int /*fence_fd*/)
66+int cancelBuffer_static(struct ANativeWindow* window,
67+ struct ANativeWindowBuffer* buffer, int fence_fd)
68 {
69- return 0;
70+ auto ioctl_control = std::make_shared<IoctlControl>();
71+ auto fence = std::make_shared<mga::SyncFence>(fence_fd, ioctl_control);
72+ auto self = static_cast<mga::MirNativeWindow*>(window);
73+ return self->cancelBuffer(buffer, fence);
74 }
75
76 }
77@@ -182,7 +185,15 @@
78 return 0;
79 }
80
81-int mga::MirNativeWindow::queueBuffer(struct ANativeWindowBuffer* buffer, std::shared_ptr<mga::SyncObject> const& fence)
82+int mga::MirNativeWindow::queueBuffer(struct ANativeWindowBuffer* buffer,
83+ std::shared_ptr<mga::SyncObject> const& fence)
84+{
85+ driver_interpreter->driver_returns_buffer(buffer, fence);
86+ return 0;
87+}
88+
89+int mga::MirNativeWindow::cancelBuffer(struct ANativeWindowBuffer* buffer,
90+ std::shared_ptr<mga::SyncObject> const& fence)
91 {
92 driver_interpreter->driver_returns_buffer(buffer, fence);
93 return 0;
94
95=== modified file 'tests/integration-tests/client/test_client_render.cpp'
96--- tests/integration-tests/client/test_client_render.cpp 2013-08-28 03:41:48 +0000
97+++ tests/integration-tests/client/test_client_render.cpp 2013-09-13 21:49:43 +0000
98@@ -29,6 +29,7 @@
99
100 #include "mir/frontend/communicator.h"
101
102+#include <iostream>
103 #include <gmock/gmock.h>
104 #include <thread>
105 #include <hardware/gralloc.h>
106@@ -65,10 +66,6 @@
107 *surf = surface;
108 }
109
110-static void next_callback(MirSurface *, void*)
111-{
112-}
113-
114 static uint32_t pattern0 [2][2] = {{0x12345678, 0x23456789},
115 {0x34567890, 0x45678901}};
116
117@@ -76,6 +73,15 @@
118 {0xFF00FF00, 0xFF0000FF}};
119 struct TestClient
120 {
121+ static MirPixelFormat select_format_for_visual_id(int visual_id)
122+ {
123+ if (visual_id == 5)
124+ return mir_pixel_format_argb_8888;
125+ if (visual_id == 1)
126+ return mir_pixel_format_abgr_8888;
127+
128+ return mir_pixel_format_invalid;
129+ }
130
131 static void sig_handle(int)
132 {
133@@ -115,6 +121,8 @@
134 /* render pattern */
135 mtd::DrawPatternCheckered<2,2> draw_pattern0(mt::pattern0);
136 draw_pattern0.draw(graphics_region);
137+
138+ mir_surface_swap_buffers_sync(surface);
139
140 mir_wait_for(mir_surface_release(surface, &create_callback, &surface));
141
142@@ -156,11 +164,13 @@
143 mtd::DrawPatternCheckered<2,2> draw_pattern0(mt::pattern0);
144 draw_pattern0.draw(graphics_region);
145
146- mir_wait_for(mir_surface_swap_buffers(surface, &next_callback, (void*) NULL));
147+ mir_surface_swap_buffers_sync(surface);
148 mir_surface_get_graphics_region( surface, graphics_region.get());
149 mtd::DrawPatternCheckered<2,2> draw_pattern1(mt::pattern1);
150 draw_pattern1.draw(graphics_region);
151
152+ mir_surface_swap_buffers_sync(surface);
153+
154 mir_wait_for(mir_surface_release(surface, &create_callback, &surface));
155
156 /* release */
157@@ -168,68 +178,62 @@
158 return 0;
159 }
160
161+ static MirSurface* create_mir_surface(MirConnection * connection, EGLDisplay display, EGLConfig config)
162+ {
163+ int visual_id;
164+ eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &visual_id);
165+
166+ /* make surface */
167+ MirSurfaceParameters surface_parameters;
168+ surface_parameters.name = "testsurface";
169+ surface_parameters.width = test_width;
170+ surface_parameters.height = test_height;
171+ surface_parameters.pixel_format = select_format_for_visual_id(visual_id);
172+ return mir_connection_create_surface_sync(connection, &surface_parameters);
173+ }
174+
175 static int render_accelerated()
176 {
177 if (signal(SIGCONT, sig_handle) == SIG_ERR)
178 return -1;
179 pause();
180
181- /* only use C api */
182- MirConnection* connection = NULL;
183- MirSurface* surface;
184- MirSurfaceParameters surface_parameters;
185-
186- /* establish connection. wait for server to come up */
187- while (connection == NULL)
188- {
189- mir_wait_for(mir_connect("./test_socket_surface", "test_renderer",
190- &connected_callback, &connection));
191- std::this_thread::sleep_for(std::chrono::milliseconds(10));
192- }
193- /* make surface */
194- surface_parameters.name = "testsurface";
195- surface_parameters.width = test_width;
196- surface_parameters.height = test_height;
197- surface_parameters.pixel_format = mir_pixel_format_abgr_8888;
198-
199- mir_wait_for(mir_connection_create_surface(connection,
200- &surface_parameters,
201- &create_callback,
202- &surface));
203-
204 int major, minor, n;
205- EGLDisplay disp;
206 EGLContext context;
207 EGLSurface egl_surface;
208 EGLConfig egl_config;
209 EGLint attribs[] = {
210 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
211- EGL_GREEN_SIZE, 8,
212+ EGL_BUFFER_SIZE, 32,
213 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
214 EGL_NONE };
215 EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
216
217- EGLNativeDisplayType native_display = (EGLNativeDisplayType)mir_connection_get_egl_native_display(connection);
218- EGLNativeWindowType native_window = (EGLNativeWindowType) mir_surface_get_egl_native_window(surface);
219-
220- disp = eglGetDisplay(native_display);
221- eglInitialize(disp, &major, &minor);
222-
223- eglChooseConfig(disp, attribs, &egl_config, 1, &n);
224- egl_surface = eglCreateWindowSurface(disp, egl_config, native_window, NULL);
225- context = eglCreateContext(disp, egl_config, EGL_NO_CONTEXT, context_attribs);
226- eglMakeCurrent(disp, egl_surface, egl_surface, context);
227+ auto connection = mir_connect_sync("./test_socket_surface", "test_renderer");
228+
229+ auto native_display = mir_connection_get_egl_native_display(connection);
230+ auto egl_display = eglGetDisplay(native_display);
231+ eglInitialize(egl_display, &major, &minor);
232+ eglChooseConfig(egl_display, attribs, &egl_config, 1, &n);
233+
234+ auto mir_surface = create_mir_surface(connection, egl_display, egl_config);
235+ auto native_window = static_cast<EGLNativeWindowType>(
236+ mir_surface_get_egl_native_window(mir_surface));
237+
238+ egl_surface = eglCreateWindowSurface(egl_display, egl_config, native_window, NULL);
239+ context = eglCreateContext(egl_display, egl_config, EGL_NO_CONTEXT, context_attribs);
240+ eglMakeCurrent(egl_display, egl_surface, egl_surface, context);
241
242 glClearColor(1.0, 0.0, 0.0, 1.0);
243 glClear(GL_COLOR_BUFFER_BIT);
244
245- eglSwapBuffers(disp, egl_surface);
246- mir_wait_for(mir_surface_release(surface, &create_callback, &surface));
247+ eglSwapBuffers(egl_display, egl_surface);
248+
249+ mir_surface_release_sync(mir_surface);
250
251 /* release */
252 mir_connection_release(connection);
253 return 0;
254-
255 }
256
257 static int render_accelerated_double()
258@@ -238,68 +242,46 @@
259 return -1;
260 pause();
261
262- /* only use C api */
263- MirConnection* connection = NULL;
264- MirSurface* surface;
265- MirSurfaceParameters surface_parameters;
266-
267- /* establish connection. wait for server to come up */
268- while (connection == NULL)
269- {
270- mir_wait_for(mir_connect("./test_socket_surface", "test_renderer",
271- &connected_callback, &connection));
272- std::this_thread::sleep_for(std::chrono::milliseconds(10));
273- }
274- /* make surface */
275- surface_parameters.name = "testsurface";
276- surface_parameters.width = test_width;
277- surface_parameters.height = test_height;
278- surface_parameters.pixel_format = mir_pixel_format_abgr_8888;
279-
280- mir_wait_for(mir_connection_create_surface(connection,
281- &surface_parameters,
282- &create_callback,
283- &surface));
284-
285 int major, minor, n;
286- EGLDisplay disp;
287 EGLContext context;
288 EGLSurface egl_surface;
289 EGLConfig egl_config;
290 EGLint attribs[] = {
291 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
292- EGL_GREEN_SIZE, 8,
293+ EGL_BUFFER_SIZE, 32,
294 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
295 EGL_NONE };
296 EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
297
298- EGLNativeDisplayType native_display = (EGLNativeDisplayType)mir_connection_get_egl_native_display(connection);
299- EGLNativeWindowType native_window = (EGLNativeWindowType)mir_surface_get_egl_native_window(surface);
300-
301- disp = eglGetDisplay(native_display);
302- eglInitialize(disp, &major, &minor);
303-
304- eglChooseConfig(disp, attribs, &egl_config, 1, &n);
305- egl_surface = eglCreateWindowSurface(disp, egl_config, native_window, NULL);
306- context = eglCreateContext(disp, egl_config, EGL_NO_CONTEXT, context_attribs);
307- eglMakeCurrent(disp, egl_surface, egl_surface, context);
308-
309+ auto connection = mir_connect_sync("./test_socket_surface", "test_renderer");
310+
311+ auto native_display = mir_connection_get_egl_native_display(connection);
312+ auto egl_display = eglGetDisplay(native_display);
313+ eglInitialize(egl_display, &major, &minor);
314+ eglChooseConfig(egl_display, attribs, &egl_config, 1, &n);
315+
316+ auto mir_surface = create_mir_surface(connection, egl_display, egl_config);
317+ auto native_window = static_cast<EGLNativeWindowType>(
318+ mir_surface_get_egl_native_window(mir_surface));
319+
320+ egl_surface = eglCreateWindowSurface(egl_display, egl_config, native_window, NULL);
321+ context = eglCreateContext(egl_display, egl_config, EGL_NO_CONTEXT, context_attribs);
322+ eglMakeCurrent(egl_display, egl_surface, egl_surface, context);
323+
324+ //draw red
325 glClearColor(1.0, 0.0, 0.0, 1.0);
326 glClear(GL_COLOR_BUFFER_BIT);
327-
328- eglSwapBuffers(disp, egl_surface);
329-
330+ eglSwapBuffers(egl_display, egl_surface);
331+
332+ //draw green
333 glClearColor(0.0, 1.0, 0.0, 1.0);
334 glClear(GL_COLOR_BUFFER_BIT);
335-
336- eglSwapBuffers(disp, egl_surface);
337-
338- mir_wait_for(mir_surface_release(surface, &create_callback, &surface));
339-
340- /* release */
341+ eglSwapBuffers(egl_display, egl_surface);
342+
343+ mir_surface_release_sync(mir_surface);
344+
345 mir_connection_release(connection);
346 return 0;
347-
348 }
349
350 static int exit_function()
351@@ -311,13 +293,13 @@
352 /* server code */
353 struct StubServerGenerator : public mt::StubServerTool
354 {
355- StubServerGenerator(std::shared_ptr<MirNativeBuffer> const& handle, int id)
356- : handle(handle),
357- next_received(false),
358- next_allowed(false),
359- handle_id(id)
360+ StubServerGenerator(std::shared_ptr<MirNativeBuffer> const& handle0,
361+ std::shared_ptr<MirNativeBuffer> const& handle1)
362+ : handle0(handle0),
363+ handle1(handle1),
364+ next_buffer_count(0),
365+ buffer_count(2)
366 {
367-
368 }
369
370 void create_surface(google::protobuf::RpcController* /*controller*/,
371@@ -325,18 +307,21 @@
372 mir::protobuf::Surface* response,
373 google::protobuf::Closure* done)
374 {
375- response->mutable_id()->set_value(13); // TODO distinct numbers & tracking
376+ auto next_handle = get_next_handle();
377+
378+ response->mutable_id()->set_value(13); //surface id
379 response->set_width(test_width);
380 response->set_height(test_height);
381+ surface_pf = geom::PixelFormat(request->pixel_format());
382 response->set_pixel_format(request->pixel_format());
383- response->mutable_buffer()->set_buffer_id(handle_id);
384- response->mutable_buffer()->set_stride(handle->stride);
385+ response->mutable_buffer()->set_buffer_id(next_buffer_count % buffer_count);
386+ response->mutable_buffer()->set_stride(next_handle->stride);
387
388 response->mutable_buffer()->set_fds_on_side_channel(1);
389- native_handle_t const* native_handle = handle->handle;
390- for(auto i=0; i<native_handle->numFds; i++)
391+ native_handle_t const* native_handle = next_handle->handle;
392+ for(auto i=0; i < native_handle->numFds; i++)
393 response->mutable_buffer()->add_fd(native_handle->data[i]);
394- for(auto i=0; i<native_handle->numInts; i++)
395+ for(auto i=0; i < native_handle->numInts; i++)
396 response->mutable_buffer()->add_data(native_handle->data[native_handle->numFds+i]);
397
398 std::unique_lock<std::mutex> lock(guard);
399@@ -352,22 +337,12 @@
400 ::mir::protobuf::Buffer* response,
401 ::google::protobuf::Closure* done)
402 {
403- {
404- std::unique_lock<std::mutex> lk(next_guard);
405- next_received = true;
406- next_cv.notify_all();
407-
408- while (!next_allowed) {
409- allow_cv.wait(lk);
410- }
411- next_allowed = false;
412- }
413-
414- response->set_buffer_id(handle_id);
415+ auto next_handle = get_next_handle();
416+ response->set_buffer_id(next_buffer_count % buffer_count);
417
418 response->set_fds_on_side_channel(1);
419- native_handle_t const* native_handle = handle->handle;
420- response->set_stride(handle->stride);
421+ native_handle_t const* native_handle = next_handle->handle;
422+ response->set_stride(next_handle->stride);
423 for(auto i=0; i<native_handle->numFds; i++)
424 response->add_fd(native_handle->data[i]);
425 for(auto i=0; i<native_handle->numInts; i++)
426@@ -376,41 +351,46 @@
427 done->Run();
428 }
429
430- void wait_on_next_buffer()
431- {
432- std::unique_lock<std::mutex> lk(next_guard);
433- while (!next_received)
434- next_cv.wait(lk);
435- next_received = false;
436- }
437-
438- void allow_next_continue()
439- {
440- std::unique_lock<std::mutex> lk(next_guard);
441- next_allowed = true;
442- allow_cv.notify_all();
443- lk.unlock();
444- }
445-
446- void set_handle(std::shared_ptr<MirNativeBuffer> const& pack, int id)
447- {
448- handle = pack;
449- handle_id = id;
450+ std::shared_ptr<MirNativeBuffer> get_next_handle()
451+ {
452+ std::swap(handle0, handle1);
453+ next_buffer_count++;
454+ return handle0;
455+ }
456+
457+ std::shared_ptr<MirNativeBuffer> second_to_last_returned()
458+ {
459+ return handle0;
460+ }
461+
462+ std::shared_ptr<MirNativeBuffer> last_returned()
463+ {
464+ return handle1;
465+ }
466+
467+ uint32_t red_value_for_surface()
468+ {
469+ if ((surface_pf == geom::PixelFormat::abgr_8888) || (surface_pf == geom::PixelFormat::xbgr_8888))
470+ return 0xFF0000FF;
471+
472+ if ((surface_pf == geom::PixelFormat::argb_8888) || (surface_pf == geom::PixelFormat::xrgb_8888))
473+ return 0xFFFF0000;
474+
475+ return 0x0;
476+ }
477+
478+ uint32_t green_value_for_surface()
479+ {
480+ return 0xFF00FF00;
481 }
482
483 private:
484- std::shared_ptr<MirNativeBuffer> handle;
485-
486- std::mutex next_guard;
487- std::condition_variable next_cv;
488- std::condition_variable allow_cv;
489- bool next_received;
490- bool next_allowed;
491-
492- int handle_id;
493+ geom::PixelFormat surface_pf; //must be a 32 bit one;
494+ std::shared_ptr<MirNativeBuffer> handle0, handle1;
495+ int next_buffer_count;
496+ int const buffer_count;
497 };
498
499-
500 }
501 }
502
503@@ -429,11 +409,6 @@
504 mt::TestClient::render_double,
505 mt::TestClient::exit_function);
506
507- second_render_with_same_buffer_client_process
508- = mtf::fork_and_run_in_a_different_process(
509- mt::TestClient::render_double,
510- mt::TestClient::exit_function);
511-
512 render_accelerated_process
513 = mtf::fork_and_run_in_a_different_process(
514 mt::TestClient::render_accelerated,
515@@ -448,22 +423,22 @@
516 void SetUp() {
517 ASSERT_FALSE(mtd::is_surface_flinger_running());
518
519- size = geom::Size{test_width, test_height};
520- pf = geom::PixelFormat::abgr_8888;
521+ auto size = geom::Size{test_width, test_height};
522+ auto pf = geom::PixelFormat::argb_8888;
523+
524+ buffer_converter = std::make_shared<mtd::TestGrallocMapper>();
525
526 auto initializer = std::make_shared<mg::NullBufferInitializer>();
527- allocator = std::make_shared<mga::AndroidGraphicBufferAllocator> (initializer);
528+ auto allocator = std::make_shared<mga::AndroidGraphicBufferAllocator> (initializer);
529 mg::BufferProperties properties(size, pf, mg::BufferUsage::hardware);
530- android_buffer = allocator->alloc_buffer(properties);
531- second_android_buffer = allocator->alloc_buffer(properties);
532-
533- buffer_converter = std::make_shared<mtd::TestGrallocMapper>();
534-
535- handle = android_buffer->native_buffer_handle();
536- second_handle = second_android_buffer->native_buffer_handle();
537+ android_buffer0 = allocator->alloc_buffer(properties);
538+ android_buffer1 = allocator->alloc_buffer(properties);
539+
540+ auto handle0 = android_buffer0->native_buffer_handle();
541+ auto handle1 = android_buffer1->native_buffer_handle();
542
543 /* start a server */
544- mock_server = std::make_shared<mt::StubServerGenerator>(handle, 14);
545+ mock_server = std::make_shared<mt::StubServerGenerator>(handle0, handle1);
546 test_server = std::make_shared<mt::TestProtobufServer>("./test_socket_surface", mock_server);
547 test_server->comm->start();
548 }
549@@ -478,29 +453,19 @@
550 std::shared_ptr<mt::TestProtobufServer> test_server;
551 std::shared_ptr<mt::StubServerGenerator> mock_server;
552
553- geom::Size size;
554- geom::PixelFormat pf;
555- mg::BufferID id1;
556- mg::BufferID id2;
557 std::shared_ptr<mtd::TestGrallocMapper> buffer_converter;
558 std::shared_ptr<mtf::Process> client_process;
559
560- std::shared_ptr<MirNativeBuffer> handle;
561- std::shared_ptr<MirNativeBuffer> second_handle;
562-
563- std::shared_ptr<mg::Buffer> android_buffer;
564- std::shared_ptr<mg::Buffer> second_android_buffer;
565- std::shared_ptr<mga::AndroidGraphicBufferAllocator> allocator;
566+ std::shared_ptr<mg::Buffer> android_buffer0;
567+ std::shared_ptr<mg::Buffer> android_buffer1;
568
569 static std::shared_ptr<mtf::Process> render_single_client_process;
570 static std::shared_ptr<mtf::Process> render_double_client_process;
571- static std::shared_ptr<mtf::Process> second_render_with_same_buffer_client_process;
572 static std::shared_ptr<mtf::Process> render_accelerated_process;
573 static std::shared_ptr<mtf::Process> render_accelerated_process_double;
574 };
575 std::shared_ptr<mtf::Process> TestClientIPCRender::render_single_client_process;
576 std::shared_ptr<mtf::Process> TestClientIPCRender::render_double_client_process;
577-std::shared_ptr<mtf::Process> TestClientIPCRender::second_render_with_same_buffer_client_process;
578 std::shared_ptr<mtf::Process> TestClientIPCRender::render_accelerated_process;
579 std::shared_ptr<mtf::Process> TestClientIPCRender::render_accelerated_process_double;
580
581@@ -514,8 +479,8 @@
582 EXPECT_TRUE(render_single_client_process->wait_for_termination().succeeded());
583
584 /* check content */
585- auto region = buffer_converter->graphic_region_from_handle(handle);
586- EXPECT_TRUE(rendered_pattern.check(region));
587+ auto last_handle = mock_server->last_returned();
588+ EXPECT_TRUE(rendered_pattern.check(buffer_converter->graphic_region_from_handle(last_handle)));
589 }
590
591 TEST_F(TestClientIPCRender, test_render_double)
592@@ -525,80 +490,42 @@
593 /* activate client */
594 render_double_client_process->cont();
595
596- /* wait for next buffer */
597- mock_server->wait_on_next_buffer();
598- auto region = buffer_converter->graphic_region_from_handle(handle);
599+ /* wait for client to finish */
600+ EXPECT_TRUE(render_double_client_process->wait_for_termination().succeeded());
601+
602+ auto second_to_last_handle = mock_server->second_to_last_returned();
603+ auto region = buffer_converter->graphic_region_from_handle(second_to_last_handle);
604 EXPECT_TRUE(rendered_pattern0.check(region));
605
606- mock_server->set_handle(second_handle, 15);
607- mock_server->allow_next_continue();
608-
609- /* wait for client to finish */
610- EXPECT_TRUE(render_double_client_process->wait_for_termination().succeeded());
611-
612- auto second_region = buffer_converter->graphic_region_from_handle(second_handle);
613+ auto last_handle = mock_server->last_returned();
614+ auto second_region = buffer_converter->graphic_region_from_handle(last_handle);
615 EXPECT_TRUE(rendered_pattern1.check(second_region));
616 }
617
618-TEST_F(TestClientIPCRender, test_second_render_with_same_buffer)
619-{
620- mtd::DrawPatternCheckered<2,2> rendered_pattern(mt::pattern1);
621- /* activate client */
622- second_render_with_same_buffer_client_process->cont();
623-
624- /* wait for next buffer */
625- mock_server->wait_on_next_buffer();
626- mock_server->allow_next_continue();
627-
628- /* wait for client to finish */
629- EXPECT_TRUE(second_render_with_same_buffer_client_process->wait_for_termination().succeeded());
630-
631- /* check content */
632- auto region = buffer_converter->graphic_region_from_handle(handle);
633- EXPECT_TRUE(rendered_pattern.check(region));
634-}
635-
636 TEST_F(TestClientIPCRender, test_accelerated_render)
637 {
638- mtd::DrawPatternSolid red_pattern(0xFF0000FF);
639-
640- /* activate client */
641 render_accelerated_process->cont();
642-
643- /* wait for next buffer */
644- mock_server->wait_on_next_buffer();
645- mock_server->allow_next_continue();
646-
647- /* wait for client to finish */
648 EXPECT_TRUE(render_accelerated_process->wait_for_termination().succeeded());
649
650 /* check content */
651- auto region = buffer_converter->graphic_region_from_handle(handle);
652- EXPECT_TRUE(red_pattern.check(region));
653+ mtd::DrawPatternSolid red_pattern(mock_server->red_value_for_surface());
654+ auto last_handle = mock_server->last_returned();
655+ EXPECT_TRUE(red_pattern.check(buffer_converter->graphic_region_from_handle(last_handle)));
656 }
657
658 TEST_F(TestClientIPCRender, test_accelerated_render_double)
659 {
660- mtd::DrawPatternSolid red_pattern(0xFF0000FF);
661- mtd::DrawPatternSolid green_pattern(0xFF00FF00);
662- /* activate client */
663 render_accelerated_process_double->cont();
664-
665- /* wait for next buffer */
666- mock_server->wait_on_next_buffer();
667- mock_server->set_handle(second_handle, 15);
668- mock_server->allow_next_continue();
669-
670- mock_server->wait_on_next_buffer();
671- mock_server->allow_next_continue();
672-
673- /* wait for client to finish */
674 EXPECT_TRUE(render_accelerated_process_double->wait_for_termination().succeeded());
675
676 /* check content */
677- auto region = buffer_converter->graphic_region_from_handle(handle);
678+ mtd::DrawPatternSolid red_pattern(mock_server->red_value_for_surface());
679+ auto second_to_last_handle = mock_server->second_to_last_returned();
680+ auto region = buffer_converter->graphic_region_from_handle(second_to_last_handle);
681 EXPECT_TRUE(red_pattern.check(region));
682
683- auto second_region = buffer_converter->graphic_region_from_handle(second_handle);
684+ mtd::DrawPatternSolid green_pattern(mock_server->green_value_for_surface());
685+ auto last_handle = mock_server->last_returned();
686+ auto second_region = buffer_converter->graphic_region_from_handle(last_handle);
687 EXPECT_TRUE(green_pattern.check(second_region));
688 }
689
690=== modified file 'tests/unit-tests/client/android/test_android_native_window.cpp'
691--- tests/unit-tests/client/android/test_android_native_window.cpp 2013-05-16 20:07:39 +0000
692+++ tests/unit-tests/client/android/test_android_native_window.cpp 2013-09-13 21:49:43 +0000
693@@ -288,3 +288,17 @@
694 auto ret = window->dequeueBuffer(window.get(), &tmp, &fencefd);
695 EXPECT_EQ(0, ret);
696 }
697+
698+TEST_F(AndroidNativeWindowTest, native_window_cancel_hook_behavior)
699+{
700+ using namespace testing;
701+ ANativeWindowBuffer buffer;
702+ int fence_fd = 33;
703+
704+ EXPECT_CALL(*mock_driver_interpreter, driver_returns_buffer(&buffer, _))
705+ .Times(1);
706+
707+ std::shared_ptr<ANativeWindow> window = std::make_shared<mga::MirNativeWindow>(mock_driver_interpreter);
708+ auto rc = window->cancelBuffer(window.get(), &buffer, fence_fd);
709+ EXPECT_EQ(0, rc);
710+}
711
712=== modified file 'tests/unit-tests/client/android/test_client_surface_interpreter.cpp'
713--- tests/unit-tests/client/android/test_client_surface_interpreter.cpp 2013-07-01 15:10:36 +0000
714+++ tests/unit-tests/client/android/test_client_surface_interpreter.cpp 2013-09-13 21:49:43 +0000
715@@ -227,3 +227,19 @@
716
717 EXPECT_EQ(surf_params.height, height);
718 }
719+
720+/* this is query key is a bit confusing from the system/window.h description.
721+ what it means is the minimum number of buffers that the server reserves for its own use in steady
722+ state. The drivers consider 'steady state' to begin after the first call to queueBuffer.
723+ So, for instance, if a driver requires 3 buffers to run at steady state, and the server needs
724+ to keep 2 buffers on hand at all time, the driver might dequeue 5 buffers, then cancel those 5 buffers.
725+ After the first call to queueBuffer however, the client may never own more than the number it has
726+ reserved (in this case, 3 buffers) */
727+TEST_F(AndroidInterpreterTest, native_window_minimum_undequeued_query_hook)
728+{
729+ testing::NiceMock<MockMirSurface> mock_surface{surf_params};
730+ mcla::ClientSurfaceInterpreter interpreter(mock_surface);
731+
732+ auto num_buffers = interpreter.driver_requests_info(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS);
733+ EXPECT_EQ(2, num_buffers);
734+}

Subscribers

People subscribed via source and target branches