1#![allow(non_camel_case_types, non_snake_case, dead_code)]
2
3pub type EGLNativeDisplayType = *mut ();
4pub type EGLNativePixmapType = ::std::os::raw::c_ulong;
5pub type EGLNativeWindowType = ::std::os::raw::c_ulong;
6
7pub use core::ptr::null_mut;
8
9pub const EGL_NO_CONTEXT: EGLContext = 0 as EGLContext;
10pub const EGL_NO_SURFACE: EGLSurface = 0 as EGLSurface;
11
12pub const EGL_WINDOW_BIT: u32 = 4;
13
14pub const EGL_OPENGL_ES2_BIT: u32 = 4;
15
16pub const EGL_SUCCESS: u32 = 12288;
17pub const EGL_ALPHA_SIZE: u32 = 12321;
18pub const EGL_BLUE_SIZE: u32 = 12322;
19pub const EGL_GREEN_SIZE: u32 = 12323;
20pub const EGL_RED_SIZE: u32 = 12324;
21pub const EGL_DEPTH_SIZE: u32 = 12325;
22pub const EGL_STENCIL_SIZE: u32 = 12326;
23pub const EGL_NATIVE_VISUAL_ID: u32 = 12334;
24pub const EGL_SURFACE_TYPE: u32 = 12339;
25pub const EGL_NONE: u32 = 0x3038;
26pub const EGL_RENDERABLE_TYPE: u32 = 12352;
27pub const EGL_HEIGHT: u32 = 12374;
28pub const EGL_WIDTH: u32 = 12375;
29pub const EGL_CONTEXT_MAJOR_VERSION: u32 = 0x3098;
30pub const EGL_CONTEXT_MINOR_VERSION_KHR: u32 = 0x30FB;
31pub const EGL_OPENGL_ES_API: u32 = 12448;
32pub const EGL_CONTEXT_OPENGL_PROFILE_MASK: u32 = 0x30FD;
33pub const EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT: u32 = 0x0002;
34pub const EGL_SAMPLES: u32 = 0x3031;
35pub const EGL_OPENGL_ES3_BIT_KHR: u32 = 0x0040;
36pub const EGL_COLOR_BUFFER_TYPE: u32 = 0x303F;
37pub const EGL_RGB_BUFFER: u32 = 0x308E;
38pub const EGL_PBUFFER_BIT: u32 = 0x0001;
39
40pub const EGL_GL_TEXTURE_2D_KHR: u32 = 12465;
41
42pub const EGL_PLATFORM_X11_EXT: u32 = 12757;
43pub const EGL_PLATFORM_GBM_KHR: u32 = 12759;
44
45pub const EGL_LINUX_DMA_BUF_EXT: u32 = 12912;
46pub const EGL_LINUX_DRM_FOURCC_EXT: u32 = 12913;
47pub const EGL_DMA_BUF_PLANE0_FD_EXT: u32 = 12914;
48pub const EGL_DMA_BUF_PLANE0_OFFSET_EXT: u32 = 12915;
49pub const EGL_DMA_BUF_PLANE0_PITCH_EXT: u32 = 12916;
50pub const EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT: u32 = 13379;
51pub const EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT: u32 = 13380;
52pub const EGL_SWAP_BEHAVIOR: i32 = 0x3093;
53pub const EGL_BUFFER_PRESERVED: i32 = 0x3094;
54pub const EGL_BUFFER_DESTROYED: i32 = 0x3095;
55pub type NativeDisplayType = EGLNativeDisplayType;
56pub type NativePixmapType = EGLNativePixmapType;
57pub type NativeWindowType = EGLNativeWindowType;
58pub type EGLint = i32;
59pub type EGLuint64KHR = u64;
60pub type EGLenum = ::std::os::raw::c_uint;
61pub type EGLBoolean = ::std::os::raw::c_uint;
62pub type EGLDisplay = *mut ::std::os::raw::c_void;
63pub type EGLConfig = *mut ::std::os::raw::c_void;
64pub type EGLSurface = *mut ::std::os::raw::c_void;
65pub type EGLContext = *mut ::std::os::raw::c_void;
66pub type EGLClientBuffer = *mut ::std::os::raw::c_void;
67pub type EGLImageKHR = *mut ::std::os::raw::c_void;
68pub type __eglMustCastToProperFunctionPointerType = ::std::option::Option<unsafe extern "C" fn()>;
69pub type PFNEGLBINDAPIPROC = ::std::option::Option<unsafe extern "C" fn(api: EGLenum) -> EGLBoolean>;
70pub type PFNEGLCHOOSECONFIGPROC = ::std::option::Option<
71unsafe extern "C" fn(
72 dpy: EGLDisplay,
73 attrib_list: *const EGLint,
74 configs: *mut EGLConfig,
75 config_size: EGLint,
76 num_config: *mut EGLint,
77) -> EGLBoolean,
78>;
79pub type PFNEGLCOPYBUFFERSPROC = ::std::option::Option<
80unsafe extern "C" fn(
81 dpy: EGLDisplay,
82 surface: EGLSurface,
83 target: EGLNativePixmapType,
84) -> EGLBoolean,
85>;
86pub type PFNEGLCREATECONTEXTPROC = ::std::option::Option<
87unsafe extern "C" fn(
88 dpy: EGLDisplay,
89 config: EGLConfig,
90 share_context: EGLContext,
91 attrib_list: *const EGLint,
92) -> EGLContext,
93>;
94pub type PFNEGLCREATEIMAGEKHRPROC = ::std::option::Option<
95unsafe extern "C" fn(
96 dpy: EGLDisplay,
97 ctx: EGLContext,
98 target: EGLenum,
99 buffer: EGLClientBuffer,
100 attrib_list: *const EGLint,
101) -> EGLImageKHR,
102>;
103pub type PFNEGLDESTROYIMAGEKHRPROC = ::std::option::Option<
104unsafe extern "C" fn(
105 dpy: EGLDisplay,
106 image: EGLImageKHR,
107) -> EGLBoolean,
108>;
109pub type PFNEGLCREATEPBUFFERSURFACEPROC = ::std::option::Option<
110unsafe extern "C" fn(
111 dpy: EGLDisplay,
112 config: EGLConfig,
113 attrib_list: *const EGLint,
114) -> EGLSurface,
115>;
116pub type PFNEGLCREATEPIXMAPSURFACEPROC = ::std::option::Option<
117unsafe extern "C" fn(
118 dpy: EGLDisplay,
119 config: EGLConfig,
120 pixmap: EGLNativePixmapType,
121 attrib_list: *const EGLint,
122) -> EGLSurface,
123>;
124pub type PFNEGLCREATEWINDOWSURFACEPROC = ::std::option::Option<
125unsafe extern "C" fn(
126 dpy: EGLDisplay,
127 config: EGLConfig,
128 win: EGLNativeWindowType,
129 attrib_list: *const EGLint,
130) -> EGLSurface,
131>;
132pub type PFNEGLDESTROYCONTEXTPROC =
133::std::option::Option<unsafe extern "C" fn(dpy: EGLDisplay, ctx: EGLContext) -> EGLBoolean>;
134pub type PFNEGLDESTROYSURFACEPROC =
135::std::option::Option<unsafe extern "C" fn(dpy: EGLDisplay, surface: EGLSurface) -> EGLBoolean>;
136pub type PFNEGLGETCONFIGATTRIBPROC = ::std::option::Option<
137unsafe extern "C" fn(
138 dpy: EGLDisplay,
139 config: EGLConfig,
140 attribute: EGLint,
141 value: *mut EGLint,
142) -> EGLBoolean,
143>;
144pub type PFNEGLGETCONFIGSPROC = ::std::option::Option<
145unsafe extern "C" fn(
146 dpy: EGLDisplay,
147 configs: *mut EGLConfig,
148 config_size: EGLint,
149 num_config: *mut EGLint,
150) -> EGLBoolean,
151>;
152pub type PFNEGLGETCURRENTDISPLAYPROC = ::std::option::Option<unsafe extern "C" fn() -> EGLDisplay>;
153pub type PFNEGLGETCURRENTSURFACEPROC =
154::std::option::Option<unsafe extern "C" fn(readdraw: EGLint) -> EGLSurface>;
155pub type PFNEGLGETDISPLAYPROC =
156::std::option::Option<unsafe extern "C" fn(display_id: EGLNativeDisplayType) -> EGLDisplay>;
157pub type PFNEGLGETERRORPROC = ::std::option::Option<unsafe extern "C" fn() -> EGLint>;
158pub type PFNEGLGETPROCADDRESSPROC = ::std::option::Option<
159unsafe extern "C" fn(
160 procname: *const ::std::os::raw::c_char,
161) -> *mut ::std::os::raw::c_void,
162>;
163pub type PFNEGLINITIALIZEPROC = ::std::option::Option<
164unsafe extern "C" fn(dpy: EGLDisplay, major: *mut EGLint, minor: *mut EGLint) -> EGLBoolean,
165>;
166pub type PFNEGLMAKECURRENTPROC = ::std::option::Option<
167unsafe extern "C" fn(
168 dpy: EGLDisplay,
169 draw: EGLSurface,
170 read: EGLSurface,
171 ctx: EGLContext,
172) -> EGLBoolean,
173>;
174pub type PFNEGLQUERYCONTEXTPROC = ::std::option::Option<
175unsafe extern "C" fn(
176 dpy: EGLDisplay,
177 ctx: EGLContext,
178 attribute: EGLint,
179 value: *mut EGLint,
180) -> EGLBoolean,
181>;
182pub type PFNEGLQUERYSTRINGPROC = ::std::option::Option<
183unsafe extern "C" fn(dpy: EGLDisplay, name: EGLint) -> *const ::std::os::raw::c_char,
184>;
185pub type PFNEGLQUERYSURFACEPROC = ::std::option::Option<
186unsafe extern "C" fn(
187 dpy: EGLDisplay,
188 surface: EGLSurface,
189 attribute: EGLint,
190 value: *mut EGLint,
191) -> EGLBoolean,
192>;
193pub type PFNEGLSWAPBUFFERSPROC =
194::std::option::Option<unsafe extern "C" fn(dpy: EGLDisplay, surface: EGLSurface) -> EGLBoolean>;
195pub type PFNEGLTERMINATEPROC =
196::std::option::Option<unsafe extern "C" fn(dpy: EGLDisplay) -> EGLBoolean>;
197pub type PFNEGLWAITGLPROC = ::std::option::Option<unsafe extern "C" fn() -> EGLBoolean>;
198pub type PFNEGLWAITNATIVEPROC =
199::std::option::Option<unsafe extern "C" fn(engine: EGLint) -> EGLBoolean>;
200pub type PFNEGLBINDTEXIMAGEPROC = ::std::option::Option<
201unsafe extern "C" fn(dpy: EGLDisplay, surface: EGLSurface, buffer: EGLint) -> EGLBoolean,
202>;
203pub type PFNEGLRELEASETEXIMAGEPROC = ::std::option::Option<
204unsafe extern "C" fn(dpy: EGLDisplay, surface: EGLSurface, buffer: EGLint) -> EGLBoolean,
205>;
206pub type PFNEGLSURFACEATTRIBPROC = ::std::option::Option<
207unsafe extern "C" fn(
208 dpy: EGLDisplay,
209 surface: EGLSurface,
210 attribute: EGLint,
211 value: EGLint,
212) -> EGLBoolean,
213>;
214pub type PFNEGLSWAPINTERVALPROC =
215::std::option::Option<unsafe extern "C" fn(dpy: EGLDisplay, interval: EGLint) -> EGLBoolean>;
216
217pub type PFNEGLGETPLATFORMDISPLAYEXTPROC = ::std::option::Option<
218unsafe extern "C" fn(
219 platform: EGLenum,
220 native_display: *mut ::std::os::raw::c_void,
221 attrib_list: *const EGLint,
222) -> EGLDisplay,
223>;
224
225pub type PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC = ::std::option::Option<
226unsafe extern "C" fn(
227 dpy: EGLDisplay,
228 image: EGLImageKHR,
229 fourcc: *mut i32,
230 num_planes: *mut i32,
231 modifiers: *mut EGLuint64KHR,
232) -> EGLBoolean,
233>;
234pub type PFNEGLEXPORTDMABUFIMAGEMESAPROC = ::std::option::Option<
235unsafe extern "C" fn(
236 dpy: EGLDisplay,
237 image: EGLImageKHR,
238 fds: *mut i32,
239 strides: *mut EGLint,
240 offsets: *mut EGLint,
241) -> EGLBoolean,
242>;
243
244type PFNGLEGLIMAGETARGETTEXTURE2DOESPROC = ::std::option::Option<
246unsafe extern "C" fn(
247 super::gl_sys::GLenum,
248 EGLImageKHR,
249),
250>;
251
252type PFNEGLPRESENTATIONTIMEANDROID = ::std::option::Option<
253unsafe extern "C" fn(
254 dpy: EGLDisplay,
255 surface: EGLSurface,
256 time: i64
257),
258>;
259
260type PFNEGLSURFACEATTRIB = ::std::option::Option<
261unsafe extern "C" fn(
262 dpy: EGLDisplay,
263 surface: EGLSurface,
264 attrib: EGLint,
265 value: EGLint
266)->EGLBoolean,
267>;
268
269pub struct LibEgl {
270 pub eglPresentationTimeANDROID: PFNEGLPRESENTATIONTIMEANDROID,
271 pub eglBindAPI: PFNEGLBINDAPIPROC,
272 pub eglChooseConfig: PFNEGLCHOOSECONFIGPROC,
273 pub eglCopyBuffers: PFNEGLCOPYBUFFERSPROC,
274 pub eglCreateContext: PFNEGLCREATECONTEXTPROC,
275 pub eglCreatePbufferSurface: PFNEGLCREATEPBUFFERSURFACEPROC,
276 pub eglCreatePixmapSurface: PFNEGLCREATEPIXMAPSURFACEPROC,
277 pub eglCreateWindowSurface: PFNEGLCREATEWINDOWSURFACEPROC,
278 pub eglDestroyContext: PFNEGLDESTROYCONTEXTPROC,
279 pub eglDestroySurface: PFNEGLDESTROYSURFACEPROC,
280 pub eglGetConfigAttrib: PFNEGLGETCONFIGATTRIBPROC,
281 pub eglGetConfigs: PFNEGLGETCONFIGSPROC,
282 pub eglGetCurrentDisplay: PFNEGLGETCURRENTDISPLAYPROC,
283 pub eglGetCurrentSurface: PFNEGLGETCURRENTSURFACEPROC,
284 pub eglGetDisplay: PFNEGLGETDISPLAYPROC,
285 pub eglGetError: PFNEGLGETERRORPROC,
286 pub eglGetProcAddress: PFNEGLGETPROCADDRESSPROC,
287 pub eglInitialize: PFNEGLINITIALIZEPROC,
288 pub eglMakeCurrent: PFNEGLMAKECURRENTPROC,
289 pub eglQueryContext: PFNEGLQUERYCONTEXTPROC,
290 pub eglQueryString: PFNEGLQUERYSTRINGPROC,
291 pub eglQuerySurface: PFNEGLQUERYSURFACEPROC,
292 pub eglSwapBuffers: PFNEGLSWAPBUFFERSPROC,
293 pub eglTerminate: PFNEGLTERMINATEPROC,
294 pub eglWaitGL: PFNEGLWAITGLPROC,
295 pub eglWaitNative: PFNEGLWAITNATIVEPROC,
296 pub eglBindTexImage: PFNEGLBINDTEXIMAGEPROC,
297 pub eglReleaseTexImage: PFNEGLRELEASETEXIMAGEPROC,
298 pub eglSurfaceAttrib: PFNEGLSURFACEATTRIBPROC,
299 pub eglSwapInterval: PFNEGLSWAPINTERVALPROC,
300
301 pub eglCreateImageKHR: PFNEGLCREATEIMAGEKHRPROC,
302 pub eglDestroyImageKHR: PFNEGLDESTROYIMAGEKHRPROC,
303 pub eglExportDMABUFImageQueryMESA: PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC,
304 pub eglExportDMABUFImageMESA: PFNEGLEXPORTDMABUFIMAGEMESAPROC,
305 pub eglGetPlatformDisplayEXT: PFNEGLGETPLATFORMDISPLAYEXTPROC,
306
307 pub glEGLImageTargetTexture2DOES: PFNGLEGLIMAGETARGETTEXTURE2DOESPROC,
309
310 _keep_module_alive: ModuleLoader,
311}
312
313use std::ffi::CStr;
314
315use crate::module_loader::ModuleLoader;
316
317impl LibEgl {
318 pub fn try_load() -> Option<LibEgl> {
319
320 let module = ModuleLoader::load("libEGL.so").or_else(|_| ModuleLoader::load("libEGL.so.1")).ok()?;
321
322 let eglGetProcAddress: PFNEGLGETPROCADDRESSPROC = module.get_symbol("eglGetProcAddress").ok();
323 macro_rules! get_ext_fn {
324 ($name:literal) => {
325 eglGetProcAddress.and_then(|gpa| unsafe {
326 std::mem::transmute(gpa(CStr::from_bytes_with_nul(concat!($name, "\0").as_bytes()).unwrap().as_ptr()))
327 })
328 }
329 }
330
331 Some(LibEgl {
332 eglPresentationTimeANDROID: module.get_symbol("eglPresentationTimeANDROID").ok(),
333 eglBindAPI: module.get_symbol("eglBindAPI").ok(),
334 eglChooseConfig: module.get_symbol("eglChooseConfig").ok(),
335 eglCopyBuffers: module.get_symbol("eglCopyBuffers").ok(),
336 eglCreateContext: module.get_symbol("eglCreateContext").ok(),
337 eglCreatePbufferSurface: module.get_symbol("eglCreatePbufferSurface").ok(),
338 eglCreatePixmapSurface: module.get_symbol("eglCreatePixmapSurface").ok(),
339 eglCreateWindowSurface: module.get_symbol("eglCreateWindowSurface").ok(),
340 eglDestroyContext: module.get_symbol("eglDestroyContext").ok(),
341 eglDestroySurface: module.get_symbol("eglDestroySurface").ok(),
342 eglGetConfigAttrib: module.get_symbol("eglGetConfigAttrib").ok(),
343 eglGetConfigs: module.get_symbol("eglGetConfigs").ok(),
344 eglGetCurrentDisplay: module.get_symbol("eglGetCurrentDisplay").ok(),
345 eglGetCurrentSurface: module.get_symbol("eglGetCurrentSurface").ok(),
346 eglGetDisplay: module.get_symbol("eglGetDisplay").ok(),
347 eglGetError: module.get_symbol("eglGetError").ok(),
348 eglGetProcAddress,
349 eglInitialize: module.get_symbol("eglInitialize").ok(),
350 eglMakeCurrent: module.get_symbol("eglMakeCurrent").ok(),
351 eglQueryContext: module.get_symbol("eglQueryContext").ok(),
352 eglQueryString: module.get_symbol("eglQueryString").ok(),
353 eglQuerySurface: module.get_symbol("eglQuerySurface").ok(),
354 eglSwapBuffers: module.get_symbol("eglSwapBuffers").ok(),
355 eglTerminate: module.get_symbol("eglTerminate").ok(),
356 eglWaitGL: module.get_symbol("eglWaitGL").ok(),
357 eglWaitNative: module.get_symbol("eglWaitNative").ok(),
358 eglBindTexImage: module.get_symbol("eglBindTexImage").ok(),
359 eglReleaseTexImage: module.get_symbol("eglReleaseTexImage").ok(),
360 eglSurfaceAttrib: module.get_symbol("eglSurfaceAttrib").ok(),
361 eglSwapInterval: module.get_symbol("eglSwapInterval").ok(),
362
363 eglCreateImageKHR: get_ext_fn!("eglCreateImageKHR"),
364 eglDestroyImageKHR: get_ext_fn!("eglDestroyImageKHR"),
365 eglExportDMABUFImageQueryMESA: get_ext_fn!("eglExportDMABUFImageQueryMESA"),
366 eglExportDMABUFImageMESA: get_ext_fn!("eglExportDMABUFImageMESA"),
367 eglGetPlatformDisplayEXT: get_ext_fn!("eglGetPlatformDisplayEXT"),
368
369 glEGLImageTargetTexture2DOES: get_ext_fn!("glEGLImageTargetTexture2DOES"),
370
371 _keep_module_alive: module,
372 })
373 }
374}
375
376#[derive(Debug)]
377pub enum EglError {
378 NoDisplay,
379 InitializeFailed,
380 CreateContextFailed,
381 ChooseConfigFailed,
382}
383
384pub struct Egl {}
385
386#[cfg(target_os="android")]
387pub unsafe fn create_egl_context(
388 egl: &mut LibEgl,
389 display: *mut std::ffi::c_void,
390) -> Result<(EGLContext, EGLConfig, EGLDisplay), EglError> {
391
392 let display = (egl.eglGetDisplay.unwrap())(display as _);
393 if display == null_mut() {
394 return Err(EglError::NoDisplay);
395 }
396
397 if (egl.eglInitialize.unwrap())(display, null_mut(), null_mut()) == 0 {
398 return Err(EglError::InitializeFailed);
399 }
400
401 #[rustfmt::skip]
402 let cfg_attributes = vec![
403 EGL_SURFACE_TYPE,
404 EGL_WINDOW_BIT,
405 EGL_RED_SIZE,
406 8,
407 EGL_GREEN_SIZE,
408 8,
409 EGL_BLUE_SIZE,
410 8,
411 EGL_ALPHA_SIZE,
412 0,
413 EGL_DEPTH_SIZE,
414 24,
415 EGL_STENCIL_SIZE,
416 0,
417 EGL_NONE,
418 ];
419 let mut available_cfgs: Vec<EGLConfig> = vec![null_mut(); 32];
420 let mut cfg_count = 0;
421
422 (egl.eglChooseConfig.unwrap())(
423 display,
424 cfg_attributes.as_ptr() as _,
425 available_cfgs.as_ptr() as _,
426 32,
427 &mut cfg_count as *mut _ as *mut _,
428 );
429 assert!(cfg_count > 0);
430 assert!(cfg_count <= 32);
431
432 let mut config: EGLConfig = null_mut();
434 let mut exact_cfg_found = false;
435 for c in &mut available_cfgs[0..cfg_count] {
436 let mut r: i32 = 0;
437 let mut g: i32 = 0;
438 let mut b: i32 = 0;
439 let mut a: i32 = 0;
440 let mut d: i32 = 0;
441 if (egl.eglGetConfigAttrib.unwrap())(display, *c, EGL_RED_SIZE as _, &mut r) == 1
442 && (egl.eglGetConfigAttrib.unwrap())(display, *c, EGL_GREEN_SIZE as _, &mut g) == 1
443 && (egl.eglGetConfigAttrib.unwrap())(display, *c, EGL_BLUE_SIZE as _, &mut b) == 1
444 && (egl.eglGetConfigAttrib.unwrap())(display, *c, EGL_ALPHA_SIZE as _, &mut a) == 1
445 && (egl.eglGetConfigAttrib.unwrap())(display, *c, EGL_DEPTH_SIZE as _, &mut d) == 1
446 && r == 8
447 && g == 8
448 && b == 8
449 && a == 0
450 && d == 16
451 {
452 exact_cfg_found = true;
453 config = *c;
454 break;
455 }
456 }
457 if !exact_cfg_found {
458 config = available_cfgs[0];
459 }
460 #[cfg(use_gles_3)]
461 let ctx_attributes = vec![EGL_CONTEXT_MAJOR_VERSION, 3, EGL_NONE];
462 #[cfg(not(use_gles_3))]
463 let ctx_attributes = vec![EGL_CONTEXT_MAJOR_VERSION, 2, EGL_NONE];
464
465 let context = (egl.eglCreateContext.unwrap())(
466 display,
467 config,
468 null_mut(),
469 ctx_attributes.as_ptr() as _,
470 );
471 if context.is_null() {
472 return Err(EglError::CreateContextFailed);
473 }
474
475 return Ok((context, config, display));
476}
477
478#[cfg(target_os="android")]
479pub unsafe fn create_egl_context_openxr(
480 egl: &mut LibEgl,
481 display: *mut std::ffi::c_void,
482) -> Result<(EGLContext, EGLConfig, EGLDisplay), EglError> {
483
484 let display = (egl.eglGetDisplay.unwrap())(display as _);
485 if display == null_mut() {
486 return Err(EglError::NoDisplay);
487 }
488
489 if (egl.eglInitialize.unwrap())(display, null_mut(), null_mut()) == 0 {
490 return Err(EglError::InitializeFailed);
491 }
492
493
494 #[rustfmt::skip]
495 let cfg_attributes = vec![
496 EGL_RED_SIZE,
497 8,
498 EGL_GREEN_SIZE,
499 8,
500 EGL_BLUE_SIZE,
501 8,
502 EGL_ALPHA_SIZE,
503 8,
504 EGL_DEPTH_SIZE,
505 0,
506 EGL_STENCIL_SIZE,
507 0,
508 EGL_SAMPLES,
509 0,
510 EGL_NONE,
511 ];
512 let mut available_cfgs: Vec<EGLConfig> = vec![null_mut(); 1024];
513 let mut cfg_count = 0;
514
515 (egl.eglGetConfigs.unwrap())(
516 display,
517 available_cfgs.as_ptr() as _,
518 available_cfgs.len() as _,
519 &mut cfg_count as *mut _ as *mut _,
520 );
521 let mut config: EGLConfig = null_mut();
534 let mut exact_cfg_found = false;
535
536
537 for c in &mut available_cfgs[0..cfg_count] {
538 let mut value = 0u32;
539 (egl.eglGetConfigAttrib.unwrap())(display, *c, EGL_RENDERABLE_TYPE as _, &mut value as *mut _ as *mut _);
540 if (value & EGL_OPENGL_ES3_BIT_KHR) != EGL_OPENGL_ES3_BIT_KHR{
541 continue;
542 }
543 (egl.eglGetConfigAttrib.unwrap())(display, *c, EGL_SURFACE_TYPE as _, &mut value as *mut _ as *mut _);
544 if (value & (EGL_WINDOW_BIT | EGL_PBUFFER_BIT)) != (EGL_WINDOW_BIT | EGL_PBUFFER_BIT) {
545 continue;
546 }
547
548 let mut j = 0;
549 while cfg_attributes[j] != EGL_NONE{
550 let mut value = 0u32;
551 (egl.eglGetConfigAttrib.unwrap())(display, *c, cfg_attributes[j] as _, &mut value as *mut _ as *mut _);
552 if value != cfg_attributes[j+1]{
553 crate::log!("FAILED AT {} {} {}", value, cfg_attributes[j+1], j);
554 break;
555 }
556 j+=2;
557 }
558 if cfg_attributes[j] == EGL_NONE{
559 exact_cfg_found = true;
560 config = *c;
561 break;
562 }
563 }
564
565 if !exact_cfg_found {
566 config = available_cfgs[0];
567 }
568 let ctx_attributes = vec![EGL_CONTEXT_MAJOR_VERSION, 3, EGL_NONE];
569 let context = (egl.eglCreateContext.unwrap())(
570 display,
571 config,
572 null_mut(),
573 ctx_attributes.as_ptr() as _,
574 );
575 if context.is_null() {
576 return Err(EglError::CreateContextFailed);
577 }
578
579 return Ok((context, config, display));
580}
581
582
583#[cfg(target_env="ohos")]
584pub unsafe fn create_egl_context(
585 egl: &mut LibEgl
586) -> Result<(EGLContext, EGLConfig, EGLDisplay), EglError> {
587 let display = (egl.eglGetDisplay.unwrap())(null_mut());
588 if display == null_mut() {
589 return Err(EglError::NoDisplay);
590 }
591
592 if (egl.eglInitialize.unwrap())(display,null_mut(),null_mut()) == 0 {
593 return Err(EglError::InitializeFailed);
594 }
595
596 #[rustfmt::skip]
597 let cfg_attributes = vec![
598 EGL_SURFACE_TYPE,
599 EGL_WINDOW_BIT,
600 EGL_RED_SIZE, 8,
601 EGL_GREEN_SIZE, 8,
602 EGL_BLUE_SIZE, 8,
603 EGL_ALPHA_SIZE, 8,
604 EGL_RENDERABLE_TYPE,
605 EGL_OPENGL_ES2_BIT,
606 EGL_DEPTH_SIZE, 0,
607 EGL_STENCIL_SIZE, 0,
608 EGL_NONE
609 ];
610 let available_cfgs: Vec<EGLConfig> = vec![null_mut(); 1];
611 let mut cfg_count = 0;
612
613 if (egl.eglChooseConfig.unwrap())(
614 display,
615 cfg_attributes.as_ptr() as _,
616 available_cfgs.as_ptr() as _,
617 1,&mut cfg_count as *mut _ as *mut _,
618 ) == 0 {
619 return Err(EglError::ChooseConfigFailed);
620 }
621
622 assert!(cfg_count > 0);
623
624 let config = available_cfgs[0];
625
626 #[cfg(ohos_sim)]
627 let ctx_attributes = vec![
628 EGL_CONTEXT_MAJOR_VERSION, 2, EGL_CONTEXT_MINOR_VERSION_KHR , 0,
630 EGL_CONTEXT_OPENGL_PROFILE_MASK,
632 EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT, EGL_NONE, 0, 0, 0,
634 ];
635
636 #[cfg(not(ohos_sim))]
637 let ctx_attributes = vec![
638 EGL_CONTEXT_MAJOR_VERSION,
639 #[cfg(use_gles_3)]
640 3, #[cfg(not(use_gles_3))]
642 2, EGL_CONTEXT_MINOR_VERSION_KHR , 0,
644 EGL_NONE,
645 ];
646
647 let context = (egl.eglCreateContext.unwrap())(
648 display,
649 config,
650 null_mut(),
651 ctx_attributes.as_ptr() as _
652 );
653 if context.is_null(){
654 return Err(EglError::CreateContextFailed);
655 }
656 crate::log!("create elg context success");
657 return Ok((context, config, display));
658}