From c715c750f641c8efc85865694845c8070b93128d Mon Sep 17 00:00:00 2001 From: Alexandros Frantzis Date: Mon, 12 Nov 2018 18:33:54 +0200 Subject: [PATCH] tests: Add tests for per commit zwp_buffer_release_v1 behavior Add tests to check that the zwp_buffer_release_v1 events are emitted per surface commit. To be able to test this we need to use a renderer that holds the buffer until the next buffer is committed, hence we use the pixman renderer. Changes in v7: - Remove references to obsolete noop-hold renderer. Changes in v5: - Meson support. Changes in v4: - Use the pixman renderer instead of the (now gone) noop-hold renderer. Signed-off-by: Alexandros Frantzis --- tests/linux-explicit-synchronization-test.c | 169 +++++++++++++++++++- tests/meson.build | 2 + 2 files changed, 165 insertions(+), 6 deletions(-) diff --git a/tests/linux-explicit-synchronization-test.c b/tests/linux-explicit-synchronization-test.c index 73b1177c..a89b252b 100644 --- a/tests/linux-explicit-synchronization-test.c +++ b/tests/linux-explicit-synchronization-test.c @@ -32,6 +32,11 @@ #include "weston-test-client-helper.h" #include "wayland-server-protocol.h" +/* We need to use the pixman renderer, since a few of the tests depend + * on the renderer holding onto a surface buffer until the next one + * is committed, which the noop renderer doesn't do. */ +char *server_parameters = "--use-pixman"; + static struct zwp_linux_explicit_synchronization_v1 * get_linux_explicit_synchronization(struct client *client) { @@ -276,7 +281,14 @@ struct zwp_linux_buffer_release_v1_listener buffer_release_listener = { buffer_release_immediate_handler }; -TEST(get_release_events_are_emitted) +/* The following release event tests depend on the behavior of the used + * backend, in this case the pixman backend. This doesn't limit their + * usefulness, though, since it allows them to check if, given a typical + * backend implementation, weston core supports the per commit nature of the + * release events. + */ + +TEST(get_release_events_are_emitted_for_different_buffers) { struct client *client = create_test_client(); struct zwp_linux_explicit_synchronization_v1 *sync = @@ -302,8 +314,9 @@ TEST(get_release_events_are_emitted) frame_callback_set(surface, &frame); wl_surface_commit(surface); frame_callback_wait(client, &frame); - /* Check that exactly one buffer_release event was emitted. */ - assert(buf_released1 == 1); + /* No release event should have been emitted yet (we are using the + * pixman renderer, which holds buffers until they are replaced). */ + assert(buf_released1 == 0); buffer_release2 = zwp_linux_surface_synchronization_v1_get_release(surface_sync); @@ -314,10 +327,18 @@ TEST(get_release_events_are_emitted) frame_callback_set(surface, &frame); wl_surface_commit(surface); frame_callback_wait(client, &frame); - /* Check that we didn't get any new events on the inactive - * buffer_release. */ + /* Check that exactly one buffer_release event was emitted for the + * previous commit (buf1). */ + assert(buf_released1 == 1); + assert(buf_released2 == 0); + + wl_surface_attach(surface, buf1->proxy, 0, 0); + frame_callback_set(surface, &frame); + wl_surface_commit(surface); + frame_callback_wait(client, &frame); + /* Check that exactly one buffer_release event was emitted for the + * previous commit (buf2). */ assert(buf_released1 == 1); - /* Check that exactly one buffer_release event was emitted. */ assert(buf_released2 == 1); buffer_destroy(buf2); @@ -327,3 +348,139 @@ TEST(get_release_events_are_emitted) zwp_linux_surface_synchronization_v1_destroy(surface_sync); zwp_linux_explicit_synchronization_v1_destroy(sync); } + +TEST(get_release_events_are_emitted_for_same_buffer_on_surface) +{ + struct client *client = create_test_client(); + struct zwp_linux_explicit_synchronization_v1 *sync = + get_linux_explicit_synchronization(client); + struct zwp_linux_surface_synchronization_v1 *surface_sync = + zwp_linux_explicit_synchronization_v1_get_synchronization( + sync, client->surface->wl_surface); + struct buffer *buf = create_shm_buffer_a8r8g8b8(client, 100, 100); + struct wl_surface *surface = client->surface->wl_surface; + struct zwp_linux_buffer_release_v1 *buffer_release1; + struct zwp_linux_buffer_release_v1 *buffer_release2; + int buf_released1 = 0; + int buf_released2 = 0; + int frame; + + buffer_release1 = + zwp_linux_surface_synchronization_v1_get_release(surface_sync); + zwp_linux_buffer_release_v1_add_listener(buffer_release1, + &buffer_release_listener, + &buf_released1); + wl_surface_attach(surface, buf->proxy, 0, 0); + frame_callback_set(surface, &frame); + wl_surface_commit(surface); + frame_callback_wait(client, &frame); + /* No release event should have been emitted yet (we are using the + * pixman renderer, which holds buffers until they are replaced). */ + assert(buf_released1 == 0); + + buffer_release2 = + zwp_linux_surface_synchronization_v1_get_release(surface_sync); + zwp_linux_buffer_release_v1_add_listener(buffer_release2, + &buffer_release_listener, + &buf_released2); + wl_surface_attach(surface, buf->proxy, 0, 0); + frame_callback_set(surface, &frame); + wl_surface_commit(surface); + frame_callback_wait(client, &frame); + /* Check that exactly one buffer_release event was emitted for the + * previous commit (buf). */ + assert(buf_released1 == 1); + assert(buf_released2 == 0); + + wl_surface_attach(surface, buf->proxy, 0, 0); + frame_callback_set(surface, &frame); + wl_surface_commit(surface); + frame_callback_wait(client, &frame); + /* Check that exactly one buffer_release event was emitted for the + * previous commit (buf again). */ + assert(buf_released1 == 1); + assert(buf_released2 == 1); + + buffer_destroy(buf); + zwp_linux_buffer_release_v1_destroy(buffer_release2); + zwp_linux_buffer_release_v1_destroy(buffer_release1); + zwp_linux_surface_synchronization_v1_destroy(surface_sync); + zwp_linux_explicit_synchronization_v1_destroy(sync); +} + +TEST(get_release_events_are_emitted_for_same_buffer_on_different_surfaces) +{ + struct client *client = create_test_client(); + struct surface *other_surface = create_test_surface(client); + struct wl_surface *surface1 = client->surface->wl_surface; + struct wl_surface *surface2 = other_surface->wl_surface; + struct zwp_linux_explicit_synchronization_v1 *sync = + get_linux_explicit_synchronization(client); + struct zwp_linux_surface_synchronization_v1 *surface_sync1 = + zwp_linux_explicit_synchronization_v1_get_synchronization( + sync, surface1); + struct zwp_linux_surface_synchronization_v1 *surface_sync2 = + zwp_linux_explicit_synchronization_v1_get_synchronization( + sync, surface2); + struct buffer *buf1 = create_shm_buffer_a8r8g8b8(client, 100, 100); + struct buffer *buf2 = create_shm_buffer_a8r8g8b8(client, 100, 100); + struct zwp_linux_buffer_release_v1 *buffer_release1; + struct zwp_linux_buffer_release_v1 *buffer_release2; + int buf_released1 = 0; + int buf_released2 = 0; + int frame; + + weston_test_move_surface(client->test->weston_test, surface2, 0, 0); + + /* Attach buf1 to both surface1 and surface2. */ + buffer_release1 = + zwp_linux_surface_synchronization_v1_get_release(surface_sync1); + zwp_linux_buffer_release_v1_add_listener(buffer_release1, + &buffer_release_listener, + &buf_released1); + wl_surface_attach(surface1, buf1->proxy, 0, 0); + frame_callback_set(surface1, &frame); + wl_surface_commit(surface1); + frame_callback_wait(client, &frame); + + buffer_release2 = + zwp_linux_surface_synchronization_v1_get_release(surface_sync2); + zwp_linux_buffer_release_v1_add_listener(buffer_release2, + &buffer_release_listener, + &buf_released2); + wl_surface_attach(surface2, buf1->proxy, 0, 0); + frame_callback_set(surface2, &frame); + wl_surface_commit(surface2); + frame_callback_wait(client, &frame); + + assert(buf_released1 == 0); + assert(buf_released2 == 0); + + /* Attach buf2 to surface1, and check that a buffer_release event for + * the previous commit (buf1) for that surface is emitted. */ + wl_surface_attach(surface1, buf2->proxy, 0, 0); + frame_callback_set(surface1, &frame); + wl_surface_commit(surface1); + frame_callback_wait(client, &frame); + + assert(buf_released1 == 1); + assert(buf_released2 == 0); + + /* Attach buf2 to surface2, and check that a buffer_release event for + * the previous commit (buf1) for that surface is emitted. */ + wl_surface_attach(surface2, buf2->proxy, 0, 0); + frame_callback_set(surface2, &frame); + wl_surface_commit(surface2); + frame_callback_wait(client, &frame); + + assert(buf_released1 == 1); + assert(buf_released2 == 1); + + buffer_destroy(buf2); + buffer_destroy(buf1); + zwp_linux_buffer_release_v1_destroy(buffer_release2); + zwp_linux_buffer_release_v1_destroy(buffer_release1); + zwp_linux_surface_synchronization_v1_destroy(surface_sync2); + zwp_linux_surface_synchronization_v1_destroy(surface_sync1); + zwp_linux_explicit_synchronization_v1_destroy(sync); +} diff --git a/tests/meson.build b/tests/meson.build index 7baee512..ee24562b 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -310,6 +310,8 @@ foreach t : tests_weston args_t += [ '--width=320' ] args_t += [ '--height=240' ] args_t += [ '--shell=weston-test-desktop-shell.so' ] + elif t.get(0) == 'linux-explicit-synchronization' + args_t += [ '--use-pixman' ] elif t.get(0).startswith('ivi-') args_t += [ '--config=@0@/../ivi-shell/weston-ivi-test.ini'.format(meson.current_build_dir()) ] args_t += [ '--shell=ivi-shell.so' ]