Merge pull request #426 from i509VCB/x11/multi-window
This commit is contained in:
commit
1088e62a6f
|
@ -30,6 +30,7 @@
|
||||||
- `Present` was merged into the `X11Surface`
|
- `Present` was merged into the `X11Surface`
|
||||||
- `X11Surface::buffer` now additionally returns the age of the buffer
|
- `X11Surface::buffer` now additionally returns the age of the buffer
|
||||||
- `X11Surface` now has an explicit `submit` function
|
- `X11Surface` now has an explicit `submit` function
|
||||||
|
- `X11Surface` is now multi-window capable.
|
||||||
|
|
||||||
### Additions
|
### Additions
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
use std::{cell::RefCell, rc::Rc, sync::atomic::Ordering, time::Duration};
|
use std::{
|
||||||
|
cell::RefCell,
|
||||||
|
rc::Rc,
|
||||||
|
sync::{atomic::Ordering, Arc, Mutex},
|
||||||
|
time::Duration,
|
||||||
|
};
|
||||||
|
|
||||||
use slog::Logger;
|
use slog::Logger;
|
||||||
#[cfg(feature = "egl")]
|
#[cfg(feature = "egl")]
|
||||||
|
@ -7,7 +12,7 @@ use smithay::{
|
||||||
backend::{
|
backend::{
|
||||||
egl::{EGLContext, EGLDisplay},
|
egl::{EGLContext, EGLDisplay},
|
||||||
renderer::{gles2::Gles2Renderer, Bind, ImportEgl, Renderer, Transform, Unbind},
|
renderer::{gles2::Gles2Renderer, Bind, ImportEgl, Renderer, Transform, Unbind},
|
||||||
x11::{X11Backend, X11Event, X11Surface},
|
x11::{WindowBuilder, X11Backend, X11Event, X11Surface},
|
||||||
SwapBuffersError,
|
SwapBuffersError,
|
||||||
},
|
},
|
||||||
reexports::{
|
reexports::{
|
||||||
|
@ -54,26 +59,39 @@ pub fn run_x11(log: Logger) {
|
||||||
let mut event_loop = EventLoop::try_new().unwrap();
|
let mut event_loop = EventLoop::try_new().unwrap();
|
||||||
let display = Rc::new(RefCell::new(Display::new()));
|
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.
|
// Obtain the DRM node the X server uses for direct rendering.
|
||||||
let drm_node = backend
|
let drm_node = handle
|
||||||
.drm_node()
|
.drm_node()
|
||||||
.expect("Could not get DRM node used by X server");
|
.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");
|
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 egl = EGLDisplay::new(&device, log.clone()).expect("Failed to create EGLDisplay");
|
||||||
|
// Create the OpenGL context
|
||||||
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,
|
let window = WindowBuilder::new()
|
||||||
device,
|
.title("Anvil")
|
||||||
context
|
.build(&handle)
|
||||||
.dmabuf_render_formats()
|
.expect("Failed to create first window");
|
||||||
.iter()
|
|
||||||
.map(|format| format.modifier),
|
let device = Arc::new(Mutex::new(device));
|
||||||
)
|
|
||||||
.expect("Failed to create X11 surface");
|
// 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 =
|
let renderer =
|
||||||
unsafe { Gles2Renderer::new(context, log.clone()) }.expect("Failed to initialize renderer");
|
unsafe { Gles2Renderer::new(context, log.clone()) }.expect("Failed to initialize renderer");
|
||||||
|
@ -98,8 +116,6 @@ pub fn run_x11(log: Logger) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let window = backend.window();
|
|
||||||
|
|
||||||
let size = {
|
let size = {
|
||||||
let s = window.size();
|
let s = window.size();
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,12 @@ pub mod dumb;
|
||||||
pub mod gbm;
|
pub mod gbm;
|
||||||
|
|
||||||
mod swapchain;
|
mod swapchain;
|
||||||
|
use std::{
|
||||||
|
cell::RefCell,
|
||||||
|
rc::Rc,
|
||||||
|
sync::{Arc, Mutex},
|
||||||
|
};
|
||||||
|
|
||||||
use crate::utils::{Buffer as BufferCoords, Size};
|
use crate::utils::{Buffer as BufferCoords, Size};
|
||||||
pub use swapchain::{Slot, Swapchain};
|
pub use swapchain::{Slot, Swapchain};
|
||||||
|
|
||||||
|
@ -60,3 +66,34 @@ pub trait Allocator<B: Buffer> {
|
||||||
modifiers: &[Modifier],
|
modifiers: &[Modifier],
|
||||||
) -> Result<B, Self::Error>;
|
) -> Result<B, Self::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// General implementations for interior mutability.
|
||||||
|
|
||||||
|
impl<A: Allocator<B>, B: Buffer> Allocator<B> for Arc<Mutex<A>> {
|
||||||
|
type Error = A::Error;
|
||||||
|
|
||||||
|
fn create_buffer(
|
||||||
|
&mut self,
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
fourcc: Fourcc,
|
||||||
|
modifiers: &[Modifier],
|
||||||
|
) -> Result<B, Self::Error> {
|
||||||
|
let mut guard = self.lock().unwrap();
|
||||||
|
guard.create_buffer(width, height, fourcc, modifiers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: Allocator<B>, B: Buffer> Allocator<B> for Rc<RefCell<A>> {
|
||||||
|
type Error = A::Error;
|
||||||
|
|
||||||
|
fn create_buffer(
|
||||||
|
&mut self,
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
fourcc: Fourcc,
|
||||||
|
modifiers: &[Modifier],
|
||||||
|
) -> Result<B, Self::Error> {
|
||||||
|
self.borrow_mut().create_buffer(width, height, fourcc, modifiers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -25,10 +25,17 @@ pub enum X11Error {
|
||||||
#[error("Creating the window failed")]
|
#[error("Creating the window failed")]
|
||||||
CreateWindow(CreateWindowError),
|
CreateWindow(CreateWindowError),
|
||||||
|
|
||||||
/// An X11 surface already exists for this backend.
|
/// An X11 surface already exists for this window.
|
||||||
#[error("An X11 surface already exists for this backend")]
|
#[error("An X11 surface already exists for this window")]
|
||||||
SurfaceExists,
|
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.
|
/// The X server is not capable of direct rendering.
|
||||||
#[error("The X server is not capable of direct rendering")]
|
#[error("The X server is not capable of direct rendering")]
|
||||||
CannotDirectRender,
|
CannotDirectRender,
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -15,6 +15,7 @@ use super::{extension::Extensions, Atoms, Window, X11Error};
|
||||||
use drm_fourcc::DrmFourcc;
|
use drm_fourcc::DrmFourcc;
|
||||||
use std::sync::{
|
use std::sync::{
|
||||||
atomic::{AtomicU32, AtomicU64},
|
atomic::{AtomicU32, AtomicU64},
|
||||||
|
mpsc::Sender,
|
||||||
Arc, Mutex, Weak,
|
Arc, Mutex, Weak,
|
||||||
};
|
};
|
||||||
use x11rb::{
|
use x11rb::{
|
||||||
|
@ -60,6 +61,10 @@ pub(crate) struct WindowInner {
|
||||||
pub atoms: Atoms,
|
pub atoms: Atoms,
|
||||||
pub cursor_state: Arc<Mutex<CursorState>>,
|
pub cursor_state: Arc<Mutex<CursorState>>,
|
||||||
pub size: Mutex<Size<u16, Logical>>,
|
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 next_serial: AtomicU32,
|
||||||
pub last_msc: Arc<AtomicU64>,
|
pub last_msc: Arc<AtomicU64>,
|
||||||
pub format: DrmFourcc,
|
pub format: DrmFourcc,
|
||||||
|
@ -154,6 +159,7 @@ impl WindowInner {
|
||||||
format,
|
format,
|
||||||
depth,
|
depth,
|
||||||
extensions,
|
extensions,
|
||||||
|
resize: Mutex::new(None),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Enable WM_DELETE_WINDOW so our client is not disconnected upon our toplevel window being destroyed.
|
// Enable WM_DELETE_WINDOW so our client is not disconnected upon our toplevel window being destroyed.
|
||||||
|
|
Loading…
Reference in New Issue