Skip to content

Commit

Permalink
Auto merge of #172 - katharostech:gfx-support, r=pcwalton
Browse files Browse the repository at this point in the history
GFX Support Features

This PR contains additions to `surfman` needed for supporting the `gfx-backend-gl` effort that is being worked on in gfx-rs/gfx#3151. Still a work in progress at the moment, but it is almost finished I think.

This supercedes: pcwalton#61.

The PR adds new functions for creating a native widget from a raw window handle and will also contain fixes to allow compiling on MacOS without having to disable unsupported features.

These are both features needed by `gfx-backend-gl`.
  • Loading branch information
bors-servo authored Apr 12, 2020
2 parents c362f2a + 2925168 commit 41ac1ee
Show file tree
Hide file tree
Showing 16 changed files with 205 additions and 22 deletions.
10 changes: 6 additions & 4 deletions surfman/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ build = "build.rs"

[build-dependencies]
gl_generator = "0.13"
cfg_aliases = "0.1.0"

[features]
default = ["sm-winit"]
Expand All @@ -25,6 +26,7 @@ sm-test = []
sm-wayland-default = []
sm-winit = ["winit"]
sm-x11 = ["x11"]
sm-raw-window-handle = ["raw-window-handle"]

[dependencies]
bitflags = "1.1"
Expand All @@ -45,6 +47,10 @@ optional = true
version = "<0.19.4" # 0.19.4 causes build errors https://github.com/rust-windowing/winit/pull/1105
optional = true

[dependencies.raw-window-handle]
version = "0.3.3"
optional = true

[dev-dependencies]
clap = "2"
gl = "0.13"
Expand All @@ -68,11 +74,7 @@ features = ["client", "dlopen", "egl"]
[target.'cfg(all(unix, not(any(target_os = "macos", target_os = "android"))))'.dependencies.x11]
version = "2.3.0"
features = ["xlib"]

[target.'cfg(any(not(unix), target_os = "macos", target_os = "android"))'.dependencies.x11]
optional = true
version = "2.3.0"
features = ["xlib"]

# Ensure that we have a static libEGL.lib present for linking with EGL bindings.
[target.'cfg(target_os = "windows")'.dependencies.mozangle]
Expand Down
21 changes: 21 additions & 0 deletions surfman/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,32 @@
//! The `surfman` build script.
use gl_generator::{Api, Fallbacks, Profile, Registry, StructGenerator};
use cfg_aliases::cfg_aliases;
use std::env;
use std::fs::File;
use std::path::PathBuf;

fn main() {
// Setup aliases for #[cfg] checks
cfg_aliases! {
// Platforms
windows: { target_os = "windows" },
macos: { target_os = "macos" },
android: { target_os = "android" },
// TODO: is `target_os = "linux"` the same as the following check?
linux: { all(unix, not(any(macos, android))) },

// Features:
// Here we collect the features that are only valid on certain platforms and
// we add aliases that include checks for the correct platform.
angle: { all(windows, feature = "sm-angle") },
angle_builtin: { all(windows, feature = "sm-angle-builtin") },
angle_default: { all(windows, feature = "sm-angle-default") },
no_wgl: { all(windows, feature = "sm-no-wgl") },
wayland_default: { all(linux, feature = "sm-wayland-default") },
x11: { all(linux, feature = "sm-x11") },
}

let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
let target_family = env::var("CARGO_CFG_TARGET_FAMILY").unwrap();
let dest = PathBuf::from(&env::var("OUT_DIR").unwrap());
Expand Down
5 changes: 5 additions & 0 deletions surfman/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,9 @@ pub trait Connection: Sized {

/// Creates a native widget from a raw pointer
unsafe fn create_native_widget_from_ptr(&self, raw: *mut c_void, size: Size2D<i32>) -> Self::NativeWidget;

/// Create a native widget type from the given `raw_window_handle::RawWindowHandle`.
#[cfg(feature = "sm-raw-window-handle")]
fn create_native_widget_from_rwh(&self, window: raw_window_handle::RawWindowHandle)
-> Result<Self::NativeWidget, Error>;
}
7 changes: 7 additions & 0 deletions surfman/src/implementation/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,11 @@ impl ConnectionInterface for Connection {
unsafe fn create_native_widget_from_ptr(&self, raw: *mut c_void, size: Size2D<i32>) -> NativeWidget {
Connection::create_native_widget_from_ptr(self, raw, size)
}

#[inline]
#[cfg(feature = "sm-raw-window-handle")]
fn create_native_widget_from_rwh(&self, window: raw_window_handle::RawWindowHandle)
-> Result<NativeWidget, Error> {
Connection::create_native_widget_from_rwh(self, window)
}
}
15 changes: 15 additions & 0 deletions surfman/src/platform/android/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,21 @@ impl Connection {
native_window: raw as *mut ANativeWindow,
}
}

