@@ -2,9 +2,20 @@ use euclid::Size2D;
2
2
use platform:: NativeGLContextMethods ;
3
3
use platform:: with_egl:: utils:: { create_pixel_buffer_backed_offscreen_context} ;
4
4
use std:: ffi:: CString ;
5
+ use std:: ops:: Deref ;
5
6
use egl;
6
7
use egl:: types:: { EGLint , EGLBoolean , EGLDisplay , EGLSurface , EGLConfig , EGLContext } ;
8
+ use libloading as lib;
7
9
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
+ }
8
19
pub struct NativeGLContextHandle ( pub EGLDisplay , pub EGLSurface ) ;
9
20
unsafe impl Send for NativeGLContextHandle { }
10
21
@@ -69,10 +80,21 @@ impl Drop for NativeGLContext {
69
80
impl NativeGLContextMethods for NativeGLContext {
70
81
type Handle = NativeGLContextHandle ;
71
82
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.
72
88
fn get_proc_address ( addr : & str ) -> * const ( ) {
73
89
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 ( )
76
98
}
77
99
}
78
100
0 commit comments