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