v / vlib / sokol / sapp / sapp_egl_linux.v
211 lines · 184 sloc · 6.13 KB · ddd4ac7880f392ad6c39719af05f01d29eb0ad3a
Raw
1module sapp
2
3// EGL initialization and teardown.
4// Shared between Wayland and X11 backends.
5
6fn sapp_egl_choose_config() EGLConfig {
7 samples := if g_sapp_state.desc.sample_count > 1 {
8 EGLint(g_sapp_state.desc.sample_count)
9 } else {
10 EGLint(0)
11 }
12 alpha_size := if g_sapp_state.desc.alpha { EGLint(8) } else { EGLint(0) }
13 sample_buffers := if g_sapp_state.desc.sample_count > 1 { EGLint(1) } else { EGLint(0) }
14
15 config_attrs := [
16 egl_surface_type,
17 egl_window_bit,
18 egl_renderable_type,
19 egl_opengl_bit,
20 egl_red_size,
21 EGLint(8),
22 egl_green_size,
23 EGLint(8),
24 egl_blue_size,
25 EGLint(8),
26 egl_alpha_size,
27 alpha_size,
28 egl_depth_size,
29 EGLint(24),
30 egl_stencil_size,
31 EGLint(8),
32 egl_sample_buffers,
33 sample_buffers,
34 egl_samples,
35 samples,
36 egl_none,
37 ]!
38
39 mut egl_configs := unsafe { [32]EGLConfig{} }
40 mut config_count := EGLint(0)
41 if C.eglChooseConfig(g_sapp_state.egl.display, &config_attrs[0], &egl_configs[0], 32, &config_count) == 0
42 || config_count == 0 {
43 eprintln('sokol_app: EGL: no configs found')
44 return egl_configs[0]
45 }
46
47 mut config := egl_configs[0]
48 for i in 0 .. int(config_count) {
49 c := egl_configs[i]
50 mut r := EGLint(0)
51 mut g := EGLint(0)
52 mut b := EGLint(0)
53 mut a := EGLint(0)
54 mut d := EGLint(0)
55 mut s := EGLint(0)
56 mut n := EGLint(0)
57 if C.eglGetConfigAttrib(g_sapp_state.egl.display, c, egl_red_size, &r) != 0
58 && C.eglGetConfigAttrib(g_sapp_state.egl.display, c, egl_green_size, &g) != 0
59 && C.eglGetConfigAttrib(g_sapp_state.egl.display, c, egl_blue_size, &b) != 0
60 && C.eglGetConfigAttrib(g_sapp_state.egl.display, c, egl_alpha_size, &a) != 0
61 && C.eglGetConfigAttrib(g_sapp_state.egl.display, c, egl_depth_size, &d) != 0
62 && C.eglGetConfigAttrib(g_sapp_state.egl.display, c, egl_stencil_size, &s) != 0
63 && C.eglGetConfigAttrib(g_sapp_state.egl.display, c, egl_samples, &n) != 0 && r == 8
64 && g == 8 && b == 8 && a == alpha_size && d == 24 && s == 8 && n == samples {
65 config = c
66 break
67 }
68 }
69 return config
70}
71
72fn sapp_egl_create_context(config EGLConfig) {
73 gl_major := if g_sapp_state.desc.gl.major_version != 0 {
74 g_sapp_state.desc.gl.major_version
75 } else {
76 4
77 }
78 gl_minor := if g_sapp_state.desc.gl.minor_version != 0 {
79 g_sapp_state.desc.gl.minor_version
80 } else {
81 1
82 }
83
84 ctx_attrs := [
85 egl_context_major_version,
86 EGLint(gl_major),
87 egl_context_minor_version,
88 EGLint(gl_minor),
89 egl_context_opengl_profile_mask,
90 egl_context_opengl_core_profile_bit,
91 egl_none,
92 ]!
93
94 g_sapp_state.egl.context = C.eglCreateContext(g_sapp_state.egl.display, config, unsafe { nil },
95 &ctx_attrs[0])
96 if g_sapp_state.egl.context == unsafe { nil } {
97 eprintln('sokol_app: EGL: failed to create context')
98 }
99}
100
101fn sapp_egl_create_surface(native_window voidptr) {
102 config := sapp_egl_choose_config()
103 g_sapp_state.egl.config = config
104 g_sapp_state.egl.surface = C.eglCreateWindowSurface(g_sapp_state.egl.display, config,
105 native_window, unsafe { nil })
106 if g_sapp_state.egl.surface == unsafe { nil } {
107 eprintln('sokol_app: EGL: failed to create window surface')
108 }
109 if g_sapp_state.egl.context == unsafe { nil } {
110 sapp_egl_create_context(config)
111 }
112}
113
114fn sapp_egl_make_current() {
115 if C.eglMakeCurrent(g_sapp_state.egl.display, g_sapp_state.egl.surface,
116 g_sapp_state.egl.surface, g_sapp_state.egl.context) == 0 {
117 eprintln('sokol_app: EGL: eglMakeCurrent failed')
118 }
119 mut fb := i32(0)
120 C.glGetIntegerv(gl_framebuffer_binding, &fb)
121 g_sapp_state.gl.framebuffer = u32(fb)
122 C.eglSwapInterval(g_sapp_state.egl.display, EGLint(g_sapp_state.swap_interval))
123}
124
125$if sokol_wayland ? {
126 fn sapp_egl_init_wayland() {
127 if C.eglBindAPI(egl_opengl_api) == 0 {
128 eprintln('sokol_app: EGL: failed to bind OpenGL API')
129 }
130
131 g_sapp_state.egl.display = C.eglGetDisplay(voidptr(g_sapp_state.wl.display))
132 if g_sapp_state.egl.display == unsafe { nil } {
133 eprintln('sokol_app: EGL: failed to get display')
134 }
135
136 mut major := EGLint(0)
137 mut minor := EGLint(0)
138 if C.eglInitialize(g_sapp_state.egl.display, &major, &minor) == 0 {
139 eprintln('sokol_app: EGL: failed to initialize')
140 }
141 g_sapp_state.gl.major = int(major)
142 g_sapp_state.gl.minor = int(minor)
143 }
144}
145
146fn sapp_egl_init_x11() {
147 if C.eglBindAPI(egl_opengl_api) == 0 {
148 eprintln('sokol_app: EGL: failed to bind OpenGL API')
149 }
150
151 g_sapp_state.egl.display = C.eglGetDisplay(voidptr(g_sapp_state.x11.display))
152 if g_sapp_state.egl.display == unsafe { nil } {
153 eprintln('sokol_app: EGL: failed to get display')
154 }
155
156 mut major := EGLint(0)
157 mut minor := EGLint(0)
158 if C.eglInitialize(g_sapp_state.egl.display, &major, &minor) == 0 {
159 eprintln('sokol_app: EGL: failed to initialize')
160 }
161 g_sapp_state.gl.major = int(major)
162 g_sapp_state.gl.minor = int(minor)
163
164 config := sapp_egl_choose_config()
165
166 mut visual_id := EGLint(0)
167 if C.eglGetConfigAttrib(g_sapp_state.egl.display, config, EGLint(0x302E), &visual_id) == 0 {
168 eprintln('sokol_app: EGL: failed to get native visual ID')
169 }
170
171 mut visual_info_template := C.XVisualInfo{}
172 visual_info_template.visualid = VisualID(visual_id)
173
174 mut num_visuals := 0
175 visual_info := C.XGetVisualInfo(g_sapp_state.x11.display, visual_id_mask,
176 &visual_info_template, &num_visuals)
177 if visual_info == unsafe { nil } {
178 eprintln('sokol_app: EGL: failed to get visual info')
179 }
180
181 x11_create_window(visual_info.visual, visual_info.depth)
182 C.XFree(visual_info)
183
184 g_sapp_state.egl.surface = C.eglCreateWindowSurface(g_sapp_state.egl.display, config,
185 EGLNativeWindowType(g_sapp_state.x11.window), unsafe { nil })
186 if g_sapp_state.egl.surface == unsafe { nil } {
187 eprintln('sokol_app: EGL: failed to create window surface')
188 }
189
190 sapp_egl_create_context(config)
191 sapp_egl_make_current()
192}
193
194fn sapp_egl_destroy() {
195 if g_sapp_state.egl.display != unsafe { nil } {
196 C.eglMakeCurrent(g_sapp_state.egl.display, unsafe { nil }, unsafe { nil }, unsafe { nil })
197
198 if g_sapp_state.egl.context != unsafe { nil } {
199 C.eglDestroyContext(g_sapp_state.egl.display, g_sapp_state.egl.context)
200 g_sapp_state.egl.context = unsafe { nil }
201 }
202
203 if g_sapp_state.egl.surface != unsafe { nil } {
204 C.eglDestroySurface(g_sapp_state.egl.display, g_sapp_state.egl.surface)
205 g_sapp_state.egl.surface = unsafe { nil }
206 }
207
208 C.eglTerminate(g_sapp_state.egl.display)
209 g_sapp_state.egl.display = unsafe { nil }
210 }
211}
212