summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2022-05-01 19:14:50 +0200
committerLuboš Luňák <l.lunak@collabora.com>2022-05-02 15:06:26 +0200
commit8e6ab6502278702499e7468404d1010069176578 (patch)
tree678b55b91894c5b57728f84ba3da9794fd7f8b43
parentbc7ea0a75911a782c0008be64508cbf3e0d74cc3 (diff)
better cache size limit for SalLayoutGlyphsCache
With just limit on the number of cached SalLayoutGlyphs instances the actual memory used could vary wildly depending on how long the text is. Change-Id: Ibcf6918e562e81276d21876c532838996e275bd6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133673 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
-rw-r--r--include/vcl/glyphitemcache.hxx8
-rw-r--r--officecfg/registry/schema/org/openoffice/Office/Common.xcs14
-rw-r--r--vcl/source/gdi/impglyphitem.cxx19
3 files changed, 39 insertions, 2 deletions
diff --git a/include/vcl/glyphitemcache.hxx b/include/vcl/glyphitemcache.hxx
index a7a49ca7a8f2..998dcf97f915 100644
--- a/include/vcl/glyphitemcache.hxx
+++ b/include/vcl/glyphitemcache.hxx
@@ -85,7 +85,13 @@ private:
{
size_t operator()(const CachedGlyphsKey& key) const { return key.hashValue; }
};
- typedef o3tl::lru_map<CachedGlyphsKey, SalLayoutGlyphs, CachedGlyphsHash> GlyphsCache;
+ struct GlyphsCost
+ {
+ size_t operator()(const SalLayoutGlyphs&) const;
+ };
+ typedef o3tl::lru_map<CachedGlyphsKey, SalLayoutGlyphs, CachedGlyphsHash,
+ std::equal_to<CachedGlyphsKey>, GlyphsCost>
+ GlyphsCache;
GlyphsCache mCachedGlyphs;
// Last temporary glyphs returned (pointer is returned, so the object needs to be kept somewhere).
std::optional<CachedGlyphsKey> mLastTemporaryKey;
diff --git a/officecfg/registry/schema/org/openoffice/Office/Common.xcs b/officecfg/registry/schema/org/openoffice/Office/Common.xcs
index f839f5778316..67fa3478b8fe 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Common.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Common.xcs
@@ -1591,6 +1591,20 @@
<value>64000000</value>
</prop>
</group>
+ <group oor:name="Font">
+ <info>
+ <desc>Specifies the cache related options for fonts.</desc>
+ </info>
+ <prop oor:name="GlyphsCacheSize" oor:type="xs:long" oor:nillable="false">
+ <info>
+ <desc>Specifies the maximum cache size in bytes for all glyphs used
+ when laying out text. Larger size may improve text drawing performance
+ in large documents.</desc>
+ <label>Glyphs Cache Size</label>
+ </info>
+ <value>20000000</value>
+ </prop>
+ </group>
</group>
<group oor:name="Path">
<!-- UIHints: Tools - Options - General - Paths -->
diff --git a/vcl/source/gdi/impglyphitem.cxx b/vcl/source/gdi/impglyphitem.cxx
index 0ae4e979e141..769c1afb9743 100644
--- a/vcl/source/gdi/impglyphitem.cxx
+++ b/vcl/source/gdi/impglyphitem.cxx
@@ -24,6 +24,7 @@
#include <tools/stream.hxx>
#include <TextLayoutCache.hxx>
#include <config_fuzzers.h>
+#include <officecfg/Office/Common.hxx>
// These need being explicit because of SalLayoutGlyphsImpl being private in vcl.
SalLayoutGlyphs::SalLayoutGlyphs() {}
@@ -208,7 +209,8 @@ bool SalLayoutGlyphsImpl::IsValid() const
SalLayoutGlyphsCache* SalLayoutGlyphsCache::self()
{
- static vcl::DeleteOnDeinit<SalLayoutGlyphsCache> cache(1000);
+ static vcl::DeleteOnDeinit<SalLayoutGlyphsCache> cache(
+ officecfg::Office::Common::Cache::Font::GlyphsCacheSize::get());
return cache.get();
}
@@ -419,4 +421,19 @@ inline bool SalLayoutGlyphsCache::CachedGlyphsKey::operator==(const CachedGlyphs
// Slower things last in the comparison.
}
+size_t SalLayoutGlyphsCache::GlyphsCost::operator()(const SalLayoutGlyphs& glyphs) const
+{
+ size_t cost = 0;
+ for (int level = 0;; ++level)
+ {
+ const SalLayoutGlyphsImpl* impl = glyphs.Impl(level);
+ if (impl == nullptr)
+ break;
+ // Count size in bytes, both the SalLayoutGlyphsImpl instance and contained GlyphItem's.
+ cost += sizeof(*impl);
+ cost += impl->size() * sizeof(impl->front());
+ }
+ return cost;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */