Merge pull request #399 from tomaka/egl-linux

Allow using EGL with X11
This commit is contained in:
tomaka 2015-04-26 08:02:19 +02:00
commit 8cbd57a307
6 changed files with 45 additions and 17 deletions

View file

@ -58,6 +58,14 @@ fn main() {
"GLX_SGI_swap_control".to_string() "GLX_SGI_swap_control".to_string()
], ],
"1.4", "core", &mut file).unwrap(); "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") { if target.contains("android") {

14
src/api/dlopen.rs Normal file
View file

@ -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;
}

View file

@ -2,8 +2,6 @@ use libc;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
extern crate winapi; extern crate winapi;
#[cfg(target_os = "linux")]
use api::x11::ffi;
#[cfg(target_os = "android")] #[cfg(target_os = "android")]
use api::android::ffi; use api::android::ffi;
@ -32,10 +30,6 @@ pub type EGLNativePixmapType = *const libc::c_void; // FIXME: egl_native_pix
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
pub type EGLNativeWindowType = winapi::HWND; pub type EGLNativeWindowType = winapi::HWND;
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
pub type EGLNativeWindowType = ffi::Window; pub type EGLNativeWindowType = *const libc::c_void;
#[cfg(target_os = "android")] #[cfg(target_os = "android")]
pub type EGLNativeWindowType = *const ffi::ANativeWindow; pub type EGLNativeWindowType = *const ffi::ANativeWindow;
#[cfg(not(target_os = "windows"))]
#[link(name = "EGL")]
extern {}

View file

@ -1,4 +1,4 @@
#![cfg(all(target_os = "windows", target_os = "linux"))] // always false of the moment #![cfg(target_os = "linux")]
use BuilderAttribs; use BuilderAttribs;
use CreationError; use CreationError;

View file

@ -1,5 +1,6 @@
pub mod android; pub mod android;
pub mod cocoa; pub mod cocoa;
pub mod dlopen;
pub mod egl; pub mod egl;
pub mod glx; pub mod glx;
pub mod osmesa; pub mod osmesa;

View file

@ -6,6 +6,7 @@ use CreationError::OsError;
use libc; use libc;
use std::{mem, ptr}; use std::{mem, ptr};
use std::cell::Cell; use std::cell::Cell;
use std::ffi::CString;
use std::sync::atomic::AtomicBool; use std::sync::atomic::AtomicBool;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::sync::{Arc, Mutex, Once, ONCE_INIT}; use std::sync::{Arc, Mutex, Once, ONCE_INIT};
@ -15,7 +16,9 @@ use CursorState;
use GlRequest; use GlRequest;
use PixelFormat; use PixelFormat;
use api::dlopen;
use api::glx::Context as GlxContext; use api::glx::Context as GlxContext;
use api::egl::Context as EglContext;
pub use self::monitor::{MonitorID, get_available_monitors, get_primary_monitor}; pub use self::monitor::{MonitorID, get_available_monitors, get_primary_monitor};
@ -64,6 +67,7 @@ pub struct XWindow {
pub enum Context { pub enum Context {
Glx(GlxContext), Glx(GlxContext),
Egl(EglContext),
None, None,
} }
@ -543,10 +547,17 @@ impl Window {
Context::Glx(try!(GlxContext::new(builder, display, window, Context::Glx(try!(GlxContext::new(builder, display, window,
fb_config, visual_infos))) fb_config, visual_infos)))
}, },
/*GlRequest::Specific(Api::OpenGlEs, _) => { GlRequest::Specific(Api::OpenGlEs, _) => {
let egl = ::egl::ffi::egl::Egl; let libegl = unsafe { dlopen::dlopen(b"libEGL.so\0".as_ptr() as *const _, dlopen::RTLD_NOW) };
Context::Egl(try!(EglContext::new(egl, builder, Some(display as *const _), window))) 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(_, _) => { GlRequest::Specific(_, _) => {
return Err(CreationError::NotSupported); return Err(CreationError::NotSupported);
}, },
@ -666,7 +677,7 @@ impl Window {
pub unsafe fn make_current(&self) { pub unsafe fn make_current(&self) {
match self.x.context { match self.x.context {
Context::Glx(ref ctxt) => ctxt.make_current(), Context::Glx(ref ctxt) => ctxt.make_current(),
//Context::Egl(ref ctxt) => ctxt.make_current(), Context::Egl(ref ctxt) => ctxt.make_current(),
Context::None => {} Context::None => {}
} }
} }
@ -674,7 +685,7 @@ impl Window {
pub fn is_current(&self) -> bool { pub fn is_current(&self) -> bool {
match self.x.context { match self.x.context {
Context::Glx(ref ctxt) => ctxt.is_current(), Context::Glx(ref ctxt) => ctxt.is_current(),
//Context::Egl(ref ctxt) => ctxt.is_current(), Context::Egl(ref ctxt) => ctxt.is_current(),
Context::None => panic!() Context::None => panic!()
} }
} }
@ -682,7 +693,7 @@ impl Window {
pub fn get_proc_address(&self, addr: &str) -> *const () { pub fn get_proc_address(&self, addr: &str) -> *const () {
match self.x.context { match self.x.context {
Context::Glx(ref ctxt) => ctxt.get_proc_address(addr), 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() Context::None => ptr::null()
} }
} }
@ -690,7 +701,7 @@ impl Window {
pub fn swap_buffers(&self) { pub fn swap_buffers(&self) {
match self.x.context { match self.x.context {
Context::Glx(ref ctxt) => ctxt.swap_buffers(), Context::Glx(ref ctxt) => ctxt.swap_buffers(),
//Context::Egl(ref ctxt) => ctxt.swap_buffers(), Context::Egl(ref ctxt) => ctxt.swap_buffers(),
Context::None => {} Context::None => {}
} }
} }
@ -707,7 +718,7 @@ impl Window {
pub fn get_api(&self) -> ::Api { pub fn get_api(&self) -> ::Api {
match self.x.context { match self.x.context {
Context::Glx(ref ctxt) => ctxt.get_api(), Context::Glx(ref ctxt) => ctxt.get_api(),
//Context::Egl(ref ctxt) => ctxt.get_api(), Context::Egl(ref ctxt) => ctxt.get_api(),
Context::None => panic!() Context::None => panic!()
} }
} }