Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 :
21 : #include "SlsGenericPageCache.hxx"
22 :
23 : #include "SlsQueueProcessor.hxx"
24 : #include "SlsRequestPriorityClass.hxx"
25 : #include "SlsRequestFactory.hxx"
26 : #include "cache/SlsPageCacheManager.hxx"
27 : #include "model/SlideSorterModel.hxx"
28 : #include "model/SlsPageDescriptor.hxx"
29 : #include "controller/SlideSorterController.hxx"
30 :
31 :
32 : namespace sd { namespace slidesorter { namespace cache {
33 :
34 0 : GenericPageCache::GenericPageCache (
35 : const Size& rPreviewSize,
36 : const bool bDoSuperSampling,
37 : const SharedCacheContext& rpCacheContext)
38 : : mpBitmapCache(),
39 : maRequestQueue(rpCacheContext),
40 : mpQueueProcessor(),
41 : mpCacheContext(rpCacheContext),
42 : maPreviewSize(rPreviewSize),
43 0 : mbDoSuperSampling(bDoSuperSampling)
44 : {
45 : // A large size may indicate an error of the caller. After all we
46 : // are creating previews.
47 : DBG_ASSERT (maPreviewSize.Width()<1000 && maPreviewSize.Height()<1000,
48 : "GenericPageCache<>::GetPreviewBitmap(): bitmap requested with large width. "
49 : "This may indicate an error.");
50 0 : }
51 :
52 :
53 :
54 :
55 0 : GenericPageCache::~GenericPageCache (void)
56 : {
57 0 : if (mpQueueProcessor.get() != NULL)
58 0 : mpQueueProcessor->Stop();
59 0 : maRequestQueue.Clear();
60 0 : if (mpQueueProcessor.get() != NULL)
61 0 : mpQueueProcessor->Terminate();
62 0 : mpQueueProcessor.reset();
63 :
64 0 : if (mpBitmapCache.get() != NULL)
65 0 : PageCacheManager::Instance()->ReleaseCache(mpBitmapCache);
66 0 : mpBitmapCache.reset();
67 0 : }
68 :
69 :
70 :
71 :
72 0 : void GenericPageCache::ProvideCacheAndProcessor (void)
73 : {
74 0 : if (mpBitmapCache.get() == NULL)
75 : mpBitmapCache = PageCacheManager::Instance()->GetCache(
76 0 : mpCacheContext->GetModel(),
77 0 : maPreviewSize);
78 :
79 0 : if (mpQueueProcessor.get() == NULL)
80 : mpQueueProcessor.reset(new QueueProcessor(
81 : maRequestQueue,
82 : mpBitmapCache,
83 : maPreviewSize,
84 : mbDoSuperSampling,
85 0 : mpCacheContext));
86 0 : }
87 :
88 :
89 :
90 :
91 0 : void GenericPageCache::ChangePreviewSize (
92 : const Size& rPreviewSize,
93 : const bool bDoSuperSampling)
94 : {
95 0 : if (rPreviewSize!=maPreviewSize || bDoSuperSampling!=mbDoSuperSampling)
96 : {
97 : // A large size may indicate an error of the caller. After all we
98 : // are creating previews.
99 : DBG_ASSERT (maPreviewSize.Width()<1000 && maPreviewSize.Height()<1000,
100 : "GenericPageCache<>::GetPreviewBitmap(): bitmap requested with large width. "
101 : "This may indicate an error.");
102 :
103 0 : if (mpBitmapCache.get() != NULL)
104 : {
105 : mpBitmapCache = PageCacheManager::Instance()->ChangeSize(
106 0 : mpBitmapCache, maPreviewSize, rPreviewSize);
107 0 : if (mpQueueProcessor.get() != NULL)
108 : {
109 0 : mpQueueProcessor->SetPreviewSize(rPreviewSize, bDoSuperSampling);
110 0 : mpQueueProcessor->SetBitmapCache(mpBitmapCache);
111 : }
112 : }
113 0 : maPreviewSize = rPreviewSize;
114 0 : mbDoSuperSampling = bDoSuperSampling;
115 : }
116 0 : }
117 :
118 :
119 :
120 :
121 0 : Bitmap GenericPageCache::GetPreviewBitmap (
122 : const CacheKey aKey,
123 : const bool bResize)
124 : {
125 : OSL_ASSERT(aKey != NULL);
126 :
127 0 : Bitmap aPreview;
128 0 : bool bMayBeUpToDate = true;
129 0 : ProvideCacheAndProcessor();
130 0 : const SdrPage* pPage = mpCacheContext->GetPage(aKey);
131 0 : if (mpBitmapCache->HasBitmap(pPage))
132 : {
133 0 : aPreview = mpBitmapCache->GetBitmap(pPage);
134 0 : const Size aBitmapSize (aPreview.GetSizePixel());
135 0 : if (aBitmapSize != maPreviewSize)
136 : {
137 : // Scale the bitmap to the desired size when that is possible,
138 : // i.e. the bitmap is not empty.
139 0 : if (bResize && aBitmapSize.Width()>0 && aBitmapSize.Height()>0)
140 : {
141 0 : aPreview.Scale(maPreviewSize);
142 : }
143 0 : bMayBeUpToDate = false;
144 : }
145 : else
146 0 : bMayBeUpToDate = true;
147 : }
148 : else
149 0 : bMayBeUpToDate = false;
150 :
151 : // Request the creation of a correctly sized preview bitmap. We do this
152 : // even when the size of the bitmap in the cache is correct because its
153 : // content may be not up-to-date anymore.
154 0 : RequestPreviewBitmap(aKey, bMayBeUpToDate);
155 :
156 0 : return aPreview;
157 : }
158 :
159 :
160 :
161 :
162 0 : Bitmap GenericPageCache::GetMarkedPreviewBitmap (
163 : const CacheKey aKey,
164 : const bool bResize)
165 : {
166 : OSL_ASSERT(aKey != NULL);
167 :
168 0 : ProvideCacheAndProcessor();
169 0 : const SdrPage* pPage = mpCacheContext->GetPage(aKey);
170 0 : Bitmap aMarkedPreview (mpBitmapCache->GetMarkedBitmap(pPage));
171 0 : const Size aBitmapSize (aMarkedPreview.GetSizePixel());
172 0 : if (bResize && aBitmapSize != maPreviewSize)
173 : {
174 : // Scale the bitmap to the desired size when that is possible,
175 : // i.e. the bitmap is not empty.
176 0 : if (aBitmapSize.Width()>0 && aBitmapSize.Height()>0)
177 : {
178 0 : aMarkedPreview.Scale(maPreviewSize);
179 : }
180 : }
181 :
182 0 : return aMarkedPreview;
183 : }
184 :
185 :
186 :
187 :
188 0 : void GenericPageCache::SetMarkedPreviewBitmap (
189 : const CacheKey aKey,
190 : const Bitmap& rMarkedBitmap)
191 : {
192 : OSL_ASSERT(aKey != NULL);
193 :
194 0 : ProvideCacheAndProcessor();
195 0 : const SdrPage* pPage = mpCacheContext->GetPage(aKey);
196 0 : mpBitmapCache->SetMarkedBitmap(pPage, rMarkedBitmap);
197 0 : }
198 :
199 :
200 :
201 :
202 0 : void GenericPageCache::RequestPreviewBitmap (
203 : const CacheKey aKey,
204 : const bool bMayBeUpToDate)
205 : {
206 : OSL_ASSERT(aKey != NULL);
207 :
208 0 : const SdrPage* pPage = mpCacheContext->GetPage(aKey);
209 :
210 0 : ProvideCacheAndProcessor();
211 :
212 : // Determine if the available bitmap is up to date.
213 0 : bool bIsUpToDate = false;
214 0 : if (bMayBeUpToDate)
215 0 : bIsUpToDate = mpBitmapCache->BitmapIsUpToDate (pPage);
216 0 : if (bIsUpToDate)
217 : {
218 0 : const Bitmap aPreview (mpBitmapCache->GetBitmap(pPage));
219 0 : if (aPreview.IsEmpty() || aPreview.GetSizePixel()!=maPreviewSize)
220 0 : bIsUpToDate = false;
221 : }
222 :
223 0 : if ( ! bIsUpToDate)
224 : {
225 : // No, the bitmap is not up-to-date. Request a new one.
226 0 : RequestPriorityClass ePriorityClass (NOT_VISIBLE);
227 0 : if (mpCacheContext->IsVisible(aKey))
228 : {
229 0 : if (mpBitmapCache->HasBitmap(pPage))
230 0 : ePriorityClass = VISIBLE_OUTDATED_PREVIEW;
231 : else
232 0 : ePriorityClass = VISIBLE_NO_PREVIEW;
233 : }
234 0 : maRequestQueue.AddRequest(aKey, ePriorityClass);
235 0 : mpQueueProcessor->Start(ePriorityClass);
236 : }
237 0 : }
238 :
239 :
240 :
241 :
242 0 : bool GenericPageCache::InvalidatePreviewBitmap (const CacheKey aKey)
243 : {
244 : // Invalidate the page in all caches that reference it, not just this one.
245 : ::boost::shared_ptr<cache::PageCacheManager> pCacheManager (
246 0 : cache::PageCacheManager::Instance());
247 0 : if (pCacheManager)
248 : return pCacheManager->InvalidatePreviewBitmap(
249 0 : mpCacheContext->GetModel(),
250 0 : aKey);
251 0 : else if (mpBitmapCache.get() != NULL)
252 0 : return mpBitmapCache->InvalidateBitmap(mpCacheContext->GetPage(aKey));
253 : else
254 0 : return false;
255 : }
256 :
257 0 : void GenericPageCache::InvalidateCache (const bool bUpdateCache)
258 : {
259 0 : if (mpBitmapCache)
260 : {
261 : // When the cache is being invalidated then it makes no sense to
262 : // continue creating preview bitmaps. However, this may be
263 : // re-started below.
264 0 : mpQueueProcessor->Stop();
265 0 : maRequestQueue.Clear();
266 :
267 : // Mark the previews in the cache as not being up-to-date anymore.
268 : // Depending on the given bUpdateCache flag we start to create new
269 : // preview bitmaps.
270 0 : mpBitmapCache->InvalidateCache();
271 0 : if (bUpdateCache)
272 0 : RequestFactory()(maRequestQueue, mpCacheContext);
273 : }
274 0 : }
275 :
276 :
277 :
278 :
279 0 : void GenericPageCache::SetPreciousFlag (
280 : const CacheKey aKey,
281 : const bool bIsPrecious)
282 : {
283 0 : ProvideCacheAndProcessor();
284 :
285 : // Change the request priority class according to the new precious flag.
286 0 : if (bIsPrecious)
287 : {
288 0 : if (mpBitmapCache->HasBitmap(mpCacheContext->GetPage(aKey)))
289 0 : maRequestQueue.ChangeClass(aKey,VISIBLE_OUTDATED_PREVIEW);
290 : else
291 0 : maRequestQueue.ChangeClass(aKey,VISIBLE_NO_PREVIEW);
292 : }
293 : else
294 : {
295 0 : if (mpBitmapCache->IsFull())
296 : {
297 : // When the bitmap cache is full then requests for slides that
298 : // are not visible are removed.
299 0 : maRequestQueue.RemoveRequest(aKey);
300 : }
301 : else
302 0 : maRequestQueue.ChangeClass(aKey,NOT_VISIBLE);
303 : }
304 :
305 0 : mpBitmapCache->SetPrecious(mpCacheContext->GetPage(aKey), bIsPrecious);
306 0 : }
307 :
308 :
309 :
310 :
311 0 : void GenericPageCache::Pause (void)
312 : {
313 0 : ProvideCacheAndProcessor();
314 0 : if (mpQueueProcessor.get() != NULL)
315 0 : mpQueueProcessor->Pause();
316 0 : }
317 :
318 :
319 :
320 :
321 0 : void GenericPageCache::Resume (void)
322 : {
323 0 : ProvideCacheAndProcessor();
324 0 : if (mpQueueProcessor.get() != NULL)
325 0 : mpQueueProcessor->Resume();
326 0 : }
327 :
328 :
329 :
330 : } } } // end of namespace ::sd::slidesorter::cache
331 :
332 :
333 :
334 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|