vcl/inc/SwapFile.hxx           |   39 +------------------
 vcl/inc/impgraph.hxx           |    2 -
 vcl/qa/cppunit/GraphicTest.cxx |   82 ++++++++++++++---------------------------
 vcl/source/gdi/impgraph.cxx    |   68 ++++++++++++----------------------
 4 files changed, 57 insertions(+), 134 deletions(-)

New commits:
commit 9645e4003c1787a32aa13a261fb94accf6770138
Author:     Noel Grandin <noelgran...@gmail.com>
AuthorDate: Wed Dec 28 18:48:42 2022 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Thu Dec 29 10:27:11 2022 +0000

    use TempFileFast for vcl graphics swapout
    
    which is considerably faster on Windows when there is lots of
    system RAM available.
    
    Change-Id: I6ebde79af06f4e969231089783f1d4109f70ea94
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144851
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/vcl/inc/SwapFile.hxx b/vcl/inc/SwapFile.hxx
index 64060fd306a9..7ca34fb60698 100644
--- a/vcl/inc/SwapFile.hxx
+++ b/vcl/inc/SwapFile.hxx
@@ -22,8 +22,7 @@
 #include <vcl/dllapi.h>
 #include <tools/urlobj.hxx>
 #include <tools/stream.hxx>
-#include <unotools/ucbhelper.hxx>
-#include <unotools/ucbstreamhelper.hxx>
+#include <unotools/tempfile.hxx>
 #include <utility>
 
 namespace vcl
@@ -31,42 +30,10 @@ namespace vcl
 class VCL_DLLPUBLIC SwapFile
 {
 private:
-    INetURLObject maSwapURL;
+    utl::TempFileFast maTempFile;
 
 public:
-    SwapFile(INetURLObject aSwapURL)
-        : maSwapURL(std::move(aSwapURL))
-    {
-    }
-
-    ~SwapFile() COVERITY_NOEXCEPT_FALSE
-    {
-        
utl::UCBContentHelper::Kill(maSwapURL.GetMainURL(INetURLObject::DecodeMechanism::NONE));
-    }
-
-    const INetURLObject& getSwapURL() const { return maSwapURL; }
-
-    OUString getSwapURLString() const
-    {
-        return maSwapURL.GetMainURL(INetURLObject::DecodeMechanism::NONE);
-    }
-
-    std::unique_ptr<SvStream> openOutputStream()
-    {
-        OUString sSwapURL = getSwapURLString();
-        if (!sSwapURL.isEmpty())
-        {
-            try
-            {
-                return utl::UcbStreamHelper::CreateStream(
-                    sSwapURL, StreamMode::READWRITE | 
StreamMode::SHARE_DENYWRITE);
-            }
-            catch (const css::uno::Exception&)
-            {
-            }
-        }
-        return std::unique_ptr<SvStream>();
-    }
+    SvStream* getStream() { return 
maTempFile.GetStream(StreamMode::READWRITE); }
 };
 }
 
diff --git a/vcl/inc/impgraph.hxx b/vcl/inc/impgraph.hxx
index 6007dcc63ed1..b62cc8e623ec 100644
--- a/vcl/inc/impgraph.hxx
+++ b/vcl/inc/impgraph.hxx
@@ -216,7 +216,7 @@ public:
     bool swapIn();
     bool swapOut();
     bool isSwappedOut() const { return mbSwapOut; }
-    OUString getSwapFileURL() const;
+    SvStream* getSwapFileStream() const;
     // public only because of use in GraphicFilter
     void updateFromLoadedGraphic(const ImpGraphic* graphic);
 };
diff --git a/vcl/qa/cppunit/GraphicTest.cxx b/vcl/qa/cppunit/GraphicTest.cxx
index 90164c7e317c..2dff15f29d34 100644
--- a/vcl/qa/cppunit/GraphicTest.cxx
+++ b/vcl/qa/cppunit/GraphicTest.cxx
@@ -191,26 +191,10 @@ std::string toHexString(const std::vector<unsigned char>& 
a)
     return aStrm.str();
 }
 
-std::unique_ptr<SvStream> createStream(OUString const& rSwapFileURL)
-{
-    std::unique_ptr<SvStream> xStream;
-
-    try
-    {
-        xStream = ::utl::UcbStreamHelper::CreateStream(
-            rSwapFileURL, StreamMode::READWRITE | StreamMode::SHARE_DENYWRITE);
-    }
-    catch (const css::uno::Exception&)
-    {
-    }
-
-    return xStream;
-}
-
-std::vector<unsigned char> calculateHash(std::unique_ptr<SvStream>& rStream)
+std::vector<unsigned char> calculateHash(SvStream* pStream)
 {
     comphelper::Hash aHashEngine(comphelper::HashType::SHA1);
-    const sal_uInt32 nSize(rStream->remainingSize());
+    const sal_uInt32 nSize(pStream->remainingSize());
     std::vector<sal_uInt8> aData(nSize);
     aHashEngine.update(aData.data(), nSize);
     return aHashEngine.finalize();
@@ -576,7 +560,7 @@ void GraphicTest::testSwappingGraphic_PNG_WithGfxLink()
     sal_uLong rByteSize = aGraphic.GetSizeBytes();
 
     // Check the swap file (shouldn't exist)
-    CPPUNIT_ASSERT_EQUAL(true, 
aGraphic.ImplGetImpGraphic()->getSwapFileURL().isEmpty());
+    CPPUNIT_ASSERT_EQUAL(true, 
aGraphic.ImplGetImpGraphic()->getSwapFileStream() == nullptr);
 
     // Swapping out
     CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->swapOut());
@@ -587,7 +571,7 @@ void GraphicTest::testSwappingGraphic_PNG_WithGfxLink()
     CPPUNIT_ASSERT_EQUAL(rByteSize, aGraphic.GetSizeBytes());
 
     // Check the swap file (still shouldn't exist)
-    CPPUNIT_ASSERT_EQUAL(true, 
aGraphic.ImplGetImpGraphic()->getSwapFileURL().isEmpty());
+    CPPUNIT_ASSERT_EQUAL(true, 
aGraphic.ImplGetImpGraphic()->getSwapFileStream() == nullptr);
 
     // Let's swap in
     CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
@@ -627,8 +611,7 @@ void GraphicTest::testSwappingGraphic_PNG_WithoutGfxLink()
 
     // Get the declared byte size of the graphic
     sal_uLong rByteSize = aGraphic.GetSizeBytes();
-    OUString rSwapFileURL = aGraphic.ImplGetImpGraphic()->getSwapFileURL();
-    CPPUNIT_ASSERT_EQUAL(true, rSwapFileURL.isEmpty());
+    CPPUNIT_ASSERT_EQUAL(true, 
aGraphic.ImplGetImpGraphic()->getSwapFileStream() == nullptr);
 
     // Swapping out
     CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->swapOut());
@@ -639,17 +622,15 @@ void GraphicTest::testSwappingGraphic_PNG_WithoutGfxLink()
     CPPUNIT_ASSERT_EQUAL(rByteSize, aGraphic.GetSizeBytes());
 
     // Let's check the swap file
-    rSwapFileURL = aGraphic.ImplGetImpGraphic()->getSwapFileURL();
-    CPPUNIT_ASSERT_EQUAL(true, 
comphelper::DirectoryHelper::fileExists(rSwapFileURL));
 
     { // Check the swap file content
-        std::unique_ptr<SvStream> xStream = createStream(rSwapFileURL);
-        CPPUNIT_ASSERT_EQUAL(true, bool(xStream));
+        SvStream* pStream = aGraphic.ImplGetImpGraphic()->getSwapFileStream();
+        pStream->Seek(0);
 
         // Check size of the stream
-        CPPUNIT_ASSERT_EQUAL(sal_uInt64(36079), xStream->remainingSize());
+        CPPUNIT_ASSERT_EQUAL(sal_uInt64(36079), pStream->remainingSize());
 
-        std::vector<unsigned char> aHash = calculateHash(xStream);
+        std::vector<unsigned char> aHash = calculateHash(pStream);
         
CPPUNIT_ASSERT_EQUAL(std::string("9347511e3b80dfdfaadf91a3bdef55a8ae85552b"),
                              toHexString(aHash));
     }
@@ -665,7 +646,7 @@ void GraphicTest::testSwappingGraphic_PNG_WithoutGfxLink()
     CPPUNIT_ASSERT_EQUAL(aChecksumBeforeSwapping, aGraphic.GetChecksum());
 
     // File shouldn't be available anymore
-    CPPUNIT_ASSERT_EQUAL(false, 
comphelper::DirectoryHelper::fileExists(rSwapFileURL));
+    CPPUNIT_ASSERT_EQUAL(true, 
aGraphic.ImplGetImpGraphic()->getSwapFileStream() == nullptr);
 
     // Check the bitmap
     CPPUNIT_ASSERT_EQUAL(tools::Long(120), aGraphic.GetSizePixel().Width());
@@ -808,7 +789,7 @@ void 
GraphicTest::testSwappingVectorGraphic_SVG_WithGfxLink()
     CPPUNIT_ASSERT_EQUAL(sal_uLong(223), rByteSize);
 
     // Make sure we don't have a file
-    CPPUNIT_ASSERT_EQUAL(true, 
aGraphic.ImplGetImpGraphic()->getSwapFileURL().isEmpty());
+    CPPUNIT_ASSERT_EQUAL(true, 
aGraphic.ImplGetImpGraphic()->getSwapFileStream() == nullptr);
 
     // SWAP OUT the Graphic and make sure it's not available currently
     CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->swapOut());
@@ -816,7 +797,7 @@ void 
GraphicTest::testSwappingVectorGraphic_SVG_WithGfxLink()
     CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
 
     // We use GfxLink so no swap file in this case
-    CPPUNIT_ASSERT_EQUAL(true, 
aGraphic.ImplGetImpGraphic()->getSwapFileURL().isEmpty());
+    CPPUNIT_ASSERT_EQUAL(true, 
aGraphic.ImplGetImpGraphic()->getSwapFileStream() == nullptr);
 
     // Byte size doesn't change when we swapped out
     CPPUNIT_ASSERT_EQUAL(rByteSize, aGraphic.GetSizeBytes());
@@ -865,8 +846,7 @@ void 
GraphicTest::testSwappingVectorGraphic_SVG_WithoutGfxLink()
     sal_uLong rByteSize = aGraphic.GetSizeBytes();
     CPPUNIT_ASSERT_EQUAL(sal_uLong(223), rByteSize);
 
-    OUString rSwapFileURL = aGraphic.ImplGetImpGraphic()->getSwapFileURL();
-    CPPUNIT_ASSERT_EQUAL(true, rSwapFileURL.isEmpty());
+    CPPUNIT_ASSERT_EQUAL(true, 
aGraphic.ImplGetImpGraphic()->getSwapFileStream() == nullptr);
 
     // Swapping out
     CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->swapOut());
@@ -878,19 +858,15 @@ void 
GraphicTest::testSwappingVectorGraphic_SVG_WithoutGfxLink()
     CPPUNIT_ASSERT_EQUAL(rByteSize, aGraphic.GetSizeBytes());
 
     // Let's check the swap file
-    rSwapFileURL = aGraphic.ImplGetImpGraphic()->getSwapFileURL();
-    CPPUNIT_ASSERT_EQUAL(false, rSwapFileURL.isEmpty());
-    CPPUNIT_ASSERT_EQUAL(true, 
comphelper::DirectoryHelper::fileExists(rSwapFileURL));
-
     {
         // Check the swap file content
-        std::unique_ptr<SvStream> xStream = createStream(rSwapFileURL);
-        CPPUNIT_ASSERT_EQUAL(true, bool(xStream));
+        SvStream* pStream = aGraphic.ImplGetImpGraphic()->getSwapFileStream();
+        pStream->Seek(0);
 
         // Check size of the stream
-        CPPUNIT_ASSERT_EQUAL(sal_uInt64(247), xStream->remainingSize());
+        CPPUNIT_ASSERT_EQUAL(sal_uInt64(247), pStream->remainingSize());
 
-        std::vector<unsigned char> aHash = calculateHash(xStream);
+        std::vector<unsigned char> aHash = calculateHash(pStream);
         
CPPUNIT_ASSERT_EQUAL(std::string("666820973fd95e6cd9e7bc5f1c53732acbc99326"),
                              toHexString(aHash));
     }
@@ -914,7 +890,8 @@ void 
GraphicTest::testSwappingVectorGraphic_SVG_WithoutGfxLink()
     CPPUNIT_ASSERT_EQUAL(aBitmapChecksumBeforeSwapping, 
aGraphic.GetBitmapEx().GetChecksum());
 
     // File shouldn't be available anymore
-    CPPUNIT_ASSERT_EQUAL(false, 
comphelper::DirectoryHelper::fileExists(rSwapFileURL));
+    CPPUNIT_ASSERT_EQUAL(static_cast<SvStream*>(nullptr),
+                         aGraphic.ImplGetImpGraphic()->getSwapFileStream());
 }
 
 void GraphicTest::testSwappingGraphicProperties_SVG_WithGfxLink()
