Skip to content

Commit d4e4065

Browse files
committed
Fix eglGetProcAddress for core OpenGL entrypoints
1 parent 7e00056 commit d4e4065

File tree

3 files changed

+35
-6
lines changed

3 files changed

+35
-6
lines changed

Cargo.toml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "offscreen_gl_context"
33
license = "MIT / Apache-2.0"
4-
version = "0.8.4"
4+
version = "0.8.5"
55
authors = ["Emilio Cobos Álvarez <[email protected]>", "The Servo Project Developers"]
66
description = "Creation and manipulation of HW accelerated offscreen rendering contexts in multiple platforms. Originally intended for the Servo project's WebGL implementation."
77
repository = "https://github.com/emilio/rust-offscreen-rendering-context"
@@ -14,14 +14,16 @@ gl_generator = "0.5"
1414
default = ["x11"]
1515
osmesa = ["osmesa-sys"]
1616
# NOTE: Just for testing use, there are no other changes
17-
test_egl_in_linux = []
17+
test_egl_in_linux = ["libloading", "lazy_static"]
1818

1919
[dependencies]
2020
log = "0.3"
2121
gleam = "0.4"
2222
euclid = "0.11"
2323
serde = { version = "0.9", optional = true }
2424
osmesa-sys = { version = "0.1", optional = true }
25+
libloading = { version = "0.3", optional = true }
26+
lazy_static = { version = "0.2", optional = true }
2527

2628
[target.x86_64-apple-darwin.dependencies]
2729
core-foundation = "0.3.0"
@@ -38,5 +40,8 @@ gdi32-sys = "0.2"
3840
user32-sys = "0.2"
3941
kernel32-sys = "0.2"
4042

41-
[target.'cfg(any(target_os="macos", target_os="windows"))'.dependencies]
43+
[target.'cfg(any(target_os="macos", target_os="windows", target_os="android"))'.dependencies]
4244
lazy_static = "0.2"
45+
46+
[target.'cfg(target_os = "android")'.dependencies]
47+
libloading = "0.3"

src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@ extern crate kernel32;
2323
extern crate gdi32;
2424
#[cfg(target_os = "windows")]
2525
extern crate user32;
26-
#[cfg(any(target_os="macos", target_os="windows"))]
26+
#[cfg(any(target_os="macos", target_os="windows", target_os="android", feature="test_egl_in_linux"))]
2727
#[macro_use]
2828
extern crate lazy_static;
29+
#[cfg(any(target_os="android", feature="test_egl_in_linux"))]
30+
extern crate libloading;
2931

3032
mod platform;
3133
pub use platform::{NativeGLContext, NativeGLContextMethods, NativeGLContextHandle};

src/platform/with_egl/native_gl_context.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,20 @@ use euclid::Size2D;
22
use platform::NativeGLContextMethods;
33
use platform::with_egl::utils::{create_pixel_buffer_backed_offscreen_context};
44
use std::ffi::CString;
5+
use std::ops::Deref;
56
use egl;
67
use egl::types::{EGLint, EGLBoolean, EGLDisplay, EGLSurface, EGLConfig, EGLContext};
8+
use libloading as lib;
79

10+
lazy_static! {
11+
static ref GL_LIB: Option<lib::Library> = {
12+
if cfg!(target_os = "android") {
13+
lib::Library::new("libGLESv2.so").ok()
14+
} else {
15+
lib::Library::new("libGL.so").ok()
16+
}
17+
};
18+
}
819
pub struct NativeGLContextHandle(pub EGLDisplay, pub EGLSurface);
920
unsafe impl Send for NativeGLContextHandle {}
1021

@@ -69,10 +80,21 @@ impl Drop for NativeGLContext {
6980
impl NativeGLContextMethods for NativeGLContext {
7081
type Handle = NativeGLContextHandle;
7182

83+
// According to the EGL spec <= 1.4, eglGetProcAddress should only be used to
84+
// retrieve extension functions. Some implementatios return NULL for core OpenGL functions.
85+
// Other implementations may return non-NULL values even
86+
// for invalid core or extension symbols. This is very dangerous, so we use dlsym
87+
// function before calling to eglGetProcAddress in order to avoid possible garbage pointers.
7288
fn get_proc_address(addr: &str) -> *const () {
7389
unsafe {
74-
let addr = CString::new(addr.as_bytes()).unwrap().as_ptr();
75-
egl::GetProcAddress(addr as *const _) as *const ()
90+
if let Some(ref lib) = *GL_LIB {
91+
let symbol: lib::Symbol<unsafe extern fn()> = lib.get(addr.as_bytes()).unwrap();
92+
return *symbol.deref() as *const();
93+
}
94+
95+
let addr = CString::new(addr.as_bytes());
96+
let addr = addr.unwrap().as_ptr();
97+
egl::GetProcAddress(addr) as *const ()
7698
}
7799
}
78100

0 commit comments

Comments
 (0)