[Libreoffice-commits] core.git: vcl/inc vcl/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Mon Mar 11 20:22:13 UTC 2019


 vcl/inc/svdata.hxx                          |    4 +
 vcl/source/app/svmain.cxx                   |    3 +
 vcl/source/gdi/FileDefinitionWidgetDraw.cxx |   72 +++++++++++++++++++++-------
 3 files changed, 61 insertions(+), 18 deletions(-)

New commits:
commit 805b15ce536e3d6c40d0dc4f98b5aa6ffa5344c0
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Mon Mar 11 16:38:32 2019 +0100
Commit:     Tomaž Vajngerl <quikee at gmail.com>
CommitDate: Mon Mar 11 21:21:50 2019 +0100

    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 at gmail.com>

diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx
index cb666e718943..c5b3482642a2 100644
--- a/vcl/inc/svdata.hxx
+++ b/vcl/inc/svdata.hxx
@@ -42,6 +42,7 @@
 #include <boost/functional/hash.hpp>
 #include "ControlCacheKey.hxx"
 #include "schedulerimpl.hxx"
+#include <basegfx/DrawCommands.hxx>
 
 struct ImplPostEventData;
 struct ImplTimerData;
@@ -199,6 +200,9 @@ struct ImplSVGDIData
     long                    mnAppFontX = 0;                 // AppFont X-Numenator for 40/tel Width
     long                    mnAppFontY = 0;                 // AppFont Y-Numenator for 80/tel Height
     bool                    mbFontSubChanged = false;       // true: FontSubstitution was changed between Begin/End
+
+    o3tl::lru_map<OUString, BitmapEx> maThemeImageCache = o3tl::lru_map<OUString, BitmapEx>(10);
+    o3tl::lru_map<OUString, gfx::DrawRoot> maThemeDrawCommandsCache = o3tl::lru_map<OUString, gfx::DrawRoot>(50);
 };
 
 struct ImplSVWinData
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;


More information about the Libreoffice-commits mailing list