egl: Allow both EXT/KHR impls for SwapBuffers to be used

This commit is contained in:
Victoria Brekenfeld 2022-10-21 20:21:45 +02:00
parent 1dbf532428
commit 3680fb9b90
5 changed files with 74 additions and 13 deletions

View file

@ -40,6 +40,7 @@ fn gl_generate() {
"EGL_KHR_gl_image",
"EGL_EXT_buffer_age",
"EGL_EXT_swap_buffers_with_damage",
"EGL_KHR_swap_buffers_with_damage",
],
)
.write_bindings(gl_generator::GlobalGenerator, &mut file)

View file

@ -517,6 +517,32 @@ impl EGLDisplay {
&self.dmabuf_import_formats
}
/// Returns when the display supports extensions required for smithays
/// damage tracking helpers.
pub fn supports_damage(&self) -> bool {
self.supports_damage_impl().supported()
}
pub(super) fn supports_damage_impl(&self) -> DamageSupport {
if self.extensions.iter().any(|ext| ext == "EGL_EXT_buffer_age") {
if self
.extensions
.iter()
.any(|ext| ext == "EGL_KHR_swap_buffers_with_damage")
{
return DamageSupport::KHR;
} else if self
.extensions
.iter()
.any(|ext| ext == "EGL_EXT_swap_buffers_with_damage")
{
return DamageSupport::EXT;
}
}
DamageSupport::No
}
/// Exports an [`EGLImage`] as a [`Dmabuf`]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub fn create_dmabuf_from_image(
@ -1110,3 +1136,24 @@ pub struct PixelFormat {
/// is srgb enabled
pub srgb: bool,
}
/// Denotes if damage tracking is supported.
///
/// Additionally notes which variant of the `EGL_*_swap_buffers_with_damage` extension was found.
/// Prefers `KHR` over `EXT`, if both are available.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum DamageSupport {
/// `EGL_KHR_swap_buffers_with_damage`
KHR,
/// `EGL_EXT_swap_buffers_with_damage`
EXT,
/// Some required extensions are missing
No,
}
impl DamageSupport {
/// Returns true, if any valid combination of required extensions was found.
pub fn supported(&self) -> bool {
self != &DamageSupport::No
}
}

View file

@ -1,6 +1,9 @@
//! Type safe native types for safe context/surface creation
use super::{display::EGLDisplayHandle, ffi, wrap_egl_call, EGLDevice, SwapBuffersError};
use super::{
display::{DamageSupport, EGLDisplayHandle},
ffi, wrap_egl_call, EGLDevice, SwapBuffersError,
};
use crate::utils::{Physical, Rectangle};
#[cfg(feature = "backend_winit")]
use std::os::raw::c_int;
@ -248,15 +251,25 @@ pub unsafe trait EGLNativeSurface: Send {
display: &Arc<EGLDisplayHandle>,
surface: ffi::egl::types::EGLSurface,
damage: Option<&mut [Rectangle<i32, Physical>]>,
damage_impl: DamageSupport,
) -> Result<(), SwapBuffersError> {
wrap_egl_call(|| unsafe {
if let Some(damage) = damage {
ffi::egl::SwapBuffersWithDamageEXT(
***display,
surface as *const _,
damage.as_mut_ptr() as *mut _,
damage.len() as i32,
);
match damage_impl {
DamageSupport::KHR => ffi::egl::SwapBuffersWithDamageKHR(
***display,
surface as *const _,
damage.as_mut_ptr() as *mut _,
damage.len() as i32,
),
DamageSupport::EXT => ffi::egl::SwapBuffersWithDamageEXT(
***display,
surface as *const _,
damage.as_mut_ptr() as *mut _,
damage.len() as i32,
),
DamageSupport::No => ffi::egl::SwapBuffers(***display, surface as *const _),
};
} else {
ffi::egl::SwapBuffers(***display, surface as *const _);
}

View file

@ -7,7 +7,7 @@ use std::sync::{
};
use crate::backend::egl::{
display::{EGLDisplay, EGLDisplayHandle, PixelFormat},
display::{DamageSupport, EGLDisplay, EGLDisplayHandle, PixelFormat},
ffi,
native::EGLNativeSurface,
EGLError, SwapBuffersError,
@ -23,6 +23,7 @@ pub struct EGLSurface {
pub(crate) surface: AtomicPtr<nix::libc::c_void>,
config_id: ffi::egl::types::EGLConfig,
pixel_format: PixelFormat,
damage_impl: DamageSupport,
logger: ::slog::Logger,
}
@ -76,6 +77,7 @@ impl EGLSurface {
surface: AtomicPtr::new(surface as *mut _),
config_id: config,
pixel_format,
damage_impl: display.supports_damage_impl(),
logger: log,
})
}
@ -147,7 +149,8 @@ impl EGLSurface {
let surface = self.surface.load(Ordering::SeqCst);
let result = if !surface.is_null() {
self.native.swap_buffers(&self.display, surface, damage)
self.native
.swap_buffers(&self.display, surface, damage, self.damage_impl)
} else {
Err(SwapBuffersError::EGLSwapBuffers(EGLError::BadSurface))
};

View file

@ -229,10 +229,7 @@ where
let egl = Rc::new(surface);
let renderer = unsafe { Gles2Renderer::new(context, log.clone())? };
let resize_notification = Rc::new(Cell::new(None));
let damage_tracking = display.extensions().iter().any(|ext| ext == "EGL_EXT_buffer_age")
&& display.extensions().iter().any(|ext| {
ext == "EGL_KHR_swap_buffers_with_damage" || ext == "EGL_EXT_swap_buffers_with_damage"
});
let damage_tracking = display.supports_damage();
Ok((
WinitGraphicsBackend {