Split GraphicsContext into Context and Surface
A `Context` is created with a display handle, and a `Surface` is created with a `&Context` and a window handle. Thus multiple windows can be created from the same context without duplicating anything that can be shared. This API is broadly similar to `wgpu` or `glutin`. On Wayland, the `Context` contains the `EventQueue`, which is shared between windows, and the `WlShm` global. On X11, `Context::new` checks for the availability of XShm, and contains a bool representing that as well as the `XCBConnection`. The shared context data is stored within the window in an `Arc`. On other platforms, the display isn't used and `Context` is empty. This does however test that the display handle has the right type on those platforms and fail otherwise. Previously the code didn't test that. Closes https://github.com/rust-windowing/softbuffer/issues/37.
This commit is contained in:
parent
3b33bbb0f5
commit
129069996e
11 changed files with 298 additions and 158 deletions
|
|
@ -1,7 +1,6 @@
|
|||
use instant::Instant;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use rayon::prelude::*;
|
||||
use softbuffer::GraphicsContext;
|
||||
use std::f64::consts::PI;
|
||||
use winit::event::{Event, WindowEvent};
|
||||
use winit::event_loop::{ControlFlow, EventLoop};
|
||||
|
|
@ -25,7 +24,8 @@ fn main() {
|
|||
.unwrap();
|
||||
}
|
||||
|
||||
let mut graphics_context = unsafe { GraphicsContext::new(&window, &window) }.unwrap();
|
||||
let context = unsafe { softbuffer::Context::new(&window) }.unwrap();
|
||||
let mut surface = unsafe { softbuffer::Surface::new(&context, &window) }.unwrap();
|
||||
|
||||
let mut old_size = (0, 0);
|
||||
let mut frames = pre_render_frames(0, 0);
|
||||
|
|
@ -48,7 +48,7 @@ fn main() {
|
|||
};
|
||||
|
||||
let buffer = &frames[((elapsed * 60.0).round() as usize).clamp(0, 59)];
|
||||
graphics_context.set_buffer(buffer.as_slice(), width as u16, height as u16);
|
||||
surface.set_buffer(buffer.as_slice(), width as u16, height as u16);
|
||||
}
|
||||
Event::MainEventsCleared => {
|
||||
window.request_redraw();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
use image::GenericImageView;
|
||||
use softbuffer::GraphicsContext;
|
||||
use winit::event::{Event, WindowEvent};
|
||||
use winit::event_loop::{ControlFlow, EventLoop};
|
||||
use winit::window::WindowBuilder;
|
||||
|
|
@ -38,14 +37,15 @@ fn main() {
|
|||
.unwrap();
|
||||
}
|
||||
|
||||
let mut graphics_context = unsafe { GraphicsContext::new(&window, &window) }.unwrap();
|
||||
let context = unsafe { softbuffer::Context::new(&window) }.unwrap();
|
||||
let mut surface = unsafe { softbuffer::Surface::new(&context, &window) }.unwrap();
|
||||
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
*control_flow = ControlFlow::Wait;
|
||||
|
||||
match event {
|
||||
Event::RedrawRequested(window_id) if window_id == window.id() => {
|
||||
graphics_context.set_buffer(&buffer, fruit.width() as u16, fruit.height() as u16);
|
||||
surface.set_buffer(&buffer, fruit.width() as u16, fruit.height() as u16);
|
||||
}
|
||||
Event::WindowEvent {
|
||||
event: WindowEvent::CloseRequested,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
#[cfg(all(feature = "x11", any(target_os = "linux", target_os = "freebsd")))]
|
||||
mod example {
|
||||
use raw_window_handle::{RawDisplayHandle, RawWindowHandle, XcbDisplayHandle, XcbWindowHandle};
|
||||
use softbuffer::GraphicsContext;
|
||||
use x11rb::{
|
||||
connection::Connection,
|
||||
protocol::{
|
||||
|
|
@ -54,13 +53,12 @@ mod example {
|
|||
|
||||
// Create a new softbuffer context.
|
||||
// SAFETY: The display and window handles outlive the context.
|
||||
let mut context = unsafe {
|
||||
GraphicsContext::from_raw(
|
||||
RawWindowHandle::Xcb(window_handle),
|
||||
RawDisplayHandle::Xcb(display_handle),
|
||||
)
|
||||
}
|
||||
.unwrap();
|
||||
let context =
|
||||
unsafe { softbuffer::Context::from_raw(RawDisplayHandle::Xcb(display_handle)) }
|
||||
.unwrap();
|
||||
let mut surface =
|
||||
unsafe { softbuffer::Surface::from_raw(&context, RawWindowHandle::Xcb(window_handle)) }
|
||||
.unwrap();
|
||||
|
||||
// Register an atom for closing the window.
|
||||
let wm_protocols_atom = conn
|
||||
|
|
@ -104,7 +102,7 @@ mod example {
|
|||
.collect::<Vec<_>>();
|
||||
|
||||
// Draw the buffer.
|
||||
context.set_buffer(&source, width, height);
|
||||
surface.set_buffer(&source, width, height);
|
||||
}
|
||||
Event::ConfigureNotify(configure_notify) => {
|
||||
width = configure_notify.width;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
use softbuffer::GraphicsContext;
|
||||
use winit::event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent};
|
||||
use winit::event_loop::{ControlFlow, EventLoop};
|
||||
use winit::window::WindowBuilder;
|
||||
|
|
@ -41,7 +40,8 @@ fn main() {
|
|||
.unwrap();
|
||||
}
|
||||
|
||||
let mut graphics_context = unsafe { GraphicsContext::new(&window, &window) }.unwrap();
|
||||
let context = unsafe { softbuffer::Context::new(&window) }.unwrap();
|
||||
let mut surface = unsafe { softbuffer::Surface::new(&context, &window) }.unwrap();
|
||||
|
||||
let mut buffer = Vec::new();
|
||||
let mut flag = false;
|
||||
|
|
@ -66,7 +66,7 @@ fn main() {
|
|||
redraw(&mut buffer, width, height, flag);
|
||||
|
||||
// Blit the offscreen buffer to the window's client area
|
||||
graphics_context.set_buffer(&buffer, width as u16, height as u16);
|
||||
surface.set_buffer(&buffer, width as u16, height as u16);
|
||||
}
|
||||
|
||||
Event::WindowEvent {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
use softbuffer::GraphicsContext;
|
||||
use winit::event::{Event, WindowEvent};
|
||||
use winit::event_loop::{ControlFlow, EventLoop};
|
||||
use winit::window::WindowBuilder;
|
||||
|
|
@ -21,7 +20,8 @@ fn main() {
|
|||
.unwrap();
|
||||
}
|
||||
|
||||
let mut graphics_context = unsafe { GraphicsContext::new(&window, &window) }.unwrap();
|
||||
let context = unsafe { softbuffer::Context::new(&window) }.unwrap();
|
||||
let mut surface = unsafe { softbuffer::Surface::new(&context, &window) }.unwrap();
|
||||
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
*control_flow = ControlFlow::Wait;
|
||||
|
|
@ -46,7 +46,7 @@ fn main() {
|
|||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
graphics_context.set_buffer(&buffer, width as u16, height as u16);
|
||||
surface.set_buffer(&buffer, width as u16, height as u16);
|
||||
}
|
||||
Event::WindowEvent {
|
||||
event: WindowEvent::CloseRequested,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
use softbuffer::GraphicsContext;
|
||||
use winit::event::{Event, WindowEvent};
|
||||
use winit::event_loop::{ControlFlow, EventLoop};
|
||||
use winit::window::WindowBuilder;
|
||||
|
|
@ -24,7 +23,8 @@ fn main() {
|
|||
.unwrap();
|
||||
}
|
||||
|
||||
let mut graphics_context = unsafe { GraphicsContext::new(&window, &window) }.unwrap();
|
||||
let context = unsafe { softbuffer::Context::new(&window) }.unwrap();
|
||||
let mut surface = unsafe { softbuffer::Surface::new(&context, &window) }.unwrap();
|
||||
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
*control_flow = ControlFlow::Wait;
|
||||
|
|
@ -45,7 +45,7 @@ fn main() {
|
|||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
graphics_context.set_buffer(&buffer, BUFFER_WIDTH as u16, BUFFER_HEIGHT as u16);
|
||||
surface.set_buffer(&buffer, BUFFER_WIDTH as u16, BUFFER_HEIGHT as u16);
|
||||
}
|
||||
Event::WindowEvent {
|
||||
event: WindowEvent::CloseRequested,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue