From 1cab27db44474cc1d954bc59a0cbdef2e06621c3 Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Thu, 3 Mar 2022 19:42:52 +0000 Subject: [PATCH] Bug 1757624 - Move FontInstanceMap out of webrender_api. r=nical,gfx-reviewers Differential Revision: https://phabricator.services.mozilla.com/D139971 --- gfx/wr/webrender/src/api_resources.rs | 2 +- gfx/wr/webrender/src/glyph_rasterizer/mod.rs | 144 ++++++++++++++++++- gfx/wr/webrender/src/render_api.rs | 3 +- gfx/wr/webrender/src/renderer/mod.rs | 4 +- gfx/wr/webrender/src/resource_cache.rs | 6 +- gfx/wr/webrender/src/scene_builder_thread.rs | 4 +- gfx/wr/webrender/src/scene_building.rs | 4 +- gfx/wr/webrender_api/src/font.rs | 139 +----------------- 8 files changed, 152 insertions(+), 154 deletions(-) diff --git a/gfx/wr/webrender/src/api_resources.rs b/gfx/wr/webrender/src/api_resources.rs index c5e45d21cd89..7606e19578af 100644 --- a/gfx/wr/webrender/src/api_resources.rs +++ b/gfx/wr/webrender/src/api_resources.rs @@ -6,8 +6,8 @@ use crate::api::{BlobImageKey, ImageDescriptor, DirtyRect, TileSize}; use crate::api::{BlobImageHandler, AsyncBlobImageRasterizer, BlobImageData, BlobImageParams}; use crate::api::{BlobImageRequest, BlobImageDescriptor, BlobImageResources}; use crate::api::{FontKey, FontTemplate, FontInstanceData, FontInstanceKey}; -use crate::api::SharedFontInstanceMap; use crate::api::units::*; +use crate::glyph_rasterizer::SharedFontInstanceMap; use crate::render_api::{ResourceUpdate, TransactionMsg, AddFont}; use crate::image_tiling::*; use crate::profiler; diff --git a/gfx/wr/webrender/src/glyph_rasterizer/mod.rs b/gfx/wr/webrender/src/glyph_rasterizer/mod.rs index 0f2112ed62c0..9c47a1f05807 100644 --- a/gfx/wr/webrender/src/glyph_rasterizer/mod.rs +++ b/gfx/wr/webrender/src/glyph_rasterizer/mod.rs @@ -2,9 +2,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use api::{FontInstanceFlags, FontSize, BaseFontInstance}; -use api::{FontKey, FontRenderMode, FontTemplate}; -use api::{ColorU, GlyphIndex, GlyphDimensions, SyntheticItalics}; +use api::{FontInstanceData, FontInstanceFlags, FontInstanceKey}; +use api::{FontInstanceOptions, FontInstancePlatformOptions}; +use api::{FontKey, FontRenderMode, FontSize, FontTemplate, FontVariation}; +use api::{ColorU, GlyphIndex, GlyphDimensions, SyntheticItalics, IdNamespace}; use api::channel::crossbeam::{unbounded, Receiver, Sender}; use api::units::*; use api::{ImageDescriptor, ImageDescriptorFlags, ImageFormat, DirtyRect}; @@ -29,7 +30,7 @@ use std::cell::Cell; use std::hash::{Hash, Hasher}; use std::mem; use std::ops::Deref; -use std::sync::{Arc, Condvar, Mutex, MutexGuard}; +use std::sync::{Arc, Condvar, Mutex, MutexGuard, RwLock, RwLockReadGuard}; use std::sync::atomic::{AtomicBool, Ordering}; pub static GLYPH_FLASHING: AtomicBool = AtomicBool::new(false); @@ -472,6 +473,141 @@ impl<'a> From<&'a LayoutToWorldTransform> for FontTransform { // Ensure glyph sizes are reasonably limited to avoid that scenario. pub const FONT_SIZE_LIMIT: f32 = 320.0; +/// Immutable description of a font instance's shared state. +/// +/// `BaseFontInstance` can be identified by a `FontInstanceKey` to avoid hashing it. +#[derive(Clone, PartialEq, Eq, Debug, Ord, PartialOrd, MallocSizeOf)] +#[cfg_attr(feature = "capture", derive(Serialize))] +#[cfg_attr(feature = "replay", derive(Deserialize))] +pub struct BaseFontInstance { + /// + pub instance_key: FontInstanceKey, + /// + pub font_key: FontKey, + /// + pub size: FontSize, + /// + pub bg_color: ColorU, + /// + pub render_mode: FontRenderMode, + /// + pub flags: FontInstanceFlags, + /// + pub synthetic_italics: SyntheticItalics, + /// + #[cfg_attr(any(feature = "capture", feature = "replay"), serde(skip))] + pub platform_options: Option, + /// + pub variations: Vec, +} + +pub type FontInstanceMap = FastHashMap>; +/// A map of font instance data accessed concurrently from multiple threads. +#[derive(Clone)] +#[cfg_attr(feature = "serialize", derive(Serialize))] +#[cfg_attr(feature = "deserialize", derive(Deserialize))] +pub struct SharedFontInstanceMap { + map: Arc>, +} + +impl SharedFontInstanceMap { + /// Creates an empty shared map. + pub fn new() -> Self { + SharedFontInstanceMap { + map: Arc::new(RwLock::new(FastHashMap::default())) + } + } + + /// Acquires a write lock on the shared map. + pub fn lock(&mut self) -> Option> { + self.map.read().ok() + } + + /// + pub fn get_font_instance_data(&self, key: FontInstanceKey) -> Option { + match self.map.read().unwrap().get(&key) { + Some(instance) => Some(FontInstanceData { + font_key: instance.font_key, + size: instance.size.into(), + options: Some(FontInstanceOptions { + render_mode: instance.render_mode, + flags: instance.flags, + bg_color: instance.bg_color, + synthetic_italics: instance.synthetic_italics, + }), + platform_options: instance.platform_options, + variations: instance.variations.clone(), + }), + None => None, + } + } + + /// Replace the shared map with the provided map. + pub fn set(&mut self, map: FontInstanceMap) { + *self.map.write().unwrap() = map; + } + + /// + pub fn get_font_instance(&self, instance_key: FontInstanceKey) -> Option> { + let instance_map = self.map.read().unwrap(); + instance_map.get(&instance_key).map(|instance| { Arc::clone(instance) }) + } + + /// + pub fn add_font_instance( + &mut self, + instance_key: FontInstanceKey, + font_key: FontKey, + size: f32, + options: Option, + platform_options: Option, + variations: Vec, + ) { + let FontInstanceOptions { + render_mode, + flags, + bg_color, + synthetic_italics, + .. + } = options.unwrap_or_default(); + + let instance = Arc::new(BaseFontInstance { + instance_key, + font_key, + size: size.into(), + bg_color, + render_mode, + flags, + synthetic_italics, + platform_options, + variations, + }); + + self.map + .write() + .unwrap() + .insert(instance_key, instance); + } + + /// + pub fn delete_font_instance(&mut self, instance_key: FontInstanceKey) { + self.map.write().unwrap().remove(&instance_key); + } + + /// + pub fn clear_namespace(&mut self, namespace: IdNamespace) { + self.map + .write() + .unwrap() + .retain(|key, _| key.0 != namespace); + } + + /// + pub fn clone_map(&self) -> FontInstanceMap { + self.map.read().unwrap().clone() + } +} + /// A mutable font instance description. /// /// Performance is sensitive to the size of this structure, so it should only contain diff --git a/gfx/wr/webrender/src/render_api.rs b/gfx/wr/webrender/src/render_api.rs index c9a3a53f45b7..597c9106f608 100644 --- a/gfx/wr/webrender/src/render_api.rs +++ b/gfx/wr/webrender/src/render_api.rs @@ -14,7 +14,7 @@ use time::precise_time_ns; //use crate::api::peek_poke::PeekPoke; use crate::api::channel::{Sender, single_msg_channel, unbounded_channel}; use crate::api::{ColorF, BuiltDisplayList, IdNamespace, ExternalScrollId, Parameter, BoolParameter}; -use crate::api::{SharedFontInstanceMap, FontKey, FontInstanceKey, NativeFontHandle}; +use crate::api::{FontKey, FontInstanceKey, NativeFontHandle}; use crate::api::{BlobImageData, BlobImageKey, ImageData, ImageDescriptor, ImageKey, Epoch, QualitySettings}; use crate::api::{BlobImageParams, BlobImageRequest, BlobImageResult, AsyncBlobImageRasterizer, BlobImageHandler}; use crate::api::{DocumentId, PipelineId, PropertyBindingId, PropertyBindingKey, ExternalEvent}; @@ -25,6 +25,7 @@ use crate::api::{FontInstanceOptions, FontInstancePlatformOptions, FontVariation use crate::api::DEFAULT_TILE_SIZE; use crate::api::units::*; use crate::api_resources::ApiResources; +use crate::glyph_rasterizer::SharedFontInstanceMap; use crate::scene_builder_thread::{SceneBuilderRequest, SceneBuilderResult}; use crate::intern::InterningMemoryReport; use crate::profiler::{self, TransactionProfile}; diff --git a/gfx/wr/webrender/src/renderer/mod.rs b/gfx/wr/webrender/src/renderer/mod.rs index 0b73c89ca471..5bed470e1ab4 100644 --- a/gfx/wr/webrender/src/renderer/mod.rs +++ b/gfx/wr/webrender/src/renderer/mod.rs @@ -42,7 +42,7 @@ use api::ExternalImageId; use api::{ExternalImageSource, ExternalImageType, FontRenderMode, ImageFormat}; use api::{PipelineId, ImageRendering, Checkpoint, NotificationRequest}; use api::{VoidPtrToSizeFn, PremultipliedColorF}; -use api::{RenderNotifier, ImageBufferKind, SharedFontInstanceMap}; +use api::{RenderNotifier, ImageBufferKind}; #[cfg(feature = "replay")] use api::ExternalImage; use api::units::*; @@ -68,7 +68,7 @@ use crate::device::FBOId; use crate::debug_item::DebugItem; use crate::frame_builder::{Frame, ChasePrimitive, FrameBuilderConfig}; use crate::glyph_cache::GlyphCache; -use crate::glyph_rasterizer::{GlyphFormat, GlyphRasterizer}; +use crate::glyph_rasterizer::{GlyphFormat, GlyphRasterizer, SharedFontInstanceMap}; use crate::gpu_cache::{GpuCacheUpdate, GpuCacheUpdateList}; use crate::gpu_cache::{GpuCacheDebugChunk, GpuCacheDebugCmd}; use crate::gpu_types::{PrimitiveInstanceData, ScalingInstance, SvgFilterInstance, CopyInstance}; diff --git a/gfx/wr/webrender/src/resource_cache.rs b/gfx/wr/webrender/src/resource_cache.rs index f0c44c9a216c..ffa050de4f88 100644 --- a/gfx/wr/webrender/src/resource_cache.rs +++ b/gfx/wr/webrender/src/resource_cache.rs @@ -8,7 +8,6 @@ use api::{ExternalImageData, ExternalImageType, ExternalImageId, BlobImageResult use api::{DirtyRect, GlyphDimensions, IdNamespace, DEFAULT_TILE_SIZE}; use api::{ImageData, ImageDescriptor, ImageKey, ImageRendering, TileSize}; use api::{BlobImageKey, VoidPtrToSizeFn}; -use api::{SharedFontInstanceMap, BaseFontInstance}; use api::units::*; use crate::{render_api::{ClearCache, AddFont, ResourceUpdate, MemoryReport}, util::WeakTable}; use crate::image_tiling::{compute_tile_size, compute_tile_range}; @@ -23,6 +22,7 @@ use crate::device::TextureFilter; use crate::glyph_cache::GlyphCache; use crate::glyph_cache::GlyphCacheEntry; use crate::glyph_rasterizer::{GLYPH_FLASHING, FontInstance, GlyphFormat, GlyphKey, GlyphRasterizer}; +use crate::glyph_rasterizer::{SharedFontInstanceMap, BaseFontInstance}; use crate::gpu_cache::{GpuCache, GpuCacheAddress, GpuCacheHandle}; use crate::gpu_types::UvRectKind; use crate::internal_types::{ @@ -39,8 +39,6 @@ use smallvec::SmallVec; use std::collections::hash_map::Entry::{self, Occupied, Vacant}; use std::collections::hash_map::{Iter, IterMut}; use std::collections::VecDeque; -#[cfg(any(feature = "capture", feature = "replay"))] -use std::collections::HashMap; use std::{cmp, mem}; use std::fmt::Debug; use std::hash::Hash; @@ -1791,7 +1789,7 @@ struct PlainImageTemplate { #[cfg_attr(feature = "replay", derive(Deserialize))] pub struct PlainResources { font_templates: FastHashMap, - font_instances: HashMap>, + font_instances: FastHashMap>, image_templates: FastHashMap, } diff --git a/gfx/wr/webrender/src/scene_builder_thread.rs b/gfx/wr/webrender/src/scene_builder_thread.rs index 4329f163e908..11e2e40207e0 100644 --- a/gfx/wr/webrender/src/scene_builder_thread.rs +++ b/gfx/wr/webrender/src/scene_builder_thread.rs @@ -5,8 +5,7 @@ use api::{AsyncBlobImageRasterizer, BlobImageResult, Parameter}; use api::{DocumentId, PipelineId, ExternalEvent, BlobImageRequest}; use api::{NotificationRequest, Checkpoint, IdNamespace, QualitySettings}; -use api::{PrimitiveKeyKind, SharedFontInstanceMap}; -use api::{GlyphDimensionRequest, GlyphIndexRequest}; +use api::{PrimitiveKeyKind, GlyphDimensionRequest, GlyphIndexRequest}; use api::channel::{unbounded_channel, single_msg_channel, Receiver, Sender}; use api::units::*; use crate::render_api::{ApiMsg, FrameMsg, SceneMsg, ResourceUpdate, TransactionMsg, MemoryReport}; @@ -16,6 +15,7 @@ use crate::frame_builder::FrameBuilderConfig; use crate::scene_building::SceneBuilder; use crate::clip::{ClipIntern, PolygonIntern}; use crate::filterdata::FilterDataIntern; +use crate::glyph_rasterizer::SharedFontInstanceMap; use crate::intern::{Internable, Interner, UpdateList}; use crate::internal_types::{FastHashMap, FastHashSet}; use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; diff --git a/gfx/wr/webrender/src/scene_building.rs b/gfx/wr/webrender/src/scene_building.rs index f1b9be6a3bd2..fdeba605f389 100644 --- a/gfx/wr/webrender/src/scene_building.rs +++ b/gfx/wr/webrender/src/scene_building.rs @@ -37,7 +37,7 @@ use api::{AlphaType, BorderDetails, BorderDisplayItem, BuiltDisplayListIter, BuiltDisplayList, PrimitiveFlags}; use api::{ClipId, ColorF, CommonItemProperties, ComplexClipRegion, ComponentTransferFuncType, RasterSpace}; -use api::{DisplayItem, DisplayItemRef, ExtendMode, ExternalScrollId, FilterData, SharedFontInstanceMap}; +use api::{DisplayItem, DisplayItemRef, ExtendMode, ExternalScrollId, FilterData}; use api::{FilterOp, FilterPrimitive, FontInstanceKey, FontSize, GlyphInstance, GlyphOptions, GradientStop}; use api::{IframeDisplayItem, ImageKey, ImageRendering, ItemRange, ColorDepth, QualitySettings}; use api::{LineOrientation, LineStyle, NinePatchBorderSource, PipelineId, MixBlendMode, StackingContextFlags}; @@ -52,7 +52,7 @@ use crate::clip::{ClipInternData, ClipNodeKind, ClipInstance, SceneClipInstance} use crate::clip::{PolygonDataHandle}; use crate::spatial_tree::{SceneSpatialTree, SpatialNodeIndex, get_external_scroll_offset}; use crate::frame_builder::{ChasePrimitive, FrameBuilderConfig}; -use crate::glyph_rasterizer::FontInstance; +use crate::glyph_rasterizer::{FontInstance, SharedFontInstanceMap}; use crate::hit_test::HitTestingScene; use crate::intern::Interner; use crate::internal_types::{FastHashMap, LayoutPrimitiveInfo, Filter, PlaneSplitter, PlaneSplitterIndex, PipelineInstanceId}; diff --git a/gfx/wr/webrender_api/src/font.rs b/gfx/wr/webrender_api/src/font.rs index 3527eed27539..351f39e5db6a 100644 --- a/gfx/wr/webrender_api/src/font.rs +++ b/gfx/wr/webrender_api/src/font.rs @@ -7,8 +7,7 @@ use std::cmp::Ordering; use std::hash::{Hash, Hasher}; #[cfg(not(target_os = "macos"))] use std::path::PathBuf; -use std::sync::{Arc, RwLock, RwLockReadGuard}; -use std::collections::HashMap; +use std::sync::Arc; // local imports use crate::IdNamespace; use crate::channel::Sender; @@ -54,142 +53,6 @@ impl FontSize { pub fn to_f64_px(&self) -> f64 { self.0 as f64 } } -/// Immutable description of a font instance requested by the user of the API. -/// -/// `BaseFontInstance` can be identified by a `FontInstanceKey` so we should -/// never need to hash it. -#[derive(Clone, PartialEq, Eq, Debug, Ord, PartialOrd, MallocSizeOf)] -#[cfg_attr(feature = "serialize", derive(Serialize))] -#[cfg_attr(feature = "deserialize", derive(Deserialize))] -pub struct BaseFontInstance { - /// - pub instance_key: FontInstanceKey, - /// - pub font_key: FontKey, - /// - pub size: FontSize, - /// - pub bg_color: ColorU, - /// - pub render_mode: FontRenderMode, - /// - pub flags: FontInstanceFlags, - /// - pub synthetic_italics: SyntheticItalics, - /// - #[cfg_attr(any(feature = "serialize", feature = "deserialize"), serde(skip))] - pub platform_options: Option, - /// - pub variations: Vec, -} - -pub type FontInstanceMap = HashMap>; -/// A map of font instance data accessed concurrently from multiple threads. -#[derive(Clone)] -#[cfg_attr(feature = "serialize", derive(Serialize))] -#[cfg_attr(feature = "deserialize", derive(Deserialize))] -pub struct SharedFontInstanceMap { - map: Arc>, -} - -impl SharedFontInstanceMap { - /// Creates an empty shared map. - pub fn new() -> Self { - SharedFontInstanceMap { - map: Arc::new(RwLock::new(HashMap::default())) - } - } - - /// Acquires a write lock on the shared map. - pub fn lock(&mut self) -> Option> { - self.map.read().ok() - } - - /// - pub fn get_font_instance_data(&self, key: FontInstanceKey) -> Option { - match self.map.read().unwrap().get(&key) { - Some(instance) => Some(FontInstanceData { - font_key: instance.font_key, - size: instance.size.into(), - options: Some(FontInstanceOptions { - render_mode: instance.render_mode, - flags: instance.flags, - bg_color: instance.bg_color, - synthetic_italics: instance.synthetic_italics, - }), - platform_options: instance.platform_options, - variations: instance.variations.clone(), - }), - None => None, - } - } - - /// Replace the shared map with the provided map. - pub fn set(&mut self, map: FontInstanceMap) { - *self.map.write().unwrap() = map; - } - - /// - pub fn get_font_instance(&self, instance_key: FontInstanceKey) -> Option> { - let instance_map = self.map.read().unwrap(); - instance_map.get(&instance_key).map(|instance| { Arc::clone(instance) }) - } - - /// - pub fn add_font_instance( - &mut self, - instance_key: FontInstanceKey, - font_key: FontKey, - size: f32, - options: Option, - platform_options: Option, - variations: Vec, - ) { - let FontInstanceOptions { - render_mode, - flags, - bg_color, - synthetic_italics, - .. - } = options.unwrap_or_default(); - - let instance = Arc::new(BaseFontInstance { - instance_key, - font_key, - size: size.into(), - bg_color, - render_mode, - flags, - synthetic_italics, - platform_options, - variations, - }); - - self.map - .write() - .unwrap() - .insert(instance_key, instance); - } - - /// - pub fn delete_font_instance(&mut self, instance_key: FontInstanceKey) { - self.map.write().unwrap().remove(&instance_key); - } - - /// - pub fn clear_namespace(&mut self, namespace: IdNamespace) { - self.map - .write() - .unwrap() - .retain(|key, _| key.0 != namespace); - } - - /// - pub fn clone_map(&self) -> FontInstanceMap { - self.map.read().unwrap().clone() - } -} - #[cfg(not(target_os = "macos"))] #[derive(Clone, Debug, Serialize, Deserialize)] pub struct NativeFontHandle {