From 41ef8b376f4616ba13e13096f7c03a4caa0c695a Mon Sep 17 00:00:00 2001 From: Seigo Nonaka Date: Tue, 13 Dec 2016 16:29:16 +0900 Subject: [PATCH] Reduce memory usage of FontCollection. Since switching to 64-bit devices, size_t is now a 64-bit integer. FontCollection::Range uses two size_t integers but they just point to an index in mFamilies. To reduce the memory usage, this CL changes the size_t integers to uint8_t. The maximum size of each integer in Range is the size of FontCollection::mFamilies. The largest this can go is the system font list plus a user defined family, which has 91 families. So an 8-bit integer should be enough. With this change, about 84 KiB of memory will be saved per font collection. Since eight font collections are created during bootstrap, about 670 KiB of memory will be saved with this CL. Bug: 33562608 Test: Ran FontCollection.collectionAllocationSizeTest on a 64-bit device. On my Nexus 5X, it changed from 327358 to 241342. Change-Id: I9e01d237c9adcb05e200932401cb1a4780049f86 --- engine/src/flutter/include/minikin/FontCollection.h | 10 +++++----- engine/src/flutter/libs/minikin/FontCollection.cpp | 13 +++++++------ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/engine/src/flutter/include/minikin/FontCollection.h b/engine/src/flutter/include/minikin/FontCollection.h index c9c8520be6..f6312dcea5 100644 --- a/engine/src/flutter/include/minikin/FontCollection.h +++ b/engine/src/flutter/include/minikin/FontCollection.h @@ -58,8 +58,8 @@ private: static const int kPageMask = (1 << kLogCharsPerPage) - 1; struct Range { - size_t start; - size_t end; + uint8_t start; + uint8_t end; }; FontFamily* getFamilyForChar(uint32_t ch, uint32_t vs, uint32_t langListId, int variant) const; @@ -87,14 +87,14 @@ private: // This vector can't be empty. std::vector mFamilies; - // This vector contains pointers into mInstances + // This vector contains indices into mFamilies. // This vector can't be empty. - std::vector mFamilyVec; + std::vector mFamilyVec; // This vector has pointers to the font family instance which has cmap 14 subtable. std::vector mVSFamilyVec; - // These are offsets into mInstanceVec, one range per page + // These are offsets into mFamilyVec, one range per page std::vector mRanges; }; diff --git a/engine/src/flutter/libs/minikin/FontCollection.cpp b/engine/src/flutter/libs/minikin/FontCollection.cpp index 365d7752b0..7ad2f48565 100644 --- a/engine/src/flutter/libs/minikin/FontCollection.cpp +++ b/engine/src/flutter/libs/minikin/FontCollection.cpp @@ -111,6 +111,8 @@ FontCollection::FontCollection(const vector& typefaces) : nTypefaces = mFamilies.size(); LOG_ALWAYS_FATAL_IF(nTypefaces == 0, "Font collection must have at least one valid typeface"); + LOG_ALWAYS_FATAL_IF(nTypefaces > 254, + "Up to 254 font families can be registered to collection."); size_t nPages = (mMaxChar + kPageMask) >> kLogCharsPerPage; size_t offset = 0; // TODO: Use variation selector map for mRanges construction. @@ -124,11 +126,11 @@ FontCollection::FontCollection(const vector& typefaces) : #ifdef VERBOSE_DEBUG ALOGD("i=%zd: range start = %zd\n", i, offset); #endif - range->start = offset; + range->start = (uint8_t)offset; for (size_t j = 0; j < nTypefaces; j++) { if (lastChar[j] < (i + 1) << kLogCharsPerPage) { FontFamily* family = mFamilies[j]; - mFamilyVec.push_back(family); + mFamilyVec.push_back((uint8_t)j); offset++; uint32_t nextChar = family->getCoverage()->nextSetBit((i + 1) << kLogCharsPerPage); #ifdef VERBOSE_DEBUG @@ -137,7 +139,7 @@ FontCollection::FontCollection(const vector& typefaces) : lastChar[j] = nextChar; } } - range->end = offset; + range->end = (uint8_t)offset; } } @@ -284,11 +286,10 @@ FontFamily* FontCollection::getFamilyForChar(uint32_t ch, uint32_t vs, return mFamilies[0]; } - const std::vector& familyVec = (vs == 0) ? mFamilyVec : mFamilies; Range range = mRanges[ch >> kLogCharsPerPage]; if (vs != 0) { - range = { 0, mFamilies.size() }; + range = { 0, (uint8_t)mFamilies.size() }; } #ifdef VERBOSE_DEBUG @@ -297,7 +298,7 @@ FontFamily* FontCollection::getFamilyForChar(uint32_t ch, uint32_t vs, FontFamily* bestFamily = nullptr; uint32_t bestScore = kUnsupportedFontScore; for (size_t i = range.start; i < range.end; i++) { - FontFamily* family = familyVec[i]; + FontFamily* family = vs == 0 ? mFamilies[mFamilyVec[i]] : mFamilies[i]; const uint32_t score = calcFamilyScore(ch, vs, variant, langListId, family); if (score == kFirstFontScore) { // If the first font family supports the given character or variation sequence, always