mirror of
https://github.com/stickynotememo/wolf_renderer.git
synced 2026-07-30 06:46:03 +10:00
use memmap2
This commit is contained in:
Generated
+10
@@ -96,6 +96,15 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memmap2"
|
||||||
|
version = "0.9.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "744133e4a0e0a658e1374cf3bf8e415c4052a15a111acd372764c55b4177d490"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memoffset"
|
name = "memoffset"
|
||||||
version = "0.6.5"
|
version = "0.6.5"
|
||||||
@@ -381,6 +390,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"memfile",
|
"memfile",
|
||||||
|
"memmap2",
|
||||||
"shared_memory",
|
"shared_memory",
|
||||||
"wayland-client",
|
"wayland-client",
|
||||||
"wayland-protocols",
|
"wayland-protocols",
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ edition = "2024"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
libc = "0.2.177"
|
libc = "0.2.177"
|
||||||
memfile = "0.3.2"
|
memfile = "0.3.2"
|
||||||
|
memmap2 = "0.9.9"
|
||||||
shared_memory = "0.12.4"
|
shared_memory = "0.12.4"
|
||||||
wayland-client = "0.31"
|
wayland-client = "0.31"
|
||||||
wayland-protocols = { version = "0.32.9", features = ["client"] }
|
wayland-protocols = { version = "0.32.9", features = ["client"] }
|
||||||
|
|||||||
+65
-24
@@ -1,8 +1,11 @@
|
|||||||
#![feature(more_qualified_paths)]
|
#![feature(more_qualified_paths)]
|
||||||
|
use std::fs::File;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::{ffi::CString, thread::sleep};
|
use std::{ffi::CString, thread::sleep};
|
||||||
use std::os::fd::BorrowedFd;
|
use std::os::fd::BorrowedFd;
|
||||||
|
|
||||||
|
use memmap2::{MmapMut, MmapOptions};
|
||||||
|
|
||||||
use wayland_client::{
|
use wayland_client::{
|
||||||
Connection, Dispatch, EventQueue, Proxy, backend::ObjectId, delegate_noop, protocol::{
|
Connection, Dispatch, EventQueue, Proxy, backend::ObjectId, delegate_noop, protocol::{
|
||||||
wl_buffer::{self, WlBuffer},
|
wl_buffer::{self, WlBuffer},
|
||||||
@@ -31,7 +34,7 @@ const HEIGHT: i32 = 540;
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct State {
|
struct State {
|
||||||
exit: bool,
|
exit: bool,
|
||||||
ready: bool,
|
_ready: bool,
|
||||||
compositor: Option<WlCompositor>,
|
compositor: Option<WlCompositor>,
|
||||||
surface: Option<WlSurface>,
|
surface: Option<WlSurface>,
|
||||||
shm: Option<WlShm>,
|
shm: Option<WlShm>,
|
||||||
@@ -41,6 +44,7 @@ struct State {
|
|||||||
xdg_surface: Option<XdgSurface>,
|
xdg_surface: Option<XdgSurface>,
|
||||||
toplevel_surface: Option<XdgToplevel>,
|
toplevel_surface: Option<XdgToplevel>,
|
||||||
pool: Option<WlShmPool>,
|
pool: Option<WlShmPool>,
|
||||||
|
memory_map: Option<MmapMut>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Dispatch<wl_registry::WlRegistry, ()> for State {
|
impl Dispatch<wl_registry::WlRegistry, ()> for State {
|
||||||
@@ -120,6 +124,8 @@ impl Dispatch<WlShm, ()> for State {
|
|||||||
// Data races should not be possible as the compositor will
|
// Data races should not be possible as the compositor will
|
||||||
// not modify the buffer. (Non owners do not have write
|
// not modify the buffer. (Non owners do not have write
|
||||||
// permissions)
|
// permissions)
|
||||||
|
//
|
||||||
|
// TODO: Use shared_memory and implement FD return
|
||||||
|
|
||||||
let fildes = shm_open(name.as_ptr(), O_RDWR | O_CREAT, S_IRWXU | S_IROTH);
|
let fildes = shm_open(name.as_ptr(), O_RDWR | O_CREAT, S_IRWXU | S_IROTH);
|
||||||
if fildes <= 0 {
|
if fildes <= 0 {
|
||||||
@@ -129,6 +135,22 @@ impl Dispatch<WlShm, ()> for State {
|
|||||||
BorrowedFd::borrow_raw(fildes)
|
BorrowedFd::borrow_raw(fildes)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut shm_file = File::from(shm_fd.try_clone_to_owned().unwrap()); // Converts borrowed
|
||||||
|
// to owned. Are there problems with this?
|
||||||
|
|
||||||
|
let mut mmap = unsafe {
|
||||||
|
// SAFETY: This effectively creates a memory map from a raw
|
||||||
|
// pointer. As above, as long as the compositor does not
|
||||||
|
// mutate the underlying shared memory pool, mutations
|
||||||
|
// should be safe and not cause data races [undefined.race]
|
||||||
|
// https://doc.rust-lang.org/reference/behavior-considered-undefined.html#r-undefined.alias
|
||||||
|
MmapOptions::new()
|
||||||
|
.len(size as usize)
|
||||||
|
.map_mut(&shm_file)
|
||||||
|
.unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
state.memory_map = Some(mmap);
|
||||||
let shm_pool = proxy.create_pool(shm_fd, size.try_into().unwrap(), qhandle, *data);
|
let shm_pool = proxy.create_pool(shm_fd, size.try_into().unwrap(), qhandle, *data);
|
||||||
// TODO: Move drawing logic to event loop (double flush)
|
// TODO: Move drawing logic to event loop (double flush)
|
||||||
state.pool = Some(shm_pool);
|
state.pool = Some(shm_pool);
|
||||||
@@ -228,16 +250,17 @@ fn main() {
|
|||||||
|
|
||||||
let mut state = State {
|
let mut state = State {
|
||||||
exit: false,
|
exit: false,
|
||||||
ready: false,
|
_ready: false,
|
||||||
|
formats: vec![],
|
||||||
compositor: None,
|
compositor: None,
|
||||||
surface: None,
|
surface: None,
|
||||||
shm: None,
|
shm: None,
|
||||||
formats: vec![],
|
|
||||||
buffer: None,
|
buffer: None,
|
||||||
wm_base: None,
|
wm_base: None,
|
||||||
xdg_surface: None,
|
xdg_surface: None,
|
||||||
toplevel_surface: None,
|
toplevel_surface: None,
|
||||||
pool: None,
|
pool: None,
|
||||||
|
memory_map: None
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut event_queue: EventQueue<State> = conn.new_event_queue();
|
let mut event_queue: EventQueue<State> = conn.new_event_queue();
|
||||||
@@ -266,33 +289,29 @@ fn main() {
|
|||||||
surface.commit();
|
surface.commit();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
state.ready = if let (Some(_), Some(_), Some(_), Some(_), Some(_)) = (
|
|
||||||
&state.compositor,
|
|
||||||
&state.surface,
|
|
||||||
&state.shm,
|
|
||||||
&state.buffer,
|
|
||||||
&state.wm_base,
|
|
||||||
) {
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(shm_pool) = &state.pool {
|
if let Some(shm_pool) = &state.pool {
|
||||||
let channels: i32 = if state.formats.contains(&Format::Xrgb8888) {
|
let format = if state.formats.contains(&Format::Xrgb8888) {
|
||||||
4
|
Format::Xrgb8888
|
||||||
} else {
|
} else {
|
||||||
4
|
Format::Argb8888
|
||||||
}; // we know that the supported formats are only the two above, so we can safely assume that any format which is not Xrgb8888 is Argb8888, requiring 4 channels.
|
};
|
||||||
|
|
||||||
|
let channel_count = match format {
|
||||||
|
Format::Xrgb8888 => 4,
|
||||||
|
Format::Argb8888 => 4,
|
||||||
|
_ => unimplemented!("Other formats not supported")
|
||||||
|
};
|
||||||
// FIX: 3 channels won't work, even with Xrgb8888 for some reason
|
// FIX: 3 channels won't work, even with Xrgb8888 for some reason
|
||||||
// TODO: Update for more channels
|
// TODO: Update for more channels
|
||||||
|
|
||||||
let size: i32 = (WIDTH * HEIGHT * channels * 2).try_into().unwrap();
|
let size: i32 = (WIDTH * HEIGHT * channel_count * 2).try_into().unwrap();
|
||||||
|
|
||||||
let buffer = shm_pool.create_buffer(
|
let buffer = shm_pool.create_buffer(
|
||||||
0,
|
0,
|
||||||
WIDTH.try_into().unwrap(),
|
WIDTH.try_into().unwrap(),
|
||||||
HEIGHT.try_into().unwrap(),
|
HEIGHT.try_into().unwrap(),
|
||||||
(WIDTH * channels).try_into().unwrap(),
|
(WIDTH * channel_count).try_into().unwrap(),
|
||||||
if state.formats.contains(&Format::Xrgb8888) {
|
if state.formats.contains(&Format::Xrgb8888) {
|
||||||
Format::Xrgb8888
|
Format::Xrgb8888
|
||||||
} else {
|
} else {
|
||||||
@@ -304,10 +323,32 @@ fn main() {
|
|||||||
state.buffer = Some(buffer.clone());
|
state.buffer = Some(buffer.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
if state.ready {
|
state._ready = if let (Some(_), Some(_), Some(_), Some(_), Some(_), Some(mmap)) = (
|
||||||
dbg!("ready");
|
&state.compositor,
|
||||||
sleep(Duration::from_secs(2));
|
&state.surface,
|
||||||
return;
|
&state.shm,
|
||||||
|
&state.buffer,
|
||||||
|
&state.wm_base,
|
||||||
|
&mut state.memory_map,
|
||||||
|
) {
|
||||||
|
draw(mmap);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn draw(memory_map: &mut MmapMut) { // TODO: WlCallback on frame
|
||||||
|
let mut pixel: u64 = 0;
|
||||||
|
|
||||||
|
for byte in &mut **memory_map {
|
||||||
|
let pixel_offset = (pixel % 4) as u8;
|
||||||
|
pixel += 1;
|
||||||
|
|
||||||
|
*byte = match pixel_offset {
|
||||||
|
1 => 0,
|
||||||
|
_ => 255
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user