Skip to content

Commit

Permalink
egl: fix handling of *_base platform
Browse files Browse the repository at this point in the history
The `Create{Window,Surface}` functions are tied to the display we've
used. So make `EglDisplay` an enum represeting `Khr`, `Ext`, and
`Legacy` variants, this fixes potential issues of using a method
we shouldn't be using.
  • Loading branch information
kchibisov authored Feb 12, 2023
1 parent 154ee0c commit 45d6e93
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 35 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Unreleased

- Fixed handling of `*_base` extensions with EGL.

# Version 0.30.5

- Fixed EGL/GLX display initialization when the provided raw-window-handle has an unknown visual_id.
Expand Down
42 changes: 28 additions & 14 deletions glutin/src/api/egl/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ impl Display {
device.raw_device() as *mut _,
attrs.as_ptr(),
)
})?;
})
.map(EglDisplay::Ext)?;

Self::initialize_display(egl, display, None)
}
Expand All @@ -166,7 +167,7 @@ impl Display {
let device = ptr::null_mut();
if unsafe {
self.inner.egl.QueryDisplayAttribEXT(
self.inner.raw.0,
*self.inner.raw,
egl::DEVICE_EXT as EGLint,
device as *mut _,
)
Expand All @@ -183,7 +184,7 @@ impl Display {
Device::from_ptr(self.inner.egl, device)
}

fn get_platform_display(egl: &Egl, display: RawDisplayHandle) -> Result<EGLDisplay> {
fn get_platform_display(egl: &Egl, display: RawDisplayHandle) -> Result<EglDisplay> {
if !egl.GetPlatformDisplay.is_loaded() {
return Err(ErrorKind::NotSupported("eglGetPlatformDisplay is not supported").into());
}
Expand Down Expand Up @@ -228,10 +229,10 @@ impl Display {
let display =
unsafe { egl.GetPlatformDisplay(platform, display as *mut _, attrs.as_ptr()) };

Self::check_display_error(display)
Self::check_display_error(display).map(EglDisplay::Khr)
}

fn get_platform_display_ext(egl: &Egl, display: RawDisplayHandle) -> Result<EGLDisplay> {
fn get_platform_display_ext(egl: &Egl, display: RawDisplayHandle) -> Result<EglDisplay> {
if !egl.GetPlatformDisplayEXT.is_loaded() {
return Err(ErrorKind::NotSupported("eglGetPlatformDisplayEXT is not supported").into());
}
Expand Down Expand Up @@ -282,10 +283,10 @@ impl Display {
let display =
unsafe { egl.GetPlatformDisplayEXT(platform, display as *mut _, attrs.as_ptr()) };

Self::check_display_error(display)
Self::check_display_error(display).map(EglDisplay::Ext)
}

fn get_display(egl: &Egl, display: RawDisplayHandle) -> Result<EGLDisplay> {
fn get_display(egl: &Egl, display: RawDisplayHandle) -> Result<EglDisplay> {
let mut display = match display {
RawDisplayHandle::Gbm(handle) => handle.gbm_device,
#[cfg(x11_platform)]
Expand All @@ -303,7 +304,7 @@ impl Display {
}

let display = unsafe { egl.GetDisplay(display) };
Self::check_display_error(display)
Self::check_display_error(display).map(EglDisplay::Legacy)
}

fn extract_display_features(
Expand Down Expand Up @@ -347,25 +348,25 @@ impl Display {

fn initialize_display(
egl: &'static Egl,
display: EGLDisplay,
display: EglDisplay,
raw_display_handle: Option<RawDisplayHandle>,
) -> Result<Self> {
let version = unsafe {
let (mut major, mut minor) = (0, 0);
if egl.Initialize(display, &mut major, &mut minor) == egl::FALSE {
if egl.Initialize(*display, &mut major, &mut minor) == egl::FALSE {
return Err(super::check_error().err().unwrap());
}

Version::new(major as u8, minor as u8)
};

// Load extensions.
let client_extensions = get_extensions(egl, display);
let client_extensions = get_extensions(egl, *display);
let features = Self::extract_display_features(&client_extensions, version);

let inner = Arc::new(DisplayInner {
egl,
raw: EglDisplay(display),
raw: display,
_native_display: raw_display_handle.map(NativeDisplay),
version,
client_extensions,
Expand Down Expand Up @@ -551,7 +552,16 @@ impl Deref for NativeDisplay {
}

#[derive(Debug, Clone)]
pub(crate) struct EglDisplay(EGLDisplay);
pub(crate) enum EglDisplay {
/// The display was created with the KHR extension.
Khr(EGLDisplay),

/// The display was created with the EXT extension.
Ext(EGLDisplay),

/// The display in use is a legacy variant.
Legacy(EGLDisplay),
}

// The EGL display could be shared between threads.
unsafe impl Send for EglDisplay {}
Expand All @@ -561,7 +571,11 @@ impl Deref for EglDisplay {
type Target = EGLDisplay;

fn deref(&self) -> &Self::Target {
&self.0
match self {
EglDisplay::Khr(display) => display,
EglDisplay::Ext(display) => display,
EglDisplay::Legacy(display) => display,
}
}
}

Expand Down
42 changes: 21 additions & 21 deletions glutin/src/api/egl/surface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use raw_window_handle::RawWindowHandle;
#[cfg(wayland_platform)]
use wayland_sys::{egl::*, ffi_dispatch};

use crate::api::egl::display::EglDisplay;
use crate::config::GetGlConfig;
use crate::context::Version;
use crate::display::GetGlDisplay;
use crate::error::{ErrorKind, Result};
use crate::prelude::*;
Expand Down Expand Up @@ -97,34 +97,34 @@ impl Display {
attrs.push(egl::NONE as EGLAttrib);

let config = config.clone();
let surface = unsafe {
if self.inner.version >= Version::new(1, 5)
&& self.inner.egl.CreatePlatformWindowSurface.is_loaded()
{
let surface = match self.inner.raw {
EglDisplay::Khr(display) => unsafe {
self.inner.egl.CreatePlatformPixmapSurface(
*self.inner.raw,
display,
*config.inner.raw,
native_pixmap.as_ptr(),
attrs.as_ptr(),
)
} else if self.inner.client_extensions.contains("EGL_EXT_platform_base") {
},
EglDisplay::Ext(display) => unsafe {
let attrs: Vec<EGLint> = attrs.into_iter().map(|attr| attr as EGLint).collect();
self.inner.egl.CreatePlatformPixmapSurfaceEXT(
*self.inner.raw,
display,
*config.inner.raw,
native_pixmap.as_ptr(),
attrs.as_ptr(),
)
} else {
},
EglDisplay::Legacy(display) => unsafe {
// This call accepts raw value, instead of pointer.
let attrs: Vec<EGLint> = attrs.into_iter().map(|attr| attr as EGLint).collect();
self.inner.egl.CreatePixmapSurface(
*self.inner.raw,
display,
*config.inner.raw,
*(native_pixmap.as_ptr() as *const egl::NativePixmapType),
attrs.as_ptr(),
)
}
},
};

let surface = Self::check_surface_error(surface)?;
Expand Down Expand Up @@ -175,34 +175,34 @@ impl Display {

let config = config.clone();

let surface = unsafe {
if self.inner.version >= Version::new(1, 5)
&& self.inner.egl.CreatePlatformWindowSurface.is_loaded()
{
let surface = match self.inner.raw {
EglDisplay::Khr(display) => unsafe {
self.inner.egl.CreatePlatformWindowSurface(
*self.inner.raw,
display,
*config.inner.raw,
native_window.as_ptr().cast(),
attrs.as_ptr(),
)
} else if self.inner.client_extensions.contains("EGL_EXT_platform_base") {
},
EglDisplay::Ext(display) => unsafe {
let attrs: Vec<EGLint> = attrs.into_iter().map(|attr| attr as EGLint).collect();
self.inner.egl.CreatePlatformWindowSurfaceEXT(
*self.inner.raw,
display,
*config.inner.raw,
native_window.as_ptr().cast(),
attrs.as_ptr(),
)
} else {
},
EglDisplay::Legacy(display) => unsafe {
let attrs: Vec<EGLint> = attrs.into_iter().map(|attr| attr as EGLint).collect();
// This call accepts raw value, instead of pointer.
self.inner.egl.CreateWindowSurface(
*self.inner.raw,
display,
*config.inner.raw,
*(native_window.as_ptr() as *const egl::NativeWindowType),
attrs.as_ptr(),
)
}
},
};

let surface = Self::check_surface_error(surface)?;
Expand Down

0 comments on commit 45d6e93

Please sign in to comment.