egl: allow display creation to specify attributes

This commit is contained in:
Victor Brekenfeld 2020-04-22 22:10:15 +02:00
parent 1a39c208c4
commit 726624cbd8
3 changed files with 41 additions and 13 deletions

View File

@ -14,7 +14,6 @@ use super::{Error, GbmDevice, GbmSurface};
use drm::control::{connector, crtc, Device as ControlDevice, Mode}; use drm::control::{connector, crtc, Device as ControlDevice, Mode};
use gbm::AsRaw; use gbm::AsRaw;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::ptr;
/// Egl Gbm backend type /// Egl Gbm backend type
/// ///
@ -28,6 +27,7 @@ impl<D: RawDevice + 'static> Backend for Gbm<D> {
unsafe fn get_display<F>( unsafe fn get_display<F>(
display: ffi::NativeDisplayType, display: ffi::NativeDisplayType,
attribs: &[ffi::EGLint],
has_dp_extension: F, has_dp_extension: F,
log: ::slog::Logger, log: ::slog::Logger,
) -> Result<ffi::egl::types::EGLDisplay, EGLError> ) -> Result<ffi::egl::types::EGLDisplay, EGLError>
@ -36,18 +36,24 @@ impl<D: RawDevice + 'static> Backend for Gbm<D> {
{ {
if has_dp_extension("EGL_KHR_platform_gbm") && ffi::egl::GetPlatformDisplay::is_loaded() { if has_dp_extension("EGL_KHR_platform_gbm") && ffi::egl::GetPlatformDisplay::is_loaded() {
trace!(log, "EGL Display Initialization via EGL_KHR_platform_gbm"); trace!(log, "EGL Display Initialization via EGL_KHR_platform_gbm");
let attribs = attribs.iter().map(|x| *x as isize).collect::<Vec<_>>();
wrap_egl_call(|| { wrap_egl_call(|| {
ffi::egl::GetPlatformDisplay(ffi::egl::PLATFORM_GBM_KHR, display as *mut _, ptr::null()) ffi::egl::GetPlatformDisplay(ffi::egl::PLATFORM_GBM_KHR, display as *mut _, attribs.as_ptr())
}) })
} else if has_dp_extension("EGL_MESA_platform_gbm") && ffi::egl::GetPlatformDisplayEXT::is_loaded() { } else if has_dp_extension("EGL_MESA_platform_gbm") && ffi::egl::GetPlatformDisplayEXT::is_loaded() {
trace!(log, "EGL Display Initialization via EGL_MESA_platform_gbm"); trace!(log, "EGL Display Initialization via EGL_MESA_platform_gbm");
wrap_egl_call(|| { wrap_egl_call(|| {
ffi::egl::GetPlatformDisplayEXT(ffi::egl::PLATFORM_GBM_MESA, display as *mut _, ptr::null()) ffi::egl::GetPlatformDisplayEXT(
ffi::egl::PLATFORM_GBM_MESA,
display as *mut _,
attribs.as_ptr(),
)
}) })
} else if has_dp_extension("EGL_MESA_platform_gbm") && ffi::egl::GetPlatformDisplay::is_loaded() { } else if has_dp_extension("EGL_MESA_platform_gbm") && ffi::egl::GetPlatformDisplay::is_loaded() {
trace!(log, "EGL Display Initialization via EGL_MESA_platform_gbm"); trace!(log, "EGL Display Initialization via EGL_MESA_platform_gbm");
let attribs = attribs.iter().map(|x| *x as isize).collect::<Vec<_>>();
wrap_egl_call(|| { wrap_egl_call(|| {
ffi::egl::GetPlatformDisplay(ffi::egl::PLATFORM_GBM_MESA, display as *mut _, ptr::null()) ffi::egl::GetPlatformDisplay(ffi::egl::PLATFORM_GBM_MESA, display as *mut _, attribs.as_ptr())
}) })
} else { } else {
trace!(log, "Default EGL Display Initialization via GetDisplay"); trace!(log, "Default EGL Display Initialization via GetDisplay");

View File

@ -69,6 +69,7 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLDisplay<B, N> {
{ {
let log = crate::slog_or_stdlog(logger.into()).new(o!("smithay_module" => "renderer_egl")); let log = crate::slog_or_stdlog(logger.into()).new(o!("smithay_module" => "renderer_egl"));
let ptr = native.ptr()?; let ptr = native.ptr()?;
let egl_attribs = native.attributes();
ffi::egl::LOAD.call_once(|| unsafe { ffi::egl::LOAD.call_once(|| unsafe {
fn constrain<F>(f: F) -> F fn constrain<F>(f: F) -> F
@ -112,7 +113,12 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLDisplay<B, N> {
debug!(log, "EGL No-Display Extensions: {:?}", dp_extensions); debug!(log, "EGL No-Display Extensions: {:?}", dp_extensions);
let display = unsafe { let display = unsafe {
B::get_display(ptr, |e: &str| dp_extensions.iter().any(|s| s == e), log.clone()) B::get_display(
ptr,
&egl_attribs,
|e: &str| dp_extensions.iter().any(|s| s == e),
log.clone(),
)
.map_err(Error::DisplayNotSupported)? .map_err(Error::DisplayNotSupported)?
}; };

View File

@ -2,9 +2,6 @@
use super::{ffi, wrap_egl_call, EGLError, Error}; use super::{ffi, wrap_egl_call, EGLError, Error};
#[cfg(feature = "backend_winit")]
use std::ptr;
#[cfg(feature = "backend_winit")] #[cfg(feature = "backend_winit")]
use wayland_egl as wegl; use wayland_egl as wegl;
#[cfg(feature = "backend_winit")] #[cfg(feature = "backend_winit")]
@ -25,6 +22,7 @@ pub trait Backend {
/// but there is no way to test that. /// but there is no way to test that.
unsafe fn get_display<F: Fn(&str) -> bool>( unsafe fn get_display<F: Fn(&str) -> bool>(
display: ffi::NativeDisplayType, display: ffi::NativeDisplayType,
attribs: &[ffi::EGLint],
has_dp_extension: F, has_dp_extension: F,
log: ::slog::Logger, log: ::slog::Logger,
) -> Result<ffi::egl::types::EGLDisplay, EGLError>; ) -> Result<ffi::egl::types::EGLDisplay, EGLError>;
@ -39,6 +37,7 @@ impl Backend for Wayland {
unsafe fn get_display<F>( unsafe fn get_display<F>(
display: ffi::NativeDisplayType, display: ffi::NativeDisplayType,
attribs: &[ffi::EGLint],
has_dp_extension: F, has_dp_extension: F,
log: ::slog::Logger, log: ::slog::Logger,
) -> Result<ffi::egl::types::EGLDisplay, EGLError> ) -> Result<ffi::egl::types::EGLDisplay, EGLError>
@ -47,8 +46,13 @@ impl Backend for Wayland {
{ {
if has_dp_extension("EGL_KHR_platform_wayland") && ffi::egl::GetPlatformDisplay::is_loaded() { if has_dp_extension("EGL_KHR_platform_wayland") && ffi::egl::GetPlatformDisplay::is_loaded() {
trace!(log, "EGL Display Initialization via EGL_KHR_platform_wayland"); trace!(log, "EGL Display Initialization via EGL_KHR_platform_wayland");
let attribs = attribs.iter().map(|x| *x as isize).collect::<Vec<_>>();
wrap_egl_call(|| { wrap_egl_call(|| {
ffi::egl::GetPlatformDisplay(ffi::egl::PLATFORM_WAYLAND_KHR, display as *mut _, ptr::null()) ffi::egl::GetPlatformDisplay(
ffi::egl::PLATFORM_WAYLAND_KHR,
display as *mut _,
attribs.as_ptr(),
)
}) })
} else if has_dp_extension("EGL_EXT_platform_wayland") && ffi::egl::GetPlatformDisplayEXT::is_loaded() } else if has_dp_extension("EGL_EXT_platform_wayland") && ffi::egl::GetPlatformDisplayEXT::is_loaded()
{ {
@ -57,7 +61,7 @@ impl Backend for Wayland {
ffi::egl::GetPlatformDisplayEXT( ffi::egl::GetPlatformDisplayEXT(
ffi::egl::PLATFORM_WAYLAND_EXT, ffi::egl::PLATFORM_WAYLAND_EXT,
display as *mut _, display as *mut _,
ptr::null(), attribs.as_ptr(),
) )
}) })
} else { } else {
@ -79,6 +83,7 @@ impl Backend for X11 {
unsafe fn get_display<F>( unsafe fn get_display<F>(
display: ffi::NativeDisplayType, display: ffi::NativeDisplayType,
attribs: &[ffi::EGLint],
has_dp_extension: F, has_dp_extension: F,
log: ::slog::Logger, log: ::slog::Logger,
) -> Result<ffi::egl::types::EGLDisplay, EGLError> ) -> Result<ffi::egl::types::EGLDisplay, EGLError>
@ -87,13 +92,18 @@ impl Backend for X11 {
{ {
if has_dp_extension("EGL_KHR_platform_x11") && ffi::egl::GetPlatformDisplay::is_loaded() { if has_dp_extension("EGL_KHR_platform_x11") && ffi::egl::GetPlatformDisplay::is_loaded() {
trace!(log, "EGL Display Initialization via EGL_KHR_platform_x11"); trace!(log, "EGL Display Initialization via EGL_KHR_platform_x11");
let attribs = attribs.iter().map(|x| *x as isize).collect::<Vec<_>>();
wrap_egl_call(|| { wrap_egl_call(|| {
ffi::egl::GetPlatformDisplay(ffi::egl::PLATFORM_X11_KHR, display as *mut _, ptr::null()) ffi::egl::GetPlatformDisplay(ffi::egl::PLATFORM_X11_KHR, display as *mut _, attribs.as_ptr())
}) })
} else if has_dp_extension("EGL_EXT_platform_x11") && ffi::egl::GetPlatformDisplayEXT::is_loaded() { } else if has_dp_extension("EGL_EXT_platform_x11") && ffi::egl::GetPlatformDisplayEXT::is_loaded() {
trace!(log, "EGL Display Initialization via EGL_EXT_platform_x11"); trace!(log, "EGL Display Initialization via EGL_EXT_platform_x11");
wrap_egl_call(|| { wrap_egl_call(|| {
ffi::egl::GetPlatformDisplayEXT(ffi::egl::PLATFORM_X11_EXT, display as *mut _, ptr::null()) ffi::egl::GetPlatformDisplayEXT(
ffi::egl::PLATFORM_X11_EXT,
display as *mut _,
attribs.as_ptr(),
)
}) })
} else { } else {
trace!(log, "Default EGL Display Initialization via GetDisplay"); trace!(log, "Default EGL Display Initialization via GetDisplay");
@ -117,6 +127,12 @@ pub unsafe trait NativeDisplay<B: Backend> {
fn is_backend(&self) -> bool; fn is_backend(&self) -> bool;
/// Return a raw pointer EGL will accept for context creation. /// Return a raw pointer EGL will accept for context creation.
fn ptr(&self) -> Result<ffi::NativeDisplayType, Error>; fn ptr(&self) -> Result<ffi::NativeDisplayType, Error>;
/// Return attributes that might be used by `B::get_display`
///
/// Default implementation returns an empty list
fn attributes(&self) -> Vec<ffi::EGLint> {
vec![ffi::egl::NONE as ffi::EGLint]
}
/// Create a surface /// Create a surface
fn create_surface(&mut self, args: Self::Arguments) -> Result<B::Surface, Self::Error>; fn create_surface(&mut self, args: Self::Arguments) -> Result<B::Surface, Self::Error>;
} }