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.
|
||||
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.
|
||||
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 surface = X11Surface::new(
|
||||
&mut backend,
|
||||
device,
|
||||
context
|
||||
.dmabuf_render_formats()
|
||||
.iter()
|
||||
.map(|format| format.modifier),
|
||||
)
|
||||
.expect("Failed to create X11 surface");
|
||||
|
||||
let renderer =
|
||||
unsafe { Gles2Renderer::new(context, log.clone()) }.expect("Failed to initialize 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")]
|
||||
use gbm::{AsRaw, Device as GbmDevice};
|
||||
|
||||
#[cfg(feature = "backend_x11")]
|
||||
use crate::backend::x11::X11Surface;
|
||||
|
||||
/// Create a `EGLPlatform<'a>` for the provided platform.
|
||||
///
|
||||
/// # 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
|
||||
#[derive(Debug)]
|
||||
pub struct X11DefaultDisplay;
|
||||
|
|
|
@ -14,8 +14,9 @@
|
|||
//! ```rust,no_run
|
||||
//! # use std::error::Error;
|
||||
//! # use smithay::backend::x11::{X11Backend, X11Surface};
|
||||
//! use smithay::backend::allocator::Fourcc;
|
||||
//! use smithay::backend::egl::{EGLDisplay, EGLContext};
|
||||
//! use smithay::reexports::gbm;
|
||||
//! use std::collections::HashSet;
|
||||
//!
|
||||
//! # struct CompositorState;
|
||||
//! fn init_x11_backend(
|
||||
|
@ -23,7 +24,7 @@
|
|||
//! logger: slog::Logger
|
||||
//! ) -> Result<(), Box<dyn Error>> {
|
||||
//! // 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.
|
||||
//! let window = backend.window();
|
||||
//!
|
||||
|
@ -33,13 +34,14 @@
|
|||
//! let drm_node = backend.drm_node()?;
|
||||
//! // Create the gbm device for allocating buffers
|
||||
//! 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
|
||||
//! // window.
|
||||
//!
|
||||
//! // 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);
|
||||
//! let surface = X11Surface::new(&mut backend, device, modifiers.into_iter());
|
||||
//!
|
||||
//! // Insert the backend into the event loop to receive events.
|
||||
//! handle.insert_source(backend, |event, _window, state| {
|
||||
|
@ -82,7 +84,7 @@ use crate::{
|
|||
utils::{x11rb::X11Source, Logical, Size},
|
||||
};
|
||||
use calloop::{EventSource, Poll, PostAction, Readiness, Token, TokenFactory};
|
||||
use drm_fourcc::DrmFourcc;
|
||||
use drm_fourcc::{DrmFourcc, DrmModifier};
|
||||
use gbm::{BufferObject, BufferObjectFlags};
|
||||
use nix::{
|
||||
fcntl::{self, OFlag},
|
||||
|
@ -440,22 +442,36 @@ impl X11Surface {
|
|||
pub fn new(
|
||||
backend: &mut X11Backend,
|
||||
device: gbm::Device<DrmNode>,
|
||||
format: DrmFourcc,
|
||||
modifiers: impl Iterator<Item = DrmModifier>,
|
||||
) -> Result<X11Surface, X11Error> {
|
||||
if backend.resize.is_some() {
|
||||
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
|
||||
.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)?;
|
||||
current
|
||||
.set_userdata(current.export().map_err(Into::<AllocateBuffersError>::into)?)
|
||||
.map_err(Into::<AllocateBuffersError>::into)?;
|
||||
|
||||
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)?;
|
||||
next.set_userdata(next.export().map_err(Into::<AllocateBuffersError>::into)?)
|
||||
.map_err(Into::<AllocateBuffersError>::into)?;
|
||||
|
@ -466,7 +482,7 @@ impl X11Surface {
|
|||
|
||||
Ok(X11Surface {
|
||||
connection: Arc::downgrade(&backend.connection),
|
||||
window: backend.window(),
|
||||
window,
|
||||
device,
|
||||
format,
|
||||
width: size.w,
|
||||
|
|
Loading…
Reference in New Issue