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