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`
|
||||
- `X11Surface::buffer` now additionally returns the age of the buffer
|
||||
- `X11Surface` now has an explicit `submit` function
|
||||
- `X11Surface` is now multi-window capable.
|
||||
|
||||
### 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;
|
||||
#[cfg(feature = "egl")]
|
||||
|
@ -7,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::{
|
||||
|
@ -54,26 +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");
|
||||
// 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");
|
||||
|
@ -98,8 +116,6 @@ pub fn run_x11(log: Logger) {
|
|||
}
|
||||
}
|
||||
|
||||
let window = backend.window();
|
||||
|
||||
let size = {
|
||||
let s = window.size();
|
||||
|
||||
|
|
|
@ -22,6 +22,12 @@ pub mod dumb;
|
|||
pub mod gbm;
|
||||
|
||||
mod swapchain;
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
rc::Rc,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use crate::utils::{Buffer as BufferCoords, Size};
|
||||
pub use swapchain::{Slot, Swapchain};
|
||||
|
||||
|
@ -60,3 +66,34 @@ pub trait Allocator<B: Buffer> {
|
|||
modifiers: &[Modifier],
|
||||
) -> 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")]
|
||||
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
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue