tests/cursor: Add test for transform cursor surfaces

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3859>
This commit is contained in:
Jonas Ådahl 2024-11-22 16:11:33 +01:00 committed by Sebastian Wick
parent 8c2e39323f
commit 5a31b4e7b8
21 changed files with 178 additions and 23 deletions

View File

@ -330,14 +330,16 @@ meta_wait_for_window_cursor (void)
} }
static void static void
test_client_cursor (ClutterStageView *view, test_client_cursor (ClutterStageView *view,
const char *scale_method, const char *scale_method,
MetaCursor cursor, MetaCursor cursor,
const char *ref_test_name, MtkMonitorTransform transform,
int ref_test_seq, const char *ref_test_name,
MetaReftestFlag ref_test_flags) int ref_test_seq,
MetaReftestFlag ref_test_flags)
{ {
const char *cursor_name; const char *cursor_name;
const char *transform_name;
MetaWaylandTestClient *test_client; MetaWaylandTestClient *test_client;
MetaWindow *window; MetaWindow *window;
MetaWindowActor *window_actor; MetaWindowActor *window_actor;
@ -345,11 +347,13 @@ test_client_cursor (ClutterStageView *view,
g_debug ("Testing cursor with client using %s", scale_method); g_debug ("Testing cursor with client using %s", scale_method);
cursor_name = meta_cursor_get_name (cursor); cursor_name = meta_cursor_get_name (cursor);
transform_name = mtk_monitor_transform_to_string (transform);
test_client = test_client =
meta_wayland_test_client_new_with_args (test_context, meta_wayland_test_client_new_with_args (test_context,
"cursor-tests-client", "cursor-tests-client",
scale_method, scale_method,
cursor_name, cursor_name,
transform_name,
NULL); NULL);
meta_wayland_test_driver_wait_for_sync_point (test_driver, 0); meta_wayland_test_driver_wait_for_sync_point (test_driver, 0);
@ -460,11 +464,13 @@ meta_test_native_cursor_scaling (void)
test_client_cursor (view, test_client_cursor (view,
CURSOR_SCALE_METHOD_BUFFER_SCALE, CURSOR_SCALE_METHOD_BUFFER_SCALE,
cursor, cursor,
MTK_MONITOR_TRANSFORM_NORMAL,
ref_test_name, 1, ref_test_name, 1,
meta_ref_test_determine_ref_test_flag ()); meta_ref_test_determine_ref_test_flag ());
test_client_cursor (view, test_client_cursor (view,
CURSOR_SCALE_METHOD_VIEWPORT, CURSOR_SCALE_METHOD_VIEWPORT,
cursor, cursor,
MTK_MONITOR_TRANSFORM_NORMAL,
ref_test_name, 0, ref_test_name, 0,
META_REFTEST_FLAG_NONE); META_REFTEST_FLAG_NONE);
} }
@ -540,6 +546,7 @@ meta_test_native_cursor_cropping (void)
test_client_cursor (view, test_client_cursor (view,
CURSOR_SCALE_METHOD_VIEWPORT_CROPPED, CURSOR_SCALE_METHOD_VIEWPORT_CROPPED,
META_CURSOR_MOVE_OR_RESIZE_WINDOW, META_CURSOR_MOVE_OR_RESIZE_WINDOW,
MTK_MONITOR_TRANSFORM_NORMAL,
ref_test_name, 0, ref_test_name, 0,
meta_ref_test_determine_ref_test_flag ()); meta_ref_test_determine_ref_test_flag ());
} }
@ -547,6 +554,100 @@ meta_test_native_cursor_cropping (void)
clutter_actor_destroy (overlay_actor); clutter_actor_destroy (overlay_actor);
} }
static void
meta_test_native_cursor_transform (void)
{
MetaBackend *backend = meta_context_get_backend (test_context);
MetaDisplay *display = meta_context_get_display (test_context);
ClutterSeat *seat = meta_backend_get_default_seat (backend);
g_autoptr (ClutterVirtualInputDevice) virtual_pointer = NULL;
ClutterActor *overlay_actor;
ClutterStageView *view;
struct {
int width;
int height;
float scale;
MetaLogicalMonitorLayoutMode layout_mode;
MtkMonitorTransform transform;
} test_cases[] = {
{
.width = 1920, .height = 1080, .scale = 1.0,
.layout_mode = META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL,
.transform = MTK_MONITOR_TRANSFORM_90,
},
{
.width = 1920, .height = 1080, .scale = 1.0,
.layout_mode = META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL,
.transform = MTK_MONITOR_TRANSFORM_90,
},
{
.width = 1920, .height = 1080, .scale = 2.0,
.layout_mode = META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL,
.transform = MTK_MONITOR_TRANSFORM_90,
},
{
.width = 1920, .height = 1080, .scale = 2.0,
.layout_mode = META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL,
.transform = MTK_MONITOR_TRANSFORM_90,
},
{
.width = 1440, .height = 900, .scale = 1.5,
.layout_mode = META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL,
},
{
.width = 1440, .height = 900, .scale = 2.25,
.layout_mode = META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL,
.transform = MTK_MONITOR_TRANSFORM_270,
},
};
int i;
meta_display_set_cursor (display, META_CURSOR_DEFAULT);
virtual_pointer = clutter_seat_create_virtual_device (seat,
CLUTTER_POINTER_DEVICE);
overlay_actor = create_overlay_actor ();
for (i = 0; i < G_N_ELEMENTS (test_cases); i++)
{
g_autofree char *ref_test_name = NULL;
g_debug ("Testing monitor resolution %dx%d with scale %f and "
"%s layout mode",
test_cases[i].width, test_cases[i].height, test_cases[i].scale,
layout_mode_to_string (test_cases[i].layout_mode));
wait_for_no_windows ();
ref_test_name = g_strdup_printf ("%s/%d", g_test_get_path (), i);
view = setup_test_case (test_cases[i].width, test_cases[i].height,
test_cases[i].scale,
test_cases[i].layout_mode,
virtual_pointer);
test_client_cursor (view,
CURSOR_SCALE_METHOD_BUFFER_SCALE,
META_CURSOR_DEFAULT,
test_cases[i].transform,
ref_test_name, 0,
meta_ref_test_determine_ref_test_flag ());
test_client_cursor (view,
CURSOR_SCALE_METHOD_VIEWPORT,
META_CURSOR_DEFAULT,
test_cases[i].transform,
ref_test_name, 1,
meta_ref_test_determine_ref_test_flag ());
test_client_cursor (view,
CURSOR_SCALE_METHOD_VIEWPORT_CROPPED,
META_CURSOR_MOVE_OR_RESIZE_WINDOW,
test_cases[i].transform,
ref_test_name, 2,
meta_ref_test_determine_ref_test_flag ());
}
clutter_actor_destroy (overlay_actor);
}
static void static void
init_tests (void) init_tests (void)
{ {
@ -554,6 +655,8 @@ init_tests (void)
meta_test_native_cursor_scaling); meta_test_native_cursor_scaling);
g_test_add_func ("/backends/native/cursor/cropping", g_test_add_func ("/backends/native/cursor/cropping",
meta_test_native_cursor_cropping); meta_test_native_cursor_cropping);
g_test_add_func ("/backends/native/cursor/transform",
meta_test_native_cursor_transform);
} }
static void static void

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@ -20,6 +20,7 @@
#include <wayland-cursor.h> #include <wayland-cursor.h>
#include "mtk/mtk.h"
#include "wayland-test-client-utils.h" #include "wayland-test-client-utils.h"
typedef enum _CursorScaleMethod typedef enum _CursorScaleMethod
@ -31,6 +32,33 @@ typedef enum _CursorScaleMethod
static CursorScaleMethod scale_method; static CursorScaleMethod scale_method;
static char *cursor_name; static char *cursor_name;
static MtkMonitorTransform cursor_transform;
static enum wl_output_transform
wl_output_transform_from_monitor_transform (MtkMonitorTransform transform)
{
switch (transform)
{
case MTK_MONITOR_TRANSFORM_NORMAL:
return WL_OUTPUT_TRANSFORM_NORMAL;
case MTK_MONITOR_TRANSFORM_90:
return WL_OUTPUT_TRANSFORM_90;
case MTK_MONITOR_TRANSFORM_180:
return WL_OUTPUT_TRANSFORM_180;
case MTK_MONITOR_TRANSFORM_270:
return WL_OUTPUT_TRANSFORM_270;
case MTK_MONITOR_TRANSFORM_FLIPPED:
return WL_OUTPUT_TRANSFORM_FLIPPED;
case MTK_MONITOR_TRANSFORM_FLIPPED_90:
return WL_OUTPUT_TRANSFORM_FLIPPED_90;
case MTK_MONITOR_TRANSFORM_FLIPPED_180:
return WL_OUTPUT_TRANSFORM_FLIPPED_180;
case MTK_MONITOR_TRANSFORM_FLIPPED_270:
return WL_OUTPUT_TRANSFORM_FLIPPED_270;
}
g_assert_not_reached ();
}
static struct wl_surface *cursor_surface; static struct wl_surface *cursor_surface;
static struct wp_viewport *cursor_viewport; static struct wp_viewport *cursor_viewport;
@ -51,8 +79,14 @@ on_pointer_enter (WaylandSurface *surface,
int ceiled_scale; int ceiled_scale;
int effective_theme_size = 0; int effective_theme_size = 0;
float image_scale; float image_scale;
int image_width;
int image_height;
int image_hotspot_x;
int image_hotspot_y;
MtkMonitorTransform hotspot_transform;
int hotspot_x = 0; int hotspot_x = 0;
int hotspot_y = 0; int hotspot_y = 0;
enum wl_output_transform buffer_transform;
if (!cursor_surface) if (!cursor_surface)
cursor_surface = wl_compositor_create_surface (display->compositor); cursor_surface = wl_compositor_create_surface (display->compositor);
@ -103,30 +137,45 @@ on_pointer_enter (WaylandSurface *surface,
image_scale = ((float) image->width / theme_size); image_scale = ((float) image->width / theme_size);
image_width = image->width;
image_height = image->height;
image_hotspot_x = image->hotspot_x;
image_hotspot_y = image->hotspot_y;
hotspot_transform = mtk_monitor_transform_invert (cursor_transform);
mtk_monitor_transform_transform_point (hotspot_transform,
&image_width,
&image_height,
&image_hotspot_x,
&image_hotspot_y);
switch (scale_method) switch (scale_method)
{ {
case CURSOR_SCALE_METHOD_BUFFER_SCALE: case CURSOR_SCALE_METHOD_BUFFER_SCALE:
hotspot_x = (int) roundf (image->hotspot_x / ceiled_scale); hotspot_x = (int) roundf (image_hotspot_x / ceiled_scale);
hotspot_y = (int) roundf (image->hotspot_y / ceiled_scale); hotspot_y = (int) roundf (image_hotspot_y / ceiled_scale);
break; break;
case CURSOR_SCALE_METHOD_VIEWPORT: case CURSOR_SCALE_METHOD_VIEWPORT:
hotspot_x = (int) roundf (image->hotspot_x / image_scale); hotspot_x = (int) roundf (image_hotspot_x / image_scale);
hotspot_y = (int) roundf (image->hotspot_y / image_scale); hotspot_y = (int) roundf (image_hotspot_y / image_scale);
break; break;
case CURSOR_SCALE_METHOD_VIEWPORT_CROPPED: case CURSOR_SCALE_METHOD_VIEWPORT_CROPPED:
hotspot_x = (int) roundf ((image->hotspot_x - hotspot_x = (int) roundf ((image_hotspot_x -
(image->width / 4)) / image_scale); (image_width / 4)) / image_scale);
hotspot_y = (int) roundf ((image->hotspot_y - hotspot_y = (int) roundf ((image_hotspot_y -
(image->height / 4)) / image_scale); (image_height / 4)) / image_scale);
break; break;
} }
buffer_transform =
wl_output_transform_from_monitor_transform (cursor_transform);
wl_surface_set_buffer_transform (cursor_surface, buffer_transform);
wl_pointer_set_cursor (pointer, serial, wl_pointer_set_cursor (pointer, serial,
cursor_surface, cursor_surface,
hotspot_x, hotspot_y); hotspot_x, hotspot_y);
wl_surface_attach (cursor_surface, buffer, 0, 0); wl_surface_attach (cursor_surface, buffer, 0, 0);
wl_surface_damage_buffer (cursor_surface, 0, 0, wl_surface_damage_buffer (cursor_surface, 0, 0,
image->width, image->height); image_width, image_height);
switch (scale_method) switch (scale_method)
{ {
@ -136,18 +185,18 @@ on_pointer_enter (WaylandSurface *surface,
break; break;
case CURSOR_SCALE_METHOD_VIEWPORT: case CURSOR_SCALE_METHOD_VIEWPORT:
wp_viewport_set_destination (cursor_viewport, wp_viewport_set_destination (cursor_viewport,
(int) roundf (image->width / image_scale), (int) roundf (image_width / image_scale),
(int) roundf (image->height / image_scale)); (int) roundf (image_height / image_scale));
break; break;
case CURSOR_SCALE_METHOD_VIEWPORT_CROPPED: case CURSOR_SCALE_METHOD_VIEWPORT_CROPPED:
wp_viewport_set_source (cursor_viewport, wp_viewport_set_source (cursor_viewport,
wl_fixed_from_int (image->width / 4), wl_fixed_from_int (image_width / 4),
wl_fixed_from_int (image->height / 4), wl_fixed_from_int (image_height / 4),
wl_fixed_from_int (image->width / 2), wl_fixed_from_int (image_width / 2),
wl_fixed_from_int (image->height / 2)); wl_fixed_from_int (image_height / 2));
wp_viewport_set_destination (cursor_viewport, wp_viewport_set_destination (cursor_viewport,
(int) roundf (image->width / 2 / image_scale), (int) roundf (image_width / 2 / image_scale),
(int) roundf (image->height / 2 / image_scale)); (int) roundf (image_height / 2 / image_scale));
break; break;
} }
@ -175,6 +224,7 @@ main (int argc,
g_error ("Missing scale method"); g_error ("Missing scale method");
cursor_name = argv[2]; cursor_name = argv[2];
cursor_transform = mtk_monitor_transform_from_string (argv[3]);
display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER); display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER);
surface = wayland_surface_new (display, surface = wayland_surface_new (display,

View File

@ -106,6 +106,7 @@ wayland_test_clients = [
'name': 'cursor-tests-client', 'name': 'cursor-tests-client',
'extra_deps': [ 'extra_deps': [
wayland_cursor_dep, wayland_cursor_dep,
libmutter_mtk_dep,
], ],
}, },
] ]
@ -141,6 +142,7 @@ foreach test : wayland_test_clients
dependencies: deps, dependencies: deps,
install: have_installed_tests, install: have_installed_tests,
install_dir: wayland_test_client_installed_tests_libexecdir, install_dir: wayland_test_client_installed_tests_libexecdir,
install_rpath: pkglibdir,
) )
test_client_executables += { test['name']: test_executable } test_client_executables += { test['name']: test_executable }