From 5eb240068a226ebae53e989c3e07a0ba9596d4c9 Mon Sep 17 00:00:00 2001 From: Corwin Date: Wed, 9 Aug 2023 21:06:54 +0100 Subject: [PATCH] video buffer using unsafe cell across ffi boundary --- emulator/mgba/src/lib.rs | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/emulator/mgba/src/lib.rs b/emulator/mgba/src/lib.rs index 2757d664..a1b68525 100644 --- a/emulator/mgba/src/lib.rs +++ b/emulator/mgba/src/lib.rs @@ -1,16 +1,20 @@ mod log; mod vfile; -use std::{ptr::NonNull, sync::atomic::{AtomicBool, Ordering}}; +use std::{ + cell::UnsafeCell, + ptr::NonNull, + sync::atomic::{AtomicBool, Ordering}, +}; -pub use log::{Logger, LogLevel}; +pub use log::{LogLevel, Logger}; pub use vfile::{file::FileBacked, memory::MemoryBacked, shared::Shared, MapFlag, VFile}; use vfile::VFileAlloc; pub struct MCore { core: NonNull, - video_buffer: Box<[u32]>, + video_buffer: UnsafeCell>, } impl Drop for MCore { @@ -51,17 +55,18 @@ impl MCore { unsafe { call_on_core!(core=>desiredVideoDimensions(&mut width, &mut height)) }; - let mut video_buffer = vec![ - 0; - (width * height * mgba_sys::BYTES_PER_PIXEL) as usize - / std::mem::size_of::() - ] - .into_boxed_slice(); + let mut video_buffer = UnsafeCell::new( + vec![ + 0; + (width * height * mgba_sys::BYTES_PER_PIXEL) as usize / std::mem::size_of::() + ] + .into_boxed_slice(), + ); unsafe { call_on_core!( core=>setVideoBuffer( - video_buffer.as_mut_ptr(), + video_buffer.get_mut().as_mut_ptr(), width as usize ) ) @@ -123,7 +128,9 @@ impl MCore { } pub fn video_buffer(&mut self) -> &[u32] { - self.video_buffer.as_ref() + // Safety: For the duration of this borrow, mgba can't be called into, + // so this reference can be taken. + unsafe { &*self.video_buffer.get() } } pub fn current_cycle(&mut self) -> u64 {