Skip to content

Commit

Permalink
Get Surfman and Glutin To Compile
Browse files Browse the repository at this point in the history
Glutin backend compiles and runs, but contexts won't share resources.

Surfman compiles, but hasn't run successfully yet.
  • Loading branch information
zicklag committed Mar 2, 2020
1 parent 20f3fd2 commit 98e5cf1
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 172 deletions.
3 changes: 2 additions & 1 deletion src/backend/gl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ winit = "0.21.0"

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
glutin = { version = "0.23.0", optional = true }
surfman = { path = "../../../../surfman/surfman", features = ["sm-x11"], optional = true }
# TODO: Replace with actual version
surfman = { path = "../../../../surfman/surfman", features = ["sm-x11", "sm-raw-window-handle"], optional = true }

[target.'cfg(target_arch = "wasm32")'.dependencies]
js-sys = "0.3.6"
Expand Down
131 changes: 1 addition & 130 deletions src/backend/gl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ impl hal::Backend for Backend {
not(target_arch = "wasm32"),
any(feature = "glutin", feature = "surfman", feature = "wgl")
))]
type Instance = Surface;
type Instance = Instance;

#[cfg(target_arch = "wasm32")]
type Instance = Surface;
Expand Down Expand Up @@ -795,132 +795,3 @@ impl hal::Instance<Backend> for DummyInstance {
unimplemented!()
}
}

// #[cfg(not(target_arch = "wasm32"))]
// #[derive(Debug)]
// pub enum Instance {
// Headless(Headless),
// Surface(Surface),
// }

// impl Instance {
// pub fn create_surface_from_wayland(
// &self,
// display: *mut c_void,
// surface: *mut c_void,
// ) -> Surface {
// unimplemented!();
// // log::trace!("Creating GL surface from wayland");
// // let context = unsafe {
// // glutin::ContextBuilder::new()
// // .with_vsync(true)
// // .build_raw_wayland_context(
// // display as _,
// // surface,
// // /*TODO: do something with these dimensions*/
// // 400,
// // 400,
// // )
// // .expect("TODO: handle this error")
// // };
// // let context = unsafe { context.make_current().expect("TODO: handle this error") };
// // Surface::from_context(context)
// }

// pub fn create_surface_from_xlib(&self, window: c_ulong, display: *mut c_void) -> Surface {
// unimplemented!();
// // log::trace!("Creating GL surface from Xlib");
// // let xconn = {
// // // This is taken from `glutin::platform::unix::x11::XConnection::new except with tweaks
// // // that allow us to create the connection with an existing display pointer
// // use glutin::platform::unix::x11::{ffi, XConnection};
// // // opening the libraries
// // let xlib = ffi::Xlib::open().expect("TODO: Handle error");
// // let xcursor = ffi::Xcursor::open().expect("TODO: Handle error");
// // let xrandr = ffi::Xrandr_2_2_0::open().expect("TODO: Handle error");
// // let xrandr_1_5 = ffi::Xrandr::open().ok();
// // let xinput2 = ffi::XInput2::open().expect("TODO: Handle error");
// // let xlib_xcb = ffi::Xlib_xcb::open().expect("TODO: Handle error");
// // let xrender = ffi::Xrender::open().expect("TODO: Handle error");

// // unsafe { (xlib.XInitThreads)() };
// // // unsafe { (xlib.XSetErrorHandler)(error_handler) };

// // // Get X11 socket file descriptor
// // let fd = unsafe { (xlib.XConnectionNumber)(display as *mut ffi::_XDisplay) };

// // XConnection {
// // xlib,
// // xrandr,
// // xrandr_1_5,
// // xcursor,
// // xinput2,
// // xlib_xcb,
// // xrender,
// // display: display as _,
// // x11_fd: fd,
// // latest_error: parking_lot::Mutex::new(None),
// // cursor_cache: Default::default(),
// // }
// // };
// // let xconn = Arc::new(xconn);

// // let context = unsafe {
// // glutin::ContextBuilder::new()
// // .with_vsync(true)
// // .build_raw_x11_context(xconn, window)
// // .expect("TODO: handle this error")
// // };
// // let context = unsafe { context.make_current().expect("TODO: handle this error") };
// // Surface::from_context(context)
// }
// }

// #[cfg(not(target_arch = "wasm32"))]
// impl hal::Instance<Backend> for Instance {
// fn create(name: &str, version: u32) -> Result<Instance, hal::UnsupportedBackend> {
// Headless::create(name, version).map(Instance::Headless)
// }

// fn enumerate_adapters(&self) -> Vec<adapter::Adapter<Backend>> {
// match self {
// Instance::Headless(instance) => instance.enumerate_adapters(),
// Instance::Surface(instance) => instance.enumerate_adapters(),
// }
// }

// unsafe fn create_surface(
// &self,
// has_handle: &impl raw_window_handle::HasRawWindowHandle,
// ) -> Result<Surface, hal::window::InitError> {
// match self {
// Instance::Headless(instance) => instance.create_surface(has_handle),
// Instance::Surface(instance) => instance.create_surface(has_handle),
// }
// // use raw_window_handle::RawWindowHandle;

// // match has_handle.raw_window_handle() {
// // #[cfg(all(unix, not(target_os = "android"), not(target_os = "macos")))]
// // RawWindowHandle::Wayland(handle) => {
// // Ok(self.create_surface_from_wayland(handle.display, handle.surface))
// // }
// // #[cfg(all(
// // feature = "x11",
// // unix,
// // not(target_os = "android"),
// // not(target_os = "macos")
// // ))]
// // RawWindowHandle::Xlib(handle) => {
// // Ok(self.create_surface_from_xlib(handle.display as *mut _, handle.window))
// // }
// // _ => Err(hal::window::InitError::UnsupportedWindowHandle),
// // }
// }

