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(); } }