diff --git a/anvil/src/x11.rs b/anvil/src/x11.rs index bf5a562..2da4ffb 100644 --- a/anvil/src/x11.rs +++ b/anvil/src/x11.rs @@ -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)); diff --git a/src/backend/egl/native.rs b/src/backend/egl/native.rs index c2441c4..6feef7c 100644 --- a/src/backend/egl/native.rs +++ b/src/backend/egl/native.rs @@ -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> { - 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; diff --git a/src/backend/x11/mod.rs b/src/backend/x11/mod.rs index 2ac1c71..06e4a05 100644 --- a/src/backend/x11/mod.rs +++ b/src/backend/x11/mod.rs @@ -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> { //! // 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::>(); +//! //! // 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, - format: DrmFourcc, + modifiers: impl Iterator, ) -> Result { if backend.resize.is_some() { return Err(X11Error::SurfaceExists); } - let size = backend.window().size(); + let modifiers = modifiers.collect::>(); + + 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::::into)?; current .set_userdata(current.export().map_err(Into::::into)?) .map_err(Into::::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::::into)?; next.set_userdata(next.export().map_err(Into::::into)?) .map_err(Into::::into)?; @@ -466,7 +482,7 @@ impl X11Surface { Ok(X11Surface { connection: Arc::downgrade(&backend.connection), - window: backend.window(), + window, device, format, width: size.w,