// unsafe fn destroy_surface(&self, surface: Surface) {
// match self {
// Instance::Headless(instance) => instance.destroy_surface(surface),
// Instance::Surface(instance) => instance.destroy_surface(surface),
// }
// }
// }
135 changes: 133 additions & 2 deletions src/backend/gl/src/window/glutin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,16 @@
use crate::{conv, native, Backend as B, Device, GlContainer, PhysicalDevice, QueueFamily, Starc};
use hal::{adapter::Adapter, format as f, image, window};

use std::ffi::c_void;
use std::os::raw::c_ulong;
use std::sync::Arc;

use arrayvec::ArrayVec;
use glow::HasContext;
use glutin;
use glutin::{self, platform::unix::RawContextExt};

use std::iter;


#[derive(Debug)]
pub struct Swapchain {
// Underlying window, required for presentation
Expand All @@ -79,6 +82,134 @@ impl window::Swapchain<B> for Swapchain {
}
}

#[cfg(not(target_arch = "wasm32"))]
#[derive(Debug)]
pub enum Instance {
Headless(Headless),
Surface(Surface),
}

impl Instance {
pub fn create_surface_from_wayland(
&self,
display: *mut c_void,
surface: *mut c_void,
) -> Surface {
log::trace!("Creating GL surface from wayland");
let context = unsafe {
glutin::ContextBuilder::new()
.with_vsync(true)
.build_raw_wayland_context(
display as _,
surface,
/*TODO: do something with these dimensions*/
400,
400,
)
.expect("TODO: handle this error")
};
let context = unsafe { context.make_current().expect("TODO: handle this error") };
Surface::from_context(context)
}

pub fn create_surface_from_xlib(&self, window: c_ulong, display: *mut c_void) -> Surface {
log::trace!("Creating GL surface from Xlib");
let xconn = {
// This is taken from `glutin::platform::unix::x11::XConnection::new except with tweaks
// that allow us to create the connection with an existing display pointer
use glutin::platform::unix::x11::{ffi, XConnection};
// opening the libraries
let xlib = ffi::Xlib::open().expect("TODO: Handle error");
let xcursor = ffi::Xcursor::open().expect("TODO: Handle error");
let xrandr = ffi::Xrandr_2_2_0::open().expect("TODO: Handle error");
let xrandr_1_5 = ffi::Xrandr::open().ok();
let xinput2 = ffi::XInput2::open().expect("TODO: Handle error");
let xlib_xcb = ffi::Xlib_xcb::open().expect("TODO: Handle error");
let xrender = ffi::Xrender::open().expect("TODO: Handle error");

unsafe { (xlib.XInitThreads)() };
// unsafe { (xlib.XSetErrorHandler)(error_handler) };

// Get X11 socket file descriptor
let fd = unsafe { (xlib.XConnectionNumber)(display as *mut ffi::_XDisplay) };

XConnection {
xlib,
xrandr,
xrandr_1_5,
xcursor,
xinput2,
xlib_xcb,
xrender,
display: display as _,
x11_fd: fd,
latest_error: parking_lot::Mutex::new(None),
cursor_cache: Default::default(),
}
};
let xconn = Arc::new(xconn);

let context = unsafe {
glutin::ContextBuilder::new()
.with_vsync(true)
.build_raw_x11_context(xconn, window)
.expect("TODO: handle this error")
};
let context = unsafe { context.make_current().expect("TODO: handle this error") };
Surface::from_context(context)
}
}

#[cfg(not(target_arch = "wasm32"))]
impl hal::Instance<B> for Instance {
fn create(name: &str, version: u32) -> Result<Instance, hal::UnsupportedBackend> {
Headless::create(name, version).map(Instance::Headless)
}

fn enumerate_adapters(&self) -> Vec<Adapter<B>> {
match self {
Instance::Headless(instance) => instance.enumerate_adapters(),
Instance::Surface(instance) => instance.enumerate_adapters(),
}
}

unsafe fn create_surface(
&self,
has_handle: &impl raw_window_handle::HasRawWindowHandle,
) -> Result<Surface, hal::window::InitError> {
use raw_window_handle::RawWindowHandle;

match self {
Instance::Headless(instance) => instance.create_surface(has_handle),
Instance::Surface(instance) => instance.create_surface(has_handle),
};

match has_handle.raw_window_handle() {
#[cfg(all(unix, not(target_os = "android"), not(target_os = "macos")))]
RawWindowHandle::Wayland(handle) => {
Ok(self.create_surface_from_wayland(handle.display, handle.surface))
}
#[cfg(all(
feature = "x11",
unix,
not(target_os = "android"),
not(target_os = "macos")
))]
RawWindowHandle::Xlib(handle) => {
Ok(self.create_surface_from_xlib(handle.display as *mut _, handle.window))
}
_ => Err(hal::window::InitError::UnsupportedWindowHandle),
}
}

unsafe fn destroy_surface(&self, surface: Surface) {
match self {
Instance::Headless(instance) => instance.destroy_surface(surface),
Instance::Surface(instance) => instance.destroy_surface(surface),
}
}
}

//TODO: if we make `Surface` a `WindowBuilder` instead of `RawContext`,
// we could spawn window + GL context when a swapchain is requested
// and actually respect the swapchain configuration provided by the user.
Expand Down
Loading

0 comments on commit 98e5cf1

Please sign in to comment.