From 7b610f8dd8c2fb250e945943594249c1e1ffa332 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 9 Oct 2023 19:50:48 +0200 Subject: [PATCH] WIP --- crates/gpui3/src/platform.rs | 4 +- .../gpui3/src/platform/mac/metal_renderer.rs | 107 +++++++++++++++--- crates/gpui3/src/scene.rs | 6 +- 3 files changed, 98 insertions(+), 19 deletions(-) diff --git a/crates/gpui3/src/platform.rs b/crates/gpui3/src/platform.rs index 1589a26ee91cb25fae27c7d3621c2ecdb8c71e8a..fb90bb9c6b51b8e677a042945682fa13837ab1cf 100644 --- a/crates/gpui3/src/platform.rs +++ b/crates/gpui3/src/platform.rs @@ -245,7 +245,7 @@ pub struct AtlasTile { pub(crate) bounds: Bounds, } -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[repr(C)] pub(crate) struct AtlasTextureId { // We use u32 instead of usize for Metal Shader Language compatibility @@ -253,7 +253,7 @@ pub(crate) struct AtlasTextureId { pub(crate) kind: AtlasTextureKind, } -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[repr(C)] pub(crate) enum AtlasTextureKind { Monochrome = 0, diff --git a/crates/gpui3/src/platform/mac/metal_renderer.rs b/crates/gpui3/src/platform/mac/metal_renderer.rs index f4c735c6068250eb786f0c4b8679ada19308e85b..4dd3250f08c4b0acdd11189e61273c13e71942a9 100644 --- a/crates/gpui3/src/platform/mac/metal_renderer.rs +++ b/crates/gpui3/src/platform/mac/metal_renderer.rs @@ -1,7 +1,7 @@ use crate::{ - point, size, AtlasTextureId, AtlasTextureKind, AtlasTile, DevicePixels, MetalAtlas, - MonochromeSprite, PathId, PolychromeSprite, PrimitiveBatch, Quad, Scene, Shadow, Size, - Underline, + point, size, AtlasTextureId, AtlasTextureKind, AtlasTile, Bounds, ContentMask, DevicePixels, + MetalAtlas, MonochromeSprite, Path, PathId, PathVertex, PolychromeSprite, PrimitiveBatch, Quad, + ScaledPixels, Scene, Shadow, Size, Underline, }; use cocoa::{ base::{NO, YES}, @@ -170,6 +170,9 @@ impl MetalRenderer { }; let command_queue = self.command_queue.clone(); let command_buffer = command_queue.new_command_buffer(); + let mut instance_offset = 0; + + let path_tiles = self.rasterize_paths(scene.paths(), &mut instance_offset, &command_buffer); let render_pass_descriptor = metal::RenderPassDescriptor::new(); let color_attachment = render_pass_descriptor @@ -192,17 +195,6 @@ impl MetalRenderer { znear: 0.0, zfar: 1.0, }); - - let mut instance_offset = 0; - - let mut path_tiles: HashMap = HashMap::default(); - for path in scene.paths() { - let tile = self - .sprite_atlas - .allocate(path.bounds.size.map(Into::into), AtlasTextureKind::Path); - path_tiles.insert(path.id, tile); - } - for batch in scene.batches() { match batch { PrimitiveBatch::Shadows(shadows) => { @@ -266,6 +258,93 @@ impl MetalRenderer { drawable.present(); } + fn rasterize_paths( + &mut self, + paths: &[Path], + offset: &mut usize, + command_buffer: &metal::CommandBufferRef, + ) -> HashMap { + let mut tiles = HashMap::default(); + let mut vertices_by_texture_id = HashMap::default(); + for path in paths { + let tile = self + .sprite_atlas + .allocate(path.bounds.size.map(Into::into), AtlasTextureKind::Path); + vertices_by_texture_id + .entry(tile.texture_id) + .or_insert(Vec::new()) + .extend(path.vertices.iter().map(|vertex| PathVertex { + xy_position: vertex.xy_position - path.bounds.origin + + tile.bounds.origin.map(Into::into), + st_position: vertex.st_position, + content_mask: ContentMask { + bounds: Bounds { + origin: vertex.xy_position - path.bounds.origin + + tile.bounds.origin.map(Into::into), + size: vertex.content_mask.bounds.size, + }, + }, + })); + tiles.insert(path.id, tile); + } + + for (texture_id, vertices) in vertices_by_texture_id { + todo!(); + // align_offset(offset); + // let next_offset = *offset + vertices.len() * mem::size_of::>(); + // assert!( + // next_offset <= INSTANCE_BUFFER_SIZE, + // "instance buffer exhausted" + // ); + + // let render_pass_descriptor = metal::RenderPassDescriptor::new(); + // let color_attachment = render_pass_descriptor + // .color_attachments() + // .object_at(0) + // .unwrap(); + + // let texture = self.sprite_atlas.metal_texture(texture_id); + // color_attachment.set_texture(Some(&texture)); + // color_attachment.set_load_action(metal::MTLLoadAction::Clear); + // color_attachment.set_store_action(metal::MTLStoreAction::Store); + // color_attachment.set_clear_color(metal::MTLClearColor::new(0., 0., 0., 1.)); + // let command_encoder = command_buffer.new_render_command_encoder(render_pass_descriptor); + // command_encoder.set_render_pipeline_state(&self.path_atlas_pipeline_state); + // command_encoder.set_vertex_buffer( + // shaders::GPUIPathAtlasVertexInputIndex_GPUIPathAtlasVertexInputIndexVertices as u64, + // Some(&self.instances), + // *offset as u64, + // ); + // command_encoder.set_vertex_bytes( + // shaders::GPUIPathAtlasVertexInputIndex_GPUIPathAtlasVertexInputIndexAtlasSize + // as u64, + // mem::size_of::() as u64, + // [vec2i(texture.width() as i32, texture.height() as i32).to_float2()].as_ptr() + // as *const c_void, + // ); + + // let buffer_contents = unsafe { + // (self.instances.contents() as *mut u8).add(*offset) as *mut shaders::GPUIPathVertex + // }; + + // for (ix, vertex) in vertices.iter().enumerate() { + // unsafe { + // *buffer_contents.add(ix) = *vertex; + // } + // } + + // command_encoder.draw_primitives( + // metal::MTLPrimitiveType::Triangle, + // 0, + // vertices.len() as u64, + // ); + // command_encoder.end_encoding(); + // *offset = next_offset; + } + + tiles + } + fn draw_shadows( &mut self, shadows: &[Shadow], diff --git a/crates/gpui3/src/scene.rs b/crates/gpui3/src/scene.rs index 11e121413ef29e0bec8aa0444be9cabce92954b7..aa5bf002ddc9a1aebdf0d62c6c1a38c776d344c2 100644 --- a/crates/gpui3/src/scene.rs +++ b/crates/gpui3/src/scene.rs @@ -180,8 +180,8 @@ pub(crate) struct Scene { } impl Scene { - pub fn paths(&self) -> impl Iterator> { - self.paths.iter() + pub fn paths(&self) -> &[Path] { + &self.paths } pub fn batches(&self) -> impl Iterator { @@ -678,7 +678,7 @@ impl From> for Primitive { } } -#[derive(Debug)] +#[derive(Clone, Debug)] #[repr(C)] pub struct PathVertex { pub(crate) xy_position: Point

,