diff --git a/build.rs b/build.rs index 5ebcb19bb2..a8585acad0 100644 --- a/build.rs +++ b/build.rs @@ -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) diff --git a/src/backend/egl/native.rs b/src/backend/egl/native.rs index 097c2062b2..1219c39da0 100644 --- a/src/backend/egl/native.rs +++ b/src/backend/egl/native.rs @@ -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, surface: ffi::egl::types::EGLSurface, + damage: Option<&mut [Rectangle]>, ) -> 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) } diff --git a/src/backend/egl/surface.rs b/src/backend/egl/surface.rs index 0070ff4ac7..20f51134f9 100644 --- a/src/backend/egl/surface.rs +++ b/src/backend/egl/surface.rs @@ -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]>, + ) -> ::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)) };