xref: /AOO41X/main/sd/source/ui/slidesorter/cache/SlsBitmapCache.cxx (revision 5b1900111deff329a5580f97b99b67a25168e53d)
1*5b190011SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*5b190011SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*5b190011SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*5b190011SAndrew Rist  * distributed with this work for additional information
6*5b190011SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*5b190011SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*5b190011SAndrew Rist  * "License"); you may not use this file except in compliance
9*5b190011SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*5b190011SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*5b190011SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*5b190011SAndrew Rist  * software distributed under the License is distributed on an
15*5b190011SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*5b190011SAndrew Rist  * KIND, either express or implied.  See the License for the
17*5b190011SAndrew Rist  * specific language governing permissions and limitations
18*5b190011SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*5b190011SAndrew Rist  *************************************************************/
21*5b190011SAndrew Rist 
22*5b190011SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sd.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "SlsBitmapCache.hxx"
28cdf0e10cSrcweir #include "SlsCacheCompactor.hxx"
29cdf0e10cSrcweir #include "SlsBitmapCompressor.hxx"
30cdf0e10cSrcweir #include "SlsCacheConfiguration.hxx"
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include "sdpage.hxx"
33cdf0e10cSrcweir #include "drawdoc.hxx"
34cdf0e10cSrcweir 
35cdf0e10cSrcweir // Uncomment the following define for some more OSL_TRACE messages.
36cdf0e10cSrcweir #ifdef DEBUG
37cdf0e10cSrcweir //#define VERBOSE
38cdf0e10cSrcweir #endif
39cdf0e10cSrcweir 
40cdf0e10cSrcweir // Define the default value for the maximal cache size that is used for
41cdf0e10cSrcweir // previews that are currently not visible.  The visible previews are all
42cdf0e10cSrcweir // held in memory at all times.  This default is used only when the
43cdf0e10cSrcweir // configuration does not have a value.
44cdf0e10cSrcweir static const sal_Int32 MAXIMAL_CACHE_SIZE = 4L*1024L*1024L;
45cdf0e10cSrcweir 
46cdf0e10cSrcweir using namespace ::com::sun::star::uno;
47cdf0e10cSrcweir 
48cdf0e10cSrcweir namespace sd { namespace slidesorter { namespace cache {
49cdf0e10cSrcweir 
50cdf0e10cSrcweir class BitmapCache::CacheEntry
51cdf0e10cSrcweir {
52cdf0e10cSrcweir public:
53cdf0e10cSrcweir     CacheEntry(const Bitmap& rBitmap, sal_Int32 nLastAccessTime, bool bIsPrecious);
54cdf0e10cSrcweir     CacheEntry(sal_Int32 nLastAccessTime, bool bIsPrecious);
~CacheEntry(void)55cdf0e10cSrcweir     ~CacheEntry (void) {};
56cdf0e10cSrcweir     inline void Recycle (const CacheEntry& rEntry);
57cdf0e10cSrcweir     inline sal_Int32 GetMemorySize (void) const;
58cdf0e10cSrcweir     void Compress (const ::boost::shared_ptr<BitmapCompressor>& rpCompressor);
59cdf0e10cSrcweir     inline void Decompress (void);
60cdf0e10cSrcweir 
IsUpToDate(void) const61cdf0e10cSrcweir     bool IsUpToDate (void) const { return mbIsUpToDate; }
SetUpToDate(bool bIsUpToDate)62cdf0e10cSrcweir     void SetUpToDate (bool bIsUpToDate) { mbIsUpToDate = bIsUpToDate; }
GetAccessTime(void) const63cdf0e10cSrcweir     sal_Int32 GetAccessTime (void) const { return mnLastAccessTime; }
SetAccessTime(sal_Int32 nAccessTime)64cdf0e10cSrcweir     void SetAccessTime (sal_Int32 nAccessTime) { mnLastAccessTime = nAccessTime; }
65cdf0e10cSrcweir 
GetPreview(void) const66cdf0e10cSrcweir     Bitmap GetPreview (void) const { return maPreview; }
67cdf0e10cSrcweir     inline void SetPreview (const Bitmap& rPreview);
68cdf0e10cSrcweir     bool HasPreview (void) const;
69cdf0e10cSrcweir 
GetMarkedPreview(void) const70cdf0e10cSrcweir     Bitmap GetMarkedPreview (void) const { return maMarkedPreview; }
71cdf0e10cSrcweir     inline void SetMarkedPreview (const Bitmap& rMarkePreview);
72cdf0e10cSrcweir     bool HasMarkedPreview (void) const;
73cdf0e10cSrcweir 
HasReplacement(void) const74cdf0e10cSrcweir     bool HasReplacement (void) const { return (mpReplacement.get() != NULL); }
75cdf0e10cSrcweir     inline bool HasLosslessReplacement (void) const;
Clear(void)76cdf0e10cSrcweir     void Clear (void) { maPreview.SetEmpty(); maMarkedPreview.SetEmpty();
77cdf0e10cSrcweir         mpReplacement.reset(); mpCompressor.reset(); }
Invalidate(void)78cdf0e10cSrcweir     void Invalidate (void) { mpReplacement.reset(); mpCompressor.reset(); mbIsUpToDate = false; }
IsPrecious(void) const79cdf0e10cSrcweir     bool IsPrecious (void) const { return mbIsPrecious; }
SetPrecious(bool bIsPrecious)80cdf0e10cSrcweir     void SetPrecious (bool bIsPrecious) { mbIsPrecious = bIsPrecious; }
81cdf0e10cSrcweir 
82cdf0e10cSrcweir private:
83cdf0e10cSrcweir     Bitmap maPreview;
84cdf0e10cSrcweir     Bitmap maMarkedPreview;
85cdf0e10cSrcweir     ::boost::shared_ptr<BitmapReplacement> mpReplacement;
86cdf0e10cSrcweir     ::boost::shared_ptr<BitmapCompressor> mpCompressor;
87cdf0e10cSrcweir     Size maBitmapSize;
88cdf0e10cSrcweir     bool mbIsUpToDate;
89cdf0e10cSrcweir     sal_Int32 mnLastAccessTime;
90cdf0e10cSrcweir     // When this flag is set then the bitmap is not modified by a cache
91cdf0e10cSrcweir     // compactor.
92cdf0e10cSrcweir     bool mbIsPrecious;
93cdf0e10cSrcweir };
94cdf0e10cSrcweir class CacheEntry;
95cdf0e10cSrcweir 
96cdf0e10cSrcweir class CacheHash {
97cdf0e10cSrcweir public:
operator ()(const BitmapCache::CacheKey & p) const98cdf0e10cSrcweir     size_t operator()(const BitmapCache::CacheKey& p) const
99cdf0e10cSrcweir     { return (size_t)p; }
100cdf0e10cSrcweir };
101cdf0e10cSrcweir 
102cdf0e10cSrcweir class BitmapCache::CacheBitmapContainer
103cdf0e10cSrcweir     : public ::std::hash_map<CacheKey, CacheEntry, CacheHash>
104cdf0e10cSrcweir {
105cdf0e10cSrcweir public:
CacheBitmapContainer(void)106cdf0e10cSrcweir     CacheBitmapContainer (void) {}
107cdf0e10cSrcweir };
108cdf0e10cSrcweir 
109cdf0e10cSrcweir namespace {
110cdf0e10cSrcweir 
111cdf0e10cSrcweir typedef ::std::vector<
112cdf0e10cSrcweir     ::std::pair< ::sd::slidesorter::cache::BitmapCache::CacheKey,
113cdf0e10cSrcweir       ::sd::slidesorter::cache::BitmapCache::CacheEntry>
114cdf0e10cSrcweir     > SortableBitmapContainer;
115cdf0e10cSrcweir 
116cdf0e10cSrcweir     /** Compare elements of the bitmap cache according to their last access
117cdf0e10cSrcweir         time.
118cdf0e10cSrcweir     */
119cdf0e10cSrcweir     class AccessTimeComparator
120cdf0e10cSrcweir     {
121cdf0e10cSrcweir     public:
operator ()(const SortableBitmapContainer::value_type & e1,const SortableBitmapContainer::value_type & e2)122cdf0e10cSrcweir         bool operator () (
123cdf0e10cSrcweir             const SortableBitmapContainer::value_type& e1,
124cdf0e10cSrcweir             const SortableBitmapContainer::value_type& e2)
125cdf0e10cSrcweir         {
126cdf0e10cSrcweir             return e1.second.GetAccessTime() < e2.second.GetAccessTime();
127cdf0e10cSrcweir         }
128cdf0e10cSrcweir     };
129cdf0e10cSrcweir 
130cdf0e10cSrcweir 
131cdf0e10cSrcweir } // end of anonymous namespace
132cdf0e10cSrcweir 
133cdf0e10cSrcweir 
134cdf0e10cSrcweir //=====  BitmapCache  =========================================================
135cdf0e10cSrcweir 
BitmapCache(const sal_Int32 nMaximalNormalCacheSize)136cdf0e10cSrcweir BitmapCache::BitmapCache (const sal_Int32 nMaximalNormalCacheSize)
137cdf0e10cSrcweir     : maMutex(),
138cdf0e10cSrcweir       mpBitmapContainer(new CacheBitmapContainer()),
139cdf0e10cSrcweir       mnNormalCacheSize(0),
140cdf0e10cSrcweir       mnPreciousCacheSize(0),
141cdf0e10cSrcweir       mnCurrentAccessTime(0),
142cdf0e10cSrcweir       mnMaximalNormalCacheSize(MAXIMAL_CACHE_SIZE),
143cdf0e10cSrcweir       mpCacheCompactor(),
144cdf0e10cSrcweir       mbIsFull(false)
145cdf0e10cSrcweir {
146cdf0e10cSrcweir     if (nMaximalNormalCacheSize > 0)
147cdf0e10cSrcweir         mnMaximalNormalCacheSize = nMaximalNormalCacheSize;
148cdf0e10cSrcweir     else
149cdf0e10cSrcweir     {
150cdf0e10cSrcweir         Any aCacheSize (CacheConfiguration::Instance()->GetValue(
151cdf0e10cSrcweir         ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CacheSize"))));
152cdf0e10cSrcweir         if (aCacheSize.has<sal_Int32>())
153cdf0e10cSrcweir             aCacheSize >>= mnMaximalNormalCacheSize;
154cdf0e10cSrcweir     }
155cdf0e10cSrcweir 
156cdf0e10cSrcweir     mpCacheCompactor = CacheCompactor::Create(*this,mnMaximalNormalCacheSize);
157cdf0e10cSrcweir }
158cdf0e10cSrcweir 
159cdf0e10cSrcweir 
160cdf0e10cSrcweir 
161cdf0e10cSrcweir 
~BitmapCache(void)162cdf0e10cSrcweir BitmapCache::~BitmapCache (void)
163cdf0e10cSrcweir {
164cdf0e10cSrcweir     Clear();
165cdf0e10cSrcweir }
166cdf0e10cSrcweir 
167cdf0e10cSrcweir 
168cdf0e10cSrcweir 
169cdf0e10cSrcweir 
Clear(void)170cdf0e10cSrcweir void BitmapCache::Clear (void)
171cdf0e10cSrcweir {
172cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
173cdf0e10cSrcweir 
174cdf0e10cSrcweir     mpBitmapContainer->clear();
175cdf0e10cSrcweir     mnNormalCacheSize = 0;
176cdf0e10cSrcweir     mnPreciousCacheSize = 0;
177cdf0e10cSrcweir     mnCurrentAccessTime = 0;
178cdf0e10cSrcweir }
179cdf0e10cSrcweir 
180cdf0e10cSrcweir 
181cdf0e10cSrcweir 
182cdf0e10cSrcweir 
IsFull(void) const183cdf0e10cSrcweir bool BitmapCache::IsFull (void) const
184cdf0e10cSrcweir {
185cdf0e10cSrcweir     return mbIsFull;
186cdf0e10cSrcweir }
187cdf0e10cSrcweir 
188cdf0e10cSrcweir 
189cdf0e10cSrcweir 
190cdf0e10cSrcweir 
GetSize(void)191cdf0e10cSrcweir sal_Int32 BitmapCache::GetSize (void)
192cdf0e10cSrcweir {
193cdf0e10cSrcweir     return mnNormalCacheSize;
194cdf0e10cSrcweir }
195cdf0e10cSrcweir 
196cdf0e10cSrcweir 
197cdf0e10cSrcweir 
198cdf0e10cSrcweir 
HasBitmap(const CacheKey & rKey)199cdf0e10cSrcweir bool BitmapCache::HasBitmap (const CacheKey& rKey)
200cdf0e10cSrcweir {
201cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
202cdf0e10cSrcweir 
203cdf0e10cSrcweir     CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey));
204cdf0e10cSrcweir     return (iEntry != mpBitmapContainer->end()
205cdf0e10cSrcweir         && (iEntry->second.HasPreview() || iEntry->second.HasReplacement()));
206cdf0e10cSrcweir }
207cdf0e10cSrcweir 
208cdf0e10cSrcweir 
209cdf0e10cSrcweir 
210cdf0e10cSrcweir 
BitmapIsUpToDate(const CacheKey & rKey)211cdf0e10cSrcweir bool BitmapCache::BitmapIsUpToDate (const CacheKey& rKey)
212cdf0e10cSrcweir {
213cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
214cdf0e10cSrcweir 
215cdf0e10cSrcweir     bool bIsUpToDate = false;
216cdf0e10cSrcweir     CacheBitmapContainer::iterator aIterator (mpBitmapContainer->find(rKey));
217cdf0e10cSrcweir     if (aIterator != mpBitmapContainer->end())
218cdf0e10cSrcweir         bIsUpToDate = aIterator->second.IsUpToDate();
219cdf0e10cSrcweir 
220cdf0e10cSrcweir     return bIsUpToDate;
221cdf0e10cSrcweir }
222cdf0e10cSrcweir 
223cdf0e10cSrcweir 
224cdf0e10cSrcweir 
225cdf0e10cSrcweir 
GetBitmap(const CacheKey & rKey)226cdf0e10cSrcweir Bitmap BitmapCache::GetBitmap (const CacheKey& rKey)
227cdf0e10cSrcweir {
228cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
229cdf0e10cSrcweir 
230cdf0e10cSrcweir     CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey));
231cdf0e10cSrcweir     if (iEntry == mpBitmapContainer->end())
232cdf0e10cSrcweir     {
233cdf0e10cSrcweir         // Create an empty bitmap for the given key that acts as placeholder
234cdf0e10cSrcweir         // until we are given the real one.  Mark it as not being up to date.
235cdf0e10cSrcweir         SetBitmap(rKey, Bitmap(), false);
236cdf0e10cSrcweir         iEntry = mpBitmapContainer->find(rKey);
237cdf0e10cSrcweir         iEntry->second.SetUpToDate(false);
238cdf0e10cSrcweir     }
239cdf0e10cSrcweir     else
240cdf0e10cSrcweir     {
241cdf0e10cSrcweir         iEntry->second.SetAccessTime(mnCurrentAccessTime++);
242cdf0e10cSrcweir 
243cdf0e10cSrcweir         // Maybe we have to decompress the preview.
244cdf0e10cSrcweir         if ( ! iEntry->second.HasPreview() && iEntry->second.HasReplacement())
245cdf0e10cSrcweir         {
246cdf0e10cSrcweir             UpdateCacheSize(iEntry->second, REMOVE);
247cdf0e10cSrcweir             iEntry->second.Decompress();
248cdf0e10cSrcweir             UpdateCacheSize(iEntry->second, ADD);
249cdf0e10cSrcweir         }
250cdf0e10cSrcweir     }
251cdf0e10cSrcweir     return iEntry->second.GetPreview();
252cdf0e10cSrcweir }
253cdf0e10cSrcweir 
254cdf0e10cSrcweir 
255cdf0e10cSrcweir 
256cdf0e10cSrcweir 
GetMarkedBitmap(const CacheKey & rKey)257cdf0e10cSrcweir Bitmap BitmapCache::GetMarkedBitmap (const CacheKey& rKey)
258cdf0e10cSrcweir {
259cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
260cdf0e10cSrcweir 
261cdf0e10cSrcweir     CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey));
262cdf0e10cSrcweir     if (iEntry != mpBitmapContainer->end())
263cdf0e10cSrcweir     {
264cdf0e10cSrcweir         iEntry->second.SetAccessTime(mnCurrentAccessTime++);
265cdf0e10cSrcweir         return iEntry->second.GetMarkedPreview();
266cdf0e10cSrcweir     }
267cdf0e10cSrcweir     else
268cdf0e10cSrcweir         return Bitmap();
269cdf0e10cSrcweir }
270cdf0e10cSrcweir 
271cdf0e10cSrcweir 
272cdf0e10cSrcweir 
273cdf0e10cSrcweir 
ReleaseBitmap(const CacheKey & rKey)274cdf0e10cSrcweir void BitmapCache::ReleaseBitmap (const CacheKey& rKey)
275cdf0e10cSrcweir {
276cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
277cdf0e10cSrcweir 
278cdf0e10cSrcweir     CacheBitmapContainer::iterator aIterator (mpBitmapContainer->find(rKey));
279cdf0e10cSrcweir     if (aIterator != mpBitmapContainer->end())
280cdf0e10cSrcweir     {
281cdf0e10cSrcweir         UpdateCacheSize(aIterator->second, REMOVE);
282cdf0e10cSrcweir         mpBitmapContainer->erase(aIterator);
283cdf0e10cSrcweir     }
284cdf0e10cSrcweir }
285cdf0e10cSrcweir 
286cdf0e10cSrcweir 
287cdf0e10cSrcweir 
288cdf0e10cSrcweir 
InvalidateBitmap(const CacheKey & rKey)289cdf0e10cSrcweir bool BitmapCache::InvalidateBitmap (const CacheKey& rKey)
290cdf0e10cSrcweir {
291cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
292cdf0e10cSrcweir 
293cdf0e10cSrcweir     CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey));
294cdf0e10cSrcweir     if (iEntry != mpBitmapContainer->end())
295cdf0e10cSrcweir     {
296cdf0e10cSrcweir         iEntry->second.SetUpToDate(false);
297cdf0e10cSrcweir 
298cdf0e10cSrcweir         // When there is a preview then we release the replacement.  The
299cdf0e10cSrcweir         // preview itself is kept until a new one is created.
300cdf0e10cSrcweir         if (iEntry->second.HasPreview())
301cdf0e10cSrcweir         {
302cdf0e10cSrcweir             UpdateCacheSize(iEntry->second, REMOVE);
303cdf0e10cSrcweir             iEntry->second.Invalidate();
304cdf0e10cSrcweir             UpdateCacheSize(iEntry->second, ADD);
305cdf0e10cSrcweir         }
306cdf0e10cSrcweir         return true;
307cdf0e10cSrcweir     }
308cdf0e10cSrcweir     else
309cdf0e10cSrcweir         return false;
310cdf0e10cSrcweir }
311cdf0e10cSrcweir 
312cdf0e10cSrcweir 
313cdf0e10cSrcweir 
314cdf0e10cSrcweir 
InvalidateCache(void)315cdf0e10cSrcweir void BitmapCache::InvalidateCache (void)
316cdf0e10cSrcweir {
317cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
318cdf0e10cSrcweir 
319cdf0e10cSrcweir     CacheBitmapContainer::iterator iEntry;
320cdf0e10cSrcweir     for (iEntry=mpBitmapContainer->begin(); iEntry!=mpBitmapContainer->end(); ++iEntry)
321cdf0e10cSrcweir     {
322cdf0e10cSrcweir         iEntry->second.Invalidate();
323cdf0e10cSrcweir     }
324cdf0e10cSrcweir     ReCalculateTotalCacheSize();
325cdf0e10cSrcweir }
326cdf0e10cSrcweir 
327cdf0e10cSrcweir 
328cdf0e10cSrcweir 
329cdf0e10cSrcweir 
SetBitmap(const CacheKey & rKey,const Bitmap & rPreview,bool bIsPrecious)330cdf0e10cSrcweir void BitmapCache::SetBitmap (
331cdf0e10cSrcweir     const CacheKey& rKey,
332cdf0e10cSrcweir     const Bitmap& rPreview,
333cdf0e10cSrcweir     bool bIsPrecious)
334cdf0e10cSrcweir {
335cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
336cdf0e10cSrcweir 
337cdf0e10cSrcweir     CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey));
338cdf0e10cSrcweir     if (iEntry != mpBitmapContainer->end())
339cdf0e10cSrcweir     {
340cdf0e10cSrcweir         UpdateCacheSize(iEntry->second, REMOVE);
341cdf0e10cSrcweir         iEntry->second.SetPreview(rPreview);
342cdf0e10cSrcweir         iEntry->second.SetUpToDate(true);
343cdf0e10cSrcweir         iEntry->second.SetAccessTime(mnCurrentAccessTime++);
344cdf0e10cSrcweir     }
345cdf0e10cSrcweir     else
346cdf0e10cSrcweir     {
347cdf0e10cSrcweir         iEntry = mpBitmapContainer->insert(CacheBitmapContainer::value_type (
348cdf0e10cSrcweir             rKey,
349cdf0e10cSrcweir             CacheEntry(rPreview, mnCurrentAccessTime++, bIsPrecious))
350cdf0e10cSrcweir             ).first;
351cdf0e10cSrcweir     }
352cdf0e10cSrcweir 
353cdf0e10cSrcweir     if (iEntry != mpBitmapContainer->end())
354cdf0e10cSrcweir         UpdateCacheSize(iEntry->second, ADD);
355cdf0e10cSrcweir }
356cdf0e10cSrcweir 
357cdf0e10cSrcweir 
358cdf0e10cSrcweir 
359cdf0e10cSrcweir 
SetMarkedBitmap(const CacheKey & rKey,const Bitmap & rPreview)360cdf0e10cSrcweir void BitmapCache::SetMarkedBitmap (
361cdf0e10cSrcweir     const CacheKey& rKey,
362cdf0e10cSrcweir     const Bitmap& rPreview)
363cdf0e10cSrcweir {
364cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
365cdf0e10cSrcweir 
366cdf0e10cSrcweir     CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey));
367cdf0e10cSrcweir     if (iEntry != mpBitmapContainer->end())
368cdf0e10cSrcweir     {
369cdf0e10cSrcweir         UpdateCacheSize(iEntry->second, REMOVE);
370cdf0e10cSrcweir         iEntry->second.SetMarkedPreview(rPreview);
371cdf0e10cSrcweir         iEntry->second.SetAccessTime(mnCurrentAccessTime++);
372cdf0e10cSrcweir         UpdateCacheSize(iEntry->second, ADD);
373cdf0e10cSrcweir     }
374cdf0e10cSrcweir }
375cdf0e10cSrcweir 
376cdf0e10cSrcweir 
377cdf0e10cSrcweir 
378cdf0e10cSrcweir 
SetPrecious(const CacheKey & rKey,bool bIsPrecious)379cdf0e10cSrcweir void BitmapCache::SetPrecious (const CacheKey& rKey, bool bIsPrecious)
380cdf0e10cSrcweir {
381cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
382cdf0e10cSrcweir 
383cdf0e10cSrcweir     CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey));
384cdf0e10cSrcweir     if (iEntry != mpBitmapContainer->end())
385cdf0e10cSrcweir     {
386cdf0e10cSrcweir         if (iEntry->second.IsPrecious() != bIsPrecious)
387cdf0e10cSrcweir         {
388cdf0e10cSrcweir             UpdateCacheSize(iEntry->second, REMOVE);
389cdf0e10cSrcweir             iEntry->second.SetPrecious(bIsPrecious);
390cdf0e10cSrcweir             UpdateCacheSize(iEntry->second, ADD);
391cdf0e10cSrcweir         }
392cdf0e10cSrcweir     }
393cdf0e10cSrcweir     else if (bIsPrecious)
394cdf0e10cSrcweir     {
395cdf0e10cSrcweir         iEntry = mpBitmapContainer->insert(CacheBitmapContainer::value_type (
396cdf0e10cSrcweir             rKey,
397cdf0e10cSrcweir             CacheEntry(Bitmap(), mnCurrentAccessTime++, bIsPrecious))
398cdf0e10cSrcweir             ).first;
399cdf0e10cSrcweir         UpdateCacheSize(iEntry->second, ADD);
400cdf0e10cSrcweir     }
401cdf0e10cSrcweir }
402cdf0e10cSrcweir 
403cdf0e10cSrcweir 
404cdf0e10cSrcweir 
405cdf0e10cSrcweir 
ReCalculateTotalCacheSize(void)406cdf0e10cSrcweir void BitmapCache::ReCalculateTotalCacheSize (void)
407cdf0e10cSrcweir {
408cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
409cdf0e10cSrcweir 
410cdf0e10cSrcweir     mnNormalCacheSize = 0;
411cdf0e10cSrcweir     mnPreciousCacheSize = 0;
412cdf0e10cSrcweir     CacheBitmapContainer::iterator iEntry;
413cdf0e10cSrcweir     for (iEntry=mpBitmapContainer->begin(); iEntry!=mpBitmapContainer->end();  ++iEntry)
414cdf0e10cSrcweir     {
415cdf0e10cSrcweir         if (iEntry->second.IsPrecious())
416cdf0e10cSrcweir             mnPreciousCacheSize += iEntry->second.GetMemorySize();
417cdf0e10cSrcweir         else
418cdf0e10cSrcweir             mnNormalCacheSize += iEntry->second.GetMemorySize();
419cdf0e10cSrcweir     }
420cdf0e10cSrcweir     mbIsFull = (mnNormalCacheSize  >= mnMaximalNormalCacheSize);
421cdf0e10cSrcweir 
422cdf0e10cSrcweir #ifdef VERBOSE
423cdf0e10cSrcweir     OSL_TRACE("cache size is %d/%d", mnNormalCacheSize, mnPreciousCacheSize);
424cdf0e10cSrcweir #endif
425cdf0e10cSrcweir }
426cdf0e10cSrcweir 
427cdf0e10cSrcweir 
428cdf0e10cSrcweir 
429cdf0e10cSrcweir 
Recycle(const BitmapCache & rCache)430cdf0e10cSrcweir void BitmapCache::Recycle (const BitmapCache& rCache)
431cdf0e10cSrcweir {
432cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
433cdf0e10cSrcweir 
434cdf0e10cSrcweir     CacheBitmapContainer::const_iterator iOtherEntry;
435cdf0e10cSrcweir     for (iOtherEntry=rCache.mpBitmapContainer->begin();
436cdf0e10cSrcweir          iOtherEntry!=rCache.mpBitmapContainer->end();
437cdf0e10cSrcweir          ++iOtherEntry)
438cdf0e10cSrcweir     {
439cdf0e10cSrcweir         CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(iOtherEntry->first));
440cdf0e10cSrcweir         if (iEntry == mpBitmapContainer->end())
441cdf0e10cSrcweir         {
442cdf0e10cSrcweir             iEntry = mpBitmapContainer->insert(CacheBitmapContainer::value_type (
443cdf0e10cSrcweir                 iOtherEntry->first,
444cdf0e10cSrcweir                 CacheEntry(mnCurrentAccessTime++, true))
445cdf0e10cSrcweir                 ).first;
446cdf0e10cSrcweir             UpdateCacheSize(iEntry->second, ADD);
447cdf0e10cSrcweir         }
448cdf0e10cSrcweir         if (iEntry != mpBitmapContainer->end())
449cdf0e10cSrcweir         {
450cdf0e10cSrcweir             UpdateCacheSize(iEntry->second, REMOVE);
451cdf0e10cSrcweir             iEntry->second.Recycle(iOtherEntry->second);
452cdf0e10cSrcweir             UpdateCacheSize(iEntry->second, ADD);
453cdf0e10cSrcweir         }
454cdf0e10cSrcweir     }
455cdf0e10cSrcweir }
456cdf0e10cSrcweir 
457cdf0e10cSrcweir 
458cdf0e10cSrcweir 
459cdf0e10cSrcweir 
GetCacheIndex(bool bIncludePrecious,bool bIncludeNoPreview) const460cdf0e10cSrcweir ::std::auto_ptr<BitmapCache::CacheIndex> BitmapCache::GetCacheIndex (
461cdf0e10cSrcweir     bool bIncludePrecious,
462cdf0e10cSrcweir     bool bIncludeNoPreview) const
463cdf0e10cSrcweir {
464cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
465cdf0e10cSrcweir 
466cdf0e10cSrcweir     // Create a copy of the bitmap container.
467cdf0e10cSrcweir     SortableBitmapContainer aSortedContainer;
468cdf0e10cSrcweir     aSortedContainer.reserve(mpBitmapContainer->size());
469cdf0e10cSrcweir 
470cdf0e10cSrcweir     // Copy the relevant entries.
471cdf0e10cSrcweir     CacheBitmapContainer::iterator iEntry;
472cdf0e10cSrcweir     for (iEntry=mpBitmapContainer->begin(); iEntry!=mpBitmapContainer->end(); ++iEntry)
473cdf0e10cSrcweir     {
474cdf0e10cSrcweir         if ( ! bIncludePrecious && iEntry->second.IsPrecious())
475cdf0e10cSrcweir             continue;
476cdf0e10cSrcweir 
477cdf0e10cSrcweir         if ( ! bIncludeNoPreview && ! iEntry->second.HasPreview())
478cdf0e10cSrcweir             continue;
479cdf0e10cSrcweir 
480cdf0e10cSrcweir         aSortedContainer.push_back(SortableBitmapContainer::value_type(
481cdf0e10cSrcweir             iEntry->first,iEntry->second));
482cdf0e10cSrcweir     }
483cdf0e10cSrcweir 
484cdf0e10cSrcweir     // Sort the remaining entries.
485cdf0e10cSrcweir     ::std::sort(aSortedContainer.begin(), aSortedContainer.end(), AccessTimeComparator());
486cdf0e10cSrcweir 
487cdf0e10cSrcweir     // Return a list with the keys of the sorted entries.
488cdf0e10cSrcweir     ::std::auto_ptr<CacheIndex> pIndex(new CacheIndex());
489cdf0e10cSrcweir     SortableBitmapContainer::iterator iIndexEntry;
490cdf0e10cSrcweir     pIndex->reserve(aSortedContainer.size());
491cdf0e10cSrcweir     for (iIndexEntry=aSortedContainer.begin(); iIndexEntry!=aSortedContainer.end(); ++iIndexEntry)
492cdf0e10cSrcweir         pIndex->push_back(iIndexEntry->first);
493cdf0e10cSrcweir     return pIndex;
494cdf0e10cSrcweir }
495cdf0e10cSrcweir 
496cdf0e10cSrcweir 
497cdf0e10cSrcweir 
498cdf0e10cSrcweir 
Compress(const CacheKey & rKey,const::boost::shared_ptr<BitmapCompressor> & rpCompressor)499cdf0e10cSrcweir void BitmapCache::Compress (
500cdf0e10cSrcweir     const CacheKey& rKey,
501cdf0e10cSrcweir     const ::boost::shared_ptr<BitmapCompressor>& rpCompressor)
502cdf0e10cSrcweir {
503cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
504cdf0e10cSrcweir 
505cdf0e10cSrcweir     CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey));
506cdf0e10cSrcweir     if (iEntry != mpBitmapContainer->end() && iEntry->second.HasPreview())
507cdf0e10cSrcweir     {
508cdf0e10cSrcweir         UpdateCacheSize(iEntry->second, REMOVE);
509cdf0e10cSrcweir         iEntry->second.Compress(rpCompressor);
510cdf0e10cSrcweir         UpdateCacheSize(iEntry->second, ADD);
511cdf0e10cSrcweir     }
512cdf0e10cSrcweir }
513cdf0e10cSrcweir 
514cdf0e10cSrcweir 
515cdf0e10cSrcweir 
516cdf0e10cSrcweir 
UpdateCacheSize(const CacheEntry & rEntry,CacheOperation eOperation)517cdf0e10cSrcweir void BitmapCache::UpdateCacheSize (const CacheEntry& rEntry, CacheOperation eOperation)
518cdf0e10cSrcweir {
519cdf0e10cSrcweir     sal_Int32 nEntrySize (rEntry.GetMemorySize());
520cdf0e10cSrcweir     sal_Int32& rCacheSize (rEntry.IsPrecious() ? mnPreciousCacheSize : mnNormalCacheSize);
521cdf0e10cSrcweir     switch (eOperation)
522cdf0e10cSrcweir     {
523cdf0e10cSrcweir         case ADD:
524cdf0e10cSrcweir             rCacheSize += nEntrySize;
525cdf0e10cSrcweir             if ( ! rEntry.IsPrecious() && mnNormalCacheSize>mnMaximalNormalCacheSize)
526cdf0e10cSrcweir             {
527cdf0e10cSrcweir                 mbIsFull = true;
528cdf0e10cSrcweir #ifdef VERBOSE
529cdf0e10cSrcweir                 OSL_TRACE("cache size is %d > %d", mnNormalCacheSize,mnMaximalNormalCacheSize);
530cdf0e10cSrcweir #endif
531cdf0e10cSrcweir                 mpCacheCompactor->RequestCompaction();
532cdf0e10cSrcweir             }
533cdf0e10cSrcweir             break;
534cdf0e10cSrcweir 
535cdf0e10cSrcweir         case REMOVE:
536cdf0e10cSrcweir             rCacheSize -= nEntrySize;
537cdf0e10cSrcweir             if (mnNormalCacheSize < mnMaximalNormalCacheSize)
538cdf0e10cSrcweir                 mbIsFull = false;
539cdf0e10cSrcweir             break;
540cdf0e10cSrcweir 
541cdf0e10cSrcweir         default:
542cdf0e10cSrcweir             OSL_ASSERT(false);
543cdf0e10cSrcweir             break;
544cdf0e10cSrcweir     }
545cdf0e10cSrcweir }
546cdf0e10cSrcweir 
547cdf0e10cSrcweir 
548cdf0e10cSrcweir 
549cdf0e10cSrcweir 
550cdf0e10cSrcweir //===== CacheEntry ============================================================
551cdf0e10cSrcweir 
CacheEntry(sal_Int32 nLastAccessTime,bool bIsPrecious)552cdf0e10cSrcweir BitmapCache::CacheEntry::CacheEntry(
553cdf0e10cSrcweir     sal_Int32 nLastAccessTime,
554cdf0e10cSrcweir     bool bIsPrecious)
555cdf0e10cSrcweir     : maPreview(),
556cdf0e10cSrcweir       maMarkedPreview(),
557cdf0e10cSrcweir       mbIsUpToDate(true),
558cdf0e10cSrcweir       mnLastAccessTime(nLastAccessTime),
559cdf0e10cSrcweir       mbIsPrecious(bIsPrecious)
560cdf0e10cSrcweir {
561cdf0e10cSrcweir }
562cdf0e10cSrcweir 
563cdf0e10cSrcweir 
564cdf0e10cSrcweir 
565cdf0e10cSrcweir 
CacheEntry(const Bitmap & rPreview,sal_Int32 nLastAccessTime,bool bIsPrecious)566cdf0e10cSrcweir BitmapCache::CacheEntry::CacheEntry(
567cdf0e10cSrcweir     const Bitmap& rPreview,
568cdf0e10cSrcweir     sal_Int32 nLastAccessTime,
569cdf0e10cSrcweir     bool bIsPrecious)
570cdf0e10cSrcweir     : maPreview(rPreview),
571cdf0e10cSrcweir       maMarkedPreview(),
572cdf0e10cSrcweir       mbIsUpToDate(true),
573cdf0e10cSrcweir       mnLastAccessTime(nLastAccessTime),
574cdf0e10cSrcweir       mbIsPrecious(bIsPrecious)
575cdf0e10cSrcweir {
576cdf0e10cSrcweir }
577cdf0e10cSrcweir 
578cdf0e10cSrcweir 
579cdf0e10cSrcweir 
580cdf0e10cSrcweir 
Recycle(const CacheEntry & rEntry)581cdf0e10cSrcweir inline void BitmapCache::CacheEntry::Recycle (const CacheEntry& rEntry)
582cdf0e10cSrcweir {
583cdf0e10cSrcweir     if ((rEntry.HasPreview() || rEntry.HasLosslessReplacement())
584cdf0e10cSrcweir         && ! (HasPreview() || HasLosslessReplacement()))
585cdf0e10cSrcweir     {
586cdf0e10cSrcweir         maPreview = rEntry.maPreview;
587cdf0e10cSrcweir         maMarkedPreview = rEntry.maMarkedPreview;
588cdf0e10cSrcweir         mpReplacement = rEntry.mpReplacement;
589cdf0e10cSrcweir         mpCompressor = rEntry.mpCompressor;
590cdf0e10cSrcweir         mnLastAccessTime = rEntry.mnLastAccessTime;
591cdf0e10cSrcweir         mbIsUpToDate = rEntry.mbIsUpToDate;
592cdf0e10cSrcweir     }
593cdf0e10cSrcweir }
594cdf0e10cSrcweir 
595cdf0e10cSrcweir 
596cdf0e10cSrcweir 
597cdf0e10cSrcweir 
GetMemorySize(void) const598cdf0e10cSrcweir inline sal_Int32 BitmapCache::CacheEntry::GetMemorySize (void) const
599cdf0e10cSrcweir {
600cdf0e10cSrcweir     sal_Int32 nSize (0);
601cdf0e10cSrcweir     nSize += maPreview.GetSizeBytes();
602cdf0e10cSrcweir     nSize += maMarkedPreview.GetSizeBytes();
603cdf0e10cSrcweir     if (mpReplacement.get() != NULL)
604cdf0e10cSrcweir         nSize += mpReplacement->GetMemorySize();
605cdf0e10cSrcweir     return nSize;
606cdf0e10cSrcweir }
607cdf0e10cSrcweir 
608cdf0e10cSrcweir 
609cdf0e10cSrcweir 
610cdf0e10cSrcweir 
Compress(const::boost::shared_ptr<BitmapCompressor> & rpCompressor)611cdf0e10cSrcweir void BitmapCache::CacheEntry::Compress (const ::boost::shared_ptr<BitmapCompressor>& rpCompressor)
612cdf0e10cSrcweir {
613cdf0e10cSrcweir     if ( ! maPreview.IsEmpty())
614cdf0e10cSrcweir     {
615cdf0e10cSrcweir         if (mpReplacement.get() == NULL)
616cdf0e10cSrcweir         {
617cdf0e10cSrcweir             mpReplacement = rpCompressor->Compress(maPreview);
618cdf0e10cSrcweir 
619cdf0e10cSrcweir #ifdef VERBOSE
620cdf0e10cSrcweir             sal_uInt32 nOldSize (maPreview.GetSizeBytes());
621cdf0e10cSrcweir             sal_uInt32 nNewSize (mpReplacement.get()!=NULL ? mpReplacement->GetMemorySize() : 0);
622cdf0e10cSrcweir             if (nOldSize == 0)
623cdf0e10cSrcweir                 nOldSize = 1;
624cdf0e10cSrcweir             sal_Int32 nRatio (100L * nNewSize / nOldSize);
625cdf0e10cSrcweir             OSL_TRACE("compressing bitmap for %x from %d to %d bytes (%d%%)",
626cdf0e10cSrcweir                 this,
627cdf0e10cSrcweir                 nOldSize,
628cdf0e10cSrcweir                 nNewSize,
629cdf0e10cSrcweir                 nRatio);
630cdf0e10cSrcweir #endif
631cdf0e10cSrcweir 
632cdf0e10cSrcweir             mpCompressor = rpCompressor;
633cdf0e10cSrcweir         }
634cdf0e10cSrcweir 
635cdf0e10cSrcweir         maPreview.SetEmpty();
636cdf0e10cSrcweir         maMarkedPreview.SetEmpty();
637cdf0e10cSrcweir     }
638cdf0e10cSrcweir }
639cdf0e10cSrcweir 
640cdf0e10cSrcweir 
641cdf0e10cSrcweir 
642cdf0e10cSrcweir 
Decompress(void)643cdf0e10cSrcweir inline void BitmapCache::CacheEntry::Decompress (void)
644cdf0e10cSrcweir {
645cdf0e10cSrcweir     if (mpReplacement.get()!=NULL && mpCompressor.get()!=NULL && maPreview.IsEmpty())
646cdf0e10cSrcweir     {
647cdf0e10cSrcweir         maPreview = mpCompressor->Decompress(*mpReplacement);
648cdf0e10cSrcweir         maMarkedPreview.SetEmpty();
649cdf0e10cSrcweir         if ( ! mpCompressor->IsLossless())
650cdf0e10cSrcweir             mbIsUpToDate = false;
651cdf0e10cSrcweir     }
652cdf0e10cSrcweir }
653cdf0e10cSrcweir 
654cdf0e10cSrcweir 
655cdf0e10cSrcweir 
SetPreview(const Bitmap & rPreview)656cdf0e10cSrcweir inline void BitmapCache::CacheEntry::SetPreview (const Bitmap& rPreview)
657cdf0e10cSrcweir {
658cdf0e10cSrcweir     maPreview = rPreview;
659cdf0e10cSrcweir     maMarkedPreview.SetEmpty();
660cdf0e10cSrcweir     mpReplacement.reset();
661cdf0e10cSrcweir     mpCompressor.reset();
662cdf0e10cSrcweir }
663cdf0e10cSrcweir 
664cdf0e10cSrcweir 
665cdf0e10cSrcweir 
666cdf0e10cSrcweir 
HasPreview(void) const667cdf0e10cSrcweir bool BitmapCache::CacheEntry::HasPreview (void) const
668cdf0e10cSrcweir {
669cdf0e10cSrcweir     return ! maPreview.IsEmpty();
670cdf0e10cSrcweir }
671cdf0e10cSrcweir 
672cdf0e10cSrcweir 
673cdf0e10cSrcweir 
674cdf0e10cSrcweir 
SetMarkedPreview(const Bitmap & rMarkedPreview)675cdf0e10cSrcweir inline void BitmapCache::CacheEntry::SetMarkedPreview (const Bitmap& rMarkedPreview)
676cdf0e10cSrcweir {
677cdf0e10cSrcweir     maMarkedPreview = rMarkedPreview;
678cdf0e10cSrcweir }
679cdf0e10cSrcweir 
680cdf0e10cSrcweir 
681cdf0e10cSrcweir 
682cdf0e10cSrcweir 
HasMarkedPreview(void) const683cdf0e10cSrcweir bool BitmapCache::CacheEntry::HasMarkedPreview (void) const
684cdf0e10cSrcweir {
685cdf0e10cSrcweir     return ! maMarkedPreview.IsEmpty();
686cdf0e10cSrcweir }
687cdf0e10cSrcweir 
688cdf0e10cSrcweir 
689cdf0e10cSrcweir 
690cdf0e10cSrcweir 
HasLosslessReplacement(void) const691cdf0e10cSrcweir inline bool BitmapCache::CacheEntry::HasLosslessReplacement (void) const
692cdf0e10cSrcweir {
693cdf0e10cSrcweir     return mpReplacement.get()!=NULL
694cdf0e10cSrcweir         && mpCompressor.get()!=NULL
695cdf0e10cSrcweir         && mpCompressor->IsLossless();
696cdf0e10cSrcweir }
697cdf0e10cSrcweir 
698cdf0e10cSrcweir 
699cdf0e10cSrcweir } } } // end of namespace ::sd::slidesorter::cache
700