summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMichael Stahl <Michael.Stahl@cib.de>2019-04-29 17:21:18 +0200
committerMichael Stahl <Michael.Stahl@cib.de>2019-04-30 15:28:03 +0200
commit3d37463eec0c891243a8971a34903b2da01c9e24 (patch)
treee1ebc0ab33b80543975ed167a34562719cc878ec /sw
parent31ae7509003b1e650463ee1468c0b315ba13efe6 (diff)
tdf#122607 sw: fix preservation of text frame cache entries
SwSaveSetLRUOfst would leave only 50 cache entries available for the CalcLayout() to use; apparently it's not enough for this document. The difference between the 1st loading/layout and the 3rd loading/layout of the document is that in many paragraphs the cache entry is missing, because the entires of the previous loads were clogging up the cache and were preserved here, and the cache only has 50 available entries; if enough entries are available, everything is positioned properly. The idea with the 100 entries per visible shell actually comes from the CVS initial import, where there was a comment suggesting that; but the corresponding parameter was actually unused and removed in 7c704c78d3c652504c064b4ac7af55a2c1ee49bb. Ideally we'd have time to investigate why a missing cache entry causes the wrong position... Change-Id: I64a72a94361dbf5717bbc709fa3bc9abbe18a37c Reviewed-on: https://gerrit.libreoffice.org/71542 Tested-by: Jenkins Reviewed-by: Michael Stahl <Michael.Stahl@cib.de>
Diffstat (limited to 'sw')
-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;