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

Reply via email to