summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoel Grandin <noelgrandin@gmail.com>2022-12-28 18:48:42 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2022-12-29 10:27:11 +0000
commit9645e4003c1787a32aa13a261fb94accf6770138 (patch)
tree91b6457eadb22c81b964b21b77eea4ddde43cc33
parent6522d0f44a92f8102f50f94e26c6d7140fd7fd44 (diff)
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.grandin@collabora.co.uk>
-rw-r--r--vcl/inc/SwapFile.hxx39
-rw-r--r--vcl/inc/impgraph.hxx2
-rw-r--r--vcl/qa/cppunit/GraphicTest.cxx82
-rw-r--r--vcl/source/gdi/impgraph.cxx68
4 files changed, 57 insertions, 134 deletions
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();
}
}