diff --git a/src/backend/drm/gbm/egl.rs b/src/backend/drm/gbm/egl.rs index 5fef49c..2f6d908 100644 --- a/src/backend/drm/gbm/egl.rs +++ b/src/backend/drm/gbm/egl.rs @@ -5,15 +5,17 @@ //! use crate::backend::drm::{Device, RawDevice, Surface}; -use crate::backend::egl::ffi; use crate::backend::egl::native::{Backend, NativeDisplay, NativeSurface}; +use crate::backend::egl::{display::EGLDisplayHandle, ffi}; use crate::backend::egl::{wrap_egl_call, EGLError, Error as EglBackendError}; use super::{Error, GbmDevice, GbmSurface}; use drm::control::{connector, crtc, Device as ControlDevice, Mode}; use gbm::AsRaw; +use nix::libc::{c_int, c_void}; use std::marker::PhantomData; +use std::ptr; /// Egl Gbm backend type /// @@ -80,10 +82,18 @@ unsafe impl NativeDisplay> for Gb } unsafe impl NativeSurface for GbmSurface { - type Error = Error<<::Surface as Surface>::Error>; - - fn ptr(&self) -> ffi::NativeWindowType { - self.0.surface.borrow().as_raw() as *const _ + unsafe fn create( + &self, + display: &EGLDisplayHandle, + config_id: ffi::egl::types::EGLConfig, + surface_attributes: &[c_int], + ) -> *const c_void { + ffi::egl::CreateWindowSurface( + display.handle, + config_id, + self.0.surface.borrow().as_raw() as *const _, + surface_attributes.as_ptr(), + ) } fn needs_recreation(&self) -> bool { diff --git a/src/backend/egl/display.rs b/src/backend/egl/display.rs index 5af7b61..9ac488d 100644 --- a/src/backend/egl/display.rs +++ b/src/backend/egl/display.rs @@ -30,8 +30,9 @@ use std::ops::Deref; /// Wrapper around [`ffi::EGLDisplay`](ffi::egl::types::EGLDisplay) to ensure display is only destroyed /// once all resources bound to it have been dropped. -pub(crate) struct EGLDisplayHandle { - handle: ffi::egl::types::EGLDisplay, +pub struct EGLDisplayHandle { + /// ffi EGLDisplay ptr + pub handle: ffi::egl::types::EGLDisplay, } impl Deref for EGLDisplayHandle { diff --git a/src/backend/egl/native.rs b/src/backend/egl/native.rs index 28dcd70..201f8ea 100644 --- a/src/backend/egl/native.rs +++ b/src/backend/egl/native.rs @@ -1,6 +1,7 @@ //! Type safe native types for safe context/surface creation -use super::{ffi, wrap_egl_call, EGLError, Error}; +use super::{display::EGLDisplayHandle, ffi, wrap_egl_call, EGLError, Error, SurfaceCreationError}; +use nix::libc::{c_int, c_void}; #[cfg(feature = "backend_winit")] use wayland_egl as wegl; @@ -200,8 +201,13 @@ pub unsafe trait NativeSurface { /// Error of the underlying surface type Error: std::error::Error; - /// Return a raw pointer egl will accept for surface creation. - fn ptr(&self) -> ffi::NativeWindowType; + /// Create an EGLSurface from the internal native type + unsafe fn create( + &self, + display: &EGLDisplayHandle, + config_id: ffi::egl::types::EGLConfig, + surface_attributes: &[c_int], + ) -> Result<*const c_void, SurfaceCreationError>; /// Will be called to check if any internal resources will need /// to be recreated. Old resources must be used until `recreate` @@ -247,8 +253,21 @@ unsafe impl NativeSurface for XlibWindow { // type Error = !; (https://github.com/rust-lang/rust/issues/35121) type Error = Never; - fn ptr(&self) -> ffi::NativeWindowType { - self.0 as *const _ + unsafe fn create( + &self, + display: &EGLDisplayHandle, + config_id: ffi::egl::types::EGLConfig, + surface_attributes: &[c_int], + ) -> Result<*const c_void, SurfaceCreationError> { + wrap_egl_call(|| { + ffi::egl::CreateWindowSurface( + display.handle, + config_id, + self.0 as *const _, + surface_attributes.as_ptr(), + ) + }) + .map_err(SurfaceCreationError::EGLSurfaceCreationFailed) } } @@ -257,7 +276,20 @@ unsafe impl NativeSurface for wegl::WlEglSurface { // type Error = !; type Error = Never; - fn ptr(&self) -> ffi::NativeWindowType { - self.ptr() as *const _ + unsafe fn create( + &self, + display: &EGLDisplayHandle, + config_id: ffi::egl::types::EGLConfig, + surface_attributes: &[c_int], + ) -> Result<*const c_void, SurfaceCreationError> { + wrap_egl_call(|| { + ffi::egl::CreateWindowSurface( + display.handle, + config_id, + self.ptr() as *const _, + surface_attributes.as_ptr(), + ) + }) + .map_err(SurfaceCreationError::EGLSurfaceCreationFailed) } } diff --git a/src/backend/egl/surface.rs b/src/backend/egl/surface.rs index 3ba5f32..0a36f8f 100644 --- a/src/backend/egl/surface.rs +++ b/src/backend/egl/surface.rs @@ -69,9 +69,7 @@ impl EGLSurface { out }; - let surface = wrap_egl_call(|| unsafe { - ffi::egl::CreateWindowSurface(**display, config, native.ptr(), surface_attributes.as_ptr()) - })?; + let surface = unsafe { native.create(&*display, config, &surface_attributes)? }; if surface == ffi::egl::NO_SURFACE { return Err(EGLError::BadSurface); @@ -112,16 +110,12 @@ impl EGLSurface { if !surface.is_null() { let _ = unsafe { ffi::egl::DestroySurface(**self.display, surface as *const _) }; } + //TODO remove recreate + self.native.recreate(); self.surface.set(unsafe { - wrap_egl_call(|| { - ffi::egl::CreateWindowSurface( - **self.display, - self.config_id, - self.native.ptr(), - self.surface_attributes.as_ptr(), - ) - }) - .map_err(SwapBuffersError::EGLCreateWindowSurface)? + self.native + .create(&*self.display, self.config_id, &self.surface_attributes) + .map_err(SwapBuffersError::EGLCreateWindowSurface)? }); result.map_err(|err| {