-
-
Notifications
You must be signed in to change notification settings - Fork 481
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added headless guards to EGL and GLX. Gets rid of libc dependency.
Signed-off-by: Hal Gentz <[email protected]>
- Loading branch information
1 parent
600030a
commit caf5a2b
Showing
16 changed files
with
372 additions
and
210 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,23 @@ | ||
#![allow(non_camel_case_types)] | ||
|
||
use libc; | ||
use std::os::raw; | ||
|
||
pub type caca_display_t = libc::c_void; | ||
pub type caca_canvas_t = libc::c_void; | ||
pub type caca_dither_t = libc::c_void; | ||
pub type caca_display_t = raw::c_void; | ||
pub type caca_canvas_t = raw::c_void; | ||
pub type caca_dither_t = raw::c_void; | ||
|
||
shared_library!(LibCaca, "libcaca.so.0", | ||
pub fn caca_create_display(cv: *mut caca_canvas_t) -> *mut caca_display_t, | ||
pub fn caca_free_display(dp: *mut caca_display_t) -> libc::c_int, | ||
pub fn caca_free_display(dp: *mut caca_display_t) -> raw::c_int, | ||
pub fn caca_get_canvas(dp: *mut caca_display_t) -> *mut caca_canvas_t, | ||
pub fn caca_refresh_display(dp: *mut caca_display_t) -> libc::c_int, | ||
pub fn caca_dither_bitmap(cv: *mut caca_canvas_t, x: libc::c_int, y: libc::c_int, | ||
w: libc::c_int, h: libc::c_int, d: *const caca_dither_t, | ||
pixels: *const libc::c_void) -> libc::c_int, | ||
pub fn caca_free_dither(d: *mut caca_dither_t) -> libc::c_int, | ||
pub fn caca_create_dither(bpp: libc::c_int, w: libc::c_int, h: libc::c_int, | ||
pitch: libc::c_int, rmask: libc::uint32_t, gmask: libc::uint32_t, | ||
bmask: libc::uint32_t, amask: libc::uint32_t) -> *mut caca_dither_t, | ||
pub fn caca_get_canvas_width(cv: *mut caca_canvas_t) -> libc::c_int, | ||
pub fn caca_get_canvas_height(cv: *mut caca_canvas_t) -> libc::c_int, | ||
pub fn caca_refresh_display(dp: *mut caca_display_t) -> raw::c_int, | ||
pub fn caca_dither_bitmap(cv: *mut caca_canvas_t, x: raw::c_int, y: raw::c_int, | ||
w: raw::c_int, h: raw::c_int, d: *const caca_dither_t, | ||
pixels: *const raw::c_void) -> raw::c_int, | ||
pub fn caca_free_dither(d: *mut caca_dither_t) -> raw::c_int, | ||
pub fn caca_create_dither(bpp: raw::c_int, w: raw::c_int, h: raw::c_int, | ||
pitch: raw::c_int, rmask: u32, gmask: u32, | ||
bmask: u32, amask: u32) -> *mut caca_dither_t, | ||
pub fn caca_get_canvas_width(cv: *mut caca_canvas_t) -> raw::c_int, | ||
pub fn caca_get_canvas_height(cv: *mut caca_canvas_t) -> raw::c_int, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
use glutin_egl_sys as ffi; | ||
|
||
/// A guard for when you want to make the context current. Destroying the guard | ||
/// restores the previously-current context. | ||
#[derive(Debug)] | ||
pub struct MakeCurrentGuard { | ||
old_display: ffi::egl::types::EGLDisplay, | ||
possibly_invalid: Option<MakeCurrentGuardInner>, | ||
} | ||
|
||
#[derive(Debug, PartialEq)] | ||
struct MakeCurrentGuardInner { | ||
old_draw_surface: ffi::egl::types::EGLSurface, | ||
old_read_surface: ffi::egl::types::EGLSurface, | ||
old_context: ffi::egl::types::EGLContext, | ||
} | ||
|
||
impl MakeCurrentGuard { | ||
pub fn new( | ||
display: ffi::egl::types::EGLDisplay, | ||
draw_surface: ffi::egl::types::EGLSurface, | ||
read_surface: ffi::egl::types::EGLSurface, | ||
context: ffi::egl::types::EGLContext, | ||
) -> Result<Self, String> { | ||
unsafe { | ||
let egl = super::EGL.as_ref().unwrap(); | ||
|
||
let ret = MakeCurrentGuard { | ||
old_display: egl.GetCurrentDisplay(), | ||
possibly_invalid: Some(MakeCurrentGuardInner { | ||
old_draw_surface: egl | ||
.GetCurrentSurface(ffi::egl::DRAW as i32), | ||
old_read_surface: egl | ||
.GetCurrentSurface(ffi::egl::READ as i32), | ||
old_context: egl.GetCurrentContext(), | ||
}), | ||
}; | ||
|
||
let res = | ||
egl.MakeCurrent(display, draw_surface, read_surface, context); | ||
|
||
if res == 0 { | ||
let err = egl.GetError(); | ||
Err(format!("`eglMakeCurrent` failed: {:?}", err)) | ||
} else { | ||
Ok(ret) | ||
} | ||
} | ||
} | ||
|
||
pub fn if_any_same_then_invalidate( | ||
&mut self, | ||
display: ffi::egl::types::EGLDisplay, | ||
draw_surface: ffi::egl::types::EGLSurface, | ||
read_surface: ffi::egl::types::EGLSurface, | ||
context: ffi::egl::types::EGLContext, | ||
) { | ||
if self.possibly_invalid.is_some() { | ||
let mgi = MakeCurrentGuardInner { | ||
old_draw_surface: draw_surface, | ||
old_read_surface: read_surface, | ||
old_context: context, | ||
}; | ||
|
||
if self.old_display == display || self.possibly_invalid == Some(mgi) | ||
{ | ||
self.invalidate(); | ||
} | ||
} | ||
} | ||
|
||
pub fn invalidate(&mut self) { | ||
self.possibly_invalid.take(); | ||
} | ||
} | ||
|
||
impl Drop for MakeCurrentGuard { | ||
fn drop(&mut self) { | ||
let egl = super::EGL.as_ref().unwrap(); | ||
let (draw_surface, read_surface, context) = | ||
match self.possibly_invalid.take() { | ||
Some(inner) => ( | ||
inner.old_draw_surface, | ||
inner.old_read_surface, | ||
inner.old_context, | ||
), | ||
None => ( | ||
ffi::egl::NO_SURFACE, | ||
ffi::egl::NO_SURFACE, | ||
ffi::egl::NO_CONTEXT, | ||
), | ||
}; | ||
|
||
unsafe { | ||
let res = egl.MakeCurrent( | ||
self.old_display, | ||
draw_surface, | ||
read_surface, | ||
context, | ||
); | ||
|
||
if res == 0 { | ||
let err = egl.GetError(); | ||
panic!("`eglMakeCurrent` failed: {:?}", err) | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
use glutin_glx_sys as ffi; | ||
use winit::os::unix::x11::XConnection; | ||
|
||
use std::sync::Arc; | ||
|
||
/// A guard for when you want to make the context current. Destroying the guard | ||
/// restores the previously-current context. | ||
#[derive(Debug)] | ||
pub struct MakeCurrentGuard { | ||
old_display: *mut ffi::Display, | ||
xconn: Arc<XConnection>, | ||
possibly_invalid: Option<MakeCurrentGuardInner>, | ||
} | ||
|
||
#[derive(Debug)] | ||
struct MakeCurrentGuardInner { | ||
old_drawable: ffi::glx::types::GLXDrawable, | ||
old_context: ffi::GLXContext, | ||
} | ||
|
||
impl MakeCurrentGuard { | ||
pub fn new( | ||
xconn: &Arc<XConnection>, | ||
drawable: ffi::glx::types::GLXDrawable, | ||
context: ffi::GLXContext, | ||
) -> Result<Self, String> { | ||
unsafe { | ||
let glx = super::GLX.as_ref().unwrap(); | ||
|
||
let ret = MakeCurrentGuard { | ||
old_display: glx.GetCurrentDisplay() as *mut _, | ||
xconn: Arc::clone(xconn), | ||
possibly_invalid: Some(MakeCurrentGuardInner { | ||
old_drawable: glx.GetCurrentDrawable(), | ||
old_context: glx.GetCurrentContext(), | ||
}), | ||
}; | ||
|
||
let res = | ||
glx.MakeCurrent(xconn.display as *mut _, drawable, context); | ||
|
||
if res == 0 { | ||
let err = xconn.check_errors(); | ||
Err(format!("`glXMakeCurrent` failed: {:?}", err)) | ||
} else { | ||
Ok(ret) | ||
} | ||
} | ||
} | ||
|
||
pub fn old_context(&mut self) -> Option<ffi::GLXContext> { | ||
self.possibly_invalid.as_ref().map(|pi| pi.old_context) | ||
} | ||
|
||
pub fn invalidate(&mut self) { | ||
self.possibly_invalid.take(); | ||
} | ||
} | ||
|
||
impl Drop for MakeCurrentGuard { | ||
fn drop(&mut self) { | ||
let glx = super::GLX.as_ref().unwrap(); | ||
let (drawable, context) = match self.possibly_invalid.take() { | ||
Some(inner) => (inner.old_drawable, inner.old_context), | ||
None => (0, std::ptr::null()), | ||
}; | ||
|
||
let res = unsafe { | ||
glx.MakeCurrent(self.old_display as *mut _, drawable, context) | ||
}; | ||
|
||
if res == 0 { | ||
let err = self.xconn.check_errors(); | ||
panic!("`glXMakeCurrent` failed: {:?}", err); | ||
} | ||
} | ||
} |
Oops, something went wrong.