egl: Optionally support buffer age and damage

This commit is contained in:
Victor Brekenfeld 2021-12-29 15:54:59 +01:00
parent 3530ac7335
commit f423244864
3 changed files with 35 additions and 3 deletions

View file

@ -35,6 +35,8 @@ fn gl_generate() {
"EGL_KHR_image_base",
"EGL_EXT_image_dma_buf_import",
"EGL_EXT_image_dma_buf_import_modifiers",
"EGL_EXT_buffer_age",
"EGL_EXT_swap_buffers_with_damage",
],
)
.write_bindings(gl_generator::GlobalGenerator, &mut file)

View file

@ -1,6 +1,7 @@
//! Type safe native types for safe context/surface creation
use super::{display::EGLDisplayHandle, ffi, wrap_egl_call, EGLDevice, SwapBuffersError};
use crate::utils::{Physical, Rectangle};
#[cfg(feature = "backend_winit")]
use std::os::raw::c_int;
use std::os::raw::c_void;
@ -246,9 +247,19 @@ pub unsafe trait EGLNativeSurface: Send + Sync {
&self,
display: &Arc<EGLDisplayHandle>,
surface: ffi::egl::types::EGLSurface,
damage: Option<&mut [Rectangle<i32, Physical>]>,
) -> Result<(), SwapBuffersError> {
wrap_egl_call(|| unsafe {
ffi::egl::SwapBuffers(***display, surface as *const _);
if let Some(damage) = damage {
ffi::egl::SwapBuffersWithDamageEXT(
***display,
surface as *const _,
damage.as_mut_ptr() as *mut _,
damage.len() as i32,
);
} else {
ffi::egl::SwapBuffers(***display, surface as *const _);
}
})
.map_err(SwapBuffersError::EGLSwapBuffers)
}

View file

@ -12,6 +12,7 @@ use crate::backend::egl::{
native::EGLNativeSurface,
EGLError, SwapBuffersError,
};
use crate::utils::{Physical, Rectangle};
use slog::{debug, o};
@ -79,12 +80,30 @@ impl EGLSurface {
})
}
/// Returns the buffer age of the underlying back buffer
pub fn buffer_age(&self) -> i32 {
let surface = self.surface.load(Ordering::SeqCst);
let mut age = 0;
unsafe {
ffi::egl::QuerySurface(
**self.display,
surface as *const _,
ffi::egl::BUFFER_AGE_EXT as i32,
&mut age as *mut _,
);
}
age
}
/// Swaps buffers at the end of a frame.
pub fn swap_buffers(&self) -> ::std::result::Result<(), SwapBuffersError> {
pub fn swap_buffers(
&self,
damage: Option<&mut [Rectangle<i32, Physical>]>,
) -> ::std::result::Result<(), SwapBuffersError> {
let surface = self.surface.load(Ordering::SeqCst);
let result = if !surface.is_null() {
self.native.swap_buffers(&self.display, surface)
self.native.swap_buffers(&self.display, surface, damage)
} else {
Err(SwapBuffersError::EGLSwapBuffers(EGLError::BadSurface))
};