summaryrefslogtreecommitdiff
path: root/tests/common/test_surface_integration.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/common/test_surface_integration.c')
-rw-r--r--tests/common/test_surface_integration.c46
1 files changed, 45 insertions, 1 deletions
diff --git a/tests/common/test_surface_integration.c b/tests/common/test_surface_integration.c
index 7862bfc..6946cf9 100644
--- a/tests/common/test_surface_integration.c
+++ b/tests/common/test_surface_integration.c
@@ -37,7 +37,8 @@ static void *wrong_thread(void *data)
struct callback_state {
yasl_loop *loop;
yasl_surface *window;
- int refreshes;
+ int refreshes, resizes, refreshes_at_resize, final_losses;
+ bool animating;
int wait_result, shutdown_result;
yasl_surface *made;
int made_destroy;
@@ -45,8 +46,18 @@ struct callback_state {
static void on_event(void *userdata, const yasl_event *e)
{
struct callback_state *st = userdata;
+ if (e->type == YASL_EVENT_DISPLAY_LOST && e->action == YASL_LOST_FINAL)
+ st->final_losses++;
+ if (e->type == YASL_EVENT_WINDOW && e->surface == st->window &&
+ e->window.width == 120 && e->window.height == 80) {
+ st->resizes++;
+ st->refreshes_at_resize = st->refreshes;
+ }
if (e->type == YASL_EVENT_REFRESH && e->surface == st->window) {
st->refreshes++;
+ /* An animation asks for its next frame before it presents this one. */
+ if (st->animating)
+ assert(yasl_surface_request_frame(e->surface) == 0);
int w = 0, h = 0;
uint32_t *pixels = yasl_cpu_pixels(e->surface, &w, &h);
assert(pixels && w > 0 && h > 0);
@@ -111,6 +122,32 @@ static void test_callback_mode(enum yasl_backend backend)
assert(yasl_loop_step(st.loop, 25) >= 0);
assert(st.refreshes == before + 1);
+ /* The frame an animation presents after its request is the frame the
+ * request waits for: one REFRESH per display refresh, not two. */
+ st.animating = true;
+ assert(yasl_surface_request_frame(st.window) == 0);
+ before = st.refreshes;
+ uint64_t start = yasl_time_ns();
+ while (yasl_time_ns() - start < 1000000000ull)
+ assert(yasl_loop_step(st.loop, 50) >= 0);
+ st.animating = false;
+ int frames = st.refreshes - before;
+ fprintf(stderr, "%d REFRESH events in 1 s of animation\n", frames);
+ assert(frames >= 20 && frames <= 75);
+
+ /* A resize owes one REFRESH, after its WINDOW event. */
+ for (int i = 0; i < 6; i++)
+ assert(yasl_loop_step(st.loop, 25) >= 0);
+ before = st.refreshes;
+ assert(yasl_surface_request_size(st.window, 120, 80) == 0);
+ step_until(&st, &st.resizes, 1);
+ for (int i = 0; i < 8; i++)
+ assert(yasl_loop_step(st.loop, 25) >= 0);
+ fprintf(stderr, "%d REFRESH events for one resize, %d before its WINDOW event\n",
+ st.refreshes - before, st.refreshes_at_resize - before);
+ assert(st.resizes == 1 && st.refreshes_at_resize == before);
+ assert(st.refreshes == before + 1);
+
/* An idle loop waits instead of spinning. */
int steps = 0;
uint64_t end = yasl_time_ns() + 300000000ull;
@@ -125,6 +162,13 @@ static void test_callback_mode(enum yasl_backend backend)
assert(yasl_loop_step(st.loop, 50) >= 0);
assert(st.made_destroy == 0);
+ /* A lost event ends the session: on_event hears it as a final loss. A
+ * string event with no text cannot be queued. */
+ struct yasl_private_event broken = {.type = YASL_PRIVATE_EVENT_PASTE, .surface = st.window,
+ .text = {NULL, 1}};
+ assert(!yasl_private_events_push(st.window->display, st.window, &broken));
+ step_until(&st, &st.final_losses, 1);
+
assert(yasl_loop_add_timer(st.loop, YASL_PRIVATE_MS_TO_NS(10), quit_in_timer, st.loop));
assert(yasl_loop_run(st.loop) == 0);
assert(yasl_shutdown() == 0);