diff --git a/crates/gpui/src/platform/mac/metal_renderer.rs b/crates/gpui/src/platform/mac/metal_renderer.rs index aa9992dfda02c..13db1bfff1cd9 100644 --- a/crates/gpui/src/platform/mac/metal_renderer.rs +++ b/crates/gpui/src/platform/mac/metal_renderer.rs @@ -24,7 +24,7 @@ const SHADERS_METALLIB: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/shader #[cfg(feature = "runtime_shaders")] const SHADERS_SOURCE_FILE: &'static str = include_str!(concat!(env!("OUT_DIR"), "/stitched_shaders.metal")); -const INSTANCE_BUFFER_SIZE: usize = 32 * 1024 * 1024; // This is an arbitrary decision. There's probably a more optimal value (maybe even we could adjust dynamically...) +const INSTANCE_BUFFER_SIZE: usize = 2 * 1024 * 1024; // This is an arbitrary decision. There's probably a more optimal value (maybe even we could adjust dynamically...) pub(crate) struct MetalRenderer { device: metal::Device, @@ -40,13 +40,13 @@ pub(crate) struct MetalRenderer { surfaces_pipeline_state: metal::RenderPipelineState, unit_vertices: metal::Buffer, #[allow(clippy::arc_with_non_send_sync)] - instance_buffers: Arc>>, + instance_buffer_pool: Arc>>, sprite_atlas: Arc, core_video_texture_cache: CVMetalTextureCache, } impl MetalRenderer { - pub fn new(is_opaque: bool) -> Self { + pub fn new(instance_buffer_pool: Arc>>) -> Self { let device: metal::Device = if let Some(device) = metal::Device::system_default() { device } else { @@ -58,7 +58,7 @@ impl MetalRenderer { layer.set_device(&device); layer.set_pixel_format(MTLPixelFormat::BGRA8Unorm); layer.set_presents_with_transaction(true); - layer.set_opaque(is_opaque); + layer.set_opaque(true); unsafe { let _: () = msg_send![&*layer, setAllowsNextDrawableTimeout: NO]; let _: () = msg_send![&*layer, setNeedsDisplayOnBoundsChange: YES]; @@ -181,7 +181,7 @@ impl MetalRenderer { polychrome_sprites_pipeline_state, surfaces_pipeline_state, unit_vertices, - instance_buffers: Arc::default(), + instance_buffer_pool, sprite_atlas, core_video_texture_cache, } @@ -211,7 +211,7 @@ impl MetalRenderer { ); return; }; - let mut instance_buffer = self.instance_buffers.lock().pop().unwrap_or_else(|| { + let mut instance_buffer = self.instance_buffer_pool.lock().pop().unwrap_or_else(|| { self.device.new_buffer( INSTANCE_BUFFER_SIZE as u64, MTLResourceOptions::StorageModeManaged, @@ -227,7 +227,8 @@ impl MetalRenderer { &mut instance_offset, command_buffer, ) else { - panic!("failed to rasterize {} paths", scene.paths().len()); + log::error!("failed to rasterize {} paths", scene.paths().len()); + return; }; let render_pass_descriptor = metal::RenderPassDescriptor::new(); @@ -314,7 +315,7 @@ impl MetalRenderer { }; if !ok { - panic!("scene too large: {} paths, {} shadows, {} quads, {} underlines, {} mono, {} poly, {} surfaces", + log::error!("scene too large: {} paths, {} shadows, {} quads, {} underlines, {} mono, {} poly, {} surfaces", scene.paths.len(), scene.shadows.len(), scene.quads.len(), @@ -322,7 +323,8 @@ impl MetalRenderer { scene.monochrome_sprites.len(), scene.polychrome_sprites.len(), scene.surfaces.len(), - ) + ); + break; } } @@ -333,11 +335,11 @@ impl MetalRenderer { length: instance_offset as NSUInteger, }); - let instance_buffers = self.instance_buffers.clone(); + let instance_buffer_pool = self.instance_buffer_pool.clone(); let instance_buffer = Cell::new(Some(instance_buffer)); let block = ConcreteBlock::new(move |_| { if let Some(instance_buffer) = instance_buffer.take() { - instance_buffers.lock().push(instance_buffer); + instance_buffer_pool.lock().push(instance_buffer); } }); let block = block.copy(); diff --git a/crates/gpui/src/platform/mac/platform.rs b/crates/gpui/src/platform/mac/platform.rs index 7c6f3df266036..0e3864065f167 100644 --- a/crates/gpui/src/platform/mac/platform.rs +++ b/crates/gpui/src/platform/mac/platform.rs @@ -146,6 +146,7 @@ pub(crate) struct MacPlatformState { foreground_executor: ForegroundExecutor, text_system: Arc, display_linker: MacDisplayLinker, + instance_buffer_pool: Arc>>, pasteboard: id, text_hash_pasteboard_type: id, metadata_pasteboard_type: id, @@ -176,6 +177,7 @@ impl MacPlatform { foreground_executor: ForegroundExecutor::new(dispatcher), text_system: Arc::new(MacTextSystem::new()), display_linker: MacDisplayLinker::new(), + instance_buffer_pool: Arc::default(), pasteboard: unsafe { NSPasteboard::generalPasteboard(nil) }, text_hash_pasteboard_type: unsafe { ns_string("zed-text-hash") }, metadata_pasteboard_type: unsafe { ns_string("zed-metadata") }, @@ -494,7 +496,13 @@ impl Platform for MacPlatform { handle: AnyWindowHandle, options: WindowOptions, ) -> Box { - Box::new(MacWindow::open(handle, options, self.foreground_executor())) + let instance_buffer_pool = self.0.lock().instance_buffer_pool.clone(); + Box::new(MacWindow::open( + handle, + options, + self.foreground_executor(), + instance_buffer_pool, + )) } fn set_display_link_output_callback( diff --git a/crates/gpui/src/platform/mac/window.rs b/crates/gpui/src/platform/mac/window.rs index 0e12dc4af00e3..bb8c08a8794cd 100644 --- a/crates/gpui/src/platform/mac/window.rs +++ b/crates/gpui/src/platform/mac/window.rs @@ -459,6 +459,7 @@ impl MacWindow { handle: AnyWindowHandle, options: WindowOptions, executor: ForegroundExecutor, + instance_buffer_pool: Arc>>, ) -> Self { unsafe { let pool = NSAutoreleasePool::new(nil); @@ -535,7 +536,7 @@ impl MacWindow { native_window, native_view: NonNull::new_unchecked(native_view as *mut _), display_link, - renderer: MetalRenderer::new(true), + renderer: MetalRenderer::new(instance_buffer_pool), kind: options.kind, request_frame_callback: None, event_callback: None,