diff options
Diffstat (limited to 'tests/common/test_surface_integration.c')
| -rw-r--r-- | tests/common/test_surface_integration.c | 46 |
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); |
