From 45dd415ba561a3ca587db51812c0bfdc6d7351bb Mon Sep 17 00:00:00 2001 From: Gary Qian Date: Fri, 30 Jun 2017 13:39:24 -0700 Subject: [PATCH] Add low memory setting on FontCollection. Only remove trailing whitespace at end of line, and do not justify last line. Change-Id: Iee32003624862b3c7f5f2d0e999ef72719302551 --- engine/src/flutter/src/font_collection.cc | 32 ++++++++++++++----- engine/src/flutter/src/font_collection.h | 9 +++++- engine/src/flutter/src/paragraph.cc | 8 +++-- .../flutter/tests/txt/paragraph_unittests.cc | 4 +-- 4 files changed, 38 insertions(+), 15 deletions(-) diff --git a/engine/src/flutter/src/font_collection.cc b/engine/src/flutter/src/font_collection.cc index eb0a793a42..ca8132e7c6 100644 --- a/engine/src/flutter/src/font_collection.cc +++ b/engine/src/flutter/src/font_collection.cc @@ -100,13 +100,31 @@ bool FontCollection::HasFamily(const std::string family) const { void FontCollection::FlushCache() { minikin_font_collection_map_.clear(); + lru_tracker_.clear(); } void FontCollection::SetCacheCapacity(const size_t cap) { cache_capacity_ = cap; } -// TODO(garyq): Rework this to use font fallback system. +void FontCollection::SetLowMemoryMode(bool mode, size_t cap) { + cache_capacity_ = cap; + if (mode) { + cache_method_ = CacheMethod::kLRU; + TrimCache(); + } else { + cache_method_ = CacheMethod::kUnlimited; + } +} + +void FontCollection::TrimCache() { + while (minikin_font_collection_map_.size() > cache_capacity_) { + std::string family_to_evict = lru_tracker_.back(); + lru_tracker_.pop_back(); + minikin_font_collection_map_.erase(family_to_evict); + } +} + const std::string FontCollection::ProcessFamilyName(const std::string& family) { #ifdef DIRECTORY_FONT_MANAGER_AVAILABLE return family.length() == 0 ? DEFAULT_FAMILY_NAME : family; @@ -178,15 +196,13 @@ FontCollection::GetMinikinFontCollectionForFamily(const std::string& family) { } // Maintain LRU and evict old fonts no longer used. + + lru_tracker_.remove(processed_family_name); + lru_tracker_.push_front(processed_family_name); if (cache_method_ == CacheMethod::kLRU) { - lru_tracker_.remove(processed_family_name); - lru_tracker_.push_front(processed_family_name); - if (lru_tracker_.size() > cache_capacity_) { - std::string family_to_evict = lru_tracker_.back(); - lru_tracker_.pop_back(); - minikin_font_collection_map_.erase(family_to_evict); - } + TrimCache(); } + return minikin_font_collection_map_[processed_family_name]; } diff --git a/engine/src/flutter/src/font_collection.h b/engine/src/flutter/src/font_collection.h index efc1dab732..b5ba03ea92 100644 --- a/engine/src/flutter/src/font_collection.h +++ b/engine/src/flutter/src/font_collection.h @@ -18,6 +18,7 @@ #define LIB_TXT_SRC_FONT_COLLECTION_H_ #define DEFAULT_FAMILY_NAME "Roboto" +#define DEFAULT_CACHE_CAPACITY 20 #include #include @@ -75,13 +76,17 @@ class FontCollection { void SetCacheCapacity(const size_t cap); + // Call this to limit memory usage by cached fonts. SetLowMemoryMode() will + // enable default LRU policy and flush fonts beyond capacity. + void SetLowMemoryMode(bool mode = true, size_t cap = DEFAULT_CACHE_CAPACITY); + private: std::vector> skia_font_managers_; // Cache the names because GetFamilyNames() can be frequently called. std::set family_names_; CacheMethod cache_method_ = CacheMethod::kUnlimited; std::list lru_tracker_; - size_t cache_capacity_ = 20; + size_t cache_capacity_ = DEFAULT_CACHE_CAPACITY; // Cache minikin font collections to prevent slow disk reads. // TODO(garyq): Implement optional low-memory optimized system to prevent @@ -95,6 +100,8 @@ class FontCollection { const std::string ProcessFamilyName(const std::string& family); + void TrimCache(); + static const std::string GetDefaultFamilyName() { return DEFAULT_FAMILY_NAME; }; diff --git a/engine/src/flutter/src/paragraph.cc b/engine/src/flutter/src/paragraph.cc index 848bda5d54..9a575537b0 100644 --- a/engine/src/flutter/src/paragraph.cc +++ b/engine/src/flutter/src/paragraph.cc @@ -252,8 +252,10 @@ void Paragraph::Layout(double width, bool force) { // Check if we should remove trailing whitespace of blobs. size_t trailing_length = 0; - while (minikin::isWordSpace( - text_[character_index + blob_length - trailing_length - 1])) { + while ( + minikin::isWordSpace( + text_[character_index + blob_length - trailing_length - 1]) && + layout_end == next_break) { ++trailing_length; } @@ -307,7 +309,7 @@ void Paragraph::Layout(double width, bool force) { paint.getFontMetrics(&metrics); // Apply additional word spacing if the text is justified. if (paragraph_style_.text_align == TextAlign::justify && - buffer_sizes.size() > 0) { + buffer_sizes.size() > 0 && character_index != text_.size()) { JustifyLine(buffers, buffer_sizes, word_count, character_index); } records_.push_back( diff --git a/engine/src/flutter/tests/txt/paragraph_unittests.cc b/engine/src/flutter/tests/txt/paragraph_unittests.cc index 187ccfa302..0c8b7e5924 100644 --- a/engine/src/flutter/tests/txt/paragraph_unittests.cc +++ b/engine/src/flutter/tests/txt/paragraph_unittests.cc @@ -567,9 +567,7 @@ TEST_F(RenderTest, JustifyAlignParagraph) { "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim " "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea " "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate " - "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint " - "occaecat cupidatat non proident, sunt in culpa qui officia deserunt " - "mollit anim id est laborum."; + "velit esse cillum dolore eu fugiat."; auto icu_text = icu::UnicodeString::fromUTF8(text); std::u16string u16_text(icu_text.getBuffer(), icu_text.getBuffer() + icu_text.length());