AtlatestRepositorysigil-wm

sigil-wm / tree / testoutput-gamma-lifecycle.c

1/* SPDX-License-Identifier: BSD-3-Clause
2 * Run the actual host and teardown, replacing only the headless backend's
3 * unsupported LUT operations with persistent synthetic hardware state. */
4#define _GNU_SOURCE
5#define wlr_output_get_gamma_size lifecycle_gamma_size
6#define wlr_output_test_state lifecycle_test_state
7#define wlr_output_commit_state lifecycle_commit_state
8#define wlr_scene_output_build_state lifecycle_build_state
9#include "../src/c/host.c"
10#undef wlr_output_get_gamma_size
11#undef wlr_output_test_state
12#undef wlr_output_commit_state
13#undef wlr_scene_output_build_state
14#include <assert.h>
15#include <sys/mman.h>
16#include <sys/wait.h>
17extern bool wlr_output_test_state(struct wlr_output *,const struct wlr_output_state *);
18extern bool wlr_output_commit_state(struct wlr_output *,const struct wlr_output_state *);
19extern bool wlr_scene_output_build_state(struct wlr_scene_output *,struct wlr_output_state *,
20 const struct wlr_scene_output_state_options *);
21struct hardware {
22 atomic_uint size,blue,start_resets,exit_resets;
23};
24static struct hardware *hardware;
25size_t lifecycle_gamma_size(struct wlr_output *output) { (void)output; return 256; }
26bool lifecycle_test_state(struct wlr_output *output,const struct wlr_output_state *state) {
27 struct wlr_output_state plain=*state;
28 plain.committed &= ~WLR_OUTPUT_STATE_GAMMA_LUT;
29 return wlr_output_test_state(output,&plain);
31bool lifecycle_build_state(struct wlr_scene_output *scene,struct wlr_output_state *state,
32 const struct wlr_scene_output_state_options *options) {
33 uint32_t gamma=state->committed&WLR_OUTPUT_STATE_GAMMA_LUT;
34 state->committed &= ~WLR_OUTPUT_STATE_GAMMA_LUT;
35 bool ok=wlr_scene_output_build_state(scene,state,options);
36 state->committed |= gamma;
37 return ok;
39bool lifecycle_commit_state(struct wlr_output *output,const struct wlr_output_state *state) {
40 struct wlr_output_state plain=*state;
41 plain.committed &= ~WLR_OUTPUT_STATE_GAMMA_LUT;
42 bool ok=wlr_output_commit_state(output,&plain);
43 if(ok && (state->committed&WLR_OUTPUT_STATE_GAMMA_LUT)) {
44 atomic_store(&hardware->blue,state->gamma_lut_size ? state->gamma_lut[3*state->gamma_lut_size-1] : 65535);
45 atomic_store(&hardware->size,state->gamma_lut_size);
46 if(!state->gamma_lut_size) {
47 if(wm_state()==4) atomic_fetch_add(&hardware->exit_resets,1);
48 else atomic_fetch_add(&hardware->start_resets,1);
49 }
50 }
51 return ok;
53static void session(bool crash) {
54 unsigned resets=atomic_load(&hardware->start_resets);
55 assert(wm_options(128,5000) && wm_start());
56 uint64_t until=now_ms()+10000,id=0;
57 while(wm_state()!=2 || !id || atomic_load(&hardware->start_resets)==resets) {
58 struct wm_message event;
59 while(wm_next(&event)) if(event.word[0]==2 && !id) {
60 id=event.word[1];
61 int64_t settings[]={id,1,0,0,1000,0,-1,1280,720,60000};
62 assert(wm_submit(2,1,settings,10));
63 }
64 if(now_ms()>=until) fprintf(stderr,"GAMMA_START_DIAGNOSTIC state=%d id=%llu resets=%u size=%u\n",
65 wm_state(),(unsigned long long)id,atomic_load(&hardware->start_resets),atomic_load(&hardware->size));
66 assert((now_ms()<until) && "GAMMA_LIFECYCLE_STARTUP_RESET");
67 usleep(1000);
68 }
69 assert((atomic_load(&hardware->size)==0 && atomic_load(&hardware->blue)==65535) &&
70 "GAMMA_LIFECYCLE_INHERITED_RESET");
71 int64_t words[2+3*256]={id,256};
72 for(size_t c=0;c<3;c++) for(size_t i=0;i<256;i++)
73 words[2+c*256+i]=i*(c==0 ? 50000 : c==1 ? 35000 : 20000)/255;
74 assert(wm_submit(16,1,words,2+3*256));
75 while(atomic_load(&hardware->size)!=256) {
76 assert((now_ms()<until) && "GAMMA_LIFECYCLE_WARM_APPLIED");
77 usleep(1000);
78 }
79 if(crash) _exit(0); /* Skip all native teardown; hardware survives below. */
80 unsigned exits=atomic_load(&hardware->exit_resets);
81 struct wm_message stop={.word={1}};
82 assert(wm_send(&stop));
83 while(wm_state()!=3) {
84 assert((now_ms()<until) && "GAMMA_LIFECYCLE_STOPPED");
85 usleep(1000);
86 }
87 assert(wm_join());
88 assert((atomic_load(&hardware->size)==0 && atomic_load(&hardware->blue)==65535 &&
89 atomic_load(&hardware->exit_resets)==exits+1) && "GAMMA_LIFECYCLE_EXIT_RESET");
91int main(void) {
92 char directory[]="/tmp/sigil-gamma-lifecycle.XXXXXX";
93 assert(mkdtemp(directory));
94 assert(setenv("XDG_RUNTIME_DIR",directory,1)==0);
95 assert(setenv("WLR_BACKENDS","headless",1)==0);
96 assert(setenv("WLR_RENDERER","pixman",1)==0);
97 assert(setenv("WLR_HEADLESS_OUTPUTS","1",1)==0);
98 unsetenv("WAYLAND_DISPLAY"); unsetenv("DISPLAY");
99 hardware=mmap(NULL,sizeof(*hardware),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
100 assert(hardware!=MAP_FAILED);
101 atomic_init(&hardware->size,256); atomic_init(&hardware->blue,20000);
102 atomic_init(&hardware->start_resets,0); atomic_init(&hardware->exit_resets,0);
103 for(int arm=0;arm<3;arm++) {
104 pid_t child=fork(); assert(child>=0);
105 if(!child) { session(arm==1); _exit(0); }
106 int status; assert(waitpid(child,&status,0)==child);
107 assert((WIFEXITED(status) && WEXITSTATUS(status)==0) && "GAMMA_LIFECYCLE_CHILD");
108 if(arm==1) assert((atomic_load(&hardware->size)==256 && atomic_load(&hardware->blue)==20000) &&
109 "GAMMA_LIFECYCLE_CRASH_PRESERVES_HARDWARE");
110 }
111 puts("GAMMA_LIFECYCLE=PASS clean-exit crash-inherited-ramp fresh-start-neutral");
112 munmap(hardware,sizeof(*hardware));
113 for(int index=0;index<4;index++) {
114 char path[128];
115 snprintf(path,sizeof(path),"%s/wayland-%d",directory,index); unlink(path);
116 snprintf(path,sizeof(path),"%s/wayland-%d.lock",directory,index); unlink(path);
117 }
118 assert(rmdir(directory)==0);
119 return 0;