Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Factory:Rebuild
nodejs-electron
bad-font-gc2.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File bad-font-gc2.patch of Package nodejs-electron
Chromium 123 was buggy, with tabs regularly hanging/crashing. The culprit was the GC cleaning up font cache stuff, and deadlocking in a FontCacheKey destructor: Thread 54 (Thread 0x7fffc55fe6c0 (LWP 413811) "Chrome_InProcRe"): #0 0x00007ffff6720719 in syscall () from /lib/x86_64-linux-gnu/libc.so.6 #1 0x000055555c1752d9 in partition_alloc::internal::SpinningMutex::LockSlow() () #2 0x000055555c185529 in allocator_shim::internal::PartitionFree(allocator_shim::AllocatorDispatch const*, void*, void*) () #3 0x000055555f7db46b in blink::FontCacheKey::~FontCacheKey() () #4 0x000055555f7db6f4 in WTF::WeakProcessingHashTableHelper<(WTF::WeakHandlingFlag)1, blink::FontCacheKey, WTF::KeyValuePair<blink::FontCacheKey, cppgc::internal::BasicMember<blink::SegmentedFontData const, cppgc::internal::WeakMemberTag, cppgc::internal::DijkstraWriteBarrierPolicy, cppgc::internal::DisabledCheckingPolicy, cppgc::internal::CompressedPointer> >, WTF::KeyValuePairExtractor, WTF::HashMapValueTraits<WTF::HashTraits<blink::FontCacheKey>, WTF::HashTraits<cppgc::internal::BasicMember<blink::SegmentedFontData const, cppgc::internal::WeakMemberTag, cppgc::internal::DijkstraWriteBarrierPolicy, cppgc::internal::DisabledCheckingPolicy, cppgc::internal::CompressedPointer> > >, WTF::HashTraits<blink::FontCacheKey>, blink::HeapAllocator>::Process(cppgc::LivenessBroker const&, void const*) () #5 0x0000555559544bef in cppgc::internal::MarkerBase::ProcessWeakness() () #6 0x000055555954487e in cppgc::internal::MarkerBase::LeaveAtomicPause() () #7 0x0000555558e8115a in v8::internal::CppHeap::FinishMarkingAndStartSweeping() () #8 0x0000555558ebcdc0 in v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::internal::GarbageCollectionReason, char const*) () #9 0x0000555558ecfe14 in v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags)::$_0::operator()() const () #10 0x0000555558ecfb65 in void heap::base::Stack::SetMarkerAndCallbackImpl<v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags)::$_0>(heap::base::Stack*, void*, void const*) () --Type <RET> for more, q to quit, c to continue without paging-- #11 0x000055555955216b in PushAllRegistersAndIterateStack () #12 0x0000555558eb8c19 in v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) () #13 0x0000555558eba3eb in v8::internal::Heap::FinalizeIncrementalMarkingAtomically(v8::internal::GarbageCollectionReason) () #14 0x0000555558ed20db in v8::internal::IncrementalMarkingJob::Task::RunInternal() () #15 0x000055555c0c49d6 in base::TaskAnnotator::RunTaskImpl(base::PendingTask&) () #16 0x000055555c0daf88 in base::sequence_manager::internal::ThreadControllerImpl::DoWork(base::sequence_manager::internal::ThreadControllerImpl::WorkType) () #17 0x000055555c0c49d6 in base::TaskAnnotator::RunTaskImpl(base::PendingTask&) () #18 0x000055555c0dd8f9 in base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl(base::LazyNow*) () #19 0x000055555c0dd3bf in base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork() () #20 0x000055555c0ddd75 in non-virtual thunk to base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork() () #21 0x000055555c07eb4f in base::MessagePumpDefault::Run(base::MessagePump::Delegate*) () #22 0x000055555c0de110 in base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run(bool, base::TimeDelta) () #23 0x000055555c0a4c26 in base::RunLoop::Run(base::Location const&) () #24 0x000055555c100155 in base::Thread::Run(base::RunLoop*) () #25 0x000055555c100342 in base::Thread::ThreadMain() () The commit below modified font stuff to go from using scoped_refptrs to getting cleaned up via GC. Reverting it fixes chromium's behavior for us. It would be good to get a proper fix for this, but reverting this will have to do for now. commit bff9ec6754f7bf97c61d84663ee2ccc5055e9eb3 Author: Ian Kilpatrick <ikilpatrick@chromium.org> Date: Tue Feb 13 19:15:19 2024 +0000 [gc] Make SimpleFontData & FontPlatformData & friends gc'd. The largest change is making the associated caches for these objects weak collections instead of relying on the relatively complex purging logic. https://variable-lizards.glitch.me/ appears not to leak. There should be no user-visible behaviour change. Bug: 41490008 Change-Id: Iba581842459cf31f7f4fe60d83665f393a7d06a3 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5262982 Reviewed-by: Caleb Raitto <caraitto@chromium.org> Reviewed-by: Dominik Röttsches <drott@chromium.org> Commit-Queue: Ian Kilpatrick <ikilpatrick@chromium.org> Cr-Commit-Position: refs/heads/main@{#1259965} --- a/third_party/blink/renderer/core/css/binary_data_font_face_source.cc +++ b/third_party/blink/renderer/core/css/binary_data_font_face_source.cc @@ -36,10 +36,10 @@ bool BinaryDataFontFaceSource::IsValid() return custom_platform_data_.get(); } -SimpleFontData* BinaryDataFontFaceSource::CreateFontData( +scoped_refptr<SimpleFontData> BinaryDataFontFaceSource::CreateFontData( const FontDescription& font_description, const FontSelectionCapabilities& font_selection_capabilities) { - return MakeGarbageCollected<SimpleFontData>( + return SimpleFontData::Create( custom_platform_data_->GetFontPlatformData( font_description.EffectiveFontSize(), font_description.AdjustedSpecifiedSize(), @@ -56,7 +56,7 @@ SimpleFontData* BinaryDataFontFaceSource : ResolvedFontFeatures(), font_description.Orientation(), font_description.VariationSettings(), font_description.GetFontPalette()), - MakeGarbageCollected<CustomFontData>()); + CustomFontData::Create()); } } // namespace blink --- a/third_party/blink/renderer/core/css/binary_data_font_face_source.h +++ b/third_party/blink/renderer/core/css/binary_data_font_face_source.h @@ -20,8 +20,9 @@ class BinaryDataFontFaceSource final : p bool IsValid() const override; private: - SimpleFontData* CreateFontData(const FontDescription&, - const FontSelectionCapabilities&) override; + scoped_refptr<SimpleFontData> CreateFontData( + const FontDescription&, + const FontSelectionCapabilities&) override; scoped_refptr<FontCustomPlatformData> custom_platform_data_; }; --- a/third_party/blink/renderer/core/css/css_custom_font_data.h +++ b/third_party/blink/renderer/core/css/css_custom_font_data.h @@ -31,18 +31,13 @@ class CSSCustomFontData final : public C public: enum FallbackVisibility { kInvisibleFallback, kVisibleFallback }; - CSSCustomFontData(CSSFontFaceSource* source, FallbackVisibility visibility) - : font_face_source_(source), fallback_visibility_(visibility) { - if (source) { - is_loading_ = source->IsLoading(); - } + static scoped_refptr<CSSCustomFontData> Create( + CSSFontFaceSource* source, + FallbackVisibility visibility) { + return base::AdoptRef(new CSSCustomFontData(source, visibility)); } - ~CSSCustomFontData() override = default; - void Trace(Visitor* visitor) const override { - visitor->Trace(font_face_source_); - CustomFontData::Trace(visitor); - } + ~CSSCustomFontData() override = default; bool ShouldSkipDrawing() const override { if (font_face_source_) { @@ -66,7 +61,16 @@ class CSSCustomFontData final : public C } private: - Member<CSSFontFaceSource> font_face_source_; + CSSCustomFontData(CSSFontFaceSource* source, FallbackVisibility visibility) + : font_face_source_(source), fallback_visibility_(visibility) { + if (source) { + is_loading_ = source->IsLoading(); + } + } + + // TODO(Oilpan): consider moving (Custom)FontFace hierarchy to the heap, + // thereby making this reference a Member<>. + WeakPersistent<CSSFontFaceSource> font_face_source_; FallbackVisibility fallback_visibility_; mutable bool is_loading_ = false; }; --- a/third_party/blink/renderer/core/css/css_font_face.cc +++ b/third_party/blink/renderer/core/css/css_font_face.cc @@ -114,7 +114,7 @@ bool CSSFontFace::FallbackVisibilityChan return true; } -const SimpleFontData* CSSFontFace::GetFontData( +scoped_refptr<SimpleFontData> CSSFontFace::GetFontData( const FontDescription& font_description) { if (!IsValid()) { return nullptr; @@ -140,7 +140,7 @@ const SimpleFontData* CSSFontFace::GetFo return nullptr; } - if (const SimpleFontData* result = + if (scoped_refptr<SimpleFontData> result = source->GetFontData(size_adjusted_description, font_face_->GetFontSelectionCapabilities())) { // The font data here is created using the primary font's description. @@ -149,7 +149,7 @@ const SimpleFontData* CSSFontFace::GetFo if (size_adjusted_description.HasSizeAdjust()) { if (auto adjusted_size = FontSizeFunctions::MetricsMultiplierAdjustedFontSize( - result, size_adjusted_description)) { + result.get(), size_adjusted_description)) { size_adjusted_description.SetAdjustedSize(adjusted_size.value()); result = source->GetFontData(size_adjusted_description, --- a/third_party/blink/renderer/core/css/css_font_face.h +++ b/third_party/blink/renderer/core/css/css_font_face.h @@ -76,7 +76,7 @@ class CORE_EXPORT CSSFontFace final : pu bool FontLoaded(CSSFontFaceSource*); bool FallbackVisibilityChanged(RemoteFontFaceSource*); - const SimpleFontData* GetFontData(const FontDescription&); + scoped_refptr<SimpleFontData> GetFontData(const FontDescription&); FontFace::LoadStatusType LoadStatus() const { return font_face_->LoadStatus(); --- a/third_party/blink/renderer/core/css/css_font_face_source.cc +++ b/third_party/blink/renderer/core/css/css_font_face_source.cc @@ -31,11 +31,22 @@ #include "third_party/blink/renderer/platform/fonts/font_face_creation_params.h" #include "third_party/blink/renderer/platform/fonts/simple_font_data.h" +namespace { +// An excessive amount of SimpleFontData objects is generated from +// CSSFontFaceSource if a lot of varying FontDescriptions point to a web +// font. These FontDescriptions can vary in size, font-feature-settings or +// font-variation settings. Well known cases are animations of font-variation +// settings, compare crbug.com/778352. For a start, let's reduce this number to +// 1024, which is still a large number and should have enough steps for font +// animations from the same font face source, but avoids unbounded growth. +const size_t kMaxCachedFontData = 1024; +} // namespace + namespace blink { CSSFontFaceSource::~CSSFontFaceSource() = default; -const SimpleFontData* CSSFontFaceSource::GetFontData( +scoped_refptr<SimpleFontData> CSSFontFaceSource::GetFontData( const FontDescription& font_description, const FontSelectionCapabilities& font_selection_capabilities) { // If the font hasn't loaded or an error occurred, then we've got nothing. @@ -53,12 +64,52 @@ const SimpleFontData* CSSFontFaceSource: FontCacheKey key = font_description.CacheKey(FontFaceCreationParams(), is_unique_match); - auto result = font_data_table_.insert(key, nullptr); - if (result.is_new_entry) { - result.stored_value->value = - CreateFontData(font_description, font_selection_capabilities); + // Get or create the font data. Take care to avoid dangling references into + // font_data_table_, because it is modified below during pruning. + scoped_refptr<SimpleFontData> font_data; + { + auto* it = font_data_table_.insert(key, nullptr).stored_value; + if (!it->value) { + it->value = CreateFontData(font_description, font_selection_capabilities); + } + font_data = it->value; + } + + font_cache_key_age.PrependOrMoveToFirst(key); + PruneOldestIfNeeded(); + + DCHECK_LE(font_data_table_.size(), kMaxCachedFontData); + // No release, because fontData is a reference to a RefPtr that is held in the + // font_data_table_. + return font_data; +} + +void CSSFontFaceSource::PruneOldestIfNeeded() { + if (font_cache_key_age.size() > kMaxCachedFontData) { + DCHECK_EQ(font_cache_key_age.size() - 1, kMaxCachedFontData); + const FontCacheKey& key = font_cache_key_age.back(); + auto font_data_entry = font_data_table_.Take(key); + font_cache_key_age.pop_back(); + DCHECK_EQ(font_cache_key_age.size(), kMaxCachedFontData); + if (font_data_entry && font_data_entry->GetCustomFontData()) { + font_data_entry->GetCustomFontData()->ClearFontFaceSource(); + } + } +} + +void CSSFontFaceSource::PruneTable() { + if (font_data_table_.empty()) { + return; + } + + for (const auto& item : font_data_table_) { + SimpleFontData* font_data = item.value.get(); + if (font_data && font_data->GetCustomFontData()) { + font_data->GetCustomFontData()->ClearFontFaceSource(); + } } - return result.stored_value->value.Get(); + font_cache_key_age.clear(); + font_data_table_.clear(); } } // namespace blink --- a/third_party/blink/renderer/core/css/css_font_face_source.h +++ b/third_party/blink/renderer/core/css/css_font_face_source.h @@ -30,9 +30,7 @@ #include "third_party/blink/renderer/core/css/font_display.h" #include "third_party/blink/renderer/platform/fonts/font_cache_key.h" #include "third_party/blink/renderer/platform/fonts/font_selection_types.h" -#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" -#include "third_party/blink/renderer/platform/heap/member.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h" #include "third_party/blink/renderer/platform/wtf/linked_hash_set.h" @@ -71,8 +69,8 @@ class CORE_EXPORT CSSFontFaceSource return nullptr; } - const SimpleFontData* GetFontData(const FontDescription&, - const FontSelectionCapabilities&); + scoped_refptr<SimpleFontData> GetFontData(const FontDescription&, + const FontSelectionCapabilities&); // TODO(https://crbug.com/947461): IsLocalFontAvailable must not have a // FontDescription argument. @@ -93,29 +91,28 @@ class CORE_EXPORT CSSFontFaceSource virtual bool HadBlankText() { return false; } virtual void PaintRequested() {} - virtual void Trace(Visitor* visitor) const { - visitor->Trace(font_data_table_); - } + virtual void Trace(Visitor* visitor) const {} protected: CSSFontFaceSource() = default; - virtual const SimpleFontData* CreateFontData( + virtual scoped_refptr<SimpleFontData> CreateFontData( const FontDescription&, const FontSelectionCapabilities&) = 0; - - void ClearTable() { font_data_table_.clear(); } + void PruneTable(); // Report the font lookup for metrics collection. Only used for local font // face sources currently. virtual void ReportFontLookup(const FontDescription& font_description, - const SimpleFontData* font_data, + SimpleFontData* font_data, bool is_loading_fallback = false) {} private: - using FontDataTable = - HeapHashMap<FontCacheKey, WeakMember<const SimpleFontData>>; + void PruneOldestIfNeeded(); + using FontDataTable = HashMap<FontCacheKey, scoped_refptr<SimpleFontData>>; + using FontCacheKeyAgeList = LinkedHashSet<FontCacheKey>; FontDataTable font_data_table_; + FontCacheKeyAgeList font_cache_key_age; }; } // namespace blink --- a/third_party/blink/renderer/core/css/css_font_selector.cc +++ b/third_party/blink/renderer/core/css/css_font_selector.cc @@ -162,7 +162,7 @@ void CSSFontSelector::FontCacheInvalidat DispatchInvalidationCallbacks(FontInvalidationReason::kGeneralInvalidation); } -const FontData* CSSFontSelector::GetFontData( +scoped_refptr<FontData> CSSFontSelector::GetFontData( const FontDescription& font_description, const FontFamily& font_family) { const auto& family_name = font_family.FamilyName(); @@ -252,13 +252,13 @@ const FontData* CSSFontSelector::GetFont family_name, request_description.GetScript(), request_description.GenericFamily(), settings_family_name); - const SimpleFontData* font_data = + scoped_refptr<SimpleFontData> font_data = FontCache::Get().GetFontData(request_description, settings_family_name); if (font_data && request_description.HasSizeAdjust()) { DCHECK(RuntimeEnabledFeatures::CSSFontSizeAdjustEnabled()); if (auto adjusted_size = FontSizeFunctions::MetricsMultiplierAdjustedFontSize( - font_data, request_description)) { + font_data.get(), request_description)) { FontDescription size_adjusted_description(request_description); size_adjusted_description.SetAdjustedSize(adjusted_size.value()); font_data = FontCache::Get().GetFontData(size_adjusted_description, --- a/third_party/blink/renderer/core/css/css_font_selector.h +++ b/third_party/blink/renderer/core/css/css_font_selector.h @@ -49,8 +49,8 @@ class CORE_EXPORT CSSFontSelector : publ unsigned Version() const override { return font_face_cache_->Version(); } - const FontData* GetFontData(const FontDescription&, - const FontFamily&) override; + scoped_refptr<FontData> GetFontData(const FontDescription&, + const FontFamily&) override; void FontFaceInvalidated(FontInvalidationReason) override; --- a/third_party/blink/renderer/core/css/css_font_selector_base.cc +++ b/third_party/blink/renderer/core/css/css_font_selector_base.cc @@ -87,21 +87,21 @@ void CSSFontSelectorBase::ReportFailedLo void CSSFontSelectorBase::ReportFontLookupByUniqueOrFamilyName( const AtomicString& name, const FontDescription& font_description, - const SimpleFontData* resulting_font_data) { + scoped_refptr<SimpleFontData> resulting_font_data) { if (FontMatchingMetrics* font_matching_metrics = GetFontMatchingMetrics()) { font_matching_metrics->ReportFontLookupByUniqueOrFamilyName( - name, font_description, resulting_font_data); + name, font_description, resulting_font_data.get()); } } void CSSFontSelectorBase::ReportFontLookupByUniqueNameOnly( const AtomicString& name, const FontDescription& font_description, - const SimpleFontData* resulting_font_data, + scoped_refptr<SimpleFontData> resulting_font_data, bool is_loading_fallback) { if (FontMatchingMetrics* font_matching_metrics = GetFontMatchingMetrics()) { font_matching_metrics->ReportFontLookupByUniqueNameOnly( - name, font_description, resulting_font_data, is_loading_fallback); + name, font_description, resulting_font_data.get(), is_loading_fallback); } } @@ -109,20 +109,20 @@ void CSSFontSelectorBase::ReportFontLook UChar32 fallback_character, FontFallbackPriority fallback_priority, const FontDescription& font_description, - const SimpleFontData* resulting_font_data) { + scoped_refptr<SimpleFontData> resulting_font_data) { if (FontMatchingMetrics* font_matching_metrics = GetFontMatchingMetrics()) { font_matching_metrics->ReportFontLookupByFallbackCharacter( fallback_character, fallback_priority, font_description, - resulting_font_data); + resulting_font_data.get()); } } void CSSFontSelectorBase::ReportLastResortFallbackFontLookup( const FontDescription& font_description, - const SimpleFontData* resulting_font_data) { + scoped_refptr<SimpleFontData> resulting_font_data) { if (FontMatchingMetrics* font_matching_metrics = GetFontMatchingMetrics()) { font_matching_metrics->ReportLastResortFallbackFontLookup( - font_description, resulting_font_data); + font_description, resulting_font_data.get()); } } --- a/third_party/blink/renderer/core/css/css_font_selector_base.h +++ b/third_party/blink/renderer/core/css/css_font_selector_base.h @@ -46,23 +46,23 @@ class CORE_EXPORT CSSFontSelectorBase : void ReportFontLookupByUniqueOrFamilyName( const AtomicString& name, const FontDescription& font_description, - const SimpleFontData* resulting_font_data) override; + scoped_refptr<SimpleFontData> resulting_font_data) override; void ReportFontLookupByUniqueNameOnly( const AtomicString& name, const FontDescription& font_description, - const SimpleFontData* resulting_font_data, + scoped_refptr<SimpleFontData> resulting_font_data, bool is_loading_fallback = false) override; void ReportFontLookupByFallbackCharacter( UChar32 fallback_character, FontFallbackPriority fallback_priority, const FontDescription& font_description, - const SimpleFontData* resulting_font_data) override; + scoped_refptr<SimpleFontData> resulting_font_data) override; void ReportLastResortFallbackFontLookup( const FontDescription& font_description, - const SimpleFontData* resulting_font_data) override; + scoped_refptr<SimpleFontData> resulting_font_data) override; void ReportFontFamilyLookupByGenericFamily( const AtomicString& generic_font_family_name, --- a/third_party/blink/renderer/core/css/css_segmented_font_face.cc +++ b/third_party/blink/renderer/core/css/css_segmented_font_face.cc @@ -38,16 +38,42 @@ #include "third_party/blink/renderer/platform/fonts/segmented_font_data.h" #include "third_party/blink/renderer/platform/fonts/simple_font_data.h" +// See comment below in CSSSegmentedFontFace::GetFontData - the cache from +// CSSSegmentedFontFace (which represents a group of @font-face declarations +// with identical FontSelectionCapabilities but differing by unicode-range) to +// FontData/SegmentedFontData, (i.e. the actual font blobs that can be used for +// shaping and painting retrieved from a CSSFontFaceSource) is usually small +// (less than a dozen, up to tens) for non-animation-cases, but grows fast to +// thousands when animating variable font parameters. Set a limit until we start +// dropping cache entries in animation scenarios. +static constexpr size_t kFontDataTableMaxSize = 250; + namespace blink { +// static +CSSSegmentedFontFace* CSSSegmentedFontFace::Create( + FontSelectionCapabilities capabilities) { + return MakeGarbageCollected<CSSSegmentedFontFace>(capabilities); +} + CSSSegmentedFontFace::CSSSegmentedFontFace( FontSelectionCapabilities font_selection_capabilities) : font_selection_capabilities_(font_selection_capabilities), + font_data_table_(kFontDataTableMaxSize), font_faces_(MakeGarbageCollected<FontFaceList>()), approximate_character_count_(0) {} CSSSegmentedFontFace::~CSSSegmentedFontFace() = default; +void CSSSegmentedFontFace::PruneTable() { + // Make sure the glyph page tree prunes out all uses of this custom font. + if (!font_data_table_.size()) { + return; + } + + font_data_table_.Clear(); +} + bool CSSSegmentedFontFace::IsValid() const { // Valid if at least one font face is valid. return font_faces_->ForEachUntilTrue( @@ -57,12 +83,12 @@ bool CSSSegmentedFontFace::IsValid() con } void CSSSegmentedFontFace::FontFaceInvalidated() { - font_data_table_.clear(); + PruneTable(); } void CSSSegmentedFontFace::AddFontFace(FontFace* font_face, bool css_connected) { - font_data_table_.clear(); + PruneTable(); font_face->CssFontFace()->AddSegmentedFontFace(this); font_faces_->Insert(font_face, css_connected); } @@ -72,11 +98,11 @@ void CSSSegmentedFontFace::RemoveFontFac return; } - font_data_table_.clear(); + PruneTable(); font_face->CssFontFace()->RemoveSegmentedFontFace(this); } -const FontData* CSSSegmentedFontFace::GetFontData( +scoped_refptr<FontData> CSSSegmentedFontFace::GetFontData( const FontDescription& font_description) { if (!IsValid()) { return nullptr; @@ -98,16 +124,16 @@ const FontData* CSSSegmentedFontFace::Ge // usually only a small number of FontData/SegmentedFontData instances created // per CSSSegmentedFontFace. Whereas in variable font animations, this number // grows rapidly. - auto it = font_data_table_.find(key); + auto it = font_data_table_.Get(key); if (it != font_data_table_.end()) { - const SegmentedFontData* cached_font_data = it->value.Get(); + scoped_refptr<SegmentedFontData> cached_font_data = it->second; if (cached_font_data && cached_font_data->NumFaces()) { return cached_font_data; } } - SegmentedFontData* created_font_data = - MakeGarbageCollected<SegmentedFontData>(); + scoped_refptr<SegmentedFontData> created_font_data = + SegmentedFontData::Create(); FontDescription requested_font_description(font_description); const FontSelectionRequest& font_selection_request = @@ -126,16 +152,26 @@ const FontData* CSSSegmentedFontFace::Ge if (!font_face->CssFontFace()->IsValid()) { return; } - if (const SimpleFontData* face_font_data = + if (scoped_refptr<SimpleFontData> face_font_data = font_face->CssFontFace()->GetFontData(requested_font_description)) { DCHECK(!face_font_data->IsSegmented()); - created_font_data->AppendFace(MakeGarbageCollected<FontDataForRangeSet>( - std::move(face_font_data), font_face->CssFontFace()->Ranges())); + if (face_font_data->IsCustomFont()) { + created_font_data->AppendFace(base::AdoptRef(new FontDataForRangeSet( + std::move(face_font_data), font_face->CssFontFace()->Ranges()))); + } else { + created_font_data->AppendFace( + base::AdoptRef(new FontDataForRangeSetFromCache( + std::move(face_font_data), + font_face->CssFontFace()->Ranges()))); + } } }); if (created_font_data->NumFaces()) { - font_data_table_.insert(std::move(key), created_font_data); + scoped_refptr<SegmentedFontData> put_to_cache(created_font_data); + font_data_table_.Put(std::move(key), std::move(put_to_cache)); + // No release, we have a reference to an object in the cache which should + // retain the ref count it has. return created_font_data; } @@ -186,7 +222,6 @@ void CSSSegmentedFontFace::Match(const S } void CSSSegmentedFontFace::Trace(Visitor* visitor) const { - visitor->Trace(font_data_table_); visitor->Trace(font_faces_); } --- a/third_party/blink/renderer/core/css/css_segmented_font_face.h +++ b/third_party/blink/renderer/core/css/css_segmented_font_face.h @@ -32,7 +32,6 @@ #include "third_party/blink/renderer/platform/fonts/font_cache_key.h" #include "third_party/blink/renderer/platform/fonts/font_selection_types.h" #include "third_party/blink/renderer/platform/fonts/segmented_font_data.h" -#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_linked_hash_set.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" @@ -84,6 +83,8 @@ class FontFaceList : public GarbageColle class CSSSegmentedFontFace final : public GarbageCollected<CSSSegmentedFontFace> { public: + static CSSSegmentedFontFace* Create(FontSelectionCapabilities); + explicit CSSSegmentedFontFace(FontSelectionCapabilities); ~CSSSegmentedFontFace(); @@ -99,7 +100,7 @@ class CSSSegmentedFontFace final void RemoveFontFace(FontFace*); bool IsEmpty() const { return font_faces_->IsEmpty(); } - const FontData* GetFontData(const FontDescription&); + scoped_refptr<FontData> GetFontData(const FontDescription&); bool CheckFont(UChar32) const; void Match(const String&, HeapVector<Member<FontFace>>*) const; @@ -112,11 +113,12 @@ class CSSSegmentedFontFace final void Trace(Visitor*) const; private: + void PruneTable(); bool IsValid() const; FontSelectionCapabilities font_selection_capabilities_; - HeapHashMap<FontCacheKey, WeakMember<const SegmentedFontData>> + base::HashingLRUCache<FontCacheKey, scoped_refptr<SegmentedFontData>> font_data_table_; // All non-CSS-connected FontFaces are stored after the CSS-connected ones. --- a/third_party/blink/renderer/core/css/font_face_cache.cc +++ b/third_party/blink/renderer/core/css/font_face_cache.cc @@ -85,8 +85,8 @@ void FontFaceCache::CapabilitiesSet::Add const auto result = map_.insert(font_face->GetFontSelectionCapabilities(), nullptr); if (result.is_new_entry) { - result.stored_value->value = MakeGarbageCollected<CSSSegmentedFontFace>( - font_face->GetFontSelectionCapabilities()); + result.stored_value->value = + CSSSegmentedFontFace::Create(font_face->GetFontSelectionCapabilities()); } result.stored_value->value->AddFontFace(font_face, css_connected); --- a/third_party/blink/renderer/core/css/local_font_face_source.cc +++ b/third_party/blink/renderer/core/css/local_font_face_source.cc @@ -52,22 +52,23 @@ bool LocalFontFaceSource::IsLocalFontAva return font_available; } -const SimpleFontData* LocalFontFaceSource::CreateLoadingFallbackFontData( +scoped_refptr<SimpleFontData> +LocalFontFaceSource::CreateLoadingFallbackFontData( const FontDescription& font_description) { FontCachePurgePreventer font_cache_purge_preventer; - const SimpleFontData* temporary_font = - FontCache::Get().GetLastResortFallbackFont(font_description); + scoped_refptr<SimpleFontData> temporary_font = + FontCache::Get().GetLastResortFallbackFont(font_description, + kDoNotRetain); if (!temporary_font) { NOTREACHED(); return nullptr; } - CSSCustomFontData* css_font_data = MakeGarbageCollected<CSSCustomFontData>( - this, CSSCustomFontData::kVisibleFallback); - return MakeGarbageCollected<SimpleFontData>(&temporary_font->PlatformData(), - css_font_data); + scoped_refptr<CSSCustomFontData> css_font_data = + CSSCustomFontData::Create(this, CSSCustomFontData::kVisibleFallback); + return SimpleFontData::Create(temporary_font->PlatformData(), css_font_data); } -const SimpleFontData* LocalFontFaceSource::CreateFontData( +scoped_refptr<SimpleFontData> LocalFontFaceSource::CreateFontData( const FontDescription& font_description, const FontSelectionCapabilities&) { if (!IsValid()) { @@ -84,9 +85,9 @@ const SimpleFontData* LocalFontFaceSourc } if (IsValid() && IsLoading()) { - const SimpleFontData* fallback_font_data = + scoped_refptr<SimpleFontData> fallback_font_data = CreateLoadingFallbackFontData(font_description); - ReportFontLookup(font_description, fallback_font_data, + ReportFontLookup(font_description, fallback_font_data.get(), true /* is_loading_fallback */); return fallback_font_data; } @@ -110,10 +111,10 @@ const SimpleFontData* LocalFontFaceSourc #endif // TODO(https://crbug.com/1302264): Enable passing down of font-palette // information here (font_description.GetFontPalette()). - const SimpleFontData* font_data = FontCache::Get().GetFontData( + scoped_refptr<SimpleFontData> font_data = FontCache::Get().GetFontData( unstyled_description, font_name_, AlternateFontName::kLocalUniqueFace); - histograms_.Record(font_data); - ReportFontLookup(unstyled_description, font_data); + histograms_.Record(font_data.get()); + ReportFontLookup(unstyled_description, font_data.get()); return font_data; } @@ -132,7 +133,7 @@ void LocalFontFaceSource::BeginLoadIfNee } void LocalFontFaceSource::NotifyFontUniqueNameLookupReady() { - ClearTable(); + PruneTable(); if (face_->FontLoaded(this)) { font_selector_->FontFaceInvalidated( @@ -168,7 +169,7 @@ void LocalFontFaceSource::Trace(Visitor* void LocalFontFaceSource::ReportFontLookup( const FontDescription& font_description, - const SimpleFontData* font_data, + SimpleFontData* font_data, bool is_loading_fallback) { font_selector_->ReportFontLookupByUniqueNameOnly( font_name_, font_description, font_data, is_loading_fallback); --- a/third_party/blink/renderer/core/css/local_font_face_source.h +++ b/third_party/blink/renderer/core/css/local_font_face_source.h @@ -48,15 +48,16 @@ class LocalFontFaceSource final : public void NotifyFontUniqueNameLookupReady(); protected: - const SimpleFontData* CreateLoadingFallbackFontData(const FontDescription&); + scoped_refptr<SimpleFontData> CreateLoadingFallbackFontData( + const FontDescription&); private: - const SimpleFontData* CreateFontData( + scoped_refptr<SimpleFontData> CreateFontData( const FontDescription&, const FontSelectionCapabilities&) override; void ReportFontLookup(const FontDescription& font_description, - const SimpleFontData* font_data, + SimpleFontData* font_data, bool is_loading_fallback = false) override; class LocalFontHistograms { --- a/third_party/blink/renderer/core/css/offscreen_font_selector.cc +++ b/third_party/blink/renderer/core/css/offscreen_font_selector.cc @@ -39,7 +39,7 @@ void OffscreenFontSelector::RegisterForI void OffscreenFontSelector::UnregisterForInvalidationCallbacks( FontSelectorClient* client) {} -const FontData* OffscreenFontSelector::GetFontData( +scoped_refptr<FontData> OffscreenFontSelector::GetFontData( const FontDescription& font_description, const FontFamily& font_family) { const auto& family_name = font_family.FamilyName(); @@ -60,11 +60,11 @@ const FontData* OffscreenFontSelector::G family_name, font_description.GetScript(), font_description.GenericFamily(), settings_family_name); - const auto* font_data = + auto font_data = FontCache::Get().GetFontData(font_description, settings_family_name); ReportFontLookupByUniqueOrFamilyName(settings_family_name, font_description, - font_data); + font_data.get()); return font_data; } --- a/third_party/blink/renderer/core/css/offscreen_font_selector.h +++ b/third_party/blink/renderer/core/css/offscreen_font_selector.h @@ -26,8 +26,8 @@ class CORE_EXPORT OffscreenFontSelector unsigned Version() const override { return 1; } - const FontData* GetFontData(const FontDescription&, - const FontFamily&) override; + scoped_refptr<FontData> GetFontData(const FontDescription&, + const FontFamily&) override; void RegisterForInvalidationCallbacks(FontSelectorClient*) override; void UnregisterForInvalidationCallbacks(FontSelectorClient*) override; --- a/third_party/blink/renderer/core/css/remote_font_face_source.cc +++ b/third_party/blink/renderer/core/css/remote_font_face_source.cc @@ -240,7 +240,8 @@ void RemoteFontFaceSource::NotifyFinishe } ClearResource(); - ClearTable(); + + PruneTable(); if (GetDocument()) { if (!GetDocument()->RenderingHasBegun()) { @@ -305,7 +306,7 @@ bool RemoteFontFaceSource::UpdatePeriod( // Invalidate the font if its fallback visibility has changed. if (IsLoading() && period_ != new_period && (period_ == kBlockPeriod || new_period == kBlockPeriod)) { - ClearTable(); + PruneTable(); if (face_->FallbackVisibilityChanged(this)) { font_selector_->FontFaceInvalidated( FontInvalidationReason::kGeneralInvalidation); @@ -349,7 +350,7 @@ bool RemoteFontFaceSource::IsLowPriority return is_intervention_triggered_; } -const SimpleFontData* RemoteFontFaceSource::CreateFontData( +scoped_refptr<SimpleFontData> RemoteFontFaceSource::CreateFontData( const FontDescription& font_description, const FontSelectionCapabilities& font_selection_capabilities) { if (period_ == kFailurePeriod || !IsValid()) { @@ -362,7 +363,7 @@ const SimpleFontData* RemoteFontFaceSour histograms_.RecordFallbackTime(); - return MakeGarbageCollected<SimpleFontData>( + return SimpleFontData::Create( custom_font_data_->GetFontPlatformData( font_description.EffectiveFontSize(), font_description.AdjustedSpecifiedSize(), @@ -379,24 +380,25 @@ const SimpleFontData* RemoteFontFaceSour : ResolvedFontFeatures(), font_description.Orientation(), font_description.VariationSettings(), font_description.GetFontPalette()), - MakeGarbageCollected<CustomFontData>()); + CustomFontData::Create()); } -const SimpleFontData* RemoteFontFaceSource::CreateLoadingFallbackFontData( +scoped_refptr<SimpleFontData> +RemoteFontFaceSource::CreateLoadingFallbackFontData( const FontDescription& font_description) { // This temporary font is not retained and should not be returned. FontCachePurgePreventer font_cache_purge_preventer; - const SimpleFontData* temporary_font = - FontCache::Get().GetLastResortFallbackFont(font_description); + scoped_refptr<SimpleFontData> temporary_font = + FontCache::Get().GetLastResortFallbackFont(font_description, + kDoNotRetain); if (!temporary_font) { DUMP_WILL_BE_NOTREACHED_NORETURN(); return nullptr; } - CSSCustomFontData* css_font_data = MakeGarbageCollected<CSSCustomFontData>( + scoped_refptr<CSSCustomFontData> css_font_data = CSSCustomFontData::Create( this, period_ == kBlockPeriod ? CSSCustomFontData::kInvisibleFallback : CSSCustomFontData::kVisibleFallback); - return MakeGarbageCollected<SimpleFontData>(&temporary_font->PlatformData(), - css_font_data); + return SimpleFontData::Create(temporary_font->PlatformData(), css_font_data); } void RemoteFontFaceSource::BeginLoadIfNeeded() { --- a/third_party/blink/renderer/core/css/remote_font_face_source.h +++ b/third_party/blink/renderer/core/css/remote_font_face_source.h @@ -66,10 +66,11 @@ class RemoteFontFaceSource final : publi void Trace(Visitor*) const override; protected: - const SimpleFontData* CreateFontData( + scoped_refptr<SimpleFontData> CreateFontData( const FontDescription&, const FontSelectionCapabilities&) override; - const SimpleFontData* CreateLoadingFallbackFontData(const FontDescription&); + scoped_refptr<SimpleFontData> CreateLoadingFallbackFontData( + const FontDescription&); private: // Periods of the Font Display Timeline. --- a/third_party/blink/renderer/core/frame/font_matching_metrics.cc +++ b/third_party/blink/renderer/core/frame/font_matching_metrics.cc @@ -127,7 +127,7 @@ void FontMatchingMetrics::ReportLocalFon } void FontMatchingMetrics::InsertFontHashIntoMap(IdentifiableTokenKey input_key, - const SimpleFontData* font_data, + SimpleFontData* font_data, TokenToTokenHashMap& hash_map) { DCHECK(IdentifiabilityStudyShouldSampleFonts()); if (hash_map.Contains(input_key)) { @@ -160,7 +160,7 @@ FontMatchingMetrics::GetTokenBuilderWith void FontMatchingMetrics::ReportFontLookupByUniqueOrFamilyName( const AtomicString& name, const FontDescription& font_description, - const SimpleFontData* resulting_font_data) { + SimpleFontData* resulting_font_data) { Dactyloscoper::TraceFontLookup( execution_context_, name, font_description, Dactyloscoper::FontLookupType::kUniqueOrFamilyName); @@ -184,7 +184,7 @@ void FontMatchingMetrics::ReportFontLook void FontMatchingMetrics::ReportFontLookupByUniqueNameOnly( const AtomicString& name, const FontDescription& font_description, - const SimpleFontData* resulting_font_data, + SimpleFontData* resulting_font_data, bool is_loading_fallback) { // We ignore lookups that result in loading fallbacks for now as they should // only be temporary. @@ -217,7 +217,7 @@ void FontMatchingMetrics::ReportFontLook UChar32 fallback_character, FontFallbackPriority fallback_priority, const FontDescription& font_description, - const SimpleFontData* resulting_font_data) { + SimpleFontData* resulting_font_data) { if (!IdentifiabilityStudySettings::Get()->ShouldSampleType( IdentifiableSurface::Type::kLocalFontLookupByFallbackCharacter)) { return; @@ -236,7 +236,7 @@ void FontMatchingMetrics::ReportFontLook void FontMatchingMetrics::ReportLastResortFallbackFontLookup( const FontDescription& font_description, - const SimpleFontData* resulting_font_data) { + SimpleFontData* resulting_font_data) { if (!IdentifiabilityStudySettings::Get()->ShouldSampleType( IdentifiableSurface::Type::kLocalFontLookupAsLastResort)) { return; @@ -361,8 +361,7 @@ void FontMatchingMetrics::PublishAllMetr PublishEmojiGlyphMetrics(); } -int64_t FontMatchingMetrics::GetHashForFontData( - const SimpleFontData* font_data) { +int64_t FontMatchingMetrics::GetHashForFontData(SimpleFontData* font_data) { return font_data ? FontGlobalContext::Get() .GetOrComputeTypefaceDigest(font_data->PlatformData()) .ToUkmMetricValue() @@ -370,7 +369,7 @@ int64_t FontMatchingMetrics::GetHashForF } IdentifiableToken FontMatchingMetrics::GetPostScriptNameTokenForFontData( - const SimpleFontData* font_data) { + SimpleFontData* font_data) { DCHECK(font_data); return FontGlobalContext::Get().GetOrComputePostScriptNameDigest( font_data->PlatformData()); --- a/third_party/blink/renderer/core/frame/font_matching_metrics.h +++ b/third_party/blink/renderer/core/frame/font_matching_metrics.h @@ -100,16 +100,15 @@ class FontMatchingMetrics { void ReportFontLookupByUniqueOrFamilyName( const AtomicString& name, const FontDescription& font_description, - const SimpleFontData* resulting_font_data); + SimpleFontData* resulting_font_data); // Reports a local font was looked up by a name and font description. This // only includes lookups where the name is allowed to match PostScript names // and full font names, but not family names. - void ReportFontLookupByUniqueNameOnly( - const AtomicString& name, - const FontDescription& font_description, - const SimpleFontData* resulting_font_data, - bool is_loading_fallback = false); + void ReportFontLookupByUniqueNameOnly(const AtomicString& name, + const FontDescription& font_description, + SimpleFontData* resulting_font_data, + bool is_loading_fallback = false); // Reports a font was looked up by a fallback character, fallback priority, // and a font description. @@ -117,12 +116,12 @@ class FontMatchingMetrics { UChar32 fallback_character, FontFallbackPriority fallback_priority, const FontDescription& font_description, - const SimpleFontData* resulting_font_data); + SimpleFontData* resulting_font_data); // Reports a last-resort fallback font was looked up by a font description. void ReportLastResortFallbackFontLookup( const FontDescription& font_description, - const SimpleFontData* resulting_font_data); + SimpleFontData* resulting_font_data); // Reports a generic font family name was matched according to the script and // the user's preferences to a font family name. @@ -171,7 +170,7 @@ class FontMatchingMetrics { // nullptr, then the typeface digest will also be saved with its PostScript // name in |font_load_postscript_name_|. void InsertFontHashIntoMap(IdentifiableTokenKey input_key, - const SimpleFontData* font_data, + SimpleFontData* font_data, TokenToTokenHashMap& hash_map); // Reports a local font's existence was looked up by a name, but its actual @@ -194,14 +193,14 @@ class FontMatchingMetrics { // Get a hash that uniquely represents the font data. Returns 0 if |font_data| // is nullptr. - int64_t GetHashForFontData(const SimpleFontData* font_data); + int64_t GetHashForFontData(SimpleFontData* font_data); void Initialize(); // Get a token that uniquely represents the typeface's PostScript name. May // represent the empty string if no PostScript name was found. IdentifiableToken GetPostScriptNameTokenForFontData( - const SimpleFontData* font_data); + SimpleFontData* font_data); TokenToTokenHashMap font_lookups_by_unique_or_family_name_; TokenToTokenHashMap font_lookups_by_unique_name_only_; --- a/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc +++ b/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc @@ -132,8 +132,8 @@ class PopupMenuCSSFontSelector : public // We don't override willUseFontData() for now because the old PopupListBox // only worked with fonts loaded when opening the popup. - const FontData* GetFontData(const FontDescription&, - const FontFamily&) override; + scoped_refptr<FontData> GetFontData(const FontDescription&, + const FontFamily&) override; void Trace(Visitor*) const override; @@ -152,7 +152,7 @@ PopupMenuCSSFontSelector::PopupMenuCSSFo PopupMenuCSSFontSelector::~PopupMenuCSSFontSelector() = default; -const FontData* PopupMenuCSSFontSelector::GetFontData( +scoped_refptr<FontData> PopupMenuCSSFontSelector::GetFontData( const FontDescription& description, const FontFamily& font_family) { return owner_font_selector_->GetFontData(description, font_family); --- a/third_party/blink/renderer/core/inspector/inspector_css_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_css_agent.cc @@ -122,7 +122,6 @@ #include "third_party/blink/renderer/platform/fonts/font_custom_platform_data.h" #include "third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h" #include "third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h" -#include "third_party/blink/renderer/platform/heap/collection_support/clear_collection_scope.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/text/text_run.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" @@ -200,10 +199,10 @@ HeapVector<Member<CSSStyleRule>> FilterD } void CollectPlatformFontsFromRunFontDataList( - const HeapVector<ShapeResult::RunFontData>& run_font_data_list, + const Vector<ShapeResult::RunFontData>& run_font_data_list, HashMap<std::pair<int, String>, std::pair<int, String>>* font_stats) { for (const auto& run_font_data : run_font_data_list) { - const auto* simple_font_data = run_font_data.font_data_.Get(); + const auto* simple_font_data = run_font_data.font_data_; String family_name = simple_font_data->PlatformData().FontFamilyName(); if (family_name.IsNull()) family_name = ""; @@ -1733,8 +1732,7 @@ void InspectorCSSAgent::CollectPlatformF if (!shape_result) { continue; } - HeapVector<ShapeResult::RunFontData> run_font_data_list; - ClearCollectionScope clear_scope(&run_font_data_list); + Vector<ShapeResult::RunFontData> run_font_data_list; shape_result->GetRunFontData(&run_font_data_list); CollectPlatformFontsFromRunFontDataList(run_font_data_list, font_stats); } --- a/third_party/blink/renderer/core/layout/inline/inline_box_state.cc +++ b/third_party/blink/renderer/core/layout/inline/inline_box_state.cc @@ -19,7 +19,6 @@ #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/core/svg/svg_length_functions.h" #include "third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h" -#include "third_party/blink/renderer/platform/heap/collection_support/clear_collection_scope.h" namespace blink { @@ -174,8 +173,7 @@ void InlineBoxState::EnsureTextMetrics(c void InlineBoxState::AccumulateUsedFonts(const ShapeResultView* shape_result) { const auto baseline_type = style->GetFontBaseline(); - HeapHashSet<Member<const SimpleFontData>> fallback_fonts; - ClearCollectionScope clear_scope(&fallback_fonts); + HashSet<const SimpleFontData*> fallback_fonts; shape_result->FallbackFonts(&fallback_fonts); for (const SimpleFontData* const fallback_font : fallback_fonts) { FontHeight fallback_metrics = --- a/third_party/blink/renderer/core/layout/inline/ruby_utils.cc +++ b/third_party/blink/renderer/core/layout/inline/ruby_utils.cc @@ -17,7 +17,6 @@ #include "third_party/blink/renderer/core/layout/layout_object_inlines.h" #include "third_party/blink/renderer/core/layout/physical_box_fragment.h" #include "third_party/blink/renderer/platform/fonts/font_height.h" -#include "third_party/blink/renderer/platform/heap/collection_support/clear_collection_scope.h" namespace blink { @@ -38,10 +37,11 @@ std::tuple<LayoutUnit, LayoutUnit> Adjus primary_font_data->GetFontMetrics().FixedAscent(font_baseline); const LayoutUnit primary_descent = line_height - primary_ascent; + DCHECK(IsMainThread()); + DEFINE_STATIC_LOCAL(Vector<ShapeResult::RunFontData>, run_fonts, ()); + DCHECK_EQ(run_fonts.size(), 0u); // We don't use ShapeResultView::FallbackFonts() because we can't know if the // primary font is actually used with FallbackFonts(). - HeapVector<ShapeResult::RunFontData> run_fonts; - ClearCollectionScope clear_scope(&run_fonts); shape_view.GetRunFontData(&run_fonts); const LayoutUnit kNoDiff = LayoutUnit::Max(); LayoutUnit over_diff = kNoDiff; @@ -65,6 +65,7 @@ std::tuple<LayoutUnit, LayoutUnit> Adjus over_diff = std::min(over_diff, current_over_diff); under_diff = std::min(under_diff, current_under_diff); } + run_fonts.resize(0); if (over_diff == kNoDiff) over_diff = LayoutUnit(); if (under_diff == kNoDiff) @@ -85,8 +86,7 @@ FontHeight ComputeEmHeight(const Logical FontHeight result_height; // We don't use ShapeResultView::FallbackFonts() because we can't know if // the primary font is actually used with FallbackFonts(). - HeapVector<ShapeResult::RunFontData> run_fonts; - ClearCollectionScope clear_scope(&run_fonts); + Vector<ShapeResult::RunFontData> run_fonts; shape_result_view->GetRunFontData(&run_fonts); for (const auto& run_font : run_fonts) { const SimpleFontData* font_data = run_font.font_data_; --- a/third_party/blink/renderer/core/layout/layout_font_accessor_win.cc +++ b/third_party/blink/renderer/core/layout/layout_font_accessor_win.cc @@ -16,7 +16,6 @@ #include "third_party/blink/renderer/platform/fonts/font_platform_data.h" #include "third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h" #include "third_party/blink/renderer/platform/fonts/simple_font_data.h" -#include "third_party/blink/renderer/platform/heap/collection_support/clear_collection_scope.h" namespace blink { @@ -36,8 +35,7 @@ void GetFontsUsedByFragment(const Physic shape_result_view->PrimaryFont()->PlatformData().FontFamilyName(); if (!font_family.empty()) result.font_names.insert(font_family); - HeapHashSet<Member<const SimpleFontData>> fallback_font_data; - ClearCollectionScope clear_scope(&fallback_font_data); + HashSet<const SimpleFontData*> fallback_font_data; shape_result_view->FallbackFonts(&fallback_font_data); for (const SimpleFontData* font_data : fallback_font_data) { result.font_names.insert(font_data->PlatformData().FontFamilyName()); --- a/third_party/blink/renderer/modules/font_access/font_metadata.cc +++ b/third_party/blink/renderer/modules/font_access/font_metadata.cc @@ -75,7 +75,7 @@ void FontMetadata::BlobImpl(ScriptPromis SetUpFontUniqueLookupIfNecessary(); FontDescription description; - const SimpleFontData* font_data = + scoped_refptr<SimpleFontData> font_data = FontCache::Get().GetFontData(description, AtomicString(postscriptName), AlternateFontName::kLocalUniqueFace); if (!font_data) { --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn @@ -634,6 +634,7 @@ component("platform") { "fonts/font_cache_memory_dump_provider.h", "fonts/font_custom_platform_data.cc", "fonts/font_custom_platform_data.h", + "fonts/font_data.cc", "fonts/font_data.h", "fonts/font_data_cache.cc", "fonts/font_data_cache.h", --- a/third_party/blink/renderer/platform/fonts/android/font_cache_android.cc +++ b/third_party/blink/renderer/platform/fonts/android/font_cache_android.cc @@ -127,7 +127,7 @@ sk_sp<SkTypeface> FontCache::CreateLocal return nullptr; } -const SimpleFontData* FontCache::PlatformFallbackFontForCharacter( +scoped_refptr<SimpleFontData> FontCache::PlatformFallbackFontForCharacter( const FontDescription& font_description, UChar32 c, const SimpleFontData*, @@ -158,7 +158,7 @@ const SimpleFontData* FontCache::Platfor if (fallback_priority == FontFallbackPriority::kEmojiEmoji && base::FeatureList::IsEnabled(features::kGMSCoreEmoji)) { auto skia_fallback_is_noto_color_emoji = [&]() { - const FontPlatformData* skia_fallback_result = GetFontPlatformData( + FontPlatformData* skia_fallback_result = GetFontPlatformData( font_description, FontFaceCreationParams(family_name)); // Determining the PostScript name is required as Skia on Android gives @@ -175,14 +175,15 @@ const SimpleFontData* FontCache::Platfor }; if (family_name.empty() || skia_fallback_is_noto_color_emoji()) { - const FontPlatformData* emoji_gms_core_font = GetFontPlatformData( + FontPlatformData* emoji_gms_core_font = GetFontPlatformData( font_description, FontFaceCreationParams(AtomicString(kNotoColorEmojiCompat))); if (emoji_gms_core_font) { SkTypeface* probe_coverage_typeface = emoji_gms_core_font->Typeface(); if (probe_coverage_typeface && probe_coverage_typeface->unicharToGlyph(c)) { - return FontDataFromFontPlatformData(emoji_gms_core_font); + return FontDataFromFontPlatformData(emoji_gms_core_font, + kDoNotRetain); } } } @@ -192,10 +193,12 @@ const SimpleFontData* FontCache::Platfor // font was not found or an OEM emoji font was not to be overridden. if (family_name.empty()) - return GetLastResortFallbackFont(font_description); + return GetLastResortFallbackFont(font_description, kDoNotRetain); - return FontDataFromFontPlatformData(GetFontPlatformData( - font_description, FontFaceCreationParams(family_name))); + return FontDataFromFontPlatformData( + GetFontPlatformData(font_description, + FontFaceCreationParams(family_name)), + kDoNotRetain); } // static --- a/third_party/blink/renderer/platform/fonts/custom_font_data.h +++ b/third_party/blink/renderer/platform/fonts/custom_font_data.h @@ -22,8 +22,8 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_CUSTOM_FONT_DATA_H_ #include "base/memory/scoped_refptr.h" -#include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/platform_export.h" +#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h" namespace blink { @@ -34,17 +34,22 @@ namespace blink { // * `BinaryDataFontFaceSource` as loaded font resource // * `LocalFontFaceSource` as derived class `CSSCustomFontData` // * `RemoteFontFaceSource` as derived class `CSSCustomFontData` -class PLATFORM_EXPORT CustomFontData : public GarbageCollected<CustomFontData> { +class PLATFORM_EXPORT CustomFontData : public RefCounted<CustomFontData> { public: - CustomFontData() = default; + static scoped_refptr<CustomFontData> Create() { + return base::AdoptRef(new CustomFontData()); + } + virtual ~CustomFontData() = default; - virtual void Trace(Visitor*) const {} virtual void BeginLoadIfNeeded() const {} virtual bool IsLoading() const { return false; } virtual bool IsLoadingFallback() const { return false; } virtual bool ShouldSkipDrawing() const { return false; } virtual bool IsPendingDataUrl() const { return false; } + + protected: + CustomFontData() = default; }; } // namespace blink --- a/third_party/blink/renderer/platform/fonts/font_cache.cc +++ b/third_party/blink/renderer/platform/fonts/font_cache.cc @@ -87,7 +87,10 @@ FontCache& FontCache::Get() { return FontGlobalContext::GetFontCache(); } -FontCache::FontCache() : font_manager_(sk_ref_sp(static_font_manager_)) { +FontCache::FontCache() + : font_manager_(sk_ref_sp(static_font_manager_)), + font_platform_data_cache_(FontPlatformDataCache::Create()), + font_data_cache_(FontDataCache::Create()) { #if BUILDFLAG(IS_WIN) if (!font_manager_ || should_use_test_font_mgr) { // This code path is only for unit tests. This SkFontMgr does not work in @@ -113,14 +116,12 @@ FontCache::~FontCache() = default; void FontCache::Trace(Visitor* visitor) const { visitor->Trace(font_cache_clients_); - visitor->Trace(font_platform_data_cache_); - visitor->Trace(fallback_list_shaper_cache_); - visitor->Trace(font_data_cache_); visitor->Trace(font_fallback_map_); + visitor->Trace(fallback_list_shaper_cache_); } #if !BUILDFLAG(IS_MAC) -const FontPlatformData* FontCache::SystemFontPlatformData( +FontPlatformData* FontCache::SystemFontPlatformData( const FontDescription& font_description) { const AtomicString& family = FontCache::SystemFontFamily(); #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_FUCHSIA) || \ @@ -135,7 +136,7 @@ const FontPlatformData* FontCache::Syste } #endif -const FontPlatformData* FontCache::GetFontPlatformData( +FontPlatformData* FontCache::GetFontPlatformData( const FontDescription& font_description, const FontFaceCreationParams& creation_params, AlternateFontName alternate_font_name) { @@ -153,7 +154,7 @@ const FontPlatformData* FontCache::GetFo } #endif - return font_platform_data_cache_.GetOrCreateFontPlatformData( + return font_platform_data_cache_->GetOrCreateFontPlatformData( this, font_description, creation_params, alternate_font_name); } @@ -175,26 +176,34 @@ void FontCache::AcceptLanguagesChanged(c Get().InvalidateShapeCache(); } -const SimpleFontData* FontCache::GetFontData( +scoped_refptr<SimpleFontData> FontCache::GetFontData( const FontDescription& font_description, const AtomicString& family, - AlternateFontName altername_font_name) { - if (const FontPlatformData* platform_data = GetFontPlatformData( + AlternateFontName altername_font_name, + ShouldRetain should_retain) { + if (FontPlatformData* platform_data = GetFontPlatformData( font_description, FontFaceCreationParams( AdjustFamilyNameToAvoidUnsupportedFonts(family)), altername_font_name)) { return FontDataFromFontPlatformData( - platform_data, font_description.SubpixelAscentDescent()); + platform_data, should_retain, font_description.SubpixelAscentDescent()); } return nullptr; } -const SimpleFontData* FontCache::FontDataFromFontPlatformData( +scoped_refptr<SimpleFontData> FontCache::FontDataFromFontPlatformData( const FontPlatformData* platform_data, + ShouldRetain should_retain, bool subpixel_ascent_descent) { - return font_data_cache_.Get(platform_data, subpixel_ascent_descent); +#if DCHECK_IS_ON() + if (should_retain == kDoNotRetain) + DCHECK(purge_prevent_count_); +#endif + + return font_data_cache_->Get(platform_data, should_retain, + subpixel_ascent_descent); } bool FontCache::IsPlatformFamilyMatchAvailable( @@ -223,7 +232,15 @@ String FontCache::FirstAvailableOrFirst( gfx::FontList::FirstAvailableOrFirst(families.Utf8().c_str())); } -const SimpleFontData* FontCache::FallbackFontForCharacter( +SimpleFontData* FontCache::GetNonRetainedLastResortFallbackFont( + const FontDescription& font_description) { + auto font = GetLastResortFallbackFont(font_description, kDoNotRetain); + if (font) + font->AddRef(); + return font.get(); +} + +scoped_refptr<SimpleFontData> FontCache::FallbackFontForCharacter( const FontDescription& description, UChar32 lookup_char, const SimpleFontData* font_data_to_substitute, @@ -240,12 +257,21 @@ const SimpleFontData* FontCache::Fallbac Character::IsNonCharacter(lookup_char)) return nullptr; base::ElapsedTimer timer; - const SimpleFontData* result = PlatformFallbackFontForCharacter( + scoped_refptr<SimpleFontData> result = PlatformFallbackFontForCharacter( description, lookup_char, font_data_to_substitute, fallback_priority); FontPerformance::AddSystemFallbackFontTime(timer.Elapsed()); return result; } +void FontCache::ReleaseFontData(const SimpleFontData* font_data) { + font_data_cache_->Release(font_data); +} + +void FontCache::PurgePlatformFontDataCache() { + TRACE_EVENT0("fonts,ui", "FontCache::PurgePlatformFontDataCache"); + font_platform_data_cache_->Purge(*font_data_cache_); +} + void FontCache::PurgeFallbackListShaperCache() { TRACE_EVENT0("fonts,ui", "FontCache::PurgeFallbackListShaperCache"); for (auto& shape_cache : fallback_list_shaper_cache_.Values()) { @@ -257,13 +283,17 @@ void FontCache::InvalidateShapeCache() { PurgeFallbackListShaperCache(); } -void FontCache::Purge() { +void FontCache::Purge(PurgeSeverity purge_severity) { // Ideally we should never be forcing the purge while the // FontCachePurgePreventer is in scope, but we call purge() at any timing // via MemoryPressureListenerRegistry. if (purge_prevent_count_) return; + if (!font_data_cache_->Purge(purge_severity)) + return; + + PurgePlatformFontDataCache(); PurgeFallbackListShaperCache(); } @@ -279,15 +309,14 @@ uint16_t FontCache::Generation() { void FontCache::Invalidate() { TRACE_EVENT0("fonts,ui", "FontCache::Invalidate"); - font_platform_data_cache_.Clear(); - font_data_cache_.Clear(); + font_platform_data_cache_->Clear(); generation_++; for (const auto& client : font_cache_clients_) { client->FontCacheInvalidated(); } - Purge(); + Purge(kForcePurge); } void FontCache::CrashWithFontInfo(const FontDescription* font_description) { @@ -320,6 +349,16 @@ void FontCache::CrashWithFontInfo(const CHECK(false); } +void FontCache::DumpFontPlatformDataCache( + base::trace_event::ProcessMemoryDump* memory_dump) { + DCHECK(IsMainThread()); + base::trace_event::MemoryAllocatorDump* dump = + memory_dump->CreateAllocatorDump("font_caches/font_platform_data_cache"); + dump->AddScalar("size", "bytes", font_platform_data_cache_->ByteSize()); + memory_dump->AddSuballocation(dump->guid(), + WTF::Partitions::kAllocatedObjectPoolName); +} + void FontCache::DumpShapeResultCache( base::trace_event::ProcessMemoryDump* memory_dump) { DCHECK(IsMainThread()); --- a/third_party/blink/renderer/platform/fonts/font_cache.h +++ b/third_party/blink/renderer/platform/fonts/font_cache.h @@ -36,13 +36,13 @@ #include <string> #include "base/gtest_prod_util.h" +#include "base/memory/scoped_refptr.h" #include "build/build_config.h" #include "third_party/blink/renderer/platform/fonts/fallback_list_composite_key.h" #include "third_party/blink/renderer/platform/fonts/font_cache_client.h" #include "third_party/blink/renderer/platform/fonts/font_data_cache.h" #include "third_party/blink/renderer/platform/fonts/font_face_creation_params.h" #include "third_party/blink/renderer/platform/fonts/font_fallback_priority.h" -#include "third_party/blink/renderer/platform/fonts/font_platform_data_cache.h" #include "third_party/blink/renderer/platform/fonts/shaping/shape_cache.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h" #include "third_party/blink/renderer/platform/platform_export.h" @@ -75,6 +75,7 @@ class FontFaceCreationParams; class FontFallbackMap; class FontGlobalContext; class FontPlatformData; +class FontPlatformDataCache; class SimpleFontData; class WebFontPrewarmer; @@ -106,7 +107,9 @@ class PLATFORM_EXPORT FontCache final { void Trace(Visitor*) const; - const SimpleFontData* FallbackFontForCharacter( + void ReleaseFontData(const SimpleFontData*); + + scoped_refptr<SimpleFontData> FallbackFontForCharacter( const FontDescription&, UChar32, const SimpleFontData* font_data_to_substitute, @@ -115,11 +118,14 @@ class PLATFORM_EXPORT FontCache final { // Also implemented by the platform. void PlatformInit(); - const SimpleFontData* GetFontData( + scoped_refptr<SimpleFontData> GetFontData( const FontDescription&, const AtomicString&, - AlternateFontName = AlternateFontName::kAllowAlternate); - const SimpleFontData* GetLastResortFallbackFont(const FontDescription&); + AlternateFontName = AlternateFontName::kAllowAlternate, + ShouldRetain = kRetain); + scoped_refptr<SimpleFontData> GetLastResortFallbackFont(const FontDescription&, + ShouldRetain = kRetain); + SimpleFontData* GetNonRetainedLastResortFallbackFont(const FontDescription&); // Should be used in determining whether family names listed in font-family: // ... are available locally. Only returns true if family name matches. @@ -212,12 +218,12 @@ class PLATFORM_EXPORT FontCache final { return *status_font_family_name_; } - const SimpleFontData* GetFallbackFamilyNameFromHardcodedChoices( + scoped_refptr<SimpleFontData> GetFallbackFamilyNameFromHardcodedChoices( const FontDescription&, UChar32 codepoint, FontFallbackPriority fallback_priority); - const SimpleFontData* GetDWriteFallbackFamily( + scoped_refptr<SimpleFontData> GetDWriteFallbackFamily( const FontDescription&, UChar32 codepoint, FontFallbackPriority fallback_priority); @@ -245,8 +251,9 @@ class PLATFORM_EXPORT FontCache final { gfx::FallbackFontData*); #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) - const SimpleFontData* FontDataFromFontPlatformData( + scoped_refptr<SimpleFontData> FontDataFromFontPlatformData( const FontPlatformData*, + ShouldRetain = kRetain, bool subpixel_ascent_descent = false); void InvalidateShapeCache(); @@ -254,6 +261,7 @@ class PLATFORM_EXPORT FontCache final { static void CrashWithFontInfo(const FontDescription*); // Memory reporting + void DumpFontPlatformDataCache(base::trace_event::ProcessMemoryDump*); void DumpShapeResultCache(base::trace_event::ProcessMemoryDump*); FontFallbackMap& GetFontFallbackMap(); @@ -268,7 +276,7 @@ class PLATFORM_EXPORT FontCache final { // elements. using Bcp47Vector = WTF::Vector<const char*, 4>; - const SimpleFontData* PlatformFallbackFontForCharacter( + scoped_refptr<SimpleFontData> PlatformFallbackFontForCharacter( const FontDescription&, UChar32, const SimpleFontData* font_data_to_substitute, @@ -283,26 +291,26 @@ class PLATFORM_EXPORT FontCache final { friend class FontGlobalContext; FontCache(); - void Purge(); + void Purge(PurgeSeverity = kPurgeIfNeeded); void DisablePurging() { purge_prevent_count_++; } void EnablePurging() { DCHECK(purge_prevent_count_); if (!--purge_prevent_count_) - Purge(); + Purge(kPurgeIfNeeded); } // FIXME: This method should eventually be removed. - const FontPlatformData* GetFontPlatformData( + FontPlatformData* GetFontPlatformData( const FontDescription&, const FontFaceCreationParams&, AlternateFontName = AlternateFontName::kAllowAlternate); #if !BUILDFLAG(IS_MAC) - const FontPlatformData* SystemFontPlatformData(const FontDescription&); + FontPlatformData* SystemFontPlatformData(const FontDescription&); #endif // !BUILDFLAG(IS_MAC) // These methods are implemented by each platform. - const FontPlatformData* CreateFontPlatformData( + std::unique_ptr<FontPlatformData> CreateFontPlatformData( const FontDescription&, const FontFaceCreationParams&, float font_size, @@ -321,8 +329,9 @@ class PLATFORM_EXPORT FontCache final { #endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || // BUILDFLAG(IS_CHROMEOS) - const SimpleFontData* FallbackOnStandardFontStyle(const FontDescription&, - UChar32); + scoped_refptr<SimpleFontData> FallbackOnStandardFontStyle( + const FontDescription&, + UChar32); // Don't purge if this count is > 0; int purge_prevent_count_ = 0; @@ -356,16 +365,17 @@ class PLATFORM_EXPORT FontCache final { uint16_t generation_ = 0; bool platform_init_ = false; HeapHashSet<WeakMember<FontCacheClient>> font_cache_clients_; - FontPlatformDataCache font_platform_data_cache_; + std::unique_ptr<FontPlatformDataCache> font_platform_data_cache_; HeapHashMap<FallbackListCompositeKey, WeakMember<ShapeCache>, FallbackListCompositeKeyTraits> fallback_list_shaper_cache_; - FontDataCache font_data_cache_; + std::unique_ptr<FontDataCache> font_data_cache_; Member<FontFallbackMap> font_fallback_map_; + void PurgePlatformFontDataCache(); void PurgeFallbackListShaperCache(); friend class SimpleFontData; // For fontDataFromFontPlatformData --- a/third_party/blink/renderer/platform/fonts/font_cache_memory_dump_provider.cc +++ b/third_party/blink/renderer/platform/fonts/font_cache_memory_dump_provider.cc @@ -21,6 +21,7 @@ bool FontCacheMemoryDumpProvider::OnMemo DCHECK(IsMainThread()); if (auto* context = FontGlobalContext::TryGet()) { FontCache& cache = context->GetFontCache(); + cache.DumpFontPlatformDataCache(memory_dump); cache.DumpShapeResultCache(memory_dump); } return true; --- a/third_party/blink/renderer/platform/fonts/font_custom_platform_data.cc +++ b/third_party/blink/renderer/platform/fonts/font_custom_platform_data.cc @@ -103,7 +103,7 @@ FontCustomPlatformData::~FontCustomPlatf } } -const FontPlatformData* FontCustomPlatformData::GetFontPlatformData( +FontPlatformData FontCustomPlatformData::GetFontPlatformData( float size, float adjusted_specified_size, bool bold, @@ -276,11 +276,10 @@ const FontPlatformData* FontCustomPlatfo return_typeface = palette_typeface; } } - return MakeGarbageCollected<FontPlatformData>( - std::move(return_typeface), std::string(), size, - synthetic_bold && !base_typeface_->isBold(), - synthetic_italic && !base_typeface_->isItalic(), text_rendering, - resolved_font_features, orientation); + return FontPlatformData(std::move(return_typeface), std::string(), size, + synthetic_bold && !base_typeface_->isBold(), + synthetic_italic && !base_typeface_->isItalic(), + text_rendering, resolved_font_features, orientation); } Vector<VariationAxis> FontCustomPlatformData::GetVariationAxes() const { --- a/third_party/blink/renderer/platform/fonts/font_custom_platform_data.h +++ b/third_party/blink/renderer/platform/fonts/font_custom_platform_data.h @@ -68,7 +68,7 @@ class PLATFORM_EXPORT FontCustomPlatform // adjusted_specified_size should come from AdjustedSpecifiedSize() of // FontDescription. The latter is needed for correctly applying // font-optical-sizing: auto; independent of zoom level. - const FontPlatformData* GetFontPlatformData( + FontPlatformData GetFontPlatformData( float size, float adjusted_specified_size, bool bold, --- /dev/null +++ b/third_party/blink/renderer/platform/fonts/font_data.cc @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "third_party/blink/renderer/platform/fonts/font_data.h" + +namespace blink { + +FontData::~FontData() = default; + +} // namespace blink --- a/third_party/blink/renderer/platform/fonts/font_data.h +++ b/third_party/blink/renderer/platform/fonts/font_data.h @@ -27,24 +27,23 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_DATA_H_ #include "base/memory/scoped_refptr.h" -#include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/forward.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_uchar.h" +#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h" namespace blink { class SimpleFontData; -class PLATFORM_EXPORT FontData : public GarbageCollected<FontData> { +class PLATFORM_EXPORT FontData : public RefCounted<FontData> { public: FontData() = default; FontData(const FontData&) = delete; FontData& operator=(const FontData&) = delete; - virtual ~FontData() = default; - virtual void Trace(Visitor*) const {} + virtual ~FontData(); virtual const SimpleFontData* FontDataForCharacter(UChar32) const = 0; virtual bool IsCustomFont() const = 0; --- a/third_party/blink/renderer/platform/fonts/font_data_cache.cc +++ b/third_party/blink/renderer/platform/fonts/font_data_cache.cc @@ -36,8 +36,23 @@ namespace blink { -const SimpleFontData* FontDataCache::Get(const FontPlatformData* platform_data, - bool subpixel_ascent_descent) { +#if !BUILDFLAG(IS_ANDROID) +const unsigned kCMaxInactiveFontData = 250; +const unsigned kCTargetInactiveFontData = 200; +#else +const unsigned kCMaxInactiveFontData = 225; +const unsigned kCTargetInactiveFontData = 200; +#endif + +// static +std::unique_ptr<FontDataCache> FontDataCache::Create() { + return std::make_unique<FontDataCache>(); +} + +scoped_refptr<SimpleFontData> FontDataCache::Get( + const FontPlatformData* platform_data, + ShouldRetain should_retain, + bool subpixel_ascent_descent) { if (!platform_data) return nullptr; @@ -50,12 +65,98 @@ const SimpleFontData* FontDataCache::Get return nullptr; } - auto add_result = cache_.insert(platform_data, nullptr); - if (add_result.is_new_entry) { - add_result.stored_value->value = MakeGarbageCollected<SimpleFontData>( - platform_data, nullptr, subpixel_ascent_descent); + Cache::iterator result = cache_.find(platform_data); + if (result == cache_.end()) { + std::pair<scoped_refptr<SimpleFontData>, unsigned> new_value( + SimpleFontData::Create(*platform_data, nullptr, + subpixel_ascent_descent), + should_retain == kRetain ? 1 : 0); + // The new SimpleFontData takes a copy of the incoming FontPlatformData + // object. The incoming key may be temporary. So, for cache storage, take + // the address of the newly created FontPlatformData that is copied an owned + // by SimpleFontData. + cache_.Set(&new_value.first->PlatformData(), new_value); + if (should_retain == kDoNotRetain) + inactive_font_data_.insert(new_value.first); + return std::move(new_value.first); + } + + if (!result.Get()->value.second) { + DCHECK(inactive_font_data_.Contains(result.Get()->value.first)); + inactive_font_data_.erase(result.Get()->value.first); + } + + if (should_retain == kRetain) { + result.Get()->value.second++; + } else if (!result.Get()->value.second) { + // If shouldRetain is DoNotRetain and count is 0, we want to remove the + // fontData from m_inactiveFontData (above) and re-add here to update LRU + // position. + inactive_font_data_.insert(result.Get()->value.first); + } + + return result.Get()->value.first; +} + +bool FontDataCache::Contains(const FontPlatformData* font_platform_data) const { + return cache_.Contains(font_platform_data); +} + +void FontDataCache::Release(const SimpleFontData* font_data) { + DCHECK(!font_data->IsCustomFont()); + + Cache::iterator it = cache_.find(&(font_data->PlatformData())); + if (it == cache_.end()) + return; + + DCHECK(it->value.second); + if (!--it->value.second) + inactive_font_data_.insert(it->value.first); +} + +bool FontDataCache::Purge(PurgeSeverity purge_severity) { + if (purge_severity == kForcePurge) + return PurgeLeastRecentlyUsed(INT_MAX); + + if (inactive_font_data_.size() > kCMaxInactiveFontData) + return PurgeLeastRecentlyUsed(inactive_font_data_.size() - + kCTargetInactiveFontData); + + return false; +} + +bool FontDataCache::PurgeLeastRecentlyUsed(int count) { + // Guard against reentry when e.g. a deleted FontData releases its small caps + // FontData. + if (is_purging_) + return false; + + base::AutoReset<bool> is_purging_auto_reset(&is_purging_, true); + + Vector<scoped_refptr<SimpleFontData>, 20> font_data_to_delete; + auto end = inactive_font_data_.end(); + auto it = inactive_font_data_.begin(); + for (int i = 0; i < count && it != end; ++it, ++i) { + const scoped_refptr<SimpleFontData>& font_data = *it; + cache_.erase(&(font_data->PlatformData())); + // We should not delete SimpleFontData here because deletion can modify + // m_inactiveFontData. See http://trac.webkit.org/changeset/44011 + font_data_to_delete.push_back(font_data); + } + + if (it == end) { + // Removed everything + inactive_font_data_.clear(); + } else { + for (int i = 0; i < count; ++i) + inactive_font_data_.erase(inactive_font_data_.begin()); } - return add_result.stored_value->value; + + bool did_work = font_data_to_delete.size(); + + font_data_to_delete.clear(); + + return did_work; } } // namespace blink --- a/third_party/blink/renderer/platform/fonts/font_data_cache.h +++ b/third_party/blink/renderer/platform/fonts/font_data_cache.h @@ -33,10 +33,14 @@ #include "third_party/blink/renderer/platform/fonts/font_platform_data.h" #include "third_party/blink/renderer/platform/fonts/simple_font_data.h" -#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h" +#include "third_party/blink/renderer/platform/wtf/hash_map.h" +#include "third_party/blink/renderer/platform/wtf/linked_hash_set.h" namespace blink { +enum ShouldRetain { kRetain, kDoNotRetain }; +enum PurgeSeverity { kPurgeIfNeeded, kForcePurge }; + struct FontDataCacheKeyHashTraits : GenericHashTraits<const FontPlatformData*> { STATIC_ONLY(FontDataCacheKeyHashTraits); static unsigned GetHash(const FontPlatformData* platform_data) { @@ -51,24 +55,36 @@ struct FontDataCacheKeyHashTraits : Gene }; class FontDataCache final { - DISALLOW_NEW(); + USING_FAST_MALLOC(FontDataCache); public: + static std::unique_ptr<FontDataCache> Create(); + FontDataCache() = default; FontDataCache(const FontDataCache&) = delete; FontDataCache& operator=(const FontDataCache&) = delete; - void Trace(Visitor* visitor) const { visitor->Trace(cache_); } - - const SimpleFontData* Get(const FontPlatformData*, - bool subpixel_ascent_descent = false); - void Clear() { cache_.clear(); } + scoped_refptr<SimpleFontData> Get(const FontPlatformData*, + ShouldRetain = kRetain, + bool subpixel_ascent_descent = false); + bool Contains(const FontPlatformData*) const; + void Release(const SimpleFontData*); + + // Purges items in FontDataCache according to provided severity. + // Returns true if any removal of cache items actually occurred. + bool Purge(PurgeSeverity); private: - HeapHashMap<Member<const FontPlatformData>, - WeakMember<const SimpleFontData>, - FontDataCacheKeyHashTraits> - cache_; + bool PurgeLeastRecentlyUsed(int count); + + typedef HashMap<const FontPlatformData*, + std::pair<scoped_refptr<SimpleFontData>, unsigned>, + FontDataCacheKeyHashTraits> + Cache; + + Cache cache_; + LinkedHashSet<scoped_refptr<SimpleFontData>> inactive_font_data_; + bool is_purging_ = false; }; } // namespace blink --- a/third_party/blink/renderer/platform/fonts/font_data_for_range_set.cc +++ b/third_party/blink/renderer/platform/fonts/font_data_for_range_set.cc @@ -13,4 +13,10 @@ FontDataForRangeSet::FontDataForRangeSet range_set_ = other.range_set_; } +FontDataForRangeSetFromCache::~FontDataForRangeSetFromCache() { + if (font_data_ && !font_data_->IsCustomFont()) { + FontCache::Get().ReleaseFontData(font_data_.get()); + } +} + } // namespace blink --- a/third_party/blink/renderer/platform/fonts/font_data_for_range_set.h +++ b/third_party/blink/renderer/platform/fonts/font_data_for_range_set.h @@ -37,19 +37,17 @@ namespace blink { class SimpleFontData; class PLATFORM_EXPORT FontDataForRangeSet - : public GarbageCollected<FontDataForRangeSet> { + : public RefCounted<FontDataForRangeSet> { public: explicit FontDataForRangeSet( - const SimpleFontData* font_data = nullptr, + scoped_refptr<SimpleFontData> font_data = nullptr, scoped_refptr<UnicodeRangeSet> range_set = nullptr) - : font_data_(font_data), range_set_(std::move(range_set)) {} + : font_data_(std::move(font_data)), range_set_(std::move(range_set)) {} FontDataForRangeSet(const FontDataForRangeSet& other); virtual ~FontDataForRangeSet() = default; - void Trace(Visitor* visitor) const { visitor->Trace(font_data_); } - bool Contains(UChar32 test_char) const { return !range_set_ || range_set_->Contains(test_char); } @@ -57,8 +55,8 @@ class PLATFORM_EXPORT FontDataForRangeSe return !range_set_ || range_set_->IsEntireRange(); } UnicodeRangeSet* Ranges() const { return range_set_.get(); } - bool HasFontData() const { return font_data_; } - const SimpleFontData* FontData() const { return font_data_.Get(); } + bool HasFontData() const { return font_data_.get(); } + const SimpleFontData* FontData() const { return font_data_.get(); } // TODO(xiaochengh): |FontData::IsLoadingFallback()| returns true if the // FontData is a pending custom font. We should rename it for better clarity. @@ -71,10 +69,20 @@ class PLATFORM_EXPORT FontDataForRangeSe } protected: - Member<const SimpleFontData> font_data_; + scoped_refptr<SimpleFontData> font_data_; scoped_refptr<UnicodeRangeSet> range_set_; }; +class PLATFORM_EXPORT FontDataForRangeSetFromCache + : public FontDataForRangeSet { + public: + explicit FontDataForRangeSetFromCache( + scoped_refptr<SimpleFontData> font_data, + scoped_refptr<UnicodeRangeSet> range_set = nullptr) + : FontDataForRangeSet(std::move(font_data), std::move(range_set)) {} + ~FontDataForRangeSetFromCache() override; +}; + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_DATA_FOR_RANGE_SET_H_ --- a/third_party/blink/renderer/platform/fonts/font_fallback_iterator.cc +++ b/third_party/blink/renderer/platform/fonts/font_fallback_iterator.cc @@ -73,8 +73,8 @@ void FontFallbackIterator::WillUseRange( selector->WillUseRange(font_description_, family, range_set); } -FontDataForRangeSet* FontFallbackIterator::UniqueOrNext( - FontDataForRangeSet* candidate, +scoped_refptr<FontDataForRangeSet> FontFallbackIterator::UniqueOrNext( + scoped_refptr<FontDataForRangeSet> candidate, const HintCharList& hint_list) { if (!candidate->HasFontData()) return Next(hint_list); @@ -117,17 +117,17 @@ bool FontFallbackIterator::NeedsHintList return font_data->IsSegmented(); } -FontDataForRangeSet* FontFallbackIterator::Next(const HintCharList& hint_list) { +scoped_refptr<FontDataForRangeSet> FontFallbackIterator::Next(const HintCharList& hint_list) { if (fallback_stage_ == kOutOfLuck) - return MakeGarbageCollected<FontDataForRangeSet>(); + return base::AdoptRef(new FontDataForRangeSet()); if (fallback_stage_ == kFallbackPriorityFonts) { // Only try one fallback priority font, // then proceed to regular system fallback. fallback_stage_ = kSystemFonts; - FontDataForRangeSet* fallback_priority_font_range = - MakeGarbageCollected<FontDataForRangeSet>( - FallbackPriorityFont(hint_list[0])); + scoped_refptr<FontDataForRangeSet> fallback_priority_font_range = + base::AdoptRef( + new FontDataForRangeSet(FallbackPriorityFont(hint_list[0]))); if (fallback_priority_font_range->HasFontData()) return UniqueOrNext(std::move(fallback_priority_font_range), hint_list); return Next(hint_list); @@ -135,11 +135,11 @@ FontDataForRangeSet* FontFallbackIterato if (fallback_stage_ == kSystemFonts) { // We've reached pref + system fallback. - const SimpleFontData* system_font = UniqueSystemFontForHintList(hint_list); + scoped_refptr<SimpleFontData> system_font = UniqueSystemFontForHintList(hint_list); if (system_font) { // Fallback fonts are not retained in the FontDataCache. - return UniqueOrNext( - MakeGarbageCollected<FontDataForRangeSet>(system_font), hint_list); + return UniqueOrNext(base::AdoptRef(new FontDataForRangeSet(system_font)), + hint_list); } // If we don't have options from the system fallback anymore or had @@ -149,16 +149,18 @@ FontDataForRangeSet* FontFallbackIterato // LastResort font, not just Times or Arial. FontCache& font_cache = FontCache::Get(); fallback_stage_ = kFirstCandidateForNotdefGlyph; - const SimpleFontData* last_resort = - font_cache.GetLastResortFallbackFont(font_description_); + scoped_refptr<SimpleFontData> last_resort = + font_cache.GetLastResortFallbackFont(font_description_).get(); if (FontSelector* font_selector = font_fallback_list_->GetFontSelector()) { - font_selector->ReportLastResortFallbackFontLookup(font_description_, - last_resort); + font_selector->ReportLastResortFallbackFontLookup( + font_description_, + last_resort.get()); } - return UniqueOrNext(MakeGarbageCollected<FontDataForRangeSet>(last_resort), - hint_list); + return UniqueOrNext( + base::AdoptRef(new FontDataForRangeSetFromCache(last_resort)), + hint_list); } if (fallback_stage_ == kFirstCandidateForNotdefGlyph) { @@ -189,13 +191,13 @@ FontDataForRangeSet* FontFallbackIterato // Skip forward to the next font family for the next call to next(). current_font_data_index_++; if (!font_data->IsLoading()) { - SimpleFontData* non_segmented = + scoped_refptr<SimpleFontData> non_segmented = const_cast<SimpleFontData*>(To<SimpleFontData>(font_data)); // The fontData object that we have here is tracked in m_fontList of // FontFallbackList and gets released in the font cache when the // FontFallbackList is destroyed. return UniqueOrNext( - MakeGarbageCollected<FontDataForRangeSet>(non_segmented), hint_list); + base::AdoptRef(new FontDataForRangeSet(non_segmented)), hint_list); } return Next(hint_list); } @@ -209,7 +211,7 @@ FontDataForRangeSet* FontFallbackIterato } DCHECK_LT(segmented_face_index_, segmented->NumFaces()); - FontDataForRangeSet* current_segmented_face = + scoped_refptr<FontDataForRangeSet> current_segmented_face = segmented->FaceAt(segmented_face_index_); segmented_face_index_++; @@ -220,7 +222,7 @@ FontDataForRangeSet* FontFallbackIterato current_font_data_index_++; } - if (RangeSetContributesForHint(hint_list, current_segmented_face)) { + if (RangeSetContributesForHint(hint_list, current_segmented_face.get())) { const SimpleFontData* current_segmented_face_font_data = current_segmented_face->FontData(); if (const CustomFontData* current_segmented_face_custom_font_data = @@ -234,15 +236,17 @@ FontDataForRangeSet* FontFallbackIterato return Next(hint_list); } -const SimpleFontData* FontFallbackIterator::FallbackPriorityFont(UChar32 hint) { - const SimpleFontData* font_data = FontCache::Get().FallbackFontForCharacter( - font_description_, hint, - font_fallback_list_->PrimarySimpleFontData(font_description_), - font_fallback_priority_); +scoped_refptr<SimpleFontData> FontFallbackIterator::FallbackPriorityFont( + UChar32 hint) { + scoped_refptr<SimpleFontData> font_data = + FontCache::Get().FallbackFontForCharacter( + font_description_, hint, + font_fallback_list_->PrimarySimpleFontData(font_description_), + font_fallback_priority_); if (FontSelector* font_selector = font_fallback_list_->GetFontSelector()) { font_selector->ReportFontLookupByFallbackCharacter( - hint, font_fallback_priority_, font_description_, font_data); + hint, font_fallback_priority_, font_description_, font_data.get()); } return font_data; } @@ -268,7 +272,7 @@ static inline unsigned ChooseHintIndex( return 0; } -const SimpleFontData* FontFallbackIterator::UniqueSystemFontForHintList( +scoped_refptr<SimpleFontData> FontFallbackIterator::UniqueSystemFontForHintList( const HintCharList& hint_list) { // When we're asked for a fallback for the same characters again, we give up // because the shaper must have previously tried shaping with the font @@ -283,13 +287,13 @@ const SimpleFontData* FontFallbackIterat return nullptr; previously_asked_for_hint_.insert(hint); - const SimpleFontData* font_data = font_cache.FallbackFontForCharacter( + scoped_refptr<SimpleFontData> font_data = font_cache.FallbackFontForCharacter( font_description_, hint, font_fallback_list_->PrimarySimpleFontData(font_description_)); if (FontSelector* font_selector = font_fallback_list_->GetFontSelector()) { font_selector->ReportFontLookupByFallbackCharacter( - hint, FontFallbackPriority::kText, font_description_, font_data); + hint, FontFallbackPriority::kText, font_description_, font_data.get()); } return font_data; } --- a/third_party/blink/renderer/platform/fonts/font_fallback_iterator.h +++ b/third_party/blink/renderer/platform/fonts/font_fallback_iterator.h @@ -5,13 +5,14 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_FALLBACK_ITERATOR_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_FALLBACK_ITERATOR_H_ +#include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/platform/fonts/font_data_for_range_set.h" #include "third_party/blink/renderer/platform/fonts/font_fallback_priority.h" -#include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/hash_set.h" #include "third_party/blink/renderer/platform/wtf/ref_counted.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_uchar.h" +#include "third_party/blink/renderer/platform/wtf/vector.h" namespace blink { @@ -49,7 +50,7 @@ class PLATFORM_EXPORT FontFallbackIterat // Some system fallback APIs (Windows, Android) require a character, or a // portion of the string to be passed. On Mac and Linux, we get a list of // fonts without passing in characters. - FontDataForRangeSet* Next(const HintCharList& hint_list); + scoped_refptr<FontDataForRangeSet> Next(const HintCharList& hint_list); void Reset(); @@ -59,11 +60,12 @@ class PLATFORM_EXPORT FontFallbackIterat bool AlreadyLoadingRangeForHintChar(UChar32 hint_char); void WillUseRange(const AtomicString& family, const FontDataForRangeSet&); - FontDataForRangeSet* UniqueOrNext(FontDataForRangeSet* candidate, - const HintCharList& hint_list); + scoped_refptr<FontDataForRangeSet> UniqueOrNext( + scoped_refptr<FontDataForRangeSet> candidate, + const HintCharList& hint_list); - const SimpleFontData* FallbackPriorityFont(UChar32 hint); - const SimpleFontData* UniqueSystemFontForHintList( + scoped_refptr<SimpleFontData> FallbackPriorityFont(UChar32 hint); + scoped_refptr<SimpleFontData> UniqueSystemFontForHintList( const HintCharList& hint_list); const FontDescription& font_description_; @@ -91,8 +93,8 @@ class PLATFORM_EXPORT FontFallbackIterat // candidate to be used for rendering the .notdef glyph, and set HasNext() to // false. HashSet<uint32_t> unique_font_data_for_range_sets_returned_; - FontDataForRangeSet* first_candidate_ = nullptr; - HeapVector<Member<FontDataForRangeSet>> tracked_loading_range_sets_; + scoped_refptr<FontDataForRangeSet> first_candidate_; + Vector<scoped_refptr<FontDataForRangeSet>> tracked_loading_range_sets_; FontFallbackPriority font_fallback_priority_; }; --- a/third_party/blink/renderer/platform/fonts/font_fallback_list.cc +++ b/third_party/blink/renderer/platform/fonts/font_fallback_list.cc @@ -52,9 +52,17 @@ FontFallbackList::FontFallbackList(FontS is_invalid_(false), nullify_primary_font_data_for_test_(false) {} +FontFallbackList::~FontFallbackList() { + unsigned num_fonts = font_list_.size(); + for (unsigned i = 0; i < num_fonts; ++i) { + if (!font_list_[i]->IsCustomFont()) { + DCHECK(!font_list_[i]->IsSegmented()); + FontCache::Get().ReleaseFontData(To<SimpleFontData>(font_list_[i].get())); + } + } +} + void FontFallbackList::Trace(Visitor* visitor) const { - visitor->Trace(font_list_); - visitor->Trace(cached_primary_simple_font_data_); visitor->Trace(font_selector_); visitor->Trace(ng_shape_cache_); visitor->Trace(shape_cache_); @@ -98,8 +106,8 @@ const SimpleFontData* FontFallbackList:: return font_data->FontDataForCharacter(kSpaceCharacter); FontCache& font_cache = FontCache::Get(); - const SimpleFontData* last_resort_fallback = - font_cache.GetLastResortFallbackFont(font_description); + SimpleFontData* last_resort_fallback = + font_cache.GetLastResortFallbackFont(font_description).get(); DCHECK(last_resort_fallback); return last_resort_fallback; } @@ -137,7 +145,7 @@ const SimpleFontData* FontFallbackList:: } } -const FontData* FontFallbackList::GetFontData( +scoped_refptr<FontData> FontFallbackList::GetFontData( const FontDescription& font_description) { const FontFamily* curr_family = &font_description.Family(); for (int i = 0; curr_family && i < family_index_; i++) @@ -148,7 +156,7 @@ const FontData* FontFallbackList::GetFon if (!font_selector_) { // Don't query system fonts for empty font family name. if (!curr_family->FamilyName().empty()) { - if (auto* result = FontCache::Get().GetFontData( + if (auto result = FontCache::Get().GetFontData( font_description, curr_family->FamilyName())) { return result; } @@ -156,7 +164,7 @@ const FontData* FontFallbackList::GetFon continue; } - const FontData* result = + scoped_refptr<FontData> result = font_selector_->GetFontData(font_description, *curr_family); // Don't query system fonts for empty font family name. if (!result && !curr_family->FamilyName().empty()) { @@ -164,7 +172,7 @@ const FontData* FontFallbackList::GetFon curr_family->FamilyName()); font_selector_->ReportFontLookupByUniqueOrFamilyName( curr_family->FamilyName(), font_description, - DynamicTo<SimpleFontData>(result)); + DynamicTo<SimpleFontData>(result.get())); } if (result) { font_selector_->ReportSuccessfulFontFamilyMatch( @@ -181,18 +189,18 @@ const FontData* FontFallbackList::GetFon FontFamily font_family; font_family.SetFamily(font_family_names::kWebkitStandard, FontFamily::Type::kGenericFamily); - if (const FontData* data = + if (scoped_refptr<FontData> data = font_selector_->GetFontData(font_description, font_family)) { return data; } } // Still no result. Hand back our last resort fallback font. - auto* last_resort = + auto last_resort = FontCache::Get().GetLastResortFallbackFont(font_description); if (font_selector_) { font_selector_->ReportLastResortFallbackFontLookup(font_description, - last_resort); + last_resort.get()); } return last_resort; } @@ -202,7 +210,7 @@ const FontData* FontFallbackList::FontDa unsigned realized_font_index) { // This fallback font is already in our list. if (realized_font_index < font_list_.size()) - return font_list_[realized_font_index].Get(); + return font_list_[realized_font_index].get(); // Make sure we're not passing in some crazy value here. DCHECK_EQ(realized_font_index, font_list_.size()); @@ -216,7 +224,7 @@ const FontData* FontFallbackList::FontDa // the same spot in the list twice. GetFontData will adjust our // |family_index_| as it scans for the right font to make. DCHECK_EQ(FontCache::Get().Generation(), generation_); - const FontData* result = GetFontData(font_description); + scoped_refptr<FontData> result = GetFontData(font_description); if (result) { font_list_.push_back(result); if (result->IsLoadingFallback()) @@ -224,7 +232,7 @@ const FontData* FontFallbackList::FontDa if (result->IsCustomFont()) has_custom_font_ = true; } - return result; + return result.get(); } bool FontFallbackList::ComputeCanShapeWordByWord( --- a/third_party/blink/renderer/platform/fonts/font_fallback_list.h +++ b/third_party/blink/renderer/platform/fonts/font_fallback_list.h @@ -49,6 +49,7 @@ class PLATFORM_EXPORT FontFallbackList FontFallbackList(const FontFallbackList&) = delete; FontFallbackList& operator=(const FontFallbackList&) = delete; + ~FontFallbackList(); void Trace(Visitor*) const; @@ -116,7 +117,7 @@ class PLATFORM_EXPORT FontFallbackList bool HasCustomFont() const { return has_custom_font_; } private: - const FontData* GetFontData(const FontDescription&); + scoped_refptr<FontData> GetFontData(const FontDescription&); const SimpleFontData* DeterminePrimarySimpleFontData(const FontDescription&); const SimpleFontData* DeterminePrimarySimpleFontDataCore( @@ -124,8 +125,8 @@ class PLATFORM_EXPORT FontFallbackList bool ComputeCanShapeWordByWord(const FontDescription&); - HeapVector<Member<const FontData>, 1> font_list_; - Member<const SimpleFontData> cached_primary_simple_font_data_ = nullptr; + Vector<scoped_refptr<FontData>, 1> font_list_; + const SimpleFontData* cached_primary_simple_font_data_ = nullptr; const Member<FontSelector> font_selector_; int family_index_ = 0; const uint16_t generation_; --- a/third_party/blink/renderer/platform/fonts/font_platform_data.cc +++ b/third_party/blink/renderer/platform/fonts/font_platform_data.cc @@ -159,10 +159,6 @@ FontPlatformData::FontPlatformData(sk_sp FontPlatformData::~FontPlatformData() = default; -void FontPlatformData::Trace(Visitor* visitor) const { - visitor->Trace(harfbuzz_face_); -} - #if BUILDFLAG(IS_MAC) CTFontRef FontPlatformData::CtFont() const { return SkTypeface_GetCTFontRef(typeface_.get()); @@ -214,10 +210,11 @@ SkTypeface* FontPlatformData::Typeface() HarfBuzzFace* FontPlatformData::GetHarfBuzzFace() const { if (!harfbuzz_face_) { - harfbuzz_face_ = MakeGarbageCollected<HarfBuzzFace>(this, UniqueID()); + harfbuzz_face_ = + HarfBuzzFace::Create(const_cast<FontPlatformData*>(this), UniqueID()); } - return harfbuzz_face_.Get(); + return harfbuzz_face_.get(); } bool FontPlatformData::HasSpaceInLigaturesOrKerning( @@ -247,7 +244,7 @@ unsigned FontPlatformData::GetHash() con } #if !BUILDFLAG(IS_MAC) -bool FontPlatformData::FontContainsCharacter(UChar32 character) const { +bool FontPlatformData::FontContainsCharacter(UChar32 character) { return CreateSkFont().unicharToGlyph(character); } #endif --- a/third_party/blink/renderer/platform/fonts/font_platform_data.h +++ b/third_party/blink/renderer/platform/fonts/font_platform_data.h @@ -39,8 +39,6 @@ #include "third_party/blink/renderer/platform/fonts/font_orientation.h" #include "third_party/blink/renderer/platform/fonts/resolved_font_features.h" #include "third_party/blink/renderer/platform/fonts/small_caps_iterator.h" -#include "third_party/blink/renderer/platform/heap/garbage_collected.h" -#include "third_party/blink/renderer/platform/heap/member.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/forward.h" @@ -61,8 +59,9 @@ namespace blink { class HarfBuzzFace; class OpenTypeVerticalData; -class PLATFORM_EXPORT FontPlatformData - : public GarbageCollected<FontPlatformData> { +class PLATFORM_EXPORT FontPlatformData { + USING_FAST_MALLOC(FontPlatformData); + public: // Used for deleted values in the font cache's hash tables. The hash table // will create us with this structure, and it will compare other values @@ -83,8 +82,6 @@ class PLATFORM_EXPORT FontPlatformData FontOrientation = FontOrientation::kHorizontal); ~FontPlatformData(); - void Trace(Visitor*) const; - #if BUILDFLAG(IS_MAC) // Returns nullptr for FreeType backed SkTypefaces, compare // FontCustomPlatformData, which are used for variable fonts on Mac OS @@ -130,7 +127,7 @@ class PLATFORM_EXPORT FontPlatformData bool IsHashTableDeletedValue() const { return is_hash_table_deleted_value_; } #if !BUILDFLAG(IS_MAC) - bool FontContainsCharacter(UChar32 character) const; + bool FontContainsCharacter(UChar32 character); #endif #if !BUILDFLAG(IS_WIN) && !BUILDFLAG(IS_MAC) @@ -186,7 +183,7 @@ class PLATFORM_EXPORT FontPlatformData WebFontRenderStyle style_; #endif - mutable Member<HarfBuzzFace> harfbuzz_face_; + mutable scoped_refptr<HarfBuzzFace> harfbuzz_face_; bool is_hash_table_deleted_value_ = false; }; --- a/third_party/blink/renderer/platform/fonts/font_platform_data_cache.cc +++ b/third_party/blink/renderer/platform/fonts/font_platform_data_cache.cc @@ -38,13 +38,20 @@ namespace blink { +// static +std::unique_ptr<FontPlatformDataCache> FontPlatformDataCache::Create() { + return std::make_unique<FontPlatformDataCache>(); +} + FontPlatformDataCache::FontPlatformDataCache() : font_size_limit_(std::nextafter( (static_cast<float>(std::numeric_limits<unsigned>::max()) - 2.f) / static_cast<float>(blink::FontCacheKey::PrecisionMultiplier()), 0.f)) {} -const FontPlatformData* FontPlatformDataCache::GetOrCreateFontPlatformData( +FontPlatformDataCache::~FontPlatformDataCache() = default; + +FontPlatformData* FontPlatformDataCache::GetOrCreateFontPlatformData( FontCache* font_cache, const FontDescription& font_description, const FontFaceCreationParams& creation_params, @@ -60,13 +67,15 @@ const FontPlatformData* FontPlatformData auto it = map_.find(key); if (it != map_.end()) { - return it->value.Get(); + return it->value.get(); } - if (const FontPlatformData* result = font_cache->CreateFontPlatformData( - font_description, creation_params, size, alternate_font_name)) { - map_.insert(key, result); - return result; + if (std::unique_ptr<FontPlatformData> result = + font_cache->CreateFontPlatformData(font_description, creation_params, + size, alternate_font_name)) { + FontPlatformData* result_ptr = result.get(); + map_.insert(key, std::move(result)); + return result_ptr; } if (alternate_font_name != AlternateFontName::kAllowAlternate || @@ -82,16 +91,35 @@ const FontPlatformData* FontPlatformData return nullptr; FontFaceCreationParams create_by_alternate_family(alternate_name); - if (const FontPlatformData* result = GetOrCreateFontPlatformData( + if (FontPlatformData* result = GetOrCreateFontPlatformData( font_cache, font_description, create_by_alternate_family, AlternateFontName::kNoAlternate)) { // Cache the platform_data under the old name. // "accessibility/font-changed.html" reaches here. - map_.insert(key, result); + map_.insert(key, std::make_unique<FontPlatformData>(*result)); return result; } return nullptr; } +size_t FontPlatformDataCache::ByteSize() const { + return map_.size() * sizeof(std::unique_ptr<FontPlatformData>); +} + +void FontPlatformDataCache::Clear() { + map_.clear(); +} + +void FontPlatformDataCache::Purge(const FontDataCache& font_data_cache) { + Vector<FontCacheKey> keys_to_remove; + keys_to_remove.ReserveInitialCapacity(map_.size()); + for (auto& entry : map_) { + if (entry.value && !font_data_cache.Contains(entry.value.get())) { + keys_to_remove.push_back(entry.key); + } + } + map_.RemoveAll(keys_to_remove); +} + } // namespace blink --- a/third_party/blink/renderer/platform/fonts/font_platform_data_cache.h +++ b/third_party/blink/renderer/platform/fonts/font_platform_data_cache.h @@ -31,13 +31,13 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_PLATFORM_DATA_CACHE_H_ #include "third_party/blink/renderer/platform/fonts/font_cache_key.h" -#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h" -#include "third_party/blink/renderer/platform/heap/garbage_collected.h" +#include "third_party/blink/renderer/platform/wtf/hash_map.h" namespace blink { enum class AlternateFontName; class FontCache; +class FontDataCache; class FontDescription; class FontFaceCreationParams; class FontPlatformData; @@ -45,23 +45,30 @@ class FontPlatformData; // `FontPlatformDataCache` is the shared cache mapping from `FontDescription` // to `FontPlatformData`. class FontPlatformDataCache final { - DISALLOW_NEW(); - public: + static std::unique_ptr<FontPlatformDataCache> Create(); + FontPlatformDataCache(); + ~FontPlatformDataCache(); + + FontPlatformDataCache(const FontPlatformDataCache&) = delete; + FontPlatformDataCache(FontPlatformDataCache&&) = delete; - void Trace(Visitor* visitor) const { visitor->Trace(map_); } + FontPlatformDataCache operator=(const FontPlatformDataCache&) = delete; + FontPlatformDataCache operator=(FontPlatformDataCache&&) = delete; - const FontPlatformData* GetOrCreateFontPlatformData( + FontPlatformData* GetOrCreateFontPlatformData( FontCache* font_cache, const FontDescription& font_description, const FontFaceCreationParams& creation_params, AlternateFontName alternate_font_name); - void Clear() { map_.clear(); } + size_t ByteSize() const; + void Clear(); + void Purge(const FontDataCache& font_data_cache); private: - HeapHashMap<FontCacheKey, WeakMember<const FontPlatformData>> map_; + HashMap<FontCacheKey, std::unique_ptr<FontPlatformData>> map_; // A maximum float value to which we limit incoming font sizes. This is the // smallest float so that multiplying it by --- a/third_party/blink/renderer/platform/fonts/font_selector.h +++ b/third_party/blink/renderer/platform/fonts/font_selector.h @@ -53,8 +53,8 @@ class UseCounter; class PLATFORM_EXPORT FontSelector : public FontCacheClient { public: ~FontSelector() override = default; - virtual const FontData* GetFontData(const FontDescription&, - const FontFamily&) = 0; + virtual scoped_refptr<FontData> GetFontData(const FontDescription&, + const FontFamily&) = 0; // TODO(crbug.com/542629): The String variant of this method should be // replaced with a better approach, now that we only have complex text. @@ -92,7 +92,7 @@ class PLATFORM_EXPORT FontSelector : pub virtual void ReportFontLookupByUniqueOrFamilyName( const AtomicString& name, const FontDescription& font_description, - const SimpleFontData* resulting_font_data) = 0; + scoped_refptr<SimpleFontData> resulting_font_data) = 0; // Called whenever a page attempts to find a local font based on a name. This // only includes lookups where the name is allowed to match PostScript names @@ -100,7 +100,7 @@ class PLATFORM_EXPORT FontSelector : pub virtual void ReportFontLookupByUniqueNameOnly( const AtomicString& name, const FontDescription& font_description, - const SimpleFontData* resulting_font_data, + scoped_refptr<SimpleFontData> resulting_font_data, bool is_loading_fallback = false) = 0; // Called whenever a page attempts to find a local font based on a fallback @@ -109,12 +109,12 @@ class PLATFORM_EXPORT FontSelector : pub UChar32 fallback_character, FontFallbackPriority fallback_priority, const FontDescription& font_description, - const SimpleFontData* resulting_font_data) = 0; + scoped_refptr<SimpleFontData> resulting_font_data) = 0; // Called whenever a page attempts to find a last-resort font. virtual void ReportLastResortFallbackFontLookup( const FontDescription& font_description, - const SimpleFontData* resulting_font_data) = 0; + scoped_refptr<SimpleFontData> resulting_font_data) = 0; virtual void ReportNotDefGlyph() const = 0; --- a/third_party/blink/renderer/platform/fonts/fuchsia/font_cache_fuchsia.cc +++ b/third_party/blink/renderer/platform/fonts/fuchsia/font_cache_fuchsia.cc @@ -45,7 +45,7 @@ void FontCache::SetSystemFontFamily(cons MutableSystemFontFamily() = family_name; } -const SimpleFontData* FontCache::PlatformFallbackFontForCharacter( +scoped_refptr<SimpleFontData> FontCache::PlatformFallbackFontForCharacter( const FontDescription& font_description, UChar32 character, const SimpleFontData* font_data_to_substitute, @@ -67,12 +67,12 @@ const SimpleFontData* FontCache::Platfor !typeface->isItalic() && font_description.SyntheticItalicAllowed(); - const auto* font_data = MakeGarbageCollected<FontPlatformData>( + auto font_data = std::make_unique<FontPlatformData>( std::move(typeface), std::string(), font_description.EffectiveFontSize(), synthetic_bold, synthetic_italic, font_description.TextRendering(), ResolvedFontFeatures(), font_description.Orientation()); - return FontDataFromFontPlatformData(font_data); + return FontDataFromFontPlatformData(font_data.get(), kDoNotRetain); } } // namespace blink --- a/third_party/blink/renderer/platform/fonts/linux/font_cache_linux.cc +++ b/third_party/blink/renderer/platform/fonts/linux/font_cache_linux.cc @@ -62,7 +62,7 @@ bool FontCache::GetFontForCharacter(UCha } } -const SimpleFontData* FontCache::PlatformFallbackFontForCharacter( +scoped_refptr<SimpleFontData> FontCache::PlatformFallbackFontForCharacter( const FontDescription& font_description, UChar32 c, const SimpleFontData*, @@ -77,9 +77,11 @@ const SimpleFontData* FontCache::Platfor AtomicString family_name = GetFamilyNameForCharacter( font_manager_.get(), c, font_description, nullptr, fallback_priority); if (family_name.empty()) - return GetLastResortFallbackFont(font_description); - return FontDataFromFontPlatformData(GetFontPlatformData( - font_description, FontFaceCreationParams(family_name))); + return GetLastResortFallbackFont(font_description, kDoNotRetain); + return FontDataFromFontPlatformData( + GetFontPlatformData(font_description, + FontFaceCreationParams(family_name)), + kDoNotRetain); } if (fallback_priority == FontFallbackPriority::kEmojiEmoji) { @@ -94,7 +96,7 @@ const SimpleFontData* FontCache::Platfor if (fallback_priority != FontFallbackPriority::kEmojiEmoji && (font_description.Style() == kItalicSlopeValue || font_description.Weight() >= kBoldThreshold)) { - const SimpleFontData* font_data = + scoped_refptr<SimpleFontData> font_data = FallbackOnStandardFontStyle(font_description, c); if (font_data) return font_data; @@ -137,16 +139,16 @@ const SimpleFontData* FontCache::Platfor description.SetStyle(kNormalSlopeValue); } - const FontPlatformData* substitute_platform_data = + FontPlatformData* substitute_platform_data = GetFontPlatformData(description, creation_params); if (!substitute_platform_data) return nullptr; - FontPlatformData* platform_data = - MakeGarbageCollected<FontPlatformData>(*substitute_platform_data); + std::unique_ptr<FontPlatformData> platform_data( + new FontPlatformData(*substitute_platform_data)); platform_data->SetSyntheticBold(should_set_synthetic_bold); platform_data->SetSyntheticItalic(should_set_synthetic_italic); - return FontDataFromFontPlatformData(platform_data); + return FontDataFromFontPlatformData(platform_data.get(), kDoNotRetain); } } // namespace blink --- a/third_party/blink/renderer/platform/fonts/segmented_font_data.h +++ b/third_party/blink/renderer/platform/fonts/segmented_font_data.h @@ -28,7 +28,6 @@ #include "third_party/blink/renderer/platform/fonts/font_data.h" #include "third_party/blink/renderer/platform/fonts/font_data_for_range_set.h" -#include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/casting.h" @@ -38,21 +37,20 @@ class SimpleFontData; class PLATFORM_EXPORT SegmentedFontData : public FontData { public: - SegmentedFontData() = default; - - void Trace(Visitor* visitor) const override { - visitor->Trace(faces_); - FontData::Trace(visitor); + static scoped_refptr<SegmentedFontData> Create() { + return base::AdoptRef(new SegmentedFontData); } - void AppendFace(FontDataForRangeSet* font_data_for_range_set) { + void AppendFace(scoped_refptr<FontDataForRangeSet> font_data_for_range_set) { faces_.push_back(std::move(font_data_for_range_set)); } unsigned NumFaces() const { return faces_.size(); } - FontDataForRangeSet* FaceAt(unsigned i) const { return faces_[i].Get(); } + scoped_refptr<FontDataForRangeSet> FaceAt(unsigned i) const { return faces_[i]; } bool ContainsCharacter(UChar32) const; private: + SegmentedFontData() = default; + const SimpleFontData* FontDataForCharacter(UChar32) const override; bool IsCustomFont() const override; @@ -61,7 +59,7 @@ class PLATFORM_EXPORT SegmentedFontData bool IsSegmented() const override; bool ShouldSkipDrawing() const override; - HeapVector<Member<FontDataForRangeSet>, 1> faces_; + Vector<scoped_refptr<FontDataForRangeSet>, 1> faces_; }; template <> --- a/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.cc +++ b/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.cc @@ -127,7 +127,7 @@ Vector<double> CachingWordShaper::Indivi total_width); } -HeapVector<ShapeResult::RunFontData> CachingWordShaper::GetRunFontData( +Vector<ShapeResult::RunFontData> CachingWordShaper::GetRunFontData( const TextRun& run) const { ShapeResultBuffer buffer; ShapeResultsForRun(GetShapeCache(), &font_, run, &buffer); --- a/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h +++ b/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h @@ -26,6 +26,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_CACHING_WORD_SHAPER_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_CACHING_WORD_SHAPER_H_ +#include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.h" #include "third_party/blink/renderer/platform/text/text_run.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" @@ -59,7 +60,7 @@ class PLATFORM_EXPORT CachingWordShaper CharacterRange GetCharacterRange(const TextRun&, unsigned from, unsigned to); Vector<double> IndividualCharacterAdvances(const TextRun&); - HeapVector<ShapeResult::RunFontData> GetRunFontData(const TextRun&) const; + Vector<ShapeResult::RunFontData> GetRunFontData(const TextRun&) const; GlyphData EmphasisMarkGlyphData(const TextRun&) const; --- a/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc +++ b/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc @@ -65,8 +65,7 @@ namespace blink { -HarfBuzzFace::HarfBuzzFace(const FontPlatformData* platform_data, - uint64_t unique_id) +HarfBuzzFace::HarfBuzzFace(FontPlatformData* platform_data, uint64_t unique_id) : platform_data_(platform_data), unique_id_(unique_id) { HbFontCacheEntry* const cache_entry = FontGlobalContext::GetHarfBuzzFontCache().RefOrNew(unique_id_, @@ -79,9 +78,6 @@ HarfBuzzFace::~HarfBuzzFace() { FontGlobalContext::GetHarfBuzzFontCache().Remove(unique_id_); } -void HarfBuzzFace::Trace(Visitor* visitor) const { - visitor->Trace(platform_data_); -} bool& GetIgnoreVariationSelectors() { DEFINE_THREAD_SAFE_STATIC_LOCAL(WTF::ThreadSpecific<bool>, @@ -486,8 +482,7 @@ static hb_blob_t* HarfBuzzSkiaGetTable(h } // TODO(yosin): We should move |CreateFace()| to "harfbuzz_font_cache.cc". -static hb::unique_ptr<hb_face_t> CreateFace( - const FontPlatformData* platform_data) { +static hb::unique_ptr<hb_face_t> CreateFace(FontPlatformData* platform_data) { hb::unique_ptr<hb_face_t> face; sk_sp<SkTypeface> typeface = sk_ref_sp(platform_data->Typeface()); @@ -535,9 +530,8 @@ static scoped_refptr<HbFontCacheEntry> C return cache_entry; } -HbFontCacheEntry* HarfBuzzFontCache::RefOrNew( - uint64_t unique_id, - const FontPlatformData* platform_data) { +HbFontCacheEntry* HarfBuzzFontCache::RefOrNew(uint64_t unique_id, + FontPlatformData* platform_data) { const auto& result = font_map_.insert(unique_id, nullptr); if (result.is_new_entry) { hb::unique_ptr<hb_face_t> face = CreateFace(platform_data); --- a/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.h +++ b/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.h @@ -34,11 +34,10 @@ #include "third_party/blink/renderer/platform/fonts/glyph.h" #include "third_party/blink/renderer/platform/fonts/typesetting_features.h" #include "third_party/blink/renderer/platform/fonts/unicode_range_set.h" -#include "third_party/blink/renderer/platform/heap/garbage_collected.h" -#include "third_party/blink/renderer/platform/heap/member.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" +#include "third_party/blink/renderer/platform/wtf/ref_counted.h" #include "third_party/blink/renderer/platform/wtf/text/character_names.h" #include <hb.h> @@ -52,16 +51,18 @@ struct HarfBuzzFontData; // |HarfBuzzFace| is a thread specific data associated to |FontPlatformData|, // hold by |HarfBuzzFontCache|. -class PLATFORM_EXPORT HarfBuzzFace final - : public GarbageCollected<HarfBuzzFace> { +class PLATFORM_EXPORT HarfBuzzFace final : public RefCounted<HarfBuzzFace> { + USING_FAST_MALLOC(HarfBuzzFace); public: - HarfBuzzFace(const FontPlatformData* platform_data, uint64_t); + static scoped_refptr<HarfBuzzFace> Create(FontPlatformData* platform_data, + uint64_t unique_id) { + return base::AdoptRef(new HarfBuzzFace(platform_data, unique_id)); + } + HarfBuzzFace(const HarfBuzzFace&) = delete; HarfBuzzFace& operator=(const HarfBuzzFace&) = delete; ~HarfBuzzFace(); - void Trace(Visitor*) const; - enum VerticalLayoutCallbacks { kPrepareForVerticalLayout, kNoVerticalLayout }; // In order to support the restricting effect of unicode-range optionally a @@ -97,10 +98,11 @@ class PLATFORM_EXPORT HarfBuzzFace final static void SetIgnoreVariationSelectors(bool value); private: + HarfBuzzFace(FontPlatformData* platform_data, uint64_t); void PrepareHarfBuzzFontData(); - Member<const FontPlatformData> platform_data_; + FontPlatformData* const platform_data_; const uint64_t unique_id_; // TODO(crbug.com/1489080): When briefly given MiraclePtr protection, // these members were both found dangling. --- a/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.h +++ b/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.h @@ -49,7 +49,7 @@ class HarfBuzzFontCache final { ~HarfBuzzFontCache(); HbFontCacheEntry* RefOrNew(uint64_t unique_id, - const FontPlatformData* platform_data); + FontPlatformData* platform_data); void Remove(uint64_t unique_id); private: --- a/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc +++ b/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc @@ -853,7 +853,7 @@ void HarfBuzzShaper::ShapeSegment( fallback_chars_hint.ReserveInitialCapacity(range_data->end - range_data->start); } - FontDataForRangeSet* current_font_data_for_range_set = nullptr; + scoped_refptr<FontDataForRangeSet> current_font_data_for_range_set; FallbackFontStage fallback_stage = kIntermediate; while (!range_data->reshape_queue.empty()) { ReshapeQueueItem current_queue_item = range_data->reshape_queue.TakeFirst(); @@ -934,7 +934,7 @@ void HarfBuzzShaper::ShapeSegment( if (needs_caps_handling) { case_map_intend = caps_support.NeedsCaseChange(small_caps_behavior); if (caps_support.NeedsSyntheticFont(small_caps_behavior)) { - adjusted_font = font_data->SmallCapsFontData(font_description); + adjusted_font = font_data->SmallCapsFontData(font_description).get(); } } --- a/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc +++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc @@ -79,10 +79,9 @@ ASSERT_SIZE(ShapeResult::RunInfo, SameSi struct SameSizeAsShapeResult { float width; - UntracedMember<void*> deprecated_ink_bounds_; - Vector<int> runs_; - Vector<int> character_position_; - UntracedMember<void*> primary_font_; + UntracedMember<void*> member; + Vector<int> vectors[2]; + void *pointer; unsigned start_index_; unsigned num_characters_; unsigned bitfields : 32; @@ -396,7 +395,7 @@ void ShapeResult::RunInfo::CharacterInde } } -ShapeResult::ShapeResult(const SimpleFontData* font_data, +ShapeResult::ShapeResult(scoped_refptr<const SimpleFontData> font_data, unsigned start_index, unsigned num_characters, TextDirection direction) @@ -432,7 +431,6 @@ void ShapeResult::Trace(Visitor* visitor visitor->Trace(deprecated_ink_bounds_); visitor->Trace(runs_); visitor->Trace(character_position_); - visitor->Trace(primary_font_); } size_t ShapeResult::ByteSize() const { @@ -732,10 +730,10 @@ bool ShapeResult::HasFallbackFonts(const return false; } -void ShapeResult::GetRunFontData(HeapVector<RunFontData>* font_data) const { +void ShapeResult::GetRunFontData(Vector<RunFontData>* font_data) const { for (const auto& run : runs_) { font_data->push_back( - RunFontData({run->font_data_.Get(), run->glyph_data_.size()})); + RunFontData({run->font_data_.get(), run->glyph_data_.size()})); } } @@ -750,7 +748,7 @@ float ShapeResult::ForEachGlyphImpl(floa for (const auto& glyph_data : run.glyph_data_) { glyph_callback(context, run.start_index_ + glyph_data.character_index, glyph_data.glyph, *glyph_offsets, total_advance, - is_horizontal, run.canvas_rotation_, run.font_data_.Get()); + is_horizontal, run.canvas_rotation_, run.font_data_.get()); total_advance += glyph_data.advance; ++glyph_offsets; } @@ -785,7 +783,7 @@ float ShapeResult::ForEachGlyphImpl(floa auto total_advance = initial_advance; unsigned run_start = run.start_index_ + index_offset; bool is_horizontal = HB_DIRECTION_IS_HORIZONTAL(run.direction_); - const SimpleFontData* font_data = run.font_data_.Get(); + const SimpleFontData* font_data = run.font_data_.get(); if (run.IsLtr()) { // Left-to-right for (const auto& glyph_data : run.glyph_data_) { @@ -1738,7 +1736,7 @@ unsigned ShapeResult::CopyRangeInternal( ShapeResult* ShapeResult::SubRange(unsigned start_offset, unsigned end_offset) const { ShapeResult* sub_range = - MakeGarbageCollected<ShapeResult>(primary_font_.Get(), 0, 0, Direction()); + MakeGarbageCollected<ShapeResult>(primary_font_.get(), 0, 0, Direction()); CopyRange(start_offset, end_offset, sub_range); return sub_range; } --- a/third_party/blink/renderer/platform/fonts/shaping/shape_result.h +++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result.h @@ -136,7 +136,7 @@ typedef void (*GraphemeClusterCallback)( class PLATFORM_EXPORT ShapeResult : public GarbageCollected<ShapeResult> { public: - ShapeResult(const SimpleFontData*, + ShapeResult(scoped_refptr<const SimpleFontData>, unsigned start_index, unsigned num_characters, TextDirection); @@ -149,7 +149,7 @@ class PLATFORM_EXPORT ShapeResult : publ void Trace(Visitor*) const; static ShapeResult* CreateEmpty(const ShapeResult& other) { - return MakeGarbageCollected<ShapeResult>(other.primary_font_.Get(), 0, 0, + return MakeGarbageCollected<ShapeResult>(other.primary_font_, 0, 0, other.Direction()); } static const ShapeResult* CreateForTabulationCharacters( @@ -181,7 +181,7 @@ class PLATFORM_EXPORT ShapeResult : publ LayoutUnit SnappedWidth() const { return LayoutUnit::FromFloatCeil(width_); } unsigned NumCharacters() const { return num_characters_; } unsigned NumGlyphs() const { return num_glyphs_; } - const SimpleFontData* PrimaryFont() const { return primary_font_.Get(); } + const SimpleFontData* PrimaryFont() const { return primary_font_.get(); } bool HasFallbackFonts(const SimpleFontData* primary_font) const; // TODO(eae): Remove start_x and return value once ShapeResultBuffer has been @@ -352,12 +352,10 @@ class PLATFORM_EXPORT ShapeResult : publ // Computes the list of fonts along with the number of glyphs for each font. struct RunFontData { - DISALLOW_NEW(); - void Trace(Visitor* visitor) const { visitor->Trace(font_data_); } - Member<SimpleFontData> font_data_; + SimpleFontData* font_data_; wtf_size_t glyph_count_; }; - void GetRunFontData(HeapVector<RunFontData>* font_data) const; + void GetRunFontData(Vector<RunFontData>* font_data) const; // Iterates over, and calls the specified callback function, for all the // glyphs. Also tracks (and returns) a seeded total advance. @@ -517,7 +515,7 @@ class PLATFORM_EXPORT ShapeResult : publ // index to x-position and O(log n) time, using binary search, from // x-position to character index. mutable HeapVector<ShapeResultCharacterData> character_position_; - Member<const SimpleFontData> primary_font_; + scoped_refptr<const SimpleFontData> primary_font_; unsigned start_index_ = 0; unsigned num_characters_ = 0; @@ -572,6 +570,5 @@ PLATFORM_EXPORT std::ostream& operator<< } // namespace blink WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::ShapeResult::ShapeRange) -WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::ShapeResult::RunFontData) #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_SHAPE_RESULT_H_ --- a/third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.cc +++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.cc @@ -249,8 +249,8 @@ int ShapeResultBuffer::OffsetForPosition return total_offset; } -HeapVector<ShapeResult::RunFontData> ShapeResultBuffer::GetRunFontData() const { - HeapVector<ShapeResult::RunFontData> font_data; +Vector<ShapeResult::RunFontData> ShapeResultBuffer::GetRunFontData() const { + Vector<ShapeResult::RunFontData> font_data; for (const auto& result : results_) result->GetRunFontData(&font_data); return font_data; @@ -264,9 +264,10 @@ GlyphData ShapeResultBuffer::EmphasisMar if (run->glyph_data_.IsEmpty()) continue; - return GlyphData(run->glyph_data_[0].glyph, - run->font_data_->EmphasisMarkFontData(font_description), - run->CanvasRotation()); + return GlyphData( + run->glyph_data_[0].glyph, + run->font_data_->EmphasisMarkFontData(font_description).get(), + run->CanvasRotation()); } } --- a/third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.h +++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.h @@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_SHAPE_RESULT_BUFFER_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_SHAPE_RESULT_BUFFER_H_ +#include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/platform/fonts/shaping/shape_result.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h" #include "third_party/blink/renderer/platform/platform_export.h" @@ -47,7 +48,7 @@ class PLATFORM_EXPORT ShapeResultBuffer TextDirection, float total_width) const; - HeapVector<ShapeResult::RunFontData> GetRunFontData() const; + Vector<ShapeResult::RunFontData> GetRunFontData() const; GlyphData EmphasisMarkGlyphData(const FontDescription&) const; --- a/third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h +++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h @@ -79,7 +79,7 @@ struct ShapeResult::RunInfo final direction_(other.direction_), canvas_rotation_(other.canvas_rotation_) {} - void Trace(Visitor* visitor) const { visitor->Trace(font_data_); } + void Trace(Visitor*) const {} unsigned NumGlyphs() const { return glyph_data_.size(); } bool IsLtr() const { return HB_DIRECTION_IS_FORWARD(direction_); } @@ -130,7 +130,7 @@ struct ShapeResult::RunInfo final return nullptr; auto* run = MakeGarbageCollected<RunInfo>( - font_data_.Get(), direction_, canvas_rotation_, script_, + font_data_.get(), direction_, canvas_rotation_, script_, start_index_ + start, number_of_glyphs, number_of_characters); run->glyph_data_.CopyFromRange(glyphs); @@ -154,7 +154,7 @@ struct ShapeResult::RunInfo final return nullptr; DCHECK_LT(start_index_, other.start_index_); auto* run = MakeGarbageCollected<RunInfo>( - font_data_.Get(), direction_, canvas_rotation_, script_, start_index_, + font_data_.get(), direction_, canvas_rotation_, script_, start_index_, glyph_data_.size() + other.glyph_data_.size(), num_characters_ + other.num_characters_); // Note: We populate |graphemes_| on demand, e.g. hit testing. @@ -374,7 +374,7 @@ struct ShapeResult::RunInfo final } GlyphDataCollection glyph_data_; - Member<SimpleFontData> font_data_; + scoped_refptr<SimpleFontData> font_data_; // graphemes_[i] is the number of graphemes up to (and including) the ith // character in the run. --- a/third_party/blink/renderer/platform/fonts/shaping/shape_result_test_info.cc +++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result_test_info.cc @@ -54,7 +54,7 @@ float ShapeResultTestInfo::AdvanceForTes SimpleFontData* ShapeResultTestInfo::FontDataForTesting( unsigned run_index) const { - return runs_[run_index]->font_data_.Get(); + return runs_[run_index]->font_data_.get(); } Vector<unsigned> ShapeResultTestInfo::CharacterIndexesForTesting() const { --- a/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.cc +++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.cc @@ -28,9 +28,7 @@ ShapeResultView::RunInfoPart::RunInfoPar start_index_(start_index), offset_(offset), num_characters_(num_characters), - width_(width) { - static_assert(std::is_trivially_destructible<RunInfoPart>::value, ""); -} + width_(width) {} void ShapeResultView::RunInfoPart::Trace(Visitor* visitor) const { visitor->Trace(run_); @@ -74,10 +72,7 @@ unsigned ShapeResultView::CharacterIndex // |InitData| provides values of const member variables of |ShapeResultView| // for constructor. struct ShapeResultView::InitData { - STACK_ALLOCATED(); - - public: - const SimpleFontData* primary_font = nullptr; + scoped_refptr<const SimpleFontData> primary_font; unsigned start_index = 0; unsigned char_index_offset = 0; TextDirection direction = TextDirection::kLtr; @@ -188,7 +183,7 @@ ShapeResult* ShapeResultView::CreateShap new_result->runs_.ReserveInitialCapacity(parts_.size()); for (const auto& part : RunsOrParts()) { auto* new_run = MakeGarbageCollected<ShapeResult::RunInfo>( - part.run_->font_data_.Get(), part.run_->direction_, + part.run_->font_data_.get(), part.run_->direction_, part.run_->canvas_rotation_, part.run_->script_, part.start_index_, part.NumGlyphs(), part.num_characters_); new_run->glyph_data_.CopyFromRange(part.range_); @@ -364,21 +359,21 @@ unsigned ShapeResultView::PreviousSafeTo } void ShapeResultView::GetRunFontData( - HeapVector<ShapeResult::RunFontData>* font_data) const { + Vector<ShapeResult::RunFontData>* font_data) const { for (const auto& part : RunsOrParts()) { font_data->push_back(ShapeResult::RunFontData( - {part.run_->font_data_.Get(), + {part.run_->font_data_.get(), static_cast<wtf_size_t>(part.end() - part.begin())})); } } void ShapeResultView::FallbackFonts( - HeapHashSet<Member<const SimpleFontData>>* fallback) const { + HashSet<const SimpleFontData*>* fallback) const { DCHECK(fallback); DCHECK(primary_font_); for (const auto& part : RunsOrParts()) { if (part.run_->font_data_ && part.run_->font_data_ != primary_font_) { - fallback->insert(part.run_->font_data_.Get()); + fallback->insert(part.run_->font_data_.get()); } } } @@ -392,7 +387,7 @@ float ShapeResultView::ForEachGlyphImpl( const auto& run = part.run_; auto total_advance = initial_advance; bool is_horizontal = HB_DIRECTION_IS_HORIZONTAL(run->direction_); - const SimpleFontData* font_data = run->font_data_.Get(); + const SimpleFontData* font_data = run->font_data_.get(); const unsigned character_index_offset_for_glyph_data = CharacterIndexOffsetForGlyphData(part); for (const auto& glyph_data : part) { @@ -435,7 +430,7 @@ float ShapeResultView::ForEachGlyphImpl( auto total_advance = initial_advance; const auto& run = part.run_; bool is_horizontal = HB_DIRECTION_IS_HORIZONTAL(run->direction_); - const SimpleFontData* font_data = run->font_data_.Get(); + const SimpleFontData* font_data = run->font_data_.get(); const unsigned character_index_offset_for_glyph_data = CharacterIndexOffsetForGlyphData(part); if (run->IsLtr()) { // Left-to-right --- a/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h +++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h @@ -10,7 +10,6 @@ #include "third_party/blink/renderer/platform/fonts/shaping/shape_result.h" #include "third_party/blink/renderer/platform/fonts/simple_font_data.h" #include "third_party/blink/renderer/platform/geometry/layout_unit.h" -#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/text/text_direction.h" #include "third_party/blink/renderer/platform/wtf/forward.h" @@ -111,10 +110,7 @@ class PLATFORM_EXPORT ShapeResultView fi ShapeResultView& operator=(const ShapeResultView&) = delete; ~ShapeResultView() = default; - void Trace(Visitor* visitor) const { - visitor->Trace(parts_); - visitor->Trace(primary_font_); - } + void Trace(Visitor* visitor) const { visitor->Trace(parts_); } ShapeResult* CreateShapeResult() const; @@ -130,7 +126,7 @@ class PLATFORM_EXPORT ShapeResultView fi bool IsLtr() const { return blink::IsLtr(Direction()); } bool IsRtl() const { return blink::IsRtl(Direction()); } bool HasVerticalOffsets() const { return has_vertical_offsets_; } - void FallbackFonts(HeapHashSet<Member<const SimpleFontData>>* fallback) const; + void FallbackFonts(HashSet<const SimpleFontData*>* fallback) const; unsigned PreviousSafeToBreakOffset(unsigned index) const; @@ -155,8 +151,10 @@ class PLATFORM_EXPORT ShapeResultView fi // bounds. gfx::RectF ComputeInkBounds() const; - const SimpleFontData* PrimaryFont() const { return primary_font_.Get(); } - void GetRunFontData(HeapVector<ShapeResult::RunFontData>*) const; + scoped_refptr<const SimpleFontData> PrimaryFont() const { + return primary_font_; + } + void GetRunFontData(Vector<ShapeResult::RunFontData>*) const; void ExpandRangeToIncludePartialGlyphs(unsigned* from, unsigned* to) const; @@ -288,8 +286,7 @@ class PLATFORM_EXPORT ShapeResultView fi unsigned StartIndexOffsetForRun() const { return char_index_offset_; } - HeapVector<RunInfoPart, 1> parts_; - Member<const SimpleFontData> const primary_font_; + scoped_refptr<const SimpleFontData> const primary_font_; const unsigned start_index_; @@ -311,6 +308,8 @@ class PLATFORM_EXPORT ShapeResultView fi // with ShapeResult::SubRange const unsigned char_index_offset_; + HeapVector<RunInfoPart, 1> parts_; + private: friend class ShapeResult; --- a/third_party/blink/renderer/platform/fonts/simple_font_data.cc +++ b/third_party/blink/renderer/platform/fonts/simple_font_data.cc @@ -76,14 +76,14 @@ constexpr int32_t kFontObjectsMemoryCons constexpr int32_t kFontObjectsMemoryConsumption = 2128; #endif -SimpleFontData::SimpleFontData(const FontPlatformData* platform_data, - const CustomFontData* custom_data, +SimpleFontData::SimpleFontData(const FontPlatformData& platform_data, + scoped_refptr<CustomFontData> custom_data, bool subpixel_ascent_descent, const FontMetricsOverride& metrics_override) : platform_data_(platform_data), - font_(platform_data->size() ? platform_data->CreateSkFont() + font_(platform_data_.size() ? platform_data.CreateSkFont() : skia::DefaultFont()), - custom_font_data_(custom_data) { + custom_font_data_(std::move(custom_data)) { // Every time new SimpleFontData instance is created, Skia will ask // FreeType to get the metrics for glyphs by invoking // af_face_globals_get_metrics. There FT will allocate style_metrics_size @@ -111,7 +111,7 @@ SimpleFontData::~SimpleFontData() { void SimpleFontData::PlatformInit(bool subpixel_ascent_descent, const FontMetricsOverride& metrics_override) { - if (!platform_data_->size()) { + if (!platform_data_.size()) { font_metrics_.Reset(); avg_char_width_ = 0; max_char_width_ = 0; @@ -126,7 +126,7 @@ void SimpleFontData::PlatformInit(bool s float descent; FontMetrics::AscentDescentWithHacks( - ascent, descent, *platform_data_, font_, subpixel_ascent_descent, + ascent, descent, platform_data_, font_, subpixel_ascent_descent, metrics_override.ascent_override, metrics_override.descent_override); font_metrics_.SetAscent(ascent); @@ -164,7 +164,7 @@ void SimpleFontData::PlatformInit(bool s float line_gap; if (metrics_override.line_gap_override) { - line_gap = *metrics_override.line_gap_override * platform_data_->size(); + line_gap = *metrics_override.line_gap_override * platform_data_.size(); } else { line_gap = SkScalarToFloat(metrics.fLeading); } @@ -261,39 +261,45 @@ bool SimpleFontData::IsSegmented() const return false; } -SimpleFontData* SimpleFontData::SmallCapsFontData( +scoped_refptr<SimpleFontData> SimpleFontData::SmallCapsFontData( const FontDescription& font_description) const { - if (!small_caps_) { - small_caps_ = + if (!derived_font_data_) + derived_font_data_ = std::make_unique<DerivedFontData>(); + if (!derived_font_data_->small_caps) { + derived_font_data_->small_caps = CreateScaledFontData(font_description, kSmallCapsFontSizeMultiplier); } - return small_caps_; + + return derived_font_data_->small_caps; } -SimpleFontData* SimpleFontData::EmphasisMarkFontData( +scoped_refptr<SimpleFontData> SimpleFontData::EmphasisMarkFontData( const FontDescription& font_description) const { - if (!emphasis_mark_) { - emphasis_mark_ = + if (!derived_font_data_) + derived_font_data_ = std::make_unique<DerivedFontData>(); + if (!derived_font_data_->emphasis_mark) { + derived_font_data_->emphasis_mark = CreateScaledFontData(font_description, kEmphasisMarkFontSizeMultiplier); } - return emphasis_mark_; + + return derived_font_data_->emphasis_mark; } -SimpleFontData* SimpleFontData::CreateScaledFontData( +scoped_refptr<SimpleFontData> SimpleFontData::CreateScaledFontData( const FontDescription& font_description, float scale_factor) const { const float scaled_size = lroundf(font_description.ComputedSize() * scale_factor); - return MakeGarbageCollected<SimpleFontData>( - MakeGarbageCollected<FontPlatformData>(*platform_data_, scaled_size), - IsCustomFont() ? MakeGarbageCollected<CustomFontData>() : nullptr); + return SimpleFontData::Create( + FontPlatformData(platform_data_, scaled_size), + IsCustomFont() ? CustomFontData::Create() : nullptr); } -SimpleFontData* SimpleFontData::MetricsOverriddenFontData( +scoped_refptr<SimpleFontData> SimpleFontData::MetricsOverriddenFontData( const FontMetricsOverride& metrics_override) const { - return MakeGarbageCollected<SimpleFontData>( - platform_data_, custom_font_data_, false /* subpixel_ascent_descent */, - metrics_override); + return base::AdoptRef(new SimpleFontData(platform_data_, custom_font_data_, + false /* subpixel_ascent_descent */, + metrics_override)); } // Internal leadings can be distributed to ascent and descent. @@ -347,7 +353,7 @@ static std::pair<int16_t, int16_t> TypoA void SimpleFontData::ComputeNormalizedTypoAscentAndDescent() const { // Compute em height metrics from OS/2 sTypoAscender and sTypoDescender. - SkTypeface* typeface = platform_data_->Typeface(); + SkTypeface* typeface = platform_data_.Typeface(); auto [typo_ascender, typo_descender] = TypoAscenderAndDescender(typeface); if (typo_ascender > 0 && TrySetNormalizedTypoAscentAndDescent(typo_ascender, typo_descender)) { @@ -434,7 +440,7 @@ const std::optional<float>& SimpleFontDa } // Compute vertical advance if the orientation is `kVerticalUpright`. - const HarfBuzzFace* hb_face = platform_data_->GetHarfBuzzFace(); + const HarfBuzzFace* hb_face = platform_data_.GetHarfBuzzFace(); const OpenTypeVerticalData& vertical_data = hb_face->VerticalData(); ideographic_inline_size_ = vertical_data.AdvanceHeight(cjk_water_glyph); }); @@ -462,9 +468,8 @@ const HanKerning::FontData& SimpleFontDa } gfx::RectF SimpleFontData::PlatformBoundsForGlyph(Glyph glyph) const { - if (!platform_data_->size()) { + if (!platform_data_.size()) return gfx::RectF(); - } static_assert(sizeof(glyph) == 2, "Glyph id should not be truncated."); @@ -477,18 +482,16 @@ void SimpleFontData::BoundsForGlyphs(con Vector<SkRect, 256>* bounds) const { DCHECK_EQ(glyphs.size(), bounds->size()); - if (!platform_data_->size()) { + if (!platform_data_.size()) return; - } DCHECK_EQ(bounds->size(), glyphs.size()); SkFontGetBoundsForGlyphs(font_, glyphs, bounds->data()); } float SimpleFontData::WidthForGlyph(Glyph glyph) const { - if (!platform_data_->size()) { + if (!platform_data_.size()) return 0; - } static_assert(sizeof(glyph) == 2, "Glyph id should not be truncated."); --- a/third_party/blink/renderer/platform/fonts/simple_font_data.h +++ b/third_party/blink/renderer/platform/fonts/simple_font_data.h @@ -40,7 +40,6 @@ #include "third_party/blink/renderer/platform/fonts/glyph.h" #include "third_party/blink/renderer/platform/fonts/shaping/han_kerning.h" #include "third_party/blink/renderer/platform/fonts/typesetting_features.h" -#include "third_party/blink/renderer/platform/heap/member.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/casting.h" #include "third_party/blink/renderer/platform/wtf/text/string_hash.h" @@ -75,18 +74,12 @@ class FontDescription; class PLATFORM_EXPORT SimpleFontData final : public FontData { public: // Used to create platform fonts. - SimpleFontData( - const FontPlatformData*, - const CustomFontData* custom_data = nullptr, - bool subpixel_ascent_descent = false, - const FontMetricsOverride& metrics_override = FontMetricsOverride()); - - void Trace(Visitor* visitor) const override { - visitor->Trace(platform_data_); - visitor->Trace(small_caps_); - visitor->Trace(emphasis_mark_); - visitor->Trace(custom_font_data_); - FontData::Trace(visitor); + static scoped_refptr<SimpleFontData> Create( + const FontPlatformData& platform_data, + scoped_refptr<CustomFontData> custom_data = nullptr, + bool subpixel_ascent_descent = false) { + return base::AdoptRef(new SimpleFontData( + platform_data, std::move(custom_data), subpixel_ascent_descent)); } SimpleFontData(const SimpleFontData&) = delete; @@ -95,11 +88,13 @@ class PLATFORM_EXPORT SimpleFontData fin SimpleFontData& operator=(const SimpleFontData&) = delete; SimpleFontData& operator=(const SimpleFontData&&) = delete; - const FontPlatformData& PlatformData() const { return *platform_data_; } + const FontPlatformData& PlatformData() const { return platform_data_; } - SimpleFontData* SmallCapsFontData(const FontDescription&) const; - SimpleFontData* EmphasisMarkFontData(const FontDescription&) const; - SimpleFontData* MetricsOverriddenFontData(const FontMetricsOverride&) const; + scoped_refptr<SimpleFontData> SmallCapsFontData(const FontDescription&) const; + scoped_refptr<SimpleFontData> EmphasisMarkFontData( + const FontDescription&) const; + scoped_refptr<SimpleFontData> MetricsOverriddenFontData( + const FontMetricsOverride&) const; FontMetrics& GetFontMetrics() { return font_metrics_; } const FontMetrics& GetFontMetrics() const { return font_metrics_; } @@ -154,7 +149,7 @@ class PLATFORM_EXPORT SimpleFontData fin Glyph GlyphForCharacter(UChar32) const; - bool IsCustomFont() const override { return custom_font_data_; } + bool IsCustomFont() const override { return custom_font_data_.get(); } bool IsLoading() const override { return custom_font_data_ ? custom_font_data_->IsLoading() : false; } @@ -169,16 +164,20 @@ class PLATFORM_EXPORT SimpleFontData fin return custom_font_data_ && custom_font_data_->ShouldSkipDrawing(); } - const CustomFontData* GetCustomFontData() const { - return custom_font_data_.Get(); - } + CustomFontData* GetCustomFontData() const { return custom_font_data_.get(); } private: + SimpleFontData( + const FontPlatformData&, + scoped_refptr<CustomFontData> custom_data, + bool subpixel_ascent_descent = false, + const FontMetricsOverride& metrics_override = FontMetricsOverride()); + void PlatformInit(bool subpixel_ascent_descent, const FontMetricsOverride&); void PlatformGlyphInit(); - SimpleFontData* CreateScaledFontData(const FontDescription&, - float scale_factor) const; + scoped_refptr<SimpleFontData> CreateScaledFontData(const FontDescription&, + float scale_factor) const; void ComputeNormalizedTypoAscentAndDescent() const; bool TrySetNormalizedTypoAscentAndDescent(float ascent, float descent) const; @@ -187,17 +186,30 @@ class PLATFORM_EXPORT SimpleFontData fin float max_char_width_ = -1; float avg_char_width_ = -1; - Member<const FontPlatformData> platform_data_; + const FontPlatformData platform_data_; const SkFont font_; Glyph space_glyph_ = 0; float space_width_ = 0; Glyph zero_glyph_ = 0; - mutable Member<SimpleFontData> small_caps_; - mutable Member<SimpleFontData> emphasis_mark_; + struct DerivedFontData final { + USING_FAST_MALLOC(DerivedFontData); + + public: + DerivedFontData() = default; + DerivedFontData(const DerivedFontData&) = delete; + DerivedFontData(DerivedFontData&&) = delete; + DerivedFontData& operator=(const DerivedFontData&) = delete; + DerivedFontData& operator=(DerivedFontData&&) = delete; + + scoped_refptr<SimpleFontData> small_caps; + scoped_refptr<SimpleFontData> emphasis_mark; + }; + + mutable std::unique_ptr<DerivedFontData> derived_font_data_; - Member<const CustomFontData> custom_font_data_; + const scoped_refptr<CustomFontData> custom_font_data_; mutable std::once_flag ideographic_inline_size_once_; mutable std::once_flag ideographic_advance_width_once_; --- a/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc +++ b/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc @@ -94,7 +94,7 @@ AtomicString FontCache::GetFamilyNameFor void FontCache::PlatformInit() {} -const SimpleFontData* FontCache::FallbackOnStandardFontStyle( +scoped_refptr<SimpleFontData> FontCache::FallbackOnStandardFontStyle( const FontDescription& font_description, UChar32 character) { FontDescription substitute_description(font_description); @@ -103,26 +103,27 @@ const SimpleFontData* FontCache::Fallbac FontFaceCreationParams creation_params( substitute_description.Family().FamilyName()); - const FontPlatformData* substitute_platform_data = + FontPlatformData* substitute_platform_data = GetFontPlatformData(substitute_description, creation_params); if (substitute_platform_data && substitute_platform_data->FontContainsCharacter(character)) { - FontPlatformData* platform_data = - MakeGarbageCollected<FontPlatformData>(*substitute_platform_data); - platform_data->SetSyntheticBold(font_description.Weight() >= - kBoldThreshold && - font_description.SyntheticBoldAllowed()); - platform_data->SetSyntheticItalic( - font_description.Style() == kItalicSlopeValue && - font_description.SyntheticItalicAllowed()); - return FontDataFromFontPlatformData(platform_data); + FontPlatformData platform_data = + FontPlatformData(*substitute_platform_data); + platform_data.SetSyntheticBold(font_description.Weight() >= + kBoldThreshold && + font_description.SyntheticBoldAllowed()); + platform_data.SetSyntheticItalic(font_description.Style() == + kItalicSlopeValue && + font_description.SyntheticItalicAllowed()); + return FontDataFromFontPlatformData(&platform_data, kDoNotRetain); } return nullptr; } -const SimpleFontData* FontCache::GetLastResortFallbackFont( - const FontDescription& description) { +scoped_refptr<SimpleFontData> FontCache::GetLastResortFallbackFont( + const FontDescription& description, + ShouldRetain should_retain) { const FontFaceCreationParams fallback_creation_params( GetFallbackFontFamily(description)); const FontPlatformData* font_platform_data = GetFontPlatformData( @@ -195,7 +196,7 @@ const SimpleFontData* FontCache::GetLast #endif DCHECK(font_platform_data); - return FontDataFromFontPlatformData(font_platform_data); + return FontDataFromFontPlatformData(font_platform_data, should_retain); } sk_sp<SkTypeface> FontCache::CreateTypeface( @@ -238,7 +239,7 @@ sk_sp<SkTypeface> FontCache::CreateTypef } #if !BUILDFLAG(IS_WIN) -const FontPlatformData* FontCache::CreateFontPlatformData( +std::unique_ptr<FontPlatformData> FontCache::CreateFontPlatformData( const FontDescription& font_description, const FontFaceCreationParams& creation_params, float font_size, @@ -293,10 +294,11 @@ const FontPlatformData* FontCache::Creat ->GetResolvedFontFeatures() : ResolvedFontFeatures(); - FontPlatformData* font_platform_data = MakeGarbageCollected<FontPlatformData>( - typeface, name, font_size, synthetic_bold, synthetic_italic, - font_description.TextRendering(), resolved_font_features, - font_description.Orientation()); + std::unique_ptr<FontPlatformData> font_platform_data = + std::make_unique<FontPlatformData>( + typeface, name, font_size, synthetic_bold, synthetic_italic, + font_description.TextRendering(), resolved_font_features, + font_description.Orientation()); font_platform_data->SetAvoidEmbeddedBitmaps( BitmapGlyphsBlockList::ShouldAvoidEmbeddedBitmapsForTypeface(*typeface)); --- a/third_party/blink/renderer/platform/testing/font_test_helpers.cc +++ b/third_party/blink/renderer/platform/testing/font_test_helpers.cc @@ -43,26 +43,23 @@ class TestFontSelector : public FontSele } ~TestFontSelector() override = default; - FontData* GetFontData(const FontDescription& font_description, - const FontFamily&) override { + scoped_refptr<FontData> GetFontData(const FontDescription& font_description, + const FontFamily&) override { FontSelectionCapabilities normal_capabilities( {kNormalWidthValue, kNormalWidthValue}, {kNormalSlopeValue, kNormalSlopeValue}, {kNormalWeightValue, kNormalWeightValue}); - const FontPlatformData* platform_data = - custom_platform_data_->GetFontPlatformData( - font_description.EffectiveFontSize(), - font_description.AdjustedSpecifiedSize(), - font_description.IsSyntheticBold() && - font_description.SyntheticBoldAllowed(), - font_description.IsSyntheticItalic() && - font_description.SyntheticItalicAllowed(), - font_description.GetFontSelectionRequest(), normal_capabilities, - font_description.FontOpticalSizing(), - font_description.TextRendering(), {}, - font_description.Orientation()); - return MakeGarbageCollected<SimpleFontData>( - platform_data, MakeGarbageCollected<CustomFontData>()); + FontPlatformData platform_data = custom_platform_data_->GetFontPlatformData( + font_description.EffectiveFontSize(), + font_description.AdjustedSpecifiedSize(), + font_description.IsSyntheticBold() && + font_description.SyntheticBoldAllowed(), + font_description.IsSyntheticItalic() && + font_description.SyntheticItalicAllowed(), + font_description.GetFontSelectionRequest(), normal_capabilities, + font_description.FontOpticalSizing(), font_description.TextRendering(), + {}, font_description.Orientation()); + return SimpleFontData::Create(platform_data, CustomFontData::Create()); } void WillUseFontData(const FontDescription&, @@ -83,20 +80,20 @@ class TestFontSelector : public FontSele void ReportFontLookupByUniqueOrFamilyName( const AtomicString& name, const FontDescription& font_description, - const SimpleFontData* resulting_font_data) override {} + scoped_refptr<SimpleFontData> resulting_font_data) override {} void ReportFontLookupByUniqueNameOnly( const AtomicString& name, const FontDescription& font_description, - const SimpleFontData* resulting_font_data, + scoped_refptr<SimpleFontData> resulting_font_data, bool is_loading_fallback = false) override {} void ReportFontLookupByFallbackCharacter( UChar32 hint, FontFallbackPriority fallback_priority, const FontDescription& font_description, - const SimpleFontData* resulting_font_data) override {} + scoped_refptr<SimpleFontData> resulting_font_data) override {} void ReportLastResortFallbackFontLookup( const FontDescription& font_description, - const SimpleFontData* resulting_font_data) override {} + scoped_refptr<SimpleFontData> resulting_font_data) override {} void ReportNotDefGlyph() const override {} void ReportEmojiSegmentGlyphCoverage(unsigned, unsigned) override {} ExecutionContext* GetExecutionContext() const override { return nullptr; } --- a/tools/privacy_budget/font_indexer/font_indexer.cc +++ b/tools/privacy_budget/font_indexer/font_indexer.cc @@ -116,7 +116,7 @@ void FontIndexer::FontListHasLoaded(base bool FontIndexer::DoesFontHaveDigest(WTF::AtomicString name, blink::FontDescription font_description, int64_t digest) { - const blink::SimpleFontData* font_data = + scoped_refptr<blink::SimpleFontData> font_data = font_cache_->GetFontData(font_description, name); DCHECK(font_data); return blink::FontGlobalContext::Get() @@ -170,7 +170,7 @@ void FontIndexer::PrintAllFontsWithName( // exists and for later comparison. int64_t default_font_digest; { - const blink::SimpleFontData* font_data = + scoped_refptr<blink::SimpleFontData> font_data = font_cache_->GetFontData(blink::FontDescription(), name); default_font_digest = font_data ? blink::FontGlobalContext::Get() @@ -231,7 +231,7 @@ void FontIndexer::PrintAllFontsWithName( for (auto slope_pair : slopes) { font_description.SetStyle(slope_pair.first); - if (const blink::SimpleFontData* font_data = + if (scoped_refptr<blink::SimpleFontData> font_data = font_cache_->GetFontData(font_description, name)) { uint64_t typeface_digest = blink::FontGlobalContext::Get()
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor