diff --git a/Cargo.toml b/Cargo.toml index ef5745b..6859089 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,4 +8,5 @@ address = "0.11.0" clap = { version = "4.5.23", features = ["derive"] } image = "0.25.5" io-uring = "0.7.3" +libc = "0.2.169" tokio = "1.42.0" diff --git a/breakwater.png b/breakwater.png new file mode 100644 index 0000000..2754506 Binary files /dev/null and b/breakwater.png differ diff --git a/src/flutr.rs b/src/flutr.rs index 9003ef9..3b41492 100644 --- a/src/flutr.rs +++ b/src/flutr.rs @@ -1,16 +1,18 @@ -use crate::pixelmsgs::PixelMsgs; +use crate::pixelmsgs::PixelStringMsgs; use address::Host; -use io_uring::{opcode, types, IoUring}; +use io_uring::{opcode, types, IoUring, Submitter}; +use libc::c_void; +use libc::iovec; use std::{io::Write, net::TcpStream, os::fd::AsRawFd}; pub struct FlutR { stream: TcpStream, stream_fd: i32, - msgs: PixelMsgs, + msgs: PixelStringMsgs, } impl FlutR { - pub fn new(host: Host, port: u16, msgs: PixelMsgs) -> Result { + pub fn new(host: Host, port: u16, msgs: PixelStringMsgs) -> Result { let stream = TcpStream::connect(format!("{host}:{port}"))?; let stream_fd = stream.as_raw_fd(); Ok(FlutR { @@ -21,20 +23,45 @@ impl FlutR { } pub fn flut(&mut self) { - loop { - //self.write_sequential(); + unsafe { self.write_io_uring(); + //self.write_sequential(); } } fn write_sequential(&mut self) { - for msg in self.msgs.clone() { - let _ = self.stream.write(&msg); + loop { + for msg in self.msgs.clone() { + let _ = self.stream.write(&msg); + } + let _ = self.stream.flush(); } - let _ = self.stream.flush(); } - fn write_io_uring(&mut self) { - for msg in self.msgs.clone() {} + unsafe fn write_io_uring(&mut self) { + let mut ring = IoUring::new(8).unwrap(); + + let buffer_len: usize = self.msgs.len() * 11; + let buffer: iovec = iovec { + iov_base: self.msgs.as_mut_ptr() as *mut c_void, + iov_len: buffer_len, + }; + ring.submitter().register_buffers(&[buffer]); + + let write_op = opcode::WriteFixed::new( + io_uring::types::Fd(self.stream_fd), + buffer.iov_base as *const u8, + buffer_len as u32, + 0, + ) + .build(); + + loop { + while ring.submission().is_full() { + ring.submission().sync(); + } + ring.submission().push(&write_op).unwrap(); + ring.submit().unwrap(); + } } } diff --git a/src/main.rs b/src/main.rs index a58e3ae..38d8364 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,7 +10,7 @@ mod pixelmsgs; use flutr::FlutR; use pixelmsgs::Add; -use pixelmsgs::PixelMsgs; +use pixelmsgs::PixelStringMsgs; #[derive(Parser, Debug)] #[command(version, about, long_about = None)] @@ -31,9 +31,7 @@ fn main() { flutr.flut(); } -fn parse_image_to_msgs(path: &PathBuf) -> PixelMsgs { - let mut result = PixelMsgs::default(); - +fn parse_image_to_msgs(path: &PathBuf) -> PixelStringMsgs { let image_result = parse_image(path); let image = match image_result { @@ -42,6 +40,7 @@ fn parse_image_to_msgs(path: &PathBuf) -> PixelMsgs { }; let rgb_image = image.into_rgb8(); + let mut result = PixelStringMsgs::with_capacity(rgb_image.len()); for pixel in rgb_image.enumerate_pixels() { result.add(pixel); } diff --git a/src/pixelmsgs.rs b/src/pixelmsgs.rs index 604280c..8005999 100644 --- a/src/pixelmsgs.rs +++ b/src/pixelmsgs.rs @@ -2,8 +2,8 @@ use image::Rgb; pub type PixelBinaryMsg = [u8; 11]; pub type PixelBinaryMsgs = Vec; -pub type PixelStringMsg<'a> = &'a [u8]; -pub type PixelStringMsgs<'a> = Vec>; +pub type PixelStringMsg = Box<[u8]>; +pub type PixelStringMsgs = Vec; pub trait Add { fn add(&mut self, item: (u32, u32, &Rgb)); @@ -25,13 +25,16 @@ impl Add for PixelBinaryMsgs { } } -impl<'a> Add for PixelStringMsgs<'a> { +impl Add for PixelStringMsgs { fn add(&mut self, item: (u32, u32, &Rgb)) { let color: &Rgb = item.2; let r = color.0[0]; let g = color.0[1]; let b = color.0[2]; - let msg = format!("PX {} {} {r:02x}{g:02x}{b:02x}\n", item.0, item.1).as_bytes(); - self.push(msg.to_owned()); + let msg = format!("PX {} {} {r:02x}{g:02x}{b:02x}\n", item.0, item.1) + .as_bytes() + .to_vec() + .into_boxed_slice(); + self.push(msg); } }