summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/source/core/bastyp/swcache.cxx1
-rw-r--r--sw/source/core/inc/swcache.hxx9
-rw-r--r--sw/source/core/text/txtcache.cxx36
-rw-r--r--sw/source/core/view/viewsh.cxx10
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;