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