r_egl/
lib.rs

1//! This crate provides a binding for the Khronos EGL 1.5 API.
2//! It was originally a fork of the [egl](https://crates.io/crates/egl) crate,
3//! which is left unmaintained.
4//!
5//! ## Usage
6//!
7//! You can access the EGL API using an [`Instance`]
8//! object defined by either statically linking with `libEGL.so.1` at compile time,
9//! or dynamically loading the EGL library at runtime.
10//!
11//! ### Static linking
12//!
13//! You must enable static linking using the `static` feature in your `Cargo.toml`:
14//! ```toml
15//! khronos-egl = { version = ..., features = ["static"] }
16//! ```
17//!
18//! This will add a dependency to the [`pkg-config`](https://crates.io/crates/pkg-config) crate,
19//! necessary to find the EGL library at compile time.
20//! Here is a simple example showing how to use this library to create an EGL context when static linking is enabled.
21//!
22//! ```rust, ignore
23//! use r_egl as egl;
24//! use wayland_client::Connection;
25//! use wayland_client::Proxy;
26//!
27//! fn main() -> Result<(), egl::Error> {
28//!   // Create an EGL API instance.
29//!   // The `egl::Static` API implementation is only available when the `static` feature is enabled.
30//!   let egl = egl::Instance::new(egl::Static);
31//!   let connection = Connection::connect_to_env().expect("unable to connect to the wayland server");
32//!   let wayland_display = connection.display();
33//!
34//!   let display = unsafe { egl.get_display(wayland_display.id().as_ptr() as *mut std::ffi::c_void) }.unwrap();
35//!   egl.initialize(display)?;
36//!
37//!   let attributes = [
38//!     egl::RED_SIZE, 8,
39//!     egl::GREEN_SIZE, 8,
40//!     egl::BLUE_SIZE, 8,
41//!     egl::NONE
42//!   ];
43//!
44//!   let config = egl.choose_first_config(display, &attributes)?.expect("unable to find an appropriate ELG configuration");
45//!
46//!   let context_attributes = [
47//!     egl::CONTEXT_MAJOR_VERSION, 4,
48//!     egl::CONTEXT_MINOR_VERSION, 0,
49//!     egl::CONTEXT_OPENGL_PROFILE_MASK, egl::CONTEXT_OPENGL_CORE_PROFILE_BIT,
50//!     egl::NONE
51//!   ];
52//!
53//!   egl.create_context(display, config, None, &context_attributes);
54//!
55//!   Ok(())
56//! }
57//! ```
58//!
59//! The creation of a `Display` instance is not detailed here since it depends on your display server.
60//! It is created using the `get_display` function with a pointer to the display server connection handle.
61//! For instance, if you are using the [wayland-client](https://crates.io/crates/wayland-client) crate,
62//! you can get this pointer using the `Display::get_display_ptr` method.
63//!
64//! #### Static API Instance
65//!
66//! It may be bothering in some applications to pass the `Instance` to every function that needs to call the EGL API.
67//! One workaround would be to define a static `Instance`,
68//! which should be possible to define at compile time using static linking.
69//! However this is not yet supported by the stable `rustc` compiler.
70//! With the nightly compiler,
71//! you can combine the `nightly` and `static` features so that this crate
72//! can provide a static `Instance`, called `API` that can then be accessed everywhere.
73//!
74//! ```
75//! # use r_egl as egl;
76//! #[cfg(feature="static")]
77//! use egl::API as egl;
78//! ```
79//!
80//! ### Dynamic Linking
81//!
82//! Dynamic linking allows your application to accept multiple versions of EGL and be more flexible.
83//! You must enable dynamic linking using the `dynamic` feature in your `Cargo.toml`:
84//! ```toml
85//! khronos-egl = { version = ..., features = ["dynamic"] }
86//! ```
87//!
88//! This will add a dependency to the [`libloading`](https://crates.io/crates/libloading) crate,
89//! necessary to find the EGL library at runtime.
90//! You can then load the EGL API into a `Instance<Dynamic<libloading::Library>>` as follows:
91//!
92//! ``` ignore
93//! # use r_egl as egl;
94//! let lib = unsafe { libloading::Library::new("libEGL.so.1") }.expect("unable to find libEGL.so.1");
95//! let egl = unsafe { egl::DynamicInstance::<egl::EGL1_4>::load_required_from(lib) }.expect("unable to load libEGL.so.1");
96//! ```
97//!
98//! Here, `egl::EGL1_4` is used to specify what is the minimum required version of EGL that must be provided by `libEGL.so.1`.
99//! This will return a `DynamicInstance<egl::EGL1_4>`, however in that case where `libEGL.so.1` provides a more recent version of EGL,
100//! you can still upcast this instance to provide version specific features:
101//! ``` ignore
102//! # use r_egl as egl;
103//! # let lib = unsafe { libloading::Library::new("libEGL.so.1") }.expect("unable to find libEGL.so.1");
104//! # let egl = unsafe { egl::DynamicInstance::<egl::EGL1_4>::load_required_from(lib) }.expect("unable to load libEGL.so.1");
105//! match egl.upcast::<egl::EGL1_5>() {
106//!   Some(egl1_5) => {
107//!     // do something with EGL 1.5
108//!   }
109//!   None => {
110//!     // do something with EGL 1.4 instead.
111//!   }
112//! };
113//! ```
114//!
115//! ## Troubleshooting
116//!
117//! ### Static Linking with OpenGL ES
118//!
119//! When using OpenGL ES with `khronos-egl` with the `static` feature,
120//! it is necessary to place a dummy extern at the top of your application which links libEGL first, then GLESv1/2.
121//! This is because libEGL provides symbols required by GLESv1/2.
122//! Here's how to work around this:
123//!
124//! ```
125//! ##[link(name = "EGL")]
126//! ##[link(name = "GLESv2")]
127//! unsafe extern "C" {}
128//! ```
129#![allow(non_upper_case_globals)]
130#![allow(non_snake_case)]
131
132extern crate libc;
133
134use std::convert::{TryFrom, TryInto};
135use std::ffi::CStr;
136use std::ffi::CString;
137use std::fmt;
138use std::ptr;
139
140use libc::{c_char, c_uint, c_void};
141
142/// EGL API provider.
143pub trait Api {
144	/// Version of the provided EGL API.
145	fn version(&self) -> Version;
146}
147
148pub trait Downcast<V> {
149	fn downcast(&self) -> &V;
150}
151
152impl<T> Downcast<T> for T {
153	fn downcast(&self) -> &T {
154		self
155	}
156}
157
158pub trait Upcast<V> {
159	fn upcast(&self) -> Option<&V>;
160}
161
162impl<T> Upcast<T> for T {
163	fn upcast(&self) -> Option<&T> {
164		Some(self)
165	}
166}
167
168/// EGL API instance.
169///
170/// An instance wraps an interface to the EGL API and provide
171/// rust-friendly access to it.
172pub struct Instance<T> {
173	api: T,
174}
175
176/// Add clone for Instance
177impl<T: Clone> Clone for Instance<T> {
178	fn clone(&self) -> Self {
179		Self {
180			api: self.api.clone(),
181		}
182	}
183}
184
185/// Add copy for Instance
186impl<T: Copy> Copy for Instance<T> {}
187
188impl<T> Instance<T> {
189	/// Cast the API.
190	#[inline(always)]
191	pub fn cast_into<U: From<T>>(self) -> Instance<U> {
192		Instance {
193			api: self.api.into(),
194		}
195	}
196
197	/// Try to cast the API.
198	#[inline(always)]
199	pub fn try_cast_into<U: TryFrom<T>>(self) -> Result<Instance<U>, Instance<U::Error>> {
200		match self.api.try_into() {
201			Ok(t) => Ok(Instance { api: t }),
202			Err(e) => Err(Instance { api: e }),
203		}
204	}
205
206	/// Returns the version of the provided EGL API.
207	#[inline(always)]
208	pub fn version(&self) -> Version
209	where
210		T: Api,
211	{
212		self.api.version()
213	}
214}
215
216impl<T> Instance<T> {
217	#[inline(always)]
218	pub const fn new(api: T) -> Instance<T> {
219		Instance { api }
220	}
221}
222
223impl<T: fmt::Debug> fmt::Debug for Instance<T> {
224	#[inline(always)]
225	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
226		write!(f, "Instance({:?})", self.api)
227	}
228}
229
230impl<T> From<T> for Instance<T> {
231	#[inline(always)]
232	fn from(t: T) -> Instance<T> {
233		Instance::new(t)
234	}
235}
236
237// ------------------------------------------------------------------------------------------------
238// EGL 1.0
239// ------------------------------------------------------------------------------------------------
240
241#[cfg(feature = "1_0")]
242mod egl1_0 {
243	use super::*;
244
245	pub type Boolean = c_uint;
246	pub type Int = i32;
247	pub type Attrib = usize;
248	pub type EGLDisplay = *mut c_void;
249	pub type EGLConfig = *mut c_void;
250	pub type EGLContext = *mut c_void;
251	pub type EGLSurface = *mut c_void;
252	pub type NativeDisplayType = *mut c_void;
253
254	#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
255	pub struct Display(EGLDisplay);
256
257	impl Display {
258		/// Creates a new display from its EGL pointer.
259		///
260		/// # Safety
261		///
262		/// `ptr` must be a valid `EGLDisplay` pointer.
263		#[inline]
264		pub unsafe fn from_ptr(ptr: EGLDisplay) -> Display {
265			Display(ptr)
266		}
267
268		#[inline]
269		pub fn as_ptr(&self) -> EGLDisplay {
270			self.0
271		}
272	}
273
274	unsafe impl std::marker::Send for Display {}
275	unsafe impl std::marker::Sync for Display {}
276
277	#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
278	pub struct Config(pub(crate) EGLConfig);
279
280	impl Config {
281		/// Creates a new configuration form its EGL pointer.
282		///
283		/// # Safety
284		///
285		/// `ptr` must be a valid `EGLConfig` pointer.
286		#[inline]
287		pub unsafe fn from_ptr(ptr: EGLConfig) -> Config {
288			Config(ptr)
289		}
290
291		#[inline]
292		pub fn as_ptr(&self) -> EGLConfig {
293			self.0
294		}
295	}
296
297	unsafe impl std::marker::Send for Config {}
298	unsafe impl std::marker::Sync for Config {}
299	#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
300	pub struct Context(pub(crate) EGLContext);
301
302	impl Context {
303		/// Creates a new context form its EGL pointer.
304		///
305		/// # Safety
306		///
307		/// `ptr` must be a valid `EGLContext` pointer.
308		#[inline]
309		pub unsafe fn from_ptr(ptr: EGLContext) -> Context {
310			Context(ptr)
311		}
312
313		#[inline]
314		pub fn as_ptr(&self) -> EGLContext {
315			self.0
316		}
317	}
318
319	unsafe impl std::marker::Send for Context {}
320	unsafe impl std::marker::Sync for Context {}
321
322	#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
323	pub struct Surface(EGLSurface);
324
325	impl Surface {
326		/// Creates a new surface form its EGL pointer.
327		///
328		/// # Safety
329		///
330		/// `ptr` must be a valid `EGLSurface` pointer.
331		#[inline]
332		pub unsafe fn from_ptr(ptr: EGLSurface) -> Surface {
333			Surface(ptr)
334		}
335
336		#[inline]
337		pub fn as_ptr(&self) -> EGLSurface {
338			self.0
339		}
340	}
341
342	unsafe impl std::marker::Send for Surface {}
343	unsafe impl std::marker::Sync for Surface {}
344
345	#[cfg(not(target_os = "android"))]
346	pub type NativePixmapType = *mut c_void;
347
348	#[cfg(not(target_os = "android"))]
349	pub type NativeWindowType = *mut c_void;
350
351	#[repr(C)]
352	#[cfg(target_os = "android")]
353	pub struct android_native_window_t;
354
355	#[repr(C)]
356	#[cfg(target_os = "android")]
357	pub struct egl_native_pixmap_t;
358
359	#[cfg(target_os = "android")]
360	pub type NativePixmapType = *mut egl_native_pixmap_t;
361
362	#[cfg(target_os = "android")]
363	pub type NativeWindowType = *mut android_native_window_t;
364
365	pub const ALPHA_SIZE: Int = 0x3021;
366	pub const BAD_ACCESS: Int = 0x3002;
367	pub const BAD_ALLOC: Int = 0x3003;
368	pub const BAD_ATTRIBUTE: Int = 0x3004;
369	pub const BAD_CONFIG: Int = 0x3005;
370	pub const BAD_CONTEXT: Int = 0x3006;
371	pub const BAD_CURRENT_SURFACE: Int = 0x3007;
372	pub const BAD_DISPLAY: Int = 0x3008;
373	pub const BAD_MATCH: Int = 0x3009;
374	pub const BAD_NATIVE_PIXMAP: Int = 0x300A;
375	pub const BAD_NATIVE_WINDOW: Int = 0x300B;
376	pub const BAD_PARAMETER: Int = 0x300C;
377	pub const BAD_SURFACE: Int = 0x300D;
378	pub const BLUE_SIZE: Int = 0x3022;
379	pub const BUFFER_SIZE: Int = 0x3020;
380	pub const CONFIG_CAVEAT: Int = 0x3027;
381	pub const CONFIG_ID: Int = 0x3028;
382	pub const CORE_NATIVE_ENGINE: Int = 0x305B;
383	pub const DEPTH_SIZE: Int = 0x3025;
384	pub const DONT_CARE: Int = -1;
385	pub const DRAW: Int = 0x3059;
386	pub const EXTENSIONS: Int = 0x3055;
387	pub const FALSE: Boolean = 0;
388	pub const GREEN_SIZE: Int = 0x3023;
389	pub const HEIGHT: Int = 0x3056;
390	pub const LARGEST_PBUFFER: Int = 0x3058;
391	pub const LEVEL: Int = 0x3029;
392	pub const MAX_PBUFFER_HEIGHT: Int = 0x302A;
393	pub const MAX_PBUFFER_PIXELS: Int = 0x302B;
394	pub const MAX_PBUFFER_WIDTH: Int = 0x302C;
395	pub const NATIVE_RENDERABLE: Int = 0x302D;
396	pub const NATIVE_VISUAL_ID: Int = 0x302E;
397	pub const NATIVE_VISUAL_TYPE: Int = 0x302F;
398	pub const NONE: Int = 0x3038;
399	pub const ATTRIB_NONE: Attrib = 0x3038;
400	pub const NON_CONFORMANT_CONFIG: Int = 0x3051;
401	pub const NOT_INITIALIZED: Int = 0x3001;
402	pub const NO_CONTEXT: EGLContext = 0 as EGLContext;
403	pub const NO_DISPLAY: EGLDisplay = 0 as EGLDisplay;
404	pub const NO_SURFACE: EGLSurface = 0 as EGLSurface;
405	pub const PBUFFER_BIT: Int = 0x0001;
406	pub const PIXMAP_BIT: Int = 0x0002;
407	pub const READ: Int = 0x305A;
408	pub const RED_SIZE: Int = 0x3024;
409	pub const SAMPLES: Int = 0x3031;
410	pub const SAMPLE_BUFFERS: Int = 0x3032;
411	pub const SLOW_CONFIG: Int = 0x3050;
412	pub const STENCIL_SIZE: Int = 0x3026;
413	pub const SUCCESS: Int = 0x3000;
414	pub const SURFACE_TYPE: Int = 0x3033;
415	pub const TRANSPARENT_BLUE_VALUE: Int = 0x3035;
416	pub const TRANSPARENT_GREEN_VALUE: Int = 0x3036;
417	pub const TRANSPARENT_RED_VALUE: Int = 0x3037;
418	pub const TRANSPARENT_RGB: Int = 0x3052;
419	pub const TRANSPARENT_TYPE: Int = 0x3034;
420	pub const TRUE: Boolean = 1;
421	pub const VENDOR: Int = 0x3053;
422	pub const VERSION: Int = 0x3054;
423	pub const WIDTH: Int = 0x3057;
424	pub const WINDOW_BIT: Int = 0x0004;
425
426	/// EGL errors.
427	/// https://registry.khronos.org/EGL/api/1.1/EGL/egl.h
428	#[derive(Clone, Copy, PartialEq, Eq, Debug)]
429	pub enum Error {
430		/// In the egl.h, the success is also in the error field. And yes, even succeeded, the
431		/// function also may be failed, I do not know why, so I add this part
432		SuccessButError,
433		/// EGL is not initialized, or could not be initialized, for the specified
434		/// EGL display connection.
435		NotInitialized,
436
437		/// EGL cannot access a requested resource (for example a context is bound
438		/// in another thread).
439		BadAccess,
440
441		/// EGL failed to allocate resources for the requested operation.
442		BadAlloc,
443
444		/// An unrecognized attribute or attribute value was passed in the attribute
445		/// list.
446		BadAttribute,
447
448		/// An Context argument does not name a valid EGL rendering context.
449		BadContext,
450
451		/// An Config argument does not name a valid EGL frame buffer configuration.
452		BadConfig,
453
454		/// The current surface of the calling thread is a window, pixel buffer or
455		/// pixmap that is no longer valid.
456		BadCurrentSurface,
457
458		/// An Display argument does not name a valid EGL display connection.
459		BadDisplay,
460
461		/// An Surface argument does not name a valid surface (window, pixel buffer
462		/// or pixmap) configured for GL rendering.
463		BadSurface,
464
465		/// Arguments are inconsistent (for example, a valid context requires
466		/// buffers not supplied by a valid surface).
467		BadMatch,
468
469		/// One or more argument values are invalid.
470		BadParameter,
471
472		/// A NativePixmapType argument does not refer to a valid native pixmap.
473		BadNativePixmap,
474
475		/// A NativeWindowType argument does not refer to a valid native window.
476		BadNativeWindow,
477
478		/// A power management event has occurred. The application must destroy all
479		/// contexts and reinitialise OpenGL ES state and objects to continue
480		/// rendering.
481		ContextLost,
482
483		//// 0x300F - 0x301F reserved for additional errors.
484		Reserved(Int),
485	}
486
487	impl std::error::Error for Error {
488		fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
489			None
490		}
491	}
492
493	impl Error {
494		pub fn native(&self) -> Int {
495			use Error::*;
496			match self {
497				SuccessButError => SUCCESS,
498				NotInitialized => NOT_INITIALIZED,
499				BadAccess => BAD_ACCESS,
500				BadAlloc => BAD_ALLOC,
501				BadAttribute => BAD_ATTRIBUTE,
502				BadContext => BAD_CONTEXT,
503				BadConfig => BAD_CONFIG,
504				BadCurrentSurface => BAD_CURRENT_SURFACE,
505				BadDisplay => BAD_DISPLAY,
506				BadSurface => BAD_SURFACE,
507				BadMatch => BAD_MATCH,
508				BadParameter => BAD_PARAMETER,
509				BadNativePixmap => BAD_NATIVE_PIXMAP,
510				BadNativeWindow => BAD_NATIVE_WINDOW,
511				ContextLost => CONTEXT_LOST,
512				Reserved(value) => *value,
513			}
514		}
515
516		fn message(&self) -> &'static str {
517			use Error::*;
518			match self {
519				SuccessButError => "Although the return is success, but it still failed",
520				NotInitialized => {
521					"EGL is not initialized, or could not be initialized, for the specified EGL display connection."
522				}
523				BadAccess => {
524					"EGL cannot access a requested resource (for example a context is bound in another thread."
525				}
526				BadAlloc => "EGL failed to allocate resources for the requested operation.",
527				BadAttribute => {
528					"An unrecognized attribute or attribute value was passed in the attribute list."
529				}
530				BadContext => "An Context argument does not name a valid EGL rendering context.",
531				BadConfig => {
532					"An Config argument does not name a valid EGL frame buffer configuration."
533				}
534				BadCurrentSurface => {
535					"The current surface of the calling thread is a window, pixel buffer or pixmap that is no longer valid."
536				}
537				BadDisplay => "An Display argument does not name a valid EGL display connection.",
538				BadSurface => {
539					"An Surface argument does not name a valid surface (window, pixel buffer or pixmap) configured for GL rendering."
540				}
541				BadMatch => {
542					"Arguments are inconsistent (for example, a valid context requires buffers not supplied by a valid surface."
543				}
544				BadParameter => "One or more argument values are invalid.",
545				BadNativePixmap => {
546					"A NativePixmapType argument does not refer to a valid native pixmap."
547				}
548				BadNativeWindow => {
549					"A NativeWindowType argument does not refer to a valid native window."
550				}
551				ContextLost => {
552					"A power management event has occurred. The application must destroy all contexts and reinitialise OpenGL ES state and objects to continue rendering."
553				}
554				Reserved(_) => "Reserved Errors",
555			}
556		}
557	}
558
559	impl From<Error> for Int {
560		fn from(e: Error) -> Int {
561			e.native()
562		}
563	}
564
565	impl TryFrom<Int> for Error {
566		type Error = Int;
567
568		fn try_from(e: Int) -> Result<Error, Int> {
569			use Error::*;
570			match e {
571				NOT_INITIALIZED => Ok(NotInitialized),
572				BAD_ACCESS => Ok(BadAccess),
573				BAD_ALLOC => Ok(BadAlloc),
574				BAD_ATTRIBUTE => Ok(BadAttribute),
575				BAD_CONTEXT => Ok(BadContext),
576				BAD_CONFIG => Ok(BadConfig),
577				BAD_CURRENT_SURFACE => Ok(BadCurrentSurface),
578				BAD_DISPLAY => Ok(BadDisplay),
579				BAD_SURFACE => Ok(BadSurface),
580				BAD_MATCH => Ok(BadMatch),
581				BAD_PARAMETER => Ok(BadParameter),
582				BAD_NATIVE_PIXMAP => Ok(BadNativePixmap),
583				BAD_NATIVE_WINDOW => Ok(BadNativeWindow),
584				CONTEXT_LOST => Ok(ContextLost),
585				// NOTE: RESERVED
586				0x300F..=0x301f => Ok(Error::Reserved(e)),
587				value => Err(value),
588			}
589		}
590	}
591
592	impl fmt::Display for Error {
593		fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
594			self.message().fmt(f)
595		}
596	}
597
598	pub fn check_int_list(attrib_list: &[Int]) -> Result<(), Error> {
599		if attrib_list.last() == Some(&NONE) {
600			Ok(())
601		} else {
602			Err(Error::BadParameter)
603		}
604	}
605
606	pub fn check_attrib_list(attrib_list: &[Attrib]) -> Result<(), Error> {
607		if attrib_list.last() == Some(&ATTRIB_NONE) {
608			Ok(())
609		} else {
610			Err(Error::BadParameter)
611		}
612	}
613
614	impl<T: api::EGL1_0> Instance<T> {
615		/// Return the number of EGL frame buffer configurations that atch specified
616		/// attributes.
617		///
618		/// This will call `eglChooseConfig` without `null` as `configs` to get the
619		/// number of matching configurations.
620		///
621		/// This will return a `BadParameter` error if `attrib_list` is not a valid
622		/// attributes list (if it does not terminate with `NONE`).
623		pub fn matching_config_count(
624			&self,
625			display: Display,
626			attrib_list: &[Int],
627		) -> Result<usize, Error> {
628			check_int_list(attrib_list)?;
629			unsafe {
630				let mut count = 0;
631
632				if self.api.eglChooseConfig(
633					display.as_ptr(),
634					attrib_list.as_ptr(),
635					ptr::null_mut(),
636					0,
637					&mut count,
638				) == TRUE
639				{
640					Ok(count as usize)
641				} else {
642					Err(self.get_error_for_sure())
643				}
644			}
645		}
646
647		/// Return a list of EGL frame buffer configurations that match specified
648		/// attributes.
649		///
650		/// This will write as many matching configurations in `configs` up to its
651		/// capacity. You can use the function [`matching_config_count`](Self::matching_config_count) to get the
652		/// exact number of configurations matching the specified attributes.
653		///
654		/// ## Example
655		///
656		/// ```ignore
657		/// # use r_egl as egl;
658		/// # use wayland_client;
659		/// # use wayland_client::Proxy;
660		/// # fn main() -> Result<(), egl::Error> {
661		/// # let egl = egl::Instance::new(egl::Static);
662		/// # let connection = Connection::connect_to_env().expect("unable to connect to the wayland server");
663		/// # let wayland_display = connection.display();
664		///
665		/// # let display = unsafe { egl.get_display(wayland_display.id().as_ptr() as *mut std::ffi::c_void) }.unwrap();
666		/// # egl.initialize(display)?;
667		/// # let attrib_list = [egl::RED_SIZE, 8, egl::GREEN_SIZE, 8, egl::BLUE_SIZE, 8, egl::NONE];
668		/// // Get the number of matching configurations.
669		/// # let count = egl.matching_config_count(display, &attrib_list)?;
670		///
671		/// # // Get the matching configurations.
672		/// # let mut configs = Vec::with_capacity(count);
673		/// # egl.choose_config(display, &attrib_list, &mut configs)?;
674		/// # Ok(())
675		/// # }
676		/// ```
677		///
678		/// This will return a `BadParameter` error if `attrib_list` is not a valid
679		/// attributes list (if it does not terminate with `NONE`).
680		pub fn choose_config(
681			&self,
682			display: Display,
683			attrib_list: &[Int],
684			configs: &mut Vec<Config>,
685		) -> Result<(), Error> {
686			check_int_list(attrib_list)?;
687
688			let capacity = configs.capacity();
689			if capacity == 0 {
690				// When the input ptr is null (when capacity is 0),
691				// eglChooseConfig behaves differently and returns the number
692				// of configurations.
693				Ok(())
694			} else {
695				unsafe {
696					let mut count = 0;
697
698					if self.api.eglChooseConfig(
699						display.as_ptr(),
700						attrib_list.as_ptr(),
701						configs.as_mut_ptr() as *mut EGLConfig,
702						capacity.try_into().unwrap(),
703						&mut count,
704					) == TRUE
705					{
706						configs.set_len(count as usize);
707						Ok(())
708					} else {
709						Err(self.get_error_for_sure())
710					}
711				}
712			}
713		}
714
715		/// Return the first EGL frame buffer configuration that match specified
716		/// attributes.
717		///
718		/// This is an helper function that will call `choose_config` with a buffer of
719		/// size 1, which is equivalent to:
720		/// ```ignore
721		/// # use r_egl as egl;
722		/// # use wayland_client::{Connection, Proxy};
723		/// # fn main() -> Result<(), egl::Error> {
724		/// # let egl = egl::Instance::new(egl::Static);
725		/// # let connection = Connection::connect_to_env().expect("unable to connect to the wayland server");
726		/// # let wayland_display = connection.display();
727		///
728		/// # let display = unsafe { egl.get_display(wayland_display.id().as_ptr() as *mut std::ffi::c_void) }.unwrap();
729		/// # egl.initialize(display)?;
730		/// # let attrib_list = [egl::RED_SIZE, 8, egl::GREEN_SIZE, 8, egl::BLUE_SIZE, 8, egl::NONE];
731		/// let mut configs = Vec::with_capacity(1);
732		/// egl.choose_config(display, &attrib_list, &mut configs)?;
733		/// configs.first();
734		/// # Ok(())
735		/// # }
736		/// ```
737		pub fn choose_first_config(
738			&self,
739			display: Display,
740			attrib_list: &[Int],
741		) -> Result<Option<Config>, Error> {
742			let mut configs = Vec::with_capacity(1);
743			self.choose_config(display, attrib_list, &mut configs)?;
744			Ok(configs.first().copied())
745		}
746
747		/// Copy EGL surface color buffer to a native pixmap.
748		///
749		/// # Safety
750		///
751		/// `target` must be a valid pointer to a native pixmap that belongs
752		/// to the same platform as `display` and `surface`.
753		pub unsafe fn copy_buffers(
754			&self,
755			display: Display,
756			surface: Surface,
757			target: NativePixmapType,
758		) -> Result<(), Error> {
759			unsafe {
760				if self
761					.api
762					.eglCopyBuffers(display.as_ptr(), surface.as_ptr(), target)
763					== TRUE
764				{
765					Ok(())
766				} else {
767					Err(self.get_error_for_sure())
768				}
769			}
770		}
771
772		/// Create a new EGL rendering context.
773		///
774		/// This will return a `BadParameter` error if `attrib_list` is not a valid
775		/// attributes list (if it does not terminate with `NONE`).
776		pub fn create_context(
777			&self,
778			display: Display,
779			config: Config,
780			share_context: Option<Context>,
781			attrib_list: &[Int],
782		) -> Result<Context, Error> {
783			check_int_list(attrib_list)?;
784			unsafe {
785				let share_context = match share_context {
786					Some(share_context) => share_context.as_ptr(),
787					None => NO_CONTEXT,
788				};
789
790				let context = self.api.eglCreateContext(
791					display.as_ptr(),
792					config.as_ptr(),
793					share_context,
794					attrib_list.as_ptr(),
795				);
796
797				if context != NO_CONTEXT {
798					Ok(Context(context))
799				} else {
800					Err(self.get_error_for_sure())
801				}
802			}
803		}
804
805		/// Create a new EGL pixel buffer surface.
806		///
807		/// This will return a `BadParameter` error if `attrib_list` is not a valid
808		/// attributes list (if it does not terminate with `NONE`).
809		pub fn create_pbuffer_surface(
810			&self,
811			display: Display,
812			config: Config,
813			attrib_list: &[Int],
814		) -> Result<Surface, Error> {
815			check_int_list(attrib_list)?;
816			unsafe {
817				let surface = self.api.eglCreatePbufferSurface(
818					display.as_ptr(),
819					config.as_ptr(),
820					attrib_list.as_ptr(),
821				);
822
823				if surface != NO_SURFACE {
824					Ok(Surface(surface))
825				} else {
826					Err(self.get_error_for_sure())
827				}
828			}
829		}
830
831		/// Create a new EGL offscreen surface.
832		///
833		/// This will return a `BadParameter` error if `attrib_list` is not a valid
834		/// attributes list (if it does not terminate with `NONE`).
835		///
836		/// # Safety
837		///
838		/// This function may raise undefined behavior if the display and native
839		/// pixmap do not belong to the same platform.
840		pub unsafe fn create_pixmap_surface(
841			&self,
842			display: Display,
843			config: Config,
844			pixmap: NativePixmapType,
845			attrib_list: &[Int],
846		) -> Result<Surface, Error> {
847			unsafe {
848				check_int_list(attrib_list)?;
849				let surface = self.api.eglCreatePixmapSurface(
850					display.as_ptr(),
851					config.as_ptr(),
852					pixmap,
853					attrib_list.as_ptr(),
854				);
855
856				if surface != NO_SURFACE {
857					Ok(Surface(surface))
858				} else {
859					Err(self.get_error_for_sure())
860				}
861			}
862		}
863
864		/// Create a new EGL window surface.
865		///
866		/// This will return a `BadParameter` error if `attrib_list` is not a valid
867		/// attributes list (if it does not terminate with `NONE`).
868		///
869		/// # Safety
870		///
871		/// This function may raise undefined behavior if the display and native
872		/// window do not belong to the same platform.
873		pub unsafe fn create_window_surface(
874			&self,
875			display: Display,
876			config: Config,
877			window: NativeWindowType,
878			attrib_list: Option<&[Int]>,
879		) -> Result<Surface, Error> {
880			unsafe {
881				let attrib_list = match attrib_list {
882					Some(attrib_list) => {
883						check_int_list(attrib_list)?;
884						attrib_list.as_ptr()
885					}
886					None => ptr::null(),
887				};
888
889				let surface = self.api.eglCreateWindowSurface(
890					display.as_ptr(),
891					config.as_ptr(),
892					window,
893					attrib_list,
894				);
895
896				if surface != NO_SURFACE {
897					Ok(Surface(surface))
898				} else {
899					Err(self.get_error_for_sure())
900				}
901			}
902		}
903
904		/// Destroy an EGL rendering context.
905		pub fn destroy_context(&self, display: Display, ctx: Context) -> Result<(), Error> {
906			unsafe {
907				if self.api.eglDestroyContext(display.as_ptr(), ctx.as_ptr()) == TRUE {
908					Ok(())
909				} else {
910					Err(self.get_error_for_sure())
911				}
912			}
913		}
914
915		/// Destroy an EGL surface.
916		pub fn destroy_surface(&self, display: Display, surface: Surface) -> Result<(), Error> {
917			unsafe {
918				if self
919					.api
920					.eglDestroySurface(display.as_ptr(), surface.as_ptr())
921					== TRUE
922				{
923					Ok(())
924				} else {
925					Err(self.get_error_for_sure())
926				}
927			}
928		}
929
930		/// Return information about an EGL frame buffer configuration.
931		pub fn get_config_attrib(
932			&self,
933			display: Display,
934			config: Config,
935			attribute: Int,
936		) -> Result<Int, Error> {
937			unsafe {
938				let mut value: Int = 0;
939				if self.api.eglGetConfigAttrib(
940					display.as_ptr(),
941					config.as_ptr(),
942					attribute,
943					&mut value,
944				) == TRUE
945				{
946					Ok(value)
947				} else {
948					Err(self.get_error_for_sure())
949				}
950			}
951		}
952
953		/// Return the number of all frame buffer configurations.
954		///
955		/// You can use it to setup the correct capacity for the configurations buffer in [`get_configs`](Self::get_configs).
956		///
957		/// ## Example
958		/// ```ignore
959		/// # use r_egl as egl;
960		/// # use wayland_client::{Connection, Proxy};
961		/// # fn main() -> Result<(), egl::Error> {
962		/// # let egl = egl::Instance::new(egl::Static);
963		/// # let connection = Connection::connect_to_env().expect("unable to connect to the wayland server");
964		/// # let wayland_display = connection.display();
965		/// # let display = unsafe { egl.get_display(wayland_display.get_display_ptr() as *mut std::ffi::c_void) }.unwrap();
966		/// # egl.initialize(display)?;
967		/// let mut configs = Vec::with_capacity(egl.get_config_count(display)?);
968		/// egl.get_configs(display, &mut configs);
969		/// assert!(configs.len() > 0);
970		/// # Ok(())
971		/// # }
972		/// ```
973		pub fn get_config_count(&self, display: Display) -> Result<usize, Error> {
974			unsafe {
975				let mut count = 0;
976
977				if self
978					.api
979					.eglGetConfigs(display.as_ptr(), std::ptr::null_mut(), 0, &mut count)
980					== TRUE
981				{
982					Ok(count as usize)
983				} else {
984					Err(self.get_error_for_sure())
985				}
986			}
987		}
988
989		/// Get the list of all EGL frame buffer configurations for a display.
990		///
991		/// The configurations are added to the `configs` buffer, up to the buffer's capacity.
992		/// You can use [`get_config_count`](Self::get_config_count) to get the total number of available frame buffer configurations,
993		/// and setup the buffer's capacity accordingly.
994		///
995		/// ## Example
996		/// ``` ignore
997		/// # use r_egl as egl;
998		/// # use wayland_client::{Connection, Proxy};
999		/// # fn main() -> Result<(), egl::Error> {
1000		/// # let egl = egl::Instance::new(egl::Static);
1001		/// # let connection = Connection::connect_to_env().expect("unable to connect to the wayland server");
1002		/// # let wayland_display = connection.display();
1003		///
1004		/// # let display = unsafe { egl.get_display(wayland_display.id().as_ptr() as *mut std::ffi::c_void) }.unwrap();
1005		/// # let wayland_display = wayland_client::Display::connect_to_env().expect("unable to connect to the wayland server");
1006		/// # let display = unsafe { egl.get_display(wayland_display.get_display_ptr() as *mut std::ffi::c_void) }.unwrap();
1007		/// # egl.initialize(display)?;
1008		/// let mut configs = Vec::with_capacity(egl.get_config_count(display)?);
1009		/// egl.get_configs(display, &mut configs);
1010		/// # Ok(())
1011		/// # }
1012		/// ```
1013		pub fn get_configs(
1014			&self,
1015			display: Display,
1016			configs: &mut Vec<Config>,
1017		) -> Result<(), Error> {
1018			let capacity = configs.capacity();
1019			if capacity == 0 {
1020				// When the input ptr is null (when capacity is 0),
1021				// eglGetConfig behaves differently and returns the number
1022				// of configurations.
1023				Ok(())
1024			} else {
1025				unsafe {
1026					let mut count = 0;
1027
1028					if self.api.eglGetConfigs(
1029						display.as_ptr(),
1030						configs.as_mut_ptr() as *mut EGLConfig,
1031						capacity.try_into().unwrap(),
1032						&mut count,
1033					) == TRUE
1034					{
1035						configs.set_len(count as usize);
1036						Ok(())
1037					} else {
1038						Err(self.get_error_for_sure())
1039					}
1040				}
1041			}
1042		}
1043
1044		/// Return the display for the current EGL rendering context.
1045		pub fn get_current_display(&self) -> Option<Display> {
1046			unsafe {
1047				let display = self.api.eglGetCurrentDisplay();
1048
1049				if display != NO_DISPLAY {
1050					Some(Display(display))
1051				} else {
1052					None
1053				}
1054			}
1055		}
1056
1057		/// Return the read or draw surface for the current EGL rendering context.
1058		pub fn get_current_surface(&self, readdraw: Int) -> Option<Surface> {
1059			unsafe {
1060				let surface = self.api.eglGetCurrentSurface(readdraw);
1061
1062				if surface != NO_SURFACE {
1063					Some(Surface(surface))
1064				} else {
1065					None
1066				}
1067			}
1068		}
1069
1070		/// Return an EGL display connection.
1071		///
1072		/// # Safety
1073		///
1074		/// The `native_display` must be a valid pointer to the native display.
1075		/// Valid values for platform are defined by EGL extensions, as are
1076		/// requirements for native_display. For example, an extension
1077		/// specification that defines support for the X11 platform may require
1078		/// that native_display be a pointer to an X11 Display, and an extension
1079		/// specification that defines support for the Microsoft Windows
1080		/// platform may require that native_display be a pointer to a Windows
1081		/// Device Context.
1082		pub unsafe fn get_display(&self, display_id: NativeDisplayType) -> Option<Display> {
1083			unsafe {
1084				let display = self.api.eglGetDisplay(display_id);
1085
1086				if display != NO_DISPLAY {
1087					Some(Display(display))
1088				} else {
1089					None
1090				}
1091			}
1092		}
1093
1094		/// Return error information.
1095		///
1096		/// Return the error of the last called EGL function in the current thread, or
1097		/// `None` if the error is set to `SUCCESS`.
1098		///
1099		/// Note that since a call to `eglGetError` sets the error to `SUCCESS`, and
1100		/// since this function is automatically called by any wrapper function
1101		/// returning a `Result` when necessary, this function may only return `None`
1102		/// from the point of view of a user.
1103		pub(crate) fn get_error_for_sure(&self) -> Error {
1104			unsafe {
1105				let err_code = self.api.eglGetError();
1106				// We should not return success code to error, but at the logic inner, we need keep
1107				// the logic do not panic. Sometimes it will fail successfully. I cannot find out
1108				// why
1109				if err_code == SUCCESS {
1110					return Error::SuccessButError;
1111				}
1112				err_code.try_into().expect("should receive an error")
1113			}
1114		}
1115		/// Return error information.
1116		///
1117		/// Return the error of the last called EGL function in the current thread, or
1118		/// `None` if the error is set to `SUCCESS`.
1119		///
1120		/// Note that since a call to `eglGetError` sets the error to `SUCCESS`, and
1121		/// since this function is automatically called by any wrapper function
1122		/// returning a `Result` when necessary, this function may only return `None`
1123		/// from the point of view of a user.
1124		pub fn get_error(&self) -> Option<Error> {
1125			unsafe { self.api.eglGetError().try_into().ok() }
1126		}
1127
1128		/// Return a GL or an EGL extension function.
1129		pub fn get_proc_address(&self, procname: &str) -> Option<extern "system" fn()> {
1130			unsafe {
1131				let string = CString::new(procname).unwrap();
1132
1133				let addr = self.api.eglGetProcAddress(string.as_ptr());
1134				if !addr.is_null() {
1135					Some(std::mem::transmute::<*const (), extern "system" fn()>(addr))
1136				} else {
1137					None
1138				}
1139			}
1140		}
1141
1142		/// Initialize an EGL display connection.
1143		pub fn initialize(&self, display: Display) -> Result<(Int, Int), Error> {
1144			unsafe {
1145				let mut major = 0;
1146				let mut minor = 0;
1147
1148				if self
1149					.api
1150					.eglInitialize(display.as_ptr(), &mut major, &mut minor)
1151					== TRUE
1152				{
1153					Ok((major, minor))
1154				} else {
1155					Err(self.get_error_for_sure())
1156				}
1157			}
1158		}
1159
1160		/// Attach an EGL rendering context to EGL surfaces.
1161		pub fn make_current(
1162			&self,
1163			display: Display,
1164			draw: Option<Surface>,
1165			read: Option<Surface>,
1166			ctx: Option<Context>,
1167		) -> Result<(), Error> {
1168			unsafe {
1169				let draw = match draw {
1170					Some(draw) => draw.as_ptr(),
1171					None => NO_SURFACE,
1172				};
1173				let read = match read {
1174					Some(read) => read.as_ptr(),
1175					None => NO_SURFACE,
1176				};
1177				let ctx = match ctx {
1178					Some(ctx) => ctx.as_ptr(),
1179					None => NO_CONTEXT,
1180				};
1181
1182				if self.api.eglMakeCurrent(display.as_ptr(), draw, read, ctx) == TRUE {
1183					Ok(())
1184				} else {
1185					Err(self.get_error_for_sure())
1186				}
1187			}
1188		}
1189
1190		/// Return EGL rendering context information.
1191		pub fn query_context(
1192			&self,
1193			display: Display,
1194			ctx: Context,
1195			attribute: Int,
1196		) -> Result<Int, Error> {
1197			unsafe {
1198				let mut value = 0;
1199				if self
1200					.api
1201					.eglQueryContext(display.as_ptr(), ctx.as_ptr(), attribute, &mut value)
1202					== TRUE
1203				{
1204					Ok(value)
1205				} else {
1206					Err(self.get_error_for_sure())
1207				}
1208			}
1209		}
1210
1211		/// Return a string describing properties of the EGL client or of an EGL display
1212		/// connection.
1213		pub fn query_string(
1214			&self,
1215			display: Option<Display>,
1216			name: Int,
1217		) -> Result<&'static CStr, Error> {
1218			unsafe {
1219				let display_ptr = match display {
1220					Some(display) => display.as_ptr(),
1221					None => NO_DISPLAY,
1222				};
1223
1224				let c_str = self.api.eglQueryString(display_ptr, name);
1225
1226				if !c_str.is_null() {
1227					Ok(CStr::from_ptr(c_str))
1228				} else {
1229					Err(self.get_error_for_sure())
1230				}
1231			}
1232		}
1233
1234		/// Return EGL surface information.
1235		pub fn query_surface(
1236			&self,
1237			display: Display,
1238			surface: Surface,
1239			attribute: Int,
1240		) -> Result<Int, Error> {
1241			unsafe {
1242				let mut value = 0;
1243				if self.api.eglQuerySurface(
1244					display.as_ptr(),
1245					surface.as_ptr(),
1246					attribute,
1247					&mut value,
1248				) == TRUE
1249				{
1250					Ok(value)
1251				} else {
1252					Err(self.get_error_for_sure())
1253				}
1254			}
1255		}
1256
1257		/// Post EGL surface color buffer to a native window.
1258		pub fn swap_buffers(&self, display: Display, surface: Surface) -> Result<(), Error> {
1259			unsafe {
1260				if self.api.eglSwapBuffers(display.as_ptr(), surface.as_ptr()) == TRUE {
1261					Ok(())
1262				} else {
1263					Err(self.get_error_for_sure())
1264				}
1265			}
1266		}
1267
1268		/// Terminate an EGL display connection.
1269		pub fn terminate(&self, display: Display) -> Result<(), Error> {
1270			unsafe {
1271				if self.api.eglTerminate(display.as_ptr()) == TRUE {
1272					Ok(())
1273				} else {
1274					Err(self.get_error_for_sure())
1275				}
1276			}
1277		}
1278
1279		/// Complete GL execution prior to subsequent native rendering calls.
1280		pub fn wait_gl(&self) -> Result<(), Error> {
1281			unsafe {
1282				if self.api.eglWaitGL() == TRUE {
1283					Ok(())
1284				} else {
1285					Err(self.get_error_for_sure())
1286				}
1287			}
1288		}
1289
1290		/// Complete native execution prior to subsequent GL rendering calls.
1291		pub fn wait_native(&self, engine: Int) -> Result<(), Error> {
1292			unsafe {
1293				if self.api.eglWaitNative(engine) == TRUE {
1294					Ok(())
1295				} else {
1296					Err(self.get_error_for_sure())
1297				}
1298			}
1299		}
1300	}
1301}
1302
1303#[cfg(feature = "1_0")]
1304pub use egl1_0::*;
1305
1306// ------------------------------------------------------------------------------------------------
1307// EGL 1.1
1308// ------------------------------------------------------------------------------------------------
1309
1310#[cfg(feature = "1_1")]
1311mod egl1_1 {
1312	use super::*;
1313
1314	pub const BACK_BUFFER: Int = 0x3084;
1315	pub const BIND_TO_TEXTURE_RGB: Int = 0x3039;
1316	pub const BIND_TO_TEXTURE_RGBA: Int = 0x303A;
1317	pub const CONTEXT_LOST: Int = 0x300E;
1318	pub const MIN_SWAP_INTERVAL: Int = 0x303B;
1319	pub const MAX_SWAP_INTERVAL: Int = 0x303C;
1320	pub const MIPMAP_TEXTURE: Int = 0x3082;
1321	pub const MIPMAP_LEVEL: Int = 0x3083;
1322	pub const NO_TEXTURE: Int = 0x305C;
1323	pub const TEXTURE_2D: Int = 0x305F;
1324	pub const TEXTURE_FORMAT: Int = 0x3080;
1325	pub const TEXTURE_RGB: Int = 0x305D;
1326	pub const TEXTURE_RGBA: Int = 0x305E;
1327	pub const TEXTURE_TARGET: Int = 0x3081;
1328
1329	impl<T: api::EGL1_1> Instance<T> {
1330		/// Defines a two-dimensional texture image.
1331		pub fn bind_tex_image(
1332			&self,
1333			display: Display,
1334			surface: Surface,
1335			buffer: Int,
1336		) -> Result<(), Error> {
1337			unsafe {
1338				if self
1339					.api
1340					.eglBindTexImage(display.as_ptr(), surface.as_ptr(), buffer)
1341					== TRUE
1342				{
1343					Ok(())
1344				} else {
1345					Err(self.get_error_for_sure())
1346				}
1347			}
1348		}
1349
1350		///  Releases a color buffer that is being used as a texture.
1351		pub fn release_tex_image(
1352			&self,
1353			display: Display,
1354			surface: Surface,
1355			buffer: Int,
1356		) -> Result<(), Error> {
1357			unsafe {
1358				if self
1359					.api
1360					.eglReleaseTexImage(display.as_ptr(), surface.as_ptr(), buffer)
1361					== TRUE
1362				{
1363					Ok(())
1364				} else {
1365					Err(self.get_error_for_sure())
1366				}
1367			}
1368		}
1369
1370		/// Set an EGL surface attribute.
1371		pub fn surface_attrib(
1372			&self,
1373			display: Display,
1374			surface: Surface,
1375			attribute: Int,
1376			value: Int,
1377		) -> Result<(), Error> {
1378			unsafe {
1379				if self
1380					.api
1381					.eglSurfaceAttrib(display.as_ptr(), surface.as_ptr(), attribute, value)
1382					== TRUE
1383				{
1384					Ok(())
1385				} else {
1386					Err(self.get_error_for_sure())
1387				}
1388			}
1389		}
1390
1391		/// Specifies the minimum number of video frame periods per buffer swap for the
1392		/// window associated with the current context.
1393		pub fn swap_interval(&self, display: Display, interval: Int) -> Result<(), Error> {
1394			unsafe {
1395				if self.api.eglSwapInterval(display.as_ptr(), interval) == TRUE {
1396					Ok(())
1397				} else {
1398					Err(self.get_error_for_sure())
1399				}
1400			}
1401		}
1402	}
1403}
1404
1405#[cfg(feature = "1_1")]
1406pub use egl1_1::*;
1407
1408// ------------------------------------------------------------------------------------------------
1409// EGL 1.2
1410// ------------------------------------------------------------------------------------------------
1411
1412#[cfg(feature = "1_2")]
1413mod egl1_2 {
1414	use super::*;
1415
1416	pub type Enum = c_uint;
1417	pub type EGLClientBuffer = *mut c_void;
1418
1419	#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
1420	pub struct ClientBuffer(EGLClientBuffer);
1421
1422	impl ClientBuffer {
1423		/// Creates a new client buffer form its EGL pointer.
1424		///
1425		/// # Safety
1426		///
1427		/// `ptr` must be a valid `EGLClientBuffer` pointer.
1428		#[inline]
1429		pub unsafe fn from_ptr(ptr: EGLClientBuffer) -> ClientBuffer {
1430			ClientBuffer(ptr)
1431		}
1432
1433		#[inline]
1434		pub fn as_ptr(&self) -> EGLClientBuffer {
1435			self.0
1436		}
1437	}
1438	unsafe impl std::marker::Send for ClientBuffer {}
1439	unsafe impl std::marker::Sync for ClientBuffer {}
1440
1441	pub const ALPHA_FORMAT: Int = 0x3088;
1442	pub const ALPHA_FORMAT_NONPRE: Int = 0x308B;
1443	pub const ALPHA_FORMAT_PRE: Int = 0x308C;
1444	pub const ALPHA_MASK_SIZE: Int = 0x303E;
1445	pub const BUFFER_PRESERVED: Int = 0x3094;
1446	pub const BUFFER_DESTROYED: Int = 0x3095;
1447	pub const CLIENT_APIS: Int = 0x308D;
1448	pub const COLORSPACE: Int = 0x3087;
1449	pub const COLORSPACE_sRGB: Int = 0x3089;
1450	pub const COLORSPACE_LINEAR: Int = 0x308A;
1451	pub const COLOR_BUFFER_TYPE: Int = 0x303F;
1452	pub const CONTEXT_CLIENT_TYPE: Int = 0x3097;
1453	pub const DISPLAY_SCALING: Int = 10000;
1454	pub const HORIZONTAL_RESOLUTION: Int = 0x3090;
1455	pub const LUMINANCE_BUFFER: Int = 0x308F;
1456	pub const LUMINANCE_SIZE: Int = 0x303D;
1457	pub const OPENGL_ES_BIT: Int = 0x0001;
1458	pub const OPENVG_BIT: Int = 0x0002;
1459	pub const OPENGL_ES_API: Enum = 0x30A0;
1460	pub const OPENVG_API: Enum = 0x30A1;
1461	pub const OPENVG_IMAGE: Int = 0x3096;
1462	pub const PIXEL_ASPECT_RATIO: Int = 0x3092;
1463	pub const RENDERABLE_TYPE: Int = 0x3040;
1464	pub const RENDER_BUFFER: Int = 0x3086;
1465	pub const RGB_BUFFER: Int = 0x308E;
1466	pub const SINGLE_BUFFER: Int = 0x3085;
1467	pub const SWAP_BEHAVIOR: Int = 0x3093;
1468	pub const UNKNOWN: Int = -1;
1469	pub const VERTICAL_RESOLUTION: Int = 0x3091;
1470
1471	/// Linux dma_buf buf
1472	/// https://registry.khronos.org/EGL/extensions/EXT/EGL_EXT_image_dma_buf_import.txt
1473	pub const LINUX_DMA_BUF_EXT: Int = 0x3270;
1474	pub const LINUX_DRM_FOURCC_EXT: Int = 0x3271;
1475	pub const DMA_BUF_PLANE0_FD_EXT: Int = 0x3272;
1476	pub const DMA_BUF_PLANE0_OFFSET_EXT: Int = 0x3273;
1477	pub const DMA_BUF_PLANE0_PITCH_EXT: Int = 0x3274;
1478	pub const DMA_BUF_PLANE1_FD_EXT: Int = 0x3275;
1479	pub const DMA_BUF_PLANE1_OFFSET_EXT: Int = 0x3276;
1480	pub const DMA_BUF_PLANE1_PITCH_EXT: Int = 0x3277;
1481	pub const DMA_BUF_PLANE2_FD_EXT: Int = 0x3278;
1482	pub const DMA_BUF_PLANE2_OFFSET_EXT: Int = 0x3279;
1483	pub const DMA_BUF_PLANE2_PITCH_EXT: Int = 0x327A;
1484	pub const YUV_COLOR_SPACE_HINT_EXT: Int = 0x327B;
1485	pub const SAMPLE_RANGE_HINT_EXT: Int = 0x327C;
1486	pub const YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT: Int = 0x327D;
1487	pub const YUV_CHROMA_VERTICAL_SITING_HINT_EXT: Int = 0x327E;
1488
1489	/// Linux dma_buf modifiers
1490	/// https://registry.khronos.org/EGL/extensions/EXT/EGL_EXT_image_dma_buf_import_modifiers.txt
1491	pub const DMA_BUF_PLANE0_MODIFIER_LO_EXT: Int = 0x3443;
1492	pub const DMA_BUF_PLANE0_MODIFIER_HI_EXT: Int = 0x3444;
1493	pub const DMA_BUF_PLANE1_MODIFIER_LO_EXT: Int = 0x3445;
1494	pub const DMA_BUF_PLANE1_MODIFIER_HI_EXT: Int = 0x3446;
1495	pub const DMA_BUF_PLANE2_MODIFIER_LO_EXT: Int = 0x3447;
1496	pub const DMA_BUF_PLANE2_MODIFIER_HI_EXT: Int = 0x3448;
1497	pub const DMA_BUF_PLANE3_FD_EXT: Int = 0x3440;
1498	pub const DMA_BUF_PLANE3_OFFSET_EXT: Int = 0x3441;
1499	pub const DMA_BUF_PLANE3_PITCH_EXT: Int = 0x3442;
1500	pub const DMA_BUF_PLANE3_MODIFIER_LO_EXT: Int = 0x3449;
1501	pub const DMA_BUF_PLANE3_MODIFIER_HI_EXT: Int = 0x344A;
1502
1503	impl<T: api::EGL1_2> Instance<T> {
1504		/// Set the current rendering API.
1505		pub fn bind_api(&self, api: Enum) -> Result<(), Error> {
1506			unsafe {
1507				if self.api.eglBindAPI(api) == TRUE {
1508					Ok(())
1509				} else {
1510					Err(self.get_error_for_sure())
1511				}
1512			}
1513		}
1514
1515		/// Query the current rendering API.
1516		pub fn query_api(&self) -> Enum {
1517			unsafe { self.api.eglQueryAPI() }
1518		}
1519
1520		/// Create a new EGL pixel buffer surface bound to an OpenVG image.
1521		///
1522		/// This will return a `BadParameter` error if `attrib_list` is not a valid
1523		/// attributes list (if it does not terminate with `NONE`).
1524		pub fn create_pbuffer_from_client_buffer(
1525			&self,
1526			display: Display,
1527			buffer_type: Enum,
1528			buffer: ClientBuffer,
1529			config: Config,
1530			attrib_list: &[Int],
1531		) -> Result<Surface, Error> {
1532			check_int_list(attrib_list)?;
1533			unsafe {
1534				let surface = self.api.eglCreatePbufferFromClientBuffer(
1535					display.as_ptr(),
1536					buffer_type,
1537					buffer.as_ptr(),
1538					config.as_ptr(),
1539					attrib_list.as_ptr(),
1540				);
1541
1542				if surface != NO_SURFACE {
1543					Ok(Surface::from_ptr(surface))
1544				} else {
1545					Err(self.get_error_for_sure())
1546				}
1547			}
1548		}
1549
1550		/// Release EGL per-thread state.
1551		pub fn release_thread(&self) -> Result<(), Error> {
1552			unsafe {
1553				if self.api.eglReleaseThread() == TRUE {
1554					Ok(())
1555				} else {
1556					Err(self.get_error_for_sure())
1557				}
1558			}
1559		}
1560
1561		/// Complete client API execution prior to subsequent native rendering calls.
1562		pub fn wait_client(&self) -> Result<(), Error> {
1563			unsafe {
1564				if self.api.eglWaitClient() == TRUE {
1565					Ok(())
1566				} else {
1567					Err(self.get_error_for_sure())
1568				}
1569			}
1570		}
1571	}
1572}
1573
1574#[cfg(feature = "1_2")]
1575pub use egl1_2::*;
1576
1577// ------------------------------------------------------------------------------------------------
1578// EGL 1.3
1579// ------------------------------------------------------------------------------------------------
1580
1581#[cfg(feature = "1_3")]
1582mod egl1_3 {
1583	use super::*;
1584
1585	pub const CONFORMANT: Int = 0x3042;
1586	pub const CONTEXT_CLIENT_VERSION: Int = 0x3098;
1587	pub const MATCH_NATIVE_PIXMAP: Int = 0x3041;
1588	pub const OPENGL_ES2_BIT: Int = 0x0004;
1589	pub const VG_ALPHA_FORMAT: Int = 0x3088;
1590	pub const VG_ALPHA_FORMAT_NONPRE: Int = 0x308B;
1591	pub const VG_ALPHA_FORMAT_PRE: Int = 0x308C;
1592	pub const VG_ALPHA_FORMAT_PRE_BIT: Int = 0x0040;
1593	pub const VG_COLORSPACE: Int = 0x3087;
1594	pub const VG_COLORSPACE_sRGB: Int = 0x3089;
1595	pub const VG_COLORSPACE_LINEAR: Int = 0x308A;
1596	pub const VG_COLORSPACE_LINEAR_BIT: Int = 0x0020;
1597}
1598
1599#[cfg(feature = "1_3")]
1600pub use egl1_3::*;
1601
1602// ------------------------------------------------------------------------------------------------
1603// EGL 1.4
1604// ------------------------------------------------------------------------------------------------
1605
1606#[cfg(feature = "1_4")]
1607mod egl1_4 {
1608	use super::*;
1609
1610	pub const DEFAULT_DISPLAY: NativeDisplayType = 0 as NativeDisplayType;
1611	pub const MULTISAMPLE_RESOLVE_BOX_BIT: Int = 0x0200;
1612	pub const MULTISAMPLE_RESOLVE: Int = 0x3099;
1613	pub const MULTISAMPLE_RESOLVE_DEFAULT: Int = 0x309A;
1614	pub const MULTISAMPLE_RESOLVE_BOX: Int = 0x309B;
1615	pub const OPENGL_API: Enum = 0x30A2;
1616	pub const OPENGL_BIT: Int = 0x0008;
1617	pub const SWAP_BEHAVIOR_PRESERVED_BIT: Int = 0x0400;
1618
1619	impl<T: api::EGL1_4> Instance<T> {
1620		/// Return the current EGL rendering context.
1621		pub fn get_current_context(&self) -> Option<Context> {
1622			unsafe {
1623				let context = self.api.eglGetCurrentContext();
1624
1625				if context != NO_CONTEXT {
1626					Some(Context(context))
1627				} else {
1628					None
1629				}
1630			}
1631		}
1632	}
1633}
1634
1635#[cfg(feature = "1_4")]
1636pub use egl1_4::*;
1637
1638// ------------------------------------------------------------------------------------------------
1639// EGL 1.5
1640// ------------------------------------------------------------------------------------------------
1641
1642#[cfg(feature = "1_5")]
1643mod egl1_5 {
1644	use super::*;
1645
1646	pub type Time = u64;
1647	pub type EGLSync = *mut c_void;
1648	pub type EGLImage = *mut c_void;
1649
1650	#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
1651	pub struct Sync(EGLSync);
1652
1653	impl Sync {
1654		/// Creates a new sync form its EGL pointer.
1655		///
1656		/// # Safety
1657		///
1658		/// `ptr` must be a valid `EGLSync` pointer.
1659		#[inline]
1660		pub unsafe fn from_ptr(ptr: EGLSync) -> Sync {
1661			Sync(ptr)
1662		}
1663
1664		#[inline]
1665		pub fn as_ptr(&self) -> EGLSync {
1666			self.0
1667		}
1668	}
1669	unsafe impl std::marker::Send for Sync {}
1670	unsafe impl std::marker::Sync for Sync {}
1671
1672	#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
1673	pub struct Image(EGLImage);
1674
1675	impl Image {
1676		/// Creates a new image form its EGL pointer.
1677		///
1678		/// # Safety
1679		///
1680		/// `ptr` must be a valid `EGLImage` pointer.
1681		#[inline]
1682		pub unsafe fn from_ptr(ptr: EGLImage) -> Image {
1683			Image(ptr)
1684		}
1685
1686		#[inline]
1687		pub fn as_ptr(&self) -> EGLImage {
1688			self.0
1689		}
1690	}
1691
1692	unsafe impl std::marker::Send for Image {}
1693	unsafe impl std::marker::Sync for Image {}
1694
1695	pub const CONTEXT_MAJOR_VERSION: Int = 0x3098;
1696	pub const CONTEXT_MINOR_VERSION: Int = 0x30FB;
1697	pub const CONTEXT_OPENGL_PROFILE_MASK: Int = 0x30FD;
1698	pub const CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY: Int = 0x31BD;
1699	pub const NO_RESET_NOTIFICATION: Int = 0x31BE;
1700	pub const LOSE_CONTEXT_ON_RESET: Int = 0x31BF;
1701	pub const CONTEXT_OPENGL_CORE_PROFILE_BIT: Int = 0x00000001;
1702	pub const CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT: Int = 0x00000002;
1703	pub const CONTEXT_OPENGL_DEBUG: Int = 0x31B0;
1704	pub const CONTEXT_OPENGL_FORWARD_COMPATIBLE: Int = 0x31B1;
1705	pub const CONTEXT_OPENGL_ROBUST_ACCESS: Int = 0x31B2;
1706	pub const OPENGL_ES3_BIT: Int = 0x00000040;
1707	pub const CL_EVENT_HANDLE: Int = 0x309C;
1708	pub const SYNC_CL_EVENT: Int = 0x30FE;
1709	pub const SYNC_CL_EVENT_COMPLETE: Int = 0x30FF;
1710	pub const SYNC_PRIOR_COMMANDS_COMPLETE: Int = 0x30F0;
1711	pub const SYNC_TYPE: Int = 0x30F7;
1712	pub const SYNC_STATUS: Int = 0x30F1;
1713	pub const SYNC_CONDITION: Int = 0x30F8;
1714	pub const SIGNALED: Int = 0x30F2;
1715	pub const UNSIGNALED: Int = 0x30F3;
1716	pub const SYNC_FLUSH_COMMANDS_BIT: Int = 0x0001;
1717	pub const FOREVER: u64 = 0xFFFFFFFFFFFFFFFFu64;
1718	pub const TIMEOUT_EXPIRED: Int = 0x30F5;
1719	pub const CONDITION_SATISFIED: Int = 0x30F6;
1720	pub const NO_SYNC: EGLSync = 0 as EGLSync;
1721	pub const SYNC_FENCE: Int = 0x30F9;
1722	pub const GL_COLORSPACE: Int = 0x309D;
1723	pub const GL_COLORSPACE_SRGB: Int = 0x3089;
1724	pub const GL_COLORSPACE_LINEAR: Int = 0x308A;
1725	pub const GL_RENDERBUFFER: Int = 0x30B9;
1726	pub const GL_TEXTURE_2D: Int = 0x30B1;
1727	pub const GL_TEXTURE_LEVEL: Int = 0x30BC;
1728	pub const GL_TEXTURE_3D: Int = 0x30B2;
1729	pub const GL_TEXTURE_ZOFFSET: Int = 0x30BD;
1730	pub const GL_TEXTURE_CUBE_MAP_POSITIVE_X: Int = 0x30B3;
1731	pub const GL_TEXTURE_CUBE_MAP_NEGATIVE_X: Int = 0x30B4;
1732	pub const GL_TEXTURE_CUBE_MAP_POSITIVE_Y: Int = 0x30B5;
1733	pub const GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: Int = 0x30B6;
1734	pub const GL_TEXTURE_CUBE_MAP_POSITIVE_Z: Int = 0x30B7;
1735	pub const GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: Int = 0x30B8;
1736	pub const IMAGE_PRESERVED: Int = 0x30D2;
1737	pub const NO_IMAGE: EGLImage = 0 as EGLImage;
1738
1739	impl<T: api::EGL1_5> Instance<T> {
1740		/// Create a new EGL sync object.
1741		///
1742		/// Note that the constant `ATTRIB_NONE` which has the type `Attrib` can be used
1743		/// instead of `NONE` to terminate the attribute list.
1744		///
1745		/// This will return a `BadParameter` error if `attrib_list` is not a valid
1746		/// attributes list (if it does not terminate with `ATTRIB_NONE`).
1747		///
1748		/// # Safety
1749		///
1750		/// When creating an OpenCL Event Sync Object, passing an invalid event
1751		/// handle in `attrib_list` may result in undefined behavior up to and including program
1752		/// termination.
1753		pub unsafe fn create_sync(
1754			&self,
1755			display: Display,
1756			ty: Enum,
1757			attrib_list: &[Attrib],
1758		) -> Result<Sync, Error> {
1759			unsafe {
1760				check_attrib_list(attrib_list)?;
1761				let sync = self
1762					.api
1763					.eglCreateSync(display.as_ptr(), ty, attrib_list.as_ptr());
1764				if sync != NO_SYNC {
1765					Ok(Sync(sync))
1766				} else {
1767					Err(self.get_error_for_sure())
1768				}
1769			}
1770		}
1771
1772		/// Destroy a sync object.
1773		///
1774		/// # Safety
1775		///
1776		/// If display does not match the display passed to eglCreateSync when
1777		/// sync was created, the behaviour is undefined.
1778		pub unsafe fn destroy_sync(&self, display: Display, sync: Sync) -> Result<(), Error> {
1779			unsafe {
1780				if self.api.eglDestroySync(display.as_ptr(), sync.as_ptr()) == TRUE {
1781					Ok(())
1782				} else {
1783					Err(self.get_error_for_sure())
1784				}
1785			}
1786		}
1787
1788		/// Wait in the client for a sync object to be signalled.
1789		///
1790		/// # Safety
1791		///
1792		/// If `display` does not match the [`Display`] passed to [`create_sync`](Self::create_sync)
1793		/// when `sync` was created, the behaviour is undefined.
1794		pub unsafe fn client_wait_sync(
1795			&self,
1796			display: Display,
1797			sync: Sync,
1798			flags: Int,
1799			timeout: Time,
1800		) -> Result<Int, Error> {
1801			unsafe {
1802				let status =
1803					self.api
1804						.eglClientWaitSync(display.as_ptr(), sync.as_ptr(), flags, timeout);
1805				if status != FALSE as Int {
1806					Ok(status)
1807				} else {
1808					Err(self.get_error_for_sure())
1809				}
1810			}
1811		}
1812
1813		/// Return an attribute of a sync object.
1814		///
1815		/// # Safety
1816		///
1817		/// If `display` does not match the [`Display`] passed to [`create_sync`](Self::create_sync)
1818		/// when `sync` was created, behavior is undefined.
1819		pub unsafe fn get_sync_attrib(
1820			&self,
1821			display: Display,
1822			sync: Sync,
1823			attribute: Int,
1824		) -> Result<Attrib, Error> {
1825			unsafe {
1826				let mut value = 0;
1827				if self.api.eglGetSyncAttrib(
1828					display.as_ptr(),
1829					sync.as_ptr(),
1830					attribute,
1831					&mut value as *mut Attrib,
1832				) == TRUE
1833				{
1834					Ok(value)
1835				} else {
1836					Err(self.get_error_for_sure())
1837				}
1838			}
1839		}
1840
1841		/// Create a new Image object.
1842		///
1843		/// Note that the constant `ATTRIB_NONE` which has the type `Attrib` can be used
1844		/// instead of `NONE` to terminate the attribute list.
1845		///
1846		/// This will return a `BadParameter` error if `attrib_list` is not a valid
1847		/// attributes list (if it does not terminate with `ATTRIB_NONE`).
1848		pub fn create_image(
1849			&self,
1850			display: Display,
1851			ctx: Context,
1852			target: Enum,
1853			buffer: ClientBuffer,
1854			attrib_list: &[Attrib],
1855		) -> Result<Image, Error> {
1856			check_attrib_list(attrib_list)?;
1857			unsafe {
1858				let image = self.api.eglCreateImage(
1859					display.as_ptr(),
1860					ctx.as_ptr(),
1861					target,
1862					buffer.as_ptr(),
1863					attrib_list.as_ptr(),
1864				);
1865				if image != NO_IMAGE {
1866					Ok(Image(image))
1867				} else {
1868					Err(self.get_error_for_sure())
1869				}
1870			}
1871		}
1872
1873		/// Destroy an Image object.
1874		pub fn destroy_image(&self, display: Display, image: Image) -> Result<(), Error> {
1875			unsafe {
1876				if self.api.eglDestroyImage(display.as_ptr(), image.as_ptr()) == TRUE {
1877					Ok(())
1878				} else {
1879					Err(self.get_error_for_sure())
1880				}
1881			}
1882		}
1883
1884		/// Return an EGL display connection.
1885		///
1886		/// Note that the constant `ATTRIB_NONE` which has the type `Attrib` can be used
1887		/// instead of `NONE` to terminate the attribute list.
1888		///
1889		/// This will return a `BadParameter` error if `attrib_list` is not a valid
1890		/// attributes list (if it does not terminate with `ATTRIB_NONE`).
1891		///
1892		/// # Safety
1893		///
1894		/// The `native_display` must be a valid pointer to the native display.
1895		/// Valid values for platform are defined by EGL extensions, as are
1896		/// requirements for native_display. For example, an extension
1897		/// specification that defines support for the X11 platform may require
1898		/// that native_display be a pointer to an X11 Display, and an extension
1899		/// specification that defines support for the Microsoft Windows
1900		/// platform may require that native_display be a pointer to a Windows
1901		/// Device Context.
1902		pub unsafe fn get_platform_display(
1903			&self,
1904			platform: Enum,
1905			native_display: NativeDisplayType,
1906			attrib_list: &[Attrib],
1907		) -> Result<Display, Error> {
1908			unsafe {
1909				check_attrib_list(attrib_list)?;
1910
1911				let display =
1912					self.api
1913						.eglGetPlatformDisplay(platform, native_display, attrib_list.as_ptr());
1914				if display != NO_DISPLAY {
1915					Ok(Display::from_ptr(display))
1916				} else {
1917					Err(self.get_error_for_sure())
1918				}
1919			}
1920		}
1921
1922		/// Create a new EGL on-screen rendering surface.
1923		///
1924		/// Note that the constant `ATTRIB_NONE` which has the type `Attrib` can be used
1925		/// instead of `NONE` to terminate the attribute list.
1926		///
1927		/// This will return a `BadParameter` error if `attrib_list` is not a valid
1928		/// attributes list (if it does not terminate with `ATTRIB_NONE`).
1929		///
1930		/// # Safety
1931		///
1932		/// The `native_window` must be a valid pointer to the native window
1933		/// and must belong to the same platform as `display`.
1934		/// EGL considers the returned EGLSurface as belonging to that same platform.
1935		/// The EGL extension that defines the platform to which display belongs
1936		/// also defines the requirements for the `native_window` parameter.
1937		pub unsafe fn create_platform_window_surface(
1938			&self,
1939			display: Display,
1940			config: Config,
1941			native_window: NativeWindowType,
1942			attrib_list: &[Attrib],
1943		) -> Result<Surface, Error> {
1944			unsafe {
1945				#[cfg(target_os = "android")]
1946				let native_window = native_window as *mut c_void;
1947				check_attrib_list(attrib_list)?;
1948
1949				let surface = self.api.eglCreatePlatformWindowSurface(
1950					display.as_ptr(),
1951					config.as_ptr(),
1952					native_window,
1953					attrib_list.as_ptr(),
1954				);
1955				if surface != NO_SURFACE {
1956					Ok(Surface::from_ptr(surface))
1957				} else {
1958					Err(self.get_error_for_sure())
1959				}
1960			}
1961		}
1962
1963		/// Create a new EGL offscreen surface.
1964		///
1965		/// Note that the constant `ATTRIB_NONE` which has the type `Attrib` can be used
1966		/// instead of `NONE` to terminate the attribute list.
1967		///
1968		/// This will return a `BadParameter` error if `attrib_list` is not a valid
1969		/// attributes list (if it does not terminate with `ATTRIB_NONE`).
1970		///
1971		/// # Safety
1972		///
1973		/// The `native_pixmap` must be a valid pointer to a native pixmap.
1974		/// and must belong to the same platform as `display`.
1975		/// EGL considers the returned EGLSurface as belonging to that same platform.
1976		/// The EGL extension that defines the platform to which display belongs
1977		/// also defines the requirements for the `native_pixmap` parameter.
1978		pub unsafe fn create_platform_pixmap_surface(
1979			&self,
1980			display: Display,
1981			config: Config,
1982			native_pixmap: NativePixmapType,
1983			attrib_list: &[Attrib],
1984		) -> Result<Surface, Error> {
1985			unsafe {
1986				check_attrib_list(attrib_list)?;
1987
1988				#[cfg(target_os = "android")]
1989				let native_pixmap = native_pixmap as *mut c_void;
1990				let surface = self.api.eglCreatePlatformPixmapSurface(
1991					display.as_ptr(),
1992					config.as_ptr(),
1993					native_pixmap,
1994					attrib_list.as_ptr(),
1995				);
1996				if surface != NO_SURFACE {
1997					Ok(Surface::from_ptr(surface))
1998				} else {
1999					Err(self.get_error_for_sure())
2000				}
2001			}
2002		}
2003
2004		/// Wait in the server for a sync object to be signalled.
2005		///
2006		/// This function is unsafe: if `display` does not match the [`Display`] passed to [`create_sync`](Self::create_sync)
2007		/// when `sync` was created, the behavior is undefined.
2008		pub fn wait_sync(&self, display: Display, sync: Sync, flags: Int) -> Result<(), Error> {
2009			unsafe {
2010				if self.api.eglWaitSync(display.as_ptr(), sync.as_ptr(), flags) == TRUE {
2011					Ok(())
2012				} else {
2013					Err(self.get_error_for_sure())
2014				}
2015			}
2016		}
2017	}
2018}
2019
2020#[cfg(feature = "1_5")]
2021pub use egl1_5::*;
2022
2023// -------------------------------------------------------------------------------------------------
2024// FFI
2025// -------------------------------------------------------------------------------------------------
2026
2027macro_rules! api {
2028	($($id:ident : $version:literal { $(fn $name:ident ($($arg:ident : $atype:ty ),* ) -> $rtype:ty ;)* }),*) => {
2029		#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
2030		pub enum Version {
2031			$(
2032				#[cfg(feature=$version)]
2033				$id,
2034			)*
2035		}
2036
2037		impl std::fmt::Display for Version {
2038			fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
2039				match self {
2040					$(
2041						#[cfg(feature=$version)]
2042						Version::$id => write!(f, $version),
2043					)*
2044				}
2045			}
2046		}
2047
2048		pub mod api {
2049			use super::*;
2050
2051			api!(@api_traits () () $($id : $version { $(fn $name ($($arg : $atype ),* ) -> $rtype ;)* })*);
2052		}
2053
2054		#[cfg(feature="static")]
2055		mod ffi {
2056			use libc::{c_char, c_void};
2057
2058			use super::{
2059				Attrib, Boolean, EGLClientBuffer, EGLConfig, EGLContext, EGLDisplay, EGLImage, EGLSurface,
2060				EGLSync, Enum, Int, NativeDisplayType, NativePixmapType, NativeWindowType, Time,
2061			};
2062
2063			$(
2064				unsafe extern "system" {
2065					$(
2066						#[cfg(feature=$version)]
2067						pub fn $name ($($arg : $atype ),* ) -> $rtype ;
2068					)*
2069				}
2070			)*
2071		}
2072
2073		#[cfg(feature="static")]
2074		/// Static EGL API interface.
2075		///
2076		/// This type is only available when the `static` feature is enabled,
2077		/// by statically linking the EGL library at compile time.
2078		#[derive(Copy, Clone, Debug)]
2079		pub struct Static;
2080
2081		#[cfg(feature="static")]
2082		impl Api for Static {
2083			#[inline(always)]
2084			fn version(&self) -> Version {
2085				LATEST
2086			}
2087		}
2088
2089		#[cfg(feature="static")]
2090		pub static API: Instance<Static> = Instance::new(Static);
2091
2092		#[cfg(feature="dynamic")]
2093		extern crate libloading;
2094
2095		api!(@dynamic_struct $($id : $version { $(fn $name ($($arg : $atype ),* ) -> $rtype ;)* })*);
2096		api!(@api_types () $($id : $version { $(fn $name ($($arg : $atype ),* ) -> $rtype ;)* })*);
2097	};
2098	(@dynamic_struct $($id:ident : $version:literal { $(fn $name:ident ($($arg:ident : $atype:ty ),* ) -> $rtype:ty ;)* })*) => {
2099		#[cfg(feature="dynamic")]
2100		#[derive(Debug)]
2101		pub enum LoadError<L> {
2102			/// Something wrong happened while loading the library.
2103			Library(L),
2104
2105			/// The provided version does not meet the requirements.
2106			InvalidVersion {
2107				provided: Version,
2108				required: Version
2109			}
2110		}
2111
2112		#[cfg(feature="dynamic")]
2113		impl<L: std::error::Error + 'static> std::error::Error for LoadError<L> {
2114			fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
2115				match self {
2116					LoadError::Library(l) => Some(l),
2117					_ => None
2118				}
2119			}
2120		}
2121
2122		#[cfg(feature="dynamic")]
2123		impl<L: std::fmt::Display> std::fmt::Display for LoadError<L> {
2124			fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
2125				match self {
2126					LoadError::Library(l) => write!(f, "Load error: {}", l),
2127					LoadError::InvalidVersion { provided, required } => write!(f, "Invalid EGL API version (required {}, provided {})", required, provided)
2128				}
2129			}
2130		}
2131
2132		#[cfg(feature="dynamic")]
2133		struct RawDynamic<L> {
2134			lib: L,
2135			version: Version,
2136			$(
2137				$(
2138					#[cfg(feature=$version)]
2139					$name : std::mem::MaybeUninit<unsafe extern "system" fn($($atype ),*) -> $rtype>,
2140				)*
2141			)*
2142		}
2143
2144		#[cfg(feature="dynamic")]
2145		impl<L> RawDynamic<L> {
2146			#[inline(always)]
2147			/// Returns the underlying EGL library.
2148			pub fn library(&self) -> &L {
2149				&self.lib
2150			}
2151
2152			#[inline(always)]
2153			/// Returns the EGL version.
2154			pub fn version(&self) -> Version {
2155				self.version
2156			}
2157
2158			#[inline(always)]
2159			/// Sets the EGL version.
2160			pub unsafe fn set_version(&mut self, version: Version) {
2161				self.version = version
2162			}
2163
2164			/// Wraps the given library but does not load the symbols.
2165			pub unsafe fn unloaded(lib: L, version: Version) -> Self {
2166				RawDynamic {
2167					lib,
2168					version,
2169					$(
2170						$(
2171							#[cfg(feature=$version)]
2172							$name : std::mem::MaybeUninit::uninit(),
2173						)*
2174					)*
2175				}
2176			}
2177		}
2178
2179		#[cfg(feature="dynamic")]
2180		/// Dynamic EGL API interface.
2181		///
2182		/// The first type parameter is the type of the underlying library handle.
2183		/// The second `Dynamic` type parameter gives the EGL API version provided by the library.
2184		///
2185		/// This type is only available when the `dynamic` feature is enabled.
2186		/// In most cases, you may prefer to directly use the `DynamicInstance` type.
2187		pub struct Dynamic<L, A> {
2188			raw: RawDynamic<L>,
2189			_api_version: std::marker::PhantomData<A>
2190		}
2191
2192		#[cfg(feature="dynamic")]
2193		impl<L, A> Dynamic<L, A> {
2194			#[inline(always)]
2195			/// Return the underlying EGL library.
2196			pub fn library(&self) -> &L {
2197				self.raw.library()
2198			}
2199
2200			/// Returns the provided EGL version.
2201			pub fn version(&self) -> Version {
2202				self.raw.version()
2203			}
2204
2205			/// Wraps the given library but does not load the symbols.
2206			pub(crate) unsafe fn unloaded(lib: L, version: Version) -> Self {
2207				unsafe {
2208					Dynamic {
2209						raw: RawDynamic::unloaded(lib, version),
2210						_api_version: std::marker::PhantomData
2211					}
2212				}
2213			}
2214		}
2215
2216		#[cfg(feature="dynamic")]
2217		impl<L, A> Api for Dynamic<L, A> {
2218			/// Returns the provided EGL version.
2219			#[inline(always)]
2220			fn version(&self) -> Version {
2221				self.version()
2222			}
2223		}
2224
2225		#[cfg(feature="dynamic")]
2226		#[cfg(feature="1_0")]
2227		impl<L: std::borrow::Borrow<libloading::Library>> Dynamic<L, EGL1_0> {
2228			#[inline]
2229			/// Load the EGL API symbols from the given library.
2230			///
2231			/// This will load the most recent API provided by the library,
2232			/// which is at least EGL 1.0.
2233			/// You can check what version has actually been loaded using [`Dynamic::version`],
2234			/// and/or convert to a more recent version using [`try_into`](TryInto::try_into).
2235			///
2236			/// ## Safety
2237			/// This is fundamentally unsafe since there are no guaranties the input library complies to the EGL API.
2238			pub unsafe fn load_from(lib: L) -> Result<Dynamic<L, EGL1_0>, libloading::Error> {
2239				unsafe {
2240					let mut result = Dynamic::unloaded(lib, Version::EGL1_0);
2241
2242					$(
2243						match $id::load_from(&mut result.raw) {
2244							Ok(()) => result.raw.set_version(Version::$id),
2245							Err(libloading::Error::DlSymUnknown) => {
2246								if Version::$id == Version::EGL1_0 {
2247									return Err(libloading::Error::DlSymUnknown) // we require at least EGL 1.0.
2248								} else {
2249									return Ok(result)
2250								}
2251							},
2252							Err(libloading::Error::DlSym { source }) => {
2253								if Version::$id == Version::EGL1_0 {
2254									return Err(libloading::Error::DlSym { source }) // we require at least EGL 1.0.
2255								} else {
2256									return Ok(result)
2257								}
2258							},
2259							Err(e) => return Err(e)
2260						}
2261					)*
2262
2263					Ok(result)
2264				}
2265			}
2266		}
2267
2268		#[cfg(feature="dynamic")]
2269		#[cfg(feature="1_0")]
2270		impl<L: std::borrow::Borrow<libloading::Library>> Instance<Dynamic<L, EGL1_0>> {
2271			#[inline(always)]
2272			/// Create an EGL instance using the symbols provided by the given library.
2273			///
2274			/// The most recent version of EGL provided by the given library is loaded.
2275			/// You can check what version has actually been loaded using [`Instance::version`],
2276			/// and/or convert to a more recent version using [`try_into`](TryInto::try_into).
2277			///
2278			/// ## Safety
2279			/// This is fundamentally unsafe since there are no guaranties the input library complies to the EGL API.
2280			pub unsafe fn load_from(lib: L) -> Result<Instance<Dynamic<L, EGL1_0>>, libloading::Error> {
2281				unsafe {
2282					Ok(Instance::new(Dynamic::<L, EGL1_0>::load_from(lib)?))
2283				}
2284			}
2285		}
2286
2287		#[cfg(feature="dynamic")]
2288		impl<L, V> Instance<Dynamic<L, V>> {
2289			/// Cast the API.
2290			#[inline(always)]
2291			pub fn downcast<W>(&self) -> &Instance<Dynamic<L, W>> where Instance<Dynamic<L, V>>: Downcast<Instance<Dynamic<L, W>>> {
2292				Downcast::downcast(self)
2293			}
2294
2295			/// Cast the API.
2296			#[inline(always)]
2297			pub fn upcast<W>(&self) -> Option<&Instance<Dynamic<L, W>>> where Instance<Dynamic<L, V>>: Upcast<Instance<Dynamic<L, W>>> {
2298				Upcast::upcast(self)
2299			}
2300		}
2301
2302		#[cfg(feature="dynamic")]
2303		unsafe impl<L: std::borrow::Borrow<libloading::Library> + Send, A: Send> Send for Dynamic<L, A> {}
2304
2305		#[cfg(feature="dynamic")]
2306		unsafe impl<L: std::borrow::Borrow<libloading::Library> + std::marker::Sync, A: std::marker::Sync> std::marker::Sync for Dynamic<L, A> {}
2307
2308		#[cfg(feature="dynamic")]
2309		impl<L: std::borrow::Borrow<libloading::Library> + fmt::Debug, A> fmt::Debug for Dynamic<L, A> {
2310			fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2311				write!(f, "Dynamic({:?})", self.library())
2312			}
2313		}
2314	};
2315	(@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 ;)* })*) => {
2316		api!(@api_trait ( ) ( ) $id : $version { $(fn $name ($($arg : $atype ),* ) -> $rtype ;)* });
2317		api!(@api_traits ( $id : $version ) ( : $id ) $($t_id : $t_version { $(fn $t_name ($($t_arg : $t_atype ),* ) -> $t_rtype ;)* })*);
2318	};
2319	(@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 ;)* })*) => {
2320		api!(@api_trait ( $($pred : $p_version)* ) ( $($deps)* ) $id : $version { $(fn $name ($($arg : $atype ),* ) -> $rtype ;)* });
2321		api!(@api_traits ( $($pred : $version)* $id : $version ) ( $($deps)* + $id ) $($t_id : $t_version { $(fn $t_name ($($t_arg : $t_atype ),* ) -> $t_rtype ;)* })*);
2322	};
2323	(@api_traits ( $($pred:ident : $p_version:literal)* ) ( $($deps:tt)* )) => {
2324		// nothing
2325	};
2326	(@api_trait ( $($pred:ident : $p_version:literal)* ) ( $($deps:tt)* ) $id:ident : $version:literal { $(fn $name:ident ($($arg:ident : $atype:ty ),* ) -> $rtype:ty ;)* }) => {
2327		/// # Safety
2328        ///
2329        /// EGL API interface.
2330		///
2331		/// An implementation of this trait can be used to create an [`Instance`].
2332		///
2333		/// This crate provides two implementation of this trait:
2334		///  - [`Static`] which is available with the `static` feature enabled,
2335		///    defined by statically linking to the EGL library at compile time.
2336		///  - [`Dynamic`] which is available with the `dynamic` feature enabled,
2337		///    defined by dynamically linking to the EGL library at runtime.
2338		///    In this case, you may prefer to directly use the `DynamicInstance` type.
2339		#[cfg(feature=$version)]
2340		pub unsafe trait $id $($deps)* {
2341			$(
2342                /// # Safety
2343				unsafe fn $name (&self, $($arg : $atype ),* ) -> $rtype ;
2344			)*
2345		}
2346	};
2347	(@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 ;)* })*) => {
2348		#[cfg(feature="dynamic")]
2349		$(
2350			#[cfg(not(feature=$t_version))]
2351		)*
2352		#[cfg(feature=$version)]
2353		/// Latest available EGL version.
2354		pub type Latest = $id;
2355
2356		$(
2357			#[cfg(not(feature=$t_version))]
2358		)*
2359		#[cfg(feature=$version)]
2360		/// Latest available EGL version.
2361		pub const LATEST: Version = Version::$id;
2362
2363		api!(@api_type ( ) $id : $version { $(fn $name ($($arg : $atype ),* ) -> $rtype ;)* });
2364		api!(@api_types ( $id : $version { $(fn $name ($($arg : $atype ),* ) -> $rtype ;)* } ) $($t_id : $t_version { $(fn $t_name ($($t_arg : $t_atype ),* ) -> $t_rtype ;)* })*);
2365	};
2366	(@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 ;)* })*) => {
2367		#[cfg(feature="dynamic")]
2368		$(
2369			#[cfg(not(feature=$t_version))]
2370		)*
2371		#[cfg(feature=$version)]
2372		/// Latest available EGL version.
2373		pub type Latest = $id;
2374
2375		$(
2376			#[cfg(not(feature=$t_version))]
2377		)*
2378		#[cfg(feature=$version)]
2379		/// Latest available EGL version.
2380		pub const LATEST: Version = Version::$id;
2381
2382		api!(@api_type ( $($pred : $p_version { $(fn $p_name ($($p_arg : $p_atype ),* ) -> $p_rtype ;)* })* ) $id : $version { $(fn $name ($($arg : $atype ),* ) -> $rtype ;)* });
2383		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 ;)* })*);
2384	};
2385	(@api_types ( $($pred:ident : $p_version:literal { $(fn $p_name:ident ($($p_arg:ident : $p_atype:ty ),* ) -> $p_rtype:ty ;)* })+ ) ) => {
2386		#[cfg(feature="dynamic")]
2387		#[cfg(feature="1_0")]
2388		/// Alias for dynamically linked instances with the latest handled version of EGL.
2389		pub type DynamicInstance<V = Latest> = Instance<Dynamic<libloading::Library, V>>;
2390
2391		#[cfg(feature="dynamic")]
2392		#[cfg(feature="1_0")]
2393		impl DynamicInstance<EGL1_0> {
2394			#[inline(always)]
2395			/// Create an EGL instance by finding and loading a dynamic library with the given filename.
2396			///
2397			/// See [`Library::new`](libloading::Library::new)
2398			/// for more details on how the `filename` argument is used.
2399			///
2400			/// On Linux plateforms, the library is loaded with the `RTLD_NODELETE` flag.
2401			/// See [#14](https://github.com/timothee-haudebourg/khronos-egl/issues/14) for more details.
2402			///
2403			/// ## Safety
2404			/// This is fundamentally unsafe since there are no guaranties the input library complies to the EGL API.
2405			pub unsafe fn load_from_filename<P: libloading::AsFilename>(filename: P) -> Result<DynamicInstance<EGL1_0>, libloading::Error> { unsafe {
2406				#[cfg(target_os = "linux")]
2407				let lib: libloading::Library = {
2408					// On Linux, load library with `RTLD_NOW | RTLD_NODELETE` to fix a SIGSEGV
2409					// See https://github.com/timothee-haudebourg/khronos-egl/issues/14 for more details.
2410					libloading::os::unix::Library::open(Some(filename), 0x2 | 0x1000)?.into()
2411				};
2412				#[cfg(not(target_os = "linux"))]
2413				let lib = libloading::Library::new(filename)?;
2414				Self::load_from(lib)
2415			}}
2416
2417			#[inline(always)]
2418			/// Create an EGL instance by finding and loading the `libEGL.so.1` or `libEGL.so` library.
2419			///
2420			/// This is equivalent to `DynamicInstance::load_from_filename("libEGL.so.1")`.
2421			///
2422			/// ## Safety
2423			/// This is fundamentally unsafe since there are no guaranties the found library complies to the EGL API.
2424			pub unsafe fn load() -> Result<DynamicInstance<EGL1_0>, libloading::Error> { unsafe {
2425				Self::load_from_filename("libEGL.so.1").or(Self::load_from_filename("libEGL.so"))
2426			}}
2427		}
2428	};
2429	(@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 ;)* }) => {
2430		#[cfg(feature="static")]
2431		#[cfg(feature=$version)]
2432		unsafe impl api::$id for Static {
2433			$(
2434				#[inline(always)]
2435				unsafe fn $name(&self, $($arg : $atype),*) -> $rtype {
2436					unsafe { ffi::$name($($arg),*) }
2437				}
2438			)*
2439		}
2440
2441		#[cfg(feature="dynamic")]
2442		#[cfg(feature=$version)]
2443		/// EGL version type.
2444		///
2445		/// Used by [`Dynamic`] to statically know the EGL API version provided by the library.
2446		pub struct $id;
2447
2448		#[cfg(feature="dynamic")]
2449		#[cfg(feature=$version)]
2450		impl $id {
2451			#[allow(unused_variables)]
2452			unsafe fn load_from<L: std::borrow::Borrow<libloading::Library>>(raw: &mut RawDynamic<L>) -> Result<(), libloading::Error> {
2453				let lib = raw.lib.borrow();
2454
2455				$(
2456					let name = stringify!($name).as_bytes();
2457					let symbol = unsafe { lib.get::<unsafe extern "system" fn($($atype ),*) -> $rtype>(name)? };
2458					#[cfg(unix)]
2459					let ptr = (&unsafe { symbol.into_raw() }.into_raw()) as *const *mut _ as *const unsafe extern "system" fn($($atype ),*) -> $rtype;
2460					#[cfg(windows)]
2461					let ptr = (&unsafe {symbol.into_raw() }.into_raw()) as *const _ as *const unsafe extern "system" fn($($atype ),*) -> $rtype;
2462					assert!(!ptr.is_null());
2463					raw.$name = unsafe { std::mem::MaybeUninit::new(*ptr) };
2464				)*
2465
2466				Ok(())
2467			}
2468		}
2469
2470		$(
2471			#[cfg(feature="dynamic")]
2472			#[cfg(feature=$version)]
2473			unsafe impl<L: std::borrow::Borrow<libloading::Library>> api::$pred for Dynamic<L, $id> {
2474				$(
2475					#[inline(always)]
2476					unsafe fn $p_name(&self, $($p_arg : $p_atype),*) -> $p_rtype { unsafe {
2477						(self.raw.$p_name.assume_init())($($p_arg),*)
2478					}}
2479				)*
2480			}
2481		)*
2482
2483		#[cfg(feature="dynamic")]
2484		#[cfg(feature=$version)]
2485		unsafe impl<L: std::borrow::Borrow<libloading::Library>> api::$id for Dynamic<L, $id> {
2486			$(
2487				#[inline(always)]
2488				unsafe fn $name(&self, $($arg : $atype),*) -> $rtype {
2489					unsafe {
2490						(self.raw.$name.assume_init())($($arg),*)
2491					}
2492				}
2493			)*
2494		}
2495
2496		$(
2497			#[cfg(feature="dynamic")]
2498			#[cfg(feature=$version)]
2499			impl<L: std::borrow::Borrow<libloading::Library>> TryFrom<Dynamic<L, $pred>> for Dynamic<L, $id> {
2500				type Error = Dynamic<L, $pred>;
2501
2502				fn try_from(other: Dynamic<L, $pred>) -> Result<Self, Dynamic<L, $pred>> {
2503					if other.version() >= Version::$id {
2504						Ok(Dynamic {
2505							raw: other.raw,
2506							_api_version: std::marker::PhantomData
2507						})
2508					} else {
2509						Err(other)
2510					}
2511				}
2512			}
2513
2514			#[cfg(feature="dynamic")]
2515			#[cfg(feature=$version)]
2516			impl<L: std::borrow::Borrow<libloading::Library>> From<Dynamic<L, $id>> for Dynamic<L, $pred> {
2517				fn from(other: Dynamic<L, $id>) -> Self {
2518					Dynamic {
2519						raw: other.raw,
2520						_api_version: std::marker::PhantomData
2521					}
2522				}
2523			}
2524
2525			#[cfg(feature="dynamic")]
2526			#[cfg(feature=$version)]
2527			impl<L: std::borrow::Borrow<libloading::Library>> AsRef<Dynamic<L, $pred>> for Dynamic<L, $id> {
2528				fn as_ref(&self) -> &Dynamic<L, $pred> {
2529					unsafe { std::mem::transmute(self) } // this is safe because both types have the same repr.
2530				}
2531			}
2532
2533			#[cfg(feature="dynamic")]
2534			#[cfg(feature=$version)]
2535			impl<L: std::borrow::Borrow<libloading::Library>> Downcast<Dynamic<L, $pred>> for Dynamic<L, $id> {
2536				fn downcast(&self) -> &Dynamic<L, $pred> {
2537					unsafe { std::mem::transmute(self) } // this is safe because both types have the same repr.
2538				}
2539			}
2540
2541			#[cfg(feature="dynamic")]
2542			#[cfg(feature=$version)]
2543			impl<L: std::borrow::Borrow<libloading::Library>> Downcast<Instance<Dynamic<L, $pred>>> for Instance<Dynamic<L, $id>> {
2544				fn downcast(&self) -> &Instance<Dynamic<L, $pred>> {
2545					unsafe { std::mem::transmute(self) } // this is safe because both types have the same repr.
2546				}
2547			}
2548
2549			#[cfg(feature="dynamic")]
2550			#[cfg(feature=$version)]
2551			impl<L: std::borrow::Borrow<libloading::Library>> Upcast<Dynamic<L, $id>> for Dynamic<L, $pred> {
2552				fn upcast(&self) -> Option<&Dynamic<L, $id>> {
2553					if self.version() >= Version::$id {
2554						Some(unsafe { std::mem::transmute::<&Dynamic<L, $pred>, &Dynamic<L, $id>>(self) }) // this is safe because both types have the same repr.
2555					} else {
2556						None
2557					}
2558				}
2559			}
2560
2561			#[cfg(feature="dynamic")]
2562			#[cfg(feature=$version)]
2563			impl<L: std::borrow::Borrow<libloading::Library>> Upcast<Instance<Dynamic<L, $id>>> for Instance<Dynamic<L, $pred>> {
2564				fn upcast(&self) -> Option<&Instance<Dynamic<L, $id>>> {
2565					if self.version() >= Version::$id {
2566						Some(unsafe { std::mem::transmute::<&Instance<Dynamic<L, $pred>>, &Instance<Dynamic<L, $id>>>(self) }) // this is safe because both types have the same repr.
2567					} else {
2568						None
2569					}
2570				}
2571			}
2572		)*
2573
2574		#[cfg(feature="dynamic")]
2575		#[cfg(feature=$version)]
2576		impl<L: std::borrow::Borrow<libloading::Library>> Dynamic<L, $id> {
2577			#[inline]
2578			/// Load the EGL API symbols from the given library.
2579			///
2580			/// The second `Dynamic` type parameter gives the EGL API version expected to be provided by the library.
2581			///
2582			/// ## Safety
2583			/// This is fundamentally unsafe since there are no guaranties the input library complies to the EGL API.
2584			pub unsafe fn load_required(lib: L) -> Result<Dynamic<L, $id>, LoadError<libloading::Error>> { unsafe {
2585				match Dynamic::<L, EGL1_0>::load_from(lib) {
2586					Ok(dynamic) => {
2587						let provided = dynamic.version();
2588						match dynamic.try_into() {
2589							Ok(t) => Ok(t),
2590							Err(_) => Err(LoadError::InvalidVersion {
2591								provided,
2592								required: Version::$id
2593							})
2594						}
2595					},
2596					Err(e) => Err(LoadError::Library(e))
2597				}
2598			}}
2599		}
2600
2601		#[cfg(feature="dynamic")]
2602		#[cfg(feature=$version)]
2603		impl<L: std::borrow::Borrow<libloading::Library>> Instance<Dynamic<L, $id>> {
2604			#[inline(always)]
2605			/// Create an EGL instance using the symbols provided by the given library.
2606			/// This function fails if the EGL library does not provide the minimum required version given by the type parameter.
2607			///
2608			/// ## Safety
2609			/// This is fundamentally unsafe since there are no guaranties the input library complies to the EGL API.
2610			pub unsafe fn load_required_from(lib: L) -> Result<Instance<Dynamic<L, $id>>, LoadError<libloading::Error>> { unsafe {
2611				Ok(Instance::new(Dynamic::<L, $id>::load_required(lib)?))
2612			}}
2613		}
2614
2615		#[cfg(feature="dynamic")]
2616		#[cfg(feature=$version)]
2617		impl DynamicInstance<$id> {
2618			#[inline(always)]
2619			/// Create an EGL instance by finding and loading a dynamic library with the given filename.
2620			/// This function fails if the EGL library does not provide the minimum required version given by the type parameter.
2621			///
2622			/// See [`Library::new`](libloading::Library::new)
2623			/// for more details on how the `filename` argument is used.
2624			///
2625			/// On Linux plateforms, the library is loaded with the `RTLD_NODELETE` flag.
2626			/// See [#14](https://github.com/timothee-haudebourg/khronos-egl/issues/14) for more details.
2627			///
2628			/// ## Safety
2629			/// This is fundamentally unsafe since there are no guaranties the input library complies to the EGL API.
2630			pub unsafe fn load_required_from_filename<P: libloading::AsFilename>(filename: P) -> Result<DynamicInstance<$id>, LoadError<libloading::Error>> {
2631				unsafe {
2632				#[cfg(target_os = "linux")]
2633					let lib: libloading::Library = {
2634						// On Linux, load library with `RTLD_NOW | RTLD_NODELETE` to fix a SIGSEGV
2635						// See https://github.com/timothee-haudebourg/khronos-egl/issues/14 for more details.
2636						libloading::os::unix::Library::open(Some(filename), 0x2 | 0x1000).map_err(LoadError::Library)?.into()
2637					};
2638					#[cfg(not(target_os = "linux"))]
2639					let lib = libloading::Library::new(filename).map_err(LoadError::Library)?;
2640					Self::load_required_from(lib)
2641				}
2642			}
2643
2644			#[inline(always)]
2645			/// Create an EGL instance by finding and loading the `libEGL.so.1` or `libEGL.so` library.
2646			/// This function fails if the EGL library does not provide the minimum required version given by the type parameter.
2647			///
2648			/// This is equivalent to `DynamicInstance::load_required_from_filename("libEGL.so.1")`.
2649			///
2650			/// ## Safety
2651			/// This is fundamentally unsafe since there are no guaranties the found library complies to the EGL API.
2652			pub unsafe fn load_required() -> Result<DynamicInstance<$id>, LoadError<libloading::Error>> {
2653				unsafe {
2654					Self::load_required_from_filename("libEGL.so.1").or(Self::load_required_from_filename("libEGL.so"))
2655				}
2656			}
2657		}
2658	}
2659}
2660
2661api! {
2662	EGL1_0 : "1_0" {
2663		fn eglChooseConfig(
2664			display: EGLDisplay,
2665			attrib_list: *const Int,
2666			configs: *mut EGLConfig,
2667			config_size: Int,
2668			num_config: *mut Int
2669		) -> Boolean;
2670		fn eglCopyBuffers(
2671			display: EGLDisplay,
2672			surface: EGLSurface,
2673			target: NativePixmapType
2674		) -> Boolean;
2675		fn eglCreateContext(
2676			display: EGLDisplay,
2677			config: EGLConfig,
2678			share_context: EGLContext,
2679			attrib_list: *const Int
2680		) -> EGLContext;
2681		fn eglCreatePbufferSurface(
2682			display: EGLDisplay,
2683			config: EGLConfig,
2684			attrib_list: *const Int
2685		) -> EGLSurface;
2686		fn eglCreatePixmapSurface(
2687			display: EGLDisplay,
2688			config: EGLConfig,
2689			pixmap: NativePixmapType,
2690			attrib_list: *const Int
2691		) -> EGLSurface;
2692		fn eglCreateWindowSurface(
2693			display: EGLDisplay,
2694			config: EGLConfig,
2695			win: NativeWindowType,
2696			attrib_list: *const Int
2697		) -> EGLSurface;
2698		fn eglDestroyContext(display: EGLDisplay, ctx: EGLContext) -> Boolean;
2699		fn eglDestroySurface(display: EGLDisplay, surface: EGLSurface) -> Boolean;
2700		fn eglGetConfigAttrib(
2701			display: EGLDisplay,
2702			config: EGLConfig,
2703			attribute: Int,
2704			value: *mut Int
2705		) -> Boolean;
2706		fn eglGetConfigs(
2707			display: EGLDisplay,
2708			configs: *mut EGLConfig,
2709			config_size: Int,
2710			num_config: *mut Int
2711		) -> Boolean;
2712		fn eglGetCurrentDisplay() -> EGLDisplay;
2713		fn eglGetCurrentSurface(readdraw: Int) -> EGLSurface;
2714		fn eglGetDisplay(display_id: NativeDisplayType) -> EGLDisplay;
2715		fn eglGetError() -> Int;
2716		fn eglGetProcAddress(procname: *const c_char) -> *const ();
2717		fn eglInitialize(display: EGLDisplay, major: *mut Int, minor: *mut Int) -> Boolean;
2718		fn eglMakeCurrent(
2719			display: EGLDisplay,
2720			draw: EGLSurface,
2721			read: EGLSurface,
2722			ctx: EGLContext
2723		) -> Boolean;
2724		fn eglQueryContext(
2725			display: EGLDisplay,
2726			ctx: EGLContext,
2727			attribute: Int,
2728			value: *mut Int
2729		) -> Boolean;
2730		fn eglQueryString(display: EGLDisplay, name: Int) -> *const c_char;
2731		fn eglQuerySurface(
2732			display: EGLDisplay,
2733			surface: EGLSurface,
2734			attribute: Int,
2735			value: *mut Int
2736		) -> Boolean;
2737		fn eglSwapBuffers(display: EGLDisplay, surface: EGLSurface) -> Boolean;
2738		fn eglTerminate(display: EGLDisplay) -> Boolean;
2739		fn eglWaitGL() -> Boolean;
2740		fn eglWaitNative(engine: Int) -> Boolean;
2741	},
2742
2743	EGL1_1 : "1_1" {
2744		fn eglBindTexImage(display: EGLDisplay, surface: EGLSurface, buffer: Int) -> Boolean;
2745		fn eglReleaseTexImage(display: EGLDisplay, surface: EGLSurface, buffer: Int) -> Boolean;
2746		fn eglSurfaceAttrib(
2747			display: EGLDisplay,
2748			surface: EGLSurface,
2749			attribute: Int,
2750			value: Int
2751		) -> Boolean;
2752		fn eglSwapInterval(display: EGLDisplay, interval: Int) -> Boolean;
2753	},
2754
2755	EGL1_2 : "1_2" {
2756		fn eglBindAPI(api: Enum) -> Boolean;
2757		fn eglQueryAPI() -> Enum;
2758		fn eglCreatePbufferFromClientBuffer(
2759			display: EGLDisplay,
2760			buftype: Enum,
2761			buffer: EGLClientBuffer,
2762			config: EGLConfig,
2763			attrib_list: *const Int
2764		) -> EGLSurface;
2765		fn eglReleaseThread() -> Boolean;
2766		fn eglWaitClient() -> Boolean;
2767	},
2768
2769	EGL1_3 : "1_3" {
2770		// nothing.
2771	},
2772
2773	EGL1_4 : "1_4" {
2774		fn eglGetCurrentContext() -> EGLContext;
2775	},
2776
2777	EGL1_5 : "1_5" {
2778		fn eglCreateSync(display: EGLDisplay, type_: Enum, attrib_list: *const Attrib) -> EGLSync;
2779		fn eglDestroySync(display: EGLDisplay, sync: EGLSync) -> Boolean;
2780		fn eglClientWaitSync(display: EGLDisplay, sync: EGLSync, flags: Int, timeout: Time) -> Int;
2781		fn eglGetSyncAttrib(
2782			display: EGLDisplay,
2783			sync: EGLSync,
2784			attribute: Int,
2785			value: *mut Attrib
2786		) -> Boolean;
2787		fn eglCreateImage(
2788			display: EGLDisplay,
2789			ctx: EGLContext,
2790			target: Enum,
2791			buffer: EGLClientBuffer,
2792			attrib_list: *const Attrib
2793		) -> EGLImage;
2794		fn eglDestroyImage(display: EGLDisplay, image: EGLImage) -> Boolean;
2795		fn eglGetPlatformDisplay(
2796			platform: Enum,
2797			native_display: *mut c_void,
2798			attrib_list: *const Attrib
2799		) -> EGLDisplay;
2800		fn eglCreatePlatformWindowSurface(
2801			display: EGLDisplay,
2802			config: EGLConfig,
2803			native_window: *mut c_void,
2804			attrib_list: *const Attrib
2805		) -> EGLSurface;
2806		fn eglCreatePlatformPixmapSurface(
2807			display: EGLDisplay,
2808			config: EGLConfig,
2809			native_pixmap: *mut c_void,
2810			attrib_list: *const Attrib
2811		) -> EGLSurface;
2812		fn eglWaitSync(display: EGLDisplay, sync: EGLSync, flags: Int) -> Boolean;
2813	}
2814}