AtlatestRepositorysigil-wm

sigil-wm / tree / testplan-presentation.c

1/* SPDX-License-Identifier: BSD-3-Clause
2 * Exercise native readiness and output placement with real scene/layout nodes.
3 * Observe scene commits without rendering a buffer. */
4#define wlr_scene_output_commit fixture_scene_commit
5#define wlr_xdg_surface_for_each_surface fixture_each_surface
6#include "../src/c/host.c"
7#include <assert.h>
8static unsigned commits,callbacks;
9void fixture_each_surface(struct wlr_xdg_surface *surface,
10 wlr_surface_iterator_func_t iterator,void *data) {
11 (void)surface; (void)iterator; assert(data); callbacks++;
13bool fixture_scene_commit(struct wlr_scene_output *output,
14 const struct wlr_scene_output_state_options *options) {
15 (void)output; (void)options; commits++; return true;
17static void initialize(struct server *s) {
18 wl_list_init(&s->outputs); wl_list_init(&s->views); wl_list_init(&s->pixels);
19 wl_list_init(&s->constraints); wl_list_init(&s->keyboards);
20 s->display=wl_display_create(); assert(s->display);
21 s->scene=wlr_scene_create(); assert(s->scene);
22 s->normal=wlr_scene_tree_create(&s->scene->tree); assert(s->normal);
23 s->cursor=wlr_cursor_create(); assert(s->cursor);
24 s->layout=wlr_output_layout_create(s->display); assert(s->layout);
25 s->scene_layout=wlr_scene_attach_output_layout(s->scene,s->layout); assert(s->scene_layout);
26 bridge.event_fd=eventfd(0,EFD_NONBLOCK|EFD_CLOEXEC); assert(bridge.event_fd>=0);
28static void finish(struct server *s) {
29 wlr_cursor_destroy(s->cursor);
30 wlr_scene_node_destroy(&s->scene->tree.node);
31 wl_display_destroy(s->display);
32 close(bridge.event_fd); free_event_stream();
34static void readiness(void) {
35 struct server s={0}; initialize(&s);
36 struct wlr_xdg_surface surface={0};
37 struct wlr_xdg_toplevel toplevel={.base=&surface};
38 struct view view={.id=1,.server=&s,.mapped=true,.native=&toplevel,.serial=24};
39 view.tree=wlr_scene_tree_create(s.normal); assert(view.tree);
40 wl_list_insert(&s.views,&view.link);
41 wlr_scene_node_set_enabled(&view.tree->node,false);
42 int64_t words[]={1,1,0,200,1,10,10,300,200,0,0,0,0,0};
43 s.plan=malloc(sizeof(words)); assert(s.plan); memcpy(s.plan,words,sizeof(words));
44 s.plan_token=100; s.plan_deadline=now_ms()+200;
45 surface.current.configure_serial=21;
46 check_plan(&s);
47 assert(!s.plan && "HIDDEN_PLACEMENT_MUST_NOT_DELAY_PLAN");
48 struct wm_message event; assert(pop(&bridge.events,&event));
49 assert(event.word[0]==22 && event.word[2]==0);
50 words[9]=1;
51 s.plan=malloc(sizeof(words)); assert(s.plan); memcpy(s.plan,words,sizeof(words));
52 check_plan(&s);
53 assert(s.plan && "SHOWN_PLACEMENT_MUST_WAIT_FOR_CONFIGURE");
54 surface.current.configure_serial=24;
55 check_plan(&s);
56 assert(!s.plan && view.tree->node.enabled);
57 wl_list_remove(&view.link); finish(&s);
58 puts("PLAN_READINESS=PASS hidden-does-not-wait shown-waits-for-commit");
60static void relocation(void) {
61 struct server s={0}; initialize(&s);
62 s.backend=wlr_headless_backend_create(wl_display_get_event_loop(s.display)); assert(s.backend);
63 struct wlr_output *native=wlr_headless_add_output(s.backend,320,240); assert(native);
64 assert(wlr_backend_start(s.backend));
65 struct wlr_output_state state; wlr_output_state_init(&state);
66 wlr_output_state_set_enabled(&state,true);
67 assert(wlr_output_commit_state(native,&state));
68 wlr_output_state_finish(&state);
69 struct output output={.server=&s,.id=1,.native=native,.configured_enabled=true};
70 output.scene=wlr_scene_output_create(s.scene,native); assert(output.scene);
71 wl_list_insert(&s.outputs,&output.link);
72 place_output_state(&s,&output,320,0);
73 /* Finish the initial scene, then move the survivor into the removed head's region. */
74 s.scene_update_deadline=0;
75 output_frame(&output.frame,NULL); unsigned before=commits;
76 place_output_state(&s,&output,0,0);
77 output_frame(&output.frame,NULL);
78 assert(commits==before && "RELOCATED_OUTPUT_MUST_WAIT_FOR_SCENE_PLAN");
79 struct wlr_xdg_surface surface={0};
80 struct wlr_xdg_toplevel toplevel={.base=&surface};
81 struct view view={.id=2,.server=&s,.mapped=true,.native=&toplevel,.serial=24};
82 view.tree=wlr_scene_tree_create(s.normal); assert(view.tree);
83 wlr_scene_node_set_position(&view.tree->node,320,0);
84 wl_list_insert(&s.views,&view.link);
85 surface.current.configure_serial=21;
86 int64_t words[]={1,1,0,200,2,0,0,300,200,1,0,0,0,0};
87 s.plan_token=101; s.plan_deadline=now_ms()+200;
88 s.plan=malloc(sizeof(words)); assert(s.plan); memcpy(s.plan,words,sizeof(words));
89 check_plan(&s); assert(s.plan);
90 output_frame(&output.frame,NULL);
91 assert(commits==before && callbacks==1 && "HELD_OUTPUT_MUST_DELIVER_PLAN_CALLBACKS");
92 surface.current.configure_serial=24;
93 check_plan(&s);
94 assert(!s.plan && now_ms()<s.plan_deadline);
95 struct wm_message event; assert(pop(&bridge.events,&event));
96 assert(event.word[0]==22 && event.word[2]==0);
97 output_frame(&output.frame,NULL);
98 assert(commits==before+1 && "APPLIED_PLAN_MUST_RELEASE_PRESENTATION");
99 place_output_state(&s,&output,0,0);
100 assert(!s.scene_update_deadline && "UNCHANGED_POSITION_MUST_NOT_HOLD");
101 place_output_state(&s,&output,320,0);
102 uint64_t hold=s.scene_update_deadline;
103 assert(hold && hold<=now_ms()+200);
104 place_output_state(&s,&output,0,0);
105 assert(s.scene_update_deadline==hold && "RELOCATION_MUST_NOT_EXTEND_HOLD");
106 s.scene_update_deadline=now_ms();
107 output_frame(&output.frame,NULL);
108 assert(commits==before+2 && "EXPIRED_HOLD_MUST_ALLOW_PRESENTATION");
109 wl_list_remove(&view.link);
110 wl_list_remove(&output.link);
111 wlr_backend_destroy(s.backend); finish(&s);
112 puts("OUTPUT_RELOCATION=PASS presentation-held-until-plan configure-callback-progress");
114int main(int argc,char **argv) {
115 assert(argc==2);
116 if(!strcmp(argv[1],"readiness")) readiness();
117 else { assert(!strcmp(argv[1],"relocation")); relocation(); }