x11: allocate buffers using gbm with modifiers
This commit is contained in:
parent
53d43905ac
commit
86716f9c9f
|
@ -62,12 +62,19 @@ pub fn run_x11(log: Logger) {
|
||||||
|
|
||||||
// Create the gbm device for buffer allocation and the X11 surface which presents to the window.
|
// Create the gbm device for buffer allocation and the X11 surface which presents to the window.
|
||||||
let device = gbm::Device::new(drm_node).expect("Failed to create gbm device");
|
let device = gbm::Device::new(drm_node).expect("Failed to create gbm device");
|
||||||
let format = backend.format();
|
|
||||||
let surface = X11Surface::new(&mut backend, device, format).expect("Failed to create X11 surface");
|
|
||||||
|
|
||||||
// Initialize EGL using the GBM device setup earlier.
|
// Initialize EGL using the GBM device setup earlier.
|
||||||
let egl = EGLDisplay::new(&surface, log.clone()).expect("Failed to create EGLDisplay");
|
let egl = EGLDisplay::new(&device, log.clone()).expect("Failed to create EGLDisplay");
|
||||||
let context = EGLContext::new(&egl, log.clone()).expect("Failed to create EGLContext");
|
let context = EGLContext::new(&egl, log.clone()).expect("Failed to create EGLContext");
|
||||||
|
let surface = X11Surface::new(
|
||||||
|
&mut backend,
|
||||||
|
device,
|
||||||
|
context
|
||||||
|
.dmabuf_render_formats()
|
||||||
|
.iter()
|
||||||
|
.map(|format| format.modifier),
|
||||||
|
)
|
||||||
|
.expect("Failed to create X11 surface");
|
||||||
|
|
||||||
let renderer =
|
let renderer =
|
||||||
unsafe { Gles2Renderer::new(context, log.clone()) }.expect("Failed to initialize renderer");
|
unsafe { Gles2Renderer::new(context, log.clone()) }.expect("Failed to initialize renderer");
|
||||||
let renderer = Rc::new(RefCell::new(renderer));
|
let renderer = Rc::new(RefCell::new(renderer));
|
||||||
|
|
|
@ -16,9 +16,6 @@ use winit::{platform::unix::WindowExtUnix, window::Window as WinitWindow};
|
||||||
#[cfg(feature = "backend_gbm")]
|
#[cfg(feature = "backend_gbm")]
|
||||||
use gbm::{AsRaw, Device as GbmDevice};
|
use gbm::{AsRaw, Device as GbmDevice};
|
||||||
|
|
||||||
#[cfg(feature = "backend_x11")]
|
|
||||||
use crate::backend::x11::X11Surface;
|
|
||||||
|
|
||||||
/// Create a `EGLPlatform<'a>` for the provided platform.
|
/// Create a `EGLPlatform<'a>` for the provided platform.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
|
@ -168,27 +165,6 @@ impl EGLNativeDisplay for WinitWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "backend_x11")]
|
|
||||||
impl EGLNativeDisplay for X11Surface {
|
|
||||||
fn supported_platforms(&self) -> Vec<EGLPlatform<'_>> {
|
|
||||||
vec![
|
|
||||||
// todo: https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_platform_device.txt
|
|
||||||
// see: https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_platform_gbm.txt
|
|
||||||
egl_platform!(
|
|
||||||
PLATFORM_GBM_KHR,
|
|
||||||
self.device().as_raw(),
|
|
||||||
&["EGL_KHR_platform_gbm"]
|
|
||||||
),
|
|
||||||
// see: https://www.khronos.org/registry/EGL/extensions/MESA/EGL_MESA_platform_gbm.txt
|
|
||||||
egl_platform!(
|
|
||||||
PLATFORM_GBM_MESA,
|
|
||||||
self.device().as_raw(),
|
|
||||||
&["EGL_MESA_platform_gbm"]
|
|
||||||
),
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Shallow type for EGL_PLATFORM_X11_EXT with the default X11 display
|
/// Shallow type for EGL_PLATFORM_X11_EXT with the default X11 display
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct X11DefaultDisplay;
|
pub struct X11DefaultDisplay;
|
||||||
|
|
|
@ -14,8 +14,9 @@
|
||||||
//! ```rust,no_run
|
//! ```rust,no_run
|
||||||
//! # use std::error::Error;
|
//! # use std::error::Error;
|
||||||
//! # use smithay::backend::x11::{X11Backend, X11Surface};
|
//! # use smithay::backend::x11::{X11Backend, X11Surface};
|
||||||
//! use smithay::backend::allocator::Fourcc;
|
//! use smithay::backend::egl::{EGLDisplay, EGLContext};
|
||||||
//! use smithay::reexports::gbm;
|
//! use smithay::reexports::gbm;
|
||||||
|
//! use std::collections::HashSet;
|
||||||
//!
|
//!
|
||||||
//! # struct CompositorState;
|
//! # struct CompositorState;
|
||||||
//! fn init_x11_backend(
|
//! fn init_x11_backend(
|
||||||
|
@ -23,7 +24,7 @@
|
||||||
//! logger: slog::Logger
|
//! logger: slog::Logger
|
||||||
//! ) -> Result<(), Box<dyn Error>> {
|
//! ) -> Result<(), Box<dyn Error>> {
|
||||||
//! // Create the backend, also yielding a surface that may be used to render to the window.
|
//! // Create the backend, also yielding a surface that may be used to render to the window.
|
||||||
//! let mut backend = X11Backend::new(logger)?;
|
//! let mut backend = X11Backend::new(logger.clone())?;
|
||||||
//! // You can get a handle to the window the backend has created for later use.
|
//! // You can get a handle to the window the backend has created for later use.
|
||||||
//! let window = backend.window();
|
//! let window = backend.window();
|
||||||
//!
|
//!
|
||||||
|
@ -33,13 +34,14 @@
|
||||||
//! let drm_node = backend.drm_node()?;
|
//! let drm_node = backend.drm_node()?;
|
||||||
//! // Create the gbm device for allocating buffers
|
//! // Create the gbm device for allocating buffers
|
||||||
//! let device = gbm::Device::new(drm_node)?;
|
//! let device = gbm::Device::new(drm_node)?;
|
||||||
//!
|
//! // Initialize EGL to retrieve the support modifier list
|
||||||
|
//! let egl = EGLDisplay::new(&device, logger.clone()).expect("Failed to create EGLDisplay");
|
||||||
|
//! let context = EGLContext::new(&egl, logger).expect("Failed to create EGLContext");
|
||||||
|
//! let modifiers = context.dmabuf_render_formats().iter().map(|format| format.modifier).collect::<HashSet<_>>();
|
||||||
|
//!
|
||||||
//! // Finally create the X11 surface, you will use this to obtain buffers that will be presented to the
|
//! // Finally create the X11 surface, you will use this to obtain buffers that will be presented to the
|
||||||
//! // window.
|
//! // window.
|
||||||
//!
|
//! let surface = X11Surface::new(&mut backend, device, modifiers.into_iter());
|
||||||
//! // It is more than likely you will want more robust format detection rather than forcing `Argb8888`,
|
|
||||||
//! // but that is outside of the scope of the example.
|
|
||||||
//! let surface = X11Surface::new(&mut backend, device, Fourcc::Argb8888);
|
|
||||||
//!
|
//!
|
||||||
//! // Insert the backend into the event loop to receive events.
|
//! // Insert the backend into the event loop to receive events.
|
||||||
//! handle.insert_source(backend, |event, _window, state| {
|
//! handle.insert_source(backend, |event, _window, state| {
|
||||||
|
@ -82,7 +84,7 @@ use crate::{
|
||||||
utils::{x11rb::X11Source, Logical, Size},
|
utils::{x11rb::X11Source, Logical, Size},
|
||||||
};
|
};
|
||||||
use calloop::{EventSource, Poll, PostAction, Readiness, Token, TokenFactory};
|
use calloop::{EventSource, Poll, PostAction, Readiness, Token, TokenFactory};
|
||||||
use drm_fourcc::DrmFourcc;
|
use drm_fourcc::{DrmFourcc, DrmModifier};
|
||||||
use gbm::{BufferObject, BufferObjectFlags};
|
use gbm::{BufferObject, BufferObjectFlags};
|
||||||
use nix::{
|
use nix::{
|
||||||
fcntl::{self, OFlag},
|
fcntl::{self, OFlag},
|
||||||
|
@ -440,22 +442,36 @@ impl X11Surface {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
backend: &mut X11Backend,
|
backend: &mut X11Backend,
|
||||||
device: gbm::Device<DrmNode>,
|
device: gbm::Device<DrmNode>,
|
||||||
format: DrmFourcc,
|
modifiers: impl Iterator<Item = DrmModifier>,
|
||||||
) -> Result<X11Surface, X11Error> {
|
) -> Result<X11Surface, X11Error> {
|
||||||
if backend.resize.is_some() {
|
if backend.resize.is_some() {
|
||||||
return Err(X11Error::SurfaceExists);
|
return Err(X11Error::SurfaceExists);
|
||||||
}
|
}
|
||||||
|
|
||||||
let size = backend.window().size();
|
let modifiers = modifiers.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let window = backend.window();
|
||||||
|
let format = window.format().unwrap();
|
||||||
|
let size = window.size();
|
||||||
let mut current = device
|
let mut current = device
|
||||||
.create_buffer_object(size.w as u32, size.h as u32, format, BufferObjectFlags::empty())
|
.create_buffer_object_with_modifiers(
|
||||||
|
size.w as u32,
|
||||||
|
size.h as u32,
|
||||||
|
format,
|
||||||
|
modifiers.iter().cloned(),
|
||||||
|
)
|
||||||
.map_err(Into::<AllocateBuffersError>::into)?;
|
.map_err(Into::<AllocateBuffersError>::into)?;
|
||||||
current
|
current
|
||||||
.set_userdata(current.export().map_err(Into::<AllocateBuffersError>::into)?)
|
.set_userdata(current.export().map_err(Into::<AllocateBuffersError>::into)?)
|
||||||
.map_err(Into::<AllocateBuffersError>::into)?;
|
.map_err(Into::<AllocateBuffersError>::into)?;
|
||||||
|
|
||||||
let mut next = device
|
let mut next = device
|
||||||
.create_buffer_object(size.w as u32, size.h as u32, format, BufferObjectFlags::empty())
|
.create_buffer_object_with_modifiers(
|
||||||
|
size.w as u32,
|
||||||
|
size.h as u32,
|
||||||
|
format,
|
||||||
|
modifiers.iter().cloned(),
|
||||||
|
)
|
||||||
.map_err(Into::<AllocateBuffersError>::into)?;
|
.map_err(Into::<AllocateBuffersError>::into)?;
|
||||||
next.set_userdata(next.export().map_err(Into::<AllocateBuffersError>::into)?)
|
next.set_userdata(next.export().map_err(Into::<AllocateBuffersError>::into)?)
|
||||||
.map_err(Into::<AllocateBuffersError>::into)?;
|
.map_err(Into::<AllocateBuffersError>::into)?;
|
||||||
|
@ -466,7 +482,7 @@ impl X11Surface {
|
||||||
|
|
||||||
Ok(X11Surface {
|
Ok(X11Surface {
|
||||||
connection: Arc::downgrade(&backend.connection),
|
connection: Arc::downgrade(&backend.connection),
|
||||||
window: backend.window(),
|
window,
|
||||||
device,
|
device,
|
||||||
format,
|
format,
|
||||||
width: size.w,
|
width: size.w,
|
||||||
|
|
Loading…
Reference in New Issue