[Libreoffice-commits] core.git: vcl/inc vcl/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Tue Apr 14 07:43:24 UTC 2020


 vcl/inc/impgraph.hxx        |    5 ++++
 vcl/source/gdi/impgraph.cxx |   47 +++++++++++++++++++++++++++++++-------------
 2 files changed, 39 insertions(+), 13 deletions(-)

New commits:
commit 952cc68929f863784c6b01c9dc071494892877d1
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Tue Apr 14 09:07:33 2020 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Tue Apr 14 09:42:52 2020 +0200

    tdf#131496 vcl image lazy load: speed up vector images with custom pref size
    
    This speeds up the loading of the bugdoc:
    
    - old cost: 6378 ms
    - new cost: 1891 ms (30% of baseline)
    
    Images were initially loaded at import time, but commit
    acb803b730f2c6bd82e39beab58949ec14f85eb0 (tdf#125591 DOC import:
    lazy-load metafiles with explicit size, 2019-06-11) changed this, so
    that they are lazy-loaded. That improved performance, but sometimes gave
    incorrect results.
    
    Then commit d8371cdfd092c6426c01aae130ea4eaa6d627a6f (tdf#127446 vcl
    image lazy-load: fix custom size handling of metafiles, 2019-09-30)
    fixed the correctness problem, but the loading was no longer lazy in the
    tdf#131496 case.
    
    This is an attempt to bring back lazy-loading for vector-based images,
    while maintaining the correct preferred size.
    
    The problem was that the PPT import triggered a vector -> bitmap
    conversion during load:
    
            #0  0x00007ffff03c7e36 in ImpGraphic::loadPrepared() (this=this at entry=0x1f88a90) at vcl/source/gdi/impgraph.cxx:1424
            #1  0x00007ffff03c72c7 in ImpGraphic::ImplSwapIn() (this=0x1f88a90) at vcl/source/gdi/impgraph.cxx:1444
            #2  0x00007ffff03c7535 in ImpGraphic::ensureAvailable() const (this=this at entry=0x1f88a90) at vcl/source/gdi/impgraph.cxx:1402
            #3  0x00007ffff03c9481 in ImpGraphic::ImplExportNative(SvStream&) const (this=0x1f88a90, rOStm=...) at vcl/source/gdi/impgraph.cxx:1590
            #4  0x00007ffff03bf9a8 in Graphic::ExportNative(SvStream&) const (this=this at entry=0x20534e0, rOStream=...) at vcl/source/gdi/graph.cxx:544
            #5  0x00007ffff1c79a28 in svt::EmbeddedObjectRef::SetGraphicToContainer(Graphic const&, comphelper::EmbeddedObjectContainer&, rtl::OUString const&, rtl::OUString const&)
                (rGraphic=..., aContainer=..., aName="Object 1", aMediaType="") at svtools/source/misc/embedhlp.cxx:773
            #6  0x00007ffff1c79b6f in svt::EmbeddedObjectRef::AssignToContainer(comphelper::EmbeddedObjectContainer*, rtl::OUString const&)
                (this=0x207ae90, pContainer=pContainer at entry=0x1f8de40, rPersistName=...) at svtools/source/misc/embedhlp.cxx:369
            #7  0x00007ffff239f736 in SdrOle2Obj::Connect_Impl() (this=this at entry=0x20734f0) at svx/source/svdraw/svdoole2.cxx:984
            #8  0x00007ffff23a6310 in SdrOle2Obj::Init() (this=this at entry=0x20734f0) at svx/source/svdraw/svdoole2.cxx:695
    
    Try to defer that conversion by not doing a
    maVectorGraphicData->getReplacement() in ImpGraphic::ImplSetPrefSize(),
    rather just store the preferred size and apply it later when
    getReplacement() is called.
    
    This helps, because the above OLE-from-PPT case loads the graphic, but
    only to export it as SVM, so it doesn't need a vector -> bitmap
    conversion otherwise.
    
    Change-Id: I24790c0a3e298d5fbb3faff35d529e79cc72845a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/92144
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins

diff --git a/vcl/inc/impgraph.hxx b/vcl/inc/impgraph.hxx
index eaf691c10f1b..8fa1df9b82fc 100644
--- a/vcl/inc/impgraph.hxx
+++ b/vcl/inc/impgraph.hxx
@@ -56,6 +56,8 @@ private:
 
     GDIMetaFile                  maMetaFile;
     BitmapEx                     maEx;
+    /// If maEx is empty, this preferred size will be set on it when it gets initialized.
+    Size                         maExPrefSize;
     ImpSwapInfo                  maSwapInfo;
     std::unique_ptr<Animation>   mpAnimation;
     std::shared_ptr<GraphicReader> mpContext;
@@ -195,6 +197,9 @@ private:
 
     const std::shared_ptr<VectorGraphicData>& getVectorGraphicData() const;
 
+    /// Gets the bitmap replacement for a vector graphic.
+    BitmapEx getVectorGraphicReplacement() const;
+
     bool ensureAvailable () const;
 
     bool loadPrepared();
diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx
index 292c0bc6d1f9..6ea0685e4943 100644
--- a/vcl/source/gdi/impgraph.cxx
+++ b/vcl/source/gdi/impgraph.cxx
@@ -490,6 +490,18 @@ bool ImpGraphic::makeAvailable()
     return ensureAvailable();
 }
 
