comphelper/source/streaming/seqstream.cxx | 52 ++++++++++++++------------- include/comphelper/seqstream.hxx | 29 ++++++++------- include/vcl/BinaryDataContainer.hxx | 4 ++ svx/source/sdr/contact/viewobjectcontact.cxx | 10 +++-- vcl/source/gdi/vectorgraphicdata.cxx | 6 +-- vcl/source/graphic/BinaryDataContainer.cxx | 20 ++++++++++ 6 files changed, 77 insertions(+), 44 deletions(-)
New commits: commit acae249396c39a6fd98551078d391ca50fe3bc61 Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Wed May 31 13:53:43 2023 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Thu Jun 1 07:58:32 2023 +0200 speed up tab-switching in a calc document with a lot of graphic objects if we are in the destructor, and we have never painted the object in question, then we don't need to do an expensive object-range calculation and invalidation Change-Id: I857c3d927142f4e90d54f79fa6c293731382f0d9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152434 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/svx/source/sdr/contact/viewobjectcontact.cxx b/svx/source/sdr/contact/viewobjectcontact.cxx index 2e2ecfe8f711..f0f5c1499ca2 100644 --- a/svx/source/sdr/contact/viewobjectcontact.cxx +++ b/svx/source/sdr/contact/viewobjectcontact.cxx @@ -166,10 +166,14 @@ ViewObjectContact::ViewObjectContact(ObjectContact& rObjectContact, ViewContact& ViewObjectContact::~ViewObjectContact() { - // invalidate in view - if(!getObjectRange().isEmpty()) + // if the object range is empty, then we have never had the primitive range change, so nothing to invalidate + if (!maObjectRange.isEmpty()) { - GetObjectContact().InvalidatePartOfView(maObjectRange); + // invalidate in view + if(!getObjectRange().isEmpty()) + { + GetObjectContact().InvalidatePartOfView(maObjectRange); + } } // delete PrimitiveAnimation commit a4d24f9a2af7cf5d6cceeedfaaa744d4da62c7a8 Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Thu May 18 11:48:26 2023 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Thu Jun 1 07:58:21 2023 +0200 tdf#63130 reduce large memory copies when reading from BinaryDataContainer rather than writing a bunch more code, extract the common part from comphelper::SequenceInputStream into a new base class Change-Id: I0d3561e3ca2e748b904128e3b5955e27196d7170 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151943 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> (cherry picked from commit 5a4d78d9a9b45c7fa387b66f5e310447ec813034) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151916 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/comphelper/source/streaming/seqstream.cxx b/comphelper/source/streaming/seqstream.cxx index 1f37a7967b04..49eebc1a99c2 100644 --- a/comphelper/source/streaming/seqstream.cxx +++ b/comphelper/source/streaming/seqstream.cxx @@ -36,26 +36,27 @@ using namespace ::osl; -SequenceInputStream::SequenceInputStream( - css::uno::Sequence<sal_Int8> const & rData) -: m_aData(rData) +MemoryInputStream::MemoryInputStream( + const sal_Int8* pData, sal_Int32 nDataLength) +: m_pMemoryData(pData) +, m_nMemoryDataLength(nDataLength) , m_nPos(0) { } // checks if closed, returns available size, not mutex-protected -inline sal_Int32 SequenceInputStream::avail() +inline sal_Int32 MemoryInputStream::avail() { if (m_nPos == -1) throw NotConnectedException(OUString(), *this); - return m_aData.getLength() - m_nPos; + return m_nMemoryDataLength - m_nPos; } // css::io::XInputStream -sal_Int32 SAL_CALL SequenceInputStream::readBytes( Sequence<sal_Int8>& aData, sal_Int32 nBytesToRead ) +sal_Int32 SAL_CALL MemoryInputStream::readBytes( Sequence<sal_Int8>& aData, sal_Int32 nBytesToRead ) { if (nBytesToRead < 0) throw BufferSizeExceededException(OUString(),*this); @@ -68,13 +69,13 @@ sal_Int32 SAL_CALL SequenceInputStream::readBytes( Sequence<sal_Int8>& aData, sa nBytesToRead = nAvail; aData.realloc(nBytesToRead); - memcpy(aData.getArray(), m_aData.getConstArray() + m_nPos, nBytesToRead); + memcpy(aData.getArray(), m_pMemoryData + m_nPos, nBytesToRead); m_nPos += nBytesToRead; return nBytesToRead; } -sal_Int32 SequenceInputStream::readSomeBytes( sal_Int8* pData, sal_Int32 nBytesToRead ) +sal_Int32 MemoryInputStream::readSomeBytes( sal_Int8* pData, sal_Int32 nBytesToRead ) { if (nBytesToRead < 0) throw BufferSizeExceededException(OUString(),*this); @@ -86,27 +87,20 @@ sal_Int32 SequenceInputStream::readSomeBytes( sal_Int8* pData, sal_Int32 nBytesT if (nAvail < nBytesToRead) nBytesToRead = nAvail; - memcpy(pData, m_aData.getConstArray() + m_nPos, nBytesToRead); + memcpy(pData, m_pMemoryData + m_nPos, nBytesToRead); m_nPos += nBytesToRead; return nBytesToRead; } -sal_Int64 SAL_CALL SequenceInputStream::getSomething( const css::uno::Sequence< sal_Int8 >& rIdentifier ) -{ - if (rIdentifier == comphelper::ByteReader::getUnoTunnelId()) - return reinterpret_cast<sal_Int64>(static_cast<comphelper::ByteReader*>(this)); - return 0; -} - -sal_Int32 SAL_CALL SequenceInputStream::readSomeBytes( Sequence<sal_Int8>& aData, sal_Int32 nMaxBytesToRead ) +sal_Int32 SAL_CALL MemoryInputStream::readSomeBytes( Sequence<sal_Int8>& aData, sal_Int32 nMaxBytesToRead ) { // all data is available at once return readBytes(aData, nMaxBytesToRead); } -void SAL_CALL SequenceInputStream::skipBytes( sal_Int32 nBytesToSkip ) +void SAL_CALL MemoryInputStream::skipBytes( sal_Int32 nBytesToSkip ) { if (nBytesToSkip < 0) throw BufferSizeExceededException(OUString(),*this); @@ -122,7 +116,7 @@ void SAL_CALL SequenceInputStream::skipBytes( sal_Int32 nBytesToSkip ) } -sal_Int32 SAL_CALL SequenceInputStream::available( ) +sal_Int32 SAL_CALL MemoryInputStream::available( ) { std::scoped_lock aGuard( m_aMutex ); @@ -130,7 +124,7 @@ sal_Int32 SAL_CALL SequenceInputStream::available( ) } -void SAL_CALL SequenceInputStream::closeInput( ) +void SAL_CALL MemoryInputStream::closeInput( ) { std::scoped_lock aGuard( m_aMutex ); @@ -140,24 +134,32 @@ void SAL_CALL SequenceInputStream::closeInput( ) m_nPos = -1; } -void SAL_CALL SequenceInputStream::seek( sal_Int64 location ) +void SAL_CALL MemoryInputStream::seek( sal_Int64 location ) { - if ( location > m_aData.getLength() || location < 0 || location > SAL_MAX_INT32 ) + if ( location > m_nMemoryDataLength || location < 0 || location > SAL_MAX_INT32 ) throw IllegalArgumentException("bad location", static_cast<cppu::OWeakObject*>(this), 1); std::scoped_lock aGuard( m_aMutex ); m_nPos = static_cast<sal_Int32>(location); } -sal_Int64 SAL_CALL SequenceInputStream::getPosition() +sal_Int64 SAL_CALL MemoryInputStream::getPosition() { std::scoped_lock aGuard( m_aMutex ); return m_nPos; } -sal_Int64 SAL_CALL SequenceInputStream::getLength( ) +sal_Int64 SAL_CALL MemoryInputStream::getLength( ) { std::scoped_lock aGuard( m_aMutex ); - return m_aData.getLength(); + return m_nMemoryDataLength; +} + + +SequenceInputStream::SequenceInputStream( + css::uno::Sequence<sal_Int8> const & rData) +: MemoryInputStream(rData.getConstArray(), rData.getLength()) +, m_aData(rData) +{ } diff --git a/include/comphelper/seqstream.hxx b/include/comphelper/seqstream.hxx index c2ba3913432b..1fd695bddf0d 100644 --- a/include/comphelper/seqstream.hxx +++ b/include/comphelper/seqstream.hxx @@ -33,21 +33,18 @@ namespace comphelper { - -// SequenceInputStream -// stream for reading data from a sequence of bytes - - -class COMPHELPER_DLLPUBLIC SequenceInputStream final - : public ::cppu::WeakImplHelper< css::io::XInputStream, css::io::XSeekable, css::lang::XUnoTunnel >, +/** Base class for wrappers around memory data that want to be exposed as an XInputStream */ +class COMPHELPER_DLLPUBLIC MemoryInputStream + : public ::cppu::WeakImplHelper< css::io::XInputStream, css::io::XSeekable >, public comphelper::ByteReader { std::mutex m_aMutex; - css::uno::Sequence<sal_Int8> const m_aData; + const sal_Int8* m_pMemoryData; + sal_Int32 m_nMemoryDataLength; sal_Int32 m_nPos; public: - SequenceInputStream(css::uno::Sequence<sal_Int8> const & rData); + MemoryInputStream(const sal_Int8* pData, sal_Int32 nDataLength); // css::io::XInputStream virtual sal_Int32 SAL_CALL readBytes( css::uno::Sequence<sal_Int8>& aData, sal_Int32 nBytesToRead ) override; @@ -64,9 +61,6 @@ public: virtual sal_Int64 SAL_CALL getPosition( ) override; virtual sal_Int64 SAL_CALL getLength( ) override; -// css::lang::XUnoTunnel - virtual sal_Int64 SAL_CALL getSomething( const css::uno::Sequence< sal_Int8 >& aIdentifier ) override; - // comphelper::ByteReader virtual sal_Int32 readSomeBytes( sal_Int8* pData, sal_Int32 nBytesToRead ) override; @@ -74,6 +68,17 @@ private: sal_Int32 avail(); }; + +// Stream for reading data from a sequence of bytes +class COMPHELPER_DLLPUBLIC SequenceInputStream final + : public MemoryInputStream +{ + css::uno::Sequence<sal_Int8> const m_aData; + +public: + SequenceInputStream(css::uno::Sequence<sal_Int8> const & rData); +}; + // don't export to avoid duplicate WeakImplHelper definitions with MSVC class SAL_DLLPUBLIC_TEMPLATE OSequenceOutputStream_Base : public ::cppu::WeakImplHelper< css::io::XOutputStream > diff --git a/include/vcl/BinaryDataContainer.hxx b/include/vcl/BinaryDataContainer.hxx index 4011c8685487..45906c65620f 100644 --- a/include/vcl/BinaryDataContainer.hxx +++ b/include/vcl/BinaryDataContainer.hxx @@ -13,6 +13,7 @@ #include <sal/config.h> #include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/io/XInputStream.hpp> #include <unotools/tempfile.hxx> #include <tools/stream.hxx> #include <vcl/dllapi.h> @@ -53,6 +54,9 @@ public: // Returns the data as a readonly stream open for reading std::shared_ptr<SvStream> getAsStream(); + // Returns the data as a readonly stream open for reading + css::uno::Reference<css::io::XInputStream> getAsXInputStream(); + /// writes the contents to the given stream std::size_t writeToStream(SvStream& rStream) const; diff --git a/vcl/source/gdi/vectorgraphicdata.cxx b/vcl/source/gdi/vectorgraphicdata.cxx index 1abc1ce097d2..7dc51073adeb 100644 --- a/vcl/source/gdi/vectorgraphicdata.cxx +++ b/vcl/source/gdi/vectorgraphicdata.cxx @@ -196,8 +196,7 @@ void VectorGraphicData::ensureSequenceAndRange() { case VectorGraphicDataType::Svg: { - css::uno::Sequence<sal_Int8> aDataSequence = maDataContainer.getAsSequence(); - const uno::Reference<io::XInputStream> xInputStream(new comphelper::SequenceInputStream(aDataSequence)); + const uno::Reference<io::XInputStream> xInputStream = maDataContainer.getAsXInputStream(); const uno::Reference< graphic::XSvgParser > xSvgParser = graphic::SvgTools::create(xContext); @@ -211,8 +210,7 @@ void VectorGraphicData::ensureSequenceAndRange() { const uno::Reference< graphic::XEmfParser > xEmfParser = graphic::EmfTools::create(xContext); - css::uno::Sequence<sal_Int8> aDataSequence = maDataContainer.getAsSequence(); - const uno::Reference<io::XInputStream> xInputStream(new comphelper::SequenceInputStream(aDataSequence)); + const uno::Reference<io::XInputStream> xInputStream = maDataContainer.getAsXInputStream(); if (xInputStream.is()) { diff --git a/vcl/source/graphic/BinaryDataContainer.cxx b/vcl/source/graphic/BinaryDataContainer.cxx index cfbd4560a8d5..43538f9b12fd 100644 --- a/vcl/source/graphic/BinaryDataContainer.cxx +++ b/vcl/source/graphic/BinaryDataContainer.cxx @@ -12,6 +12,7 @@ #include <o3tl/hash_combine.hxx> #include <unotools/tempfile.hxx> #include <comphelper/lok.hxx> +#include <comphelper/seqstream.hxx> #include <sal/log.hxx> struct BinaryDataContainer::Impl @@ -114,12 +115,31 @@ public: } }; +class ReferencedXInputStream : public comphelper::MemoryInputStream +{ + std::shared_ptr<std::vector<sal_uInt8>> mpData; + +public: + ReferencedXInputStream(const std::shared_ptr<std::vector<sal_uInt8>>& pData) + : comphelper::MemoryInputStream(reinterpret_cast<const sal_Int8*>(pData->data()), + pData->size()) + , mpData(pData) + { + } +}; + std::shared_ptr<SvStream> BinaryDataContainer::getAsStream() { ensureSwappedIn(); // TODO: transfer in streamed chunks return std::make_shared<ReferencedMemoryStream>(mpImpl->mpData); } +css::uno::Reference<css::io::XInputStream> BinaryDataContainer::getAsXInputStream() +{ + ensureSwappedIn(); // TODO: transfer in streamed chunks + return new ReferencedXInputStream(mpImpl->mpData); +} + std::size_t BinaryDataContainer::writeToStream(SvStream& rStream) const { ensureSwappedIn(); // TODO: transfer in streamed chunks