compare-render: Run clip tests using new runner

This requires adding infrastructure to generate per-test data, so that
the random clip rect can be computed and reused for both test and
reference generation.

So add this infrastructure.
This commit is contained in:
Benjamin Otte 2024-08-30 02:22:55 +02:00
parent ffd836e6f4
commit b88fe301be

View File

@ -214,14 +214,15 @@ load_node_file (const char *node_file)
} }
static void static void
make_random_clip (const graphene_rect_t *bounds, make_random_clip (cairo_rectangle_int_t *int_clip,
cairo_rectangle_int_t *int_clip) int width,
int height)
{ {
int_clip->width = g_test_rand_int_range (1, (int) floor (bounds->size.width)); int_clip->width = g_test_rand_int_range (1, width);
int_clip->height = g_test_rand_int_range (1, (int) floor (bounds->size.height)); int_clip->height = g_test_rand_int_range (1, height);
int_clip->x = g_test_rand_int_range ((int) ceil (bounds->origin.x), (int) floor (bounds->origin.x + bounds->size.width - int_clip->width)); int_clip->x = g_test_rand_int_range (0, width - int_clip->width);
int_clip->y = g_test_rand_int_range ((int) ceil (bounds->origin.y), (int) floor (bounds->origin.y + bounds->size.height - int_clip->height)); int_clip->y = g_test_rand_int_range (0, height - int_clip->height);
} }
static void static void
@ -235,7 +236,8 @@ gsk_rect_from_cairo (graphene_rect_t *rect,
} }
static GskRenderNode * static GskRenderNode *
flip_create_test (GskRenderNode *node) flip_create_test (GskRenderNode *node,
gconstpointer unused)
{ {
GskRenderNode *result; GskRenderNode *result;
GskTransform *transform; GskTransform *transform;
@ -248,8 +250,9 @@ flip_create_test (GskRenderNode *node)
} }
static GdkTexture * static GdkTexture *
flip_create_reference (GskRenderer *renderer, flip_create_reference (GskRenderer *renderer,
GdkTexture *texture) GdkTexture *texture,
gconstpointer unused)
{ {
GskRenderNode *texture_node, *transform_node; GskRenderNode *texture_node, *transform_node;
GdkTexture *result; GdkTexture *result;
@ -275,7 +278,8 @@ flip_create_reference (GskRenderer *renderer,
} }
static GskRenderNode * static GskRenderNode *
repeat_create_test (GskRenderNode *node) repeat_create_test (GskRenderNode *node,
gconstpointer unused)
{ {
graphene_rect_t bounds, node_bounds; graphene_rect_t bounds, node_bounds;
@ -293,8 +297,9 @@ repeat_create_test (GskRenderNode *node)
} }
static GdkTexture * static GdkTexture *
repeat_create_reference (GskRenderer *renderer, repeat_create_reference (GskRenderer *renderer,
GdkTexture *texture) GdkTexture *texture,
gconstpointer unused)
{ {
GskRenderNode *texture_nodes[16], *container_node, *reference_node; GskRenderNode *texture_nodes[16], *container_node, *reference_node;
GdkTexture *result; GdkTexture *result;
@ -336,7 +341,8 @@ repeat_create_reference (GskRenderer *renderer,
} }
static GskRenderNode * static GskRenderNode *
rotate_create_test (GskRenderNode *node) rotate_create_test (GskRenderNode *node,
gconstpointer unused)
{ {
GskRenderNode *result; GskRenderNode *result;
GskTransform *transform; GskTransform *transform;
@ -349,8 +355,9 @@ rotate_create_test (GskRenderNode *node)
} }
static GdkTexture * static GdkTexture *
rotate_create_reference (GskRenderer *renderer, rotate_create_reference (GskRenderer *renderer,
GdkTexture *texture) GdkTexture *texture,
gconstpointer unused)
{ {
GskRenderNode *texture_node, *transform_node; GskRenderNode *texture_node, *transform_node;
GdkTexture *result; GdkTexture *result;
@ -376,7 +383,8 @@ rotate_create_reference (GskRenderer *renderer,
} }
static GskRenderNode * static GskRenderNode *
mask_create_test (GskRenderNode *node) mask_create_test (GskRenderNode *node,
gconstpointer unused)
{ {
GskRenderNode *result, *nodes[2], *mask_node; GskRenderNode *result, *nodes[2], *mask_node;
graphene_rect_t bounds; graphene_rect_t bounds;
@ -409,8 +417,9 @@ mask_create_test (GskRenderNode *node)
} }
static GdkTexture * static GdkTexture *
mask_create_reference (GskRenderer *renderer, mask_create_reference (GskRenderer *renderer,
GdkTexture *texture) GdkTexture *texture,
gconstpointer unused)
{ {
GskRenderNode *texture_node, *reference_node; GskRenderNode *texture_node, *reference_node;
GdkTexture *result; GdkTexture *result;
@ -452,7 +461,8 @@ mask_create_reference (GskRenderer *renderer,
} }
static GskRenderNode * static GskRenderNode *
replay_create_test (GskRenderNode *node) replay_create_test (GskRenderNode *node,
gconstpointer unused)
{ {
GskRenderNode *result; GskRenderNode *result;
graphene_rect_t node_bounds, result_bounds; graphene_rect_t node_bounds, result_bounds;
@ -486,8 +496,72 @@ replay_create_test (GskRenderNode *node)
return result; return result;
} }
static gpointer
clip_setup (GskRenderNode *node)
{
cairo_rectangle_int_t *result;
graphene_rect_t bounds;
result = g_new (cairo_rectangle_int_t, 1);
gsk_render_node_get_bounds (node, &bounds);
if (bounds.size.width <= 1 || bounds.size.height <= 1)
*result = (cairo_rectangle_int_t) { 0, 0, 1, 1 };
else
make_random_clip (result, ceil (bounds.size.width), ceil (bounds.size.height));
g_print ("Random clip rectangle %d %d %d %d\n",
result->x, result->y, result->width, result->height);
return result;
}
static GskRenderNode * static GskRenderNode *
colorflip_create_test (GskRenderNode *node) clip_create_test (GskRenderNode *node,
gconstpointer data)
{
const cairo_rectangle_int_t *int_clip = data;
graphene_rect_t clip_rect, bounds;
gsk_rect_from_cairo (&clip_rect, int_clip);
gsk_render_node_get_bounds (node, &bounds);
clip_rect.origin.x += bounds.origin.x;
clip_rect.origin.y += bounds.origin.y;
return gsk_clip_node_new (node, &clip_rect);
}
static GdkTexture *
clip_create_reference (GskRenderer *renderer,
GdkTexture *texture,
gconstpointer data)
{
const cairo_rectangle_int_t *int_clip = data;
GskRenderNode *texture_node, *reference_node;
graphene_rect_t clip_rect;
GdkTexture *result;
gsk_rect_from_cairo (&clip_rect, int_clip);
texture_node = gsk_texture_node_new (texture,
&GRAPHENE_RECT_INIT (
0,
0,
gdk_texture_get_width (texture),
gdk_texture_get_height (texture)
));
reference_node = gsk_clip_node_new (texture_node, &clip_rect);
result = gsk_renderer_render_texture (renderer, reference_node, NULL);
gsk_render_node_unref (reference_node);
gsk_render_node_unref (texture_node);
return result;
}
static GskRenderNode *
colorflip_create_test (GskRenderNode *node,
gconstpointer unused)
{ {
graphene_matrix_t matrix; graphene_matrix_t matrix;
@ -501,8 +575,9 @@ colorflip_create_test (GskRenderNode *node)
} }
static GdkTexture * static GdkTexture *
colorflip_create_reference (GskRenderer *renderer, colorflip_create_reference (GskRenderer *renderer,
GdkTexture *texture) GdkTexture *texture,
gconstpointer unused)
{ {
GskRenderNode *texture_node, *reference_node; GskRenderNode *texture_node, *reference_node;
GdkTexture *result; GdkTexture *result;
@ -533,9 +608,13 @@ typedef struct _TestSetup TestSetup;
struct _TestSetup struct _TestSetup
{ {
const char *name; const char *name;
GskRenderNode * (* create_test) (GskRenderNode *node); gpointer (* setup) (GskRenderNode *node);
void (* free) (gpointer data);
GskRenderNode * (* create_test) (GskRenderNode *node,
gconstpointer data);
GdkTexture * (* create_reference) (GskRenderer *renderer, GdkTexture * (* create_reference) (GskRenderer *renderer,
GdkTexture *texture); GdkTexture *texture,
gconstpointer data);
}; };
static const TestSetup test_setups[] = { static const TestSetup test_setups[] = {
@ -569,6 +648,13 @@ static const TestSetup test_setups[] = {
.create_test = replay_create_test, .create_test = replay_create_test,
.create_reference = NULL, .create_reference = NULL,
}, },
{
.name = "clip",
.setup = clip_setup,
.free = g_free,
.create_test = clip_create_test,
.create_reference = clip_create_reference,
},
{ {
.name = "colorflip", .name = "colorflip",
.create_test = colorflip_create_test, .create_test = colorflip_create_test,
@ -585,10 +671,16 @@ run_single_test (const TestSetup *setup,
{ {
GskRenderNode *test; GskRenderNode *test;
GdkTexture *reference, *rendered, *diff; GdkTexture *reference, *rendered, *diff;
gpointer test_data;
if (setup->setup)
test_data = setup->setup (org_test);
else
test_data = NULL;
if (setup->create_test) if (setup->create_test)
{ {
test = setup->create_test (org_test); test = setup->create_test (org_test, test_data);
save_node (test, file_name, setup->name, ".node"); save_node (test, file_name, setup->name, ".node");
} }
else else
@ -599,12 +691,15 @@ run_single_test (const TestSetup *setup,
if (setup->create_reference) if (setup->create_reference)
{ {
reference = setup->create_reference (renderer, org_reference); reference = setup->create_reference (renderer, org_reference, test_data);
save_image (reference, file_name, setup->name, ".ref.png"); save_image (reference, file_name, setup->name, ".ref.png");
} }
else else
reference = g_object_ref (org_reference); reference = g_object_ref (org_reference);
if (setup->free)
setup->free (test_data);
diff = reftest_compare_textures (reference, rendered); diff = reftest_compare_textures (reference, rendered);
if (diff) if (diff)
{ {
@ -644,12 +739,10 @@ run_node_test (gconstpointer data)
{ {
const TestData *test = data; const TestData *test = data;
GdkTexture *reference_texture = NULL; GdkTexture *reference_texture = NULL;
GdkTexture *rendered_texture = NULL;
GskRenderer *renderer; GskRenderer *renderer;
GdkSurface *window; GdkSurface *window;
GskRenderNode *node; GskRenderNode *node;
GError *error = NULL; GError *error = NULL;
GdkTexture *diff_texture = NULL;
g_print ("Node file: '%s'\n", test->node_file); g_print ("Node file: '%s'\n", test->node_file);
g_print ("PNG file: '%s'\n", test->png_file); g_print ("PNG file: '%s'\n", test->png_file);
@ -694,66 +787,10 @@ run_node_test (gconstpointer data)
run_single_test (&test_setups[5], test->node_file, renderer, node, reference_texture); run_single_test (&test_setups[5], test->node_file, renderer, node, reference_texture);
if (clip) if (clip)
{ run_single_test (&test_setups[6], test->node_file, renderer, node, reference_texture);
GskRenderNode *node2, *texture_node, *reference_node;
GdkTexture *clipped_reference;
graphene_rect_t bounds;
cairo_rectangle_int_t int_clip;
graphene_rect_t clip_rect;
gsk_render_node_get_bounds (node, &bounds);
if (bounds.size.width <= 1 || bounds.size.height <= 1)
{
g_test_skip ("Can't make a random clip");
goto skip_clip;
}
make_random_clip (&bounds, &int_clip);
g_print ("Random clip rectangle %d %d %d %d\n",
int_clip.x, int_clip.y, int_clip.width, int_clip.height);
gsk_rect_from_cairo (&clip_rect, &int_clip);
g_assert_true (graphene_rect_contains_rect (&bounds, &clip_rect));
g_assert_true (graphene_rect_get_area (&clip_rect) != 0);
node2 = gsk_clip_node_new (node, &clip_rect);
save_node (node2, test->node_file, "clip", ".node");
rendered_texture = gsk_renderer_render_texture (renderer, node2, NULL);
save_image (rendered_texture, test->node_file, "clip", ".out.png");
texture_node = gsk_texture_node_new (reference_texture,
&GRAPHENE_RECT_INIT (
(int) bounds.origin.x,
(int) bounds.origin.y,
gdk_texture_get_width (reference_texture),
gdk_texture_get_height (reference_texture)
));
reference_node = gsk_clip_node_new (texture_node, &clip_rect);
clipped_reference = gsk_renderer_render_texture (renderer, reference_node, NULL);
save_image (clipped_reference, test->node_file, "clip", ".ref.png");
diff_texture = reftest_compare_textures (clipped_reference, rendered_texture);
if (diff_texture)
{
save_image (diff_texture, test->node_file, "clip", ".diff.png");
g_test_fail ();
}
g_clear_object (&diff_texture);
g_clear_object (&rendered_texture);
g_clear_object (&clipped_reference);
gsk_render_node_unref (reference_node);
gsk_render_node_unref (texture_node);
gsk_render_node_unref (node2);
}
skip_clip:
if (colorflip) if (colorflip)
run_single_test (&test_setups[6], test->node_file, renderer, node, reference_texture); run_single_test (&test_setups[7], test->node_file, renderer, node, reference_texture);
g_object_unref (reference_texture); g_object_unref (reference_texture);
gsk_render_node_unref (node); gsk_render_node_unref (node);