diff options
-rw-r--r-- | sw/source/core/bastyp/swcache.cxx | 1 | ||||
-rw-r--r-- | sw/source/core/inc/swcache.hxx | 9 | ||||
-rw-r--r-- | sw/source/core/text/txtcache.cxx | 36 | ||||
-rw-r--r-- | sw/source/core/view/viewsh.cxx | 10 |
4 files changed, 44 insertions, 12 deletions
diff --git a/sw/source/core/bastyp/swcache.cxx b/sw/source/core/bastyp/swcache.cxx index ff6d568b8e83..64eb233b6bf7 100644 --- a/sw/source/core/bastyp/swcache.cxx +++ b/sw/source/core/bastyp/swcache.cxx @@ -436,6 +436,7 @@ bool SwCache::Insert( SwCacheObj *pNew ) void SwCache::SetLRUOfst( const sal_uInt16 nOfst ) { + assert(nOfst < m_nCurMax); if ( !m_pRealFirst || ((m_aCacheObjects.size() - m_aFreePositions.size()) < nOfst) ) return; diff --git a/sw/source/core/inc/swcache.hxx b/sw/source/core/inc/swcache.hxx index 9a6563e256ba..00f33514ff39 100644 --- a/sw/source/core/inc/swcache.hxx +++ b/sw/source/core/inc/swcache.hxx @@ -117,15 +117,12 @@ public: sal_uInt16 size() { return m_aCacheObjects.size(); } }; -/// Safely manipulate the cache +/// Try to prevent visible SwParaPortions from being deleted. class SwSaveSetLRUOfst { - SwCache &rCache; public: - SwSaveSetLRUOfst( SwCache &rC, const sal_uInt16 nOfst ) - : rCache( rC ) { rCache.SetLRUOfst( nOfst ); } - - ~SwSaveSetLRUOfst() { rCache.ResetLRUOfst(); } + SwSaveSetLRUOfst(); + ~SwSaveSetLRUOfst(); }; /** diff --git a/sw/source/core/text/txtcache.cxx b/sw/source/core/text/txtcache.cxx index b0f540a2a024..fcc8b434cdd8 100644 --- a/sw/source/core/text/txtcache.cxx +++ b/sw/source/core/text/txtcache.cxx @@ -21,6 +21,9 @@ #include <txtfrm.hxx> #include "porlay.hxx" +#include <sfx2/viewsh.hxx> +#include <view.hxx> + SwTextLine::SwTextLine( SwTextFrame const *pFrame, std::unique_ptr<SwParaPortion> pNew ) : SwCacheObj( static_cast<void const *>(pFrame) ), pLine( std::move(pNew) ) @@ -135,4 +138,37 @@ void SwTextFrame::SetPara( SwParaPortion *pNew, bool bDelete ) } } +/** Prevent the SwParaPortions of the *visible* paragraphs from being deleted; + they would just be recreated on the next paint. + + Heuristic: 100 per view are visible + + If the cache is too small, enlarge it to ensure there are sufficient free + entries for the layout so it doesn't have to throw away a node's + SwParaPortion when it starts formatting the next node. +*/ +SwSaveSetLRUOfst::SwSaveSetLRUOfst() +{ + sal_uInt16 nVisibleShells(0); + for (auto pView = SfxViewShell::GetFirst(true, checkSfxViewShell<SwView>); + pView != nullptr; + pView = SfxViewShell::GetNext(*pView, true, checkSfxViewShell<SwView>)) + { + ++nVisibleShells; + } + + sal_uInt16 const nPreserved(100 * nVisibleShells); + SwCache & rCache(*SwTextFrame::GetTextCache()); + if (rCache.GetCurMax() < nPreserved + 250) + { + rCache.IncreaseMax(nPreserved + 250 - rCache.GetCurMax()); + } + rCache.SetLRUOfst(nPreserved); +} + +SwSaveSetLRUOfst::~SwSaveSetLRUOfst() +{ + SwTextFrame::GetTextCache()->ResetLRUOfst(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx index f8a805dad4a9..ae1bc40512d0 100644 --- a/sw/source/core/view/viewsh.cxx +++ b/sw/source/core/view/viewsh.cxx @@ -712,9 +712,8 @@ void SwViewShell::LayoutIdle() #endif { - //Prepare and recover cache, so that it will not get fouled. - SwSaveSetLRUOfst aSave( *SwTextFrame::GetTextCache(), - SwTextFrame::GetTextCache()->GetCurMax() - 50 ); + // Preserve top of the text frame cache. + SwSaveSetLRUOfst aSaveLRU; // #125243# there are lots of stacktraces indicating that Imp() returns NULL // this SwViewShell seems to be invalid - but it's not clear why // this return is only a workaround! @@ -990,9 +989,8 @@ void SwViewShell::CalcLayout() SET_CURR_SHELL( this ); SwWait aWait( *GetDoc()->GetDocShell(), true ); - //prepare and recover cache, so that it will not get fouled. - SwSaveSetLRUOfst aSaveLRU( *SwTextFrame::GetTextCache(), - SwTextFrame::GetTextCache()->GetCurMax() - 50 ); + // Preserve top of the text frame cache. + SwSaveSetLRUOfst aSaveLRU; //switch on Progress when none is running yet. const bool bEndProgress = SfxProgress::GetActiveProgress( GetDoc()->GetDocShell() ) == nullptr; |