conform: Use a repaint function
Timeouts and idles are subject to the whims of the load of the machine running the tests, as we found out with the new installed tests and OSTree-based VM running the conformance test suite continuously. We should be able to use a repaint function and a blocking loop that either is terminated because we hit g_assert(), or because a flag gets toggled once we know that the Stage has been at least painted once. The currently enabled tests using clutter_stage_read_pixels() have been updated to this approach. https://bugzilla.gnome.org/show_bug.cgi?id=703476
This commit is contained in:
parent
e352047499
commit
f1971844b9
@ -16,7 +16,6 @@ struct _TestState
|
|||||||
gint in_validation;
|
gint in_validation;
|
||||||
|
|
||||||
guint is_running : 1;
|
guint is_running : 1;
|
||||||
guint success : 1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static TestState *
|
static TestState *
|
||||||
@ -169,38 +168,28 @@ validate_state (ClutterActor *stage,
|
|||||||
|
|
||||||
clutter_actor_get_allocation_box (actor, &box);
|
clutter_actor_get_allocation_box (actor, &box);
|
||||||
|
|
||||||
g_assert (check_color_at (stage, actor, color, box.x1 + 2, box.y1 + 2));
|
check_color_at (stage, actor, color, box.x1 + 2, box.y1 + 2);
|
||||||
g_assert (check_color_at (stage, actor, color, box.x2 - 2, box.y2 - 2));
|
check_color_at (stage, actor, color, box.x2 - 2, box.y2 - 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
test_state_pop_validation (state);
|
test_state_pop_validation (state);
|
||||||
|
|
||||||
state->success = TRUE;
|
state->is_running = FALSE;
|
||||||
|
|
||||||
clutter_main_quit ();
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
queue_redraw (gpointer data_)
|
|
||||||
{
|
|
||||||
TestState *state = data_;
|
|
||||||
|
|
||||||
clutter_actor_queue_redraw (state->stage);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
test_state_run (TestState *state)
|
test_state_run (TestState *state)
|
||||||
{
|
{
|
||||||
state->is_running = TRUE;
|
|
||||||
|
|
||||||
g_signal_connect_after (state->stage, "paint", G_CALLBACK (validate_state), state);
|
g_signal_connect_after (state->stage, "paint", G_CALLBACK (validate_state), state);
|
||||||
state->id = clutter_threads_add_idle (queue_redraw, state);
|
|
||||||
|
|
||||||
clutter_main ();
|
while (state->is_running)
|
||||||
|
{
|
||||||
|
clutter_actor_queue_redraw (state->stage);
|
||||||
|
|
||||||
return state->success;
|
g_main_context_iteration (NULL, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -26,6 +26,7 @@ typedef struct
|
|||||||
ClutterActor *container;
|
ClutterActor *container;
|
||||||
ClutterActor *child;
|
ClutterActor *child;
|
||||||
ClutterActor *unrelated_actor;
|
ClutterActor *unrelated_actor;
|
||||||
|
gboolean was_painted;
|
||||||
} Data;
|
} Data;
|
||||||
|
|
||||||
GType foo_actor_get_type (void) G_GNUC_CONST;
|
GType foo_actor_get_type (void) G_GNUC_CONST;
|
||||||
@ -89,15 +90,15 @@ typedef struct _FooGroupClass FooGroupClass;
|
|||||||
|
|
||||||
struct _FooGroupClass
|
struct _FooGroupClass
|
||||||
{
|
{
|
||||||
ClutterGroupClass parent_class;
|
ClutterActorClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _FooGroup
|
struct _FooGroup
|
||||||
{
|
{
|
||||||
ClutterGroup parent;
|
ClutterActor parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (FooGroup, foo_group, CLUTTER_TYPE_GROUP);
|
G_DEFINE_TYPE (FooGroup, foo_group, CLUTTER_TYPE_ACTOR)
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
foo_group_has_overlaps (ClutterActor *actor)
|
foo_group_has_overlaps (ClutterActor *actor)
|
||||||
@ -175,7 +176,7 @@ verify_redraw (Data *data, int expected_paint_count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
timeout_cb (gpointer user_data)
|
run_verify (gpointer user_data)
|
||||||
{
|
{
|
||||||
Data *data = user_data;
|
Data *data = user_data;
|
||||||
|
|
||||||
@ -288,7 +289,7 @@ timeout_cb (gpointer user_data)
|
|||||||
clutter_actor_set_position (data->unrelated_actor, 0, 1);
|
clutter_actor_set_position (data->unrelated_actor, 0, 1);
|
||||||
verify_redraw (data, 0);
|
verify_redraw (data, 0);
|
||||||
|
|
||||||
clutter_main_quit ();
|
data->was_painted = TRUE;
|
||||||
|
|
||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
@ -296,53 +297,44 @@ timeout_cb (gpointer user_data)
|
|||||||
void
|
void
|
||||||
actor_offscreen_redirect (TestConformSimpleFixture *fixture,
|
actor_offscreen_redirect (TestConformSimpleFixture *fixture,
|
||||||
gconstpointer test_data)
|
gconstpointer test_data)
|
||||||
{
|
|
||||||
if (cogl_features_available (COGL_FEATURE_OFFSCREEN))
|
|
||||||
{
|
{
|
||||||
Data data;
|
Data data;
|
||||||
|
|
||||||
|
if (!cogl_features_available (COGL_FEATURE_OFFSCREEN))
|
||||||
|
{
|
||||||
|
if (g_test_verbose ())
|
||||||
|
g_print ("Offscreen buffers are not available, skipping test.\n");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
data.stage = clutter_stage_new ();
|
data.stage = clutter_stage_new ();
|
||||||
|
data.parent_container = clutter_actor_new ();
|
||||||
data.parent_container = clutter_group_new ();
|
|
||||||
|
|
||||||
data.container = g_object_new (foo_group_get_type (), NULL);
|
data.container = g_object_new (foo_group_get_type (), NULL);
|
||||||
|
|
||||||
data.foo_actor = g_object_new (foo_actor_get_type (), NULL);
|
data.foo_actor = g_object_new (foo_actor_get_type (), NULL);
|
||||||
clutter_actor_set_size (CLUTTER_ACTOR (data.foo_actor), 100, 100);
|
clutter_actor_set_size (CLUTTER_ACTOR (data.foo_actor), 100, 100);
|
||||||
|
|
||||||
clutter_container_add_actor (CLUTTER_CONTAINER (data.container),
|
clutter_actor_add_child (data.container, CLUTTER_ACTOR (data.foo_actor));
|
||||||
CLUTTER_ACTOR (data.foo_actor));
|
clutter_actor_add_child (data.parent_container, data.container);
|
||||||
|
clutter_actor_add_child (data.stage, data.parent_container);
|
||||||
|
|
||||||
clutter_container_add_actor (CLUTTER_CONTAINER (data.parent_container),
|
data.child = clutter_actor_new ();
|
||||||
data.container);
|
|
||||||
|
|
||||||
clutter_container_add_actor (CLUTTER_CONTAINER (data.stage),
|
|
||||||
data.parent_container);
|
|
||||||
|
|
||||||
data.child = clutter_rectangle_new ();
|
|
||||||
clutter_actor_set_size (data.child, 1, 1);
|
clutter_actor_set_size (data.child, 1, 1);
|
||||||
clutter_container_add_actor (CLUTTER_CONTAINER (data.container),
|
clutter_actor_add_child (data.container, data.child);
|
||||||
data.child);
|
|
||||||
|
|
||||||
data.unrelated_actor = clutter_rectangle_new ();
|
data.unrelated_actor = clutter_actor_new ();
|
||||||
clutter_actor_set_size (data.child, 1, 1);
|
clutter_actor_set_size (data.child, 1, 1);
|
||||||
clutter_container_add_actor (CLUTTER_CONTAINER (data.stage),
|
clutter_actor_add_child (data.stage, data.unrelated_actor);
|
||||||
data.unrelated_actor);
|
|
||||||
|
|
||||||
clutter_actor_show (data.stage);
|
clutter_actor_show (data.stage);
|
||||||
|
|
||||||
/* Start the test after a short delay to allow the stage to
|
clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT,
|
||||||
render its initial frames without affecting the results */
|
run_verify,
|
||||||
g_timeout_add_full (G_PRIORITY_LOW, 250, timeout_cb, &data, NULL);
|
&data,
|
||||||
|
NULL);
|
||||||
|
|
||||||
clutter_main ();
|
while (!data.was_painted)
|
||||||
|
g_main_context_iteration (NULL, FALSE);
|
||||||
|
|
||||||
clutter_actor_destroy (data.stage);
|
clutter_actor_destroy (data.stage);
|
||||||
|
|
||||||
if (g_test_verbose ())
|
|
||||||
g_print ("OK\n");
|
|
||||||
}
|
}
|
||||||
else if (g_test_verbose ())
|
|
||||||
g_print ("Skipping\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ typedef struct _TestState
|
|||||||
{
|
{
|
||||||
ClutterActor *stage;
|
ClutterActor *stage;
|
||||||
guint frame;
|
guint frame;
|
||||||
|
gboolean was_painted;
|
||||||
} TestState;
|
} TestState;
|
||||||
|
|
||||||
static ClutterActor *
|
static ClutterActor *
|
||||||
@ -137,16 +138,12 @@ validate_result (TestState *state)
|
|||||||
g_print ("Testing onscreen clone with path clip...\n");
|
g_print ("Testing onscreen clone with path clip...\n");
|
||||||
validate_part (state, SOURCE_SIZE, ypos * SOURCE_SIZE, 1);
|
validate_part (state, SOURCE_SIZE, ypos * SOURCE_SIZE, 1);
|
||||||
ypos++;
|
ypos++;
|
||||||
|
|
||||||
/* Comment this out if you want visual feedback of what this test
|
|
||||||
* paints.
|
|
||||||
*/
|
|
||||||
clutter_main_quit ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gboolean
|
||||||
on_paint (ClutterActor *actor, TestState *state)
|
on_paint (gpointer data)
|
||||||
{
|
{
|
||||||
|
TestState *state = data;
|
||||||
int frame_num;
|
int frame_num;
|
||||||
|
|
||||||
/* XXX: validate_result calls clutter_stage_read_pixels which will result in
|
/* XXX: validate_result calls clutter_stage_read_pixels which will result in
|
||||||
@ -155,14 +152,10 @@ on_paint (ClutterActor *actor, TestState *state)
|
|||||||
frame_num = state->frame++;
|
frame_num = state->frame++;
|
||||||
if (frame_num == 1)
|
if (frame_num == 1)
|
||||||
validate_result (state);
|
validate_result (state);
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
state->was_painted = TRUE;
|
||||||
queue_redraw (gpointer stage)
|
|
||||||
{
|
|
||||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
|
||||||
|
|
||||||
return G_SOURCE_CONTINUE;
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -174,7 +167,12 @@ texture_fbo (TestConformSimpleFixture *fixture,
|
|||||||
int ypos = 0;
|
int ypos = 0;
|
||||||
|
|
||||||
if (!cogl_features_available (COGL_FEATURE_OFFSCREEN))
|
if (!cogl_features_available (COGL_FEATURE_OFFSCREEN))
|
||||||
|
{
|
||||||
|
if (g_test_verbose ())
|
||||||
|
g_print ("Offscreen buffers are not available, skipping.\n");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
state.frame = 0;
|
state.frame = 0;
|
||||||
|
|
||||||
@ -224,18 +222,15 @@ texture_fbo (TestConformSimpleFixture *fixture,
|
|||||||
clutter_container_add (CLUTTER_CONTAINER (state.stage), actor, NULL);
|
clutter_container_add (CLUTTER_CONTAINER (state.stage), actor, NULL);
|
||||||
ypos++;
|
ypos++;
|
||||||
|
|
||||||
/* We force continuous redrawing of the stage, since we need to skip
|
clutter_actor_show (state.stage);
|
||||||
* the first few frames, and we wont be doing anything else that
|
|
||||||
* will trigger redrawing. */
|
|
||||||
clutter_threads_add_idle (queue_redraw, state.stage);
|
|
||||||
g_signal_connect_after (state.stage, "paint", G_CALLBACK (on_paint), &state);
|
|
||||||
|
|
||||||
clutter_actor_show_all (state.stage);
|
clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT,
|
||||||
|
on_paint,
|
||||||
|
&state,
|
||||||
|
NULL);
|
||||||
|
|
||||||
clutter_main ();
|
while (!state.was_painted)
|
||||||
|
g_main_context_iteration (NULL, FALSE);
|
||||||
|
|
||||||
clutter_actor_destroy (state.stage);
|
clutter_actor_destroy (state.stage);
|
||||||
|
|
||||||
if (g_test_verbose ())
|
|
||||||
g_print ("OK\n");
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user