summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2019-02-06 13:46:24 +0000
committerNoel Grandin <noel.grandin@collabora.co.uk>2019-02-07 19:10:27 +0100
commit0012f765304a9587d77ccb54bbeeef4e332e5d92 (patch)
tree27ebdcb1906aa958a259e9ee848180c496107de1
parente9534eddcec78e5f6f551c848fa18f07a298ccfa (diff)
tdf#123165 cache recently scaled bitmaps for reuse
dropping the cached scaled bitmap when the bitmap is accesed via BitmapAccessMode::Write for writing Reviewed-on: https://gerrit.libreoffice.org/67459 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com> (cherry picked from commit 9f3926df5c2828ad3e8cfce2b4444b1c84352cf4) Change-Id: Ib6539522944838238bd699ec3531039d21dc0f8b Reviewed-on: https://gerrit.libreoffice.org/67492 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
-rw-r--r--vcl/inc/salbmp.hxx2
-rw-r--r--vcl/inc/svdata.hxx4
-rw-r--r--vcl/source/app/salvtables.cxx11
-rw-r--r--vcl/source/app/svmain.cxx2
-rw-r--r--vcl/source/bitmap/BitmapScaleSuperFilter.cxx16
-rw-r--r--vcl/source/gdi/bmpacc.cxx13
6 files changed, 43 insertions, 5 deletions
diff --git a/vcl/inc/salbmp.hxx b/vcl/inc/salbmp.hxx
index 7a89e82e057f..460bb7ec5210 100644
--- a/vcl/inc/salbmp.hxx
+++ b/vcl/inc/salbmp.hxx
@@ -72,6 +72,8 @@ public:
virtual bool ScalingSupported() const = 0;
virtual bool Scale( const double& rScaleX, const double& rScaleY, BmpScaleFlag nScaleFlag ) = 0;
+ void DropScaledCache();
+
virtual bool Replace( const Color& rSearchColor, const Color& rReplaceColor, sal_uInt8 nTol ) = 0;
virtual bool ConvertToGreyscale()
diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx
index 5ae913a0dbca..e5c21757a233 100644
--- a/vcl/inc/svdata.hxx
+++ b/vcl/inc/svdata.hxx
@@ -22,6 +22,7 @@
#include <config_version.h>
+#include <o3tl/lru_map.hxx>
#include <tools/fldunit.hxx>
#include <unotools/options.hxx>
#include <vcl/svapp.hxx>
@@ -174,6 +175,8 @@ struct ImplSVAppData
DECL_LINK(VclEventTestingHdl, Timer*, void);
};
+typedef o3tl::lru_map<SalBitmap*, BitmapEx> lru_scale_cache;
+
struct ImplSVGDIData
{
~ImplSVGDIData();
@@ -192,6 +195,7 @@ struct ImplSVGDIData
ImplPrnQueueList* mpPrinterQueueList = nullptr; // List of all printer queue
std::shared_ptr<PhysicalFontCollection> mxScreenFontList; // Screen-Font-List
std::shared_ptr<ImplFontCache> mxScreenFontCache; // Screen-Font-Cache
+ lru_scale_cache maScaleCache = lru_scale_cache(10); // Cache for scaled images
ImplDirectFontSubstitution* mpDirectFontSubst = nullptr; // Font-Substitutions defined in Tools->Options->Fonts
GraphicConverter* mpGrfConverter = nullptr; // Converter for graphics
long mnAppFontX = 0; // AppFont X-Numenator for 40/tel Width
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 6be5e24f7bd4..9dacfafaf9cf 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -139,8 +139,19 @@ SalTimer::~SalTimer() COVERITY_NOEXCEPT_FALSE
{
}
+void SalBitmap::DropScaledCache()
+{
+ if (ImplSVData* pSVData = ImplGetSVData())
+ {
+ auto& rCache = pSVData->maGDIData.maScaleCache;
+ rCache.remove_if([this] (const o3tl::lru_map<SalBitmap*, BitmapEx>::key_value_pair_t& rKeyValuePair)
+ { return rKeyValuePair.first == this; });
+ }
+}
+
SalBitmap::~SalBitmap()
{
+ DropScaledCache();
}
SalI18NImeStatus::~SalI18NImeStatus()
diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx
index ce825e7062aa..c543732630de 100644
--- a/vcl/source/app/svmain.cxx
+++ b/vcl/source/app/svmain.cxx
@@ -574,6 +574,8 @@ void DeInitVCL()
pSVData->maGDIData.mxScreenFontList.reset();
pSVData->maGDIData.mxScreenFontCache.reset();
+ pSVData->maGDIData.maScaleCache.remove_if([](const o3tl::lru_map<SalBitmap*, BitmapEx>::key_value_pair_t&)
+ { return true; });
// Deinit Sal
if (pSVData->mpDefInst)
diff --git a/vcl/source/bitmap/BitmapScaleSuperFilter.cxx b/vcl/source/bitmap/BitmapScaleSuperFilter.cxx
index eb081281b56d..14b18e9f7a02 100644
--- a/vcl/source/bitmap/BitmapScaleSuperFilter.cxx
+++ b/vcl/source/bitmap/BitmapScaleSuperFilter.cxx
@@ -26,6 +26,7 @@
#include <algorithm>
#include <memory>
+#include <svdata.hxx>
#include <sal/log.hxx>
namespace {
@@ -935,6 +936,7 @@ BitmapScaleSuperFilter::~BitmapScaleSuperFilter()
BitmapEx BitmapScaleSuperFilter::execute(BitmapEx const& rBitmap) const
{
Bitmap aBitmap(rBitmap.GetBitmap());
+ SalBitmap* pKey = aBitmap.ImplGetSalBitmap().get();
bool bRet = false;
@@ -954,6 +956,16 @@ BitmapEx BitmapScaleSuperFilter::execute(BitmapEx const& rBitmap) const
if (nDstW <= 1 || nDstH <= 1)
return BitmapEx();
+ // check cache for a previously scaled version of this
+ ImplSVData* pSVData = ImplGetSVData();
+ auto& rCache = pSVData->maGDIData.maScaleCache;
+ auto aFind = rCache.find(pKey);
+ if (aFind != rCache.end())
+ {
+ if (aFind->second.GetSizePixel().Width() == nDstW && aFind->second.GetSizePixel().Height() == nDstH)
+ return aFind->second;
+ }
+
{
Bitmap::ScopedReadAccess pReadAccess(aBitmap);
@@ -1077,7 +1089,9 @@ BitmapEx BitmapScaleSuperFilter::execute(BitmapEx const& rBitmap) const
{
tools::Rectangle aRect(Point(0, 0), Point(nDstW, nDstH));
aBitmap.Crop(aRect);
- return BitmapEx(aBitmap);
+ BitmapEx aRet(aBitmap);
+ rCache.insert(std::make_pair(pKey, aRet));
+ return aRet;
}
return BitmapEx();
diff --git a/vcl/source/gdi/bmpacc.cxx b/vcl/source/gdi/bmpacc.cxx
index ba7a1923e4ca..f970c93428ce 100644
--- a/vcl/source/gdi/bmpacc.cxx
+++ b/vcl/source/gdi/bmpacc.cxx
@@ -40,11 +40,16 @@ BitmapInfoAccess::BitmapInfoAccess( Bitmap& rBitmap, BitmapAccessMode nMode ) :
if( !xImpBmp )
return;
- if( mnAccessMode == BitmapAccessMode::Write && xImpBmp.use_count() > 2 )
+ if (mnAccessMode == BitmapAccessMode::Write)
{
- xImpBmp.reset();
- rBitmap.ImplMakeUnique();
- xImpBmp = rBitmap.ImplGetSalBitmap();
+ xImpBmp->DropScaledCache();
+
+ if (xImpBmp.use_count() > 2)
+ {
+ xImpBmp.reset();
+ rBitmap.ImplMakeUnique();
+ xImpBmp = rBitmap.ImplGetSalBitmap();
+ }
}
mpBuffer = xImpBmp->AcquireBuffer( mnAccessMode );