/// Create a native widget type from the given `raw_window_handle::RawWindowHandle`.
#[cfg(feature = "sm-raw-window-handle")]
#[inline]
pub fn create_native_widget_from_rwh(&self, raw_handle: raw_window_handle::RawWindowHandle)
-> Result<NativeWidget, Error> {
use raw_window_handle::RawWindowHandle::Android;

match raw_handle {
Android(handle) => Ok(NativeWidget {
native_window: handle.a_native_window as *mut _,
}),
_ => Err(Error::IncompatibleNativeWidget),
}
}
}

impl NativeConnection {
Expand Down
4 changes: 1 addition & 3 deletions surfman/src/platform/generic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
//
//! Backends that are not specific to any operating system.
#[cfg(any(target_os = "android",
all(target_os = "windows", feature = "sm-angle"),
all(unix, not(target_os = "macos"))))]
#[cfg(any(android, angle, linux))]
pub(crate) mod egl;

pub mod multi;
24 changes: 24 additions & 0 deletions surfman/src/platform/generic/multi/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,22 @@ impl<Def, Alt> Connection<Def, Alt>
}
}
}

/// Create a native widget type from the given `raw_window_handle::HasRawWindowHandle`.
#[cfg(feature = "sm-raw-window-handle")]
pub fn create_native_widget_from_rwh(&self, raw_handle: raw_window_handle::RawWindowHandle)
-> Result<NativeWidget<Def, Alt>, Error> {
match *self {
Connection::Default(ref connection) => {
connection.create_native_widget_from_rwh(raw_handle)
.map(NativeWidget::Default)
}
Connection::Alternate(ref connection) => {
connection.create_native_widget_from_rwh(raw_handle)
.map(NativeWidget::Alternate)
}
}
}
}

impl<Def, Alt> ConnectionInterface for Connection<Def, Alt>
Expand Down Expand Up @@ -290,4 +306,12 @@ impl<Def, Alt> ConnectionInterface for Connection<Def, Alt>
unsafe fn create_native_widget_from_ptr(&self, raw: *mut c_void, size: Size2D<i32>) -> NativeWidget<Def, Alt> {
Connection::create_native_widget_from_ptr(self, raw, size)
}

#[cfg(feature = "sm-raw-window-handle")]
fn create_native_widget_from_rwh(
&self,
raw_handle: raw_window_handle::RawWindowHandle,
) -> Result<Self::NativeWidget, Error> {
Connection::create_native_widget_from_rwh(self, raw_handle)
}
}
22 changes: 22 additions & 0 deletions surfman/src/platform/macos/cgl/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ use euclid::default::Size2D;

use std::os::raw::c_void;

#[cfg(feature = "sm-raw-window-handle")]
use crate::platform::macos::system::surface::NSView;
#[cfg(feature = "sm-raw-window-handle")]
use cocoa::base::id;

#[cfg(feature = "sm-winit")]
use winit::Window;

Expand Down Expand Up @@ -112,4 +117,21 @@ impl Connection {
pub unsafe fn create_native_widget_from_ptr(&self, raw: *mut c_void, size: Size2D<i32>) -> NativeWidget {
self.0.create_native_widget_from_ptr(raw, size)
}

/// Create a native widget type from the given `raw_window_handle::RawWindowHandle`.
#[cfg(feature = "sm-raw-window-handle")]
#[inline]
pub fn create_native_widget_from_rwh(&self, raw_handle: raw_window_handle::RawWindowHandle)
-> Result<NativeWidget, Error> {
use raw_window_handle::RawWindowHandle::MacOS;

match raw_handle {
MacOS(handle) => Ok(NativeWidget {
view: NSView(unsafe {
msg_send![handle.ns_view as id, retain]
}),
}),
_ => Err(Error::IncompatibleNativeWidget),
}
}
}
17 changes: 17 additions & 0 deletions surfman/src/platform/macos/system/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,23 @@ impl Connection {
view: NSView(raw as id),
}
}

/// Create a native widget type from the given `raw_window_handle::RawWindowHandle`.
#[cfg(feature = "sm-raw-window-handle")]
#[inline]
pub fn create_native_widget_from_rwh(&self, raw_handle: raw_window_handle::RawWindowHandle)
-> Result<NativeWidget, Error> {
use raw_window_handle::RawWindowHandle::MacOS;

match raw_handle {
MacOS(handle) => Ok(NativeWidget {
view: NSView(unsafe {
msg_send![handle.ns_view as id, retain]
}),
}),
_ => Err(Error::IncompatibleNativeWidget),
}
}
}

