diff --git a/examples/animation.rs b/examples/animation.rs index f91b20c..17635a3 100644 --- a/examples/animation.rs +++ b/examples/animation.rs @@ -1,7 +1,7 @@ -use std::f64::consts::PI; use instant::Instant; #[cfg(not(target_arch = "wasm32"))] use rayon::prelude::*; +use std::f64::consts::PI; use swbuf::GraphicsContext; use winit::event::{Event, WindowEvent}; use winit::event_loop::{ControlFlow, EventLoop}; @@ -42,12 +42,12 @@ fn main() { (size.width, size.height) }; - if (width, height) != old_size{ + if (width, height) != old_size { old_size = (width, height); frames = pre_render_frames(width as usize, height as usize); }; - let buffer = &frames[((elapsed*60.0).round() as usize).clamp(0, 59)]; + 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); } Event::MainEventsCleared => { @@ -64,17 +64,20 @@ fn main() { }); } -fn pre_render_frames(width: usize, height: usize) -> Vec>{ - let render = |frame_id|{ - let elapsed = ((frame_id as f64)/(60.0))*2.0*PI; +fn pre_render_frames(width: usize, height: usize) -> Vec> { + let render = |frame_id| { + let elapsed = ((frame_id as f64) / (60.0)) * 2.0 * PI; (0..(width * height)) .map(|index| { - let y = ((index / width) as f64)/(height as f64); - let x = ((index % width) as f64)/(width as f64); - let red = ((((y + elapsed).sin()*0.5+0.5)*255.0).round() as u32).clamp(0, 255); - let green = ((((x + elapsed).sin()*0.5+0.5)*255.0).round() as u32).clamp(0, 255); - let blue = ((((y - elapsed).cos()*0.5+0.5)*255.0).round() as u32).clamp(0, 255); + let y = ((index / width) as f64) / (height as f64); + let x = ((index % width) as f64) / (width as f64); + let red = + ((((y + elapsed).sin() * 0.5 + 0.5) * 255.0).round() as u32).clamp(0, 255); + let green = + ((((x + elapsed).sin() * 0.5 + 0.5) * 255.0).round() as u32).clamp(0, 255); + let blue = + ((((y - elapsed).cos() * 0.5 + 0.5) * 255.0).round() as u32).clamp(0, 255); blue | (green << 8) | (red << 16) }) diff --git a/examples/fruit.rs b/examples/fruit.rs index fabf979..bf97c25 100644 --- a/examples/fruit.rs +++ b/examples/fruit.rs @@ -7,13 +7,16 @@ use winit::window::WindowBuilder; fn main() { //see fruit.jpg.license for the license of fruit.jpg let fruit = image::load_from_memory(include_bytes!("fruit.jpg")).unwrap(); - let buffer = fruit.pixels().map(|(_x, _y, pixel)|{ - let red = pixel.0[0] as u32; - let green = pixel.0[1] as u32; - let blue = pixel.0[2] as u32; - - blue | (green << 8) | (red << 16) - }).collect::>(); + let buffer = fruit + .pixels() + .map(|(_x, _y, pixel)| { + let red = pixel.0[0] as u32; + let green = pixel.0[1] as u32; + let blue = pixel.0[2] as u32; + + blue | (green << 8) | (red << 16) + }) + .collect::>(); let event_loop = EventLoop::new(); let window = WindowBuilder::new() diff --git a/src/cg.rs b/src/cg.rs index 7703b43..c879ed5 100644 --- a/src/cg.rs +++ b/src/cg.rs @@ -1,12 +1,14 @@ use crate::SwBufError; -use raw_window_handle::AppKitWindowHandle; -use core_graphics::base::{kCGBitmapByteOrder32Little, kCGImageAlphaNoneSkipFirst, kCGRenderingIntentDefault}; +use core_graphics::base::{ + kCGBitmapByteOrder32Little, kCGImageAlphaNoneSkipFirst, kCGRenderingIntentDefault, +}; use core_graphics::color_space::CGColorSpace; use core_graphics::data_provider::CGDataProvider; use core_graphics::image::CGImage; +use raw_window_handle::AppKitWindowHandle; +use cocoa::appkit::{NSView, NSViewHeightSizable, NSViewWidthSizable, NSWindow}; use cocoa::base::{id, nil}; -use cocoa::appkit::{NSView, NSViewWidthSizable, NSViewHeightSizable, NSWindow}; use cocoa::quartzcore::{CALayer, ContentsGravity}; use foreign_types::ForeignType; @@ -30,14 +32,13 @@ impl CGImpl { view.addSubview_(subview); // retains subview (+1) = 2 let _: () = msg_send![subview, release]; // releases subview (-1) = 1 - Ok(Self{layer}) + Ok(Self { layer }) } pub(crate) unsafe fn set_buffer(&mut self, buffer: &[u32], width: u16, height: u16) { let color_space = CGColorSpace::create_device_rgb(); - let data = std::slice::from_raw_parts( - buffer.as_ptr() as *const u8, - buffer.len() * 4).to_vec(); + let data = + std::slice::from_raw_parts(buffer.as_ptr() as *const u8, buffer.len() * 4).to_vec(); let data_provider = CGDataProvider::from_buffer(Arc::new(data)); let image = CGImage::new( width as usize, diff --git a/src/error.rs b/src/error.rs index 12bedda..8aab36f 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,5 +1,5 @@ -use std::error::Error; use raw_window_handle::{RawDisplayHandle, RawWindowHandle}; +use std::error::Error; use thiserror::Error; #[derive(Error, Debug)] @@ -12,7 +12,7 @@ pub enum SwBufError { human_readable_window_platform_name: &'static str, human_readable_display_platform_name: &'static str, window_handle: RawWindowHandle, - display_handle: RawDisplayHandle + display_handle: RawDisplayHandle, }, #[error("The provided window handle is null.")] @@ -22,13 +22,19 @@ pub enum SwBufError { IncompleteDisplayHandle, #[error("Platform error")] - PlatformError(Option, Option>) + PlatformError(Option, Option>), } #[allow(unused)] // This isn't used on all platforms -pub(crate) fn unwrap(res: Result, str: &str) -> Result{ - match res{ +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)))) + Err(e) => Err(SwBufError::PlatformError( + Some(str.into()), + Some(Box::new(e)), + )), } } diff --git a/src/lib.rs b/src/lib.rs index 6b17e67..d7e6771 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,33 +5,35 @@ extern crate objc; extern crate core; -#[cfg(target_os = "windows")] -mod win32; #[cfg(target_os = "macos")] mod cg; -#[cfg(all(feature = "x11", any(target_os = "linux", target_os = "freebsd")))] -mod x11; +#[cfg(target_os = "redox")] +mod orbital; #[cfg(all(feature = "wayland", any(target_os = "linux", target_os = "freebsd")))] mod wayland; #[cfg(target_arch = "wasm32")] mod web; -#[cfg(target_os = "redox")] -mod orbital; +#[cfg(target_os = "windows")] +mod win32; +#[cfg(all(feature = "x11", any(target_os = "linux", target_os = "freebsd")))] +mod x11; mod error; pub use error::SwBufError; -use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle}; +use raw_window_handle::{ + HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle, +}; /// An instance of this struct contains the platform-specific data that must be managed in order to /// write to a window on that platform. pub struct GraphicsContext { /// The inner static dispatch object. - /// + /// /// This is boxed so that `GraphicsContext` is the same size on every platform, which should /// hopefully prevent surprises. - graphics_context_impl: Box + graphics_context_impl: Box, } /// A macro for creating the enum used to statically dispatch to the platform-specific implementation. @@ -84,7 +86,10 @@ impl GraphicsContext { /// /// - Ensure that the provided objects are valid to draw a 2D buffer to, and are valid for the /// lifetime of the GraphicsContext - pub unsafe fn new(window: &W, display: &D) -> Result { + pub unsafe fn new( + window: &W, + display: &D, + ) -> Result { Self::from_raw(window.raw_window_handle(), display.raw_display_handle()) } @@ -94,30 +99,54 @@ impl GraphicsContext { /// /// - Ensure that the provided handles are valid to draw a 2D buffer to, and are valid for the /// lifetime of the GraphicsContext - pub unsafe fn from_raw(raw_window_handle: RawWindowHandle, raw_display_handle: RawDisplayHandle) -> Result { + pub unsafe fn from_raw( + raw_window_handle: RawWindowHandle, + raw_display_handle: RawDisplayHandle, + ) -> Result { let imple: Dispatch = match (raw_window_handle, raw_display_handle) { #[cfg(all(feature = "x11", any(target_os = "linux", target_os = "freebsd")))] - (RawWindowHandle::Xlib(xlib_window_handle), RawDisplayHandle::Xlib(xlib_display_handle)) => Dispatch::X11(x11::X11Impl::new(xlib_window_handle, xlib_display_handle)?), + ( + RawWindowHandle::Xlib(xlib_window_handle), + RawDisplayHandle::Xlib(xlib_display_handle), + ) => Dispatch::X11(x11::X11Impl::new(xlib_window_handle, xlib_display_handle)?), #[cfg(all(feature = "wayland", any(target_os = "linux", target_os = "freebsd")))] - (RawWindowHandle::Wayland(wayland_window_handle), RawDisplayHandle::Wayland(wayland_display_handle)) => Dispatch::Wayland(wayland::WaylandImpl::new(wayland_window_handle, wayland_display_handle)?), + ( + RawWindowHandle::Wayland(wayland_window_handle), + RawDisplayHandle::Wayland(wayland_display_handle), + ) => Dispatch::Wayland(wayland::WaylandImpl::new( + wayland_window_handle, + wayland_display_handle, + )?), #[cfg(target_os = "windows")] - (RawWindowHandle::Win32(win32_handle), _) => Dispatch::Win32(win32::Win32Impl::new(&win32_handle)?), + (RawWindowHandle::Win32(win32_handle), _) => { + Dispatch::Win32(win32::Win32Impl::new(&win32_handle)?) + } #[cfg(target_os = "macos")] - (RawWindowHandle::AppKit(appkit_handle), _) => Dispatch::CG(cg::CGImpl::new(appkit_handle)?), + (RawWindowHandle::AppKit(appkit_handle), _) => { + Dispatch::CG(cg::CGImpl::new(appkit_handle)?) + } #[cfg(target_arch = "wasm32")] (RawWindowHandle::Web(web_handle), _) => Dispatch::Web(web::WebImpl::new(web_handle)?), #[cfg(target_os = "redox")] - (RawWindowHandle::Orbital(orbital_handle), _) => Dispatch::Orbital(orbital::OrbitalImpl::new(orbital_handle)?), - (unimplemented_window_handle, unimplemented_display_handle) => return Err(SwBufError::UnsupportedPlatform { - 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, - display_handle: unimplemented_display_handle - }), + (RawWindowHandle::Orbital(orbital_handle), _) => { + Dispatch::Orbital(orbital::OrbitalImpl::new(orbital_handle)?) + } + (unimplemented_window_handle, unimplemented_display_handle) => { + return Err(SwBufError::UnsupportedPlatform { + 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, + display_handle: unimplemented_display_handle, + }) + } }; Ok(Self { - graphics_context_impl: Box::new(imple) + graphics_context_impl: Box::new(imple), }) } diff --git a/src/orbital.rs b/src/orbital.rs index e678e0a..9c58f83 100644 --- a/src/orbital.rs +++ b/src/orbital.rs @@ -1,9 +1,5 @@ use raw_window_handle::OrbitalWindowHandle; -use std::{ - cmp, - slice, - str, -}; +use std::{cmp, slice, str}; use crate::SwBufError; @@ -19,12 +15,15 @@ impl OrbitalMap { let size = pages * syscall::PAGE_SIZE; // Map window buffer - let address = syscall::fmap(fd, &syscall::Map { - offset: 0, - size, - flags: syscall::PROT_READ | syscall::PROT_WRITE, - address: 0, - })?; + let address = syscall::fmap( + fd, + &syscall::Map { + offset: 0, + size, + flags: syscall::PROT_READ | syscall::PROT_WRITE, + address: 0, + }, + )?; Ok(Self { address, size }) } @@ -34,8 +33,7 @@ impl Drop for OrbitalMap { fn drop(&mut self) { unsafe { // Unmap window buffer on drop - syscall::funmap(self.address, self.size) - .expect("failed to unmap orbital window"); + syscall::funmap(self.address, self.size).expect("failed to unmap orbital window"); } } } @@ -71,15 +69,13 @@ impl OrbitalImpl { { // Map window buffer - let window_map = OrbitalMap::new( - window_fd, - window_width * window_height * 4 - ).expect("failed to map orbital window"); + let window_map = OrbitalMap::new(window_fd, window_width * window_height * 4) + .expect("failed to map orbital window"); // Window buffer is u32 color data in 0xAABBGGRR format let window_data = slice::from_raw_parts_mut( window_map.address as *mut u32, - window_width * window_height + window_width * window_height, ); // Copy each line, cropping to fit @@ -90,9 +86,8 @@ impl OrbitalImpl { for y in 0..min_height { let offset_buffer = y * width; let offset_data = y * window_width; - window_data[offset_data..offset_data + min_width].copy_from_slice( - &buffer[offset_buffer..offset_buffer + min_width] - ); + window_data[offset_data..offset_data + min_width] + .copy_from_slice(&buffer[offset_buffer..offset_buffer + min_width]); } // Window buffer map is dropped here diff --git a/src/web.rs b/src/web.rs index ce7ec20..dd0ee43 100644 --- a/src/web.rs +++ b/src/web.rs @@ -32,10 +32,7 @@ impl WebImpl { // `querySelector` only throws an error if the selector is invalid. .unwrap() .ok_or_else(|| { - SwBufError::PlatformError( - Some("No canvas found with the given id".into()), - None, - ) + SwBufError::PlatformError(Some("No canvas found with the given id".into()), None) })? // We already made sure this was a canvas in `querySelector`. .unchecked_into();