1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "SlsGenericPageCache.hxx"
22 #include "SlsQueueProcessor.hxx"
23 #include "SlsRequestPriorityClass.hxx"
24 #include "SlsRequestFactory.hxx"
25 #include "cache/SlsPageCacheManager.hxx"
26 #include "model/SlideSorterModel.hxx"
27 #include "model/SlsPageDescriptor.hxx"
28 #include "controller/SlideSorterController.hxx"
30 namespace sd
{ namespace slidesorter
{ namespace cache
{
32 GenericPageCache::GenericPageCache (
33 const Size
& rPreviewSize
,
34 const bool bDoSuperSampling
,
35 const SharedCacheContext
& rpCacheContext
)
37 maRequestQueue(rpCacheContext
),
39 mpCacheContext(rpCacheContext
),
40 maPreviewSize(rPreviewSize
),
41 mbDoSuperSampling(bDoSuperSampling
)
43 // A large size may indicate an error of the caller. After all we
44 // are creating previews.
45 DBG_ASSERT (maPreviewSize
.Width()<1000 && maPreviewSize
.Height()<1000,
46 "GenericPageCache<>::GetPreviewBitmap(): bitmap requested with large width. "
47 "This may indicate an error.");
50 GenericPageCache::~GenericPageCache()
52 if (mpQueueProcessor
.get() != NULL
)
53 mpQueueProcessor
->Stop();
54 maRequestQueue
.Clear();
55 mpQueueProcessor
.reset();
57 if (mpBitmapCache
.get() != NULL
)
58 PageCacheManager::Instance()->ReleaseCache(mpBitmapCache
);
59 mpBitmapCache
.reset();
62 void GenericPageCache::ProvideCacheAndProcessor()
64 if (mpBitmapCache
.get() == NULL
)
65 mpBitmapCache
= PageCacheManager::Instance()->GetCache(
66 mpCacheContext
->GetModel(),
69 if (mpQueueProcessor
.get() == NULL
)
70 mpQueueProcessor
.reset(new QueueProcessor(
78 void GenericPageCache::ChangePreviewSize (
79 const Size
& rPreviewSize
,
80 const bool bDoSuperSampling
)
82 if (rPreviewSize
!=maPreviewSize
|| bDoSuperSampling
!=mbDoSuperSampling
)
84 // A large size may indicate an error of the caller. After all we
85 // are creating previews.
86 DBG_ASSERT (maPreviewSize
.Width()<1000 && maPreviewSize
.Height()<1000,
87 "GenericPageCache<>::GetPreviewBitmap(): bitmap requested with large width. "
88 "This may indicate an error.");
90 if (mpBitmapCache
.get() != NULL
)
92 mpBitmapCache
= PageCacheManager::Instance()->ChangeSize(
93 mpBitmapCache
, maPreviewSize
, rPreviewSize
);
94 if (mpQueueProcessor
.get() != NULL
)
96 mpQueueProcessor
->SetPreviewSize(rPreviewSize
, bDoSuperSampling
);
97 mpQueueProcessor
->SetBitmapCache(mpBitmapCache
);
100 maPreviewSize
= rPreviewSize
;
101 mbDoSuperSampling
= bDoSuperSampling
;
105 Bitmap
GenericPageCache::GetPreviewBitmap (
109 OSL_ASSERT(aKey
!= NULL
);
112 bool bMayBeUpToDate
= true;
113 ProvideCacheAndProcessor();
114 const SdrPage
* pPage
= mpCacheContext
->GetPage(aKey
);
115 if (mpBitmapCache
->HasBitmap(pPage
))
117 aPreview
= mpBitmapCache
->GetBitmap(pPage
);
118 const Size
aBitmapSize (aPreview
.GetSizePixel());
119 if (aBitmapSize
!= maPreviewSize
)
121 // Scale the bitmap to the desired size when that is possible,
122 // i.e. the bitmap is not empty.
123 if (bResize
&& aBitmapSize
.Width()>0 && aBitmapSize
.Height()>0)
125 aPreview
.Scale(maPreviewSize
);
127 bMayBeUpToDate
= false;
130 bMayBeUpToDate
= true;
133 bMayBeUpToDate
= false;
135 // Request the creation of a correctly sized preview bitmap. We do this
136 // even when the size of the bitmap in the cache is correct because its
137 // content may be not up-to-date anymore.
138 RequestPreviewBitmap(aKey
, bMayBeUpToDate
);
143 Bitmap
GenericPageCache::GetMarkedPreviewBitmap (
147 OSL_ASSERT(aKey
!= NULL
);
149 ProvideCacheAndProcessor();
150 const SdrPage
* pPage
= mpCacheContext
->GetPage(aKey
);
151 Bitmap
aMarkedPreview (mpBitmapCache
->GetMarkedBitmap(pPage
));
152 const Size
aBitmapSize (aMarkedPreview
.GetSizePixel());
153 if (bResize
&& aBitmapSize
!= maPreviewSize
)
155 // Scale the bitmap to the desired size when that is possible,
156 // i.e. the bitmap is not empty.
157 if (aBitmapSize
.Width()>0 && aBitmapSize
.Height()>0)
159 aMarkedPreview
.Scale(maPreviewSize
);
163 return aMarkedPreview
;
166 void GenericPageCache::SetMarkedPreviewBitmap (
168 const Bitmap
& rMarkedBitmap
)
170 OSL_ASSERT(aKey
!= NULL
);
172 ProvideCacheAndProcessor();
173 const SdrPage
* pPage
= mpCacheContext
->GetPage(aKey
);
174 mpBitmapCache
->SetMarkedBitmap(pPage
, rMarkedBitmap
);
177 void GenericPageCache::RequestPreviewBitmap (
179 const bool bMayBeUpToDate
)
181 OSL_ASSERT(aKey
!= NULL
);
183 const SdrPage
* pPage
= mpCacheContext
->GetPage(aKey
);
185 ProvideCacheAndProcessor();
187 // Determine if the available bitmap is up to date.
188 bool bIsUpToDate
= false;
190 bIsUpToDate
= mpBitmapCache
->BitmapIsUpToDate (pPage
);
193 const Bitmap
aPreview (mpBitmapCache
->GetBitmap(pPage
));
194 if (aPreview
.IsEmpty() || aPreview
.GetSizePixel()!=maPreviewSize
)
200 // No, the bitmap is not up-to-date. Request a new one.
201 RequestPriorityClass
ePriorityClass (NOT_VISIBLE
);
202 if (mpCacheContext
->IsVisible(aKey
))
204 if (mpBitmapCache
->HasBitmap(pPage
))
205 ePriorityClass
= VISIBLE_OUTDATED_PREVIEW
;
207 ePriorityClass
= VISIBLE_NO_PREVIEW
;
209 maRequestQueue
.AddRequest(aKey
, ePriorityClass
);
210 mpQueueProcessor
->Start(ePriorityClass
);
214 bool GenericPageCache::InvalidatePreviewBitmap (const CacheKey aKey
)
216 // Invalidate the page in all caches that reference it, not just this one.
217 ::boost::shared_ptr
<cache::PageCacheManager
> pCacheManager (
218 cache::PageCacheManager::Instance());
220 return pCacheManager
->InvalidatePreviewBitmap(
221 mpCacheContext
->GetModel(),
223 else if (mpBitmapCache
.get() != NULL
)
224 return mpBitmapCache
->InvalidateBitmap(mpCacheContext
->GetPage(aKey
));
229 void GenericPageCache::InvalidateCache (const bool bUpdateCache
)
233 // When the cache is being invalidated then it makes no sense to
234 // continue creating preview bitmaps. However, this may be
236 mpQueueProcessor
->Stop();
237 maRequestQueue
.Clear();
239 // Mark the previews in the cache as not being up-to-date anymore.
240 // Depending on the given bUpdateCache flag we start to create new
242 mpBitmapCache
->InvalidateCache();
244 RequestFactory()(maRequestQueue
, mpCacheContext
);
248 void GenericPageCache::SetPreciousFlag (
250 const bool bIsPrecious
)
252 ProvideCacheAndProcessor();
254 // Change the request priority class according to the new precious flag.
257 if (mpBitmapCache
->HasBitmap(mpCacheContext
->GetPage(aKey
)))
258 maRequestQueue
.ChangeClass(aKey
,VISIBLE_OUTDATED_PREVIEW
);
260 maRequestQueue
.ChangeClass(aKey
,VISIBLE_NO_PREVIEW
);
264 if (mpBitmapCache
->IsFull())
266 // When the bitmap cache is full then requests for slides that
267 // are not visible are removed.
268 maRequestQueue
.RemoveRequest(aKey
);
271 maRequestQueue
.ChangeClass(aKey
,NOT_VISIBLE
);
274 mpBitmapCache
->SetPrecious(mpCacheContext
->GetPage(aKey
), bIsPrecious
);
277 void GenericPageCache::Pause()
279 ProvideCacheAndProcessor();
280 if (mpQueueProcessor
.get() != NULL
)
281 mpQueueProcessor
->Pause();
284 void GenericPageCache::Resume()
286 ProvideCacheAndProcessor();
287 if (mpQueueProcessor
.get() != NULL
)
288 mpQueueProcessor
->Resume();
291 } } } // end of namespace ::sd::slidesorter::cache
293 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */