diff options
author | Michael Meeks <michael.meeks@collabora.com> | 2020-02-26 06:59:09 +0000 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2020-05-08 21:31:32 +0100 |
commit | ef541e3731ec6941b3c3fd0040404d74963da81f (patch) | |
tree | 3ac3058ddd0e8fd05599c76d3f99f3b827d380ef | |
parent | FrameLineColor - add Color parameter, and share code for color params. (diff) | |
download | core-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.hxx | 40 | ||||
-rw-r--r-- | vcl/source/app/salvtables.cxx | 4 | ||||
-rw-r--r-- | vcl/source/app/svmain.cxx | 2 | ||||
-rw-r--r-- | vcl/source/bitmap/BitmapScaleSuperFilter.cxx | 11 |
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; } |