Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE
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