+BitmapEx ImpGraphic::getVectorGraphicReplacement() const
+{
+    BitmapEx aRet = maVectorGraphicData->getReplacement();
+
+    if (maExPrefSize.getWidth() && maExPrefSize.getHeight())
+    {
+        aRet.SetPrefSize(maExPrefSize);
+    }
+
+    return aRet;
+}
+
 Bitmap ImpGraphic::ImplGetBitmap(const GraphicConversionParameters& rParameters) const
 {
     Bitmap aRetBmp;
@@ -501,7 +513,7 @@ Bitmap ImpGraphic::ImplGetBitmap(const GraphicConversionParameters& rParameters)
         if(maVectorGraphicData.get() && maEx.IsEmpty())
         {
             // use maEx as local buffer for rendered svg
-            const_cast< ImpGraphic* >(this)->maEx = maVectorGraphicData->getReplacement();
+            const_cast< ImpGraphic* >(this)->maEx = getVectorGraphicReplacement();
         }
 
         const BitmapEx& rRetBmpEx = ( mpAnimation ? mpAnimation->GetBitmapEx() : maEx );
@@ -610,7 +622,7 @@ BitmapEx ImpGraphic::ImplGetBitmapEx(const GraphicConversionParameters& rParamet
         if(maVectorGraphicData.get() && maEx.IsEmpty())
         {
             // use maEx as local buffer for rendered svg
-            const_cast< ImpGraphic* >(this)->maEx = maVectorGraphicData->getReplacement();
+            const_cast< ImpGraphic* >(this)->maEx = getVectorGraphicReplacement();
         }
 
         aRetBmpEx = ( mpAnimation ? mpAnimation->GetBitmapEx() : maEx );
@@ -697,7 +709,7 @@ const GDIMetaFile& ImpGraphic::ImplGetGDIMetaFile() const
         if(maVectorGraphicData.get() && !maEx)
         {
             // use maEx as local buffer for rendered svg
-            pThat->maEx = maVectorGraphicData->getReplacement();
+            pThat->maEx = getVectorGraphicReplacement();
         }
 
         // #123983# directly create a metafile with the same PrefSize and PrefMapMode
@@ -752,10 +764,17 @@ Size ImpGraphic::ImplGetPrefSize() const
             {
                 if(maVectorGraphicData.get() && maEx.IsEmpty())
                 {
-                    // svg not yet buffered in maEx, return size derived from range
-                    const basegfx::B2DRange& rRange = maVectorGraphicData->getRange();
+                    if (!maExPrefSize.getWidth() || !maExPrefSize.getHeight())
+                    {
+                        // svg not yet buffered in maEx, return size derived from range
+                        const basegfx::B2DRange& rRange = maVectorGraphicData->getRange();
 
-                    aSize = Size(basegfx::fround(rRange.getWidth()), basegfx::fround(rRange.getHeight()));
+                        aSize = Size(basegfx::fround(rRange.getWidth()), basegfx::fround(rRange.getHeight()));
+                    }
+                    else
+                    {
+                        aSize = maExPrefSize;
+                    }
                 }
                 else
                 {
@@ -797,8 +816,7 @@ void ImpGraphic::ImplSetPrefSize( const Size& rPrefSize )
             // to allow setting the PrefSize at the BitmapEx to hold it
             if(maVectorGraphicData.get() && maEx.IsEmpty())
             {
-                // use maEx as local buffer for rendered svg
-                maEx = maVectorGraphicData->getReplacement();
+                maExPrefSize = rPrefSize;
             }
 
             // #108077# Push through pref size to animation object,
@@ -808,7 +826,10 @@ void ImpGraphic::ImplSetPrefSize( const Size& rPrefSize )
                 const_cast< BitmapEx& >(mpAnimation->GetBitmapEx()).SetPrefSize( rPrefSize );
             }
 
-            maEx.SetPrefSize( rPrefSize );
+            if (!maExPrefSize.getWidth() || !maExPrefSize.getHeight())
+            {
+                maEx.SetPrefSize( rPrefSize );
+            }
         }
         break;
 
@@ -881,7 +902,7 @@ void ImpGraphic::ImplSetPrefMapMode( const MapMode& rPrefMapMode )
             if(maVectorGraphicData.get())
             {
                 // ignore for Vector Graphic Data. If this is really used (except the grfcache)
-                // it can be extended by using maEx as buffer for maVectorGraphicData->getReplacement()
+                // it can be extended by using maEx as buffer for getVectorGraphicReplacement()
             }
             else
             {
@@ -953,7 +974,7 @@ void ImpGraphic::ImplDraw( OutputDevice* pOutDev, const Point& rDestPt ) const
                 if(maVectorGraphicData.get() && !maEx)
                 {
                     // use maEx as local buffer for rendered svg
-                    const_cast< ImpGraphic* >(this)->maEx = maVectorGraphicData->getReplacement();
+                    const_cast< ImpGraphic* >(this)->maEx = getVectorGraphicReplacement();
                 }
 
                 if ( mpAnimation )
@@ -990,7 +1011,7 @@ void ImpGraphic::ImplDraw( OutputDevice* pOutDev,
                 if(maVectorGraphicData.get() && maEx.IsEmpty())
                 {
                     // use maEx as local buffer for rendered svg
-                    const_cast< ImpGraphic* >(this)->maEx = maVectorGraphicData->getReplacement();
+                    const_cast< ImpGraphic* >(this)->maEx = getVectorGraphicReplacement();
                 }
 
                 if( mpAnimation )
@@ -1138,7 +1159,7 @@ bool ImpGraphic::ImplReadEmbedded( SvStream& rIStm )
             if(maVectorGraphicData.get() && maEx.IsEmpty())
             {
                 // use maEx as local buffer for rendered svg
-                maEx = maVectorGraphicData->getReplacement();
+                maEx = getVectorGraphicReplacement();
             }
 
             maEx.SetSizePixel(aSize);


More information about the Libreoffice-commits mailing list