Skip to content

Commit

Permalink
Finish out full glutin implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
notgull committed Jul 15, 2023
1 parent 68a94f9 commit bcf2996
Show file tree
Hide file tree
Showing 10 changed files with 369 additions and 234 deletions.
9 changes: 4 additions & 5 deletions glutin/src/api/egl/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ use std::ops::Deref;
use std::sync::Arc;
use std::{fmt, mem};

use raw_window_handle::{
HasDisplayHandle, HasRawDisplayHandle, HasRawWindowHandle, HasWindowHandle, RawWindowHandle,
};
use raw_window_handle::{HasDisplayHandle, HasRawWindowHandle, HasWindowHandle, RawWindowHandle};

use glutin_egl_sys::egl;
use glutin_egl_sys::egl::types::{EGLConfig, EGLint};
Expand Down Expand Up @@ -186,7 +184,7 @@ impl<D: HasDisplayHandle> Display<D> {
}

let raw_handle =
template.native_window.map(|w| w.window_handle()?.raw_window_handle()).transpose()?;
template._native_window.map(|w| w.window_handle()?.raw_window_handle()).transpose()?;
let configs = found_configs
.into_iter()
.map(move |raw| {
Expand Down Expand Up @@ -352,7 +350,7 @@ impl<D: HasDisplayHandle> GlConfig for Config<D> {

#[cfg(any(wayland_platform, x11_platform))]
fn supports_transparency(&self) -> Option<bool> {
use raw_window_handle::RawDisplayHandle;
use raw_window_handle::{HasRawDisplayHandle, RawDisplayHandle};
match self
.inner
.display
Expand Down Expand Up @@ -411,6 +409,7 @@ impl<D: HasDisplayHandle> AsRawConfig for Config<D> {
#[cfg(x11_platform)]
impl<D: HasDisplayHandle> X11GlConfigExt for Config<D> {
fn x11_visual(&self) -> Option<X11VisualInfo> {
use raw_window_handle::HasRawDisplayHandle;
match self
.inner
.display
Expand Down
39 changes: 26 additions & 13 deletions glutin/src/api/egl/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ use raw_window_handle::{HasDisplayHandle, HasRawDisplayHandle, HasWindowHandle,

use crate::config::ConfigTemplate;
use crate::context::Version;
use crate::display::{AsRawDisplay, DisplayFeatures, GetDisplayExtensions, RawDisplay};
use crate::display::{
AsRawDisplay, DisplayFeatures, DisplayResult, GetDisplayExtensions, RawDisplay,
};
use crate::error::{ErrorKind, Result};
use crate::prelude::*;
use crate::private::Sealed;
Expand Down Expand Up @@ -55,32 +57,39 @@ impl<D: HasDisplayHandle> Display<D> {
/// `EGL_DEFAULT_DISPLAY`, which is not recommended or will
/// work on a platform with a concept of native display, like Wayland.
pub fn new(raw_display: D) -> Result<Self> {
Self::new_with_display(raw_display).map_err(Into::into)
}

pub(crate) fn new_with_display(raw_display: D) -> DisplayResult<Self, D> {
let egl = match EGL.as_ref() {
Some(egl) => egl,
None => return Err(ErrorKind::NotFound.into()),
None => return Err((ErrorKind::NotFound, raw_display).into()),
};

NO_DISPLAY_EXTENSIONS.get_or_init(|| get_extensions(egl, egl::NO_DISPLAY));

// Create a EGL display by chaining all display creation functions aborting on
// `EGL_BAD_ATTRIBUTE`.
let display = Self::get_platform_display(egl, raw_display)
let display = match Self::get_platform_display(egl, &raw_display)
.or_else(|err| {
if err.error_kind() == ErrorKind::BadAttribute {
Err(err)
} else {
Self::get_platform_display_ext(egl, raw_display)
Self::get_platform_display_ext(egl, &raw_display)
}
})
.or_else(|err| {
if err.error_kind() == ErrorKind::BadAttribute {
Err(err)
} else {
Self::get_display(egl, raw_display)
Self::get_display(egl, &raw_display)
}
})?;
}) {
Ok(display) => display,
Err(err) => return Err((err, raw_display).into()),
};

Self::initialize_display(egl, display, Some(raw_display))
Self::initialize_display(egl, display, Some(raw_display)).map_err(|e| e.unwrap())
}

/// Create an EGL display using the specified device.
Expand Down Expand Up @@ -145,7 +154,7 @@ impl<D: HasDisplayHandle> Display<D> {
})
.map(EglDisplay::Ext)?;

Self::initialize_display(egl, display, None)
Self::initialize_display(egl, display, None).map_err(Into::into)
}

/// Get the [`Device`] the display is using.
Expand Down Expand Up @@ -188,7 +197,7 @@ impl<D: HasDisplayHandle> Display<D> {
Device::from_ptr(self.inner.egl, device)
}

fn get_platform_display(egl: &Egl, display: D) -> Result<EglDisplay> {
fn get_platform_display(egl: &Egl, display: &D) -> Result<EglDisplay> {
if !egl.GetPlatformDisplay.is_loaded() {
return Err(ErrorKind::NotSupported("eglGetPlatformDisplay is not supported").into());
}
Expand Down Expand Up @@ -236,7 +245,7 @@ impl<D: HasDisplayHandle> Display<D> {
Self::check_display_error(display).map(EglDisplay::Khr)
}

fn get_platform_display_ext(egl: &Egl, display: D) -> Result<EglDisplay> {
fn get_platform_display_ext(egl: &Egl, display: &D) -> Result<EglDisplay> {
if !egl.GetPlatformDisplayEXT.is_loaded() {
return Err(ErrorKind::NotSupported("eglGetPlatformDisplayEXT is not supported").into());
}
Expand Down Expand Up @@ -306,7 +315,7 @@ impl<D: HasDisplayHandle> Display<D> {
})
}

fn get_display(egl: &Egl, display: D) -> Result<EglDisplay> {
fn get_display(egl: &Egl, display: &D) -> Result<EglDisplay> {
let mut display = match display.display_handle()?.raw_display_handle()? {
RawDisplayHandle::Gbm(handle) => handle.gbm_device,
#[cfg(x11_platform)]
Expand Down Expand Up @@ -374,11 +383,15 @@ impl<D: HasDisplayHandle> Display<D> {
egl: &'static Egl,
display: EglDisplay,
handle: Option<D>,
) -> Result<Self> {
) -> DisplayResult<Self, Option<D>> {
let version = unsafe {
let (mut major, mut minor) = (0, 0);
if egl.Initialize(*display, &mut major, &mut minor) == egl::FALSE {
return Err(super::check_error().expect_err("eglInit failed without a reason"));
return Err((
super::check_error().expect_err("eglInit failed without a reason"),
handle,
)
.into());
}

Version::new(major as u8, minor as u8)
Expand Down
2 changes: 1 addition & 1 deletion glutin/src/api/glx/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ impl<D: HasDisplayHandle> Display<D> {

// Add visual if was provided.
if let Some(RawWindowHandle::Xlib(window)) =
template.native_window.map(|w| w.window_handle()?.raw_window_handle()).transpose()?
template._native_window.map(|w| w.window_handle()?.raw_window_handle()).transpose()?
{
if window.visual_id > 0 {
config_attributes.push(glx::VISUAL_ID as c_int);
Expand Down
55 changes: 36 additions & 19 deletions glutin/src/api/glx/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ use raw_window_handle::{HasDisplayHandle, HasRawDisplayHandle, HasWindowHandle,

use crate::config::ConfigTemplate;
use crate::context::Version;
use crate::display::{AsRawDisplay, DisplayFeatures, GetDisplayExtensions, RawDisplay};
use crate::display::{
AsRawDisplay, DisplayFeatures, DisplayResult, GetDisplayExtensions, RawDisplay,
};
use crate::error::{ErrorKind, Result};
use crate::prelude::*;
use crate::private::Sealed;
Expand All @@ -39,25 +41,36 @@ impl<D> Clone for Display<D> {
impl<D: HasDisplayHandle> Display<D> {
/// Create GLX display.
pub fn new(display_handle: D, error_hook_registrar: XlibErrorHookRegistrar) -> Result<Self> {
Self::new_with_display(display_handle, error_hook_registrar).map_err(Into::into)
}

pub(crate) fn new_with_display(
display_handle: D,
error_hook_registrar: XlibErrorHookRegistrar,
) -> DisplayResult<Self, D> {
// Don't load GLX when unsupported platform was requested.
let (display, screen) = match display_handle.display_handle()?.raw_display_handle()? {
RawDisplayHandle::Xlib(handle) => {
if handle.display.is_null() {
return Err(ErrorKind::BadDisplay.into());
}

(GlxDisplay(handle.display as *mut _), handle.screen as i32)
},
_ => {
return Err(
ErrorKind::NotSupported("provided native display isn't supported").into()
)
},
};
let (display, screen) =
match display_handle.display_handle().and_then(|w| w.raw_display_handle()) {
Ok(RawDisplayHandle::Xlib(handle)) => {
if handle.display.is_null() {
return Err((ErrorKind::BadDisplay, display_handle).into());
}

(GlxDisplay(handle.display as *mut _), handle.screen as i32)
},
Ok(_) => {
return Err((
ErrorKind::NotSupported("provided native display isn't supported"),
display_handle,
)
.into())
},
Err(e) => return Err((crate::error::Error::from(e), display_handle).into()),
};

let glx = match GLX.as_ref() {
Some(glx) => glx,
None => return Err(ErrorKind::NotFound.into()),
None => return Err((ErrorKind::NotFound, display_handle).into()),
};

// Set the base for errors coming from GLX.
Expand All @@ -66,7 +79,7 @@ impl<D: HasDisplayHandle> Display<D> {
let mut event_base = 0;
if glx.QueryExtension(display.0, &mut error_base, &mut event_base) == 0 {
// The glx extension isn't present.
return Err(ErrorKind::InitializationFailed.into());
return Err((ErrorKind::InitializationFailed, display_handle).into());
}
GLX_BASE_ERROR.store(error_base, Ordering::Relaxed);
}
Expand All @@ -82,13 +95,17 @@ impl<D: HasDisplayHandle> Display<D> {
let version = unsafe {
let (mut major, mut minor) = (0, 0);
if glx.QueryVersion(display.0, &mut major, &mut minor) == 0 {
return Err(ErrorKind::InitializationFailed.into());
return Err((ErrorKind::InitializationFailed, display_handle).into());
}
Version::new(major as u8, minor as u8)
};

if version < Version::new(1, 3) {
return Err(ErrorKind::NotSupported("the glx below 1.3 isn't supported").into());
return Err((
ErrorKind::NotSupported("the glx below 1.3 isn't supported"),
display_handle,
)
.into());
}

// Register the error handling hook.
Expand Down
Loading

0 comments on commit bcf2996

Please sign in to comment.