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 gbm::AsRaw;
use std::marker::PhantomData;
use std::ptr;
/// Egl Gbm backend type
///
@ -28,6 +27,7 @@ impl<D: RawDevice + 'static> Backend for Gbm<D> {
unsafe fn get_display<F>(
display: ffi::NativeDisplayType,
attribs: &[ffi::EGLint],
has_dp_extension: F,
log: ::slog::Logger,
) -> 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() {
trace!(log, "EGL Display Initialization via EGL_KHR_platform_gbm");
let attribs = attribs.iter().map(|x| *x as isize).collect::<Vec<_>>();
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() {
trace!(log, "EGL Display Initialization via EGL_MESA_platform_gbm");
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() {
trace!(log, "EGL Display Initialization via EGL_MESA_platform_gbm");
let attribs = attribs.iter().map(|x| *x as isize).collect::<Vec<_>>();
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 {
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 ptr = native.ptr()?;
let egl_attribs = native.attributes();
ffi::egl::LOAD.call_once(|| unsafe {
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);
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)?
};

View File

@ -2,9 +2,6 @@
use super::{ffi, wrap_egl_call, EGLError, Error};
#[cfg(feature = "backend_winit")]
use std::ptr;
#[cfg(feature = "backend_winit")]
use wayland_egl as wegl;
#[cfg(feature = "backend_winit")]
@ -25,6 +22,7 @@ pub trait Backend {
/// but there is no way to test that.
unsafe fn get_display<F: Fn(&str) -> bool>(
display: ffi::NativeDisplayType,
attribs: &[ffi::EGLint],
has_dp_extension: F,
log: ::slog::Logger,
) -> Result<ffi::egl::types::EGLDisplay, EGLError>;
@ -39,6 +37,7 @@ impl Backend for Wayland {
unsafe fn get_display<F>(
display: ffi::NativeDisplayType,
attribs: &[ffi::EGLint],
has_dp_extension: F,
log: ::slog::Logger,
) -> 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() {
trace!(log, "EGL Display Initialization via EGL_KHR_platform_wayland");
let attribs = attribs.iter().map(|x| *x as isize).collect::<Vec<_>>();
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()
{
@ -57,7 +61,7 @@ impl Backend for Wayland {
ffi::egl::GetPlatformDisplayEXT(
ffi::egl::PLATFORM_WAYLAND_EXT,
display as *mut _,
ptr::null(),
attribs.as_ptr(),
)
})
} else {
@ -79,6 +83,7 @@ impl Backend for X11 {
unsafe fn get_display<F>(
display: ffi::NativeDisplayType,
attribs: &[ffi::EGLint],
has_dp_extension: F,
log: ::slog::Logger,
) -> 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() {
trace!(log, "EGL Display Initialization via EGL_KHR_platform_x11");
let attribs = attribs.iter().map(|x| *x as isize).collect::<Vec<_>>();
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() {
trace!(log, "EGL Display Initialization via EGL_EXT_platform_x11");
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 {
trace!(log, "Default EGL Display Initialization via GetDisplay");
@ -117,6 +127,12 @@ pub unsafe trait NativeDisplay<B: Backend> {
fn is_backend(&self) -> bool;
/// Return a raw pointer EGL will accept for context creation.
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
fn create_surface(&mut self, args: Self::Arguments) -> Result<B::Surface, Self::Error>;
}