aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortomaka <pierre.krieger1708@gmail.com>2015-04-26 08:02:19 +0200
committertomaka <pierre.krieger1708@gmail.com>2015-04-26 08:02:19 +0200
commit8cbd57a307392e5ccb48905f3fc7b1e66cd3384a (patch)
treeab8ffec55c47ba2e5cd9a2c7895773e840d6e213
parent9a0ca92692b0d5c60e89dbdc18cafb5c468e75b0 (diff)
parent0417f7003f133fbef63e8e9d98d305368b1eed47 (diff)
downloadglutin-8cbd57a307392e5ccb48905f3fc7b1e66cd3384a.tar.gz
glutin-8cbd57a307392e5ccb48905f3fc7b1e66cd3384a.zip
Merge pull request #399 from tomaka/egl-linux
Allow using EGL with X11
-rw-r--r--build.rs8
-rw-r--r--src/api/dlopen.rs14
-rw-r--r--src/api/egl/ffi.rs8
-rw-r--r--src/api/egl/mod.rs2
-rw-r--r--src/api/mod.rs1
-rw-r--r--src/api/x11/mod.rs29
6 files changed, 45 insertions, 17 deletions
diff --git a/build.rs b/build.rs
index ca95574..4f96710 100644
--- a/build.rs
+++ b/build.rs
@@ -58,6 +58,14 @@ fn main() {
"GLX_SGI_swap_control".to_string()
],
"1.4", "core", &mut file).unwrap();
+
+ let mut file = File::create(&dest.join("egl_bindings.rs")).unwrap();
+ gl_generator::generate_bindings(gl_generator::StructGenerator,
+ gl_generator::registry::Ns::Egl,
+ gl_generator::Fallbacks::All,
+ khronos_api::EGL_XML,
+ vec![],
+ "1.5", "core", &mut file).unwrap();
}
if target.contains("android") {
diff --git a/src/api/dlopen.rs b/src/api/dlopen.rs
new file mode 100644
index 0000000..63f690a
--- /dev/null
+++ b/src/api/dlopen.rs
@@ -0,0 +1,14 @@
+#![cfg(target_os = "linux")]
+
+use libc;
+
+pub const RTLD_LAZY: libc::c_int = 0x001;
+pub const RTLD_NOW: libc::c_int = 0x002;
+
+#[link="dl"]
+extern {
+ pub fn dlopen(filename: *const libc::c_char, flag: libc::c_int) -> *mut libc::c_void;
+ pub fn dlerror() -> *mut libc::c_char;
+ pub fn dlsym(handle: *mut libc::c_void, symbol: *const libc::c_char) -> *mut libc::c_void;
+ pub fn dlclose(handle: *mut libc::c_void) -> libc::c_int;
+}
diff --git a/src/api/egl/ffi.rs b/src/api/egl/ffi.rs
index e3cf32e..8e2528d 100644
--- a/src/api/egl/ffi.rs
+++ b/src/api/egl/ffi.rs
@@ -2,8 +2,6 @@ use libc;
#[cfg(target_os = "windows")]
extern crate winapi;
-#[cfg(target_os = "linux")]
-use api::x11::ffi;
#[cfg(target_os = "android")]
use api::android::ffi;
@@ -32,10 +30,6 @@ pub type EGLNativePixmapType = *const libc::c_void; // FIXME: egl_native_pix
#[cfg(target_os = "windows")]
pub type EGLNativeWindowType = winapi::HWND;
#[cfg(target_os = "linux")]
-pub type EGLNativeWindowType = ffi::Window;
+pub type EGLNativeWindowType = *const libc::c_void;
#[cfg(target_os = "android")]
pub type EGLNativeWindowType = *const ffi::ANativeWindow;
-
-#[cfg(not(target_os = "windows"))]
-#[link(name = "EGL")]
-extern {}
diff --git a/src/api/egl/mod.rs b/src/api/egl/mod.rs
index d9ac313..fdea2cd 100644
--- a/src/api/egl/mod.rs
+++ b/src/api/egl/mod.rs
@@ -1,4 +1,4 @@
-#![cfg(all(target_os = "windows", target_os = "linux"))] // always false of the moment
+#![cfg(target_os = "linux")]
use BuilderAttribs;
use CreationError;
diff --git a/src/api/mod.rs b/src/api/mod.rs
index c71c239..34ef01d 100644
--- a/src/api/mod.rs
+++ b/src/api/mod.rs
@@ -1,5 +1,6 @@
pub mod android;
pub mod cocoa;
+pub mod dlopen;
pub mod egl;
pub mod glx;
pub mod osmesa;
diff --git a/src/api/x11/mod.rs b/src/api/x11/mod.rs
index 0bb5c88..3dd90d3 100644
--- a/src/api/x11/mod.rs
+++ b/src/api/x11/mod.rs
@@ -6,6 +6,7 @@ use CreationError::OsError;
use libc;
use std::{mem, ptr};
use std::cell::Cell;
+use std::ffi::CString;
use std::sync::atomic::AtomicBool;
use std::collections::VecDeque;
use std::sync::{Arc, Mutex, Once, ONCE_INIT};
@@ -15,7 +16,9 @@ use CursorState;
use GlRequest;
use PixelFormat;
+use api::dlopen;
use api::glx::Context as GlxContext;
+use api::egl::Context as EglContext;
pub use self::monitor::{MonitorID, get_available_monitors, get_primary_monitor};
@@ -64,6 +67,7 @@ pub struct XWindow {
pub enum Context {
Glx(GlxContext),
+ Egl(EglContext),
None,
}
@@ -543,10 +547,17 @@ impl Window {
Context::Glx(try!(GlxContext::new(builder, display, window,
fb_config, visual_infos)))
},
- /*GlRequest::Specific(Api::OpenGlEs, _) => {
- let egl = ::egl::ffi::egl::Egl;
- Context::Egl(try!(EglContext::new(egl, builder, Some(display as *const _), window)))
- },*/
+ GlRequest::Specific(Api::OpenGlEs, _) => {
+ let libegl = unsafe { dlopen::dlopen(b"libEGL.so\0".as_ptr() as *const _, dlopen::RTLD_NOW) };
+ if libegl.is_null() {
+ return Err(CreationError::NotSupported);
+ }
+ let egl = ::api::egl::ffi::egl::Egl::load_with(|sym| {
+ let sym = CString::new(sym).unwrap();
+ unsafe { dlopen::dlsym(libegl, sym.as_ptr()) }
+ });
+ Context::Egl(try!(EglContext::new(egl, builder, Some(display as *const _), unsafe { mem::transmute(window) })))
+ },
GlRequest::Specific(_, _) => {
return Err(CreationError::NotSupported);
},
@@ -666,7 +677,7 @@ impl Window {
pub unsafe fn make_current(&self) {
match self.x.context {
Context::Glx(ref ctxt) => ctxt.make_current(),
- //Context::Egl(ref ctxt) => ctxt.make_current(),
+ Context::Egl(ref ctxt) => ctxt.make_current(),
Context::None => {}
}
}
@@ -674,7 +685,7 @@ impl Window {
pub fn is_current(&self) -> bool {
match self.x.context {
Context::Glx(ref ctxt) => ctxt.is_current(),
- //Context::Egl(ref ctxt) => ctxt.is_current(),
+ Context::Egl(ref ctxt) => ctxt.is_current(),
Context::None => panic!()
}
}
@@ -682,7 +693,7 @@ impl Window {
pub fn get_proc_address(&self, addr: &str) -> *const () {
match self.x.context {
Context::Glx(ref ctxt) => ctxt.get_proc_address(addr),
- //Context::Egl(ref ctxt) => ctxt.get_proc_address(addr),
+ Context::Egl(ref ctxt) => ctxt.get_proc_address(addr),
Context::None => ptr::null()
}
}
@@ -690,7 +701,7 @@ impl Window {
pub fn swap_buffers(&self) {
match self.x.context {
Context::Glx(ref ctxt) => ctxt.swap_buffers(),
- //Context::Egl(ref ctxt) => ctxt.swap_buffers(),
+ Context::Egl(ref ctxt) => ctxt.swap_buffers(),
Context::None => {}
}
}
@@ -707,7 +718,7 @@ impl Window {
pub fn get_api(&self) -> ::Api {
match self.x.context {
Context::Glx(ref ctxt) => ctxt.get_api(),
- //Context::Egl(ref ctxt) => ctxt.get_api(),
+ Context::Egl(ref ctxt) => ctxt.get_api(),
Context::None => panic!()
}
}