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 <vmik...@collabora.com> AuthorDate: Tue Apr 14 09:07:33 2020 +0200 Commit: Miklos Vajna <vmik...@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@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@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@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@entry=0x1f8de40, rPersistName=...) at svtools/source/misc/embedhlp.cxx:369 #7 0x00007ffff239f736 in SdrOle2Obj::Connect_Impl() (this=this@entry=0x20734f0) at svx/source/svdraw/svdoole2.cxx:984 #8 0x00007ffff23a6310 in SdrOle2Obj::Init() (this=this@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 <vmik...@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); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits