Bug 1757624 - Move FontInstanceMap out of webrender_api. r=nical,gfx-reviewers

Differential Revision: https://phabricator.services.mozilla.com/D139971
This commit is contained in:
Lee Salzman 2022-03-03 19:42:52 +00:00
Родитель 2b99a38b76
Коммит 1cab27db44
8 изменённых файлов: 152 добавлений и 154 удалений

Просмотреть файл

@ -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;

Просмотреть файл

@ -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<FontInstancePlatformOptions>,
///
pub variations: Vec<FontVariation>,
}
pub type FontInstanceMap = FastHashMap<FontInstanceKey, Arc<BaseFontInstance>>;
/// 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<RwLock<FontInstanceMap>>,
}
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<RwLockReadGuard<FontInstanceMap>> {
self.map.read().ok()
}
///
pub fn get_font_instance_data(&self, key: FontInstanceKey) -> Option<FontInstanceData> {
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<Arc<BaseFontInstance>> {
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<FontInstanceOptions>,
platform_options: Option<FontInstancePlatformOptions>,
variations: Vec<FontVariation>,
) {
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

Просмотреть файл

@ -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};

Просмотреть файл

@ -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};

Просмотреть файл

@ -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<FontKey, PlainFontTemplate>,
font_instances: HashMap<FontInstanceKey, Arc<BaseFontInstance>>,
font_instances: FastHashMap<FontInstanceKey, Arc<BaseFontInstance>>,
image_templates: FastHashMap<ImageKey, PlainImageTemplate>,
}

Просмотреть файл

@ -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};

Просмотреть файл

@ -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};

Просмотреть файл

@ -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<FontInstancePlatformOptions>,
///
pub variations: Vec<FontVariation>,
}
pub type FontInstanceMap = HashMap<FontInstanceKey, Arc<BaseFontInstance>>;
/// 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<RwLock<FontInstanceMap>>,
}
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<RwLockReadGuard<FontInstanceMap>> {
self.map.read().ok()
}
///
pub fn get_font_instance_data(&self, key: FontInstanceKey) -> Option<FontInstanceData> {
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<Arc<BaseFontInstance>> {
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<FontInstanceOptions>,
platform_options: Option<FontInstancePlatformOptions>,
variations: Vec<FontVariation>,
) {
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 {