summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@collabora.com>2020-02-26 06:59:09 +0000
committerMichael Meeks <michael.meeks@collabora.com>2020-05-08 21:31:32 +0100
commitef541e3731ec6941b3c3fd0040404d74963da81f (patch)
tree3ac3058ddd0e8fd05599c76d3f99f3b827d380ef
parentFrameLineColor - add Color parameter, and share code for color params. (diff)
downloadcore-ef541e3731ec6941b3c3fd0040404d74963da81f.tar.gz
core-ef541e3731ec6941b3c3fd0040404d74963da81f.zip
lru_scale_cache - cache the same bitmap at multiple scales.
Helps accelerate different views at different scales, as well as document / image thumbnailing on save, as well as stray views that can get rendered behind the scenes at odd scales on mobile. Each scale + bitmap combination is another key in the LRU table. Change-Id: Id82ce2e4180608082c9ca16fad35bba9e8c2e81a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89497 Reviewed-by: Tomaž Vajngerl <quikee@gmail.com> Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Michael Meeks <michael.meeks@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89503 Tested-by: Jenkins
-rw-r--r--vcl/inc/svdata.hxx40
-rw-r--r--vcl/source/app/salvtables.cxx4
-rw-r--r--vcl/source/app/svmain.cxx2
-rw-r--r--vcl/source/bitmap/BitmapScaleSuperFilter.cxx11
4 files changed, 49 insertions, 8 deletions
diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx
index e41ec23488b3..654b9ec968f1 100644
--- a/vcl/inc/svdata.hxx
+++ b/vcl/inc/svdata.hxx
@@ -165,6 +165,44 @@ struct ImplSVAppData
DECL_LINK(VclEventTestingHdl, Timer*, void);
};
+/// Cache multiple scalings for the same bitmap
+struct ScaleCacheKey {
+ SalBitmap *mpBitmap;
+ Size maDestSize;
+ ScaleCacheKey(SalBitmap *pBitmap, const Size &aDestSize)
+ {
+ mpBitmap = pBitmap;
+ maDestSize = aDestSize;
+ }
+ ScaleCacheKey(const ScaleCacheKey &key)
+ {
+ mpBitmap = key.mpBitmap;
+ maDestSize = key.maDestSize;
+ }
+ bool operator==(ScaleCacheKey const& rOther) const
+ {
+ return mpBitmap == rOther.mpBitmap && maDestSize == rOther.maDestSize;
+ }
+};
+
+namespace std
+{
+template <> struct hash<ScaleCacheKey>
+{
+ std::size_t operator()(ScaleCacheKey const& k) const noexcept
+ {
+ std::size_t seed = 0;
+ boost::hash_combine(seed, k.mpBitmap);
+ boost::hash_combine(seed, k.maDestSize.getWidth());
+ boost::hash_combine(seed, k.maDestSize.getHeight());
+ return seed;
+ }
+};
+
+} // end std namespace
+
+typedef o3tl::lru_map<ScaleCacheKey, BitmapEx> lru_scale_cache;
+
struct ImplSVGDIData
{
~ImplSVGDIData();
@@ -181,7 +219,7 @@ struct ImplSVGDIData
std::unique_ptr<ImplPrnQueueList> mpPrinterQueueList; // List of all printer queue
std::shared_ptr<PhysicalFontCollection> mxScreenFontList; // Screen-Font-List
std::shared_ptr<ImplFontCache> mxScreenFontCache; // Screen-Font-Cache
- o3tl::lru_map<SalBitmap*, BitmapEx> maScaleCache = o3tl::lru_map<SalBitmap*, BitmapEx>(10); // Cache for scaled images
+ 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 9bfeb9997041..d9d25ee5494f 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -157,8 +157,8 @@ 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; });
+ rCache.remove_if([this] (const lru_scale_cache::key_value_pair_t& rKeyValuePair)
+ { return rKeyValuePair.first.mpBitmap == this; });
}
}
diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx
index e032edcc710f..b0e3ce33b973 100644
--- a/vcl/source/app/svmain.cxx
+++ b/vcl/source/app/svmain.cxx
@@ -564,7 +564,7 @@ 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&)
+ pSVData->maGDIData.maScaleCache.remove_if([](const lru_scale_cache::key_value_pair_t&)
{ return true; });
pSVData->maGDIData.maThemeDrawCommandsCache.clear();
diff --git a/vcl/source/bitmap/BitmapScaleSuperFilter.cxx b/vcl/source/bitmap/BitmapScaleSuperFilter.cxx
index 9ee6e80c7b40..bd6b7bd00b56 100644
--- a/vcl/source/bitmap/BitmapScaleSuperFilter.cxx
+++ b/vcl/source/bitmap/BitmapScaleSuperFilter.cxx
@@ -1016,8 +1016,6 @@ BitmapScaleSuperFilter::~BitmapScaleSuperFilter()
BitmapEx BitmapScaleSuperFilter::execute(BitmapEx const& rBitmap) const
{
Bitmap aBitmap(rBitmap.GetBitmap());
- SalBitmap* pKey = aBitmap.ImplGetSalBitmap().get();
-
bool bRet = false;
const Size aSizePix(rBitmap.GetSizePixel());
@@ -1037,13 +1035,18 @@ BitmapEx BitmapScaleSuperFilter::execute(BitmapEx const& rBitmap) const
return BitmapEx();
// check cache for a previously scaled version of this
+ ScaleCacheKey aKey(aBitmap.ImplGetSalBitmap().get(),
+ Size(nDstW, nDstH));
+
ImplSVData* pSVData = ImplGetSVData();
auto& rCache = pSVData->maGDIData.maScaleCache;
- auto aFind = rCache.find(pKey);
+ auto aFind = rCache.find(aKey);
if (aFind != rCache.end())
{
if (aFind->second.GetSizePixel().Width() == nDstW && aFind->second.GetSizePixel().Height() == nDstH)
return aFind->second;
+ else
+ SAL_WARN("vcl.gdi", "Error: size mismatch in scale cache");
}
{
@@ -1187,7 +1190,7 @@ BitmapEx BitmapScaleSuperFilter::execute(BitmapEx const& rBitmap) const
tools::Rectangle aRect(Point(0, 0), Point(nDstW, nDstH));
aBitmap.Crop(aRect);
BitmapEx aRet(aBitmap);
- rCache.insert(std::make_pair(pKey, aRet));
+ rCache.insert(std::make_pair(aKey, aRet));
return aRet;
}