From 552db318195f7e56972729b4685907af520f850e Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Mon, 25 Sep 2017 16:45:55 -0400 Subject: [PATCH] Update to make it work with more recent gl_generator crate --- Cargo.toml | 21 +++-- build/epoxy_gen.rs | 136 +++++++++++++++------------ build/main.rs | 225 ++++++++++++++++++++++----------------------- 3 files changed, 196 insertions(+), 186 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9376491..e0f9e77 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,17 +1,22 @@ [package] -name = "epoxy" -version = "0.0.2" authors = ["Maxwell Koo "] +build = "build/main.rs" description = "Rust bindings for libepoxy, an OpenGL function pointer manager." -repository = "https://github.com/mjkoo/epoxy-rs" -license = "Apache-2.0" keywords = ["epoxy", "libepoxy", "opengl", "gl", "gtk"] -build = "build/main.rs" +license = "Apache-2.0" +name = "epoxy" +repository = "https://github.com/mjkoo/epoxy-rs" +version = "0.0.2" [build-dependencies] -gl_generator = "^0.1" -khronos_api = "^0" +gl_generator = "0.5.3" [dependencies] -libc = "^0.1" +gl = "0.6.2" gl_common = "^0.1" +libc = "^0.2" +shared_library = "0.1.5" + +[features] +default = ["gl_generator/unstable_generator_utils"] +debug_marker = [] diff --git a/build/epoxy_gen.rs b/build/epoxy_gen.rs index ba76523..7065168 100644 --- a/build/epoxy_gen.rs +++ b/build/epoxy_gen.rs @@ -1,7 +1,4 @@ -// Based on StaticGenerator from `gl_generator` crate, original copyright below: -// -// Copyright 2013-2014 The gl-rs developers. For a full listing of the authors, -// refer to the AUTHORS file at the top-level directory of this distribution. +// 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. @@ -15,39 +12,46 @@ // See the License for the specific language governing permissions and // limitations under the License. -extern crate gl_generator; - -use gl_generator::registry::{Registry, Ns}; use std::io; +use gl_generator::{Cmd, Generator, Registry}; +use gl_generator::generators::{gen_enum_item, gen_parameters, gen_symbol_name, gen_types}; + #[allow(missing_copy_implementations)] pub struct EpoxyGenerator; -impl gl_generator::generators::Generator for EpoxyGenerator { - fn write(&self, registry: &Registry, ns: Ns, dest: &mut W) -> io::Result<()> where W: io::Write { +impl Generator for EpoxyGenerator { + fn write(&self, registry: &Registry, dest: &mut W) -> io::Result<()> + where W: io::Write + { try!(write_header(dest)); try!(write_metaloadfn(dest)); - try!(write_type_aliases(&ns, 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, &ns, dest)); - try!(write_error_fns(&ns, dest)); + try!(write_fn_mods(registry, dest)); + try!(write_error_fns(dest)); try!(write_load_fn(registry, dest)); - try!(write_get_proc_addr(registry, &ns, dest)); + try!(write_get_proc_addr(registry, dest)); Ok(()) } } -/// Creates a `__gl_imports` module which contains all the external symbols that we need for the bindings. -fn write_header(dest: &mut W) -> io::Result<()> where W: io::Write { - writeln!(dest, r#" +/// Creates a `__gl_imports` module which contains all the external symbols that we need for the +/// bindings. +fn write_header(dest: &mut W) -> io::Result<()> + where W: io::Write +{ + writeln!(dest, + r#" mod __gl_imports {{ pub extern crate gl_common; pub extern crate libc; pub use std::mem; pub use std::ptr; + pub use std::os::raw; pub use std::process::exit; }} "#) @@ -58,8 +62,8 @@ fn write_metaloadfn(dest: &mut W) -> io::Result<()> where W: io::Write { writeln!(dest, r#" fn metaloadfn(mut loadfn: F, symbol: &str, - fallbacks: &[&str]) -> *const *const __gl_imports::libc::c_void - where F: FnMut(&str) -> *const __gl_imports::libc::c_void {{ + fallbacks: &[&str]) -> *const *const __gl_imports::raw::c_void + where F: FnMut(&str) -> *const __gl_imports::raw::c_void {{ let mut ptr = loadfn(symbol); if ptr.is_null() {{ for &sym in fallbacks.iter() {{ @@ -67,34 +71,37 @@ fn write_metaloadfn(dest: &mut W) -> io::Result<()> where W: io::Write { if !ptr.is_null() {{ break; }} }} }} - ptr as *const *const __gl_imports::libc::c_void + ptr as *const *const __gl_imports::raw::c_void }} "#) } /// Creates a `types` module which contains all the type aliases. /// -/// See also `generators::gen_type_aliases`. -fn write_type_aliases(ns: &Ns, dest: &mut W) -> io::Result<()> where W: io::Write { - try!(writeln!(dest, r#" +/// See also `generators::gen_types`. +fn write_type_aliases(registry: &Registry, dest: &mut W) -> io::Result<()> + where W: io::Write +{ + try!(writeln!(dest, + r#" pub mod types {{ - #![allow(non_camel_case_types)] - #![allow(non_snake_case)] - #![allow(dead_code)] - #![allow(missing_copy_implementations)] + #![allow(non_camel_case_types, non_snake_case, dead_code, missing_copy_implementations)] "#)); - try!(gl_generator::generators::gen_type_aliases(ns, dest)); + try!(gen_types(registry.api, dest)); - writeln!(dest, " + writeln!(dest, + " }} ") } /// Creates all the `` elements at the root of the bindings. -fn write_enums(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write { - for e in registry.enum_iter() { - try!(gl_generator::generators::gen_enum_item(e, "types::", dest)); +fn write_enums(registry: &Registry, dest: &mut W) -> io::Result<()> + where W: io::Write +{ + for enm in ®istry.enums { + try!(gen_enum_item(enm, "types::", dest)); } Ok(()) @@ -105,7 +112,7 @@ fn write_enums(registry: &Registry, dest: &mut W) -> io::Result<()> where W: /// The function calls the corresponding function pointer stored in the `storage` module created /// by `write_ptrs`. fn write_fns(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write { - for c in registry.cmd_iter() { + for c in ®istry.cmds { if let Some(v) = registry.aliases.get(&c.proto.ident) { try!(writeln!(dest, "/// Fallbacks: {}", v.join(", "))); } @@ -117,30 +124,41 @@ fn write_fns(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io (*storage::{name}.pf)({idents}) }}"#, name = c.proto.ident, - params = gl_generator::generators::gen_parameters(c, true, true).join(", "), - typed_params = gl_generator::generators::gen_parameters(c, false, true).join(", "), - return_suffix = gl_generator::generators::gen_return_type(c), - idents = gl_generator::generators::gen_parameters(c, true, false).join(", "), + params = gen_parameters(c, true, true).join(", "), + typed_params = gen_parameters(c, false, true).join(", "), + return_suffix = gen_return_type(c), + idents = gen_parameters(c, true, false).join(", "), )); } Ok(()) } +fn gen_return_type(cmd: &Cmd) -> String { + // turn the return type into a Rust type + let ty = &cmd.proto.ty; + + // ... but there is one more step: if the Rust type is `c_void`, we replace it with `()` + if ty == "__gl_imports::raw::c_void" { + return "()".to_string(); + } + + ty.to_string() +} + /// Creates a `FnPtr` structure which contains the store for a single binding. fn write_fnptr_struct_def(dest: &mut W) -> io::Result<()> where W: io::Write { writeln!(dest, " #[allow(missing_copy_implementations)] pub struct FnPtr {{ /// Pointer to the entry in libepoxy's dispatch table - pf: *const *const __gl_imports::libc::c_void, + pf: *const *const __gl_imports::raw::c_void, /// True if the pointer points to a real function, false if points to an error fn is_loaded: bool, }} - impl FnPtr {{ /// Creates a `FnPtr` from a load attempt. - pub fn new(ptr: *const *const __gl_imports::libc::c_void) -> FnPtr {{ + pub fn new(ptr: *const *const __gl_imports::raw::c_void) -> FnPtr {{ if ptr.is_null() {{ FnPtr {{ pf: &PMISSING_FN_EXIT, @@ -158,11 +176,11 @@ fn write_fnptr_struct_def(dest: &mut W) -> io::Result<()> where W: io::Write fn write_ptrs(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write { try!(writeln!(dest, "mod storage {{ - #![allow(non_snake_case)] + #![allow(non_snake_case, non_upper_case_globals)] use super::PMISSING_FN_EXIT; use super::FnPtr;")); - for c in registry.cmd_iter() { + for c in ®istry.cmds { try!(writeln!(dest, "pub static mut {name}: FnPtr = FnPtr {{ pf: &PMISSING_FN_EXIT, @@ -179,18 +197,18 @@ fn write_ptrs(registry: &Registry, dest: &mut W) -> io::Result<()> where W: i /// /// Each module contains `is_loaded` and `load_with` which interact with the `storage` module /// created by `write_ptrs`. -fn write_fn_mods(registry: &Registry, ns: &Ns, dest: &mut W) -> io::Result<()> where W: io::Write { - for c in registry.cmd_iter() { +fn write_fn_mods(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write { + for c in ®istry.cmds { let fallbacks = match registry.aliases.get(&c.proto.ident) { Some(v) => { let names = v.iter().map(|name| format!(r#""{}""#, - gl_generator::generators::gen_symbol_name(ns, &name[..]))).collect::>(); + gen_symbol_name(registry.api, &name[..]))).collect::>(); format!("&[{}]", names.join(", ")) }, None => "&[]".to_string(), }; let fnname = &c.proto.ident[..]; - let symbol = gl_generator::generators::gen_symbol_name(ns, &c.proto.ident[..]); + let symbol = gen_symbol_name(registry.api, &c.proto.ident[..]); let symbol = &symbol[..]; try!(writeln!(dest, r#" @@ -198,15 +216,13 @@ fn write_fn_mods(registry: &Registry, ns: &Ns, dest: &mut W) -> io::Result<() pub mod {fnname} {{ use super::{{storage, metaloadfn}}; use super::FnPtr; - #[inline] #[allow(dead_code)] pub fn is_loaded() -> bool {{ unsafe {{ storage::{fnname}.is_loaded }} }} - #[allow(dead_code)] - pub fn load_with(loadfn: F) where F: FnMut(&str) -> *const super::__gl_imports::libc::c_void {{ + pub fn load_with(loadfn: F) where F: FnMut(&str) -> *const super::__gl_imports::raw::c_void {{ unsafe {{ storage::{fnname} = FnPtr::new(metaloadfn(loadfn, "epoxy_{symbol}", {fallbacks})) }} @@ -224,15 +240,14 @@ fn write_fn_mods(registry: &Registry, ns: &Ns, dest: &mut W) -> io::Result<() /// Creates a `missing_fn_exit` function. /// /// This function is the mock that is called if the real function could not be called. -fn write_error_fns(ns: &Ns, dest: &mut W) -> io::Result<()> where W: io::Write { +fn write_error_fns(dest: &mut W) -> io::Result<()> where W: io::Write { writeln!(dest, r#" #[inline(never)] extern fn missing_fn_exit() {{ - println!("{ns} function was not loaded"); + println!("function was not loaded"); __gl_imports::exit(1); }} - const PMISSING_FN_EXIT: *const __gl_imports::libc::c_void = missing_fn_exit as *const __gl_imports::libc::c_void;"#, - ns = ns, + const PMISSING_FN_EXIT: *const __gl_imports::raw::c_void = missing_fn_exit as *const __gl_imports::raw::c_void;"#, ) } @@ -242,20 +257,19 @@ fn write_error_fns(ns: &Ns, dest: &mut W) -> io::Result<()> where W: io::Writ fn write_load_fn(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write { try!(writeln!(dest, r#" #[allow(dead_code)] - pub fn load_with(mut loadfn: F) where F: FnMut(&str) -> *const __gl_imports::libc::c_void {{ + pub fn load_with(mut loadfn: F) where F: FnMut(&str) -> *const __gl_imports::raw::c_void {{ "#)); - for c in registry.cmd_iter() { + for c in ®istry.cmds { try!(writeln!(dest, "{name}::load_with(|s| loadfn(s));", name = &c.proto.ident[..])); } writeln!(dest, " }} - #[allow(dead_code)] pub fn load(loader: &T) {{ - load_with(|name| loader.get_proc_addr(name)); + load_with(|name| loader.get_proc_addr(name) as _); }} ") } @@ -263,17 +277,17 @@ fn write_load_fn(registry: &Registry, dest: &mut W) -> io::Result<()> where W /// Creates the `get_proc_addr` function. /// /// The function adds in a layer of indirection, but allows compatibility with the `gl` crate -fn write_get_proc_addr(registry: &Registry, ns: &Ns, dest: &mut W) -> io::Result<()> where W: io::Write { +fn write_get_proc_addr(registry: &Registry, dest: &mut W) -> io::Result<()> where W: io::Write { try!(writeln!(dest, r#" #[allow(dead_code)] - pub fn get_proc_addr(symbol: &str) -> *const __gl_imports::libc::c_void {{ + pub fn get_proc_addr(symbol: &str) -> *const __gl_imports::raw::c_void {{ match &symbol[..] {{ "#)); - for c in registry.cmd_iter() { + for c in ®istry.cmds { try!(writeln!(dest, r#" - "{symbol}" => {name} as *const __gl_imports::libc::c_void,"#, - symbol = gl_generator::generators::gen_symbol_name(ns, &c.proto.ident[..]), + "{symbol}" => {name} as *const __gl_imports::raw::c_void,"#, + symbol = gen_symbol_name(registry.api, &c.proto.ident[..]), name = &c.proto.ident[..], )); } diff --git a/build/main.rs b/build/main.rs index b648b81..4ec01e9 100644 --- a/build/main.rs +++ b/build/main.rs @@ -1,16 +1,17 @@ // Based on `glium`'s build/main.rs extern crate gl_generator; -extern crate khronos_api; + +mod epoxy_gen; use std::env; use std::fs::File; -use std::io::{BufReader, BufWriter, Write}; +use std::io::{BufWriter, Write}; use std::path::Path; -use gl_generator::generators::Generator; +use gl_generator::{Api, Fallbacks, Profile, Registry}; -mod epoxy_gen; +use epoxy_gen::EpoxyGenerator; fn main() { let out_dir = env::var("OUT_DIR").unwrap(); @@ -21,119 +22,109 @@ fn main() { } fn generate_gl_bindings(dest: &mut W) where W: Write { - let gl_registry = { - let reader = BufReader::new(khronos_api::GL_XML); - let ns = gl_generator::registry::Ns::Gl; - - let filter = gl_generator::registry::Filter { - fallbacks: gl_generator::Fallbacks::None, - api: gl_generator::registry::Ns::Gl.to_string(), - extensions: vec![ - "GL_AMD_depth_clamp_separate".to_string(), - "GL_APPLE_vertex_array_object".to_string(), - "GL_ARB_bindless_texture".to_string(), - "GL_ARB_buffer_storage".to_string(), - "GL_ARB_compute_shader".to_string(), - "GL_ARB_copy_buffer".to_string(), - "GL_ARB_debug_output".to_string(), - "GL_ARB_depth_texture".to_string(), - "GL_ARB_direct_state_access".to_string(), - "GL_ARB_draw_buffers".to_string(), - "GL_ARB_ES2_compatibility".to_string(), - "GL_ARB_ES3_compatibility".to_string(), - "GL_ARB_ES3_1_compatibility".to_string(), - "GL_ARB_ES3_2_compatibility".to_string(), - "GL_ARB_framebuffer_sRGB".to_string(), - "GL_ARB_geometry_shader4".to_string(), - "GL_ARB_gpu_shader_fp64".to_string(), - "GL_ARB_gpu_shader_int64".to_string(), - "GL_ARB_invalidate_subdata".to_string(), - "GL_ARB_multi_draw_indirect".to_string(), - "GL_ARB_occlusion_query".to_string(), - "GL_ARB_pixel_buffer_object".to_string(), - "GL_ARB_robustness".to_string(), - "GL_ARB_shader_image_load_store".to_string(), - "GL_ARB_shader_objects".to_string(), - "GL_ARB_texture_buffer_object".to_string(), - "GL_ARB_texture_float".to_string(), - "GL_ARB_texture_multisample".to_string(), - "GL_ARB_texture_rg".to_string(), - "GL_ARB_texture_rgb10_a2ui".to_string(), - "GL_ARB_transform_feedback3".to_string(), - "GL_ARB_vertex_buffer_object".to_string(), - "GL_ARB_vertex_shader".to_string(), - "GL_ATI_draw_buffers".to_string(), - "GL_ATI_meminfo".to_string(), - "GL_EXT_debug_marker".to_string(), - "GL_EXT_direct_state_access".to_string(), - "GL_EXT_framebuffer_blit".to_string(), - "GL_EXT_framebuffer_multisample".to_string(), - "GL_EXT_framebuffer_object".to_string(), - "GL_EXT_framebuffer_sRGB".to_string(), - "GL_EXT_gpu_shader4".to_string(), - "GL_EXT_packed_depth_stencil".to_string(), - "GL_EXT_provoking_vertex".to_string(), - "GL_EXT_texture_array".to_string(), - "GL_EXT_texture_buffer_object".to_string(), - "GL_EXT_texture_compression_s3tc".to_string(), - "GL_EXT_texture_filter_anisotropic".to_string(), - "GL_EXT_texture_integer".to_string(), - "GL_EXT_texture_sRGB".to_string(), - "GL_EXT_transform_feedback".to_string(), - "GL_GREMEDY_string_marker".to_string(), - "GL_KHR_robustness".to_string(), - "GL_NVX_gpu_memory_info".to_string(), - "GL_NV_conditional_render".to_string(), - "GL_NV_vertex_attrib_integer_64bit".to_string(), - ], - version: "4.5".to_string(), - profile: "compatibility".to_string(), - }; - - gl_generator::registry::Registry::from_xml(reader, ns, Some(filter)) - }; - - let gles_registry = { - let reader = BufReader::new(khronos_api::GL_XML); - let ns = gl_generator::registry::Ns::Gles2; - - let filter = gl_generator::registry::Filter { - fallbacks: gl_generator::Fallbacks::None, - api: gl_generator::registry::Ns::Gles2.to_string(), - extensions: vec![ - "GL_ANGLE_framebuffer_multisample".to_string(), - "GL_APPLE_framebuffer_multisample".to_string(), - "GL_APPLE_sync".to_string(), - "GL_ARM_rgba8".to_string(), - "GL_EXT_buffer_storage".to_string(), - "GL_EXT_disjoint_timer_query".to_string(), - "GL_EXT_multi_draw_indirect".to_string(), - "GL_EXT_multisampled_render_to_texture".to_string(), - "GL_EXT_occlusion_query_boolean".to_string(), - "GL_EXT_primitive_bounding_box".to_string(), - "GL_EXT_robustness".to_string(), - "GL_KHR_debug".to_string(), - "GL_NV_copy_buffer".to_string(), - "GL_NV_framebuffer_multisample".to_string(), - "GL_NV_internalformat_sample_query".to_string(), - "GL_NV_pixel_buffer_object".to_string(), - "GL_OES_depth_texture".to_string(), - "GL_OES_draw_elements_base_vertex".to_string(), - "GL_OES_packed_depth_stencil".to_string(), - "GL_OES_primitive_bounding_box".to_string(), - "GL_OES_rgb8_rgba8".to_string(), - "GL_OES_texture_buffer".to_string(), - "GL_OES_texture_npot".to_string(), - "GL_OES_vertex_array_object".to_string(), - "GL_OES_vertex_type_10_10_10_2".to_string(), - ], - version: "3.2".to_string(), - profile: "compatibility".to_string(), - }; + let mut features = vec![]; + features.extend_from_slice(&[ + "GL_AMD_depth_clamp_separate", + "GL_APPLE_vertex_array_object", + "GL_ARB_bindless_texture", + "GL_ARB_buffer_storage", + "GL_ARB_compute_shader", + "GL_ARB_copy_buffer", + "GL_ARB_debug_output", + "GL_ARB_depth_texture", + "GL_ARB_direct_state_access", + "GL_ARB_draw_buffers", + "GL_ARB_ES2_compatibility", + "GL_ARB_ES3_compatibility", + "GL_ARB_ES3_1_compatibility", + "GL_ARB_ES3_2_compatibility", + "GL_ARB_framebuffer_sRGB", + "GL_ARB_geometry_shader4", + "GL_ARB_gpu_shader_fp64", + "GL_ARB_gpu_shader_int64", + "GL_ARB_invalidate_subdata", + "GL_ARB_multi_draw_indirect", + "GL_ARB_occlusion_query", + "GL_ARB_pixel_buffer_object", + "GL_ARB_robustness", + "GL_ARB_shader_image_load_store", + "GL_ARB_shader_objects", + "GL_ARB_texture_buffer_object", + "GL_ARB_texture_float", + "GL_ARB_texture_multisample", + "GL_ARB_texture_rg", + "GL_ARB_texture_rgb10_a2ui", + "GL_ARB_transform_feedback3", + "GL_ARB_vertex_buffer_object", + "GL_ARB_vertex_shader", + "GL_ATI_draw_buffers", + "GL_ATI_meminfo", + "GL_EXT_direct_state_access", + "GL_EXT_framebuffer_blit", + "GL_EXT_framebuffer_multisample", + "GL_EXT_framebuffer_object", + "GL_EXT_framebuffer_sRGB", + "GL_EXT_gpu_shader4", + "GL_EXT_packed_depth_stencil", + "GL_EXT_provoking_vertex", + "GL_EXT_texture_array", + "GL_EXT_texture_buffer_object", + "GL_EXT_texture_compression_s3tc", + "GL_EXT_texture_filter_anisotropic", + "GL_EXT_texture_integer", + "GL_EXT_texture_sRGB", + "GL_EXT_transform_feedback", + "GL_GREMEDY_string_marker", + "GL_KHR_robustness", + "GL_NVX_gpu_memory_info", + "GL_NV_conditional_render", + "GL_NV_vertex_attrib_integer_64bit", + ]); + #[cfg(feature="debug_marker")] + features.push("GL_EXT_debug_marker"); + let gl_registry = Registry::new( + Api::Gl, + (4, 5), + Profile::Compatibility, + Fallbacks::None, + features, + ); - gl_generator::registry::Registry::from_xml(reader, ns, Some(filter)) - }; + let gles_registry = Registry::new( + Api::Gles2, + (3, 2), + Profile::Compatibility, + Fallbacks::None, + vec![ + "GL_ANGLE_framebuffer_multisample", + "GL_APPLE_framebuffer_multisample", + "GL_APPLE_sync", + "GL_ARM_rgba8", + "GL_EXT_buffer_storage", + "GL_EXT_disjoint_timer_query", + "GL_EXT_multi_draw_indirect", + "GL_EXT_multisampled_render_to_texture", + "GL_EXT_occlusion_query_boolean", + "GL_EXT_primitive_bounding_box", + "GL_EXT_robustness", + "GL_KHR_debug", + "GL_NV_copy_buffer", + "GL_NV_framebuffer_multisample", + "GL_NV_internalformat_sample_query", + "GL_NV_pixel_buffer_object", + "GL_OES_depth_texture", + "GL_OES_draw_elements_base_vertex", + "GL_OES_packed_depth_stencil", + "GL_OES_primitive_bounding_box", + "GL_OES_rgb8_rgba8", + "GL_OES_texture_buffer", + "GL_OES_texture_npot", + "GL_OES_vertex_array_object", + "GL_OES_vertex_type_10_10_10_2", + ], + ); - epoxy_gen::EpoxyGenerator.write(&(gl_registry + gles_registry), - gl_generator::registry::Ns::Gl, dest).unwrap(); + (gl_registry + gles_registry) + .write_bindings(EpoxyGenerator, dest) + .unwrap(); }