mirror of
https://github.com/Smithay/smithay.git
synced 2024-09-28 03:21:14 +02:00
egl: Allow both EXT/KHR impls for SwapBuffers to be used
This commit is contained in:
parent
1dbf532428
commit
3680fb9b90
5 changed files with 74 additions and 13 deletions
1
build.rs
1
build.rs
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 _);
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
};
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue