diff --git a/libweston/compositor.c b/libweston/compositor.c index da0a25743..322b7f219 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -90,9 +90,6 @@ #define DEFAULT_REPAINT_WINDOW 7 /* milliseconds */ -static void -weston_output_update_matrix(struct weston_output *output); - static void weston_output_transform_scale_init(struct weston_output *output, uint32_t transform, uint32_t scale); @@ -1854,7 +1851,7 @@ fixed_round_up_to_int(wl_fixed_t f) return wl_fixed_to_int(wl_fixed_from_int(1) - 1 + f); } -static void +WESTON_EXPORT_FOR_TESTS void convert_size_by_transform_scale(int32_t *width_out, int32_t *height_out, int32_t width, int32_t height, uint32_t transform, @@ -3724,7 +3721,7 @@ weston_surface_commit_subsurface_order(struct weston_surface *surface) } } -static void +WESTON_EXPORT_FOR_TESTS void weston_surface_build_buffer_matrix(const struct weston_surface *surface, struct weston_matrix *matrix) { @@ -6248,7 +6245,7 @@ weston_region_global_to_output(pixman_region32_t *dst, weston_matrix_transform_region(dst, &output->matrix, src); } -static void +WESTON_EXPORT_FOR_TESTS void weston_output_update_matrix(struct weston_output *output) { weston_matrix_init(&output->matrix); diff --git a/libweston/libweston-internal.h b/libweston/libweston-internal.h index 34feaf5d0..f387fe88e 100644 --- a/libweston/libweston-internal.h +++ b/libweston/libweston-internal.h @@ -496,6 +496,19 @@ wl_data_device_manager_init(struct wl_display *display); bool weston_output_set_color_outcome(struct weston_output *output); +void +weston_surface_build_buffer_matrix(const struct weston_surface *surface, + struct weston_matrix *matrix); + +void +weston_output_update_matrix(struct weston_output *output); + +void +convert_size_by_transform_scale(int32_t *width_out, int32_t *height_out, + int32_t width, int32_t height, + uint32_t transform, + int32_t scale); + /* User authentication for remote backends */ bool diff --git a/tests/matrix-transform-test.c b/tests/matrix-transform-test.c index a5c995282..be5ea2553 100644 --- a/tests/matrix-transform-test.c +++ b/tests/matrix-transform-test.c @@ -284,3 +284,125 @@ TEST(transformation_matrix) transform_expect(&a, true, WL_OUTPUT_TRANSFORM_NORMAL); assert(!weston_matrix_needs_filtering(&a)); } + +static void +simple_weston_surface_prepare(struct weston_surface *surf, + int buffer_width, int buffer_height, + int surface_width, int surface_height, + int scale, uint32_t transform, + int src_x, int src_y, + int src_width, int src_height) +{ + struct weston_buffer_viewport vp = { + .buffer = { + .transform = transform, + .scale = scale, + .src_x = wl_fixed_from_int(src_x), + .src_y = wl_fixed_from_int(src_y), + .src_width = wl_fixed_from_int(src_width), + .src_height = wl_fixed_from_int(src_height), + }, + .surface = { + .width = surface_width, + .height = surface_height, + }, + }; + surf->buffer_viewport = vp; + convert_size_by_transform_scale(&surf->width_from_buffer, + &surf->height_from_buffer, + buffer_width, + buffer_height, + transform, + scale); + weston_surface_build_buffer_matrix(surf, + &surf->surface_to_buffer_matrix); + weston_matrix_invert(&surf->buffer_to_surface_matrix, + &surf->surface_to_buffer_matrix); +} + +static void +surface_test_all_transforms(struct weston_surface *surf, + int buffer_width, int buffer_height, + int surface_width, int surface_height, + int scale, int src_x, int src_y, + int src_width, int src_height) +{ + int transform; + + for (transform = WL_OUTPUT_TRANSFORM_NORMAL; + transform <= WL_OUTPUT_TRANSFORM_FLIPPED_270; transform++) { + simple_weston_surface_prepare(surf, + buffer_width, buffer_height, + surface_width, surface_height, + scale, transform, + src_x, src_y, + src_width, src_height); + transform_expect(&surf->surface_to_buffer_matrix, + true, transform); + } +} + +TEST(surface_matrix_to_standard_transform) +{ + struct weston_surface surf; + int scale; + + for (scale = 1; scale < 8; scale++) { + /* A simple case */ + surface_test_all_transforms(&surf, 500, 700, -1, -1, scale, + 0, 0, 500, 700); + /* Translate the source corner */ + surface_test_all_transforms(&surf, 500, 700, -1, -1, scale, + 70, 20, 500, 700); + /* Get some scaling (and fractional translation) in there */ + surface_test_all_transforms(&surf, 723, 300, 512, 77, scale, + 120, 10, 200, 200); + } +} + +static void +simple_weston_output_prepare(struct weston_output *output, + int x, int y, int width, int height, + int scale, uint32_t transform) +{ + output->x = x; + output->y = y; + output->width = width; + output->height = height; + output->current_scale = scale; + output->transform = transform; + weston_output_update_matrix(output); +} + +static void +output_test_all_transforms(struct weston_output *output, + int x, int y, int width, int height, int scale) +{ + int transform; + + for (transform = WL_OUTPUT_TRANSFORM_NORMAL; + transform <= WL_OUTPUT_TRANSFORM_FLIPPED_270; transform++) { + simple_weston_output_prepare(output, x, y, width, height, + scale, transform); + /* The inverse matrix takes us from output to global space, + * which makes it the one that will have the expected + * standard transform. + */ + transform_expect(&output->matrix, true, transform); + } +} + +TEST(output_matrix_to_standard_transform) +{ + struct weston_output output; + int scale; + + /* Just a few arbitrary sizes and positions to make sure we have + * scales and translations. + */ + for (scale = 1; scale < 8; scale++) { + output_test_all_transforms(&output, 0, 0, 1024, 768, scale); + output_test_all_transforms(&output, 1000, 1000, 1024, 768, scale); + output_test_all_transforms(&output, 1024, 768, 1920, 1080, scale); + } +}