Skip to content

Commit

Permalink
Fix eglGetProcAddress for core OpenGL entrypoints
Browse files Browse the repository at this point in the history
  • Loading branch information
MortimerGoro committed Mar 30, 2017
1 parent 7e00056 commit 59f2701
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 6 deletions.
11 changes: 8 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "offscreen_gl_context"
license = "MIT / Apache-2.0"
version = "0.8.4"
version = "0.8.5"
authors = ["Emilio Cobos Álvarez <emilio@crisal.io>", "The Servo Project Developers"]
description = "Creation and manipulation of HW accelerated offscreen rendering contexts in multiple platforms. Originally intended for the Servo project's WebGL implementation."
repository = "https://github.com/emilio/rust-offscreen-rendering-context"
Expand All @@ -14,14 +14,16 @@ gl_generator = "0.5"
default = ["x11"]
osmesa = ["osmesa-sys"]
# NOTE: Just for testing use, there are no other changes
test_egl_in_linux = []
test_egl_in_linux = ["libloading", "lazy_static"]

[dependencies]
log = "0.3"
gleam = "0.4"
euclid = "0.11"
serde = { version = "0.9", optional = true }
osmesa-sys = { version = "0.1", optional = true }
libloading = { version = "0.3", optional = true }
lazy_static = { version = "0.2", optional = true }

[target.x86_64-apple-darwin.dependencies]
core-foundation = "0.3.0"
Expand All @@ -38,5 +40,8 @@ gdi32-sys = "0.2"
user32-sys = "0.2"
kernel32-sys = "0.2"

[target.'cfg(any(target_os="macos", target_os="windows"))'.dependencies]
[target.'cfg(any(target_os="macos", target_os="windows", target_os="android"))'.dependencies]
lazy_static = "0.2"

[target.'cfg(target_os = "android")'.dependencies]
libloading = "0.3"
4 changes: 3 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ extern crate kernel32;
extern crate gdi32;
#[cfg(target_os = "windows")]
extern crate user32;
#[cfg(any(target_os="macos", target_os="windows"))]
#[cfg(any(target_os="macos", target_os="windows", target_os="android", feature="test_egl_in_linux"))]
#[macro_use]
extern crate lazy_static;
#[cfg(any(target_os="android", feature="test_egl_in_linux"))]
extern crate libloading;

mod platform;
pub use platform::{NativeGLContext, NativeGLContextMethods, NativeGLContextHandle};
Expand Down
26 changes: 24 additions & 2 deletions src/platform/with_egl/native_gl_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,20 @@ use euclid::Size2D;
use platform::NativeGLContextMethods;
use platform::with_egl::utils::{create_pixel_buffer_backed_offscreen_context};
use std::ffi::CString;
use std::ops::Deref;
use egl;
use egl::types::{EGLint, EGLBoolean, EGLDisplay, EGLSurface, EGLConfig, EGLContext};
use libloading as lib;

lazy_static! {
static ref GL_LIB: Option<lib::Library> = {
if cfg!(target_os = "android") {
lib::Library::new("libGLESv2.so").ok()
} else {
lib::Library::new("libGL.so").ok()
}
};
}
pub struct NativeGLContextHandle(pub EGLDisplay, pub EGLSurface);
unsafe impl Send for NativeGLContextHandle {}

Expand Down Expand Up @@ -69,10 +80,21 @@ impl Drop for NativeGLContext {
impl NativeGLContextMethods for NativeGLContext {
type Handle = NativeGLContextHandle;

// According to the EGL spec <= 1.4, eglGetProcAddress should only be used to
// retrieve extension functions. Some implementatios return NULL for core OpenGL functions.
// Other implementations may return non-NULL values even for invalid core or extension symbols.
// This is very dangerous, so we use dlsym function before calling eglGetProcAddress
// in order to avoid possible garbage pointers.
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 ()
if let Some(ref lib) = *GL_LIB {
let symbol: lib::Symbol<unsafe extern fn()> = lib.get(addr.as_bytes()).unwrap();
return *symbol.deref() as *const();
}

let addr = CString::new(addr.as_bytes());
let addr = addr.unwrap().as_ptr();
egl::GetProcAddress(addr) as *const ()
}
}

Expand Down

0 comments on commit 59f2701

Please sign in to comment.