egl: move surface creation into `NativeSurface`
This commit is contained in:
parent
4647141770
commit
0267703e91
|
@ -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<D: RawDevice + ControlDevice + 'static> NativeDisplay<Gbm<D>> for Gb
|
|||
}
|
||||
|
||||
unsafe impl<D: RawDevice + 'static> NativeSurface for GbmSurface<D> {
|
||||
type Error = Error<<<D as RawDevice>::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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<Self::Error>>;
|
||||
|
||||
/// 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<Never>> {
|
||||
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<Never>> {
|
||||
wrap_egl_call(|| {
|
||||
ffi::egl::CreateWindowSurface(
|
||||
display.handle,
|
||||
config_id,
|
||||
self.ptr() as *const _,
|
||||
surface_attributes.as_ptr(),
|
||||
)
|
||||
})
|
||||
.map_err(SurfaceCreationError::EGLSurfaceCreationFailed)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,9 +69,7 @@ impl<N: native::NativeSurface> EGLSurface<N> {
|
|||
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,15 +110,11 @@ impl<N: native::NativeSurface> EGLSurface<N> {
|
|||
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(),
|
||||
)
|
||||
})
|
||||
self.native
|
||||
.create(&*self.display, self.config_id, &self.surface_attributes)
|
||||
.map_err(SwapBuffersError::EGLCreateWindowSurface)?
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue