From 1e0ff653373ae2b89a75b7288c946771022b5a55 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 3 Oct 2023 20:19:59 -0600 Subject: [PATCH] Checkpoint --- crates/gpui3/src/platform.rs | 26 ++++++++++++++----- crates/gpui3/src/platform/mac/metal_atlas.rs | 22 +++++++--------- .../gpui3/src/platform/mac/metal_renderer.rs | 7 +++-- crates/gpui3/src/platform/mac/text_system.rs | 10 +++---- crates/gpui3/src/platform/mac/window.rs | 12 ++++----- crates/gpui3/src/text_system.rs | 10 +++---- crates/gpui3/src/window.rs | 16 +++++++----- 7 files changed, 57 insertions(+), 46 deletions(-) diff --git a/crates/gpui3/src/platform.rs b/crates/gpui3/src/platform.rs index 8fd70ba44168e1530b07b6c50646365a7ca1a8aa..718056e152537f433e7025640d6a39b42809f062 100644 --- a/crates/gpui3/src/platform.rs +++ b/crates/gpui3/src/platform.rs @@ -6,8 +6,8 @@ mod mac; mod test; use crate::{ - AnyWindowHandle, Bounds, DevicePixels, Font, FontId, FontMetrics, GlyphId, GlyphRasterParams, - Pixels, Point, Result, Scene, ShapedLine, SharedString, Size, + AnyWindowHandle, Bounds, DevicePixels, Font, FontId, FontMetrics, GlyphId, Pixels, Point, + RenderGlyphParams, Result, Scene, ShapedLine, SharedString, Size, }; use anyhow::anyhow; use async_task::Runnable; @@ -147,7 +147,7 @@ pub trait PlatformWindow { fn is_topmost_for_position(&self, position: Point) -> bool; fn draw(&self, scene: Scene); - fn glyph_atlas(&self) -> Arc>; + fn glyph_atlas(&self) -> Arc; } pub trait PlatformDispatcher: Send + Sync { @@ -163,8 +163,8 @@ pub trait PlatformTextSystem: Send + Sync { fn typographic_bounds(&self, font_id: FontId, glyph_id: GlyphId) -> Result>; fn advance(&self, font_id: FontId, glyph_id: GlyphId) -> Result>; fn glyph_for_char(&self, font_id: FontId, ch: char) -> Option; - fn glyph_raster_bounds(&self, params: &GlyphRasterParams) -> Result>; - fn rasterize_glyph(&self, params: &GlyphRasterParams) -> Result<(Size, Vec)>; + fn glyph_raster_bounds(&self, params: &RenderGlyphParams) -> Result>; + fn rasterize_glyph(&self, params: &RenderGlyphParams) -> Result<(Size, Vec)>; fn layout_line(&self, text: &str, font_size: Pixels, runs: &[(usize, FontId)]) -> ShapedLine; fn wrap_line( &self, @@ -175,10 +175,22 @@ pub trait PlatformTextSystem: Send + Sync { ) -> Vec; } -pub trait PlatformAtlas: Send + Sync { +#[derive(PartialEq, Eq, Hash, Clone)] +pub enum AtlasKey { + Glyph(RenderGlyphParams), + // Svg(RenderSvgParams), +} + +impl From for AtlasKey { + fn from(params: RenderGlyphParams) -> Self { + Self::Glyph(params) + } +} + +pub trait PlatformAtlas: Send + Sync { fn get_or_insert_with( &self, - key: &Key, + key: &AtlasKey, build: &mut dyn FnMut() -> Result<(Size, Vec)>, ) -> Result; diff --git a/crates/gpui3/src/platform/mac/metal_atlas.rs b/crates/gpui3/src/platform/mac/metal_atlas.rs index 7f649800eada0e8daf668172b4a0f3541f3acc4d..3753be5bfd7b6a60865620ee23feb3656222c04a 100644 --- a/crates/gpui3/src/platform/mac/metal_atlas.rs +++ b/crates/gpui3/src/platform/mac/metal_atlas.rs @@ -1,4 +1,6 @@ -use crate::{AtlasTextureId, AtlasTile, Bounds, DevicePixels, PlatformAtlas, Point, Size}; +use crate::{ + AtlasKey, AtlasTextureId, AtlasTile, Bounds, DevicePixels, PlatformAtlas, Point, Size, +}; use anyhow::{anyhow, Result}; use collections::HashMap; use derive_more::{Deref, DerefMut}; @@ -7,11 +9,10 @@ use foreign_types::ForeignType; use metal::{Device, TextureDescriptor}; use objc::{msg_send, sel, sel_impl}; use parking_lot::Mutex; -use std::hash::Hash; -pub struct MetalAtlas(Mutex>); +pub struct MetalAtlas(Mutex); -impl MetalAtlas { +impl MetalAtlas { pub fn new( size: Size, pixel_format: metal::MTLPixelFormat, @@ -34,20 +35,17 @@ impl MetalAtlas { } } -struct MetalAtlasState { +struct MetalAtlasState { device: AssertSend, texture_descriptor: AssertSend, textures: Vec, - tiles_by_key: HashMap, + tiles_by_key: HashMap, } -impl PlatformAtlas for MetalAtlas -where - Key: Clone + Eq + Hash + Send, -{ +impl PlatformAtlas for MetalAtlas { fn get_or_insert_with( &self, - key: &Key, + key: &AtlasKey, build: &mut dyn FnMut() -> Result<(Size, Vec)>, ) -> Result { let mut lock = self.0.lock(); @@ -75,7 +73,7 @@ where } } -impl MetalAtlasState { +impl MetalAtlasState { fn push_texture(&mut self, min_size: Size) -> &mut MetalAtlasTexture { let default_atlas_size = Size { width: self.texture_descriptor.width().into(), diff --git a/crates/gpui3/src/platform/mac/metal_renderer.rs b/crates/gpui3/src/platform/mac/metal_renderer.rs index a61c73156fb8cc7b72ffeb8fdcd3d3069c27bccb..d88e27e8dc49096a6c0388fd6a30ebfb451f2e70 100644 --- a/crates/gpui3/src/platform/mac/metal_renderer.rs +++ b/crates/gpui3/src/platform/mac/metal_renderer.rs @@ -1,6 +1,5 @@ use crate::{ - point, size, AtlasTextureId, DevicePixels, GlyphRasterParams, MetalAtlas, MonochromeSprite, - Quad, Scene, Size, + point, size, AtlasTextureId, DevicePixels, MetalAtlas, MonochromeSprite, Quad, Scene, Size, }; use cocoa::{ base::{NO, YES}, @@ -21,7 +20,7 @@ pub struct MetalRenderer { sprites_pipeline_state: metal::RenderPipelineState, unit_vertices: metal::Buffer, instances: metal::Buffer, - glyph_atlas: Arc>, + glyph_atlas: Arc, } impl MetalRenderer { @@ -124,7 +123,7 @@ impl MetalRenderer { &*self.layer } - pub fn glyph_atlas(&self) -> &Arc> { + pub fn glyph_atlas(&self) -> &Arc { &self.glyph_atlas } diff --git a/crates/gpui3/src/platform/mac/text_system.rs b/crates/gpui3/src/platform/mac/text_system.rs index 29c97f4754bfafde61cfa9d9aa444cfee8cb7213..7dd13d52fba69c61e9dfa72998268b82d7181001 100644 --- a/crates/gpui3/src/platform/mac/text_system.rs +++ b/crates/gpui3/src/platform/mac/text_system.rs @@ -1,6 +1,6 @@ use crate::{ point, px, size, Bounds, DevicePixels, Font, FontFeatures, FontId, FontMetrics, FontStyle, - FontWeight, GlyphId, GlyphRasterParams, Pixels, PlatformTextSystem, Point, Result, ShapedGlyph, + FontWeight, GlyphId, Pixels, PlatformTextSystem, Point, RenderGlyphParams, Result, ShapedGlyph, ShapedLine, ShapedRun, SharedString, Size, SUBPIXEL_VARIANTS, }; use anyhow::anyhow; @@ -134,13 +134,13 @@ impl PlatformTextSystem for MacTextSystem { self.0.read().glyph_for_char(font_id, ch) } - fn glyph_raster_bounds(&self, params: &GlyphRasterParams) -> Result> { + fn glyph_raster_bounds(&self, params: &RenderGlyphParams) -> Result> { self.0.read().raster_bounds(params) } fn rasterize_glyph( &self, - glyph_id: &GlyphRasterParams, + glyph_id: &RenderGlyphParams, ) -> Result<(Size, Vec)> { self.0.read().rasterize_glyph(glyph_id) } @@ -234,7 +234,7 @@ impl MacTextSystemState { }) } - fn raster_bounds(&self, params: &GlyphRasterParams) -> Result> { + fn raster_bounds(&self, params: &RenderGlyphParams) -> Result> { let font = &self.fonts[params.font_id.0]; let scale = Transform2F::from_scale(params.scale_factor); Ok(font @@ -248,7 +248,7 @@ impl MacTextSystemState { .into()) } - fn rasterize_glyph(&self, params: &GlyphRasterParams) -> Result<(Size, Vec)> { + fn rasterize_glyph(&self, params: &RenderGlyphParams) -> Result<(Size, Vec)> { let glyph_bounds = self.raster_bounds(params)?; if glyph_bounds.size.width.0 == 0 || glyph_bounds.size.height.0 == 0 { Err(anyhow!("glyph bounds are empty")) diff --git a/crates/gpui3/src/platform/mac/window.rs b/crates/gpui3/src/platform/mac/window.rs index 6e87543fc94a7a423052d7b06f9e1ac349de7b80..a669b1cf485736e2a06972ab2306c64593dc03f5 100644 --- a/crates/gpui3/src/platform/mac/window.rs +++ b/crates/gpui3/src/platform/mac/window.rs @@ -1,10 +1,10 @@ use super::{ns_string, MetalRenderer, NSRange}; use crate::{ - point, px, size, AnyWindowHandle, Bounds, Event, GlyphRasterParams, KeyDownEvent, Keystroke, - MacScreen, Modifiers, ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMovedEvent, - MouseUpEvent, NSRectExt, Pixels, Platform, PlatformAtlas, PlatformDispatcher, - PlatformInputHandler, PlatformScreen, PlatformWindow, Point, Scene, Size, Timer, - WindowAppearance, WindowBounds, WindowKind, WindowOptions, WindowPromptLevel, + point, px, size, AnyWindowHandle, Bounds, Event, KeyDownEvent, Keystroke, MacScreen, Modifiers, + ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMovedEvent, MouseUpEvent, NSRectExt, + Pixels, Platform, PlatformAtlas, PlatformDispatcher, PlatformInputHandler, PlatformScreen, + PlatformWindow, Point, Scene, Size, Timer, WindowAppearance, WindowBounds, WindowKind, + WindowOptions, WindowPromptLevel, }; use block::ConcreteBlock; use cocoa::{ @@ -886,7 +886,7 @@ impl PlatformWindow for MacWindow { } } - fn glyph_atlas(&self) -> Arc> { + fn glyph_atlas(&self) -> Arc { self.0.lock().renderer.glyph_atlas().clone() } } diff --git a/crates/gpui3/src/text_system.rs b/crates/gpui3/src/text_system.rs index 4529214ea710e7fce3917c7a7e38d162b7959c65..6deaad925c41b1de5c95feb02d3b7feeefc735bd 100644 --- a/crates/gpui3/src/text_system.rs +++ b/crates/gpui3/src/text_system.rs @@ -215,13 +215,13 @@ impl TextSystem { }) } - pub fn raster_bounds(&self, params: &GlyphRasterParams) -> Result> { + pub fn raster_bounds(&self, params: &RenderGlyphParams) -> Result> { self.platform_text_system.glyph_raster_bounds(params) } pub fn rasterize_glyph( &self, - glyph_id: &GlyphRasterParams, + glyph_id: &RenderGlyphParams, ) -> Result<(Size, Vec)> { self.platform_text_system.rasterize_glyph(glyph_id) } @@ -384,7 +384,7 @@ pub struct ShapedGlyph { } #[derive(Clone, Debug, PartialEq)] -pub struct GlyphRasterParams { +pub struct RenderGlyphParams { pub(crate) font_id: FontId, pub(crate) glyph_id: GlyphId, pub(crate) font_size: Pixels, @@ -392,9 +392,9 @@ pub struct GlyphRasterParams { pub(crate) scale_factor: f32, } -impl Eq for GlyphRasterParams {} +impl Eq for RenderGlyphParams {} -impl Hash for GlyphRasterParams { +impl Hash for RenderGlyphParams { fn hash(&self, state: &mut H) { self.font_id.0.hash(state); self.glyph_id.0.hash(state); diff --git a/crates/gpui3/src/window.rs b/crates/gpui3/src/window.rs index 34048b54519a8c80509d31698ae9b20897860748..2e2f6eea5441efe21b3f02128d25ebfed4b1aa87 100644 --- a/crates/gpui3/src/window.rs +++ b/crates/gpui3/src/window.rs @@ -1,9 +1,9 @@ use crate::{ px, AnyView, AppContext, AvailableSpace, BorrowAppContext, Bounds, Context, Corners, Effect, - Element, EntityId, FontId, GlyphId, GlyphRasterParams, Handle, Hsla, IsZero, LayerId, LayoutId, - MainThread, MainThreadOnly, MonochromeSprite, Pixels, PlatformAtlas, PlatformWindow, Point, - Reference, ScaledPixels, Scene, Size, Style, TaffyLayoutEngine, WeakHandle, WindowOptions, - SUBPIXEL_VARIANTS, + Element, EntityId, FontId, GlyphId, Handle, Hsla, IsZero, LayerId, LayoutId, MainThread, + MainThreadOnly, MonochromeSprite, Pixels, PlatformAtlas, PlatformWindow, Point, Reference, + RenderGlyphParams, ScaledPixels, Scene, Size, Style, TaffyLayoutEngine, WeakHandle, + WindowOptions, SUBPIXEL_VARIANTS, }; use anyhow::Result; use futures::Future; @@ -16,7 +16,7 @@ pub struct AnyWindow {} pub struct Window { handle: AnyWindowHandle, platform_window: MainThreadOnly>, - glyph_atlas: Arc>, + glyph_atlas: Arc, rem_size: Pixels, content_size: Size, layout_engine: TaffyLayoutEngine, @@ -222,7 +222,7 @@ impl<'a, 'w> WindowContext<'a, 'w> { x: (glyph_origin.x.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8, y: (glyph_origin.y.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8, }; - let params = GlyphRasterParams { + let params = RenderGlyphParams { font_id, glyph_id, font_size, @@ -236,7 +236,9 @@ impl<'a, 'w> WindowContext<'a, 'w> { let tile = self .window .glyph_atlas - .get_or_insert_with(¶ms, &mut || self.text_system().rasterize_glyph(¶ms))?; + .get_or_insert_with(¶ms.clone().into(), &mut || { + self.text_system().rasterize_glyph(¶ms) + })?; let bounds = Bounds { origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into), size: tile.bounds.size.map(Into::into),