diff --git a/gb-vst/src/lib.rs b/gb-vst/src/lib.rs index 7c79e46..8d91398 100644 --- a/gb-vst/src/lib.rs +++ b/gb-vst/src/lib.rs @@ -7,10 +7,12 @@ use gb_emu_lib::{ AudioOutput, CgbRomType, DownsampleType, EmulatorCoreTrait, EmulatorMessage, EmulatorOptions, JoypadButtons, NoCamera, RomFile, SerialTarget, }, + renderer::RendererBackendManager, EmulatorCore, HEIGHT, WIDTH, }; use nih_plug::prelude::*; use nih_plug::{midi::MidiResult::Basic, params::persist::PersistentField}; + use serde::{Deserialize, Serialize}; use std::{ path::PathBuf, @@ -107,6 +109,7 @@ pub struct GameboyEmu { frame_receiver: Arc, key_handler: Arc, params: Arc, + renderer_manager: Arc>>>, } type Frame = Vec<[u8; 4]>; @@ -247,7 +250,7 @@ impl Plugin for GameboyEmu { ProcessStatus::KeepAlive } - fn editor(&mut self, _: AsyncExecutor) -> Option> { + fn editor(&mut self, _e: AsyncExecutor) -> Option> { let configs = access_config(); let size = Size::new( @@ -258,6 +261,7 @@ impl Plugin for GameboyEmu { Some(Box::new(Emulator::new( self.frame_receiver.clone(), self.key_handler.clone(), + self.renderer_manager.clone(), size, ))) } diff --git a/gb-vst/src/ui.rs b/gb-vst/src/ui.rs index a699efb..fc25801 100644 --- a/gb-vst/src/ui.rs +++ b/gb-vst/src/ui.rs @@ -2,7 +2,7 @@ use std::{ path::PathBuf, sync::{ mpsc::{self, Receiver, Sender}, - Arc, + Arc, Mutex, }, }; @@ -19,6 +19,7 @@ use crate::{access_config, Frame, FrameReceiver, JoypadInfo, JoypadSender, IS_CG pub struct Emulator { frame_receiver: Arc, joypad_sender: Arc, + manager: Arc>>>, size: Size, } @@ -26,11 +27,13 @@ impl Emulator { pub fn new( frame_receiver: Arc, joypad_sender: Arc, + manager: Arc>>>, size: Size, ) -> Self { Self { frame_receiver, joypad_sender, + manager, size, } } @@ -74,6 +77,8 @@ impl Editor for Emulator { (HEIGHT * scale_factor) as f64, ); + let m = self.manager.clone(); + Window::open_parented( &parent, WindowOpenOptions { @@ -87,15 +92,18 @@ impl Editor for Emulator { w, fr_cloned, js_cloned, + m, size, #[cfg(feature = "vulkan")] shader_path, ) + .0 }, ); Box::new(Self::new( self.frame_receiver.clone(), self.joypad_sender.clone(), + self.manager.clone(), size, )) } @@ -128,9 +136,10 @@ impl EmulatorWindow { window: &mut Window, frame_receiver: Arc, joypad_sender: Arc, + manager: Arc>>>, size: Size, #[cfg(feature = "vulkan")] shader_path: Option, - ) -> Self { + ) -> (Self, Arc) { let current_resolution = ResolutionData { real_width: size.width as u32, real_height: size.height as u32, @@ -139,29 +148,32 @@ impl EmulatorWindow { }; #[cfg(feature = "vulkan")] - let (manager, window_options) = { - use raw_window_handle::HasRawDisplayHandle; - ( - Arc::new(RendererBackendManager::new(window.raw_display_handle())), - WindowOptions { shader_path }, - ) - }; + let window_options = WindowOptions { shader_path }; #[cfg(feature = "pixels")] - let (manager, window_options) = - { (Arc::new(RendererBackendManager::new()), WindowOptions {}) }; + let window_options = WindowOptions {}; - let renderer = - RendererBackend::new(current_resolution, window, window_options, manager.clone()); + let mut guard = manager.lock().unwrap(); - Self { - renderer, - manager, - frame_receiver, - joypad_sender, - current_resolution, - } + let m = guard.get_or_insert_with(|| { + use raw_window_handle::HasRawDisplayHandle; + Arc::new(RendererBackendManager::new(window.raw_display_handle())) + }); + + let renderer = RendererBackend::new(current_resolution, window, window_options, m.clone()); + + ( + Self { + renderer, + manager: m.clone(), + frame_receiver, + joypad_sender, + current_resolution, + }, + m.clone(), + ) } } + impl WindowHandler for EmulatorWindow { fn on_frame(&mut self, _window: &mut Window) { if let Some(ref mut receiver) = *self.frame_receiver.lock().expect("failed to lock mutex") { @@ -209,7 +221,6 @@ impl WindowHandler for EmulatorWindow { EventStatus::Ignored } } - Event::Window(WindowEvent::WillClose) => EventStatus::Ignored, _ => EventStatus::Ignored, } }