diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2022-03-14 15:55:00 +0100 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2022-03-15 14:35:54 +0100 |
commit | b2f0da51e36ae65d304881967605700ecee59575 (patch) | |
tree | d0bab1befdfc83b174d8d0318fe5e400eb04152b | |
parent | 3cc41346f5529026d7d38f2863ae3d84948e6ab7 (diff) |
make CreateTextLayoutCache() cached (tdf#116400)
The result depends only on the string, so it's possible to cache it
easily, and caching this for text drawing calls can have a good
hit rate.
Change-Id: I56c6e254cc176ab07afe0df24ed37b19579fe64d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/131556
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
-rw-r--r-- | include/vcl/outdev.hxx | 2 | ||||
-rw-r--r-- | sw/source/core/text/inftxt.hxx | 8 | ||||
-rw-r--r-- | sw/source/core/text/porfld.cxx | 2 | ||||
-rw-r--r-- | sw/source/core/text/pormulti.cxx | 2 | ||||
-rw-r--r-- | vcl/inc/sallayout.hxx | 2 | ||||
-rw-r--r-- | vcl/source/gdi/CommonSalLayout.cxx | 31 | ||||
-rw-r--r-- | vcl/source/outdev/text.cxx | 2 |
7 files changed, 38 insertions, 11 deletions
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx index fe1d9583e2ba..e1f85ad16fc7 100644 --- a/include/vcl/outdev.hxx +++ b/include/vcl/outdev.hxx @@ -1075,7 +1075,7 @@ public: sal_Int32 nIndex, sal_Int32 nLen, tools::Long nCharExtra, vcl::text::TextLayoutCache const* = nullptr) const; - static std::shared_ptr<vcl::text::TextLayoutCache> CreateTextLayoutCache(OUString const&); + static std::shared_ptr<const vcl::text::TextLayoutCache> CreateTextLayoutCache(OUString const&); protected: SAL_DLLPRIVATE void ImplInitTextLineSize(); diff --git a/sw/source/core/text/inftxt.hxx b/sw/source/core/text/inftxt.hxx index 9ee658364355..7c7bf57afa56 100644 --- a/sw/source/core/text/inftxt.hxx +++ b/sw/source/core/text/inftxt.hxx @@ -145,7 +145,7 @@ protected: // performance hack - this is only used by SwTextFormatInfo but // because it's not even possible to dynamic_cast these things // currently it has to be stored here - std::shared_ptr<vcl::text::TextLayoutCache> m_pCachedVclData; + std::shared_ptr<const vcl::text::TextLayoutCache> m_pCachedVclData; SwFont *m_pFnt; SwUnderlineFont *m_pUnderFnt; // Font for underlining @@ -325,11 +325,11 @@ public: { return ( m_pKanaComp && m_nKanaIdx < m_pKanaComp->size() ) ? (*m_pKanaComp)[m_nKanaIdx] : 0; } - const std::shared_ptr<vcl::text::TextLayoutCache>& GetCachedVclData() const + const std::shared_ptr<const vcl::text::TextLayoutCache>& GetCachedVclData() const { return m_pCachedVclData; } - void SetCachedVclData(std::shared_ptr<vcl::text::TextLayoutCache> const& pCachedVclData) + void SetCachedVclData(std::shared_ptr<const vcl::text::TextLayoutCache> const& pCachedVclData) { m_pCachedVclData = pCachedVclData; } @@ -673,7 +673,7 @@ public: class SwTextSlot final { OUString aText; - std::shared_ptr<vcl::text::TextLayoutCache> m_pOldCachedVclData; + std::shared_ptr<const vcl::text::TextLayoutCache> m_pOldCachedVclData; const OUString *pOldText; sw::WrongListIterator * m_pOldSmartTagList; sw::WrongListIterator * m_pOldGrammarCheckList; diff --git a/sw/source/core/text/porfld.cxx b/sw/source/core/text/porfld.cxx index 47a55150ab3f..8c586530eff8 100644 --- a/sw/source/core/text/porfld.cxx +++ b/sw/source/core/text/porfld.cxx @@ -137,7 +137,7 @@ namespace { */ class SwFieldSlot { - std::shared_ptr<vcl::text::TextLayoutCache> m_pOldCachedVclData; + std::shared_ptr<const vcl::text::TextLayoutCache> m_pOldCachedVclData; const OUString *pOldText; OUString aText; TextFrameIndex nIdx; diff --git a/sw/source/core/text/pormulti.cxx b/sw/source/core/text/pormulti.cxx index 2e4831065537..d47b281ac9a9 100644 --- a/sw/source/core/text/pormulti.cxx +++ b/sw/source/core/text/pormulti.cxx @@ -2000,7 +2000,7 @@ bool SwTextFormatter::BuildMultiPortion( SwTextFormatInfo &rInf, // save some values const OUString* pOldText = &(rInf.GetText()); const SwTwips nOldPaintOfst = rInf.GetPaintOfst(); - std::shared_ptr<vcl::text::TextLayoutCache> const pOldCachedVclData(rInf.GetCachedVclData()); + std::shared_ptr<const vcl::text::TextLayoutCache> const pOldCachedVclData(rInf.GetCachedVclData()); rInf.SetCachedVclData(nullptr); OUString const aMultiStr( rInf.GetText().copy(0, sal_Int32(nMultiLen + rInf.GetIdx())) ); diff --git a/vcl/inc/sallayout.hxx b/vcl/inc/sallayout.hxx index 847c22ace091..75110158dc53 100644 --- a/vcl/inc/sallayout.hxx +++ b/vcl/inc/sallayout.hxx @@ -113,7 +113,7 @@ public: void AdjustLayout(vcl::text::ImplLayoutArgs&) final override; bool LayoutText(vcl::text::ImplLayoutArgs&, const SalLayoutGlyphsImpl*) final override; void DrawText(SalGraphics&) const final override; - static std::shared_ptr<vcl::text::TextLayoutCache> CreateTextLayoutCache(OUString const&); + static std::shared_ptr<const vcl::text::TextLayoutCache> CreateTextLayoutCache(OUString const&); SalLayoutGlyphs GetGlyphs() const final override; bool IsKashidaPosValid(int nCharPos) const final override; diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index 811849309d67..e26dc68692bf 100644 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -21,8 +21,11 @@ #include <sal/log.hxx> #include <unotools/configmgr.hxx> +#include <o3tl/hash_combine.hxx> +#include <o3tl/lru_map.hxx> #include <o3tl/temporary.hxx> +#include <vcl/lazydelete.hxx> #include <vcl/unohelp.hxx> #include <vcl/font/Feature.hxx> #include <vcl/font/FeatureParser.hxx> @@ -151,11 +154,35 @@ namespace { return VerticalOrientation(nRet); } +struct FirstCharsStringHash +{ + size_t operator()( const OUString& str ) const + { + // Strings passed to GenericSalLayout::CreateTextLayoutCache() may be very long, + // and computing an entire hash could almost negate the gain of hashing. Hash just first + // characters, that should be good enough. + size_t hash = rtl_ustr_hashCode_WithLength( str.getStr(), std::min<size_t>( 100, str.getLength())); + o3tl::hash_combine(hash, str.getLength()); + return hash; + } +}; + } // namespace -std::shared_ptr<vcl::text::TextLayoutCache> GenericSalLayout::CreateTextLayoutCache(OUString const& rString) +std::shared_ptr<const vcl::text::TextLayoutCache> GenericSalLayout::CreateTextLayoutCache(OUString const& rString) { - return std::make_shared<vcl::text::TextLayoutCache>(rString.getStr(), rString.getLength()); + typedef o3tl::lru_map<OUString, std::shared_ptr<const vcl::text::TextLayoutCache>, FirstCharsStringHash> Cache; + static vcl::DeleteOnDeinit< Cache > cache( 1000 ); + if( Cache* map = cache.get()) + { + auto it = map->find(rString); + if( it != map->end()) + return it->second; + auto ret = std::make_shared<const vcl::text::TextLayoutCache>(rString.getStr(), rString.getLength()); + map->insert( { rString, ret } ); + return ret; + } + return std::make_shared<const vcl::text::TextLayoutCache>(rString.getStr(), rString.getLength()); } SalLayoutGlyphs GenericSalLayout::GetGlyphs() const diff --git a/vcl/source/outdev/text.cxx b/vcl/source/outdev/text.cxx index e9c9ff59d414..8ac3cc379073 100644 --- a/vcl/source/outdev/text.cxx +++ b/vcl/source/outdev/text.cxx @@ -1456,7 +1456,7 @@ std::unique_ptr<SalLayout> OutputDevice::ImplLayout(const OUString& rOrigStr, return pSalLayout; } -std::shared_ptr<vcl::text::TextLayoutCache> OutputDevice::CreateTextLayoutCache( +std::shared_ptr<const vcl::text::TextLayoutCache> OutputDevice::CreateTextLayoutCache( OUString const& rString) { return GenericSalLayout::CreateTextLayoutCache(rString); |