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 {
@@ -169,8 +168,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
@@ -12,7 +12,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 {
@@ -33,10 +32,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;
@@ -60,6 +60,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)
--- 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
@@ -77,7 +77,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
@@ -621,6 +621,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
@@ -60,8 +60,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 Vector<UChar32>& hint_list) {
if (!candidate->HasFontData())
return Next(hint_list);
@@ -104,18 +104,18 @@ bool FontFallbackIterator::NeedsHintList
return font_data->IsSegmented();
}
-FontDataForRangeSet* FontFallbackIterator::Next(
+scoped_refptr<FontDataForRangeSet> FontFallbackIterator::Next(
const Vector<UChar32>& 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);
@@ -123,11 +123,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
@@ -137,16 +137,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) {
@@ -177,13 +179,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);
}
@@ -197,7 +199,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_++;
@@ -208,7 +210,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 =
@@ -222,15 +224,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;
}
@@ -255,7 +259,7 @@ static inline unsigned ChooseHintIndex(c
return 0;
}
-const SimpleFontData* FontFallbackIterator::UniqueSystemFontForHintList(
+scoped_refptr<SimpleFontData> FontFallbackIterator::UniqueSystemFontForHintList(
const Vector<UChar32>& 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
@@ -270,13 +274,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 {
@@ -42,7 +43,7 @@ class FontFallbackIterator {
// 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 Vector<UChar32>& hint_list);
+ scoped_refptr<FontDataForRangeSet> Next(const Vector<UChar32>& hint_list);
private:
bool RangeSetContributesForHint(const Vector<UChar32>& hint_list,
@@ -50,11 +51,12 @@ class FontFallbackIterator {
bool AlreadyLoadingRangeForHintChar(UChar32 hint_char);
void WillUseRange(const AtomicString& family, const FontDataForRangeSet&);
- FontDataForRangeSet* UniqueOrNext(FontDataForRangeSet* candidate,
- const Vector<UChar32>& hint_list);
+ scoped_refptr<FontDataForRangeSet> UniqueOrNext(
+ scoped_refptr<FontDataForRangeSet> candidate,
+ const Vector<UChar32>& hint_list);
- const SimpleFontData* FallbackPriorityFont(UChar32 hint);
- const SimpleFontData* UniqueSystemFontForHintList(
+ scoped_refptr<SimpleFontData> FallbackPriorityFont(UChar32 hint);
+ scoped_refptr<SimpleFontData> UniqueSystemFontForHintList(
const Vector<UChar32>& hint_list);
const FontDescription& font_description_;
@@ -82,8 +84,8 @@ class FontFallbackIterator {
// 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
@@ -158,10 +158,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());
@@ -213,10 +209,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(
@@ -246,7 +243,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
@@ -129,7 +126,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)
@@ -185,7 +182,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
@@ -62,8 +62,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_,
@@ -76,10 +75,6 @@ HarfBuzzFace::~HarfBuzzFace() {
FontGlobalContext::GetHarfBuzzFontCache().Remove(unique_id_);
}
-void HarfBuzzFace::Trace(Visitor* visitor) const {
- visitor->Trace(platform_data_);
-}
-
static hb_bool_t HarfBuzzGetGlyph(hb_font_t* hb_font,
void* font_data,
hb_codepoint_t unicode,
@@ -426,8 +421,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());
@@ -475,9 +469,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,9 +34,8 @@
#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/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>
@@ -50,15 +49,19 @@ struct HarfBuzzFontData;
// |HarfBuzzFace| is a thread specific data associated to |FontPlatformData|,
// hold by |HarfBuzzFontCache|.
-class HarfBuzzFace final : public GarbageCollected<HarfBuzzFace> {
+class 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
@@ -87,10 +90,11 @@ class HarfBuzzFace final : public Garbag
static void Init();
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
@@ -784,7 +784,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;
while (!range_data->reshape_queue.empty()) {
ReshapeQueueItem current_queue_item = range_data->reshape_queue.TakeFirst();
@@ -847,7 +847,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();
}
CaseMappingHarfBuzzBufferFiller(
--- 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)
@@ -436,7 +435,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 {
@@ -736,10 +734,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()}));
}
}
@@ -754,7 +752,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;
}
@@ -789,7 +787,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_) {
@@ -1679,7 +1677,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
@@ -139,7 +139,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);
@@ -152,7 +152,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(
@@ -184,7 +184,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
@@ -350,12 +350,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.
@@ -515,7 +513,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_;
unsigned num_characters_;
@@ -570,6 +568,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.
@@ -346,7 +352,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)) {
@@ -433,7 +439,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);
});
@@ -461,9 +467,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.");
@@ -476,18 +481,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()