Boop

Conrad Irwin created

Change summary

crates/gpui/src/platform/mac/metal_renderer.rs | 70 +++++++++++--------
1 file changed, 41 insertions(+), 29 deletions(-)

Detailed changes

crates/gpui/src/platform/mac/metal_renderer.rs 🔗

@@ -18,7 +18,7 @@ use smallvec::SmallVec;
 use std::{ffi::c_void, mem, ptr, sync::Arc};
 
 const SHADERS_METALLIB: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/shaders.metallib"));
-const INSTANCE_BUFFER_SIZE: usize = 8192 * 1024; // This is an arbitrary decision. There's probably a more optimal value.
+const INSTANCE_BUFFER_SIZE: usize = 8192 * 1024; // This is an arbitrary decision. There's probably a more optimal value. []
 
 pub(crate) struct MetalRenderer {
     layer: metal::MetalLayer,
@@ -429,6 +429,13 @@ impl MetalRenderer {
 
         let shadow_bytes_len = std::mem::size_of_val(shadows);
         let buffer_contents = unsafe { (self.instances.contents() as *mut u8).add(*offset) };
+
+        let next_offset = *offset + shadow_bytes_len;
+        assert!(
+            next_offset <= INSTANCE_BUFFER_SIZE,
+            "instance buffer exhausted"
+        );
+
         unsafe {
             ptr::copy_nonoverlapping(
                 shadows.as_ptr() as *const u8,
@@ -437,12 +444,6 @@ impl MetalRenderer {
             );
         }
 
-        let next_offset = *offset + shadow_bytes_len;
-        assert!(
-            next_offset <= INSTANCE_BUFFER_SIZE,
-            "instance buffer exhausted"
-        );
-
         command_encoder.draw_primitives_instanced(
             metal::MTLPrimitiveType::Triangle,
             0,
@@ -489,15 +490,15 @@ impl MetalRenderer {
 
         let quad_bytes_len = std::mem::size_of_val(quads);
         let buffer_contents = unsafe { (self.instances.contents() as *mut u8).add(*offset) };
-        unsafe {
-            ptr::copy_nonoverlapping(quads.as_ptr() as *const u8, buffer_contents, quad_bytes_len);
-        }
 
         let next_offset = *offset + quad_bytes_len;
         assert!(
             next_offset <= INSTANCE_BUFFER_SIZE,
             "instance buffer exhausted"
         );
+        unsafe {
+            ptr::copy_nonoverlapping(quads.as_ptr() as *const u8, buffer_contents, quad_bytes_len);
+        }
 
         command_encoder.draw_primitives_instanced(
             metal::MTLPrimitiveType::Triangle,
@@ -586,23 +587,33 @@ impl MetalRenderer {
                 command_encoder
                     .set_fragment_texture(SpriteInputIndex::AtlasTexture as u64, Some(&texture));
 
+                // hypothesis: sprites.as_ptr() does something bogus sometimes?
+                //
                 let sprite_bytes_len = mem::size_of::<MonochromeSprite>() * sprites.len();
+                let next_offset = *offset + sprite_bytes_len;
+                assert!(
+                    next_offset <= INSTANCE_BUFFER_SIZE,
+                    "instance buffer exhausted"
+                );
                 let buffer_contents =
                     unsafe { (self.instances.contents() as *mut u8).add(*offset) };
-                unsafe {
-                    ptr::copy_nonoverlapping(
-                        sprites.as_ptr() as *const u8,
-                        buffer_contents,
-                        sprite_bytes_len,
-                    );
-                }
 
+                // buffer_contents.len() < spite_bytes_len must be out of range.
+                // PANIC HERE!
                 let next_offset = *offset + sprite_bytes_len;
                 assert!(
                     next_offset <= INSTANCE_BUFFER_SIZE,
                     "instance buffer exhausted"
                 );
 
+                unsafe {
+                    ptr::copy_nonoverlapping(
+                        sprites.as_ptr() as *const u8, //src
+                        buffer_contents,               //dest
+                        sprite_bytes_len,              // count
+                    );
+                }
+
                 command_encoder.draw_primitives_instanced(
                     metal::MTLPrimitiveType::Triangle,
                     0,
@@ -723,6 +734,13 @@ impl MetalRenderer {
 
         let sprite_bytes_len = std::mem::size_of_val(sprites);
         let buffer_contents = unsafe { (self.instances.contents() as *mut u8).add(*offset) };
+
+        let next_offset = *offset + sprite_bytes_len;
+        assert!(
+            next_offset <= INSTANCE_BUFFER_SIZE,
+            "instance buffer exhausted"
+        );
+
         unsafe {
             ptr::copy_nonoverlapping(
                 sprites.as_ptr() as *const u8,
@@ -731,12 +749,6 @@ impl MetalRenderer {
             );
         }
 
-        let next_offset = *offset + sprite_bytes_len;
-        assert!(
-            next_offset <= INSTANCE_BUFFER_SIZE,
-            "instance buffer exhausted"
-        );
-
         command_encoder.draw_primitives_instanced(
             metal::MTLPrimitiveType::Triangle,
             0,
@@ -794,6 +806,12 @@ impl MetalRenderer {
 
         let sprite_bytes_len = std::mem::size_of_val(sprites);
         let buffer_contents = unsafe { (self.instances.contents() as *mut u8).add(*offset) };
+
+        let next_offset = *offset + sprite_bytes_len;
+        assert!(
+            next_offset <= INSTANCE_BUFFER_SIZE,
+            "instance buffer exhausted"
+        );
         unsafe {
             ptr::copy_nonoverlapping(
                 sprites.as_ptr() as *const u8,
@@ -802,12 +820,6 @@ impl MetalRenderer {
             );
         }
 
-        let next_offset = *offset + sprite_bytes_len;
-        assert!(
-            next_offset <= INSTANCE_BUFFER_SIZE,
-            "instance buffer exhausted"
-        );
-
         command_encoder.draw_primitives_instanced(
             metal::MTLPrimitiveType::Triangle,
             0,