AtlatestRepositorysigil-wm

sigil-wm / tree / testoutput-gamma.c

1/* SPDX-License-Identifier: BSD-3-Clause
2 * Real state allocation/ownership with deterministic backend commit faults. */
3#define listen socket_listen
4#include <sys/socket.h>
5#undef listen
6#define wlr_scene_output_build_state fixture_build_state
7#define wlr_scene_output_commit fixture_scene_commit
8#define wlr_output_test_state fixture_test_state
9#define wlr_output_commit_state fixture_commit_state
10#define wlr_output_schedule_frame fixture_schedule_frame
11#define wlr_output_get_gamma_size fixture_gamma_size
12#define wlr_gamma_control_v1_send_failed_and_destroy fixture_gamma_failed
13#include "../src/c/host.c"
14#include <assert.h>
15static unsigned commits,scheduled,plain,failed;
16static bool reject_gamma,reject_scene,fail_commit;
17static uint16_t applied[12];
18static size_t applied_size;
19bool fixture_build_state(struct wlr_scene_output *scene,struct wlr_output_state *state,
20 const struct wlr_scene_output_state_options *options) {
21 (void)scene; (void)state; (void)options; return true;
23bool fixture_scene_commit(struct wlr_scene_output *scene,const struct wlr_scene_output_state_options *options) {
24 (void)scene; (void)options; plain++; return true;
26bool fixture_test_state(struct wlr_output *output,const struct wlr_output_state *state) {
27 assert(!output->frame_pending);
28 return !reject_scene && (!reject_gamma || !(state->committed&WLR_OUTPUT_STATE_GAMMA_LUT));
30bool fixture_commit_state(struct wlr_output *output,const struct wlr_output_state *state) {
31 assert(!output->frame_pending);
32 commits++;
33 if(fail_commit) { errno=EBUSY; return false; }
34 if(state->committed&WLR_OUTPUT_STATE_GAMMA_LUT) {
35 applied_size=state->gamma_lut_size;
36 if(applied_size) memcpy(applied,state->gamma_lut,applied_size*3*sizeof(uint16_t));
37 }
38 output->frame_pending=true;
39 return true;
41void fixture_schedule_frame(struct wlr_output *output) { (void)output; scheduled++; }
42size_t fixture_gamma_size(struct wlr_output *output) { (void)output; return 4; }
43void fixture_gamma_failed(struct wlr_gamma_control_v1 *control) {
44 failed++; wl_list_remove(&control->link);
46int main(void) {
47 bridge.event_fd=eventfd(0,EFD_CLOEXEC|EFD_NONBLOCK);
48 assert(bridge.event_fd>=0);
49 struct server s={0};
50 wl_list_init(&s.outputs); wl_list_init(&s.output_controls);
51 wl_list_init(&s.permissions); wl_list_init(&s.data_requests);
52 wl_list_init(&s.output_requests); wl_list_init(&s.pointer_hints); wl_list_init(&s.popups);
53 struct wlr_gamma_control_manager_v1 manager={0};
54 wl_list_init(&manager.controls); s.gamma_manager=&manager;
55 struct wlr_output native={.enabled=true};
56 struct output o={.server=&s,.native=&native,.id=7,.gamma_pending=true};
57 native.data=&o; wl_list_insert(&s.outputs,&o.link);
58 applied_size=99;
59 output_commit_gamma(&o);
60 assert((commits==1 && applied_size==0 && !o.gamma_pending) && "GAMMA_CHECK_TAKEOVER_NEUTRAL");
61 puts("GAMMA_NEUTRAL=PASS reset-zero-table");
62 int64_t words[]={7,4,0,100,200,300,0,90,180,270,0,80,160,240};
63 assert(output_set_gamma(&s,23,words,14));
64 words[3]=999; /* Payload is copied before the caller can change it. */
65 assert((o.gamma_table[1]==100 && o.gamma_token==23) && "GAMMA_CHECK_COPIED_RAMP");
66 native.frame_pending=false;
67 output_commit_gamma(&o);
68 assert(commits==2 && applied_size==4 && applied[1]==100 && applied[11]==240);
69 assert(!o.gamma_pending);
70 o.gamma_pending=true;
71 output_commit_gamma(&o); /* An outstanding flip cannot be raced. */
72 assert(commits==2 && o.gamma_pending);
73 native.frame_pending=false; fail_commit=true;
74 unsigned before=commits;
75 unsigned scheduled_before=scheduled;
76 output_commit_gamma(&o);
77 assert((commits==before+1 && plain==0 && o.gamma_pending && !native.frame_pending) && "GAMMA_CHECK_BUSY_SINGLE_COMMIT");
78 assert((scheduled==scheduled_before && o.gamma_retry_at>now_ms()) && "GAMMA_CHECK_BOUNDED_RETRY");
79 assert(native_deadline(&s,now_ms())==o.gamma_retry_at);
80 output_gamma_present(&o.gamma_present,NULL);
81 assert(!o.gamma_retry_at && scheduled==scheduled_before+1);
82 fail_commit=false;
83 output_commit_gamma(&o);
84 assert(commits==before+2 && !o.gamma_pending && !o.gamma_retry_at);
85 o.gamma_retry_at=now_ms();
86 output_gamma_expire(&s);
87 assert(!o.gamma_retry_at && scheduled==scheduled_before+2);
88 puts("GAMMA_FRAMES=PASS one-commit busy-retry pending-flip");
89 native.frame_pending=false; o.gamma_pending=true; reject_scene=true;
90 before=commits;
91 output_commit_gamma(&o);
92 assert(commits==before && o.gamma_pending && o.gamma_retry_at>now_ms());
93 reject_scene=false;
94 output_commit_gamma(&o);
95 assert(commits==before+1 && !o.gamma_pending);
96 puts("GAMMA_SCENE_RETRY=PASS backend-test-failure-retains-ramp");
97 uint16_t external[12]={0,101,202,303,0,91,182,273,0,81,162,243};
98 struct wlr_gamma_control_v1 control={.output=&native,.table=NULL,.ramp_size=4};
99 wl_list_insert(&manager.controls,&control.link);
100 o.gamma_pending=true;
101 output_gamma_observe(&s);
102 assert(o.gamma_external && !o.gamma_pending);
103 assert(output_set_gamma(&s,24,words,14));
104 assert(!o.gamma_pending && "GAMMA_CHECK_EXTERNAL_OWNER");
105 control.table=external; o.gamma_pending=true; native.frame_pending=false;
106 output_commit_gamma(&o);
107 assert(applied[1]==101 && applied[11]==243);
108 wl_list_remove(&control.link);
109 struct wlr_gamma_control_manager_v1_set_gamma_event release={.output=&native};
110 output_gamma_request(&s.gamma_request,&release);
111 assert(o.gamma_pending && s.output_control_count==0);
112 output_gamma_observe(&s);
113 assert(!o.gamma_external && o.gamma_pending);
114 native.frame_pending=false;
115 output_commit_gamma(&o);
116 assert(applied[1]==999 && o.gamma_token==24);
117 puts("GAMMA_OWNERSHIP=PASS acquire-before-table external release-latest-base");
118 wl_list_insert(&manager.controls,&control.link);
119 o.gamma_pending=true; native.frame_pending=false; reject_gamma=true;
120 before=commits;
121 output_commit_gamma(&o);
122 assert(failed==1 && commits==before+1 && plain==0);
123 puts("GAMMA_REJECT=PASS scene-preserved single-commit");
124 native.frame_pending=false; reject_gamma=false;
125 before=commits;
126 output_gamma_finish(&s);
127 assert((commits==before+1 && applied_size==0) && "GAMMA_CHECK_EXIT_NEUTRAL");
128 native.frame_pending=false;
129 wl_list_insert(&manager.controls,&control.link);
130 output_gamma_finish(&s);
131 assert(commits==before+1 && "GAMMA_CHECK_EXIT_EXTERNAL_OWNER");
132 wl_list_remove(&control.link);
133 native.enabled=false;
134 output_gamma_finish(&s);
135 assert(commits==before+1 && "GAMMA_CHECK_EXIT_DISABLED_OUTPUT");
136 puts("GAMMA_EXIT=PASS neutral owned-externally-disabled-skipped");
137 free(o.gamma_table);
138 close(bridge.event_fd);
139 puts("OUTPUT_GAMMA=PASS");
140 return 0;