From 99d63063b6435ee2029f4ccd7ab2d620c68a12b8 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Tue, 20 Dec 2022 08:43:26 -0700 Subject: [PATCH] Take a reference to a window in GraphicsContext::new, like glutin and wgpu --- README.md | 8 ++--- examples/animation.rs | 12 ++++---- examples/fruit.rs | 6 ++-- examples/winit.rs | 8 ++--- examples/winit_wrong_sized_buffer.rs | 6 ++-- src/cg.rs | 4 +-- src/error.rs | 9 +++--- src/lib.rs | 45 ++++------------------------ src/orbital.rs | 3 +- src/wayland.rs | 6 ++-- src/web.rs | 3 +- src/win32.rs | 4 +-- src/x11.rs | 4 +-- 13 files changed, 40 insertions(+), 78 deletions(-) diff --git a/README.md b/README.md index 8c4b006..7ff697c 100644 --- a/README.md +++ b/README.md @@ -63,15 +63,15 @@ use winit::window::WindowBuilder; fn main() { let event_loop = EventLoop::new(); let window = WindowBuilder::new().build(&event_loop).unwrap(); - let mut graphics_context = unsafe { GraphicsContext::new(window) }.unwrap(); + let mut graphics_context = unsafe { GraphicsContext::new(&window) }.unwrap(); event_loop.run(move |event, _, control_flow| { *control_flow = ControlFlow::Wait; match event { - Event::RedrawRequested(window_id) if window_id == graphics_context.window().id() => { + Event::RedrawRequested(window_id) if window_id == window.id() => { let (width, height) = { - let size = graphics_context.window().inner_size(); + let size = window.inner_size(); (size.width, size.height) }; let buffer = (0..((width * height) as usize)) @@ -93,7 +93,7 @@ fn main() { Event::WindowEvent { event: WindowEvent::CloseRequested, window_id, - } if window_id == graphics_context.window().id() => { + } if window_id == window.id() => { *control_flow = ControlFlow::Exit; } _ => {} diff --git a/examples/animation.rs b/examples/animation.rs index 34da928..28f455d 100644 --- a/examples/animation.rs +++ b/examples/animation.rs @@ -25,7 +25,7 @@ fn main() { .unwrap(); } - let mut graphics_context = unsafe { GraphicsContext::new(window) }.unwrap(); + let mut graphics_context = unsafe { GraphicsContext::new(&window) }.unwrap(); let mut old_size = (0, 0); let mut frames = pre_render_frames(0, 0); @@ -35,10 +35,10 @@ fn main() { *control_flow = ControlFlow::Poll; match event { - Event::RedrawRequested(window_id) if window_id == graphics_context.window().id() => { + Event::RedrawRequested(window_id) if window_id == window.id() => { let elapsed = start.elapsed().as_secs_f64() % 1.0; let (width, height) = { - let size = graphics_context.window().inner_size(); + let size = window.inner_size(); (size.width, size.height) }; @@ -51,12 +51,12 @@ fn main() { graphics_context.set_buffer(buffer.as_slice(), width as u16, height as u16); } Event::MainEventsCleared => { - graphics_context.window().request_redraw(); + window.request_redraw(); } Event::WindowEvent { event: WindowEvent::CloseRequested, window_id, - } if window_id == graphics_context.window().id() => { + } if window_id == window.id() => { *control_flow = ControlFlow::Exit; } _ => {} @@ -89,4 +89,4 @@ fn pre_render_frames(width: usize, height: usize) -> Vec>{ #[cfg(not(target_arch = "wasm32"))] (0..60).into_par_iter().map(render).collect() -} \ No newline at end of file +} diff --git a/examples/fruit.rs b/examples/fruit.rs index df59bdd..760149f 100644 --- a/examples/fruit.rs +++ b/examples/fruit.rs @@ -32,19 +32,19 @@ fn main() { .unwrap(); } - let mut graphics_context = unsafe { GraphicsContext::new(window) }.unwrap(); + let mut graphics_context = unsafe { GraphicsContext::new(&window) }.unwrap(); event_loop.run(move |event, _, control_flow| { *control_flow = ControlFlow::Wait; match event { - Event::RedrawRequested(window_id) if window_id == graphics_context.window().id() => { + Event::RedrawRequested(window_id) if window_id == window.id() => { graphics_context.set_buffer(&buffer, fruit.width() as u16, fruit.height() as u16); } Event::WindowEvent { event: WindowEvent::CloseRequested, window_id, - } if window_id == graphics_context.window().id() => { + } if window_id == window.id() => { *control_flow = ControlFlow::Exit; } _ => {} diff --git a/examples/winit.rs b/examples/winit.rs index c0e0f84..1eff181 100644 --- a/examples/winit.rs +++ b/examples/winit.rs @@ -21,15 +21,15 @@ fn main() { .unwrap(); } - let mut graphics_context = unsafe { GraphicsContext::new(window) }.unwrap(); + let mut graphics_context = unsafe { GraphicsContext::new(&window) }.unwrap(); event_loop.run(move |event, _, control_flow| { *control_flow = ControlFlow::Wait; match event { - Event::RedrawRequested(window_id) if window_id == graphics_context.window().id() => { + Event::RedrawRequested(window_id) if window_id == window.id() => { let (width, height) = { - let size = graphics_context.window().inner_size(); + let size = window.inner_size(); (size.width, size.height) }; let buffer = (0..((width * height) as usize)) @@ -51,7 +51,7 @@ fn main() { Event::WindowEvent { event: WindowEvent::CloseRequested, window_id, - } if window_id == graphics_context.window().id() => { + } if window_id == window.id() => { *control_flow = ControlFlow::Exit; } _ => {} diff --git a/examples/winit_wrong_sized_buffer.rs b/examples/winit_wrong_sized_buffer.rs index f2472fa..c59eff5 100644 --- a/examples/winit_wrong_sized_buffer.rs +++ b/examples/winit_wrong_sized_buffer.rs @@ -24,13 +24,13 @@ fn main() { .unwrap(); } - let mut graphics_context = unsafe { GraphicsContext::new(window) }.unwrap(); + let mut graphics_context = unsafe { GraphicsContext::new(&window) }.unwrap(); event_loop.run(move |event, _, control_flow| { *control_flow = ControlFlow::Wait; match event { - Event::RedrawRequested(window_id) if window_id == graphics_context.window().id() => { + Event::RedrawRequested(window_id) if window_id == window.id() => { let buffer = (0..((BUFFER_WIDTH * BUFFER_HEIGHT) as usize)) .map(|index| { let y = index / (BUFFER_WIDTH as usize); @@ -50,7 +50,7 @@ fn main() { Event::WindowEvent { event: WindowEvent::CloseRequested, window_id, - } if window_id == graphics_context.window().id() => { + } if window_id == window.id() => { *control_flow = ControlFlow::Exit; } _ => {} diff --git a/src/cg.rs b/src/cg.rs index 276ca65..901600e 100644 --- a/src/cg.rs +++ b/src/cg.rs @@ -1,5 +1,5 @@ use crate::{GraphicsContextImpl, SwBufError}; -use raw_window_handle::{HasRawWindowHandle, AppKitWindowHandle}; +use raw_window_handle::AppKitWindowHandle; use core_graphics::base::{kCGBitmapByteOrder32Little, kCGImageAlphaNoneSkipFirst, kCGRenderingIntentDefault}; use core_graphics::color_space::CGColorSpace; use core_graphics::data_provider::CGDataProvider; @@ -17,7 +17,7 @@ pub struct CGImpl { } impl CGImpl { - pub unsafe fn new(handle: AppKitWindowHandle) -> Result> { + pub unsafe fn new(handle: AppKitWindowHandle) -> Result { let view = handle.ns_view as id; let layer = CALayer::new(); let subview: id = NSView::alloc(nil).initWithFrame_(view.frame()); diff --git a/src/error.rs b/src/error.rs index b77adb0..7b1ce4a 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,14 +1,13 @@ use std::error::Error; -use raw_window_handle::{HasRawWindowHandle, RawDisplayHandle, RawWindowHandle}; +use raw_window_handle::{RawDisplayHandle, RawWindowHandle}; use thiserror::Error; #[derive(Error, Debug)] -pub enum SwBufError { +pub enum SwBufError { #[error( "The provided window returned an unsupported platform: {human_readable_window_platform_name}, {human_readable_display_platform_name}." )] UnsupportedPlatform { - window: W, human_readable_window_platform_name: &'static str, human_readable_display_platform_name: &'static str, window_handle: RawWindowHandle, @@ -19,9 +18,9 @@ pub enum SwBufError { } #[allow(unused)] // This isn't used on all platforms -pub(crate) fn unwrap(res: Result, str: &str) -> Result>{ +pub(crate) fn unwrap(res: Result, str: &str) -> Result{ match res{ Ok(t) => Ok(t), Err(e) => Err(SwBufError::PlatformError(Some(str.into()), Some(Box::new(e)))) } -} \ No newline at end of file +} diff --git a/src/lib.rs b/src/lib.rs index 653592f..880f334 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,18 +28,18 @@ use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandl /// write to a window on that platform. This struct owns the window that this data corresponds to /// to ensure safety, as that data must be destroyed before the window itself is destroyed. You may /// access the underlying window via [`window`](Self::window) and [`window_mut`](Self::window_mut). -pub struct GraphicsContext { - window: W, +pub struct GraphicsContext { graphics_context_impl: Box, } -impl GraphicsContext { +impl GraphicsContext { /// Creates a new instance of this struct, consuming the given window. /// /// # Safety /// - /// - Ensure that the passed object is valid to draw a 2D buffer to - pub unsafe fn new(window: W) -> Result> { + /// - Ensure that the passed object is valid to draw a 2D buffer to, and is valid for the + /// lifetime of the GraphicsContext + pub unsafe fn new(window: &W) -> Result { let raw_window_handle = window.raw_window_handle(); let raw_display_handle = window.raw_display_handle(); @@ -57,7 +57,6 @@ impl GraphicsContext { #[cfg(target_os = "redox")] (RawWindowHandle::Orbital(orbital_handle), _) => Box::new(orbital::OrbitalImpl::new(orbital_handle)?), (unimplemented_window_handle, unimplemented_display_handle) => return Err(SwBufError::UnsupportedPlatform { - window, human_readable_window_platform_name: window_handle_type_name(&unimplemented_window_handle), human_readable_display_platform_name: display_handle_type_name(&unimplemented_display_handle), window_handle: unimplemented_window_handle, @@ -66,36 +65,10 @@ impl GraphicsContext { }; Ok(Self { - window, graphics_context_impl: imple, }) } - /// Gets shared access to the underlying window. - #[inline] - pub fn window(&self) -> &W { - &self.window - } - - /// Gets mut/exclusive access to the underlying window. - /// - /// This method is `unsafe` because it could be used to replace the window with another one, - /// thus dropping the original window and violating the property that this [`GraphicsContext`] - /// will always be destroyed before the window it writes into. This method should only be used - /// when the window type in use requires mutable access to perform some action on an existing - /// window. - /// - /// # Safety - /// - /// - After the returned mutable reference is dropped, the window must still be the same window - /// which this [`GraphicsContext`] was created for; and within that window, the - /// platform-specific configuration for 2D drawing must not have been modified. (For example, - /// on macOS the view hierarchy of the window must not have been modified.) - #[inline] - pub unsafe fn window_mut(&mut self) -> &mut W { - &mut self.window - } - /// Shows the given buffer with the given width and height on the window corresponding to this /// graphics context. Panics if buffer.len() ≠ width*height. If the size of the buffer does /// not match the size of the window, the buffer is drawn in the upper-left corner of the window. @@ -131,14 +104,6 @@ impl GraphicsContext { } } -impl AsRef for GraphicsContext { - /// Equivalent to [`self.window()`](Self::window()). - #[inline] - fn as_ref(&self) -> &W { - self.window() - } -} - trait GraphicsContextImpl { unsafe fn set_buffer(&mut self, buffer: &[u32], width: u16, height: u16); } diff --git a/src/orbital.rs b/src/orbital.rs index 48e7122..ab0fcde 100644 --- a/src/orbital.rs +++ b/src/orbital.rs @@ -1,4 +1,3 @@ -use raw_window_handle::HasRawWindowHandle; use raw_window_handle::OrbitalWindowHandle; use std::{ cmp, @@ -47,7 +46,7 @@ pub struct OrbitalImpl { } impl OrbitalImpl { - pub fn new(handle: OrbitalWindowHandle) -> Result> { + pub fn new(handle: OrbitalWindowHandle) -> Result { Ok(Self { handle }) } } diff --git a/src/wayland.rs b/src/wayland.rs index a494c58..581bd7a 100644 --- a/src/wayland.rs +++ b/src/wayland.rs @@ -1,6 +1,6 @@ use crate::{error::unwrap, GraphicsContextImpl, SwBufError}; use nix::sys::memfd::{memfd_create, MemFdCreateFlag}; -use raw_window_handle::{HasRawWindowHandle, WaylandDisplayHandle, WaylandWindowHandle}; +use raw_window_handle::{WaylandDisplayHandle, WaylandWindowHandle}; use std::{ ffi::CStr, fs::File, @@ -40,10 +40,10 @@ impl Drop for WaylandBuffer { } impl WaylandImpl { - pub unsafe fn new( + pub unsafe fn new( window_handle: WaylandWindowHandle, display_handle: WaylandDisplayHandle, - ) -> Result> { + ) -> Result { let conn = Connection::from_backend(Backend::from_foreign_display( display_handle.display as *mut _, )); diff --git a/src/web.rs b/src/web.rs index 423b5b0..d12a61f 100644 --- a/src/web.rs +++ b/src/web.rs @@ -1,4 +1,3 @@ -use raw_window_handle::HasRawWindowHandle; use raw_window_handle::WebWindowHandle; use wasm_bindgen::Clamped; use wasm_bindgen::JsCast; @@ -15,7 +14,7 @@ pub struct WebImpl { } impl WebImpl { - pub fn new(handle: WebWindowHandle) -> Result> { + pub fn new(handle: WebWindowHandle) -> Result { let canvas: HtmlCanvasElement = web_sys::window() .ok_or_else(|| { SwBufError::PlatformError( diff --git a/src/win32.rs b/src/win32.rs index f4f1c5c..273d0fa 100644 --- a/src/win32.rs +++ b/src/win32.rs @@ -1,5 +1,5 @@ use crate::{GraphicsContextImpl, SwBufError}; -use raw_window_handle::{HasRawWindowHandle, Win32WindowHandle}; +use raw_window_handle::Win32WindowHandle; use std::os::raw::c_int; use windows_sys::Win32::Foundation::HWND; @@ -22,7 +22,7 @@ struct BitmapInfo { } impl Win32Impl { - pub unsafe fn new(handle: &Win32WindowHandle) -> Result> { + pub unsafe fn new(handle: &Win32WindowHandle) -> Result { let dc = GetDC(handle.hwnd as HWND); if dc == 0 { diff --git a/src/x11.rs b/src/x11.rs index 8cd6ff0..e8d48b6 100644 --- a/src/x11.rs +++ b/src/x11.rs @@ -1,5 +1,5 @@ use crate::{GraphicsContextImpl, SwBufError}; -use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle, XlibDisplayHandle, XlibWindowHandle}; +use raw_window_handle::{XlibDisplayHandle, XlibWindowHandle}; use std::os::raw::{c_char, c_uint}; use x11_dl::xlib::{Display, Visual, Xlib, ZPixmap, GC}; @@ -13,7 +13,7 @@ pub struct X11Impl { } impl X11Impl { - pub unsafe fn new(window_handle: XlibWindowHandle, display_handle: XlibDisplayHandle) -> Result> { + pub unsafe fn new(window_handle: XlibWindowHandle, display_handle: XlibDisplayHandle) -> Result { let lib = match Xlib::open() { Ok(lib) => lib, Err(e) => return Err(SwBufError::PlatformError(Some("Failed to open Xlib".into()), Some(Box::new(e))))