summaryrefslogtreecommitdiff
path: root/vcl/source
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2019-03-11 16:38:32 +0100
committerTomaž Vajngerl <quikee@gmail.com>2019-03-11 21:21:50 +0100
commit805b15ce536e3d6c40d0dc4f98b5aa6ffa5344c0 (patch)
tree425e0cd87f7419ddcdbb64e3abe832836761170d /vcl/source
parent812316f63bc07520c9736af0360c711780fcbf55 (diff)
cache file based widget images and draw commands
It is wasteful to parse svg icons all the time so lets cache the result when this make sense in a LRU map. Change-Id: I95cc317c9301138a9e384d270223ba147a123e59 Reviewed-on: https://gerrit.libreoffice.org/69055 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'vcl/source')
-rw-r--r--vcl/source/app/svmain.cxx3
-rw-r--r--vcl/source/gdi/FileDefinitionWidgetDraw.cxx72
2 files changed, 57 insertions, 18 deletions
diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx
index 7f23e366cc67..6319208896ae 100644
--- a/vcl/source/app/svmain.cxx
+++ b/vcl/source/app/svmain.cxx
@@ -575,6 +575,9 @@ void DeInitVCL()
pSVData->maGDIData.maScaleCache.remove_if([](const o3tl::lru_map<SalBitmap*, BitmapEx>::key_value_pair_t&)
{ return true; });
+ pSVData->maGDIData.maThemeDrawCommandsCache.clear();
+ pSVData->maGDIData.maThemeImageCache.clear();
+
// Deinit Sal
if (pSVData->mpDefInst)
{
diff --git a/vcl/source/gdi/FileDefinitionWidgetDraw.cxx b/vcl/source/gdi/FileDefinitionWidgetDraw.cxx
index e321734e9a6e..3c0ad43c99b7 100644
--- a/vcl/source/gdi/FileDefinitionWidgetDraw.cxx
+++ b/vcl/source/gdi/FileDefinitionWidgetDraw.cxx
@@ -343,9 +343,26 @@ void munchDrawCommands(std::vector<std::shared_ptr<DrawCommand>> const& rDrawCom
nScaleFactor = comphelper::LibreOfficeKit::getDPIScale();
auto const& rDrawCommand = static_cast<ImageDrawCommand const&>(*pDrawCommand);
- SvFileStream aFileStream(rDrawCommand.msSource, StreamMode::READ);
+ auto& rCacheImages = ImplGetSVData()->maGDIData.maThemeImageCache;
+ OUString rCacheKey = rDrawCommand.msSource + "@" + OUString::number(nScaleFactor);
+ auto& aIterator = rCacheImages.find(rCacheKey);
+
BitmapEx aBitmap;
- vcl::bitmap::loadFromSvg(aFileStream, "", aBitmap, nScaleFactor);
+ if (aIterator == rCacheImages.end())
+ {
+ SvFileStream aFileStream(rDrawCommand.msSource, StreamMode::READ);
+
+ vcl::bitmap::loadFromSvg(aFileStream, "", aBitmap, nScaleFactor);
+ if (!!aBitmap)
+ {
+ rCacheImages.insert(std::make_pair(rCacheKey, aBitmap));
+ }
+ }
+ else
+ {
+ aBitmap = aIterator->second;
+ }
+
long nImageWidth = aBitmap.GetSizePixel().Width();
long nImageHeight = aBitmap.GetSizePixel().Height();
SalTwoRect aTR(0, 0, nImageWidth, nImageHeight, nX, nY, nImageWidth / nScaleFactor,
@@ -370,27 +387,46 @@ void munchDrawCommands(std::vector<std::shared_ptr<DrawCommand>> const& rDrawCom
case DrawCommandType::EXTERNAL:
{
auto const& rDrawCommand = static_cast<ImageDrawCommand const&>(*pDrawCommand);
- SvFileStream aFileStream(rDrawCommand.msSource, StreamMode::READ);
- uno::Reference<uno::XComponentContext> xContext(
- comphelper::getProcessComponentContext());
- const uno::Reference<graphic::XSvgParser> xSvgParser
- = graphic::SvgTools::create(xContext);
+ auto& rCacheDrawCommands = ImplGetSVData()->maGDIData.maThemeDrawCommandsCache;
- std::size_t nSize = aFileStream.remainingSize();
- std::vector<sal_Int8> aBuffer(nSize + 1);
- aFileStream.ReadBytes(aBuffer.data(), nSize);
- aBuffer[nSize] = 0;
+ auto& aIterator = rCacheDrawCommands.find(rDrawCommand.msSource);
- uno::Sequence<sal_Int8> aData(aBuffer.data(), nSize + 1);
- uno::Reference<io::XInputStream> aInputStream(
- new comphelper::SequenceInputStream(aData));
+ gfx::DrawRoot aDrawRoot;
- uno::Any aAny = xSvgParser->getDrawCommands(aInputStream, "");
- if (aAny.has<sal_uInt64>())
+ if (aIterator == rCacheDrawCommands.end())
+ {
+ SvFileStream aFileStream(rDrawCommand.msSource, StreamMode::READ);
+
+ uno::Reference<uno::XComponentContext> xContext(
+ comphelper::getProcessComponentContext());
+ const uno::Reference<graphic::XSvgParser> xSvgParser
+ = graphic::SvgTools::create(xContext);
+
+ std::size_t nSize = aFileStream.remainingSize();
+ std::vector<sal_Int8> aBuffer(nSize + 1);
+ aFileStream.ReadBytes(aBuffer.data(), nSize);
+ aBuffer[nSize] = 0;
+
+ uno::Sequence<sal_Int8> aData(aBuffer.data(), nSize + 1);
+ uno::Reference<io::XInputStream> aInputStream(
+ new comphelper::SequenceInputStream(aData));
+
+ uno::Any aAny = xSvgParser->getDrawCommands(aInputStream, "");
+ if (aAny.has<sal_uInt64>())
+ {
+ auto* pDrawRoot = reinterpret_cast<gfx::DrawRoot*>(aAny.get<sal_uInt64>());
+ if (pDrawRoot)
+ {
+ rCacheDrawCommands.insert(
+ std::make_pair(rDrawCommand.msSource, *pDrawRoot));
+ drawFromDrawCommands(*pDrawRoot, rGraphics, nX, nY, nWidth, nHeight);
+ }
+ }
+ }
+ else
{
- auto* pDrawRoot = reinterpret_cast<gfx::DrawRoot*>(aAny.get<sal_uInt64>());
- drawFromDrawCommands(*pDrawRoot, rGraphics, nX, nY, nWidth, nHeight);
+ drawFromDrawCommands(aIterator->second, rGraphics, nX, nY, nWidth, nHeight);
}
}
break;