diff --git a/Cargo.toml b/Cargo.toml index a19ac1f..6b380d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,15 @@ [package] name = "offscreen_gl_context" -version = "0.0.1" -authors = ["ecoal95 "] +license = "MIT / Apache-2.0" +version = "0.1.0" +authors = ["ecoal95 ", "The Servo Project Developers"] +description = "Creation and manipulation of HW accelerated offscreen rendering contexts in multiple platforms. Originally intended for the Servo project WebGL implementation." +repository = "https://github.com/ecoal95/rust-offscreen-rendering-context" +build = "build.rs" + +[build-dependencies] +gl_generator = "*" +khronos_api = "*" [features] texture_surface = ["layers"] @@ -10,9 +18,7 @@ texture_surface = ["layers"] libc = "*" log = "*" gleam = "0.1" - -[dependencies.geom] -git = "https://github.com/servo/rust-geom" +euclid = "0.1" [dependencies.layers] git = "https://github.com/servo/rust-layers" @@ -22,15 +28,6 @@ optional = true core-foundation = "*" cgl = "0.1" -[target.i686-unknown-linux-gnu.dependencies.glx] -git = "https://github.com/servo/rust-glx" - -[target.x86_64-unknown-linux-gnu.dependencies.glx] -git = "https://github.com/servo/rust-glx" - -[target.arm-unknown-linux-gnueabihf.dependencies.glx] -git = "https://github.com/servo/rust-glx" - [target.i686-unknown-linux-gnu.dependencies.x11] version = "*" features = ["xlib"] @@ -42,6 +39,3 @@ features = ["xlib"] [target.arm-unknown-linux-gnueabihf.dependencies.x11] version = "*" features = ["xlib"] - -[target.arm-linux-androideabi.dependencies.egl] -git = "https://github.com/servo/rust-egl" diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..0adfd57 --- /dev/null +++ b/build.rs @@ -0,0 +1,29 @@ +extern crate gl_generator; +extern crate khronos_api; + +use std::env; +use std::fs::File; +use std::path::PathBuf; + +fn main() { + let target = env::var("TARGET").unwrap(); + let dest = PathBuf::from(&env::var("OUT_DIR").unwrap()); + + if target.contains("linux") { + let mut file = File::create(&dest.join("glx_bindings.rs")).unwrap(); + gl_generator::generate_bindings(gl_generator::StaticGenerator, + gl_generator::registry::Ns::Glx, + gl_generator::Fallbacks::All, + khronos_api::GLX_XML, vec![], + "1.4", "core", &mut file).unwrap(); + } + + if target.contains("android") { + let mut file = File::create(&dest.join("egl_bindings.rs")).unwrap(); + gl_generator::generate_bindings(gl_generator::StaticGenerator, + gl_generator::registry::Ns::Egl, + gl_generator::Fallbacks::All, + khronos_api::EGL_XML, vec![], + "1.5", "core", &mut file).unwrap(); + } +} diff --git a/src/draw_buffer.rs b/src/draw_buffer.rs index 99275d1..405de1e 100644 --- a/src/draw_buffer.rs +++ b/src/draw_buffer.rs @@ -1,4 +1,4 @@ -use geom::Size2D; +use euclid::Size2D; use gleam::gl; use gleam::gl::types::{GLuint, GLenum, GLint}; diff --git a/src/gl_context.rs b/src/gl_context.rs index 2f6a2e9..170e49f 100644 --- a/src/gl_context.rs +++ b/src/gl_context.rs @@ -1,4 +1,4 @@ -use geom::Size2D; +use euclid::Size2D; use gleam::gl; use gleam::gl::types::{GLint, GLuint}; diff --git a/src/layers_surface_wrapper.rs b/src/layers_surface_wrapper.rs index 91dfd6b..9f03d4f 100644 --- a/src/layers_surface_wrapper.rs +++ b/src/layers_surface_wrapper.rs @@ -1,6 +1,6 @@ use layers::platform::surface::{NativeSurface, NativeGraphicsMetadata, NativePaintingGraphicsContext, NativeCompositingGraphicsContext}; use layers::texturegl::Texture; -use geom::Size2D; +use euclid::Size2D; /// A surface wrapper that owns the surface, /// and thus destroys it on drop @@ -52,7 +52,7 @@ impl LayersSurfaceWrapper { } pub fn borrow_surface(&self) -> &NativeSurface { - &self.surface + &self.surface } pub fn get_surface_id(&self) -> isize { diff --git a/src/lib.rs b/src/lib.rs index 4f0730f..e15c4e5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,17 +1,13 @@ extern crate gleam; extern crate libc; -extern crate geom; +extern crate euclid; #[cfg(target_os="linux")] extern crate x11; -#[cfg(target_os="linux")] -extern crate glx; #[cfg(target_os="macos")] extern crate cgl; #[cfg(target_os="macos")] extern crate core_foundation; -#[cfg(target_os="android")] -extern crate egl; mod platform; pub use platform::{NativeGLContext, NativeGLContextMethods}; @@ -37,6 +33,28 @@ pub use gl_formats::GLFormats; #[macro_use] extern crate log; +#[cfg(target_os="linux")] +mod glx { + include!(concat!(env!("OUT_DIR"), "/glx_bindings.rs")); +} + +#[cfg(target_os="android")] +#[allow(non_camel_case_types)] +mod egl { + use libc; + pub type khronos_utime_nanoseconds_t = khronos_uint64_t; + pub type khronos_uint64_t = libc::uint64_t; + pub type khronos_ssize_t = libc::c_long; + pub type EGLint = libc::int32_t; + pub type EGLNativeDisplayType = *const libc::c_void; + pub type EGLNativePixmapType = *const libc::c_void; + pub type EGLNativeWindowType = *const libc::c_void; + pub type NativeDisplayType = EGLNativeDisplayType; + pub type NativePixmapType = EGLNativePixmapType; + pub type NativeWindowType = EGLNativeWindowType; + include!(concat!(env!("OUT_DIR"), "/egl_bindings.rs")); +} + #[cfg(feature="texture_surface")] extern crate layers; #[cfg(feature="texture_surface")] diff --git a/src/platform/with_egl/native_gl_context.rs b/src/platform/with_egl/native_gl_context.rs index fb347f0..c05eef2 100644 --- a/src/platform/with_egl/native_gl_context.rs +++ b/src/platform/with_egl/native_gl_context.rs @@ -1,7 +1,9 @@ -use geom::Size2D; +use std::ffi::CString; +use euclid::Size2D; use platform::NativeGLContextMethods; use platform::with_egl::utils::{create_pixel_buffer_backed_offscreen_context}; -use egl::egl::{self, EGLint, EGLDisplay, EGLSurface, EGLConfig, EGLContext}; +use egl; +use egl::types::{EGLint, EGLBoolean, EGLDisplay, EGLSurface, EGLConfig, EGLContext}; #[cfg(feature="texture_surface")] use layers::platform::surface::NativeGraphicsMetadata; @@ -21,20 +23,20 @@ impl NativeGLContext { let shared = match share_context { Some(ctx) => ctx.as_native_egl_context(), - None => egl::EGL_NO_CONTEXT as EGLContext, + None => egl::NO_CONTEXT as EGLContext, }; let attributes = [ - egl::EGL_CONTEXT_CLIENT_VERSION as EGLint, 2, - egl::EGL_NONE as EGLint, 0, 0, 0, // see mod.rs + egl::CONTEXT_CLIENT_VERSION as EGLint, 2, + egl::NONE as EGLint, 0, 0, 0, // see mod.rs ]; - let ctx = egl::CreateContext(display, config, shared, attributes.as_ptr()); + let ctx = unsafe { egl::CreateContext(display, config, shared, attributes.as_ptr()) }; // TODO: Check for every type of error possible, not just client error? // Note if we do it we must do it too on egl::CreatePBufferSurface, etc... - if ctx == (egl::EGL_NO_CONTEXT as EGLContext) { - egl::DestroySurface(display, surface); + if ctx == (egl::NO_CONTEXT as EGLContext) { + unsafe { egl::DestroySurface(display, surface) }; return Err("Error creating an EGL context"); } @@ -54,22 +56,23 @@ impl NativeGLContext { impl Drop for NativeGLContext { fn drop(&mut self) { let _ = self.unbind(); - - if egl::DestroySurface(self.native_display, self.native_surface) == 0 { - debug!("egl::DestroySurface failed"); - } - if egl::DestroyContext(self.native_display, self.native_context) == 0 { - debug!("egl::DestroyContext failed"); + unsafe { + if egl::DestroySurface(self.native_display, self.native_surface) == 0 { + debug!("egl::DestroySurface failed"); + } + if egl::DestroyContext(self.native_display, self.native_context) == 0 { + debug!("egl::DestroyContext failed"); + } } } } impl NativeGLContextMethods for NativeGLContext { - fn get_proc_address(_addr: &str) -> *const () { - // TODO: add eglGetProcAddress to rust-egl? - // let addr = CString::new(addr.as_bytes()).unwrap().as_ptr(); - // egl::GetProcAddress(addr as *const _) as *const () - 0 as *const () + fn get_proc_address(addr: &str) -> *const () { + unsafe { + let addr = CString::new(addr.as_bytes()).unwrap().as_ptr(); + egl::GetProcAddress(addr as *const _) as *const () + } } fn create_headless() -> Result { @@ -80,30 +83,36 @@ impl NativeGLContextMethods for NativeGLContext { #[inline(always)] fn is_current(&self) -> bool { - egl::GetCurrentContext() == self.native_context + unsafe { + egl::GetCurrentContext() == self.native_context + } } fn make_current(&self) -> Result<(), &'static str> { - if !self.is_current() && - egl::MakeCurrent(self.native_display, - self.native_surface, - self.native_surface, - self.native_context) == egl::EGL_FALSE { - Err("egl::MakeCurrent") - } else { - Ok(()) + unsafe { + if !self.is_current() && + egl::MakeCurrent(self.native_display, + self.native_surface, + self.native_surface, + self.native_context) == (egl::FALSE as EGLBoolean) { + Err("egl::MakeCurrent") + } else { + Ok(()) + } } } fn unbind(&self) -> Result<(), &'static str> { - if self.is_current() && - egl::MakeCurrent(self.native_display, - egl::EGL_NO_SURFACE as EGLSurface, - egl::EGL_NO_SURFACE as EGLSurface, - egl::EGL_NO_CONTEXT as EGLContext) == egl::EGL_FALSE { - Err("egl::MakeCurrent (on unbind)") - } else { - Ok(()) + unsafe { + if self.is_current() && + egl::MakeCurrent(self.native_display, + egl::NO_SURFACE as EGLSurface, + egl::NO_SURFACE as EGLSurface, + egl::NO_CONTEXT as EGLContext) == (egl::FALSE as EGLBoolean) { + Err("egl::MakeCurrent (on unbind)") + } else { + Ok(()) + } } } diff --git a/src/platform/with_egl/utils.rs b/src/platform/with_egl/utils.rs index d80cd79..55ac7c5 100644 --- a/src/platform/with_egl/utils.rs +++ b/src/platform/with_egl/utils.rs @@ -1,18 +1,20 @@ -use egl::egl::{self, EGLNativeDisplayType, EGLDisplay, EGLConfig, EGLSurface, EGLint}; use std::mem; -use geom::Size2D; +use euclid::Size2D; use super::NativeGLContext; +use egl; +use egl::types::{EGLNativeDisplayType, EGLDisplay, EGLConfig, EGLSurface, EGLint}; + fn create_pbuffer_surface(display: EGLDisplay, config: EGLConfig, size: Size2D) -> Result { let mut attrs = [ - egl::EGL_WIDTH as EGLint, size.width as EGLint, - egl::EGL_HEIGHT as EGLint, size.height as EGLint, - egl::EGL_NONE as EGLint, 0, 0, 0, // see mod.rs + egl::WIDTH as EGLint, size.width as EGLint, + egl::HEIGHT as EGLint, size.height as EGLint, + egl::NONE as EGLint, 0, 0, 0, // see mod.rs ]; let surface = unsafe { egl::CreatePbufferSurface(display, config, &mut *attrs.as_mut_ptr()) }; - if surface == (egl::EGL_NO_SURFACE as EGLSurface) { + if surface == (egl::NO_SURFACE as EGLSurface) { return Err("egl::CreatePBufferSurface"); } @@ -21,19 +23,19 @@ fn create_pbuffer_surface(display: EGLDisplay, config: EGLConfig, size: Size2D) -> Result { let attributes = [ - egl::EGL_SURFACE_TYPE as EGLint, egl::EGL_PBUFFER_BIT as EGLint, - egl::EGL_RENDERABLE_TYPE as EGLint, egl::EGL_OPENGL_ES2_BIT as EGLint, - egl::EGL_RED_SIZE as EGLint, 8, - egl::EGL_GREEN_SIZE as EGLint, 8, - egl::EGL_BLUE_SIZE as EGLint, 8, - egl::EGL_ALPHA_SIZE as EGLint, 0, - egl::EGL_NONE as EGLint, 0, 0, 0, // see mod.rs + egl::SURFACE_TYPE as EGLint, egl::PBUFFER_BIT as EGLint, + egl::RENDERABLE_TYPE as EGLint, egl::OPENGL_ES2_BIT as EGLint, + egl::RED_SIZE as EGLint, 8, + egl::GREEN_SIZE as EGLint, 8, + egl::BLUE_SIZE as EGLint, 8, + egl::ALPHA_SIZE as EGLint, 0, + egl::NONE as EGLint, 0, 0, 0, // see mod.rs ]; // TODO: Check if we should use `egl::GetCurrentDisplay` instead - let display = egl::GetDisplay(egl::EGL_DEFAULT_DISPLAY as EGLNativeDisplayType); + let display = unsafe { egl::GetDisplay(egl::DEFAULT_DISPLAY as EGLNativeDisplayType) }; - if display == (egl::EGL_NO_DISPLAY as EGLDisplay) { + if display == (egl::NO_DISPLAY as EGLDisplay) { return Err("egl::GetDisplay"); } @@ -41,8 +43,10 @@ pub fn create_pixel_buffer_backed_offscreen_context(size: Size2D) -> Result let mut config : EGLConfig = unsafe { mem::uninitialized() }; let mut found_configs : EGLint = 0; - if egl::ChooseConfig(display, attributes.as_ptr(), &mut config, 1, &mut found_configs) == 0 { - return Err("egl::ChooseConfig"); + unsafe { + if egl::ChooseConfig(display, attributes.as_ptr(), &mut config, 1, &mut found_configs) == 0 { + return Err("egl::ChooseConfig"); + } } if found_configs == 0 { diff --git a/src/platform/with_glx/native_gl_context.rs b/src/platform/with_glx/native_gl_context.rs index c225f21..1261b63 100644 --- a/src/platform/with_glx/native_gl_context.rs +++ b/src/platform/with_glx/native_gl_context.rs @@ -4,7 +4,7 @@ use glx; use x11::xlib::*; use libc::*; use glx::types::{GLXContext, GLXDrawable, GLXFBConfig, GLXPixmap}; -use geom::{Size2D}; +use euclid::Size2D; use super::utils::{create_offscreen_pixmap_backed_context}; use platform::NativeGLContextMethods; diff --git a/src/platform/with_glx/utils.rs b/src/platform/with_glx/utils.rs index 8cf5d82..eeada45 100644 --- a/src/platform/with_glx/utils.rs +++ b/src/platform/with_glx/utils.rs @@ -2,7 +2,7 @@ use glx; use x11::xlib::*; use glx::types::{GLXDrawable}; use libc::*; -use geom::{Size2D}; +use euclid::Size2D; use NativeGLContext; diff --git a/src/tests.rs b/src/tests.rs index 3addb27..0158bad 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1,5 +1,5 @@ use gleam::gl; -use geom::Size2D; +use euclid::Size2D; use GLContext; use GLContextAttributes;