@@ -1161,7 +1138,7 @@ void 
GraphicTest::testSwappingAnimationGraphic_GIF_WithGfxLink()
     CPPUNIT_ASSERT_EQUAL(sal_uLong(89552), rByteSize);
 
     // Make sure we don't have a file
-    CPPUNIT_ASSERT_EQUAL(true, 
aGraphic.ImplGetImpGraphic()->getSwapFileURL().isEmpty());
+    CPPUNIT_ASSERT_EQUAL(true, 
aGraphic.ImplGetImpGraphic()->getSwapFileStream() == nullptr);
 
     // SWAP OUT the Graphic and make sure it's not available currently
     CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->swapOut());
@@ -1169,7 +1146,7 @@ void 
GraphicTest::testSwappingAnimationGraphic_GIF_WithGfxLink()
     CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
 
     // We use GfxLink so no swap file in this case
-    CPPUNIT_ASSERT_EQUAL(true, 
aGraphic.ImplGetImpGraphic()->getSwapFileURL().isEmpty());
+    CPPUNIT_ASSERT_EQUAL(true, 
aGraphic.ImplGetImpGraphic()->getSwapFileStream() == nullptr);
 
     // Byte size doesn't change when we swapped out
     CPPUNIT_ASSERT_EQUAL(rByteSize, aGraphic.GetSizeBytes());
@@ -1212,8 +1189,7 @@ void 
GraphicTest::testSwappingAnimationGraphic_GIF_WithoutGfxLink()
 
     // Get the declared byte size of the graphic
     sal_uLong rByteSize = aGraphic.GetSizeBytes();
-    OUString rSwapFileURL = aGraphic.ImplGetImpGraphic()->getSwapFileURL();
-    CPPUNIT_ASSERT_EQUAL(true, rSwapFileURL.isEmpty());
+    CPPUNIT_ASSERT_EQUAL(true, 
aGraphic.ImplGetImpGraphic()->getSwapFileStream() == nullptr);
 
     // SWAP OUT
     CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
@@ -1225,18 +1201,15 @@ void 
GraphicTest::testSwappingAnimationGraphic_GIF_WithoutGfxLink()
     CPPUNIT_ASSERT_EQUAL(rByteSize, aGraphic.GetSizeBytes());
 
     // Let's check the swap file
-    rSwapFileURL = aGraphic.ImplGetImpGraphic()->getSwapFileURL();
-    CPPUNIT_ASSERT_EQUAL(true, 
comphelper::DirectoryHelper::fileExists(rSwapFileURL));
-
     {
         // Check the swap file content
-        std::unique_ptr<SvStream> xStream = createStream(rSwapFileURL);
-        CPPUNIT_ASSERT_EQUAL(true, bool(xStream));
+        SvStream* pStream = aGraphic.ImplGetImpGraphic()->getSwapFileStream();
+        pStream->Seek(0);
 
         // Check size of the stream
-        CPPUNIT_ASSERT_EQUAL(sal_uInt64(15139), xStream->remainingSize());
+        CPPUNIT_ASSERT_EQUAL(sal_uInt64(15139), pStream->remainingSize());
 
-        std::vector<unsigned char> aHash = calculateHash(xStream);
+        std::vector<unsigned char> aHash = calculateHash(pStream);
         
CPPUNIT_ASSERT_EQUAL(std::string("ecae5354edd9cf98553eb3153e44181f56d35338"),
                              toHexString(aHash));
     }
@@ -1248,7 +1221,8 @@ void 
GraphicTest::testSwappingAnimationGraphic_GIF_WithoutGfxLink()
     CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut());
 
     // File shouldn't be available anymore
-    CPPUNIT_ASSERT_EQUAL(false, 
comphelper::DirectoryHelper::fileExists(rSwapFileURL));
+    CPPUNIT_ASSERT_EQUAL(static_cast<SvStream*>(nullptr),
+                         aGraphic.ImplGetImpGraphic()->getSwapFileStream());
 
     // Check the bitmap
     CPPUNIT_ASSERT_EQUAL(tools::Long(124), aGraphic.GetSizePixel().Width());
diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx
index ca63d8645063..65f8fb25a827 100644
--- a/vcl/source/gdi/impgraph.cxx
+++ b/vcl/source/gdi/impgraph.cxx
@@ -65,20 +65,19 @@ private:
     OUString maOriginURL;
 
 public:
