This commit is contained in:
Drakulix 2017-06-10 23:29:09 +02:00
parent 2d255fd48d
commit eef617258e
2 changed files with 57 additions and 42 deletions

View File

@ -17,8 +17,8 @@ use std::ffi::{CStr, CString};
use std::fmt; use std::fmt;
use std::io; use std::io;
use std::mem; use std::mem;
use std::ptr;
use std::ops::Deref; use std::ops::Deref;
use std::ptr;
#[allow(non_camel_case_types, dead_code)] #[allow(non_camel_case_types, dead_code)]
mod ffi { mod ffi {
@ -155,8 +155,8 @@ impl EGLContext {
/// ///
/// This method is marked unsafe, because the contents of `NativeDisplay` cannot be verified and msy /// This method is marked unsafe, because the contents of `NativeDisplay` cannot be verified and msy
/// contain dangeling pointers are similar unsafe content /// contain dangeling pointers are similar unsafe content
pub unsafe fn new<L>(native: NativeDisplay, mut attributes: GlAttributes, reqs: PixelFormatRequirements, pub unsafe fn new<L>(native: NativeDisplay, mut attributes: GlAttributes,
logger: L) reqs: PixelFormatRequirements, logger: L)
-> Result<EGLContext, CreationError> -> Result<EGLContext, CreationError>
where L: Into<Option<::slog::Logger>> where L: Into<Option<::slog::Logger>>
{ {
@ -226,31 +226,31 @@ impl EGLContext {
let display = match native { let display = match native {
NativeDisplay::X11(display) if has_dp_extension("EGL_KHR_platform_x11") && NativeDisplay::X11(display) if has_dp_extension("EGL_KHR_platform_x11") &&
egl.GetPlatformDisplay.is_loaded() => { egl.GetPlatformDisplay.is_loaded() => {
trace!(log, "EGL Display Initialization via EGL_KHR_platform_x11"); trace!(log, "EGL Display Initialization via EGL_KHR_platform_x11");
egl.GetPlatformDisplay(ffi::egl::PLATFORM_X11_KHR, display as *mut _, ptr::null()) egl.GetPlatformDisplay(ffi::egl::PLATFORM_X11_KHR, display as *mut _, ptr::null())
} }
NativeDisplay::X11(display) if has_dp_extension("EGL_EXT_platform_x11") && NativeDisplay::X11(display) if has_dp_extension("EGL_EXT_platform_x11") &&
egl.GetPlatformDisplayEXT.is_loaded() => { egl.GetPlatformDisplayEXT.is_loaded() => {
trace!(log, "EGL Display Initialization via EGL_EXT_platform_x11"); trace!(log, "EGL Display Initialization via EGL_EXT_platform_x11");
egl.GetPlatformDisplayEXT(ffi::egl::PLATFORM_X11_EXT, display as *mut _, ptr::null()) egl.GetPlatformDisplayEXT(ffi::egl::PLATFORM_X11_EXT, display as *mut _, ptr::null())
} }
NativeDisplay::Gbm(display) if has_dp_extension("EGL_KHR_platform_gbm") && NativeDisplay::Gbm(display) if has_dp_extension("EGL_KHR_platform_gbm") &&
egl.GetPlatformDisplay.is_loaded() => { egl.GetPlatformDisplay.is_loaded() => {
trace!(log, "EGL Display Initialization via EGL_KHR_platform_gbm"); trace!(log, "EGL Display Initialization via EGL_KHR_platform_gbm");
egl.GetPlatformDisplay(ffi::egl::PLATFORM_GBM_KHR, display as *mut _, ptr::null()) egl.GetPlatformDisplay(ffi::egl::PLATFORM_GBM_KHR, display as *mut _, ptr::null())
} }
NativeDisplay::Gbm(display) if has_dp_extension("EGL_MESA_platform_gbm") && NativeDisplay::Gbm(display) if has_dp_extension("EGL_MESA_platform_gbm") &&
egl.GetPlatformDisplayEXT.is_loaded() => { egl.GetPlatformDisplayEXT.is_loaded() => {
trace!(log, "EGL Display Initialization via EGL_MESA_platform_gbm"); trace!(log, "EGL Display Initialization via EGL_MESA_platform_gbm");
egl.GetPlatformDisplayEXT(ffi::egl::PLATFORM_GBM_KHR, display as *mut _, ptr::null()) egl.GetPlatformDisplayEXT(ffi::egl::PLATFORM_GBM_KHR, display as *mut _, ptr::null())
} }
NativeDisplay::Wayland(display) if has_dp_extension("EGL_KHR_platform_wayland") && NativeDisplay::Wayland(display) if has_dp_extension("EGL_KHR_platform_wayland") &&
egl.GetPlatformDisplay.is_loaded() => { egl.GetPlatformDisplay.is_loaded() => {
trace!(log, trace!(log,
"EGL Display Initialization via EGL_KHR_platform_wayland"); "EGL Display Initialization via EGL_KHR_platform_wayland");
egl.GetPlatformDisplay(ffi::egl::PLATFORM_WAYLAND_KHR, egl.GetPlatformDisplay(ffi::egl::PLATFORM_WAYLAND_KHR,
@ -259,7 +259,7 @@ impl EGLContext {
} }
NativeDisplay::Wayland(display) if has_dp_extension("EGL_EXT_platform_wayland") && NativeDisplay::Wayland(display) if has_dp_extension("EGL_EXT_platform_wayland") &&
egl.GetPlatformDisplayEXT.is_loaded() => { egl.GetPlatformDisplayEXT.is_loaded() => {
trace!(log, trace!(log,
"EGL Display Initialization via EGL_EXT_platform_wayland"); "EGL Display Initialization via EGL_EXT_platform_wayland");
egl.GetPlatformDisplayEXT(ffi::egl::PLATFORM_WAYLAND_EXT, egl.GetPlatformDisplayEXT(ffi::egl::PLATFORM_WAYLAND_EXT,
@ -528,15 +528,15 @@ impl EGLContext {
info!(log, "EGL context created"); info!(log, "EGL context created");
Ok(EGLContext { Ok(EGLContext {
_lib: lib, _lib: lib,
context: context as *const _, context: context as *const _,
display: display as *const _, display: display as *const _,
egl: egl, egl: egl,
config_id: config_id, config_id: config_id,
surface_attributes: surface_attributes, surface_attributes: surface_attributes,
pixel_format: desc, pixel_format: desc,
logger: log, logger: log,
}) })
} }
/// Creates a surface bound to the given egl context for rendering /// Creates a surface bound to the given egl context for rendering
@ -545,14 +545,21 @@ impl EGLContext {
/// ///
/// This method is marked unsafe, because the contents of `NativeSurface` cannot be verified and msy /// This method is marked unsafe, because the contents of `NativeSurface` cannot be verified and msy
/// contain dangeling pointers are similar unsafe content /// contain dangeling pointers are similar unsafe content
pub unsafe fn create_surface<'a>(&'a self, native: NativeSurface) -> Result<EGLSurface<'a>, CreationError> { pub unsafe fn create_surface<'a>(&'a self, native: NativeSurface)
-> Result<EGLSurface<'a>, CreationError> {
trace!(self.logger, "Creating EGL window surface..."); trace!(self.logger, "Creating EGL window surface...");
let surface = { let surface = {
let surface = match native { let surface = match native {
NativeSurface::X11(window) | NativeSurface::X11(window) |
NativeSurface::Wayland(window) | NativeSurface::Wayland(window) |
NativeSurface::Gbm(window) => self.egl.CreateWindowSurface(self.display, self.config_id, window, self.surface_attributes.as_ptr()), NativeSurface::Gbm(window) => {
self.egl
.CreateWindowSurface(self.display,
self.config_id,
window,
self.surface_attributes.as_ptr())
}
}; };
if surface.is_null() { if surface.is_null() {
@ -565,9 +572,9 @@ impl EGLContext {
debug!(self.logger, "EGL window surface successfully created"); debug!(self.logger, "EGL window surface successfully created");
Ok(EGLSurface { Ok(EGLSurface {
context: &self, context: &self,
surface: surface, surface: surface,
}) })
} }
/// Returns the address of an OpenGL function. /// Returns the address of an OpenGL function.
@ -594,7 +601,8 @@ impl<'a> EGLSurface<'a> {
/// Swaps buffers at the end of a frame. /// Swaps buffers at the end of a frame.
pub fn swap_buffers(&self) -> Result<(), SwapBuffersError> { pub fn swap_buffers(&self) -> Result<(), SwapBuffersError> {
let ret = unsafe { let ret = unsafe {
self.context.egl self.context
.egl
.SwapBuffers(self.context.display as *const _, self.surface as *const _) .SwapBuffers(self.context.display as *const _, self.surface as *const _)
}; };
@ -615,7 +623,8 @@ impl<'a> EGLSurface<'a> {
/// This function is marked unsafe, because the context cannot be made current /// This function is marked unsafe, because the context cannot be made current
/// on multiple threads. /// on multiple threads.
pub unsafe fn make_current(&self) -> Result<(), SwapBuffersError> { pub unsafe fn make_current(&self) -> Result<(), SwapBuffersError> {
let ret = self.context.egl let ret = self.context
.egl
.MakeCurrent(self.context.display as *const _, .MakeCurrent(self.context.display as *const _,
self.surface as *const _, self.surface as *const _,
self.surface as *const _, self.surface as *const _,
@ -652,7 +661,8 @@ impl Drop for EGLContext {
impl<'a> Drop for EGLSurface<'a> { impl<'a> Drop for EGLSurface<'a> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
self.context.egl self.context
.egl
.DestroySurface(self.context.display as *const _, self.surface as *const _); .DestroySurface(self.context.display as *const _, self.surface as *const _);
} }
} }

View File

@ -2,8 +2,8 @@
use backend::{SeatInternal, TouchSlotInternal}; use backend::{SeatInternal, TouchSlotInternal};
use backend::graphics::GraphicsBackend; use backend::graphics::GraphicsBackend;
use backend::graphics::egl::{CreationError, EGLContext, EGLGraphicsBackend, GlAttributes, NativeDisplay, NativeSurface, use backend::graphics::egl::{CreationError, EGLContext, EGLGraphicsBackend, GlAttributes, NativeDisplay,
PixelFormat, PixelFormatRequirements, SwapBuffersError}; NativeSurface, PixelFormat, PixelFormatRequirements, SwapBuffersError};
use backend::input::{Axis, AxisSource, Event as BackendEvent, InputBackend, InputHandler, KeyState, use backend::input::{Axis, AxisSource, Event as BackendEvent, InputBackend, InputHandler, KeyState,
KeyboardKeyEvent, MouseButton, MouseButtonState, PointerAxisEvent, PointerButtonEvent, KeyboardKeyEvent, MouseButton, MouseButtonState, PointerAxisEvent, PointerButtonEvent,
PointerMotionAbsoluteEvent, Seat, SeatCapabilities, TouchCancelEvent, TouchDownEvent, PointerMotionAbsoluteEvent, Seat, SeatCapabilities, TouchCancelEvent, TouchDownEvent,
@ -103,19 +103,22 @@ pub fn init_from_builder_with_gl_attr<L>
let window = Rc::new(builder.build(&events_loop)?); let window = Rc::new(builder.build(&events_loop)?);
debug!(log, "Window created"); debug!(log, "Window created");
let (native_display, native_surface, surface) = let (native_display, native_surface, surface) = if let (Some(conn), Some(window)) =
if let (Some(conn), Some(window)) = (get_x11_xconnection(), window.get_xlib_window()) { (get_x11_xconnection(), window.get_xlib_window()) {
debug!(log, "Window is backed by X11"); debug!(log, "Window is backed by X11");
(NativeDisplay::X11(conn.display as *const _), NativeSurface::X11(window), None) (NativeDisplay::X11(conn.display as *const _), NativeSurface::X11(window), None)
} else if let (Some(display), Some(surface)) = (window.get_wayland_display(), window.get_wayland_client_surface()) { } else if let (Some(display), Some(surface)) =
debug!(log, "Window is backed by Wayland"); (window.get_wayland_display(), window.get_wayland_client_surface()) {
let (w, h) = window.get_inner_size().unwrap(); debug!(log, "Window is backed by Wayland");
let egl_surface = wegl::WlEglSurface::new(surface, w as i32, h as i32); let (w, h) = window.get_inner_size().unwrap();
(NativeDisplay::Wayland(display), NativeSurface::Wayland(egl_surface.ptr() as *const _), Some(egl_surface)) let egl_surface = wegl::WlEglSurface::new(surface, w as i32, h as i32);
} else { (NativeDisplay::Wayland(display),
error!(log, "Window is backed by an unsupported graphics framework"); NativeSurface::Wayland(egl_surface.ptr() as *const _),
return Err(CreationError::NotSupported) Some(egl_surface))
}; } else {
error!(log, "Window is backed by an unsupported graphics framework");
return Err(CreationError::NotSupported);
};
let context = unsafe { let context = unsafe {
match EGLContext::new(native_display, match EGLContext::new(native_display,
@ -137,7 +140,9 @@ pub fn init_from_builder_with_gl_attr<L>
Ok((WinitGraphicsBackend { Ok((WinitGraphicsBackend {
window: window.clone(), window: window.clone(),
context: match egl::RentEGL::try_new(Box::new(context), move |context| unsafe { context.create_surface(native_surface) }) { context: match egl::RentEGL::try_new(Box::new(context), move |context| unsafe {
context.create_surface(native_surface)
}) {
Ok(x) => x, Ok(x) => x,
Err(::rental::TryNewError(err, _)) => return Err(err), Err(::rental::TryNewError(err, _)) => return Err(err),
}, },