vcl/inc/impgraph.hxx | 34 ++++++++++++ vcl/source/gdi/impgraph.cxx | 117 +++++++++++++++++++++++--------------------- 2 files changed, 95 insertions(+), 56 deletions(-)
New commits: commit 2d7af5bf61d8582feb57102a492e024c2218f411 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Thu Jan 23 18:52:16 2025 +0900 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Mon Feb 24 12:56:41 2025 +0100 vcl: AnimationContainer to handle Animation with memory managing This adds the continer for Animation objects (AnimationContainer) which will handle memory management and swapping for Animations. Change-Id: I9f48169f3d513913d1922fe0d365a0c586931284 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180621 Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> Tested-by: Jenkins diff --git a/vcl/inc/impgraph.hxx b/vcl/inc/impgraph.hxx index 77e89f5b02ac..75a5e00f8a4f 100644 --- a/vcl/inc/impgraph.hxx +++ b/vcl/inc/impgraph.hxx @@ -100,6 +100,38 @@ public: return maBitmapEx.GetPrefMapMode(); return {}; } + + sal_uInt64 getSizeBytes() + { + return maBitmapEx.GetSizeBytes(); + } +}; + +class SAL_DLLPUBLIC_RTTI AnimationContainer final +{ +public: + Animation maAnimation; + + AnimationContainer() = default; + + AnimationContainer(Animation const& rAnimation) + : maAnimation(rAnimation) + {} + + bool operator==(const AnimationContainer& rOther) const + { + return maAnimation == rOther.maAnimation; + } + + bool isTransparent() const + { + return maAnimation.IsTransparent(); + } + + sal_uInt64 getSizeBytes() + { + return maAnimation.GetSizeBytes(); + } }; class SAL_DLLPUBLIC_RTTI ImpGraphic final : public vcl::graphic::MemoryManaged @@ -115,7 +147,7 @@ private: /// If maBitmapEx 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<AnimationContainer> mpAnimationContainer; std::shared_ptr<ImpSwapFile> mpSwapFile; std::shared_ptr<GfxLink> mpGfxLink; std::shared_ptr<VectorGraphicData> maVectorGraphicData; diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx index db073a515180..c48c29b7d802 100644 --- a/vcl/source/gdi/impgraph.cxx +++ b/vcl/source/gdi/impgraph.cxx @@ -106,10 +106,10 @@ ImpGraphic::ImpGraphic(const ImpGraphic& rImpGraphic) updateCurrentSizeInBytes(mnSizeBytes); // Special case for animations - if (rImpGraphic.mpAnimation) + if (rImpGraphic.mpAnimationContainer) { - mpAnimation = std::make_unique<Animation>(*rImpGraphic.mpAnimation); - maCachedBitmap = mpAnimation->GetBitmapEx(); + mpAnimationContainer = std::make_shared<AnimationContainer>(rImpGraphic.mpAnimationContainer->maAnimation); + maCachedBitmap = mpAnimationContainer->maAnimation.GetBitmapEx(); } } @@ -119,7 +119,7 @@ ImpGraphic::ImpGraphic(ImpGraphic&& rImpGraphic) noexcept , maMetaFile(std::move(rImpGraphic.maMetaFile)) , mpBitmapContainer(std::move(rImpGraphic.mpBitmapContainer)) , maSwapInfo(std::move(rImpGraphic.maSwapInfo)) - , mpAnimation(std::move(rImpGraphic.mpAnimation)) + , mpAnimationContainer(std::move(rImpGraphic.mpAnimationContainer)) , mpSwapFile(std::move(rImpGraphic.mpSwapFile)) , mpGfxLink(std::move(rImpGraphic.mpGfxLink)) , maVectorGraphicData(std::move(rImpGraphic.maVectorGraphicData)) @@ -179,7 +179,7 @@ ImpGraphic::ImpGraphic(const std::shared_ptr<VectorGraphicData>& rVectorGraphicD ImpGraphic::ImpGraphic(const Animation& rAnimation) : MemoryManaged(true) , maCachedBitmap(rAnimation.GetBitmapEx()) - , mpAnimation(std::make_unique<Animation>(rAnimation)) + , mpAnimationContainer(std::make_shared<AnimationContainer>(rAnimation)) , meType(GraphicType::Bitmap) { ensureCurrentSizeInBytes(); @@ -210,18 +210,18 @@ ImpGraphic& ImpGraphic::operator=(const ImpGraphic& rImpGraphic) mbDummyContext = rImpGraphic.mbDummyContext; maGraphicExternalLink = rImpGraphic.maGraphicExternalLink; - mpAnimation.reset(); - - if (rImpGraphic.mpAnimation) + mpAnimationContainer.reset(); + if (rImpGraphic.mpAnimationContainer) { - mpAnimation = std::make_unique<Animation>(*rImpGraphic.mpAnimation); - maCachedBitmap = mpAnimation->GetBitmapEx(); + mpAnimationContainer = std::make_shared<AnimationContainer>(*rImpGraphic.mpAnimationContainer); + maCachedBitmap = mpAnimationContainer->maAnimation.GetBitmapEx(); } else { maCachedBitmap = rImpGraphic.maCachedBitmap; } + mpBitmapContainer.reset(); if (rImpGraphic.mpBitmapContainer) mpBitmapContainer = rImpGraphic.mpBitmapContainer; @@ -231,7 +231,10 @@ ImpGraphic& ImpGraphic::operator=(const ImpGraphic& rImpGraphic) mpGfxLink = rImpGraphic.mpGfxLink; - maVectorGraphicData = rImpGraphic.maVectorGraphicData; + maVectorGraphicData.reset(); + if (rImpGraphic.maVectorGraphicData) + maVectorGraphicData = rImpGraphic.maVectorGraphicData; + resetLastUsed(); changeExisting(mnSizeBytes); @@ -248,7 +251,7 @@ ImpGraphic& ImpGraphic::operator=(ImpGraphic&& rImpGraphic) maSwapInfo = std::move(rImpGraphic.maSwapInfo); mbDummyContext = rImpGraphic.mbDummyContext; maCachedBitmap = std::move(rImpGraphic.maCachedBitmap); - mpAnimation = std::move(rImpGraphic.mpAnimation); + mpAnimationContainer = std::move(rImpGraphic.mpAnimationContainer); mpBitmapContainer = std::move(rImpGraphic.mpBitmapContainer); mbSwapOut = rImpGraphic.mbSwapOut; mpSwapFile = std::move(rImpGraphic.mpSwapFile); @@ -301,12 +304,11 @@ bool ImpGraphic::operator==( const ImpGraphic& rOther ) const // equal content bRet = (*maVectorGraphicData) == (*rOther.maVectorGraphicData); } - else if (mpAnimation && rOther.mpAnimation && *rOther.mpAnimation == *mpAnimation) + else if (mpAnimationContainer && rOther.mpAnimationContainer && (*mpAnimationContainer == *rOther.mpAnimationContainer)) { bRet = true; } - else if (mpBitmapContainer && rOther.mpBitmapContainer - && mpBitmapContainer->maBitmapEx == rOther.mpBitmapContainer->maBitmapEx) + else if (mpBitmapContainer && rOther.mpBitmapContainer && (*mpBitmapContainer == *rOther.mpBitmapContainer)) { bRet = true; } @@ -368,7 +370,7 @@ void ImpGraphic::clearGraphics() maCachedBitmap.Clear(); mpBitmapContainer.reset(); maMetaFile.Clear(); - mpAnimation.reset(); + mpAnimationContainer.reset(); maVectorGraphicData.reset(); } @@ -460,8 +462,8 @@ bool ImpGraphic::isTransparent() const return true; else if (mpBitmapContainer) return mpBitmapContainer->isAlpha(); - else if (mpAnimation) - return mpAnimation->IsTransparent(); + else if (mpAnimationContainer) + return mpAnimationContainer->isTransparent(); } return true; @@ -484,7 +486,7 @@ bool ImpGraphic::isAlpha() const bool ImpGraphic::isAnimated() const { - return mbSwapOut ? maSwapInfo.mbIsAnimated : mpAnimation != nullptr; + return mbSwapOut ? maSwapInfo.mbIsAnimated : mpAnimationContainer != nullptr; } bool ImpGraphic::isEPS() const @@ -534,10 +536,12 @@ Bitmap ImpGraphic::getBitmap(const GraphicConversionParameters& rParameters) con if (meType == GraphicType::Bitmap) { - if (!mpAnimation && maVectorGraphicData) + if (!mpAnimationContainer && maVectorGraphicData) updateBitmapFromVectorGraphic(rParameters.getSizePixel()); - const BitmapEx& rRetBmpEx = mpAnimation ? mpAnimation->GetBitmapEx() : (mpBitmapContainer ? mpBitmapContainer->maBitmapEx : maCachedBitmap); + const BitmapEx& rRetBmpEx = mpAnimationContainer + ? mpAnimationContainer->maAnimation.GetBitmapEx() + : (mpBitmapContainer ? mpBitmapContainer->maBitmapEx : maCachedBitmap); aRetBmp = rRetBmpEx.GetBitmap(COL_WHITE); @@ -636,7 +640,9 @@ BitmapEx ImpGraphic::getBitmapEx(const GraphicConversionParameters& rParameters) if (maVectorGraphicData) updateBitmapFromVectorGraphic(rParameters.getSizePixel()); - aBitmapEx = mpAnimation ? mpAnimation->GetBitmapEx() : (mpBitmapContainer ? mpBitmapContainer->maBitmapEx : maCachedBitmap); + aBitmapEx = mpAnimationContainer + ? mpAnimationContainer->maAnimation.GetBitmapEx() + : (mpBitmapContainer ? mpBitmapContainer->maBitmapEx : maCachedBitmap); if (rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height()) aBitmapEx.Scale(rParameters.getSizePixel(), BmpScaleFlag::Fast); @@ -662,8 +668,9 @@ Animation ImpGraphic::getAnimation() const Animation aAnimation; ensureAvailable(); - if( mpAnimation ) - aAnimation = *mpAnimation; + + if (mpAnimationContainer) + aAnimation = mpAnimationContainer->maAnimation; return aAnimation; } @@ -797,7 +804,7 @@ Size ImpGraphic::getPrefSize() const aSize = maExPrefSize; } } - else if (mpAnimation || maVectorGraphicData) + else if (mpAnimationContainer || maVectorGraphicData) { aSize = maCachedBitmap.GetPrefSize(); @@ -841,9 +848,9 @@ void ImpGraphic::setValuesForPrefSize(const Size& rPrefSize) } // #108077# Push through pref size to animation object, // will be lost on copy otherwise - else if (mpAnimation) + else if (mpAnimationContainer) { - const_cast<BitmapEx&>(mpAnimation->GetBitmapEx()).SetPrefSize(rPrefSize); + const_cast<BitmapEx&>(mpAnimationContainer->maAnimation.GetBitmapEx()).SetPrefSize(rPrefSize); maCachedBitmap.SetPrefSize(rPrefSize); } else if (mpBitmapContainer) @@ -933,9 +940,9 @@ void ImpGraphic::setValuesForPrefMapMod(const MapMode& rPrefMapMode) // #108077# Push through pref mapmode to animation object, // will be lost on copy otherwise - else if (mpAnimation) + else if (mpAnimationContainer) { - const_cast<BitmapEx&>(mpAnimation->GetBitmapEx()).SetPrefMapMode(rPrefMapMode); + const_cast<BitmapEx&>(mpAnimationContainer->maAnimation.GetBitmapEx()).SetPrefMapMode(rPrefMapMode); maCachedBitmap.SetPrefMapMode(rPrefMapMode); } else if (mpBitmapContainer) @@ -994,10 +1001,10 @@ sal_uLong ImpGraphic::getSizeBytes() const } else { - if (mpAnimation) - mnSizeBytes = mpAnimation->GetSizeBytes(); + if (mpAnimationContainer) + mnSizeBytes = mpAnimationContainer->getSizeBytes(); else if (mpBitmapContainer) - mnSizeBytes = mpBitmapContainer->maBitmapEx.GetSizeBytes(); + mnSizeBytes = mpBitmapContainer->getSizeBytes(); } } break; @@ -1028,9 +1035,9 @@ void ImpGraphic::draw(OutputDevice& rOutDev, { case GraphicType::Bitmap: { - if (mpAnimation) + if (mpAnimationContainer) { - mpAnimation->Draw(rOutDev, rDestPt, rDestSize); + mpAnimationContainer->maAnimation.Draw(rOutDev, rDestPt, rDestSize); } else { @@ -1062,24 +1069,24 @@ void ImpGraphic::startAnimation(OutputDevice& rOutDev, const Point& rDestPt, { ensureAvailable(); - if( isSupportedGraphic() && !isSwappedOut() && mpAnimation ) - mpAnimation->Start(rOutDev, rDestPt, rDestSize, nRendererId, pFirstFrameOutDev); + if (isSupportedGraphic() && !isSwappedOut() && mpAnimationContainer) + mpAnimationContainer->maAnimation.Start(rOutDev, rDestPt, rDestSize, nRendererId, pFirstFrameOutDev); } void ImpGraphic::stopAnimation( const OutputDevice* pOutDev, tools::Long nRendererId ) { ensureAvailable(); - if( isSupportedGraphic() && !isSwappedOut() && mpAnimation ) - mpAnimation->Stop( pOutDev, nRendererId ); + if (isSupportedGraphic() && !isSwappedOut() && mpAnimationContainer) + mpAnimationContainer->maAnimation.Stop( pOutDev, nRendererId ); } void ImpGraphic::setAnimationNotifyHdl( const Link<Animation*,void>& rLink ) { ensureAvailable(); - if( mpAnimation ) - mpAnimation->SetNotifyHdl( rLink ); + if (mpAnimationContainer) + mpAnimationContainer->maAnimation.SetNotifyHdl( rLink ); } Link<Animation*,void> ImpGraphic::getAnimationNotifyHdl() const @@ -1088,8 +1095,8 @@ Link<Animation*,void> ImpGraphic::getAnimationNotifyHdl() const ensureAvailable(); - if( mpAnimation ) - aLink = mpAnimation->GetNotifyHdl(); + if (mpAnimationContainer) + aLink = mpAnimationContainer->maAnimation.GetNotifyHdl(); return aLink; } @@ -1099,7 +1106,7 @@ sal_uInt32 ImpGraphic::getAnimationLoopCount() const if (mbSwapOut) return maSwapInfo.mnAnimationLoopCount; - return mpAnimation ? mpAnimation->GetLoopCount() : 0; + return mpAnimationContainer ? mpAnimationContainer->maAnimation.GetLoopCount() : 0; } bool ImpGraphic::swapInContent(SvStream& rStream) @@ -1197,10 +1204,10 @@ bool ImpGraphic::swapOutGraphic(SvStream& rStream) rStream.WriteUInt32(maVectorGraphicData->getBinaryDataContainer().getSize()); maVectorGraphicData->getBinaryDataContainer().writeToStream(rStream); } - else if (mpAnimation) + else if (mpAnimationContainer) { rStream.WriteInt32(sal_Int32(GraphicContentType::Animation)); - WriteAnimation(rStream, *mpAnimation); + WriteAnimation(rStream, mpAnimationContainer->maAnimation); } else if (mpBitmapContainer) { @@ -1363,12 +1370,12 @@ void ImpGraphic::updateFromLoadedGraphic(const ImpGraphic* pGraphic) else { // Move over only graphic content - mpAnimation.reset(); + mpAnimationContainer.reset(); - if (pGraphic->mpAnimation) + if (pGraphic->mpAnimationContainer) { - mpAnimation = std::make_unique<Animation>(*pGraphic->mpAnimation); - maCachedBitmap = mpAnimation->GetBitmapEx(); + mpAnimationContainer = std::make_shared<AnimationContainer>(*pGraphic->mpAnimationContainer); + maCachedBitmap = mpAnimationContainer->maAnimation.GetBitmapEx(); } else if (pGraphic->mpBitmapContainer) { @@ -1594,12 +1601,12 @@ bool ImpGraphic::swapInGraphic(SvStream& rStream) case GraphicContentType::Animation: { - auto pAnimation = std::make_unique<Animation>(); - ReadAnimation(rStream, *pAnimation); + Animation aAnimation; + ReadAnimation(rStream, aAnimation); if (!rStream.GetError()) { - mpAnimation = std::move(pAnimation); - maCachedBitmap = mpAnimation->GetBitmapEx(); + mpAnimationContainer = std::make_shared<AnimationContainer>(aAnimation); + maCachedBitmap = mpAnimationContainer->maAnimation.GetBitmapEx(); bReturn = true; } } @@ -1712,8 +1719,8 @@ BitmapChecksum ImpGraphic::getChecksum() const { if (maVectorGraphicData) mnChecksum = maVectorGraphicData->GetChecksum(); - else if (mpAnimation) - mnChecksum = mpAnimation->GetChecksum(); + else if (mpAnimationContainer) + mnChecksum = mpAnimationContainer->maAnimation.GetChecksum(); else if (mpBitmapContainer) mnChecksum = mpBitmapContainer->maBitmapEx.GetChecksum(); }