egl: force surface creation on resume

This commit is contained in:
Victor Brekenfeld 2020-05-03 17:58:01 +02:00
parent 140185f6f5
commit a6863af496
2 changed files with 17 additions and 7 deletions

View File

@ -11,7 +11,7 @@ use std::rc::{Rc, Weak};
use super::{EglDevice, EglSurfaceInternal}; use super::{EglDevice, EglSurfaceInternal};
use crate::backend::drm::{Device, Surface}; use crate::backend::drm::{Device, Surface};
use crate::backend::egl::native::{Backend, NativeDisplay, NativeSurface}; use crate::backend::egl::{ffi, native::{Backend, NativeDisplay, NativeSurface}};
use crate::backend::session::{AsSessionObserver, SessionObserver}; use crate::backend::session::{AsSessionObserver, SessionObserver};
/// [`SessionObserver`](SessionObserver) /// [`SessionObserver`](SessionObserver)
@ -50,5 +50,15 @@ impl<S: SessionObserver + 'static, N: NativeSurface + Surface> SessionObserver f
fn activate(&mut self, devnum: Option<(u32, u32, Option<RawFd>)>) { fn activate(&mut self, devnum: Option<(u32, u32, Option<RawFd>)>) {
self.observer.activate(devnum); self.observer.activate(devnum);
if let Some(backends) = self.backends.upgrade() {
for (_crtc, backend) in backends.borrow().iter() {
if let Some(backend) = backend.upgrade() {
let old_surface = backend.surface.surface.replace(std::ptr::null());
if !old_surface.is_null() {
unsafe { ffi::egl::DestroySurface(**backend.surface.display, old_surface as *const _); }
}
}
}
}
} }
} }

View File

@ -12,7 +12,7 @@ use std::{
/// EGL surface of a given EGL context for rendering /// EGL surface of a given EGL context for rendering
pub struct EGLSurface<N: native::NativeSurface> { pub struct EGLSurface<N: native::NativeSurface> {
display: Arc<EGLDisplayHandle>, pub(crate) display: Arc<EGLDisplayHandle>,
native: N, native: N,
pub(crate) surface: Cell<ffi::egl::types::EGLSurface>, pub(crate) surface: Cell<ffi::egl::types::EGLSurface>,
config_id: ffi::egl::types::EGLConfig, config_id: ffi::egl::types::EGLConfig,
@ -90,9 +90,7 @@ impl<N: native::NativeSurface> EGLSurface<N> {
wrap_egl_call(|| unsafe { ffi::egl::SwapBuffers(**self.display, surface as *const _) }) wrap_egl_call(|| unsafe { ffi::egl::SwapBuffers(**self.display, surface as *const _) })
.map_err(SwapBuffersError::EGLSwapBuffers) .map_err(SwapBuffersError::EGLSwapBuffers)
.and_then(|_| self.native.swap_buffers().map_err(SwapBuffersError::Underlying)) .and_then(|_| self.native.swap_buffers().map_err(SwapBuffersError::Underlying))
} else { } else { Err(SwapBuffersError::EGLSwapBuffers(EGLError::BadSurface)) };
Ok(())
};
// workaround for missing `PartialEq` impl // workaround for missing `PartialEq` impl
let is_bad_surface = if let Err(SwapBuffersError::EGLSwapBuffers(EGLError::BadSurface)) = result { let is_bad_surface = if let Err(SwapBuffersError::EGLSwapBuffers(EGLError::BadSurface)) = result {
@ -117,10 +115,12 @@ impl<N: native::NativeSurface> EGLSurface<N> {
}) })
.map_err(SwapBuffersError::EGLCreateWindowSurface)? .map_err(SwapBuffersError::EGLCreateWindowSurface)?
}); });
}
result.map_err(|_| SwapBuffersError::EGLSwapBuffers(EGLError::BadSurface))
} else {
result result
} }
}
/// Returns true if the OpenGL surface is the current one in the thread. /// Returns true if the OpenGL surface is the current one in the thread.
pub fn is_current(&self) -> bool { pub fn is_current(&self) -> bool {