Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP3:GA
libreoffice.10350
bsc1124658.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File bsc1124658.patch of Package libreoffice.10350
From 0012f765304a9587d77ccb54bbeeef4e332e5d92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com> Date: Wed, 6 Feb 2019 13:46:24 +0000 Subject: tdf#123165 cache recently scaled bitmaps for reuse MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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> --- vcl/inc/salbmp.hxx | 2 ++ vcl/inc/svdata.hxx | 4 ++++ vcl/source/app/salvtables.cxx | 11 +++++++++++ vcl/source/app/svmain.cxx | 2 ++ vcl/source/bitmap/BitmapScaleSuperFilter.cxx | 16 +++++++++++++++- vcl/source/gdi/bmpacc.cxx | 13 +++++++++---- 6 files changed, 43 insertions(+), 5 deletions(-) Index: libreoffice-6.1.5.2/vcl/inc/salbmp.hxx =================================================================== --- libreoffice-6.1.5.2.orig/vcl/inc/salbmp.hxx +++ libreoffice-6.1.5.2/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() Index: libreoffice-6.1.5.2/vcl/inc/svdata.hxx =================================================================== --- libreoffice-6.1.5.2.orig/vcl/inc/svdata.hxx +++ libreoffice-6.1.5.2/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> @@ -168,6 +169,8 @@ struct ImplSVAppData DECL_LINK(VclEventTestingHdl, Timer*, void); }; +typedef o3tl::lru_map<SalBitmap*, BitmapEx> lru_scale_cache; + struct ImplSVGDIData { ~ImplSVGDIData(); @@ -186,6 +189,7 @@ struct ImplSVGDIData ImplPrnQueueList* mpPrinterQueueList = nullptr; // List of all printer queue PhysicalFontCollection* mpScreenFontList = nullptr; // Screen-Font-List ImplFontCache* mpScreenFontCache = nullptr; // 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 Index: libreoffice-6.1.5.2/vcl/source/app/salvtables.cxx =================================================================== --- libreoffice-6.1.5.2.orig/vcl/source/app/salvtables.cxx +++ libreoffice-6.1.5.2/vcl/source/app/salvtables.cxx @@ -117,8 +117,19 @@ SalTimer::~SalTimer() COVERITY_NOEXCEPT_ { } +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() Index: libreoffice-6.1.5.2/vcl/source/app/svmain.cxx =================================================================== --- libreoffice-6.1.5.2.orig/vcl/source/app/svmain.cxx +++ libreoffice-6.1.5.2/vcl/source/app/svmain.cxx @@ -619,6 +619,8 @@ void DeInitVCL() pSVData->maGDIData.mpScreenFontList = nullptr; delete pSVData->maGDIData.mpScreenFontCache; pSVData->maGDIData.mpScreenFontCache = nullptr; + pSVData->maGDIData.maScaleCache.remove_if([](const o3tl::lru_map<SalBitmap*, BitmapEx>::key_value_pair_t&) + { return true; }); // Deinit Sal if (pSVData->mpDefInst) Index: libreoffice-6.1.5.2/vcl/source/bitmap/BitmapScaleSuperFilter.cxx =================================================================== --- libreoffice-6.1.5.2.orig/vcl/source/bitmap/BitmapScaleSuperFilter.cxx +++ libreoffice-6.1.5.2/vcl/source/bitmap/BitmapScaleSuperFilter.cxx @@ -26,6 +26,7 @@ #include <algorithm> #include <memory> +#include <svdata.hxx> namespace { @@ -932,6 +933,7 @@ BitmapScaleSuperFilter::~BitmapScaleSupe BitmapEx BitmapScaleSuperFilter::execute(BitmapEx const& rBitmap) { Bitmap aBitmap(rBitmap.GetBitmap()); + SalBitmap* pKey = aBitmap.ImplGetSalBitmap().get(); bool bRet = false; @@ -950,6 +952,17 @@ BitmapEx BitmapScaleSuperFilter::execute 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); @@ -1070,7 +1083,9 @@ BitmapEx BitmapScaleSuperFilter::execute { 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(); Index: libreoffice-6.1.5.2/vcl/source/gdi/bmpacc.cxx =================================================================== --- libreoffice-6.1.5.2.orig/vcl/source/gdi/bmpacc.cxx +++ libreoffice-6.1.5.2/vcl/source/gdi/bmpacc.cxx @@ -34,38 +34,37 @@ BitmapInfoAccess::BitmapInfoAccess( Bitm { std::shared_ptr<SalBitmap> xImpBmp = rBitmap.ImplGetSalBitmap(); - SAL_WARN_IF( !xImpBmp, "vcl", "Forbidden Access to empty bitmap!" ); + assert( xImpBmp && "Forbidden Access to empty bitmap!" ); - if( xImpBmp ) + if( !xImpBmp ) + return; + + if( mnAccessMode == BitmapAccessMode::Write) { - if( mnAccessMode == BitmapAccessMode::Write && !maBitmap.ImplGetSalBitmap() ) + xImpBmp->DropScaledCache(); + + if (xImpBmp.use_count() > 2) { xImpBmp.reset(); rBitmap.ImplMakeUnique(); xImpBmp = rBitmap.ImplGetSalBitmap(); } - else - { - DBG_ASSERT( mnAccessMode != BitmapAccessMode::Write || - xImpBmp.use_count() == 2, - "Unpredictable results: bitmap is referenced more than once!" ); - } + } - mpBuffer = xImpBmp->AcquireBuffer( mnAccessMode ); + mpBuffer = xImpBmp->AcquireBuffer( mnAccessMode ); - if( !mpBuffer ) + if( !mpBuffer ) + { + std::shared_ptr<SalBitmap> xNewImpBmp(ImplGetSVData()->mpDefInst->CreateSalBitmap()); + if (xNewImpBmp->Create(*xImpBmp, rBitmap.GetBitCount())) { - std::shared_ptr<SalBitmap> xNewImpBmp(ImplGetSVData()->mpDefInst->CreateSalBitmap()); - if (xNewImpBmp->Create(*xImpBmp, rBitmap.GetBitCount())) - { - xImpBmp = xNewImpBmp; - rBitmap.ImplSetSalBitmap( xImpBmp ); - mpBuffer = xImpBmp->AcquireBuffer( mnAccessMode ); - } + xImpBmp = xNewImpBmp; + rBitmap.ImplSetSalBitmap( xImpBmp ); + mpBuffer = xImpBmp->AcquireBuffer( mnAccessMode ); } - - maBitmap = rBitmap; } + + maBitmap = rBitmap; } BitmapInfoAccess::~BitmapInfoAccess() Index: libreoffice-6.1.5.2/include/o3tl/lru_map.hxx =================================================================== --- libreoffice-6.1.5.2.orig/include/o3tl/lru_map.hxx +++ libreoffice-6.1.5.2/include/o3tl/lru_map.hxx @@ -11,6 +11,7 @@ #ifndef INCLUDED_O3TL_LRU_MAP_HXX #define INCLUDED_O3TL_LRU_MAP_HXX +#include <cassert> #include <list> #include <unordered_map> @@ -30,16 +31,18 @@ namespace o3tl * for most of the operations with a combination unordered map and linked list. * **/ -template<typename Key, typename Value, class KeyHash = std::hash<Key>> +template<typename Key, typename Value, class KeyHash = std::hash<Key>, class KeyEqual = std::equal_to<Key>> class lru_map final { -private: +public: typedef typename std::pair<Key, Value> key_value_pair_t; + +private: typedef std::list<key_value_pair_t> list_t; typedef typename list_t::iterator list_iterator_t; typedef typename list_t::const_iterator list_const_iterator_t; - typedef std::unordered_map<Key, list_iterator_t, KeyHash> map_t; + typedef std::unordered_map<Key, list_iterator_t, KeyHash, KeyEqual> map_t; typedef typename map_t::iterator map_iterator_t; typedef typename map_t::const_iterator map_const_iterator_t; @@ -57,12 +60,14 @@ private: mLruList.pop_back(); } } + public: typedef list_iterator_t iterator; typedef list_const_iterator_t const_iterator; + // a size of 0 effectively disables the LRU cleanup code lru_map(size_t nMaxSize) - : mMaxSize(nMaxSize) + : mMaxSize(nMaxSize ? nMaxSize : std::min(mLruMap.max_size(), mLruList.max_size())) {} void insert(key_value_pair_t& rPair) @@ -74,7 +79,8 @@ public: // add to front of the list mLruList.push_front(rPair); // add the list position (iterator) to the map - mLruMap[rPair.first] = mLruList.begin(); + auto it = mLruList.begin(); + mLruMap[it->first] = it; checkLRU(); } else // already exists -> replace value @@ -95,7 +101,8 @@ public: // add to front of the list mLruList.push_front(std::move(rPair)); // add the list position (iterator) to the map - mLruMap[rPair.first] = mLruList.begin(); + auto it = mLruList.begin(); + mLruMap[it->first] = it; checkLRU(); } else // already exists -> replace value @@ -123,6 +130,28 @@ public: } } + // reverse-iterates the list removing all items matching the predicate + template<class UnaryPredicate> + void remove_if(UnaryPredicate pred) + { + auto it = mLruList.rbegin(); + while (it != mLruList.rend()) + { + if (pred(*it)) + { + mLruMap.erase(it->first); + it = decltype(it){ mLruList.erase(std::next(it).base()) }; + } + else + ++it; + } + } + + const list_const_iterator_t begin() const + { + return mLruList.cbegin(); + } + const list_const_iterator_t end() const { return mLruList.cend(); @@ -130,7 +159,8 @@ public: size_t size() const { - return mLruList.size(); + assert(mLruMap.size() == mLruList.size()); + return mLruMap.size(); } void clear()
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor