diff --git a/src/tests/ref-tests/wayland_buffer_single_pixel_buffer_0.ref.png b/src/tests/ref-tests/wayland_buffer_single_pixel_buffer_0.ref.png new file mode 100644 index 000000000..4cf29195d Binary files /dev/null and b/src/tests/ref-tests/wayland_buffer_single_pixel_buffer_0.ref.png differ diff --git a/src/tests/ref-tests/wayland_buffer_single_pixel_buffer_1.ref.png b/src/tests/ref-tests/wayland_buffer_single_pixel_buffer_1.ref.png new file mode 100644 index 000000000..c35e23bf1 Binary files /dev/null and b/src/tests/ref-tests/wayland_buffer_single_pixel_buffer_1.ref.png differ diff --git a/src/tests/ref-tests/wayland_buffer_single_pixel_buffer_2.ref.png b/src/tests/ref-tests/wayland_buffer_single_pixel_buffer_2.ref.png new file mode 100644 index 000000000..083750c84 Binary files /dev/null and b/src/tests/ref-tests/wayland_buffer_single_pixel_buffer_2.ref.png differ diff --git a/src/tests/ref-tests/wayland_buffer_single_pixel_buffer_3.ref.png b/src/tests/ref-tests/wayland_buffer_single_pixel_buffer_3.ref.png new file mode 100644 index 000000000..61cb65d1a Binary files /dev/null and b/src/tests/ref-tests/wayland_buffer_single_pixel_buffer_3.ref.png differ diff --git a/src/tests/ref-tests/wayland_buffer_single_pixel_buffer_4.ref.png b/src/tests/ref-tests/wayland_buffer_single_pixel_buffer_4.ref.png new file mode 100644 index 000000000..3153e6d76 Binary files /dev/null and b/src/tests/ref-tests/wayland_buffer_single_pixel_buffer_4.ref.png differ diff --git a/src/tests/ref-tests/wayland_buffer_single_pixel_buffer_5.ref.png b/src/tests/ref-tests/wayland_buffer_single_pixel_buffer_5.ref.png new file mode 100644 index 000000000..06373fd95 Binary files /dev/null and b/src/tests/ref-tests/wayland_buffer_single_pixel_buffer_5.ref.png differ diff --git a/src/tests/ref-tests/wayland_buffer_single_pixel_buffer_6.ref.png b/src/tests/ref-tests/wayland_buffer_single_pixel_buffer_6.ref.png new file mode 100644 index 000000000..0d2cac218 Binary files /dev/null and b/src/tests/ref-tests/wayland_buffer_single_pixel_buffer_6.ref.png differ diff --git a/src/tests/wayland-test-clients/meson.build b/src/tests/wayland-test-clients/meson.build index 6633b56f4..0610f3cc5 100644 --- a/src/tests/wayland-test-clients/meson.build +++ b/src/tests/wayland-test-clients/meson.build @@ -49,6 +49,9 @@ wayland_test_clients = [ { 'name': 'buffer-transform', }, + { + 'name': 'single-pixel-buffer', + }, { 'name': 'subsurface-remap-toplevel', }, diff --git a/src/tests/wayland-test-clients/single-pixel-buffer.c b/src/tests/wayland-test-clients/single-pixel-buffer.c new file mode 100644 index 000000000..ed98939a3 --- /dev/null +++ b/src/tests/wayland-test-clients/single-pixel-buffer.c @@ -0,0 +1,270 @@ +/* + * Copyright (C) 2022 Collabora, Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "config.h" + +#include +#include + +#include "wayland-test-client-utils.h" + +static WaylandDisplay *display; +static struct wl_surface *surface; +static struct xdg_surface *xdg_surface; +static struct xdg_toplevel *xdg_toplevel; +static struct wl_buffer *buffer; +static struct wl_surface *subsurface_surface; +static struct wl_subsurface *subsurface; + +static gboolean waiting_for_configure = FALSE; +static gboolean fullscreen = 0; +static uint32_t window_width = 0; +static uint32_t window_height = 0; + +static void +handle_xdg_toplevel_configure (void *data, + struct xdg_toplevel *xdg_toplevel, + int32_t width, + int32_t height, + struct wl_array *states) +{ + uint32_t *p; + + fullscreen = 0; + wl_array_for_each(p, states) + { + uint32_t state = *p; + + switch (state) + { + case XDG_TOPLEVEL_STATE_FULLSCREEN: + fullscreen = 1; + break; + } + } + + if (width > 0 && height > 0) + { + window_width = width; + window_height = height; + } +} + +static void +handle_xdg_toplevel_close(void *data, + struct xdg_toplevel *xdg_toplevel) +{ + g_assert_not_reached (); +} + +static const struct xdg_toplevel_listener xdg_toplevel_listener = { + handle_xdg_toplevel_configure, + handle_xdg_toplevel_close, +}; + +static void +handle_xdg_surface_configure (void *data, + struct xdg_surface *xdg_surface, + uint32_t serial) +{ + xdg_surface_ack_configure (xdg_surface, serial); + + waiting_for_configure = FALSE; +} + +static const struct xdg_surface_listener xdg_surface_listener = { + handle_xdg_surface_configure, +}; + +static void +wait_for_configure (void) +{ + waiting_for_configure = TRUE; + while (waiting_for_configure || window_width == 0) + { + if (wl_display_dispatch (display->display) == -1) + exit (EXIT_FAILURE); + } +} + +static void +handle_buffer_release (void *data, + struct wl_buffer *callback_buffer) +{ + g_assert (callback_buffer == buffer); + g_clear_pointer (&buffer, wl_buffer_destroy); +} + +static const struct wl_buffer_listener buffer_listener = { + handle_buffer_release +}; + +static void +wait_for_buffer_released (void) +{ + while (buffer) + { + if (wl_display_dispatch (display->display) == -1) + g_error ("%s: Failed to dispatch Wayland display", __func__); + } +} + +int +main (int argc, + char **argv) +{ + struct wp_viewport *viewport; + struct wp_viewport *subsurface_viewport; + + display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER); + + surface = wl_compositor_create_surface (display->compositor); + xdg_surface = xdg_wm_base_get_xdg_surface (display->xdg_wm_base, surface); + xdg_surface_add_listener (xdg_surface, &xdg_surface_listener, NULL); + xdg_toplevel = xdg_surface_get_toplevel (xdg_surface); + xdg_toplevel_add_listener (xdg_toplevel, &xdg_toplevel_listener, NULL); + + xdg_toplevel_set_fullscreen (xdg_toplevel, NULL); + wl_surface_commit (surface); + wait_for_configure (); + + viewport = wp_viewporter_get_viewport (display->viewporter, surface); + wp_viewport_set_destination (viewport, window_width, window_height); + + buffer = + wp_single_pixel_buffer_manager_v1_create_u32_rgba_buffer (display->single_pixel_mgr, + 0xffffffff, + 0xffffffff, + 0xffffffff, + 0xffffffff); + wl_buffer_add_listener (buffer, &buffer_listener, NULL); + wl_surface_attach (surface, buffer, 0, 0); + wl_surface_commit (surface); + wait_for_effects_completed (display, surface); + wait_for_view_verified (display, 0); + + wait_for_buffer_released (); + + subsurface_surface = wl_compositor_create_surface (display->compositor); + subsurface = wl_subcompositor_get_subsurface (display->subcompositor, + subsurface_surface, + surface); + wl_subsurface_set_desync (subsurface); + wl_subsurface_set_position (subsurface, 20, 20); + wl_surface_commit (surface); + + subsurface_viewport = wp_viewporter_get_viewport (display->viewporter, + subsurface_surface); + wp_viewport_set_destination (subsurface_viewport, + window_width - 40, + window_height - 40); + + buffer = + wp_single_pixel_buffer_manager_v1_create_u32_rgba_buffer (display->single_pixel_mgr, + 0x00000000, + 0x00000000, + 0x00000000, + 0xffffffff); + wl_buffer_add_listener (buffer, &buffer_listener, NULL); + wl_surface_attach (subsurface_surface, buffer, 0, 0); + wl_surface_commit (subsurface_surface); + wait_for_view_verified (display, 1); + + wait_for_buffer_released (); + + buffer = + wp_single_pixel_buffer_manager_v1_create_u32_rgba_buffer (display->single_pixel_mgr, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000); + wl_buffer_add_listener (buffer, &buffer_listener, NULL); + wl_surface_attach (subsurface_surface, buffer, 0, 0); + wl_surface_commit (subsurface_surface); + wait_for_view_verified (display, 0); + + wait_for_buffer_released (); + + buffer = + wp_single_pixel_buffer_manager_v1_create_u32_rgba_buffer (display->single_pixel_mgr, + 0xffffffff, + 0x00000000, + 0x00000000, + 0xffffffff); + wl_buffer_add_listener (buffer, &buffer_listener, NULL); + wl_surface_attach (subsurface_surface, buffer, 0, 0); + wl_surface_commit (subsurface_surface); + wait_for_view_verified (display, 2); + + wait_for_buffer_released (); + + buffer = + wp_single_pixel_buffer_manager_v1_create_u32_rgba_buffer (display->single_pixel_mgr, + 0x00000000, + 0xffffffff, + 0x00000000, + 0xffffffff); + wl_buffer_add_listener (buffer, &buffer_listener, NULL); + wl_surface_attach (subsurface_surface, buffer, 0, 0); + wl_surface_commit (subsurface_surface); + wait_for_view_verified (display, 3); + + wait_for_buffer_released (); + + buffer = + wp_single_pixel_buffer_manager_v1_create_u32_rgba_buffer (display->single_pixel_mgr, + 0x00000000, + 0x00000000, + 0xffffffff, + 0xffffffff); + wl_buffer_add_listener (buffer, &buffer_listener, NULL); + wl_surface_attach (subsurface_surface, buffer, 0, 0); + wl_surface_commit (subsurface_surface); + wait_for_view_verified (display, 4); + + wait_for_buffer_released (); + + buffer = + wp_single_pixel_buffer_manager_v1_create_u32_rgba_buffer (display->single_pixel_mgr, + 0x80808080, + 0x00000000, + 0x80808080, + 0xffffffff); + wl_buffer_add_listener (buffer, &buffer_listener, NULL); + wl_surface_attach (subsurface_surface, buffer, 0, 0); + wl_surface_commit (subsurface_surface); + wait_for_view_verified (display, 5); + + wait_for_buffer_released (); + + buffer = + wp_single_pixel_buffer_manager_v1_create_u32_rgba_buffer (display->single_pixel_mgr, + 0x80808080, + 0x00000000, + 0x80808080, + 0x80808080); + wl_buffer_add_listener (buffer, &buffer_listener, NULL); + wl_surface_attach (subsurface_surface, buffer, 0, 0); + wl_surface_commit (subsurface_surface); + wait_for_view_verified (display, 6); + + wait_for_buffer_released (); + + g_clear_object (&display); + + return EXIT_SUCCESS; +} diff --git a/src/tests/wayland-test-clients/wayland-test-client-utils.c b/src/tests/wayland-test-clients/wayland-test-client-utils.c index 7cbe5f4fd..d00a2fb5b 100644 --- a/src/tests/wayland-test-clients/wayland-test-client-utils.c +++ b/src/tests/wayland-test-clients/wayland-test-client-utils.c @@ -166,6 +166,17 @@ handle_registry_global (void *user_data, display->shm = wl_registry_bind (registry, id, &wl_shm_interface, 1); } + else if (strcmp (interface, "wp_single_pixel_buffer_manager_v1") == 0) + { + display->single_pixel_mgr = + wl_registry_bind (registry, id, + &wp_single_pixel_buffer_manager_v1_interface, 1); + } + else if (strcmp (interface, "wp_viewporter") == 0) + { + display->viewporter = wl_registry_bind (registry, id, + &wp_viewporter_interface, 1); + } else if (strcmp (interface, "xdg_wm_base") == 0) { int xdg_wm_base_version = 1; @@ -227,6 +238,8 @@ wayland_display_new (WaylandDisplayCapabilities capabilities) g_assert_nonnull (display->compositor); g_assert_nonnull (display->subcompositor); g_assert_nonnull (display->shm); + g_assert_nonnull (display->single_pixel_mgr); + g_assert_nonnull (display->viewporter); g_assert_nonnull (display->xdg_wm_base); if (capabilities & WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER) diff --git a/src/tests/wayland-test-clients/wayland-test-client-utils.h b/src/tests/wayland-test-clients/wayland-test-client-utils.h index 8d5eda155..114e1098d 100644 --- a/src/tests/wayland-test-clients/wayland-test-client-utils.h +++ b/src/tests/wayland-test-clients/wayland-test-client-utils.h @@ -5,7 +5,9 @@ #include #include +#include "single-pixel-buffer-v1-client-protocol.h" #include "test-driver-client-protocol.h" +#include "viewporter-client-protocol.h" #include "xdg-shell-client-protocol.h" typedef enum _WaylandDisplayCapabilities @@ -25,8 +27,10 @@ typedef struct _WaylandDisplay struct wl_registry *registry; struct wl_compositor *compositor; struct wl_subcompositor *subcompositor; - struct xdg_wm_base *xdg_wm_base; struct wl_shm *shm; + struct wp_single_pixel_buffer_manager_v1 *single_pixel_mgr; + struct wp_viewporter *viewporter; + struct xdg_wm_base *xdg_wm_base; struct test_driver *test_driver; GHashTable *properties; diff --git a/src/tests/wayland-unit-tests.c b/src/tests/wayland-unit-tests.c index 9acbca23c..12dc6d8d3 100644 --- a/src/tests/wayland-unit-tests.c +++ b/src/tests/wayland-unit-tests.c @@ -75,6 +75,16 @@ buffer_transform (void) meta_wayland_test_client_finish (wayland_test_client); } +static void +single_pixel_buffer (void) +{ + MetaWaylandTestClient *wayland_test_client; + + wayland_test_client = + meta_wayland_test_client_new ("single-pixel-buffer"); + meta_wayland_test_client_finish (wayland_test_client); +} + static void subsurface_reparenting (void) { @@ -668,6 +678,8 @@ init_tests (void) { g_test_add_func ("/wayland/buffer/transform", buffer_transform); + g_test_add_func ("/wayland/buffer/single_pixel_buffer", + single_pixel_buffer); g_test_add_func ("/wayland/subsurface/remap-toplevel", subsurface_remap_toplevel); g_test_add_func ("/wayland/subsurface/reparent",