diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2022-02-26 18:18:34 +0100 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2022-03-23 09:09:05 +0100 |
commit | d0031d1a8d8148e6a915549bbf9bc2e0b3b90a46 (patch) | |
tree | 1da6c8134fc49619b30a34f62295460609a62977 /sc/inc | |
parent | aa63f06739cef299be1df4641622a29b5f2faf46 (diff) |
do not allocate so many CellInfo objects in FillInfo()
FillInfo() is used for drawing to screen, so it's given a range
of rows and columns, but drawing also depends on all cells
to the left (e.g. their width, for position), so it allocated
CellInfo for all columns starting from 0. But with many columns
this can easily mean allocating and initializing a large amount
of memory, easily 90MiB with a maximized window and going to XFD1,
and handling all that can be slow enough to be seen when moving
around.
Since only few of the CellInfo fields are actually needed for all
columns, split them into a separate smaller BasicCellInfo, and
allocate CellInfo only for columns that need it. And exception
is the nRotMaxCol code (for rotated cells?), which accesses more
of the fields, so for that case allocate the same way as before.
Change-Id: I2f0f2a9c27b1a8b74b70fc2d208d0689e16ee1a2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130607
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'sc/inc')
-rw-r--r-- | sc/inc/fillinfo.hxx | 62 |
1 files changed, 48 insertions, 14 deletions
diff --git a/sc/inc/fillinfo.hxx b/sc/inc/fillinfo.hxx index 0bc72e4e3ed3..d6ab0bd537c6 100644 --- a/sc/inc/fillinfo.hxx +++ b/sc/inc/fillinfo.hxx @@ -96,6 +96,22 @@ struct ScIconSetInfo bool mbShowValue; }; +// FillInfo() computes some info for all cells starting from column 0, +// but most of the info is needed only for cells in the given columns. +// Keeping all the info in CellInfo could lead to allocation and initialization +// of MiB's of memory, so split the info needed for all cells to a smaller structure. +struct BasicCellInfo +{ + BasicCellInfo() + : nWidth(0) + , bEmptyCellText(true) + , bEditEngine(false) // view-internal + {} + sal_uInt16 nWidth; + bool bEmptyCellText : 1; + bool bEditEngine : 1; // output-internal +}; + struct CellInfo { CellInfo() @@ -113,9 +129,7 @@ struct CellInfo , eHShadowPart(SC_SHADOW_HSTART) , eVShadowPart(SC_SHADOW_HSTART) , nClipMark(ScClipMark::NONE) - , nWidth(0) , nRotateDir(ScRotateDir::NONE) - , bEmptyCellText(false) , bMerged(false) , bHOverlapped(false) , bVOverlapped(false) @@ -125,7 +139,6 @@ struct CellInfo , bFilterActive(false) , bPrinted(false) // view-internal , bHideGrid(false) // view-internal - , bEditEngine(false) // view-internal { } @@ -154,10 +167,8 @@ struct CellInfo ScShadowPart eHShadowPart : 4; // shadow effective for drawing ScShadowPart eVShadowPart : 4; ScClipMark nClipMark; - sal_uInt16 nWidth; ScRotateDir nRotateDir; - bool bEmptyCellText : 1; bool bMerged : 1; bool bHOverlapped : 1; bool bVOverlapped : 1; @@ -167,7 +178,6 @@ struct CellInfo bool bFilterActive:1; bool bPrinted : 1; // when required (pagebreak mode) bool bHideGrid : 1; // output-internal - bool bEditEngine : 1; // output-internal }; const SCCOL SC_ROTMAX_NONE = SCCOL_MAX; @@ -180,24 +190,44 @@ struct RowInfo CellInfo& cellInfo(SCCOL nCol) { + assert( nCol >= nStartCol - 1 ); #ifdef DBG_UTIL - assert( nCol >= -1 && nCol <= nCols + 1 ); + assert( nCol <= nEndCol + 1 ); #endif - return pCellInfo[ nCol + 1 ]; + return pCellInfo[ nCol - nStartCol + 1 ]; } const CellInfo& cellInfo(SCCOL nCol) const { return const_cast<RowInfo*>(this)->cellInfo(nCol); } - void allocCellInfo(SCCOL cols) + BasicCellInfo& basicCellInfo(SCCOL nCol) + { + assert( nCol >= -1 ); +#ifdef DBG_UTIL + assert( nCol <= nEndCol + 1 ); +#endif + return pBasicCellInfo[ nCol + 1 ]; + } + const BasicCellInfo& basicCellInfo(SCCOL nCol) const + { + return const_cast<RowInfo*>(this)->basicCellInfo(nCol); + } + + void allocCellInfo(SCCOL startCol, SCCOL endCol) { + nStartCol = startCol; #ifdef DBG_UTIL - nCols = cols; + nEndCol = endCol; #endif - pCellInfo = new CellInfo[ cols + 2 ]; + pCellInfo = new CellInfo[ endCol - nStartCol + 1 + 2 ]; + pBasicCellInfo = new BasicCellInfo[ endCol + 2 ]; + } + void freeCellInfo() + { + delete[] pCellInfo; + delete[] pBasicCellInfo; } - void freeCellInfo() { delete[] pCellInfo; } sal_uInt16 nHeight; SCROW nRowNo; @@ -211,10 +241,14 @@ struct RowInfo private: // This class allocates CellInfo with also one item extra before and after. // To make handling easier, this is private and access functions take care of adjusting - // the array indexes and error-checking. + // the array indexes and error-checking. CellInfo is allocated only for a given + // range of columns plus one on each side, BasicCellInfo is allocated for columns + // starting from column 0 until the last column given, again plus one on each side. CellInfo* pCellInfo; + BasicCellInfo* pBasicCellInfo; + SCCOL nStartCol; #ifdef DBG_UTIL - SCCOL nCols; + SCCOL nEndCol; #endif }; |