x11: rework impl to allow multiple windows

This commit is contained in:
i509VCB 2021-11-29 17:04:46 -06:00
parent 4f26641f8c
commit e4e964c869
5 changed files with 568 additions and 413 deletions

View File

@ -30,6 +30,7 @@
- `Present` was merged into the `X11Surface`
- `X11Surface::buffer` now additionally returns the age of the buffer
- `X11Surface` now has an explicit `submit` function
- `X11Surface` is now multi-window capable.
### Additions

View File

@ -12,7 +12,7 @@ use smithay::{
backend::{
egl::{EGLContext, EGLDisplay},
renderer::{gles2::Gles2Renderer, Bind, ImportEgl, Renderer, Transform, Unbind},
x11::{X11Backend, X11Event, X11Surface},
x11::{WindowBuilder, X11Backend, X11Event, X11Surface},
SwapBuffersError,
},
reexports::{
@ -59,27 +59,39 @@ pub fn run_x11(log: Logger) {
let mut event_loop = EventLoop::try_new().unwrap();
let display = Rc::new(RefCell::new(Display::new()));
let mut backend = X11Backend::with_title("Anvil", log.clone()).expect("Failed to initialize X11 backend");
let backend = X11Backend::new(log.clone()).expect("Failed to initilize X11 backend");
let handle = backend.handle();
// Obtain the DRM node the X server uses for direct rendering.
let drm_node = backend
let drm_node = handle
.drm_node()
.expect("Could not get DRM node used by X server");
// Create the gbm device for buffer allocation and the X11 surface which presents to the window.
// Create the gbm device for buffer allocation.
let device = gbm::Device::new(drm_node).expect("Failed to create gbm device");
// Initialize EGL using the GBM device setup earlier.
// Initialize EGL using the GBM device.
let egl = EGLDisplay::new(&device, log.clone()).expect("Failed to create EGLDisplay");
let device = Arc::new(Mutex::new(device));
// Create the OpenGL context
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 window = WindowBuilder::new()
.title("Anvil")
.build(&handle)
.expect("Failed to create first window");
let device = Arc::new(Mutex::new(device));
// Create the surface for the window.
let surface = handle
.create_surface(
&window,
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");
@ -104,8 +116,6 @@ pub fn run_x11(log: Logger) {
}
}
let window = backend.window();
let size = {
let s = window.size();

View File

@ -25,10 +25,17 @@ pub enum X11Error {
#[error("Creating the window failed")]
CreateWindow(CreateWindowError),
/// An X11 surface already exists for this backend.
#[error("An X11 surface already exists for this backend")]
/// An X11 surface already exists for this window.
#[error("An X11 surface already exists for this window")]
SurfaceExists,
/// An invalid window was used to create an X11 surface.
///
/// This error will be risen if the window was destroyed or the window does not belong to the [`X11Handle`](super::X11Handle)
/// in use.
#[error("An invalid window was used to create an X11 surface")]
InvalidWindow,
/// The X server is not capable of direct rendering.
#[error("The X server is not capable of direct rendering")]
CannotDirectRender,

File diff suppressed because it is too large Load Diff

View File

@ -15,6 +15,7 @@ use super::{extension::Extensions, Atoms, Window, X11Error};
use drm_fourcc::DrmFourcc;
use std::sync::{
atomic::{AtomicU32, AtomicU64},
mpsc::Sender,
Arc, Mutex, Weak,
};
use x11rb::{
@ -60,6 +61,10 @@ pub(crate) struct WindowInner {
pub atoms: Atoms,
pub cursor_state: Arc<Mutex<CursorState>>,
pub size: Mutex<Size<u16, Logical>>,
/// Channel used to send resize notifications to the surface that presents to this window.
///
/// This value will be [`None`] if no surface is bound to the window.
pub resize: Mutex<Option<Sender<Size<u16, Logical>>>>,
pub next_serial: AtomicU32,
pub last_msc: Arc<AtomicU64>,
pub format: DrmFourcc,
@ -154,6 +159,7 @@ impl WindowInner {
format,
depth,
extensions,
resize: Mutex::new(None),
};
// Enable WM_DELETE_WINDOW so our client is not disconnected upon our toplevel window being destroyed.