diff --git a/gpui/build.rs b/gpui/build.rs index b6d0f6ee8c..8cd0636557 100644 --- a/gpui/build.rs +++ b/gpui/build.rs @@ -51,7 +51,16 @@ fn compile_metal_shaders() { println!("cargo:rerun-if-changed={}", shader_path); let output = Command::new("xcrun") - .args(&["-sdk", "macosx", "metal", "-c", shader_path, "-o"]) + .args(&[ + "-sdk", + "macosx", + "metal", + "-gline-tables-only", + "-MO", + "-c", + shader_path, + "-o", + ]) .arg(&air_output_path) .output() .unwrap(); diff --git a/gpui/src/platform/mac/renderer.rs b/gpui/src/platform/mac/renderer.rs index 2a9ae35312..798f1462f0 100644 --- a/gpui/src/platform/mac/renderer.rs +++ b/gpui/src/platform/mac/renderer.rs @@ -278,7 +278,7 @@ impl Renderer { .or_insert_with(Vec::new) .push(shaders::GPUISprite { origin: (glyph.origin * scene.scale_factor()).to_float2(), - size: (bounds.size().to_f32() * scene.scale_factor()).to_float2(), + size: bounds.size().to_float2(), atlas_origin: bounds.origin().to_float2(), color: glyph.color.to_uchar4(), }); @@ -293,18 +293,15 @@ impl Renderer { 0, ); ctx.command_encoder.set_vertex_bytes( - shaders::GPUISpriteVertexInputIndex_GPUISpriteVertexInputIndexUniforms as u64, - mem::size_of::() as u64, - [shaders::GPUIUniforms { - viewport_size: ctx.drawable_size.to_float2(), - }] - .as_ptr() as *const c_void, + shaders::GPUISpriteVertexInputIndex_GPUISpriteVertexInputIndexViewportSize as u64, + mem::size_of::() as u64, + [ctx.drawable_size.to_float2()].as_ptr() as *const c_void, + ); + ctx.command_encoder.set_vertex_bytes( + shaders::GPUISpriteVertexInputIndex_GPUISpriteVertexInputIndexAtlasSize as u64, + mem::size_of::() as u64, + [self.sprite_cache.atlas_size().to_float2()].as_ptr() as *const c_void, ); - - let buffer_contents = unsafe { - (self.instances.contents() as *mut u8).offset(*offset as isize) - as *mut shaders::GPUISprite - }; for (atlas_id, sprites) in sprites_by_atlas { align_offset(offset); @@ -327,6 +324,9 @@ impl Renderer { ); unsafe { + let buffer_contents = (self.instances.contents() as *mut u8) + .offset(*offset as isize) + as *mut shaders::GPUISprite; std::ptr::copy_nonoverlapping(sprites.as_ptr(), buffer_contents, sprites.len()); } self.instances.did_modify_range(NSRange { @@ -430,10 +430,7 @@ mod shaders { impl ToFloat2 for Vector2I { fn to_float2(&self) -> vector_float2 { - let mut output = self.y() as vector_float2; - output <<= 32; - output |= self.x() as vector_float2; - output + self.to_f32().to_float2() } } diff --git a/gpui/src/platform/mac/shaders/shaders.h b/gpui/src/platform/mac/shaders/shaders.h index cabb9304de..5b07a9e839 100644 --- a/gpui/src/platform/mac/shaders/shaders.h +++ b/gpui/src/platform/mac/shaders/shaders.h @@ -39,7 +39,8 @@ typedef struct { typedef enum { GPUISpriteVertexInputIndexVertices = 0, GPUISpriteVertexInputIndexSprites = 1, - GPUISpriteVertexInputIndexUniforms = 2, + GPUISpriteVertexInputIndexViewportSize = 2, + GPUISpriteVertexInputIndexAtlasSize = 3, } GPUISpriteVertexInputIndex; typedef enum { diff --git a/gpui/src/platform/mac/shaders/shaders.metal b/gpui/src/platform/mac/shaders/shaders.metal index 422a9faf40..464328ba7b 100644 --- a/gpui/src/platform/mac/shaders/shaders.metal +++ b/gpui/src/platform/mac/shaders/shaders.metal @@ -151,13 +151,14 @@ vertex SpriteFragmentInput sprite_vertex( uint sprite_id [[instance_id]], constant float2 *unit_vertices [[buffer(GPUISpriteVertexInputIndexVertices)]], constant GPUISprite *sprites [[buffer(GPUISpriteVertexInputIndexSprites)]], - constant GPUIUniforms *uniforms [[buffer(GPUISpriteVertexInputIndexUniforms)]] + constant float2 *viewport_size [[buffer(GPUISpriteVertexInputIndexViewportSize)]], + constant float2 *atlas_size [[buffer(GPUISpriteVertexInputIndexAtlasSize)]] ) { float2 unit_vertex = unit_vertices[unit_vertex_id]; GPUISprite sprite = sprites[sprite_id]; float2 position = unit_vertex * sprite.size + sprite.origin; - float2 atlas_position = unit_vertex * sprite.size + sprite.atlas_origin; - float4 device_position = to_device_position(position, uniforms->viewport_size); + float4 device_position = to_device_position(position, *viewport_size); + float2 atlas_position = (unit_vertex * sprite.size + sprite.atlas_origin) / *atlas_size; return SpriteFragmentInput { device_position, @@ -172,6 +173,7 @@ fragment float4 sprite_fragment( ) { constexpr sampler atlas_sampler(mag_filter::linear, min_filter::linear); float4 color = input.color; - color.a *= atlas.sample(atlas_sampler, input.atlas_position).r; + float4 mask = atlas.sample(atlas_sampler, input.atlas_position); + color.a *= mask.a; return color; } diff --git a/gpui/src/platform/mac/sprite_cache.rs b/gpui/src/platform/mac/sprite_cache.rs index c47c0cbf96..97bed4141c 100644 --- a/gpui/src/platform/mac/sprite_cache.rs +++ b/gpui/src/platform/mac/sprite_cache.rs @@ -39,6 +39,10 @@ impl SpriteCache { } } + pub fn atlas_size(&self) -> Vector2I { + self.atlas_size + } + pub fn render_glyph( &mut self, font_id: FontId, @@ -64,12 +68,12 @@ impl SpriteCache { let atlas = atlasses.last_mut().unwrap(); if let Some(bounds) = atlas.try_insert(size, &mask) { - Some((atlasses.len() - 1, bounds)) + Some((atlasses.len() - 1, RectI::new(bounds.origin(), size))) } else { let mut atlas = Atlas::new(device, atlas_size); let bounds = atlas.try_insert(size, &mask).unwrap(); atlasses.push(atlas); - Some((atlasses.len() - 1, bounds)) + Some((atlasses.len() - 1, RectI::new(bounds.origin(), size))) } }) .clone()