1#![allow(non_upper_case_globals)]
126#![allow(non_snake_case)]
127
128extern crate libc;
129
130use std::convert::{TryFrom, TryInto};
131use std::ffi::CStr;
132use std::ffi::CString;
133use std::fmt;
134use std::ptr;
135
136use libc::{c_uint, c_char, c_void};
137
138pub trait Api {
140 fn version(&self) -> Version;
142}
143
144pub trait Downcast<V> {
145 fn downcast(&self) -> &V;
146}
147
148impl<T> Downcast<T> for T {
149 fn downcast(&self) -> &T {
150 self
151 }
152}
153
154pub trait Upcast<V> {
155 fn upcast(&self) -> Option<&V>;
156}
157
158impl<T> Upcast<T> for T {
159 fn upcast(&self) -> Option<&T> {
160 Some(self)
161 }
162}
163
164pub struct Instance<T> {
169 api: T
170}
171
172impl<T> Instance<T> {
173 #[inline(always)]
175 pub fn cast_into<U: From<T>>(self) -> Instance<U> {
176 Instance {
177 api: self.api.into()
178 }
179 }
180
181 #[inline(always)]
183 pub fn try_cast_into<U: TryFrom<T>>(self) -> Result<Instance<U>, Instance<U::Error>> {
184 match self.api.try_into() {
185 Ok(t) => Ok(Instance {
186 api: t
187 }),
188 Err(e) => Err(Instance {
189 api: e
190 })
191 }
192 }
193
194 #[inline(always)]
196 pub fn version(&self) -> Version where T: Api {
197 self.api.version()
198 }
199}
200
201impl<T> Instance<T> {
202 #[inline(always)]
203 pub const fn new(api: T) -> Instance<T> {
204 Instance {
205 api
206 }
207 }
208}
209
210impl<T: fmt::Debug> fmt::Debug for Instance<T> {
211 #[inline(always)]
212 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
213 write!(f, "Instance({:?})", self.api)
214 }
215}
216
217impl<T> From<T> for Instance<T> {
218 #[inline(always)]
219 fn from(t: T) -> Instance<T> {
220 Instance::new(t)
221 }
222}
223
224#[cfg(feature = "1_0")]
229mod egl1_0 {
230 use super::*;
231
232 pub type Boolean = c_uint;
233 pub type Int = i32;
234 pub type Attrib = usize;
235 pub type EGLDisplay = *mut c_void;
236 pub type EGLConfig = *mut c_void;
237 pub type EGLContext = *mut c_void;
238 pub type EGLSurface = *mut c_void;
239 pub type NativeDisplayType = *mut c_void;
240
241 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
242 pub struct Display(pub(crate) EGLDisplay);
243
244 impl Display {
245 #[inline]
246 pub unsafe fn from_ptr(ptr: EGLDisplay) -> Display {
247 Display(ptr)
248 }
249
250 #[inline]
251 pub fn as_ptr(&self) -> EGLDisplay {
252 self.0
253 }
254 }
255
256 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
257 pub struct Config(pub(crate) EGLConfig);
258
259 impl Config {
260 #[inline]
261 pub unsafe fn from_ptr(ptr: EGLConfig) -> Config {
262 Config(ptr)
263 }
264
265 #[inline]
266 pub fn as_ptr(&self) -> EGLConfig {
267 self.0
268 }
269 }
270
271 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
272 pub struct Context(pub(crate) EGLContext);
273
274 impl Context {
275 #[inline]
276 pub unsafe fn from_ptr(ptr: EGLContext) -> Context {
277 Context(ptr)
278 }
279
280 #[inline]
281 pub fn as_ptr(&self) -> EGLContext {
282 self.0
283 }
284 }
285
286 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
287 pub struct Surface(pub(crate) EGLSurface);
288
289 impl Surface {
290 #[inline]
291 pub unsafe fn from_ptr(ptr: EGLSurface) -> Surface {
292 Surface(ptr)
293 }
294
295 #[inline]
296 pub fn as_ptr(&self) -> EGLSurface {
297 self.0
298 }
299 }
300
301 #[cfg(not(android))]
302 pub type NativePixmapType = *mut c_void;
303
304 #[cfg(not(android))]
305 pub type NativeWindowType = *mut c_void;
306
307 #[repr(C)]
308 #[cfg(android)]
309 struct android_native_window_t;
310
311 #[repr(C)]
312 #[cfg(android)]
313 struct egl_native_pixmap_t;
314
315 #[cfg(android)]
316 pub type NativePixmapType = *mut egl_native_pixmap_t;
317
318 #[cfg(android)]
319 pub type NativeWindowType = *mut android_native_window_t;
320
321 pub const ALPHA_SIZE: Int = 0x3021;
322 pub const BAD_ACCESS: Int = 0x3002;
323 pub const BAD_ALLOC: Int = 0x3003;
324 pub const BAD_ATTRIBUTE: Int = 0x3004;
325 pub const BAD_CONFIG: Int = 0x3005;
326 pub const BAD_CONTEXT: Int = 0x3006;
327 pub const BAD_CURRENT_SURFACE: Int = 0x3007;
328 pub const BAD_DISPLAY: Int = 0x3008;
329 pub const BAD_MATCH: Int = 0x3009;
330 pub const BAD_NATIVE_PIXMAP: Int = 0x300A;
331 pub const BAD_NATIVE_WINDOW: Int = 0x300B;
332 pub const BAD_PARAMETER: Int = 0x300C;
333 pub const BAD_SURFACE: Int = 0x300D;
334 pub const BLUE_SIZE: Int = 0x3022;
335 pub const BUFFER_SIZE: Int = 0x3020;
336 pub const CONFIG_CAVEAT: Int = 0x3027;
337 pub const CONFIG_ID: Int = 0x3028;
338 pub const CORE_NATIVE_ENGINE: Int = 0x305B;
339 pub const DEPTH_SIZE: Int = 0x3025;
340 pub const DONT_CARE: Int = -1;
341 pub const DRAW: Int = 0x3059;
342 pub const EXTENSIONS: Int = 0x3055;
343 pub const FALSE: Boolean = 0;
344 pub const GREEN_SIZE: Int = 0x3023;
345 pub const HEIGHT: Int = 0x3056;
346 pub const LARGEST_PBUFFER: Int = 0x3058;
347 pub const LEVEL: Int = 0x3029;
348 pub const MAX_PBUFFER_HEIGHT: Int = 0x302A;
349 pub const MAX_PBUFFER_PIXELS: Int = 0x302B;
350 pub const MAX_PBUFFER_WIDTH: Int = 0x302C;
351 pub const NATIVE_RENDERABLE: Int = 0x302D;
352 pub const NATIVE_VISUAL_ID: Int = 0x302E;
353 pub const NATIVE_VISUAL_TYPE: Int = 0x302F;
354 pub const NONE: Int = 0x3038;
355 pub const ATTRIB_NONE: Attrib = 0x3038;
356 pub const NON_CONFORMANT_CONFIG: Int = 0x3051;
357 pub const NOT_INITIALIZED: Int = 0x3001;
358 pub const NO_CONTEXT: EGLContext = 0 as EGLContext;
359 pub const NO_DISPLAY: EGLDisplay = 0 as EGLDisplay;
360 pub const NO_SURFACE: EGLSurface = 0 as EGLSurface;
361 pub const PBUFFER_BIT: Int = 0x0001;
362 pub const PIXMAP_BIT: Int = 0x0002;
363 pub const READ: Int = 0x305A;
364 pub const RED_SIZE: Int = 0x3024;
365 pub const SAMPLES: Int = 0x3031;
366 pub const SAMPLE_BUFFERS: Int = 0x3032;
367 pub const SLOW_CONFIG: Int = 0x3050;
368 pub const STENCIL_SIZE: Int = 0x3026;
369 pub const SUCCESS: Int = 0x3000;
370 pub const SURFACE_TYPE: Int = 0x3033;
371 pub const TRANSPARENT_BLUE_VALUE: Int = 0x3035;
372 pub const TRANSPARENT_GREEN_VALUE: Int = 0x3036;
373 pub const TRANSPARENT_RED_VALUE: Int = 0x3037;
374 pub const TRANSPARENT_RGB: Int = 0x3052;
375 pub const TRANSPARENT_TYPE: Int = 0x3034;
376 pub const TRUE: Boolean = 1;
377 pub const VENDOR: Int = 0x3053;
378 pub const VERSION: Int = 0x3054;
379 pub const WIDTH: Int = 0x3057;
380 pub const WINDOW_BIT: Int = 0x0004;
381
382 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
384 pub enum Error {
385 NotInitialized,
388
389 BadAccess,
392
393 BadAlloc,
395
396 BadAttribute,
399
400 BadContext,
402
403 BadConfig,
405
406 BadCurrentSurface,
409
410 BadDisplay,
412
413 BadSurface,
416
417 BadMatch,
420
421 BadParameter,
423
424 BadNativePixmap,
426
427 BadNativeWindow,
429
430 ContextLost,
434 }
435
436 impl std::error::Error for Error {
437 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
438 None
439 }
440 }
441
442 impl Error {
443 pub fn native(&self) -> Int {
444 use Error::*;
445 match self {
446 NotInitialized => NOT_INITIALIZED,
447 BadAccess => BAD_ACCESS,
448 BadAlloc => BAD_ALLOC,
449 BadAttribute => BAD_ATTRIBUTE,
450 BadContext => BAD_CONTEXT,
451 BadConfig => BAD_CONFIG,
452 BadCurrentSurface => BAD_CURRENT_SURFACE,
453 BadDisplay => BAD_DISPLAY,
454 BadSurface => BAD_SURFACE,
455 BadMatch => BAD_MATCH,
456 BadParameter => BAD_PARAMETER,
457 BadNativePixmap => BAD_NATIVE_PIXMAP,
458 BadNativeWindow => BAD_NATIVE_WINDOW,
459 ContextLost => CONTEXT_LOST,
460 }
461 }
462
463 fn message(&self) -> &'static str {
464 use Error::*;
465 match self {
466 NotInitialized => "EGL is not initialized, or could not be initialized, for the specified EGL display connection.",
467 BadAccess => "EGL cannot access a requested resource (for example a context is bound in another thread.",
468 BadAlloc => "EGL failed to allocate resources for the requested operation.",
469 BadAttribute => "An unrecognized attribute or attribute value was passed in the attribute list.",
470 BadContext => "An Context argument does not name a valid EGL rendering context.",
471 BadConfig => "An Config argument does not name a valid EGL frame buffer configuration.",
472 BadCurrentSurface => "The current surface of the calling thread is a window, pixel buffer or pixmap that is no longer valid.",
473 BadDisplay => "An Display argument does not name a valid EGL display connection.",
474 BadSurface => "An Surface argument does not name a valid surface (window, pixel buffer or pixmap) configured for GL rendering.",
475 BadMatch => "Arguments are inconsistent (for example, a valid context requires buffers not supplied by a valid surface.",
476 BadParameter => "One or more argument values are invalid.",
477 BadNativePixmap => "A NativePixmapType argument does not refer to a valid native pixmap.",
478 BadNativeWindow => "A NativeWindowType argument does not refer to a valid native window.",
479 ContextLost => "A power management event has occurred. The application must destroy all contexts and reinitialise OpenGL ES state and objects to continue rendering."
480 }
481 }
482 }
483
484 impl From<Error> for Int {
485 fn from(e: Error) -> Int {
486 e.native()
487 }
488 }
489
490 impl TryFrom<Int> for Error {
491 type Error = Int;
492
493 fn try_from(e: Int) -> Result<Error, Int> {
494 use Error::*;
495 match e {
496 NOT_INITIALIZED => Ok(NotInitialized),
497 BAD_ACCESS => Ok(BadAccess),
498 BAD_ALLOC => Ok(BadAlloc),
499 BAD_ATTRIBUTE => Ok(BadAttribute),
500 BAD_CONTEXT => Ok(BadContext),
501 BAD_CONFIG => Ok(BadConfig),
502 BAD_CURRENT_SURFACE => Ok(BadCurrentSurface),
503 BAD_DISPLAY => Ok(BadDisplay),
504 BAD_SURFACE => Ok(BadSurface),
505 BAD_MATCH => Ok(BadMatch),
506 BAD_PARAMETER => Ok(BadParameter),
507 BAD_NATIVE_PIXMAP => Ok(BadNativePixmap),
508 BAD_NATIVE_WINDOW => Ok(BadNativeWindow),
509 CONTEXT_LOST => Ok(ContextLost),
510 _ => Err(e),
511 }
512 }
513 }
514
515 impl fmt::Display for Error {
516 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
517 self.message().fmt(f)
518 }
519 }
520
521 pub fn check_int_list(attrib_list: &[Int]) -> Result<(), Error> {
522 if attrib_list.last() == Some(&NONE) {
523 Ok(())
524 } else {
525 Err(Error::BadParameter)
526 }
527 }
528
529 pub fn check_attrib_list(attrib_list: &[Attrib]) -> Result<(), Error> {
530 if attrib_list.last() == Some(&ATTRIB_NONE) {
531 Ok(())
532 } else {
533 Err(Error::BadParameter)
534 }
535 }
536
537 impl<T: api::EGL1_0> Instance<T> {
538 pub fn matching_config_count(&self, display: Display, attrib_list: &[Int]) -> Result<usize, Error> {
547 check_int_list(attrib_list)?;
548 unsafe {
549 let mut count = 0;
550
551 if self.api.eglChooseConfig(
552 display.as_ptr(),
553 attrib_list.as_ptr(),
554 ptr::null_mut(),
555 0,
556 &mut count,
557 ) == TRUE
558 {
559 Ok(count as usize)
560 } else {
561 Err(self.get_error().unwrap())
562 }
563 }
564 }
565
566 pub fn choose_config(&self, display: Display, attrib_list: &[Int], configs: &mut Vec<Config>) -> Result<(), Error> {
597 check_int_list(attrib_list)?;
598 unsafe {
599 let capacity = configs.capacity();
600 let mut count = 0;
601
602 if self.api.eglChooseConfig(
603 display.as_ptr(),
604 attrib_list.as_ptr(),
605 configs.as_mut_ptr() as *mut EGLConfig,
606 capacity.try_into().unwrap(),
607 &mut count,
608 ) == TRUE
609 {
610 configs.set_len(count as usize);
611 Ok(())
612 } else {
613 Err(self.get_error().unwrap())
614 }
615 }
616 }
617
618 pub fn choose_first_config(&self, display: Display, attrib_list: &[Int]) -> Result<Option<Config>, Error> {
639 let mut configs = Vec::with_capacity(1);
640 self.choose_config(display, attrib_list, &mut configs)?;
641 Ok(configs.first().map(|config| *config))
642 }
643
644 pub fn copy_buffers(&self, display: Display, surface: Surface, target: NativePixmapType) -> Result<(), Error> {
646 unsafe {
647 if self.api.eglCopyBuffers(display.as_ptr(), surface.as_ptr(), target) == TRUE {
648 Ok(())
649 } else {
650 Err(self.get_error().unwrap())
651 }
652 }
653 }
654
655 pub fn create_context(&self, display: Display, config: Config, share_context: Option<Context>, attrib_list: &[Int]) -> Result<Context, Error> {
660 check_int_list(attrib_list)?;
661 unsafe {
662 let share_context = match share_context {
663 Some(share_context) => share_context.as_ptr(),
664 None => NO_CONTEXT,
665 };
666
667 let context = self.api.eglCreateContext(
668 display.as_ptr(),
669 config.as_ptr(),
670 share_context,
671 attrib_list.as_ptr(),
672 );
673
674 if context != NO_CONTEXT {
675 Ok(Context(context))
676 } else {
677 Err(self.get_error().unwrap())
678 }
679 }
680 }
681
682 pub fn create_pbuffer_surface(&self, display: Display, config: Config, attrib_list: &[Int]) -> Result<Surface, Error> {
687 check_int_list(attrib_list)?;
688 unsafe {
689 let surface =
690 self.api.eglCreatePbufferSurface(display.as_ptr(), config.as_ptr(), attrib_list.as_ptr());
691
692 if surface != NO_SURFACE {
693 Ok(Surface(surface))
694 } else {
695 Err(self.get_error().unwrap())
696 }
697 }
698 }
699
700 pub unsafe fn create_pixmap_surface(&self, display: Display, config: Config, pixmap: NativePixmapType, attrib_list: &[Int]) -> Result<Surface, Error> {
708 check_int_list(attrib_list)?;
709 let surface = self.api.eglCreatePixmapSurface(
710 display.as_ptr(),
711 config.as_ptr(),
712 pixmap,
713 attrib_list.as_ptr(),
714 );
715
716 if surface != NO_SURFACE {
717 Ok(Surface(surface))
718 } else {
719 Err(self.get_error().unwrap())
720 }
721 }
722
723 pub unsafe fn create_window_surface(&self, display: Display, config: Config, window: NativeWindowType, attrib_list: Option<&[Int]>) -> Result<Surface, Error> {
731 let attrib_list = match attrib_list {
732 Some(attrib_list) => {
733 check_int_list(attrib_list)?;
734 attrib_list.as_ptr()
735 }
736 None => ptr::null(),
737 };
738
739 let surface =
740 self.api.eglCreateWindowSurface(display.as_ptr(), config.as_ptr(), window, attrib_list);
741
742 if surface != NO_SURFACE {
743 Ok(Surface(surface))
744 } else {
745 Err(self.get_error().unwrap())
746 }
747 }
748
749 pub fn destroy_context(&self, display: Display, ctx: Context) -> Result<(), Error> {
751 unsafe {
752 if self.api.eglDestroyContext(display.as_ptr(), ctx.as_ptr()) == TRUE {
753 Ok(())
754 } else {
755 Err(self.get_error().unwrap())
756 }
757 }
758 }
759
760 pub fn destroy_surface(&self, display: Display, surface: Surface) -> Result<(), Error> {
762 unsafe {
763 if self.api.eglDestroySurface(display.as_ptr(), surface.as_ptr()) == TRUE {
764 Ok(())
765 } else {
766 Err(self.get_error().unwrap())
767 }
768 }
769 }
770
771 pub fn get_config_attrib(&self, display: Display, config: Config, attribute: Int) -> Result<Int, Error> {
773 unsafe {
774 let mut value: Int = 0;
775 if self.api.eglGetConfigAttrib(display.as_ptr(), config.as_ptr(), attribute, &mut value) == TRUE
776 {
777 Ok(value)
778 } else {
779 Err(self.get_error().unwrap())
780 }
781 }
782 }
783
784 pub fn get_config_count(&self, display: Display) -> Result<usize, Error> {
804 unsafe {
805 let mut count = 0;
806
807 if self.api.eglGetConfigs(display.as_ptr(), std::ptr::null_mut(), 0, &mut count) == TRUE {
808 Ok(count as usize)
809 } else {
810 Err(self.get_error().unwrap())
811 }
812 }
813 }
814
815 pub fn get_configs(&self, display: Display, configs: &mut Vec<Config>) -> Result<(), Error> {
836 unsafe {
837 let capacity = configs.capacity();
838 let mut count = 0;
839
840 if self.api.eglGetConfigs(
841 display.as_ptr(),
842 configs.as_mut_ptr() as *mut EGLConfig,
843 capacity.try_into().unwrap(),
844 &mut count,
845 ) == TRUE
846 {
847 configs.set_len(count as usize);
848 Ok(())
849 } else {
850 Err(self.get_error().unwrap())
851 }
852 }
853 }
854
855 pub fn get_current_display(&self) -> Option<Display> {
857 unsafe {
858 let display = self.api.eglGetCurrentDisplay();
859
860 if display != NO_DISPLAY {
861 Some(Display(display))
862 } else {
863 None
864 }
865 }
866 }
867
868 pub fn get_current_surface(&self, readdraw: Int) -> Option<Surface> {
870 unsafe {
871 let surface = self.api.eglGetCurrentSurface(readdraw);
872
873 if surface != NO_SURFACE {
874 Some(Surface(surface))
875 } else {
876 None
877 }
878 }
879 }
880
881 pub fn get_display(&self, display_id: NativeDisplayType) -> Option<Display> {
883 unsafe {
884 let display = self.api.eglGetDisplay(display_id);
885
886 if display != NO_DISPLAY {
887 Some(Display(display))
888 } else {
889 None
890 }
891 }
892 }
893
894 pub fn get_error(&self) -> Option<Error> {
904 unsafe {
905 let e = self.api.eglGetError();
906 if e == SUCCESS {
907 None
908 } else {
909 Some(e.try_into().unwrap())
910 }
911 }
912 }
913
914 pub fn get_proc_address(&self, procname: &str) -> Option<extern "C" fn()> {
916 unsafe {
917 let string = CString::new(procname).unwrap();
918
919 let addr = self.api.eglGetProcAddress(string.as_ptr());
920 if !(addr as *const ()).is_null() {
921 Some(addr)
922 } else {
923 None
924 }
925 }
926 }
927
928 pub fn initialize(&self, display: Display) -> Result<(Int, Int), Error> {
930 unsafe {
931 let mut major = 0;
932 let mut minor = 0;
933
934 if self.api.eglInitialize(display.as_ptr(), &mut major, &mut minor) == TRUE {
935 Ok((major, minor))
936 } else {
937 Err(self.get_error().unwrap())
938 }
939 }
940 }
941
942 pub fn make_current(&self, display: Display, draw: Option<Surface>, read: Option<Surface>, ctx: Option<Context>) -> Result<(), Error> {
944 unsafe {
945 let draw = match draw {
946 Some(draw) => draw.as_ptr(),
947 None => NO_SURFACE,
948 };
949 let read = match read {
950 Some(read) => read.as_ptr(),
951 None => NO_SURFACE,
952 };
953 let ctx = match ctx {
954 Some(ctx) => ctx.as_ptr(),
955 None => NO_CONTEXT,
956 };
957
958 if self.api.eglMakeCurrent(display.as_ptr(), draw, read, ctx) == TRUE {
959 Ok(())
960 } else {
961 Err(self.get_error().unwrap())
962 }
963 }
964 }
965
966 pub fn query_context(&self, display: Display, ctx: Context, attribute: Int) -> Result<Int, Error> {
968 unsafe {
969 let mut value = 0;
970 if self.api.eglQueryContext(display.as_ptr(), ctx.as_ptr(), attribute, &mut value) == TRUE {
971 Ok(value)
972 } else {
973 Err(self.get_error().unwrap())
974 }
975 }
976 }
977
978 pub fn query_string(&self, display: Option<Display>, name: Int) -> Result<&'static CStr, Error> {
981 unsafe {
982 let display_ptr = match display {
983 Some(display) => display.as_ptr(),
984 None => NO_DISPLAY
985 };
986
987 let c_str = self.api.eglQueryString(display_ptr, name);
988
989 if !c_str.is_null() {
990 Ok(CStr::from_ptr(c_str))
991 } else {
992 Err(self.get_error().unwrap())
993 }
994 }
995 }
996
997 pub fn query_surface(&self, display: Display, surface: Surface, attribute: Int) -> Result<Int, Error> {
999 unsafe {
1000 let mut value = 0;
1001 if self.api.eglQuerySurface(display.as_ptr(), surface.as_ptr(), attribute, &mut value) == TRUE {
1002 Ok(value)
1003 } else {
1004 Err(self.get_error().unwrap())
1005 }
1006 }
1007 }
1008
1009 pub fn swap_buffers(&self, display: Display, surface: Surface) -> Result<(), Error> {
1011 unsafe {
1012 if self.api.eglSwapBuffers(display.as_ptr(), surface.as_ptr()) == TRUE {
1013 Ok(())
1014 } else {
1015 Err(self.get_error().unwrap())
1016 }
1017 }
1018 }
1019
1020 pub fn terminate(&self, display: Display) -> Result<(), Error> {
1022 unsafe {
1023 if self.api.eglTerminate(display.as_ptr()) == TRUE {
1024 Ok(())
1025 } else {
1026 Err(self.get_error().unwrap())
1027 }
1028 }
1029 }
1030
1031 pub fn wait_gl(&self) -> Result<(), Error> {
1033 unsafe {
1034 if self.api.eglWaitGL() == TRUE {
1035 Ok(())
1036 } else {
1037 Err(self.get_error().unwrap())
1038 }
1039 }
1040 }
1041
1042 pub fn wait_native(&self, engine: Int) -> Result<(), Error> {
1044 unsafe {
1045 if self.api.eglWaitNative(engine) == TRUE {
1046 Ok(())
1047 } else {
1048 Err(self.get_error().unwrap())
1049 }
1050 }
1051 }
1052 }
1053}
1054
1055#[cfg(feature = "1_0")]
1056pub use egl1_0::*;
1057
1058#[cfg(feature = "1_1")]
1063mod egl1_1 {
1064 use super::*;
1065
1066 pub const BACK_BUFFER: Int = 0x3084;
1067 pub const BIND_TO_TEXTURE_RGB: Int = 0x3039;
1068 pub const BIND_TO_TEXTURE_RGBA: Int = 0x303A;
1069 pub const CONTEXT_LOST: Int = 0x300E;
1070 pub const MIN_SWAP_INTERVAL: Int = 0x303B;
1071 pub const MAX_SWAP_INTERVAL: Int = 0x303C;
1072 pub const MIPMAP_TEXTURE: Int = 0x3082;
1073 pub const MIPMAP_LEVEL: Int = 0x3083;
1074 pub const NO_TEXTURE: Int = 0x305C;
1075 pub const TEXTURE_2D: Int = 0x305F;
1076 pub const TEXTURE_FORMAT: Int = 0x3080;
1077 pub const TEXTURE_RGB: Int = 0x305D;
1078 pub const TEXTURE_RGBA: Int = 0x305E;
1079 pub const TEXTURE_TARGET: Int = 0x3081;
1080
1081 impl<T: api::EGL1_1> Instance<T> {
1082 pub fn bind_tex_image(&self, display: Display, surface: Surface, buffer: Int) -> Result<(), Error> {
1084 unsafe {
1085 if self.api.eglBindTexImage(display.as_ptr(), surface.as_ptr(), buffer) == TRUE {
1086 Ok(())
1087 } else {
1088 Err(self.get_error().unwrap())
1089 }
1090 }
1091 }
1092
1093 pub fn release_tex_image(&self, display: Display, surface: Surface, buffer: Int) -> Result<(), Error> {
1095 unsafe {
1096 if self.api.eglReleaseTexImage(display.as_ptr(), surface.as_ptr(), buffer) == TRUE {
1097 Ok(())
1098 } else {
1099 Err(self.get_error().unwrap())
1100 }
1101 }
1102 }
1103
1104 pub fn surface_attrib(&self, display: Display, surface: Surface, attribute: Int, value: Int) -> Result<(), Error> {
1106 unsafe {
1107 if self.api.eglSurfaceAttrib(display.as_ptr(), surface.as_ptr(), attribute, value) == TRUE {
1108 Ok(())
1109 } else {
1110 Err(self.get_error().unwrap())
1111 }
1112 }
1113 }
1114
1115 pub fn swap_interval(&self, display: Display, interval: Int) -> Result<(), Error> {
1118 unsafe {
1119 if self.api.eglSwapInterval(display.as_ptr(), interval) == TRUE {
1120 Ok(())
1121 } else {
1122 Err(self.get_error().unwrap())
1123 }
1124 }
1125 }
1126 }
1127}
1128
1129#[cfg(feature = "1_1")]
1130pub use egl1_1::*;
1131
1132#[cfg(feature = "1_2")]
1137mod egl1_2 {
1138 use super::*;
1139
1140 pub type Enum = c_uint;
1141 pub type EGLClientBuffer = *mut c_void;
1142
1143 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
1144 pub struct ClientBuffer(EGLClientBuffer);
1145
1146 impl ClientBuffer {
1147 #[inline]
1148 pub unsafe fn from_ptr(ptr: EGLClientBuffer) -> ClientBuffer {
1149 ClientBuffer(ptr)
1150 }
1151
1152 #[inline]
1153 pub fn as_ptr(&self) -> EGLClientBuffer {
1154 self.0
1155 }
1156 }
1157
1158 pub const ALPHA_FORMAT: Int = 0x3088;
1159 pub const ALPHA_FORMAT_NONPRE: Int = 0x308B;
1160 pub const ALPHA_FORMAT_PRE: Int = 0x308C;
1161 pub const ALPHA_MASK_SIZE: Int = 0x303E;
1162 pub const BUFFER_PRESERVED: Int = 0x3094;
1163 pub const BUFFER_DESTROYED: Int = 0x3095;
1164 pub const CLIENT_APIS: Int = 0x308D;
1165 pub const COLORSPACE: Int = 0x3087;
1166 pub const COLORSPACE_sRGB: Int = 0x3089;
1167 pub const COLORSPACE_LINEAR: Int = 0x308A;
1168 pub const COLOR_BUFFER_TYPE: Int = 0x303F;
1169 pub const CONTEXT_CLIENT_TYPE: Int = 0x3097;
1170 pub const DISPLAY_SCALING: Int = 10000;
1171 pub const HORIZONTAL_RESOLUTION: Int = 0x3090;
1172 pub const LUMINANCE_BUFFER: Int = 0x308F;
1173 pub const LUMINANCE_SIZE: Int = 0x303D;
1174 pub const OPENGL_ES_BIT: Int = 0x0001;
1175 pub const OPENVG_BIT: Int = 0x0002;
1176 pub const OPENGL_ES_API: Enum = 0x30A0;
1177 pub const OPENVG_API: Enum = 0x30A1;
1178 pub const OPENVG_IMAGE: Int = 0x3096;
1179 pub const PIXEL_ASPECT_RATIO: Int = 0x3092;
1180 pub const RENDERABLE_TYPE: Int = 0x3040;
1181 pub const RENDER_BUFFER: Int = 0x3086;
1182 pub const RGB_BUFFER: Int = 0x308E;
1183 pub const SINGLE_BUFFER: Int = 0x3085;
1184 pub const SWAP_BEHAVIOR: Int = 0x3093;
1185 pub const UNKNOWN: Int = -1;
1186 pub const VERTICAL_RESOLUTION: Int = 0x3091;
1187
1188 impl<T: api::EGL1_2> Instance<T> {
1189 pub fn bind_api(&self, api: Enum) -> Result<(), Error> {
1191 unsafe {
1192 if self.api.eglBindAPI(api) == TRUE {
1193 Ok(())
1194 } else {
1195 Err(self.get_error().unwrap())
1196 }
1197 }
1198 }
1199
1200 pub fn query_api(&self) -> Enum {
1202 unsafe { self.api.eglQueryAPI() }
1203 }
1204
1205 pub fn create_pbuffer_from_client_buffer(&self, display: Display, buffer_type: Enum, buffer: ClientBuffer, config: Config, attrib_list: &[Int]) -> Result<Surface, Error> {
1210 check_int_list(attrib_list)?;
1211 unsafe {
1212 let surface = self.api.eglCreatePbufferFromClientBuffer(
1213 display.as_ptr(),
1214 buffer_type,
1215 buffer.as_ptr(),
1216 config.as_ptr(),
1217 attrib_list.as_ptr(),
1218 );
1219
1220 if surface != NO_SURFACE {
1221 Ok(Surface(surface))
1222 } else {
1223 Err(self.get_error().unwrap())
1224 }
1225 }
1226 }
1227
1228 pub fn release_thread(&self) -> Result<(), Error> {
1230 unsafe {
1231 if self.api.eglReleaseThread() == TRUE {
1232 Ok(())
1233 } else {
1234 Err(self.get_error().unwrap())
1235 }
1236 }
1237 }
1238
1239 pub fn wait_client(&self) -> Result<(), Error> {
1241 unsafe {
1242 if self.api.eglWaitClient() == TRUE {
1243 Ok(())
1244 } else {
1245 Err(self.get_error().unwrap())
1246 }
1247 }
1248 }
1249 }
1250}
1251
1252#[cfg(feature = "1_2")]
1253pub use egl1_2::*;
1254
1255#[cfg(feature = "1_3")]
1260mod egl1_3 {
1261 use super::*;
1262
1263 pub const CONFORMANT: Int = 0x3042;
1264 pub const CONTEXT_CLIENT_VERSION: Int = 0x3098;
1265 pub const MATCH_NATIVE_PIXMAP: Int = 0x3041;
1266 pub const OPENGL_ES2_BIT: Int = 0x0004;
1267 pub const VG_ALPHA_FORMAT: Int = 0x3088;
1268 pub const VG_ALPHA_FORMAT_NONPRE: Int = 0x308B;
1269 pub const VG_ALPHA_FORMAT_PRE: Int = 0x308C;
1270 pub const VG_ALPHA_FORMAT_PRE_BIT: Int = 0x0040;
1271 pub const VG_COLORSPACE: Int = 0x3087;
1272 pub const VG_COLORSPACE_sRGB: Int = 0x3089;
1273 pub const VG_COLORSPACE_LINEAR: Int = 0x308A;
1274 pub const VG_COLORSPACE_LINEAR_BIT: Int = 0x0020;
1275}
1276
1277#[cfg(feature = "1_3")]
1278pub use egl1_3::*;
1279
1280#[cfg(feature = "1_4")]
1285mod egl1_4 {
1286 use super::*;
1287
1288 pub const DEFAULT_DISPLAY: NativeDisplayType = 0 as NativeDisplayType;
1289 pub const MULTISAMPLE_RESOLVE_BOX_BIT: Int = 0x0200;
1290 pub const MULTISAMPLE_RESOLVE: Int = 0x3099;
1291 pub const MULTISAMPLE_RESOLVE_DEFAULT: Int = 0x309A;
1292 pub const MULTISAMPLE_RESOLVE_BOX: Int = 0x309B;
1293 pub const OPENGL_API: Enum = 0x30A2;
1294 pub const OPENGL_BIT: Int = 0x0008;
1295 pub const SWAP_BEHAVIOR_PRESERVED_BIT: Int = 0x0400;
1296
1297 impl<T: api::EGL1_4> Instance<T> {
1298 pub fn get_current_context(&self) -> Option<Context> {
1300 unsafe {
1301 let context = self.api.eglGetCurrentContext();
1302
1303 if context != NO_CONTEXT {
1304 Some(Context(context))
1305 } else {
1306 None
1307 }
1308 }
1309 }
1310 }
1311}
1312
1313#[cfg(feature = "1_4")]
1314pub use egl1_4::*;
1315
1316#[cfg(feature = "1_5")]
1321mod egl1_5 {
1322 use super::*;
1323
1324 pub type Time = u64;
1325 pub type EGLSync = *mut c_void;
1326 pub type EGLImage = *mut c_void;
1327
1328 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
1329 pub struct Sync(EGLSync);
1330
1331 impl Sync {
1332 #[inline]
1333 pub unsafe fn from_ptr(ptr: EGLSync) -> Sync {
1334 Sync(ptr)
1335 }
1336
1337 #[inline]
1338 pub fn as_ptr(&self) -> EGLSync {
1339 self.0
1340 }
1341 }
1342
1343 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
1344 pub struct Image(EGLImage);
1345
1346 impl Image {
1347 #[inline]
1348 pub unsafe fn from_ptr(ptr: EGLImage) -> Image {
1349 Image(ptr)
1350 }
1351
1352 #[inline]
1353 pub fn as_ptr(&self) -> EGLImage {
1354 self.0
1355 }
1356 }
1357
1358 pub const CONTEXT_MAJOR_VERSION: Int = 0x3098;
1359 pub const CONTEXT_MINOR_VERSION: Int = 0x30FB;
1360 pub const CONTEXT_OPENGL_PROFILE_MASK: Int = 0x30FD;
1361 pub const CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY: Int = 0x31BD;
1362 pub const NO_RESET_NOTIFICATION: Int = 0x31BE;
1363 pub const LOSE_CONTEXT_ON_RESET: Int = 0x31BF;
1364 pub const CONTEXT_OPENGL_CORE_PROFILE_BIT: Int = 0x00000001;
1365 pub const CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT: Int = 0x00000002;
1366 pub const CONTEXT_OPENGL_DEBUG: Int = 0x31B0;
1367 pub const CONTEXT_OPENGL_FORWARD_COMPATIBLE: Int = 0x31B1;
1368 pub const CONTEXT_OPENGL_ROBUST_ACCESS: Int = 0x31B2;
1369 pub const OPENGL_ES3_BIT: Int = 0x00000040;
1370 pub const CL_EVENT_HANDLE: Int = 0x309C;
1371 pub const SYNC_CL_EVENT: Int = 0x30FE;
1372 pub const SYNC_CL_EVENT_COMPLETE: Int = 0x30FF;
1373 pub const SYNC_PRIOR_COMMANDS_COMPLETE: Int = 0x30F0;
1374 pub const SYNC_TYPE: Int = 0x30F7;
1375 pub const SYNC_STATUS: Int = 0x30F1;
1376 pub const SYNC_CONDITION: Int = 0x30F8;
1377 pub const SIGNALED: Int = 0x30F2;
1378 pub const UNSIGNALED: Int = 0x30F3;
1379 pub const SYNC_FLUSH_COMMANDS_BIT: Int = 0x0001;
1380 pub const FOREVER: u64 = 0xFFFFFFFFFFFFFFFFu64;
1381 pub const TIMEOUT_EXPIRED: Int = 0x30F5;
1382 pub const CONDITION_SATISFIED: Int = 0x30F6;
1383 pub const NO_SYNC: EGLSync = 0 as EGLSync;
1384 pub const SYNC_FENCE: Int = 0x30F9;
1385 pub const GL_COLORSPACE: Int = 0x309D;
1386 pub const GL_COLORSPACE_SRGB: Int = 0x3089;
1387 pub const GL_COLORSPACE_LINEAR: Int = 0x308A;
1388 pub const GL_RENDERBUFFER: Int = 0x30B9;
1389 pub const GL_TEXTURE_2D: Int = 0x30B1;
1390 pub const GL_TEXTURE_LEVEL: Int = 0x30BC;
1391 pub const GL_TEXTURE_3D: Int = 0x30B2;
1392 pub const GL_TEXTURE_ZOFFSET: Int = 0x30BD;
1393 pub const GL_TEXTURE_CUBE_MAP_POSITIVE_X: Int = 0x30B3;
1394 pub const GL_TEXTURE_CUBE_MAP_NEGATIVE_X: Int = 0x30B4;
1395 pub const GL_TEXTURE_CUBE_MAP_POSITIVE_Y: Int = 0x30B5;
1396 pub const GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: Int = 0x30B6;
1397 pub const GL_TEXTURE_CUBE_MAP_POSITIVE_Z: Int = 0x30B7;
1398 pub const GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: Int = 0x30B8;
1399 pub const IMAGE_PRESERVED: Int = 0x30D2;
1400 pub const NO_IMAGE: EGLImage = 0 as EGLImage;
1401
1402 impl<T: api::EGL1_5> Instance<T> {
1403 pub unsafe fn create_sync(&self, display: Display, ty: Enum, attrib_list: &[Attrib]) -> Result<Sync, Error> {
1415 check_attrib_list(attrib_list)?;
1416 let sync = self.api.eglCreateSync(display.as_ptr(), ty, attrib_list.as_ptr());
1417 if sync != NO_SYNC {
1418 Ok(Sync(sync))
1419 } else {
1420 Err(self.get_error().unwrap())
1421 }
1422 }
1423
1424 pub unsafe fn destroy_sync(&self, display: Display, sync: Sync) -> Result<(), Error> {
1429 if self.api.eglDestroySync(display.as_ptr(), sync.as_ptr()) == TRUE {
1430 Ok(())
1431 } else {
1432 Err(self.get_error().unwrap())
1433 }
1434 }
1435
1436 pub unsafe fn client_wait_sync(&self, display: Display, sync: Sync, flags: Int, timeout: Time) -> Result<Int, Error> {
1441 let status = self.api.eglClientWaitSync(display.as_ptr(), sync.as_ptr(), flags, timeout);
1442 if status != FALSE as Int {
1443 Ok(status)
1444 } else {
1445 Err(self.get_error().unwrap())
1446 }
1447 }
1448
1449 pub unsafe fn get_sync_attrib(&self, display: Display, sync: Sync, attribute: Int) -> Result<Attrib, Error> {
1454 let mut value = 0;
1455 if self.api.eglGetSyncAttrib(
1456 display.as_ptr(),
1457 sync.as_ptr(),
1458 attribute,
1459 &mut value as *mut Attrib,
1460 ) == TRUE
1461 {
1462 Ok(value)
1463 } else {
1464 Err(self.get_error().unwrap())
1465 }
1466 }
1467
1468 pub fn create_image(&self, display: Display, ctx: Context, target: Enum, buffer: ClientBuffer, attrib_list: &[Attrib]) -> Result<Image, Error> {
1476 check_attrib_list(attrib_list)?;
1477 unsafe {
1478 let image = self.api.eglCreateImage(
1479 display.as_ptr(),
1480 ctx.as_ptr(),
1481 target,
1482 buffer.as_ptr(),
1483 attrib_list.as_ptr(),
1484 );
1485 if image != NO_IMAGE {
1486 Ok(Image(image))
1487 } else {
1488 Err(self.get_error().unwrap())
1489 }
1490 }
1491 }
1492
1493 pub fn destroy_image(&self, display: Display, image: Image) -> Result<(), Error> {
1495 unsafe {
1496 if self.api.eglDestroyImage(display.as_ptr(), image.as_ptr()) == TRUE {
1497 Ok(())
1498 } else {
1499 Err(self.get_error().unwrap())
1500 }
1501 }
1502 }
1503
1504 pub fn get_platform_display(&self, platform: Enum, native_display: *mut c_void, attrib_list: &[Attrib]) -> Result<Display, Error> {
1512 check_attrib_list(attrib_list)?;
1513 unsafe {
1514 let display = self.api.eglGetPlatformDisplay(platform, native_display, attrib_list.as_ptr());
1515 if display != NO_DISPLAY {
1516 Ok(Display(display))
1517 } else {
1518 Err(self.get_error().unwrap())
1519 }
1520 }
1521 }
1522
1523 pub fn create_platform_window_surface(&self, display: Display, config: Config, native_window: *mut c_void, attrib_list: &[Attrib]) -> Result<Surface, Error> {
1531 check_attrib_list(attrib_list)?;
1532 unsafe {
1533 let surface = self.api.eglCreatePlatformWindowSurface(
1534 display.as_ptr(),
1535 config.as_ptr(),
1536 native_window,
1537 attrib_list.as_ptr(),
1538 );
1539 if surface != NO_SURFACE {
1540 Ok(Surface(surface))
1541 } else {
1542 Err(self.get_error().unwrap())
1543 }
1544 }
1545 }
1546
1547 pub fn create_platform_pixmap_surface(&self, display: Display, config: Config, native_pixmap: *mut c_void, attrib_list: &[Attrib]) -> Result<Surface, Error> {
1555 check_attrib_list(attrib_list)?;
1556 unsafe {
1557 let surface = self.api.eglCreatePlatformPixmapSurface(
1558 display.as_ptr(),
1559 config.as_ptr(),
1560 native_pixmap,
1561 attrib_list.as_ptr(),
1562 );
1563 if surface != NO_SURFACE {
1564 Ok(Surface(surface))
1565 } else {
1566 Err(self.get_error().unwrap())
1567 }
1568 }
1569 }
1570
1571 pub fn wait_sync(&self, display: Display, sync: Sync, flags: Int) -> Result<(), Error> {
1576 unsafe {
1577 if self.api.eglWaitSync(display.as_ptr(), sync.as_ptr(), flags) == TRUE {
1578 Ok(())
1579 } else {
1580 Err(self.get_error().unwrap())
1581 }
1582 }
1583 }
1584 }
1585}
1586
1587#[cfg(feature = "1_5")]
1588pub use egl1_5::*;
1589
1590macro_rules! api {
1595 ($($id:ident : $version:literal { $(fn $name:ident ($($arg:ident : $atype:ty ),* ) -> $rtype:ty ;)* }),*) => {
1596 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
1597 pub enum Version {
1598 $(
1599 #[cfg(feature=$version)]
1600 $id,
1601 )*
1602 }
1603
1604 impl std::fmt::Display for Version {
1605 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1606 match self {
1607 $(
1608 #[cfg(feature=$version)]
1609 Version::$id => write!(f, $version),
1610 )*
1611 }
1612 }
1613 }
1614
1615 pub mod api {
1616 use super::*;
1617
1618 api!(@api_traits () () $($id : $version { $(fn $name ($($arg : $atype ),* ) -> $rtype ;)* })*);
1619 }
1620
1621 #[cfg(feature="static")]
1622 mod ffi {
1623 use libc::{c_char, c_void};
1624
1625 use super::{
1626 Attrib, Boolean, EGLClientBuffer, EGLConfig, EGLContext, EGLDisplay, EGLImage, EGLSurface,
1627 EGLSync, Enum, Int, NativeDisplayType, NativePixmapType, NativeWindowType, Time,
1628 };
1629
1630 $(
1631 extern "C" {
1632 $(
1633 #[cfg(feature=$version)]
1634 pub fn $name ($($arg : $atype ),* ) -> $rtype ;
1635 )*
1636 }
1637 )*
1638 }
1639
1640 #[cfg(feature="static")]
1641 #[derive(Copy, Clone, Debug)]
1646 pub struct Static;
1647
1648 #[cfg(feature="static")]
1649 impl Api for Static {
1650 #[inline(always)]
1651 fn version(&self) -> Version {
1652 LATEST
1653 }
1654 }
1655
1656 #[cfg(feature="static")]
1657 pub static API: Instance<Static> = Instance::new(Static);
1658
1659 #[cfg(feature="dynamic")]
1660 extern crate libloading;
1661
1662 api!(@dynamic_struct $($id : $version { $(fn $name ($($arg : $atype ),* ) -> $rtype ;)* })*);
1663 api!(@api_types () $($id : $version { $(fn $name ($($arg : $atype ),* ) -> $rtype ;)* })*);
1664 };
1665 (@dynamic_struct $($id:ident : $version:literal { $(fn $name:ident ($($arg:ident : $atype:ty ),* ) -> $rtype:ty ;)* })*) => {
1666 #[cfg(feature="dynamic")]
1667 #[derive(Debug)]
1668 pub enum LoadError<L> {
1669 Library(L),
1671
1672 InvalidVersion {
1674 provided: Version,
1675 required: Version
1676 }
1677 }
1678
1679 #[cfg(feature="dynamic")]
1680 impl<L: std::error::Error + 'static> std::error::Error for LoadError<L> {
1681 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1682 match self {
1683 LoadError::Library(l) => Some(l),
1684 _ => None
1685 }
1686 }
1687 }
1688
1689 #[cfg(feature="dynamic")]
1690 impl<L: std::fmt::Display> std::fmt::Display for LoadError<L> {
1691 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1692 match self {
1693 LoadError::Library(l) => write!(f, "Load error: {}", l),
1694 LoadError::InvalidVersion { provided, required } => write!(f, "Invalid EGL API version (required {}, provided {})", required, provided)
1695 }
1696 }
1697 }
1698
1699 #[cfg(feature="dynamic")]
1700 struct RawDynamic<L> {
1701 lib: L,
1702 version: Version,
1703 $(
1704 $(
1705 #[cfg(feature=$version)]
1706 $name : std::mem::MaybeUninit<unsafe extern "C" fn($($atype ),*) -> $rtype>,
1707 )*
1708 )*
1709 }
1710
1711 #[cfg(feature="dynamic")]
1712 impl<L> RawDynamic<L> {
1713 #[inline(always)]
1714 pub fn library(&self) -> &L {
1716 &self.lib
1717 }
1718
1719 #[inline(always)]
1720 pub fn version(&self) -> Version {
1722 self.version
1723 }
1724
1725 #[inline(always)]
1726 pub unsafe fn set_version(&mut self, version: Version) {
1728 self.version = version
1729 }
1730
1731 pub unsafe fn unloaded(lib: L, version: Version) -> Self {
1733 RawDynamic {
1734 lib,
1735 version,
1736 $(
1737 $(
1738 #[cfg(feature=$version)]
1739 $name : std::mem::MaybeUninit::uninit(),
1740 )*
1741 )*
1742 }
1743 }
1744 }
1745
1746 #[cfg(feature="dynamic")]
1747 pub struct Dynamic<L, A> {
1755 raw: RawDynamic<L>,
1756 _api_version: std::marker::PhantomData<A>
1757 }
1758
1759 #[cfg(feature="dynamic")]
1760 impl<L, A> Dynamic<L, A> {
1761 #[inline(always)]
1762 pub fn library(&self) -> &L {
1764 self.raw.library()
1765 }
1766
1767 pub fn version(&self) -> Version {
1769 self.raw.version()
1770 }
1771
1772 pub(crate) unsafe fn unloaded(lib: L, version: Version) -> Self {
1774 Dynamic {
1775 raw: RawDynamic::unloaded(lib, version),
1776 _api_version: std::marker::PhantomData
1777 }
1778 }
1779 }
1780
1781 #[cfg(feature="dynamic")]
1782 impl<L, A> Api for Dynamic<L, A> {
1783 #[inline(always)]
1785 fn version(&self) -> Version {
1786 self.version()
1787 }
1788 }
1789
1790 #[cfg(feature="dynamic")]
1791 #[cfg(feature="1_0")]
1792 impl<L: std::borrow::Borrow<libloading::Library>> Dynamic<L, EGL1_0> {
1793 #[inline]
1794 pub unsafe fn load_from(lib: L) -> Result<Dynamic<L, EGL1_0>, libloading::Error> {
1804 let mut result = Dynamic::unloaded(lib, Version::EGL1_0);
1805
1806 $(
1807 match $id::load_from(&mut result.raw) {
1808 Ok(()) => result.raw.set_version(Version::$id),
1809 Err(libloading::Error::DlSymUnknown) => {
1810 if Version::$id == Version::EGL1_0 {
1811 return Err(libloading::Error::DlSymUnknown) } else {
1813 return Ok(result)
1814 }
1815 },
1816 Err(libloading::Error::DlSym { desc }) => {
1817 if Version::$id == Version::EGL1_0 {
1818 return Err(libloading::Error::DlSym { desc }) } else {
1820 return Ok(result)
1821 }
1822 },
1823 Err(e) => return Err(e)
1824 }
1825 )*
1826
1827 Ok(result)
1828 }
1829 }
1830
1831 #[cfg(feature="dynamic")]
1832 #[cfg(feature="1_0")]
1833 impl<L: std::borrow::Borrow<libloading::Library>> Instance<Dynamic<L, EGL1_0>> {
1834 #[inline(always)]
1835 pub unsafe fn load_from(lib: L) -> Result<Instance<Dynamic<L, EGL1_0>>, libloading::Error> {
1844 Ok(Instance::new(Dynamic::<L, EGL1_0>::load_from(lib)?))
1845 }
1846 }
1847
1848 #[cfg(feature="dynamic")]
1849 impl<L, V> Instance<Dynamic<L, V>> {
1850 #[inline(always)]
1852 pub fn downcast<W>(&self) -> &Instance<Dynamic<L, W>> where Instance<Dynamic<L, V>>: Downcast<Instance<Dynamic<L, W>>> {
1853 Downcast::downcast(self)
1854 }
1855
1856 #[inline(always)]
1858 pub fn upcast<W>(&self) -> Option<&Instance<Dynamic<L, W>>> where Instance<Dynamic<L, V>>: Upcast<Instance<Dynamic<L, W>>> {
1859 Upcast::upcast(self)
1860 }
1861 }
1862
1863 #[cfg(feature="dynamic")]
1864 unsafe impl<L: std::borrow::Borrow<libloading::Library> + Send, A: Send> Send for Dynamic<L, A> {}
1865
1866 #[cfg(feature="dynamic")]
1867 unsafe impl<L: std::borrow::Borrow<libloading::Library> + std::marker::Sync, A: std::marker::Sync> std::marker::Sync for Dynamic<L, A> {}
1868
1869 #[cfg(feature="dynamic")]
1870 impl<L: std::borrow::Borrow<libloading::Library> + fmt::Debug, A> fmt::Debug for Dynamic<L, A> {
1871 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1872 write!(f, "Dynamic({:?})", self.library())
1873 }
1874 }
1875 };
1876 (@api_traits ( ) ( ) $id:ident : $version:literal { $(fn $name:ident ($($arg:ident : $atype:ty ),* ) -> $rtype:ty ;)* } $($t_id:ident : $t_version:literal { $(fn $t_name:ident ($($t_arg:ident : $t_atype:ty ),* ) -> $t_rtype:ty ;)* })*) => {
1877 api!(@api_trait ( ) ( ) $id : $version { $(fn $name ($($arg : $atype ),* ) -> $rtype ;)* });
1878 api!(@api_traits ( $id : $version ) ( : $id ) $($t_id : $t_version { $(fn $t_name ($($t_arg : $t_atype ),* ) -> $t_rtype ;)* })*);
1879 };
1880 (@api_traits ( $($pred:ident : $p_version:literal)+ ) ( $($deps:tt)+ ) $id:ident : $version:literal { $(fn $name:ident ($($arg:ident : $atype:ty ),* ) -> $rtype:ty ;)* } $($t_id:ident : $t_version:literal { $(fn $t_name:ident ($($t_arg:ident : $t_atype:ty ),* ) -> $t_rtype:ty ;)* })*) => {
1881 api!(@api_trait ( $($pred : $p_version)* ) ( $($deps)* ) $id : $version { $(fn $name ($($arg : $atype ),* ) -> $rtype ;)* });
1882 api!(@api_traits ( $($pred : $version)* $id : $version ) ( $($deps)* + $id ) $($t_id : $t_version { $(fn $t_name ($($t_arg : $t_atype ),* ) -> $t_rtype ;)* })*);
1883 };
1884 (@api_traits ( $($pred:ident : $p_version:literal)* ) ( $($deps:tt)* )) => {
1885 };
1887 (@api_trait ( $($pred:ident : $p_version:literal)* ) ( $($deps:tt)* ) $id:ident : $version:literal { $(fn $name:ident ($($arg:ident : $atype:ty ),* ) -> $rtype:ty ;)* }) => {
1888 #[cfg(feature=$version)]
1899 pub unsafe trait $id $($deps)* {
1900 $(
1901 unsafe fn $name (&self, $($arg : $atype ),* ) -> $rtype ;
1902 )*
1903 }
1904 };
1905 (@api_types ( ) $id:ident : $version:literal { $(fn $name:ident ($($arg:ident : $atype:ty ),* ) -> $rtype:ty ;)* } $($t_id:ident : $t_version:literal { $(fn $t_name:ident ($($t_arg:ident : $t_atype:ty ),* ) -> $t_rtype:ty ;)* })*) => {
1906 #[cfg(feature="dynamic")]
1907 $(
1908 #[cfg(not(feature=$t_version))]
1909 )*
1910 #[cfg(feature=$version)]
1911 pub type Latest = $id;
1913
1914 $(
1915 #[cfg(not(feature=$t_version))]
1916 )*
1917 #[cfg(feature=$version)]
1918 pub const LATEST: Version = Version::$id;
1920
1921 api!(@api_type ( ) $id : $version { $(fn $name ($($arg : $atype ),* ) -> $rtype ;)* });
1922 api!(@api_types ( $id : $version { $(fn $name ($($arg : $atype ),* ) -> $rtype ;)* } ) $($t_id : $t_version { $(fn $t_name ($($t_arg : $t_atype ),* ) -> $t_rtype ;)* })*);
1923 };
1924 (@api_types ( $($pred:ident : $p_version:literal { $(fn $p_name:ident ($($p_arg:ident : $p_atype:ty ),* ) -> $p_rtype:ty ;)* })+ ) $id:ident : $version:literal { $(fn $name:ident ($($arg:ident : $atype:ty ),* ) -> $rtype:ty ;)* } $($t_id:ident : $t_version:literal { $(fn $t_name:ident ($($t_arg:ident : $t_atype:ty ),* ) -> $t_rtype:ty ;)* })*) => {
1925 #[cfg(feature="dynamic")]
1926 $(
1927 #[cfg(not(feature=$t_version))]
1928 )*
1929 #[cfg(feature=$version)]
1930 pub type Latest = $id;
1932
1933 $(
1934 #[cfg(not(feature=$t_version))]
1935 )*
1936 #[cfg(feature=$version)]
1937 pub const LATEST: Version = Version::$id;
1939
1940 api!(@api_type ( $($pred : $p_version { $(fn $p_name ($($p_arg : $p_atype ),* ) -> $p_rtype ;)* })* ) $id : $version { $(fn $name ($($arg : $atype ),* ) -> $rtype ;)* });
1941 api!(@api_types ( $($pred : $p_version { $(fn $p_name ($($p_arg : $p_atype ),* ) -> $p_rtype ;)* })* $id : $version { $(fn $name ($($arg : $atype ),* ) -> $rtype ;)* } ) $($t_id : $t_version { $(fn $t_name ($($t_arg : $t_atype ),* ) -> $t_rtype ;)* })*);
1942 };
1943 (@api_types ( $($pred:ident : $p_version:literal { $(fn $p_name:ident ($($p_arg:ident : $p_atype:ty ),* ) -> $p_rtype:ty ;)* })+ ) ) => {
1944 #[cfg(feature="dynamic")]
1945 #[cfg(feature="1_0")]
1946 pub type DynamicInstance<V = Latest> = Instance<Dynamic<libloading::Library, V>>;
1948
1949 #[cfg(feature="dynamic")]
1950 #[cfg(feature="1_0")]
1951 impl DynamicInstance<EGL1_0> {
1952 #[inline(always)]
1953 pub unsafe fn load_from_filename<P: AsRef<std::ffi::OsStr>>(filename: P) -> Result<DynamicInstance<EGL1_0>, libloading::Error> {
1964 #[cfg(target_os = "linux")]
1965 let lib: libloading::Library = {
1966 libloading::os::unix::Library::open(Some(filename), 0x2 | 0x1000)?.into()
1969 };
1970 #[cfg(not(target_os = "linux"))]
1971 let lib = libloading::Library::new(filename)?;
1972 Self::load_from(lib)
1973 }
1974
1975 #[inline(always)]
1976 pub unsafe fn load() -> Result<DynamicInstance<EGL1_0>, libloading::Error> {
1983 Self::load_from_filename("libEGL.so.1").or(Self::load_from_filename("libEGL.so"))
1984 }
1985 }
1986 };
1987 (@api_type ( $($pred:ident : $p_version:literal { $(fn $p_name:ident ($($p_arg:ident : $p_atype:ty ),* ) -> $p_rtype:ty ;)* })* ) $id:ident : $version:literal { $(fn $name:ident ($($arg:ident : $atype:ty ),* ) -> $rtype:ty ;)* }) => {
1988 #[cfg(feature="static")]
1989 #[cfg(feature=$version)]
1990 unsafe impl api::$id for Static {
1991 $(
1992 #[inline(always)]
1993 unsafe fn $name(&self, $($arg : $atype),*) -> $rtype {
1994 ffi::$name($($arg),*)
1995 }
1996 )*
1997 }
1998
1999 #[cfg(feature="dynamic")]
2000 #[cfg(feature=$version)]
2001 pub struct $id;
2005
2006 #[cfg(feature="dynamic")]
2007 #[cfg(feature=$version)]
2008 impl $id {
2009 #[allow(unused_variables)]
2010 unsafe fn load_from<L: std::borrow::Borrow<libloading::Library>>(raw: &mut RawDynamic<L>) -> Result<(), libloading::Error> {
2011 let lib = raw.lib.borrow();
2012
2013 $(
2014 let name = stringify!($name).as_bytes();
2015 let symbol = lib.get::<unsafe extern "C" fn($($atype ),*) -> $rtype>(name)?;
2016 let ptr = (&symbol.into_raw().into_raw()) as *const *mut _ as *const unsafe extern "C" fn($($atype ),*) -> $rtype;
2017 assert!(!ptr.is_null());
2018 raw.$name = std::mem::MaybeUninit::new(*ptr);
2019 )*
2020
2021 Ok(())
2022 }
2023 }
2024
2025 $(
2026 #[cfg(feature="dynamic")]
2027 #[cfg(feature=$version)]
2028 unsafe impl<L: std::borrow::Borrow<libloading::Library>> api::$pred for Dynamic<L, $id> {
2029 $(
2030 #[inline(always)]
2031 unsafe fn $p_name(&self, $($p_arg : $p_atype),*) -> $p_rtype {
2032 (self.raw.$p_name.assume_init())($($p_arg),*)
2033 }
2034 )*
2035 }
2036 )*
2037
2038 #[cfg(feature="dynamic")]
2039 #[cfg(feature=$version)]
2040 unsafe impl<L: std::borrow::Borrow<libloading::Library>> api::$id for Dynamic<L, $id> {
2041 $(
2042 #[inline(always)]
2043 unsafe fn $name(&self, $($arg : $atype),*) -> $rtype {
2044 (self.raw.$name.assume_init())($($arg),*)
2045 }
2046 )*
2047 }
2048
2049 $(
2050 #[cfg(feature="dynamic")]
2051 #[cfg(feature=$version)]
2052 impl<L: std::borrow::Borrow<libloading::Library>> TryFrom<Dynamic<L, $pred>> for Dynamic<L, $id> {
2053 type Error = Dynamic<L, $pred>;
2054
2055 fn try_from(other: Dynamic<L, $pred>) -> Result<Self, Dynamic<L, $pred>> {
2056 if other.version() >= Version::$id {
2057 Ok(Dynamic {
2058 raw: other.raw,
2059 _api_version: std::marker::PhantomData
2060 })
2061 } else {
2062 Err(other)
2063 }
2064 }
2065 }
2066
2067 #[cfg(feature="dynamic")]
2068 #[cfg(feature=$version)]
2069 impl<L: std::borrow::Borrow<libloading::Library>> From<Dynamic<L, $id>> for Dynamic<L, $pred> {
2070 fn from(other: Dynamic<L, $id>) -> Self {
2071 Dynamic {
2072 raw: other.raw,
2073 _api_version: std::marker::PhantomData
2074 }
2075 }
2076 }
2077
2078 #[cfg(feature="dynamic")]
2079 #[cfg(feature=$version)]
2080 impl<L: std::borrow::Borrow<libloading::Library>> AsRef<Dynamic<L, $pred>> for Dynamic<L, $id> {
2081 fn as_ref(&self) -> &Dynamic<L, $pred> {
2082 unsafe { std::mem::transmute(self) } }
2084 }
2085
2086 #[cfg(feature="dynamic")]
2087 #[cfg(feature=$version)]
2088 impl<L: std::borrow::Borrow<libloading::Library>> Downcast<Dynamic<L, $pred>> for Dynamic<L, $id> {
2089 fn downcast(&self) -> &Dynamic<L, $pred> {
2090 unsafe { std::mem::transmute(self) } }
2092 }
2093
2094 #[cfg(feature="dynamic")]
2095 #[cfg(feature=$version)]
2096 impl<L: std::borrow::Borrow<libloading::Library>> Downcast<Instance<Dynamic<L, $pred>>> for Instance<Dynamic<L, $id>> {
2097 fn downcast(&self) -> &Instance<Dynamic<L, $pred>> {
2098 unsafe { std::mem::transmute(self) } }
2100 }
2101
2102 #[cfg(feature="dynamic")]
2103 #[cfg(feature=$version)]
2104 impl<L: std::borrow::Borrow<libloading::Library>> Upcast<Dynamic<L, $id>> for Dynamic<L, $pred> {
2105 fn upcast(&self) -> Option<&Dynamic<L, $id>> {
2106 if self.version() >= Version::$id {
2107 Some(unsafe { std::mem::transmute(self) }) } else {
2109 None
2110 }
2111 }
2112 }
2113
2114 #[cfg(feature="dynamic")]
2115 #[cfg(feature=$version)]
2116 impl<L: std::borrow::Borrow<libloading::Library>> Upcast<Instance<Dynamic<L, $id>>> for Instance<Dynamic<L, $pred>> {
2117 fn upcast(&self) -> Option<&Instance<Dynamic<L, $id>>> {
2118 if self.version() >= Version::$id {
2119 Some(unsafe { std::mem::transmute(self) }) } else {
2121 None
2122 }
2123 }
2124 }
2125 )*
2126
2127 #[cfg(feature="dynamic")]
2128 #[cfg(feature=$version)]
2129 impl<L: std::borrow::Borrow<libloading::Library>> Dynamic<L, $id> {
2130 #[inline]
2131 pub unsafe fn load_required(lib: L) -> Result<Dynamic<L, $id>, LoadError<libloading::Error>> {
2138 match Dynamic::<L, EGL1_0>::load_from(lib) {
2139 Ok(dynamic) => {
2140 let provided = dynamic.version();
2141 match dynamic.try_into() {
2142 Ok(t) => Ok(t),
2143 Err(_) => Err(LoadError::InvalidVersion {
2144 provided,
2145 required: Version::$id
2146 })
2147 }
2148 },
2149 Err(e) => Err(LoadError::Library(e))
2150 }
2151 }
2152 }
2153
2154 #[cfg(feature="dynamic")]
2155 #[cfg(feature=$version)]
2156 impl<L: std::borrow::Borrow<libloading::Library>> Instance<Dynamic<L, $id>> {
2157 #[inline(always)]
2158 pub unsafe fn load_required_from(lib: L) -> Result<Instance<Dynamic<L, $id>>, LoadError<libloading::Error>> {
2164 Ok(Instance::new(Dynamic::<L, $id>::load_required(lib)?))
2165 }
2166 }
2167
2168 #[cfg(feature="dynamic")]
2169 #[cfg(feature=$version)]
2170 impl DynamicInstance<$id> {
2171 #[inline(always)]
2172 pub unsafe fn load_required_from_filename<P: AsRef<std::ffi::OsStr>>(filename: P) -> Result<DynamicInstance<$id>, LoadError<libloading::Error>> {
2184 #[cfg(target_os = "linux")]
2185 let lib: libloading::Library = {
2186 libloading::os::unix::Library::open(Some(filename), 0x2 | 0x1000).map_err(LoadError::Library)?.into()
2189 };
2190 #[cfg(not(target_os = "linux"))]
2191 let lib = libloading::Library::new(filename).map_err(LoadError::Library)?;
2192 Self::load_required_from(lib)
2193 }
2194
2195 #[inline(always)]
2196 pub unsafe fn load_required() -> Result<DynamicInstance<$id>, LoadError<libloading::Error>> {
2204 Self::load_required_from_filename("libEGL.so.1").or(Self::load_required_from_filename("libEGL.so"))
2205 }
2206 }
2207 }
2208}
2209
2210api! {
2211 EGL1_0 : "1_0" {
2212 fn eglChooseConfig(
2213 display: EGLDisplay,
2214 attrib_list: *const Int,
2215 configs: *mut EGLConfig,
2216 config_size: Int,
2217 num_config: *mut Int
2218 ) -> Boolean;
2219 fn eglCopyBuffers(
2220 display: EGLDisplay,
2221 surface: EGLSurface,
2222 target: NativePixmapType
2223 ) -> Boolean;
2224 fn eglCreateContext(
2225 display: EGLDisplay,
2226 config: EGLConfig,
2227 share_context: EGLContext,
2228 attrib_list: *const Int
2229 ) -> EGLContext;
2230 fn eglCreatePbufferSurface(
2231 display: EGLDisplay,
2232 config: EGLConfig,
2233 attrib_list: *const Int
2234 ) -> EGLSurface;
2235 fn eglCreatePixmapSurface(
2236 display: EGLDisplay,
2237 config: EGLConfig,
2238 pixmap: NativePixmapType,
2239 attrib_list: *const Int
2240 ) -> EGLSurface;
2241 fn eglCreateWindowSurface(
2242 display: EGLDisplay,
2243 config: EGLConfig,
2244 win: NativeWindowType,
2245 attrib_list: *const Int
2246 ) -> EGLSurface;
2247 fn eglDestroyContext(display: EGLDisplay, ctx: EGLContext) -> Boolean;
2248 fn eglDestroySurface(display: EGLDisplay, surface: EGLSurface) -> Boolean;
2249 fn eglGetConfigAttrib(
2250 display: EGLDisplay,
2251 config: EGLConfig,
2252 attribute: Int,
2253 value: *mut Int
2254 ) -> Boolean;
2255 fn eglGetConfigs(
2256 display: EGLDisplay,
2257 configs: *mut EGLConfig,
2258 config_size: Int,
2259 num_config: *mut Int
2260 ) -> Boolean;
2261 fn eglGetCurrentDisplay() -> EGLDisplay;
2262 fn eglGetCurrentSurface(readdraw: Int) -> EGLSurface;
2263 fn eglGetDisplay(display_id: NativeDisplayType) -> EGLDisplay;
2264 fn eglGetError() -> Int;
2265 fn eglGetProcAddress(procname: *const c_char) -> extern "C" fn();
2266 fn eglInitialize(display: EGLDisplay, major: *mut Int, minor: *mut Int) -> Boolean;
2267 fn eglMakeCurrent(
2268 display: EGLDisplay,
2269 draw: EGLSurface,
2270 read: EGLSurface,
2271 ctx: EGLContext
2272 ) -> Boolean;
2273 fn eglQueryContext(
2274 display: EGLDisplay,
2275 ctx: EGLContext,
2276 attribute: Int,
2277 value: *mut Int
2278 ) -> Boolean;
2279 fn eglQueryString(display: EGLDisplay, name: Int) -> *const c_char;
2280 fn eglQuerySurface(
2281 display: EGLDisplay,
2282 surface: EGLSurface,
2283 attribute: Int,
2284 value: *mut Int
2285 ) -> Boolean;
2286 fn eglSwapBuffers(display: EGLDisplay, surface: EGLSurface) -> Boolean;
2287 fn eglTerminate(display: EGLDisplay) -> Boolean;
2288 fn eglWaitGL() -> Boolean;
2289 fn eglWaitNative(engine: Int) -> Boolean;
2290 },
2291
2292 EGL1_1 : "1_1" {
2293 fn eglBindTexImage(display: EGLDisplay, surface: EGLSurface, buffer: Int) -> Boolean;
2294 fn eglReleaseTexImage(display: EGLDisplay, surface: EGLSurface, buffer: Int) -> Boolean;
2295 fn eglSurfaceAttrib(
2296 display: EGLDisplay,
2297 surface: EGLSurface,
2298 attribute: Int,
2299 value: Int
2300 ) -> Boolean;
2301 fn eglSwapInterval(display: EGLDisplay, interval: Int) -> Boolean;
2302 },
2303
2304 EGL1_2 : "1_2" {
2305 fn eglBindAPI(api: Enum) -> Boolean;
2306 fn eglQueryAPI() -> Enum;
2307 fn eglCreatePbufferFromClientBuffer(
2308 display: EGLDisplay,
2309 buftype: Enum,
2310 buffer: EGLClientBuffer,
2311 config: EGLConfig,
2312 attrib_list: *const Int
2313 ) -> EGLSurface;
2314 fn eglReleaseThread() -> Boolean;
2315 fn eglWaitClient() -> Boolean;
2316 },
2317
2318 EGL1_3 : "1_3" {
2319 },
2321
2322 EGL1_4 : "1_4" {
2323 fn eglGetCurrentContext() -> EGLContext;
2324 },
2325
2326 EGL1_5 : "1_5" {
2327 fn eglCreateSync(display: EGLDisplay, type_: Enum, attrib_list: *const Attrib) -> EGLSync;
2328 fn eglDestroySync(display: EGLDisplay, sync: EGLSync) -> Boolean;
2329 fn eglClientWaitSync(display: EGLDisplay, sync: EGLSync, flags: Int, timeout: Time) -> Int;
2330 fn eglGetSyncAttrib(
2331 display: EGLDisplay,
2332 sync: EGLSync,
2333 attribute: Int,
2334 value: *mut Attrib
2335 ) -> Boolean;
2336 fn eglCreateImage(
2337 display: EGLDisplay,
2338 ctx: EGLContext,
2339 target: Enum,
2340 buffer: EGLClientBuffer,
2341 attrib_list: *const Attrib
2342 ) -> EGLImage;
2343 fn eglDestroyImage(display: EGLDisplay, image: EGLImage) -> Boolean;
2344 fn eglGetPlatformDisplay(
2345 platform: Enum,
2346 native_display: *mut c_void,
2347 attrib_list: *const Attrib
2348 ) -> EGLDisplay;
2349 fn eglCreatePlatformWindowSurface(
2350 display: EGLDisplay,
2351 config: EGLConfig,
2352 native_window: *mut c_void,
2353 attrib_list: *const Attrib
2354 ) -> EGLSurface;
2355 fn eglCreatePlatformPixmapSurface(
2356 display: EGLDisplay,
2357 config: EGLConfig,
2358 native_pixmap: *mut c_void,
2359 attrib_list: *const Attrib
2360 ) -> EGLSurface;
2361 fn eglWaitSync(display: EGLDisplay, sync: EGLSync, flags: Int) -> Boolean;
2362 }
2363}