impl NativeConnection {
Expand Down
20 changes: 10 additions & 10 deletions surfman/src/platform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,26 @@
pub mod generic;

#[cfg(target_os = "android")]
#[cfg(android)]
pub mod android;
#[cfg(target_os = "android")]
#[cfg(android)]
pub use android as default;

#[cfg(target_os = "macos")]
#[cfg(macos)]
pub mod macos;
#[cfg(all(target_os = "macos", not(feature = "sm-x11")))]
#[cfg(macos)]
pub use macos::cgl as default;
#[cfg(target_os = "macos")]
#[cfg(macos)]
pub use macos::system;

#[cfg(unix)]
#[cfg(linux)]
pub mod unix;
#[cfg(all(unix, not(target_os = "macos"), not(target_os = "android")))]
#[cfg(linux)]
pub use unix::default;

#[cfg(target_os = "windows")]
#[cfg(windows)]
pub mod windows;
#[cfg(all(target_os = "windows", feature = "sm-angle-default"))]
#[cfg(angle_default)]
pub use windows::angle as default;
#[cfg(all(target_os = "windows", not(feature = "sm-angle-default")))]
#[cfg(all(windows, not(angle_default)))]
pub use windows::wgl as default;
8 changes: 8 additions & 0 deletions surfman/src/platform/unix/generic/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,5 +153,13 @@ impl Connection {
pub unsafe fn create_native_widget_from_ptr(&self, _raw: *mut c_void, _size: Size2D<i32>) -> NativeWidget {
NativeWidget
}

/// Create a native widget type from the given `raw_window_handle::RawWindowHandle`.
#[cfg(feature = "sm-raw-window-handle")]
#[inline]
pub fn create_native_widget_from_rwh(&self, _: raw_window_handle::RawWindowHandle)
-> Result<NativeWidget, Error> {
Err(Error::IncompatibleNativeWidget)
}
}

16 changes: 11 additions & 5 deletions surfman/src/platform/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@
//
//! Backends specific to Unix-like systems, particularly Linux.
#[cfg(all(unix, not(any(target_os = "macos", target_os = "android"))))]
// The default when x11 is enabled
#[cfg(x11)]
pub mod default;
#[cfg(all(unix, not(any(target_os = "macos", target_os = "android"))))]

// The default when x11 is not enabled
#[cfg(not(x11))]
pub use wayland as default;

#[cfg(linux)]
pub mod generic;
#[cfg(all(unix, not(any(target_os = "macos", target_os = "android"))))]

#[cfg(linux)]
pub mod wayland;
#[cfg(all(any(feature = "sm-x11",
all(unix, not(any(target_os = "macos", target_os = "android"))))))]
#[cfg(x11)]
pub mod x11;
19 changes: 19 additions & 0 deletions surfman/src/platform/unix/wayland/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,25 @@ impl Connection {
size,
}
}

/// Creates a native widget type from the given `raw_window_handle::HasRawWindowHandle`
#[cfg(feature = "sm-raw-window-handle")]
pub fn create_native_widget_from_rwh(
&self,
raw_handle: raw_window_handle::RawWindowHandle)
-> Result<NativeWidget, Error> {
use raw_window_handle::RawWindowHandle::Wayland;

let wayland_surface = match raw_handle {
Wayland(handle) => handle.surface as *mut wl_proxy,
_ => return Err(Error::IncompatibleNativeWidget),
};

// TODO: Find out how to get actual size from the raw window handle
let window_size = Size2D::new(400, 500);

Ok(NativeWidget { wayland_surface, size: window_size })
}
}

impl Drop for NativeConnectionWrapper {
Expand Down
14 changes: 14 additions & 0 deletions surfman/src/platform/unix/x11/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,20 @@ impl Connection {
window: std::mem::transmute(raw),
}
}

/// Create a native widget type from the given `raw_window_handle::HasRawWindowHandle`.
#[cfg(feature = "sm-raw-window-handle")]
pub fn create_native_widget_from_rwh(&self, raw_handle: raw_window_handle::RawWindowHandle,)
-> Result<NativeWidget, Error> {
use raw_window_handle::RawWindowHandle::Xlib;

match raw_handle {
Xlib(handle) => Ok(NativeWidget {
window: handle.window,
}),
_ => Err(Error::IncompatibleNativeWidget),
}
}
}

impl NativeConnectionWrapper {
Expand Down
9 changes: 9 additions & 0 deletions surfman/src/platform/windows/angle/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,15 @@ impl Connection {
egl_native_window: raw as EGLNativeWindowType,
}
}

/// Create a native widget type from the given `raw_window_handle::RawWindowHandle`.
#[cfg(feature = "sm-raw-window-handle")]
#[inline]
pub fn create_native_widget_from_rwh(&self, _: raw_window_handle::RawWindowHandle)
-> Result<NativeWidget, Error> {
// TODO: support raw window handle on windows angle
Err(Error::UnsupportedOnThisPlatform)
}
}

impl NativeConnection {
Expand Down
16 changes: 16 additions & 0 deletions surfman/src/platform/windows/wgl/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,22 @@ impl Connection {
window_handle: raw as HWND,
}
}

/// Create a native widget type from the given `raw_window_handle::HasRawWindowHandle`.
#[cfg(feature = "sm-raw-window-handle")]
pub fn create_native_widget_from_rwh(
&self,
raw_handle: raw_window_handle::RawWindowHandle,
) -> Result<NativeWidget, Error> {
use raw_window_handle::RawWindowHandle::Xlib;

match raw_handle {
Xlib(handle) => Ok(NativeWidget {
window: handle.window,
}),
_ => Err(Error::IncompatibleNativeWidget),
}
}
}

impl NativeConnection {
Expand Down

0 comments on commit 41ac1ee

Please sign in to comment.