-    ImpSwapFile(INetURLObject const & rSwapURL, OUString aOriginURL)
-        : SwapFile(rSwapURL)
-        , maOriginURL(std::move(aOriginURL))
+    ImpSwapFile(OUString aOriginURL)
+        : maOriginURL(std::move(aOriginURL))
     {
     }
 
     OUString const & getOriginURL() const { return maOriginURL; }
 };
 
-OUString ImpGraphic::getSwapFileURL() const
+SvStream* ImpGraphic::getSwapFileStream() const
 {
     if (mpSwapFile)
-        return 
mpSwapFile->getSwapURL().GetMainURL(INetURLObject::DecodeMechanism::NONE);
-    return OUString();
+        return mpSwapFile->getStream();
+    return nullptr;
 }
 
 ImpGraphic::ImpGraphic() :
@@ -1320,28 +1319,25 @@ bool ImpGraphic::swapOut()
     }
     else
     {
-        // Create a temp filename for the swap file
-        const INetURLObject aTempFileURL(utl::CreateTempURL());
-
         // Create a swap file
-        auto pSwapFile = o3tl::make_shared<ImpSwapFile>(aTempFileURL, 
getOriginURL());
+        auto pSwapFile = o3tl::make_shared<ImpSwapFile>(getOriginURL());
 
         // Open a stream to write the swap file to
         {
-            std::unique_ptr<SvStream> xOutputStream = 
pSwapFile->openOutputStream();
+            SvStream* pOutputStream = pSwapFile->getStream();
 
-            if (!xOutputStream)
+            if (!pOutputStream)
                 return false;
 
             // Write to stream
-            xOutputStream->SetVersion(SOFFICE_FILEFORMAT_50);
-            xOutputStream->SetCompressMode(SvStreamCompressFlags::NATIVE);
-            xOutputStream->SetBufferSize(GRAPHIC_STREAMBUFSIZE);
+            pOutputStream->SetVersion(SOFFICE_FILEFORMAT_50);
+            pOutputStream->SetCompressMode(SvStreamCompressFlags::NATIVE);
+            pOutputStream->SetBufferSize(GRAPHIC_STREAMBUFSIZE);
 
-            if (!xOutputStream->GetError() && swapOutContent(*xOutputStream))
+            if (!pOutputStream->GetError() && swapOutContent(*pOutputStream))
             {
-                xOutputStream->FlushBuffer();
-                bResult = !xOutputStream->GetError();
+                pOutputStream->FlushBuffer();
+                bResult = !pOutputStream->GetError();
             }
         }
 
@@ -1511,39 +1507,25 @@ bool ImpGraphic::swapIn()
     }
     else
     {
-        OUString aSwapURL;
+        SvStream* pStream = nullptr;
 
         if (mpSwapFile)
-            aSwapURL = 
mpSwapFile->getSwapURL().GetMainURL(INetURLObject::DecodeMechanism::NONE);
+            pStream = mpSwapFile->getStream();
 
-        if (!aSwapURL.isEmpty())
+        if (pStream)
         {
-            std::unique_ptr<SvStream> xStream;
-            try
-            {
-                xStream = ::utl::UcbStreamHelper::CreateStream(aSwapURL, 
StreamMode::READWRITE | StreamMode::SHARE_DENYWRITE);
-            }
-            catch( const css::uno::Exception& )
-            {
-            }
+            pStream->SetVersion(SOFFICE_FILEFORMAT_50);
+            pStream->SetCompressMode(SvStreamCompressFlags::NATIVE);
+            pStream->SetBufferSize(GRAPHIC_STREAMBUFSIZE);
+            pStream->Seek(STREAM_SEEK_TO_BEGIN);
 
-            if (xStream)
-            {
-                xStream->SetVersion(SOFFICE_FILEFORMAT_50);
-                xStream->SetCompressMode(SvStreamCompressFlags::NATIVE);
-                xStream->SetBufferSize(GRAPHIC_STREAMBUFSIZE);
-
-                bReturn = swapInFromStream(*xStream);
-
-                xStream.reset();
+            bReturn = swapInFromStream(*pStream);
 
-                restoreFromSwapInfo();
+            restoreFromSwapInfo();
 
-                if (mpSwapFile)
-                    setOriginURL(mpSwapFile->getOriginURL());
+            setOriginURL(mpSwapFile->getOriginURL());
 
-                mpSwapFile.reset();
-            }
+            mpSwapFile.reset();
         }
     }
 

Reply via email to