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