diff --git a/CHANGELOG.md b/CHANGELOG.md index 8669f2a..c93804e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - Update to `objc2` 0.6.0. - Bump MSRV to Rust 1.71. +- Make `Context` cloneable. # 0.4.6 diff --git a/README.md b/README.md index c17e01f..2966266 100644 --- a/README.md +++ b/README.md @@ -79,20 +79,16 @@ mod winit_app; fn main() { let event_loop = EventLoop::new().unwrap(); + let context = softbuffer::Context::new(event_loop.owned_display_handle()).unwrap(); let mut app = winit_app::WinitAppBuilder::with_init( |elwt| { - let window = { - let window = elwt.create_window(Window::default_attributes()); - Rc::new(window.unwrap()) - }; - let context = softbuffer::Context::new(window.clone()).unwrap(); - - (window, context) + let window = elwt.create_window(Window::default_attributes()); + Rc::new(window.unwrap()) }, - |_elwt, (window, context)| softbuffer::Surface::new(context, window.clone()).unwrap(), + |_elwt, window| softbuffer::Surface::new(&context, window.clone()).unwrap(), ) - .with_event_handler(|(window, _context), surface, event, elwt| { + .with_event_handler(|window, surface, event, elwt| { elwt.set_control_flow(ControlFlow::Wait); match event { diff --git a/benches/buffer_mut.rs b/benches/buffer_mut.rs index beaea99..536ebe3 100644 --- a/benches/buffer_mut.rs +++ b/benches/buffer_mut.rs @@ -18,6 +18,7 @@ fn buffer_mut(c: &mut Criterion) { use winit::platform::run_on_demand::EventLoopExtRunOnDemand; let mut evl = winit::event_loop::EventLoop::new().unwrap(); + let context = Context::new(evl.owned_display_handle()).unwrap(); let window = evl .create_window(winit::window::Window::default_attributes().with_visible(false)) .unwrap(); @@ -28,10 +29,7 @@ fn buffer_mut(c: &mut Criterion) { if let winit::event::Event::AboutToWait = ev { elwt.exit(); - let mut surface = { - let context = Context::new(elwt).unwrap(); - Surface::new(&context, &window).unwrap() - }; + let mut surface = { Surface::new(&context, &window).unwrap() }; let size = window.inner_size(); surface diff --git a/examples/animation.rs b/examples/animation.rs index c075923..714a7b2 100644 --- a/examples/animation.rs +++ b/examples/animation.rs @@ -14,23 +14,23 @@ fn main() { let event_loop = EventLoop::new().unwrap(); let start = Instant::now(); + let context = softbuffer::Context::new(event_loop.owned_display_handle()).unwrap(); + let app = winit_app::WinitAppBuilder::with_init( |event_loop| { let window = winit_app::make_window(event_loop, |w| w); - let context = softbuffer::Context::new(window.clone()).unwrap(); - let old_size = (0, 0); let frames = pre_render_frames(0, 0); - (window, context, old_size, frames) + (window, old_size, frames) }, - |_elwft, (window, context, _old_size, _frames)| { - softbuffer::Surface::new(context, window.clone()).unwrap() + move |_elwft, (window, _old_size, _frames)| { + softbuffer::Surface::new(&context, window.clone()).unwrap() }, ) .with_event_handler(move |state, surface, event, elwt| { - let (window, _context, old_size, frames) = state; + let (window, old_size, frames) = state; elwt.set_control_flow(ControlFlow::Poll); diff --git a/examples/fruit.rs b/examples/fruit.rs index 0402e8a..b325dd5 100644 --- a/examples/fruit.rs +++ b/examples/fruit.rs @@ -13,19 +13,16 @@ fn main() { let (width, height) = (fruit.width(), fruit.height()); let event_loop = EventLoop::new().unwrap(); + let context = softbuffer::Context::new(event_loop.owned_display_handle()).unwrap(); let app = winit_app::WinitAppBuilder::with_init( move |elwt| { - let window = winit_app::make_window(elwt, |w| { + winit_app::make_window(elwt, |w| { w.with_inner_size(winit::dpi::PhysicalSize::new(width, height)) - }); - - let context = softbuffer::Context::new(window.clone()).unwrap(); - - (window, context) + }) }, - move |_elwt, (window, context)| { - let mut surface = softbuffer::Surface::new(context, window.clone()).unwrap(); + move |_elwt, window| { + let mut surface = softbuffer::Surface::new(&context, window.clone()).unwrap(); // Intentionally only set the size of the surface once, at creation. // This is needed if the window chooses to ignore the size we passed in above, and for the // platforms softbuffer supports that don't yet extract the size from the window. @@ -38,8 +35,7 @@ fn main() { surface }, ) - .with_event_handler(move |state, surface, event, elwt| { - let (window, _context) = state; + .with_event_handler(move |window, surface, event, elwt| { elwt.set_control_flow(ControlFlow::Wait); match event { diff --git a/examples/rectangle.rs b/examples/rectangle.rs index b92f30b..70df087 100644 --- a/examples/rectangle.rs +++ b/examples/rectangle.rs @@ -24,6 +24,7 @@ fn redraw(buffer: &mut [u32], width: usize, height: usize, flag: bool) { fn main() { let event_loop = EventLoop::new().unwrap(); + let context = softbuffer::Context::new(event_loop.owned_display_handle()).unwrap(); let app = winit_app::WinitAppBuilder::with_init( |elwt| { @@ -31,18 +32,14 @@ fn main() { w.with_title("Press space to show/hide a rectangle") }); - let context = softbuffer::Context::new(window.clone()).unwrap(); - let flag = false; - (window, context, flag) - }, - |_elwt, (window, context, _flag)| { - softbuffer::Surface::new(context, window.clone()).unwrap() + (window, flag) }, + move |_elwt, (window, _flag)| softbuffer::Surface::new(&context, window.clone()).unwrap(), ) .with_event_handler(|state, surface, event, elwt| { - let (window, _context, flag) = state; + let (window, flag) = state; elwt.set_control_flow(ControlFlow::Wait); diff --git a/examples/winit.rs b/examples/winit.rs index 27a3cef..6ecc4bb 100644 --- a/examples/winit.rs +++ b/examples/winit.rs @@ -12,17 +12,13 @@ fn main() { } pub(crate) fn entry(event_loop: EventLoop<()>) { - let app = winit_app::WinitAppBuilder::with_init( - |elwt| { - let window = winit_app::make_window(elwt, |w| w); - - let context = softbuffer::Context::new(window.clone()).unwrap(); + let context = softbuffer::Context::new(event_loop.owned_display_handle()).unwrap(); - (window, context) - }, - |_elwt, (window, context)| softbuffer::Surface::new(context, window.clone()).unwrap(), + let app = winit_app::WinitAppBuilder::with_init( + |elwt| winit_app::make_window(elwt, |w| w), + move |_elwt, window| softbuffer::Surface::new(&context, window.clone()).unwrap(), ) - .with_event_handler(|(window, _context), surface, event, elwt| { + .with_event_handler(|window, surface, event, elwt| { elwt.set_control_flow(ControlFlow::Wait); match event { diff --git a/examples/winit_multithread.rs b/examples/winit_multithread.rs index 03afcc5..b58f161 100644 --- a/examples/winit_multithread.rs +++ b/examples/winit_multithread.rs @@ -9,13 +9,13 @@ pub mod ex { use std::num::NonZeroU32; use std::sync::{mpsc, Arc, Mutex}; use winit::event::{Event, KeyEvent, WindowEvent}; - use winit::event_loop::{ControlFlow, EventLoop}; + use winit::event_loop::{ControlFlow, EventLoop, OwnedDisplayHandle}; use winit::keyboard::{Key, NamedKey}; use winit::window::Window; use super::winit_app; - type Surface = softbuffer::Surface, Arc>; + type Surface = softbuffer::Surface>; fn render_thread( window: Arc, @@ -60,6 +60,8 @@ pub mod ex { } pub fn entry(event_loop: EventLoop<()>) { + let context = softbuffer::Context::new(event_loop.owned_display_handle()).unwrap(); + let app = winit_app::WinitAppBuilder::with_init( |elwt| { let attributes = Window::default_attributes(); @@ -68,8 +70,6 @@ pub mod ex { winit::platform::web::WindowAttributesExtWebSys::with_append(attributes, true); let window = Arc::new(elwt.create_window(attributes).unwrap()); - let context = softbuffer::Context::new(window.clone()).unwrap(); - // Spawn a thread to handle rendering for this specific surface. The channels will // be closed and the thread will be stopped whenever this surface (the returned // context below) is dropped, so that it can all be recreated again (on Android) @@ -82,17 +82,17 @@ pub mod ex { move || render_thread(window, do_render, render_done) }); - (window, context, start_render, finish_render) + (window, start_render, finish_render) }, - |_elwt, (window, context, _start_render, _finish_render)| { + move |_elwt, (window, _start_render, _finish_render)| { println!("making surface..."); Arc::new(Mutex::new( - softbuffer::Surface::new(context, window.clone()).unwrap(), + softbuffer::Surface::new(&context, window.clone()).unwrap(), )) }, ) .with_event_handler(|state, surface, event, elwt| { - let (window, _context, start_render, finish_render) = state; + let (window, start_render, finish_render) = state; elwt.set_control_flow(ControlFlow::Wait); match event { diff --git a/examples/winit_wrong_sized_buffer.rs b/examples/winit_wrong_sized_buffer.rs index 0c58a11..b135680 100644 --- a/examples/winit_wrong_sized_buffer.rs +++ b/examples/winit_wrong_sized_buffer.rs @@ -11,17 +11,12 @@ const BUFFER_HEIGHT: usize = 128; fn main() { let event_loop = EventLoop::new().unwrap(); + let context = softbuffer::Context::new(event_loop.owned_display_handle()).unwrap(); let app = winit_app::WinitAppBuilder::with_init( - |elwt| { - let window = winit_app::make_window(elwt, |w| w); - - let context = softbuffer::Context::new(window.clone()).unwrap(); - - (window, context) - }, - |_elwt, (window, context)| { - let mut surface = softbuffer::Surface::new(context, window.clone()).unwrap(); + |elwt| winit_app::make_window(elwt, |w| w), + move |_elwt, window| { + let mut surface = softbuffer::Surface::new(&context, window.clone()).unwrap(); // Intentionally set the size of the surface to something different than the size of the window. surface .resize( @@ -32,8 +27,7 @@ fn main() { surface }, ) - .with_event_handler(|state, surface, event, elwt| { - let (window, _context) = state; + .with_event_handler(|window, surface, event, elwt| { elwt.set_control_flow(ControlFlow::Wait); match event { diff --git a/src/backend_dispatch.rs b/src/backend_dispatch.rs index a86832e..3b5d269 100644 --- a/src/backend_dispatch.rs +++ b/src/backend_dispatch.rs @@ -17,6 +17,7 @@ macro_rules! make_dispatch { ($context_inner: ty, $surface_inner: ty, $buffer_inner: ty), )* ) => { + #[derive(Clone)] pub(crate) enum ContextDispatch<$dgen> { $( $(#[$attr])* diff --git a/src/backends/web.rs b/src/backends/web.rs index 4eb8fe0..6ebc70d 100644 --- a/src/backends/web.rs +++ b/src/backends/web.rs @@ -18,6 +18,7 @@ use std::num::NonZeroU32; /// Display implementation for the web platform. /// /// This just caches the document to prevent having to query it every time. +#[derive(Clone)] pub struct WebDisplayImpl { document: web_sys::Document, _display: D, diff --git a/src/lib.rs b/src/lib.rs index 2e25967..ec3f1e9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,6 +30,7 @@ pub use backends::web::SurfaceExtWeb; /// An instance of this struct contains the platform-specific data that must be managed in order to /// write to a window on that platform. +#[derive(Clone)] pub struct Context { /// The inner static dispatch object. context_impl: ContextDispatch,