summaryrefslogtreecommitdiffstats
path: root/third_party/rust/gl_generator/generators
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/gl_generator/generators')
-rw-r--r--third_party/rust/gl_generator/generators/debug_struct_gen.rs289
-rw-r--r--third_party/rust/gl_generator/generators/global_gen.rs309
-rw-r--r--third_party/rust/gl_generator/generators/mod.rs119
-rw-r--r--third_party/rust/gl_generator/generators/static_gen.rs115
-rw-r--r--third_party/rust/gl_generator/generators/static_struct_gen.rs165
-rw-r--r--third_party/rust/gl_generator/generators/struct_gen.rs256
-rw-r--r--third_party/rust/gl_generator/generators/templates/types/egl.rs70
-rw-r--r--third_party/rust/gl_generator/generators/templates/types/gl.rs108
-rw-r--r--third_party/rust/gl_generator/generators/templates/types/glx.rs128
-rw-r--r--third_party/rust/gl_generator/generators/templates/types/wgl.rs139
10 files changed, 1698 insertions, 0 deletions
diff --git a/third_party/rust/gl_generator/generators/debug_struct_gen.rs b/third_party/rust/gl_generator/generators/debug_struct_gen.rs
new file mode 100644
index 0000000000..98fbcef158
--- /dev/null
+++ b/third_party/rust/gl_generator/generators/debug_struct_gen.rs
@@ -0,0 +1,289 @@
+// Copyright 2015 Brendan Zabarauskas and the gl-rs developers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use registry::Registry;
+use std::io;
+
+#[allow(missing_copy_implementations)]
+pub struct DebugStructGenerator;
+
+impl super::Generator for DebugStructGenerator {
+ fn write<W>(&self, registry: &Registry, dest: &mut W) -> io::Result<()>
+ where
+ W: io::Write,
+ {
+ try!(write_header(dest));
+ try!(write_type_aliases(registry, dest));
+ try!(write_enums(registry, dest));
+ try!(write_fnptr_struct_def(dest));
+ try!(write_panicking_fns(registry, dest));
+ try!(write_struct(registry, dest));
+ try!(write_impl(registry, dest));
+ Ok(())
+ }
+}
+
+/// Creates a `__gl_imports` module which contains all the external symbols that we need for the
+/// bindings.
+fn write_header<W>(dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ writeln!(
+ dest,
+ r#"
+ mod __gl_imports {{
+ pub use std::mem;
+ pub use std::marker::Send;
+ pub use std::os::raw;
+ }}
+ "#
+ )
+}
+
+/// Creates a `types` module which contains all the type aliases.
+///
+/// See also `generators::gen_types`.
+fn write_type_aliases<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ try!(writeln!(
+ dest,
+ r#"
+ pub mod types {{
+ #![allow(non_camel_case_types, non_snake_case, dead_code, missing_copy_implementations)]
+ "#
+ ));
+
+ try!(super::gen_types(registry.api, dest));
+
+ writeln!(dest, "}}")
+}
+
+/// Creates all the `<enum>` elements at the root of the bindings.
+fn write_enums<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ for enm in &registry.enums {
+ try!(super::gen_enum_item(enm, "types::", dest));
+ }
+
+ Ok(())
+}
+
+/// Creates a `FnPtr` structure which contains the store for a single binding.
+fn write_fnptr_struct_def<W>(dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ writeln!(
+ dest,
+ "
+ #[allow(dead_code, missing_copy_implementations)]
+ #[derive(Clone)]
+ pub struct FnPtr {{
+ /// The function pointer that will be used when calling the function.
+ f: *const __gl_imports::raw::c_void,
+ /// True if the pointer points to a real function, false if points to a `panic!` fn.
+ is_loaded: bool,
+ }}
+
+ impl FnPtr {{
+ /// Creates a `FnPtr` from a load attempt.
+ fn new(ptr: *const __gl_imports::raw::c_void) -> FnPtr {{
+ if ptr.is_null() {{
+ FnPtr {{
+ f: missing_fn_panic as *const __gl_imports::raw::c_void,
+ is_loaded: false
+ }}
+ }} else {{
+ FnPtr {{ f: ptr, is_loaded: true }}
+ }}
+ }}
+
+ /// Returns `true` if the function has been successfully loaded.
+ ///
+ /// If it returns `false`, calling the corresponding function will fail.
+ #[inline]
+ #[allow(dead_code)]
+ pub fn is_loaded(&self) -> bool {{
+ self.is_loaded
+ }}
+ }}
+ "
+ )
+}
+
+/// Creates a `panicking` module which contains one function per GL command.
+///
+/// These functions are the mocks that are called if the real function could not be loaded.
+fn write_panicking_fns<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ writeln!(
+ dest,
+ "#[inline(never)]
+ fn missing_fn_panic() -> ! {{
+ panic!(\"{api} function was not loaded\")
+ }}",
+ api = registry.api
+ )
+}
+
+/// Creates a structure which stores all the `FnPtr` of the bindings.
+///
+/// The name of the struct corresponds to the namespace.
+fn write_struct<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ try!(writeln!(
+ dest,
+ "
+ #[allow(non_camel_case_types, non_snake_case, dead_code)]
+ #[derive(Clone)]
+ pub struct {api} {{",
+ api = super::gen_struct_name(registry.api)
+ ));
+
+ for cmd in &registry.cmds {
+ if let Some(v) = registry.aliases.get(&cmd.proto.ident) {
+ try!(writeln!(dest, "/// Fallbacks: {}", v.join(", ")));
+ }
+ try!(writeln!(dest, "pub {name}: FnPtr,", name = cmd.proto.ident));
+ }
+ try!(writeln!(dest, "_priv: ()"));
+
+ writeln!(dest, "}}")
+}
+
+/// Creates the `impl` of the structure created by `write_struct`.
+fn write_impl<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ try!(writeln!(dest,
+ "impl {api} {{
+ /// Load each OpenGL symbol using a custom load function. This allows for the
+ /// use of functions like `glfwGetProcAddress` or `SDL_GL_GetProcAddress`.
+ ///
+ /// ~~~ignore
+ /// let gl = Gl::load_with(|s| glfw.get_proc_address(s));
+ /// ~~~
+ #[allow(dead_code, unused_variables)]
+ pub fn load_with<F>(mut loadfn: F) -> {api} where F: FnMut(&'static str) -> *const __gl_imports::raw::c_void {{
+ #[inline(never)]
+ fn do_metaloadfn(loadfn: &mut dyn FnMut(&'static str) -> *const __gl_imports::raw::c_void,
+ symbol: &'static str,
+ symbols: &[&'static str])
+ -> *const __gl_imports::raw::c_void {{
+ let mut ptr = loadfn(symbol);
+ if ptr.is_null() {{
+ for &sym in symbols {{
+ ptr = loadfn(sym);
+ if !ptr.is_null() {{ break; }}
+ }}
+ }}
+ ptr
+ }}
+ let mut metaloadfn = |symbol: &'static str, symbols: &[&'static str]| {{
+ do_metaloadfn(&mut loadfn, symbol, symbols)
+ }};
+ {api} {{",
+ api = super::gen_struct_name(registry.api)));
+
+ for cmd in &registry.cmds {
+ try!(writeln!(
+ dest,
+ "{name}: FnPtr::new(metaloadfn(\"{symbol}\", &[{fallbacks}])),",
+ name = cmd.proto.ident,
+ symbol = super::gen_symbol_name(registry.api, &cmd.proto.ident),
+ fallbacks = match registry.aliases.get(&cmd.proto.ident) {
+ Some(fbs) => fbs
+ .iter()
+ .map(|name| format!("\"{}\"", super::gen_symbol_name(registry.api, &name)))
+ .collect::<Vec<_>>()
+ .join(", "),
+ None => format!(""),
+ },
+ ))
+ }
+ try!(writeln!(dest, "_priv: ()"));
+
+ try!(writeln!(
+ dest,
+ "}}
+ }}"
+ ));
+
+ for cmd in &registry.cmds {
+ let idents = super::gen_parameters(cmd, true, false);
+ let typed_params = super::gen_parameters(cmd, false, true);
+ let println = format!(
+ "println!(\"[OpenGL] {}({})\" {});",
+ cmd.proto.ident,
+ (0..idents.len())
+ .map(|_| "{:?}".to_string())
+ .collect::<Vec<_>>()
+ .join(", "),
+ idents
+ .iter()
+ .zip(typed_params.iter())
+ .map(|(name, ty)| if ty.contains("GLDEBUGPROC") {
+ format!(", \"<callback>\"")
+ } else {
+ format!(", {}", name)
+ }).collect::<Vec<_>>()
+ .concat()
+ );
+
+ try!(writeln!(dest,
+ "#[allow(non_snake_case, unused_variables, dead_code)]
+ #[inline] pub unsafe fn {name}(&self, {params}) -> {return_suffix} {{ \
+ {println}
+ let r = __gl_imports::mem::transmute::<_, extern \"system\" fn({typed_params}) -> {return_suffix}>\
+ (self.{name}.f)({idents});
+ {print_err}
+ r
+ }}",
+ name = cmd.proto.ident,
+ params = super::gen_parameters(cmd, true, true).join(", "),
+ typed_params = typed_params.join(", "),
+ return_suffix = cmd.proto.ty,
+ idents = idents.join(", "),
+ println = println,
+ print_err = if cmd.proto.ident != "GetError" &&
+ registry
+ .cmds
+ .iter()
+ .find(|cmd| cmd.proto.ident == "GetError")
+ .is_some() {
+ format!(r#"match __gl_imports::mem::transmute::<_, extern "system" fn() -> u32>
+ (self.GetError.f)() {{ 0 => (), r => println!("[OpenGL] ^ GL error triggered: {{}}", r) }}"#)
+ } else {
+ format!("")
+ }))
+ }
+
+ writeln!(
+ dest,
+ "}}
+
+ unsafe impl __gl_imports::Send for {api} {{}}",
+ api = super::gen_struct_name(registry.api)
+ )
+}
diff --git a/third_party/rust/gl_generator/generators/global_gen.rs b/third_party/rust/gl_generator/generators/global_gen.rs
new file mode 100644
index 0000000000..82c4710979
--- /dev/null
+++ b/third_party/rust/gl_generator/generators/global_gen.rs
@@ -0,0 +1,309 @@
+// Copyright 2015 Brendan Zabarauskas and the gl-rs developers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use registry::Registry;
+use std::io;
+
+#[allow(missing_copy_implementations)]
+pub struct GlobalGenerator;
+
+impl super::Generator for GlobalGenerator {
+ fn write<W>(&self, registry: &Registry, dest: &mut W) -> io::Result<()>
+ where
+ W: io::Write,
+ {
+ try!(write_header(dest));
+ try!(write_metaloadfn(dest));
+ try!(write_type_aliases(registry, dest));
+ try!(write_enums(registry, dest));
+ try!(write_fns(registry, dest));
+ try!(write_fnptr_struct_def(dest));
+ try!(write_ptrs(registry, dest));
+ try!(write_fn_mods(registry, dest));
+ try!(write_panicking_fns(registry, dest));
+ try!(write_load_fn(registry, dest));
+ Ok(())
+ }
+}
+
+/// Creates a `__gl_imports` module which contains all the external symbols that we need for the
+/// bindings.
+fn write_header<W>(dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ writeln!(
+ dest,
+ r#"
+ mod __gl_imports {{
+ pub use std::mem;
+ pub use std::os::raw;
+ }}
+ "#
+ )
+}
+
+/// Creates the metaloadfn function for fallbacks
+fn write_metaloadfn<W>(dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ writeln!(
+ dest,
+ r#"
+ #[inline(never)]
+ fn metaloadfn(loadfn: &mut dyn FnMut(&'static str) -> *const __gl_imports::raw::c_void,
+ symbol: &'static str,
+ fallbacks: &[&'static str]) -> *const __gl_imports::raw::c_void {{
+ let mut ptr = loadfn(symbol);
+ if ptr.is_null() {{
+ for &sym in fallbacks {{
+ ptr = loadfn(sym);
+ if !ptr.is_null() {{ break; }}
+ }}
+ }}
+ ptr
+ }}
+ "#
+ )
+}
+
+/// Creates a `types` module which contains all the type aliases.
+///
+/// See also `generators::gen_types`.
+fn write_type_aliases<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ try!(writeln!(
+ dest,
+ r#"
+ pub mod types {{
+ #![allow(non_camel_case_types, non_snake_case, dead_code, missing_copy_implementations)]
+ "#
+ ));
+
+ try!(super::gen_types(registry.api, dest));
+
+ writeln!(
+ dest,
+ "
+ }}
+ "
+ )
+}
+
+/// Creates all the `<enum>` elements at the root of the bindings.
+fn write_enums<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ for enm in &registry.enums {
+ try!(super::gen_enum_item(enm, "types::", dest));
+ }
+
+ Ok(())
+}
+
+/// Creates the functions corresponding to the GL commands.
+///
+/// The function calls the corresponding function pointer stored in the `storage` module created
+/// by `write_ptrs`.
+fn write_fns<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ for cmd in &registry.cmds {
+ if let Some(v) = registry.aliases.get(&cmd.proto.ident) {
+ try!(writeln!(dest, "/// Fallbacks: {}", v.join(", ")));
+ }
+
+ try!(writeln!(dest,
+ "#[allow(non_snake_case, unused_variables, dead_code)] #[inline]
+ pub unsafe fn {name}({params}) -> {return_suffix} {{ \
+ __gl_imports::mem::transmute::<_, extern \"system\" fn({typed_params}) -> {return_suffix}>\
+ (storage::{name}.f)({idents}) \
+ }}",
+ name = cmd.proto.ident,
+ params = super::gen_parameters(cmd, true, true).join(", "),
+ typed_params = super::gen_parameters(cmd, false, true).join(", "),
+ return_suffix = cmd.proto.ty,
+ idents = super::gen_parameters(cmd, true, false).join(", "),
+ ));
+ }
+
+ Ok(())
+}
+
+/// Creates a `FnPtr` structure which contains the store for a single binding.
+fn write_fnptr_struct_def<W>(dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ writeln!(dest,
+ "
+ #[allow(missing_copy_implementations)]
+ pub struct FnPtr {{
+ /// The function pointer that will be used when calling the function.
+ f: *const __gl_imports::raw::c_void,
+ /// True if the pointer points to a real function, false if points to a `panic!` fn.
+ is_loaded: bool,
+ }}
+
+ impl FnPtr {{
+ /// Creates a `FnPtr` from a load attempt.
+ pub fn new(ptr: *const __gl_imports::raw::c_void) -> FnPtr {{
+ if ptr.is_null() {{
+ FnPtr {{ f: missing_fn_panic as *const __gl_imports::raw::c_void, is_loaded: false }}
+ }} else {{
+ FnPtr {{ f: ptr, is_loaded: true }}
+ }}
+ }}
+ }}
+ ")
+}
+
+/// Creates a `storage` module which contains a static `FnPtr` per GL command in the registry.
+fn write_ptrs<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ try!(writeln!(
+ dest,
+ "mod storage {{
+ #![allow(non_snake_case)]
+ #![allow(non_upper_case_globals)]
+ use super::__gl_imports::raw;
+ use super::FnPtr;"
+ ));
+
+ for c in &registry.cmds {
+ try!(writeln!(
+ dest,
+ "pub static mut {name}: FnPtr = FnPtr {{
+ f: super::missing_fn_panic as *const raw::c_void,
+ is_loaded: false
+ }};",
+ name = c.proto.ident
+ ));
+ }
+
+ writeln!(dest, "}}")
+}
+
+/// Creates one module for each GL command.
+///
+/// Each module contains `is_loaded` and `load_with` which interact with the `storage` module
+/// created by `write_ptrs`.
+fn write_fn_mods<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ for c in &registry.cmds {
+ let fallbacks = match registry.aliases.get(&c.proto.ident) {
+ Some(v) => {
+ let names = v
+ .iter()
+ .map(|name| format!("\"{}\"", super::gen_symbol_name(registry.api, &name[..])))
+ .collect::<Vec<_>>();
+ format!("&[{}]", names.join(", "))
+ },
+ None => "&[]".to_string(),
+ };
+ let fnname = &c.proto.ident[..];
+ let symbol = super::gen_symbol_name(registry.api, &c.proto.ident[..]);
+ let symbol = &symbol[..];
+
+ try!(writeln!(dest, r##"
+ #[allow(non_snake_case)]
+ pub mod {fnname} {{
+ use super::{{storage, metaloadfn}};
+ use super::__gl_imports::raw;
+ use super::FnPtr;
+
+ #[inline]
+ #[allow(dead_code)]
+ pub fn is_loaded() -> bool {{
+ unsafe {{ storage::{fnname}.is_loaded }}
+ }}
+
+ #[allow(dead_code)]
+ pub fn load_with<F>(mut loadfn: F) where F: FnMut(&'static str) -> *const raw::c_void {{
+ unsafe {{
+ storage::{fnname} = FnPtr::new(metaloadfn(&mut loadfn, "{symbol}", {fallbacks}))
+ }}
+ }}
+ }}
+ "##, fnname = fnname, fallbacks = fallbacks, symbol = symbol));
+ }
+
+ Ok(())
+}
+
+/// Creates a `missing_fn_panic` function.
+///
+/// This function is the mock that is called if the real function could not be called.
+fn write_panicking_fns<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ writeln!(
+ dest,
+ "#[inline(never)]
+ fn missing_fn_panic() -> ! {{
+ panic!(\"{api} function was not loaded\")
+ }}
+ ",
+ api = registry.api
+ )
+}
+
+/// Creates the `load_with` function.
+///
+/// The function calls `load_with` in each module created by `write_fn_mods`.
+fn write_load_fn<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ try!(writeln!(dest,
+ "
+ /// Load each OpenGL symbol using a custom load function. This allows for the
+ /// use of functions like `glfwGetProcAddress` or `SDL_GL_GetProcAddress`.
+ /// ~~~ignore
+ /// gl::load_with(|s| glfw.get_proc_address(s));
+ /// ~~~
+ #[allow(dead_code)]
+ pub fn load_with<F>(mut loadfn: F) where F: FnMut(&'static str) -> *const __gl_imports::raw::c_void {{
+ #[inline(never)]
+ fn inner(loadfn: &mut dyn FnMut(&'static str) -> *const __gl_imports::raw::c_void) {{
+ "));
+
+ for c in &registry.cmds {
+ try!(writeln!(
+ dest,
+ "{cmd_name}::load_with(&mut *loadfn);",
+ cmd_name = &c.proto.ident[..]
+ ));
+ }
+
+ writeln!(
+ dest,
+ "
+ }}
+
+ inner(&mut loadfn)
+ }}
+ "
+ )
+}
diff --git a/third_party/rust/gl_generator/generators/mod.rs b/third_party/rust/gl_generator/generators/mod.rs
new file mode 100644
index 0000000000..659d2ecaf4
--- /dev/null
+++ b/third_party/rust/gl_generator/generators/mod.rs
@@ -0,0 +1,119 @@
+// Copyright 2015 Brendan Zabarauskas and the gl-rs developers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use registry::{Cmd, Enum, Registry};
+use std::io;
+use Api;
+
+pub mod debug_struct_gen;
+pub mod global_gen;
+pub mod static_gen;
+pub mod static_struct_gen;
+pub mod struct_gen;
+
+/// Trait for a bindings generator.
+///
+/// See https://github.com/brendanzab/gl-rs/tree/master/gl_generator#generator-types
+pub trait Generator {
+ /// Builds the GL bindings.
+ fn write<W>(&self, registry: &Registry, dest: &mut W) -> io::Result<()>
+ where
+ W: io::Write;
+}
+
+pub fn gen_struct_name(api: Api) -> &'static str {
+ match api {
+ Api::Gl => "Gl",
+ Api::Glx => "Glx",
+ Api::Wgl => "Wgl",
+ Api::Egl => "Egl",
+ Api::GlCore => "GlCore",
+ Api::Gles1 => "Gles1",
+ Api::Gles2 => "Gles2",
+ Api::Glsc2 => "Glsc2",
+ }
+}
+
+/// This function generates a `const name: type = value;` item.
+pub fn gen_enum_item<W>(enm: &Enum, types_prefix: &str, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ writeln!(dest,
+ "#[allow(dead_code, non_upper_case_globals)] pub const {ident}: {types_prefix}{ty} = {value}{cast_suffix};",
+ ident = enm.ident,
+ types_prefix = if enm.ty == "&'static str" { "" } else { types_prefix },
+ ty = enm.ty,
+ value = enm.value,
+ cast_suffix = match enm.cast {
+ true => format!(" as {}{}", types_prefix, enm.ty),
+ false => String::new(),
+ },
+ )
+}
+
+/// Generates all the type aliases for a namespace.
+///
+/// Aliases are either `pub type = ...` or `#[repr(C)] pub struct ... { ... }` and contain all the
+/// things that we can't obtain from the XML files.
+pub fn gen_types<W>(api: Api, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ if let Api::Egl = api {
+ try!(writeln!(dest, "{}", include_str!("templates/types/egl.rs")));
+ return Ok(());
+ }
+
+ try!(writeln!(dest, "{}", include_str!("templates/types/gl.rs")));
+
+ match api {
+ Api::Glx => try!(writeln!(dest, "{}", include_str!("templates/types/glx.rs"))),
+ Api::Wgl => try!(writeln!(dest, "{}", include_str!("templates/types/wgl.rs"))),
+ _ => {},
+ }
+
+ Ok(())
+}
+
+/// Generates the list of Rust `Arg`s that a `Cmd` requires.
+pub fn gen_parameters(cmd: &Cmd, with_idents: bool, with_types: bool) -> Vec<String> {
+ cmd.params
+ .iter()
+ .map(|binding| {
+ // returning
+ if with_idents && with_types {
+ format!("{}: {}", binding.ident, binding.ty)
+ } else if with_types {
+ format!("{}", binding.ty)
+ } else if with_idents {
+ format!("{}", binding.ident)
+ } else {
+ panic!()
+ }
+ })
+ .collect()
+}
+
+/// Generates the native symbol name of a `Cmd`.
+///
+/// Example results: `"glClear"`, `"wglCreateContext"`, etc.
+pub fn gen_symbol_name(api: Api, cmd: &str) -> String {
+ match api {
+ Api::Gl | Api::GlCore | Api::Gles1 | Api::Gles2 | Api::Glsc2 => format!("gl{}", cmd),
+ Api::Glx => format!("glX{}", cmd),
+ Api::Wgl => format!("wgl{}", cmd),
+ Api::Egl => format!("egl{}", cmd),
+ }
+}
diff --git a/third_party/rust/gl_generator/generators/static_gen.rs b/third_party/rust/gl_generator/generators/static_gen.rs
new file mode 100644
index 0000000000..8d15de0103
--- /dev/null
+++ b/third_party/rust/gl_generator/generators/static_gen.rs
@@ -0,0 +1,115 @@
+// Copyright 2015 Brendan Zabarauskas and the gl-rs developers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use registry::Registry;
+use std::io;
+
+#[allow(missing_copy_implementations)]
+pub struct StaticGenerator;
+
+impl super::Generator for StaticGenerator {
+ fn write<W>(&self, registry: &Registry, dest: &mut W) -> io::Result<()>
+ where
+ W: io::Write,
+ {
+ try!(write_header(dest));
+ try!(write_type_aliases(registry, dest));
+ try!(write_enums(registry, dest));
+ try!(write_fns(registry, dest));
+ Ok(())
+ }
+}
+
+/// Creates a `__gl_imports` module which contains all the external symbols that we need for the
+/// bindings.
+fn write_header<W>(dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ writeln!(
+ dest,
+ r#"
+ mod __gl_imports {{
+ pub use std::mem;
+ pub use std::os::raw;
+ }}
+ "#
+ )
+}
+
+/// Creates a `types` module which contains all the type aliases.
+///
+/// See also `generators::gen_types`.
+fn write_type_aliases<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ try!(writeln!(
+ dest,
+ r#"
+ pub mod types {{
+ #![allow(non_camel_case_types, non_snake_case, dead_code, missing_copy_implementations)]
+ "#
+ ));
+
+ try!(super::gen_types(registry.api, dest));
+
+ writeln!(
+ dest,
+ "
+ }}
+ "
+ )
+}
+
+/// Creates all the `<enum>` elements at the root of the bindings.
+fn write_enums<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ for enm in &registry.enums {
+ try!(super::gen_enum_item(enm, "types::", dest));
+ }
+
+ Ok(())
+}
+
+/// io::Writes all functions corresponding to the GL bindings.
+///
+/// These are foreign functions, they don't have any content.
+fn write_fns<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ try!(writeln!(
+ dest,
+ "
+ #[allow(non_snake_case, unused_variables, dead_code)]
+ extern \"system\" {{"
+ ));
+
+ for cmd in &registry.cmds {
+ try!(writeln!(
+ dest,
+ "#[link_name=\"{symbol}\"]
+ pub fn {name}({params}) -> {return_suffix};",
+ symbol = super::gen_symbol_name(registry.api, &cmd.proto.ident),
+ name = cmd.proto.ident,
+ params = super::gen_parameters(cmd, true, true).join(", "),
+ return_suffix = cmd.proto.ty,
+ ));
+ }
+
+ writeln!(dest, "}}")
+}
diff --git a/third_party/rust/gl_generator/generators/static_struct_gen.rs b/third_party/rust/gl_generator/generators/static_struct_gen.rs
new file mode 100644
index 0000000000..c03a3e09dd
--- /dev/null
+++ b/third_party/rust/gl_generator/generators/static_struct_gen.rs
@@ -0,0 +1,165 @@
+// Copyright 2015 Brendan Zabarauskas and the gl-rs developers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use registry::Registry;
+use std::io;
+
+#[allow(missing_copy_implementations)]
+pub struct StaticStructGenerator;
+
+impl super::Generator for StaticStructGenerator {
+ fn write<W>(&self, registry: &Registry, dest: &mut W) -> io::Result<()>
+ where
+ W: io::Write,
+ {
+ try!(write_header(dest));
+ try!(write_type_aliases(registry, dest));
+ try!(write_enums(registry, dest));
+ try!(write_struct(registry, dest));
+ try!(write_impl(registry, dest));
+ try!(write_fns(registry, dest));
+ Ok(())
+ }
+}
+
+/// Creates a `__gl_imports` module which contains all the external symbols that we need for the
+/// bindings.
+fn write_header<W>(dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ writeln!(
+ dest,
+ r#"
+ mod __gl_imports {{
+ pub use std::mem;
+ pub use std::os::raw;
+ }}
+ "#
+ )
+}
+
+/// Creates a `types` module which contains all the type aliases.
+///
+/// See also `generators::gen_types`.
+fn write_type_aliases<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ try!(writeln!(
+ dest,
+ r#"
+ pub mod types {{
+ #![allow(non_camel_case_types, non_snake_case, dead_code, missing_copy_implementations)]
+ "#
+ ));
+
+ try!(super::gen_types(registry.api, dest));
+
+ writeln!(dest, "}}")
+}
+
+/// Creates all the `<enum>` elements at the root of the bindings.
+fn write_enums<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ for enm in &registry.enums {
+ try!(super::gen_enum_item(enm, "types::", dest));
+ }
+
+ Ok(())
+}
+
+/// Creates a stub structure.
+///
+/// The name of the struct corresponds to the namespace.
+fn write_struct<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ writeln!(
+ dest,
+ "
+ #[allow(non_camel_case_types, non_snake_case, dead_code)]
+ #[derive(Copy, Clone)]
+ pub struct {api};",
+ api = super::gen_struct_name(registry.api),
+ )
+}
+
+/// Creates the `impl` of the structure created by `write_struct`.
+fn write_impl<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ try!(writeln!(dest,
+ "impl {api} {{
+ /// Stub function.
+ #[allow(dead_code)]
+ pub fn load_with<F>(mut _loadfn: F) -> {api} where F: FnMut(&'static str) -> *const __gl_imports::raw::c_void {{
+ {api}
+ }}",
+ api = super::gen_struct_name(registry.api),
+ ));
+
+ for cmd in &registry.cmds {
+ try!(writeln!(
+ dest,
+ "#[allow(non_snake_case)]
+ // #[allow(unused_variables)]
+ #[allow(dead_code)]
+ #[inline]
+ pub unsafe fn {name}(&self, {typed_params}) -> {return_suffix} {{
+ {name}({idents})
+ }}",
+ name = cmd.proto.ident,
+ typed_params = super::gen_parameters(cmd, true, true).join(", "),
+ return_suffix = cmd.proto.ty,
+ idents = super::gen_parameters(cmd, true, false).join(", "),
+ ));
+ }
+
+ writeln!(dest, "}}")
+}
+
+/// io::Writes all functions corresponding to the GL bindings.
+///
+/// These are foreign functions, they don't have any content.
+fn write_fns<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ try!(writeln!(
+ dest,
+ "
+ #[allow(non_snake_case)]
+ #[allow(unused_variables)]
+ #[allow(dead_code)]
+ extern \"system\" {{"
+ ));
+
+ for cmd in &registry.cmds {
+ try!(writeln!(
+ dest,
+ "#[link_name=\"{symbol}\"] fn {name}({params}) -> {return_suffix};",
+ symbol = super::gen_symbol_name(registry.api, &cmd.proto.ident),
+ name = cmd.proto.ident,
+ params = super::gen_parameters(cmd, true, true).join(", "),
+ return_suffix = cmd.proto.ty,
+ ));
+ }
+
+ writeln!(dest, "}}")
+}
diff --git a/third_party/rust/gl_generator/generators/struct_gen.rs b/third_party/rust/gl_generator/generators/struct_gen.rs
new file mode 100644
index 0000000000..6fcc3af00e
--- /dev/null
+++ b/third_party/rust/gl_generator/generators/struct_gen.rs
@@ -0,0 +1,256 @@
+// Copyright 2015 Brendan Zabarauskas and the gl-rs developers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use registry::Registry;
+use std::io;
+
+#[allow(missing_copy_implementations)]
+pub struct StructGenerator;
+
+impl super::Generator for StructGenerator {
+ fn write<W>(&self, registry: &Registry, dest: &mut W) -> io::Result<()>
+ where
+ W: io::Write,
+ {
+ try!(write_header(dest));
+ try!(write_type_aliases(registry, dest));
+ try!(write_enums(registry, dest));
+ try!(write_fnptr_struct_def(dest));
+ try!(write_panicking_fns(registry, dest));
+ try!(write_struct(registry, dest));
+ try!(write_impl(registry, dest));
+ Ok(())
+ }
+}
+
+/// Creates a `__gl_imports` module which contains all the external symbols that we need for the
+/// bindings.
+fn write_header<W>(dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ writeln!(
+ dest,
+ r#"
+ mod __gl_imports {{
+ pub use std::mem;
+ pub use std::marker::Send;
+ pub use std::os::raw;
+ }}
+ "#
+ )
+}
+
+/// Creates a `types` module which contains all the type aliases.
+///
+/// See also `generators::gen_types`.
+fn write_type_aliases<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ try!(writeln!(
+ dest,
+ r#"
+ pub mod types {{
+ #![allow(non_camel_case_types, non_snake_case, dead_code, missing_copy_implementations)]
+ "#
+ ));
+
+ try!(super::gen_types(registry.api, dest));
+
+ writeln!(dest, "}}")
+}
+
+/// Creates all the `<enum>` elements at the root of the bindings.
+fn write_enums<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ for enm in &registry.enums {
+ try!(super::gen_enum_item(enm, "types::", dest));
+ }
+
+ Ok(())
+}
+
+/// Creates a `FnPtr` structure which contains the store for a single binding.
+fn write_fnptr_struct_def<W>(dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ writeln!(
+ dest,
+ "
+ #[allow(dead_code, missing_copy_implementations)]
+ #[derive(Clone)]
+ pub struct FnPtr {{
+ /// The function pointer that will be used when calling the function.
+ f: *const __gl_imports::raw::c_void,
+ /// True if the pointer points to a real function, false if points to a `panic!` fn.
+ is_loaded: bool,
+ }}
+
+ impl FnPtr {{
+ /// Creates a `FnPtr` from a load attempt.
+ fn new(ptr: *const __gl_imports::raw::c_void) -> FnPtr {{
+ if ptr.is_null() {{
+ FnPtr {{
+ f: missing_fn_panic as *const __gl_imports::raw::c_void,
+ is_loaded: false
+ }}
+ }} else {{
+ FnPtr {{ f: ptr, is_loaded: true }}
+ }}
+ }}
+
+ /// Returns `true` if the function has been successfully loaded.
+ ///
+ /// If it returns `false`, calling the corresponding function will fail.
+ #[inline]
+ #[allow(dead_code)]
+ pub fn is_loaded(&self) -> bool {{
+ self.is_loaded
+ }}
+ }}
+ "
+ )
+}
+
+/// Creates a `panicking` module which contains one function per GL command.
+///
+/// These functions are the mocks that are called if the real function could not be loaded.
+fn write_panicking_fns<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ writeln!(
+ dest,
+ "#[inline(never)]
+ fn missing_fn_panic() -> ! {{
+ panic!(\"{api} function was not loaded\")
+ }}",
+ api = registry.api
+ )
+}
+
+/// Creates a structure which stores all the `FnPtr` of the bindings.
+///
+/// The name of the struct corresponds to the namespace.
+fn write_struct<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ try!(writeln!(
+ dest,
+ "
+ #[allow(non_camel_case_types, non_snake_case, dead_code)]
+ #[derive(Clone)]
+ pub struct {api} {{",
+ api = super::gen_struct_name(registry.api)
+ ));
+
+ for cmd in &registry.cmds {
+ if let Some(v) = registry.aliases.get(&cmd.proto.ident) {
+ try!(writeln!(dest, "/// Fallbacks: {}", v.join(", ")));
+ }
+ try!(writeln!(dest, "pub {name}: FnPtr,", name = cmd.proto.ident));
+ }
+ try!(writeln!(dest, "_priv: ()"));
+
+ writeln!(dest, "}}")
+}
+
+/// Creates the `impl` of the structure created by `write_struct`.
+fn write_impl<W>(registry: &Registry, dest: &mut W) -> io::Result<()>
+where
+ W: io::Write,
+{
+ try!(writeln!(dest,
+ "impl {api} {{
+ /// Load each OpenGL symbol using a custom load function. This allows for the
+ /// use of functions like `glfwGetProcAddress` or `SDL_GL_GetProcAddress`.
+ ///
+ /// ~~~ignore
+ /// let gl = Gl::load_with(|s| glfw.get_proc_address(s));
+ /// ~~~
+ #[allow(dead_code, unused_variables)]
+ pub fn load_with<F>(mut loadfn: F) -> {api} where F: FnMut(&'static str) -> *const __gl_imports::raw::c_void {{
+ #[inline(never)]
+ fn do_metaloadfn(loadfn: &mut dyn FnMut(&'static str) -> *const __gl_imports::raw::c_void,
+ symbol: &'static str,
+ symbols: &[&'static str])
+ -> *const __gl_imports::raw::c_void {{
+ let mut ptr = loadfn(symbol);
+ if ptr.is_null() {{
+ for &sym in symbols {{
+ ptr = loadfn(sym);
+ if !ptr.is_null() {{ break; }}
+ }}
+ }}
+ ptr
+ }}
+ let mut metaloadfn = |symbol: &'static str, symbols: &[&'static str]| {{
+ do_metaloadfn(&mut loadfn, symbol, symbols)
+ }};
+ {api} {{",
+ api = super::gen_struct_name(registry.api)));
+
+ for cmd in &registry.cmds {
+ try!(writeln!(
+ dest,
+ "{name}: FnPtr::new(metaloadfn(\"{symbol}\", &[{fallbacks}])),",
+ name = cmd.proto.ident,
+ symbol = super::gen_symbol_name(registry.api, &cmd.proto.ident),
+ fallbacks = match registry.aliases.get(&cmd.proto.ident) {
+ Some(fbs) => fbs
+ .iter()
+ .map(|name| format!("\"{}\"", super::gen_symbol_name(registry.api, &name)))
+ .collect::<Vec<_>>()
+ .join(", "),
+ None => format!(""),
+ },
+ ))
+ }
+
+ try!(writeln!(dest, "_priv: ()"));
+
+ try!(writeln!(
+ dest,
+ "}}
+ }}"
+ ));
+
+ for cmd in &registry.cmds {
+ try!(writeln!(dest,
+ "#[allow(non_snake_case, unused_variables, dead_code)]
+ #[inline] pub unsafe fn {name}(&self, {params}) -> {return_suffix} {{ \
+ __gl_imports::mem::transmute::<_, extern \"system\" fn({typed_params}) -> {return_suffix}>\
+ (self.{name}.f)({idents}) \
+ }}",
+ name = cmd.proto.ident,
+ params = super::gen_parameters(cmd, true, true).join(", "),
+ typed_params = super::gen_parameters(cmd, false, true).join(", "),
+ return_suffix = cmd.proto.ty,
+ idents = super::gen_parameters(cmd, true, false).join(", "),
+ ))
+ }
+
+ writeln!(
+ dest,
+ "}}
+
+ unsafe impl __gl_imports::Send for {api} {{}}",
+ api = super::gen_struct_name(registry.api)
+ )
+}
diff --git a/third_party/rust/gl_generator/generators/templates/types/egl.rs b/third_party/rust/gl_generator/generators/templates/types/egl.rs
new file mode 100644
index 0000000000..877638ab98
--- /dev/null
+++ b/third_party/rust/gl_generator/generators/templates/types/egl.rs
@@ -0,0 +1,70 @@
+// platform-specific aliases are unknown
+// IMPORTANT: these are alises to the same level of the bindings
+// the values must be defined by the user
+#[allow(dead_code)]
+pub type khronos_utime_nanoseconds_t = super::khronos_utime_nanoseconds_t;
+#[allow(dead_code)]
+pub type khronos_uint64_t = super::khronos_uint64_t;
+#[allow(dead_code)]
+pub type khronos_ssize_t = super::khronos_ssize_t;
+pub type EGLNativeDisplayType = super::EGLNativeDisplayType;
+#[allow(dead_code)]
+pub type EGLNativePixmapType = super::EGLNativePixmapType;
+#[allow(dead_code)]
+pub type EGLNativeWindowType = super::EGLNativeWindowType;
+pub type EGLint = super::EGLint;
+#[allow(dead_code)]
+pub type NativeDisplayType = super::NativeDisplayType;
+#[allow(dead_code)]
+pub type NativePixmapType = super::NativePixmapType;
+#[allow(dead_code)]
+pub type NativeWindowType = super::NativeWindowType;
+
+// EGL alises
+pub type Bool = EGLBoolean; // TODO: not sure
+pub type EGLBoolean = super::__gl_imports::raw::c_uint;
+pub type EGLenum = super::__gl_imports::raw::c_uint;
+pub type EGLAttribKHR = isize;
+pub type EGLAttrib = isize;
+pub type EGLConfig = *const super::__gl_imports::raw::c_void;
+pub type EGLContext = *const super::__gl_imports::raw::c_void;
+pub type EGLDeviceEXT = *const super::__gl_imports::raw::c_void;
+pub type EGLDisplay = *const super::__gl_imports::raw::c_void;
+pub type EGLSurface = *const super::__gl_imports::raw::c_void;
+pub type EGLClientBuffer = *const super::__gl_imports::raw::c_void;
+pub enum __eglMustCastToProperFunctionPointerType_fn {}
+pub type __eglMustCastToProperFunctionPointerType =
+ *mut __eglMustCastToProperFunctionPointerType_fn;
+pub type EGLImageKHR = *const super::__gl_imports::raw::c_void;
+pub type EGLImage = *const super::__gl_imports::raw::c_void;
+pub type EGLOutputLayerEXT = *const super::__gl_imports::raw::c_void;
+pub type EGLOutputPortEXT = *const super::__gl_imports::raw::c_void;
+pub type EGLSyncKHR = *const super::__gl_imports::raw::c_void;
+pub type EGLSync = *const super::__gl_imports::raw::c_void;
+pub type EGLTimeKHR = khronos_utime_nanoseconds_t;
+pub type EGLTime = khronos_utime_nanoseconds_t;
+pub type EGLSyncNV = *const super::__gl_imports::raw::c_void;
+pub type EGLTimeNV = khronos_utime_nanoseconds_t;
+pub type EGLuint64NV = khronos_utime_nanoseconds_t;
+pub type EGLStreamKHR = *const super::__gl_imports::raw::c_void;
+pub type EGLuint64KHR = khronos_uint64_t;
+pub type EGLNativeFileDescriptorKHR = super::__gl_imports::raw::c_int;
+pub type EGLsizeiANDROID = khronos_ssize_t;
+pub type EGLSetBlobFuncANDROID = extern "system" fn(*const super::__gl_imports::raw::c_void,
+ EGLsizeiANDROID,
+ *const super::__gl_imports::raw::c_void,
+ EGLsizeiANDROID)
+ -> ();
+pub type EGLGetBlobFuncANDROID = extern "system" fn(*const super::__gl_imports::raw::c_void,
+ EGLsizeiANDROID,
+ *mut super::__gl_imports::raw::c_void,
+ EGLsizeiANDROID)
+ -> EGLsizeiANDROID;
+
+#[repr(C)]
+pub struct EGLClientPixmapHI {
+ pData: *const super::__gl_imports::raw::c_void,
+ iWidth: EGLint,
+ iHeight: EGLint,
+ iStride: EGLint,
+}
diff --git a/third_party/rust/gl_generator/generators/templates/types/gl.rs b/third_party/rust/gl_generator/generators/templates/types/gl.rs
new file mode 100644
index 0000000000..90e4620104
--- /dev/null
+++ b/third_party/rust/gl_generator/generators/templates/types/gl.rs
@@ -0,0 +1,108 @@
+// Common types from OpenGL 1.1
+pub type GLenum = super::__gl_imports::raw::c_uint;
+pub type GLboolean = super::__gl_imports::raw::c_uchar;
+pub type GLbitfield = super::__gl_imports::raw::c_uint;
+pub type GLvoid = super::__gl_imports::raw::c_void;
+pub type GLbyte = super::__gl_imports::raw::c_char;
+pub type GLshort = super::__gl_imports::raw::c_short;
+pub type GLint = super::__gl_imports::raw::c_int;
+pub type GLclampx = super::__gl_imports::raw::c_int;
+pub type GLubyte = super::__gl_imports::raw::c_uchar;
+pub type GLushort = super::__gl_imports::raw::c_ushort;
+pub type GLuint = super::__gl_imports::raw::c_uint;
+pub type GLsizei = super::__gl_imports::raw::c_int;
+pub type GLfloat = super::__gl_imports::raw::c_float;
+pub type GLclampf = super::__gl_imports::raw::c_float;
+pub type GLdouble = super::__gl_imports::raw::c_double;
+pub type GLclampd = super::__gl_imports::raw::c_double;
+pub type GLeglImageOES = *const super::__gl_imports::raw::c_void;
+pub type GLchar = super::__gl_imports::raw::c_char;
+pub type GLcharARB = super::__gl_imports::raw::c_char;
+
+#[cfg(target_os = "macos")]
+pub type GLhandleARB = *const super::__gl_imports::raw::c_void;
+#[cfg(not(target_os = "macos"))]
+pub type GLhandleARB = super::__gl_imports::raw::c_uint;
+
+pub type GLhalfARB = super::__gl_imports::raw::c_ushort;
+pub type GLhalf = super::__gl_imports::raw::c_ushort;
+
+// Must be 32 bits
+pub type GLfixed = GLint;
+
+pub type GLintptr = isize;
+pub type GLsizeiptr = isize;
+pub type GLint64 = i64;
+pub type GLuint64 = u64;
+pub type GLintptrARB = isize;
+pub type GLsizeiptrARB = isize;
+pub type GLint64EXT = i64;
+pub type GLuint64EXT = u64;
+
+pub enum __GLsync {}
+pub type GLsync = *const __GLsync;
+
+// compatible with OpenCL cl_context
+pub enum _cl_context {}
+pub enum _cl_event {}
+
+pub type GLDEBUGPROC = Option<extern "system" fn(source: GLenum,
+ gltype: GLenum,
+ id: GLuint,
+ severity: GLenum,
+ length: GLsizei,
+ message: *const GLchar,
+ userParam: *mut super::__gl_imports::raw::c_void)>;
+pub type GLDEBUGPROCARB = Option<extern "system" fn(source: GLenum,
+ gltype: GLenum,
+ id: GLuint,
+ severity: GLenum,
+ length: GLsizei,
+ message: *const GLchar,
+ userParam: *mut super::__gl_imports::raw::c_void)>;
+pub type GLDEBUGPROCKHR = Option<extern "system" fn(source: GLenum,
+ gltype: GLenum,
+ id: GLuint,
+ severity: GLenum,
+ length: GLsizei,
+ message: *const GLchar,
+ userParam: *mut super::__gl_imports::raw::c_void)>;
+
+// GLES 1 types
+// "pub type GLclampx = i32;",
+
+// GLES 1/2 types (tagged for GLES 1)
+// "pub type GLbyte = i8;",
+// "pub type GLubyte = u8;",
+// "pub type GLfloat = GLfloat;",
+// "pub type GLclampf = GLfloat;",
+// "pub type GLfixed = i32;",
+// "pub type GLint64 = i64;",
+// "pub type GLuint64 = u64;",
+// "pub type GLintptr = intptr_t;",
+// "pub type GLsizeiptr = ssize_t;",
+
+// GLES 1/2 types (tagged for GLES 2 - attribute syntax is limited)
+// "pub type GLbyte = i8;",
+// "pub type GLubyte = u8;",
+// "pub type GLfloat = GLfloat;",
+// "pub type GLclampf = GLfloat;",
+// "pub type GLfixed = i32;",
+// "pub type GLint64 = i64;",
+// "pub type GLuint64 = u64;",
+// "pub type GLint64EXT = i64;",
+// "pub type GLuint64EXT = u64;",
+// "pub type GLintptr = intptr_t;",
+// "pub type GLsizeiptr = ssize_t;",
+
+// GLES 2 types (none currently)
+
+// Vendor extension types
+pub type GLDEBUGPROCAMD = Option<extern "system" fn(id: GLuint,
+ category: GLenum,
+ severity: GLenum,
+ length: GLsizei,
+ message: *const GLchar,
+ userParam: *mut super::__gl_imports::raw::c_void)>;
+pub type GLhalfNV = super::__gl_imports::raw::c_ushort;
+pub type GLvdpauSurfaceNV = GLintptr;
diff --git a/third_party/rust/gl_generator/generators/templates/types/glx.rs b/third_party/rust/gl_generator/generators/templates/types/glx.rs
new file mode 100644
index 0000000000..b0078da0a1
--- /dev/null
+++ b/third_party/rust/gl_generator/generators/templates/types/glx.rs
@@ -0,0 +1,128 @@
+pub type XID = super::__gl_imports::raw::c_ulong;
+pub type Bool = super::__gl_imports::raw::c_int; // Not sure if this is correct...
+pub enum Display {}
+
+pub type Font = XID;
+pub type Pixmap = XID;
+pub enum Visual {} // TODO: not sure
+pub type VisualID = super::__gl_imports::raw::c_ulong; // TODO: not sure
+pub type Window = XID;
+pub type GLXFBConfigID = XID;
+pub type GLXFBConfig = *const super::__gl_imports::raw::c_void;
+pub type GLXContextID = XID;
+pub type GLXContext = *const super::__gl_imports::raw::c_void;
+pub type GLXPixmap = XID;
+pub type GLXDrawable = XID;
+pub type GLXWindow = XID;
+pub type GLXPbuffer = XID;
+pub enum __GLXextFuncPtr_fn {}
+pub type __GLXextFuncPtr = *mut __GLXextFuncPtr_fn;
+pub type GLXVideoCaptureDeviceNV = XID;
+pub type GLXVideoDeviceNV = super::__gl_imports::raw::c_int;
+pub type GLXVideoSourceSGIX = XID;
+pub type GLXFBConfigIDSGIX = XID;
+pub type GLXFBConfigSGIX = *const super::__gl_imports::raw::c_void;
+pub type GLXPbufferSGIX = XID;
+
+#[repr(C)]
+pub struct XVisualInfo {
+ pub visual: *mut Visual,
+ pub visualid: VisualID,
+ pub screen: super::__gl_imports::raw::c_int,
+ pub depth: super::__gl_imports::raw::c_int,
+ pub class: super::__gl_imports::raw::c_int,
+ pub red_mask: super::__gl_imports::raw::c_ulong,
+ pub green_mask: super::__gl_imports::raw::c_ulong,
+ pub blue_mask: super::__gl_imports::raw::c_ulong,
+ pub colormap_size: super::__gl_imports::raw::c_int,
+ pub bits_per_rgb: super::__gl_imports::raw::c_int,
+}
+
+#[repr(C)]
+pub struct GLXPbufferClobberEvent {
+ pub event_type: super::__gl_imports::raw::c_int, // GLX_DAMAGED or GLX_SAVED
+ pub draw_type: super::__gl_imports::raw::c_int, // GLX_WINDOW or GLX_PBUFFER
+ pub serial: super::__gl_imports::raw::c_ulong, // # of last request processed by server
+ pub send_event: Bool, // true if this came for SendEvent request
+ pub display: *const Display, // display the event was read from
+ pub drawable: GLXDrawable, // XID of Drawable
+ pub buffer_mask: super::__gl_imports::raw::c_uint, // mask indicating which buffers are affected
+ pub aux_buffer: super::__gl_imports::raw::c_uint, // which aux buffer was affected
+ pub x: super::__gl_imports::raw::c_int,
+ pub y: super::__gl_imports::raw::c_int,
+ pub width: super::__gl_imports::raw::c_int,
+ pub height: super::__gl_imports::raw::c_int,
+ pub count: super::__gl_imports::raw::c_int, // if nonzero, at least this many more
+}
+
+#[repr(C)]
+pub struct GLXBufferSwapComplete {
+ pub type_: super::__gl_imports::raw::c_int,
+ pub serial: super::__gl_imports::raw::c_ulong, // # of last request processed by server
+ pub send_event: Bool, // true if this came from a SendEvent request
+ pub display: *const Display, // Display the event was read from
+ pub drawable: GLXDrawable, // drawable on which event was requested in event mask
+ pub event_type: super::__gl_imports::raw::c_int,
+ pub ust: i64,
+ pub msc: i64,
+ pub sbc: i64,
+}
+
+// typedef union __GLXEvent {
+// GLXPbufferClobberEvent glxpbufferclobber;
+// GLXBufferSwapComplete glxbufferswapcomplete;
+// long pad[24];
+// }
+
+#[repr(C)]
+pub struct GLXBufferClobberEventSGIX {
+ pub type_: super::__gl_imports::raw::c_int,
+ pub serial: super::__gl_imports::raw::c_ulong, // # of last request processed by server
+ pub send_event: Bool, // true if this came for SendEvent request
+ pub display: *const Display, // display the event was read from
+ pub drawable: GLXDrawable, // i.d. of Drawable
+ pub event_type: super::__gl_imports::raw::c_int, // GLX_DAMAGED_SGIX or GLX_SAVED_SGIX
+ pub draw_type: super::__gl_imports::raw::c_int, // GLX_WINDOW_SGIX or GLX_PBUFFER_SGIX
+ pub mask: super::__gl_imports::raw::c_uint, // mask indicating which buffers are affected
+ pub x: super::__gl_imports::raw::c_int,
+ pub y: super::__gl_imports::raw::c_int,
+ pub width: super::__gl_imports::raw::c_int,
+ pub height: super::__gl_imports::raw::c_int,
+ pub count: super::__gl_imports::raw::c_int, // if nonzero, at least this many more
+}
+
+#[repr(C)]
+pub struct GLXHyperpipeNetworkSGIX {
+ pub pipeName: [super::__gl_imports::raw::c_char; 80], // Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]
+ pub networkId: super::__gl_imports::raw::c_int,
+}
+
+#[repr(C)]
+pub struct GLXHyperpipeConfigSGIX {
+ pub pipeName: [super::__gl_imports::raw::c_char; 80], // Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]
+ pub channel: super::__gl_imports::raw::c_int,
+ pub participationType: super::__gl_imports::raw::c_uint,
+ pub timeSlice: super::__gl_imports::raw::c_int,
+}
+
+#[repr(C)]
+pub struct GLXPipeRect {
+ pub pipeName: [super::__gl_imports::raw::c_char; 80], // Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]
+ pub srcXOrigin: super::__gl_imports::raw::c_int,
+ pub srcYOrigin: super::__gl_imports::raw::c_int,
+ pub srcWidth: super::__gl_imports::raw::c_int,
+ pub srcHeight: super::__gl_imports::raw::c_int,
+ pub destXOrigin: super::__gl_imports::raw::c_int,
+ pub destYOrigin: super::__gl_imports::raw::c_int,
+ pub destWidth: super::__gl_imports::raw::c_int,
+ pub destHeight: super::__gl_imports::raw::c_int,
+}
+
+#[repr(C)]
+pub struct GLXPipeRectLimits {
+ pub pipeName: [super::__gl_imports::raw::c_char; 80], // Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]
+ pub XOrigin: super::__gl_imports::raw::c_int,
+ pub YOrigin: super::__gl_imports::raw::c_int,
+ pub maxHeight: super::__gl_imports::raw::c_int,
+ pub maxWidth: super::__gl_imports::raw::c_int,
+}
diff --git a/third_party/rust/gl_generator/generators/templates/types/wgl.rs b/third_party/rust/gl_generator/generators/templates/types/wgl.rs
new file mode 100644
index 0000000000..a376d4fa05
--- /dev/null
+++ b/third_party/rust/gl_generator/generators/templates/types/wgl.rs
@@ -0,0 +1,139 @@
+// From WinNT.h
+
+pub type CHAR = super::__gl_imports::raw::c_char;
+pub type HANDLE = PVOID;
+pub type LONG = super::__gl_imports::raw::c_long;
+pub type LPCSTR = *const super::__gl_imports::raw::c_char;
+pub type VOID = ();
+// #define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name
+pub type HPBUFFERARB = *const super::__gl_imports::raw::c_void;
+pub type HPBUFFEREXT = *const super::__gl_imports::raw::c_void;
+pub type HVIDEOOUTPUTDEVICENV = *const super::__gl_imports::raw::c_void;
+pub type HPVIDEODEV = *const super::__gl_imports::raw::c_void;
+pub type HPGPUNV = *const super::__gl_imports::raw::c_void;
+pub type HGPUNV = *const super::__gl_imports::raw::c_void;
+pub type HVIDEOINPUTDEVICENV = *const super::__gl_imports::raw::c_void;
+
+// From Windef.h
+
+pub type BOOL = super::__gl_imports::raw::c_int;
+pub type BYTE = super::__gl_imports::raw::c_uchar;
+pub type COLORREF = DWORD;
+pub type FLOAT = super::__gl_imports::raw::c_float;
+pub type HDC = HANDLE;
+pub type HENHMETAFILE = HANDLE;
+pub type HGLRC = *const super::__gl_imports::raw::c_void;
+pub type INT = super::__gl_imports::raw::c_int;
+pub type PVOID = *const super::__gl_imports::raw::c_void;
+pub type LPVOID = *const super::__gl_imports::raw::c_void;
+pub enum __PROC_fn {}
+pub type PROC = *mut __PROC_fn;
+
+#[repr(C)]
+pub struct RECT {
+ left: LONG,
+ top: LONG,
+ right: LONG,
+ bottom: LONG,
+}
+
+pub type UINT = super::__gl_imports::raw::c_uint;
+pub type USHORT = super::__gl_imports::raw::c_ushort;
+pub type WORD = super::__gl_imports::raw::c_ushort;
+
+// From BaseTsd.h
+
+pub type INT32 = i32;
+pub type INT64 = i64;
+
+// From IntSafe.h
+
+pub type DWORD = super::__gl_imports::raw::c_ulong;
+
+// From Wingdi.h
+
+#[repr(C)]
+pub struct POINTFLOAT {
+ pub x: FLOAT,
+ pub y: FLOAT,
+}
+
+#[repr(C)]
+pub struct GLYPHMETRICSFLOAT {
+ pub gmfBlackBoxX: FLOAT,
+ pub gmfBlackBoxY: FLOAT,
+ pub gmfptGlyphOrigin: POINTFLOAT,
+ pub gmfCellIncX: FLOAT,
+ pub gmfCellIncY: FLOAT,
+}
+pub type LPGLYPHMETRICSFLOAT = *const GLYPHMETRICSFLOAT;
+
+#[repr(C)]
+pub struct LAYERPLANEDESCRIPTOR {
+ pub nSize: WORD,
+ pub nVersion: WORD,
+ pub dwFlags: DWORD,
+ pub iPixelType: BYTE,
+ pub cColorBits: BYTE,
+ pub cRedBits: BYTE,
+ pub cRedShift: BYTE,
+ pub cGreenBits: BYTE,
+ pub cGreenShift: BYTE,
+ pub cBlueBits: BYTE,
+ pub cBlueShift: BYTE,
+ pub cAlphaBits: BYTE,
+ pub cAlphaShift: BYTE,
+ pub cAccumBits: BYTE,
+ pub cAccumRedBits: BYTE,
+ pub cAccumGreenBits: BYTE,
+ pub cAccumBlueBits: BYTE,
+ pub cAccumAlphaBits: BYTE,
+ pub cDepthBits: BYTE,
+ pub cStencilBits: BYTE,
+ pub cAuxBuffers: BYTE,
+ pub iLayerType: BYTE,
+ pub bReserved: BYTE,
+ pub crTransparent: COLORREF,
+}
+
+#[repr(C)]
+pub struct PIXELFORMATDESCRIPTOR {
+ pub nSize: WORD,
+ pub nVersion: WORD,
+ pub dwFlags: DWORD,
+ pub iPixelType: BYTE,
+ pub cColorBits: BYTE,
+ pub cRedBits: BYTE,
+ pub cRedShift: BYTE,
+ pub cGreenBits: BYTE,
+ pub cGreenShift: BYTE,
+ pub cBlueBits: BYTE,
+ pub cBlueShift: BYTE,
+ pub cAlphaBits: BYTE,
+ pub cAlphaShift: BYTE,
+ pub cAccumBits: BYTE,
+ pub cAccumRedBits: BYTE,
+ pub cAccumGreenBits: BYTE,
+ pub cAccumBlueBits: BYTE,
+ pub cAccumAlphaBits: BYTE,
+ pub cDepthBits: BYTE,
+ pub cStencilBits: BYTE,
+ pub cAuxBuffers: BYTE,
+ pub iLayerType: BYTE,
+ pub bReserved: BYTE,
+ pub dwLayerMask: DWORD,
+ pub dwVisibleMask: DWORD,
+ pub dwDamageMask: DWORD,
+}
+
+#[repr(C)]
+pub struct _GPU_DEVICE {
+ cb: DWORD,
+ DeviceName: [CHAR; 32],
+ DeviceString: [CHAR; 128],
+ Flags: DWORD,
+ rcVirtualScreen: RECT,
+}
+
+pub struct GPU_DEVICE(_GPU_DEVICE);
+pub struct PGPU_DEVICE(*const _GPU_DEVICE);