15b190011SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
35b190011SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
45b190011SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
55b190011SAndrew Rist  * distributed with this work for additional information
65b190011SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
75b190011SAndrew Rist  * to you under the Apache License, Version 2.0 (the
85b190011SAndrew Rist  * "License"); you may not use this file except in compliance
95b190011SAndrew Rist  * with the License.  You may obtain a copy of the License at
105b190011SAndrew Rist  *
115b190011SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
125b190011SAndrew Rist  *
135b190011SAndrew Rist  * Unless required by applicable law or agreed to in writing,
145b190011SAndrew Rist  * software distributed under the License is distributed on an
155b190011SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
165b190011SAndrew Rist  * KIND, either express or implied.  See the License for the
175b190011SAndrew Rist  * specific language governing permissions and limitations
185b190011SAndrew Rist  * under the License.
195b190011SAndrew Rist  *
205b190011SAndrew Rist  *************************************************************/
215b190011SAndrew Rist 
225b190011SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include "precompiled_sd.hxx"
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include "SlsGenericPageCache.hxx"
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include "SlsQueueProcessor.hxx"
29cdf0e10cSrcweir #include "SlsRequestPriorityClass.hxx"
30cdf0e10cSrcweir #include "SlsRequestFactory.hxx"
31cdf0e10cSrcweir #include "cache/SlsPageCacheManager.hxx"
32cdf0e10cSrcweir #include "model/SlideSorterModel.hxx"
33cdf0e10cSrcweir #include "model/SlsPageDescriptor.hxx"
34cdf0e10cSrcweir #include "controller/SlideSorterController.hxx"
35cdf0e10cSrcweir 
36cdf0e10cSrcweir 
37cdf0e10cSrcweir namespace sd { namespace slidesorter { namespace cache {
38cdf0e10cSrcweir 
GenericPageCache(const Size & rPreviewSize,const bool bDoSuperSampling,const SharedCacheContext & rpCacheContext)39cdf0e10cSrcweir GenericPageCache::GenericPageCache (
40cdf0e10cSrcweir     const Size& rPreviewSize,
41cdf0e10cSrcweir     const bool bDoSuperSampling,
42cdf0e10cSrcweir     const SharedCacheContext& rpCacheContext)
43cdf0e10cSrcweir     : mpBitmapCache(),
44cdf0e10cSrcweir       maRequestQueue(rpCacheContext),
45cdf0e10cSrcweir       mpQueueProcessor(),
46cdf0e10cSrcweir       mpCacheContext(rpCacheContext),
47cdf0e10cSrcweir       maPreviewSize(rPreviewSize),
48cdf0e10cSrcweir       mbDoSuperSampling(bDoSuperSampling)
49cdf0e10cSrcweir {
50cdf0e10cSrcweir     // A large size may indicate an error of the caller.  After all we
51cdf0e10cSrcweir     // are creating previews.
52cdf0e10cSrcweir         DBG_ASSERT (maPreviewSize.Width()<1000 && maPreviewSize.Height()<1000,
53cdf0e10cSrcweir         "GenericPageCache<>::GetPreviewBitmap(): bitmap requested with large width. "
54cdf0e10cSrcweir         "This may indicate an error.");
55cdf0e10cSrcweir }
56cdf0e10cSrcweir 
57cdf0e10cSrcweir 
58cdf0e10cSrcweir 
59cdf0e10cSrcweir 
~GenericPageCache(void)60cdf0e10cSrcweir GenericPageCache::~GenericPageCache (void)
61cdf0e10cSrcweir {
62cdf0e10cSrcweir     if (mpQueueProcessor.get() != NULL)
63cdf0e10cSrcweir         mpQueueProcessor->Stop();
64cdf0e10cSrcweir     maRequestQueue.Clear();
65cdf0e10cSrcweir     if (mpQueueProcessor.get() != NULL)
66cdf0e10cSrcweir         mpQueueProcessor->Terminate();
67cdf0e10cSrcweir     mpQueueProcessor.reset();
68cdf0e10cSrcweir 
69cdf0e10cSrcweir     if (mpBitmapCache.get() != NULL)
70cdf0e10cSrcweir         PageCacheManager::Instance()->ReleaseCache(mpBitmapCache);
71cdf0e10cSrcweir     mpBitmapCache.reset();
72cdf0e10cSrcweir }
73cdf0e10cSrcweir 
74cdf0e10cSrcweir 
75cdf0e10cSrcweir 
76cdf0e10cSrcweir 
ProvideCacheAndProcessor(void)77cdf0e10cSrcweir void GenericPageCache::ProvideCacheAndProcessor (void)
78cdf0e10cSrcweir {
79cdf0e10cSrcweir     if (mpBitmapCache.get() == NULL)
80cdf0e10cSrcweir         mpBitmapCache = PageCacheManager::Instance()->GetCache(
81cdf0e10cSrcweir             mpCacheContext->GetModel(),
82cdf0e10cSrcweir             maPreviewSize);
83cdf0e10cSrcweir 
84cdf0e10cSrcweir     if (mpQueueProcessor.get() == NULL)
85cdf0e10cSrcweir         mpQueueProcessor.reset(new QueueProcessor(
86cdf0e10cSrcweir             maRequestQueue,
87cdf0e10cSrcweir             mpBitmapCache,
88cdf0e10cSrcweir             maPreviewSize,
89cdf0e10cSrcweir             mbDoSuperSampling,
90cdf0e10cSrcweir             mpCacheContext));
91cdf0e10cSrcweir }
92cdf0e10cSrcweir 
93cdf0e10cSrcweir 
94cdf0e10cSrcweir 
95cdf0e10cSrcweir 
ChangePreviewSize(const Size & rPreviewSize,const bool bDoSuperSampling)96cdf0e10cSrcweir void GenericPageCache::ChangePreviewSize (
97cdf0e10cSrcweir     const Size& rPreviewSize,
98cdf0e10cSrcweir     const bool bDoSuperSampling)
99cdf0e10cSrcweir {
100cdf0e10cSrcweir     if (rPreviewSize!=maPreviewSize || bDoSuperSampling!=mbDoSuperSampling)
101cdf0e10cSrcweir     {
102cdf0e10cSrcweir         // A large size may indicate an error of the caller.  After all we
103cdf0e10cSrcweir         // are creating previews.
104cdf0e10cSrcweir         DBG_ASSERT (maPreviewSize.Width()<1000 && maPreviewSize.Height()<1000,
105cdf0e10cSrcweir             "GenericPageCache<>::GetPreviewBitmap(): bitmap requested with large width. "
106cdf0e10cSrcweir             "This may indicate an error.");
107cdf0e10cSrcweir 
108cdf0e10cSrcweir         if (mpBitmapCache.get() != NULL)
109cdf0e10cSrcweir         {
110cdf0e10cSrcweir             mpBitmapCache = PageCacheManager::Instance()->ChangeSize(
111cdf0e10cSrcweir                 mpBitmapCache, maPreviewSize, rPreviewSize);
112cdf0e10cSrcweir             if (mpQueueProcessor.get() != NULL)
113cdf0e10cSrcweir             {
114cdf0e10cSrcweir                 mpQueueProcessor->SetPreviewSize(rPreviewSize, bDoSuperSampling);
115cdf0e10cSrcweir                 mpQueueProcessor->SetBitmapCache(mpBitmapCache);
116cdf0e10cSrcweir             }
117cdf0e10cSrcweir         }
118cdf0e10cSrcweir         maPreviewSize = rPreviewSize;
119cdf0e10cSrcweir         mbDoSuperSampling = bDoSuperSampling;
120cdf0e10cSrcweir     }
121cdf0e10cSrcweir }
122cdf0e10cSrcweir 
123cdf0e10cSrcweir 
124cdf0e10cSrcweir 
125cdf0e10cSrcweir 
GetPreviewBitmap(const CacheKey aKey,const bool bResize)126cdf0e10cSrcweir Bitmap GenericPageCache::GetPreviewBitmap (
127cdf0e10cSrcweir     const CacheKey aKey,
128cdf0e10cSrcweir     const bool bResize)
129cdf0e10cSrcweir {
130cdf0e10cSrcweir     OSL_ASSERT(aKey != NULL);
131cdf0e10cSrcweir 
132cdf0e10cSrcweir     Bitmap aPreview;
133cdf0e10cSrcweir     bool bMayBeUpToDate = true;
134cdf0e10cSrcweir     ProvideCacheAndProcessor();
135cdf0e10cSrcweir     const SdrPage* pPage = mpCacheContext->GetPage(aKey);
136cdf0e10cSrcweir     if (mpBitmapCache->HasBitmap(pPage))
137cdf0e10cSrcweir     {
138cdf0e10cSrcweir         aPreview = mpBitmapCache->GetBitmap(pPage);
139cdf0e10cSrcweir         const Size aBitmapSize (aPreview.GetSizePixel());
140cdf0e10cSrcweir         if (aBitmapSize != maPreviewSize)
141cdf0e10cSrcweir         {
142cdf0e10cSrcweir             // Scale the bitmap to the desired size when that is possible,
143cdf0e10cSrcweir             // i.e. the bitmap is not empty.
144cdf0e10cSrcweir             if (bResize && aBitmapSize.Width()>0 && aBitmapSize.Height()>0)
145cdf0e10cSrcweir             {
146*37ab0f2dSArmin Le Grand                 aPreview.Scale(maPreviewSize, BMP_SCALE_FASTESTINTERPOLATE);
147cdf0e10cSrcweir             }
148cdf0e10cSrcweir             bMayBeUpToDate = false;
149cdf0e10cSrcweir         }
150cdf0e10cSrcweir         else
151cdf0e10cSrcweir             bMayBeUpToDate = true;
152cdf0e10cSrcweir     }
153cdf0e10cSrcweir     else
154cdf0e10cSrcweir         bMayBeUpToDate = false;
155cdf0e10cSrcweir 
156cdf0e10cSrcweir     // Request the creation of a correctly sized preview bitmap.  We do this
157cdf0e10cSrcweir     // even when the size of the bitmap in the cache is correct because its
158cdf0e10cSrcweir     // content may be not up-to-date anymore.
159cdf0e10cSrcweir     RequestPreviewBitmap(aKey, bMayBeUpToDate);
160cdf0e10cSrcweir 
161cdf0e10cSrcweir     return aPreview;
162cdf0e10cSrcweir }
163cdf0e10cSrcweir 
164cdf0e10cSrcweir 
165cdf0e10cSrcweir 
166cdf0e10cSrcweir 
GetMarkedPreviewBitmap(const CacheKey aKey,const bool bResize)167cdf0e10cSrcweir Bitmap GenericPageCache::GetMarkedPreviewBitmap (
168cdf0e10cSrcweir     const CacheKey aKey,
169cdf0e10cSrcweir     const bool bResize)
170cdf0e10cSrcweir {
171cdf0e10cSrcweir     OSL_ASSERT(aKey != NULL);
172cdf0e10cSrcweir 
173cdf0e10cSrcweir     ProvideCacheAndProcessor();
174cdf0e10cSrcweir     const SdrPage* pPage = mpCacheContext->GetPage(aKey);
175cdf0e10cSrcweir     Bitmap aMarkedPreview (mpBitmapCache->GetMarkedBitmap(pPage));
176cdf0e10cSrcweir     const Size aBitmapSize (aMarkedPreview.GetSizePixel());
177cdf0e10cSrcweir     if (bResize && aBitmapSize != maPreviewSize)
178cdf0e10cSrcweir     {
179cdf0e10cSrcweir         // Scale the bitmap to the desired size when that is possible,
180cdf0e10cSrcweir         // i.e. the bitmap is not empty.
181cdf0e10cSrcweir         if (aBitmapSize.Width()>0 && aBitmapSize.Height()>0)
182cdf0e10cSrcweir         {
183*37ab0f2dSArmin Le Grand             aMarkedPreview.Scale(maPreviewSize, BMP_SCALE_FASTESTINTERPOLATE);
184cdf0e10cSrcweir         }
185cdf0e10cSrcweir     }
186cdf0e10cSrcweir 
187cdf0e10cSrcweir     return aMarkedPreview;
188cdf0e10cSrcweir }
189cdf0e10cSrcweir 
190cdf0e10cSrcweir 
191cdf0e10cSrcweir 
192cdf0e10cSrcweir 
SetMarkedPreviewBitmap(const CacheKey aKey,const Bitmap & rMarkedBitmap)193cdf0e10cSrcweir void GenericPageCache::SetMarkedPreviewBitmap (
194cdf0e10cSrcweir     const CacheKey aKey,
195cdf0e10cSrcweir     const Bitmap& rMarkedBitmap)
196cdf0e10cSrcweir {
197cdf0e10cSrcweir     OSL_ASSERT(aKey != NULL);
198cdf0e10cSrcweir 
199cdf0e10cSrcweir     ProvideCacheAndProcessor();
200cdf0e10cSrcweir     const SdrPage* pPage = mpCacheContext->GetPage(aKey);
201cdf0e10cSrcweir     mpBitmapCache->SetMarkedBitmap(pPage, rMarkedBitmap);
202cdf0e10cSrcweir }
203cdf0e10cSrcweir 
204cdf0e10cSrcweir 
205cdf0e10cSrcweir 
206cdf0e10cSrcweir 
RequestPreviewBitmap(const CacheKey aKey,const bool bMayBeUpToDate)207cdf0e10cSrcweir void GenericPageCache::RequestPreviewBitmap (
208cdf0e10cSrcweir     const CacheKey aKey,
209cdf0e10cSrcweir     const bool bMayBeUpToDate)
210cdf0e10cSrcweir {
211cdf0e10cSrcweir     OSL_ASSERT(aKey != NULL);
212cdf0e10cSrcweir 
213cdf0e10cSrcweir     const SdrPage* pPage = mpCacheContext->GetPage(aKey);
214cdf0e10cSrcweir 
215cdf0e10cSrcweir     ProvideCacheAndProcessor();
216cdf0e10cSrcweir 
217cdf0e10cSrcweir     // Determine if the available bitmap is up to date.
218cdf0e10cSrcweir     bool bIsUpToDate = false;
219cdf0e10cSrcweir     if (bMayBeUpToDate)
220cdf0e10cSrcweir         bIsUpToDate = mpBitmapCache->BitmapIsUpToDate (pPage);
221cdf0e10cSrcweir     if (bIsUpToDate)
222cdf0e10cSrcweir     {
223cdf0e10cSrcweir         const Bitmap aPreview (mpBitmapCache->GetBitmap(pPage));
224cdf0e10cSrcweir         if (aPreview.IsEmpty() || aPreview.GetSizePixel()!=maPreviewSize)
225cdf0e10cSrcweir               bIsUpToDate = false;
226cdf0e10cSrcweir     }
227cdf0e10cSrcweir 
228cdf0e10cSrcweir     if ( ! bIsUpToDate)
229cdf0e10cSrcweir     {
230cdf0e10cSrcweir         // No, the bitmap is not up-to-date.  Request a new one.
231cdf0e10cSrcweir         RequestPriorityClass ePriorityClass (NOT_VISIBLE);
232cdf0e10cSrcweir         if (mpCacheContext->IsVisible(aKey))
233cdf0e10cSrcweir         {
234cdf0e10cSrcweir             if (mpBitmapCache->HasBitmap(pPage))
235cdf0e10cSrcweir                 ePriorityClass = VISIBLE_OUTDATED_PREVIEW;
236cdf0e10cSrcweir             else
237cdf0e10cSrcweir                 ePriorityClass = VISIBLE_NO_PREVIEW;
238cdf0e10cSrcweir         }
239cdf0e10cSrcweir         maRequestQueue.AddRequest(aKey, ePriorityClass);
240cdf0e10cSrcweir         mpQueueProcessor->Start(ePriorityClass);
241cdf0e10cSrcweir     }
242cdf0e10cSrcweir }
243cdf0e10cSrcweir 
244cdf0e10cSrcweir 
245cdf0e10cSrcweir 
246cdf0e10cSrcweir 
InvalidatePreviewBitmap(const CacheKey aKey)247cdf0e10cSrcweir bool GenericPageCache::InvalidatePreviewBitmap (const CacheKey aKey)
248cdf0e10cSrcweir {
249cdf0e10cSrcweir     // Invalidate the page in all caches that reference it, not just this one.
250cdf0e10cSrcweir     ::boost::shared_ptr<cache::PageCacheManager> pCacheManager (
251cdf0e10cSrcweir         cache::PageCacheManager::Instance());
252cdf0e10cSrcweir     if (pCacheManager)
253cdf0e10cSrcweir         return pCacheManager->InvalidatePreviewBitmap(
254cdf0e10cSrcweir             mpCacheContext->GetModel(),
255cdf0e10cSrcweir             aKey);
256cdf0e10cSrcweir     else if (mpBitmapCache.get() != NULL)
257cdf0e10cSrcweir         return mpBitmapCache->InvalidateBitmap(mpCacheContext->GetPage(aKey));
258cdf0e10cSrcweir     else
259cdf0e10cSrcweir         return false;
260cdf0e10cSrcweir }
261cdf0e10cSrcweir 
262cdf0e10cSrcweir 
263cdf0e10cSrcweir 
264cdf0e10cSrcweir 
ReleasePreviewBitmap(const CacheKey aKey)265cdf0e10cSrcweir void GenericPageCache::ReleasePreviewBitmap (const CacheKey aKey)
266cdf0e10cSrcweir {
267cdf0e10cSrcweir     if (mpBitmapCache.get() != NULL)
268cdf0e10cSrcweir     {
269cdf0e10cSrcweir         // Suspend the queue processing temporarily to avoid the reinsertion
270cdf0e10cSrcweir         // of the request that is to be deleted.
271cdf0e10cSrcweir         mpQueueProcessor->Stop();
272cdf0e10cSrcweir 
273cdf0e10cSrcweir         maRequestQueue.RemoveRequest(aKey);
274cdf0e10cSrcweir         mpQueueProcessor->RemoveRequest(aKey);
275cdf0e10cSrcweir 
276cdf0e10cSrcweir         // Resume the queue processing.
277cdf0e10cSrcweir         if ( ! maRequestQueue.IsEmpty())
278cdf0e10cSrcweir         {
279cdf0e10cSrcweir             try
280cdf0e10cSrcweir             {
281cdf0e10cSrcweir                 mpQueueProcessor->Start(maRequestQueue.GetFrontPriorityClass());
282cdf0e10cSrcweir             }
283cdf0e10cSrcweir             catch (::com::sun::star::uno::RuntimeException)
284cdf0e10cSrcweir             {
285cdf0e10cSrcweir             }
286cdf0e10cSrcweir         }
287cdf0e10cSrcweir     }
288cdf0e10cSrcweir 
289cdf0e10cSrcweir     // We do not relase the preview bitmap that is associated with the page
290cdf0e10cSrcweir     // of the given request data because this method is called when the
291cdf0e10cSrcweir     // request data, typically a view-object-contact object, is destroyed.
292cdf0e10cSrcweir     // The page object usually lives longer than that and thus the preview
293cdf0e10cSrcweir     // bitmap may be used later on.
294cdf0e10cSrcweir }
295cdf0e10cSrcweir 
296cdf0e10cSrcweir 
297cdf0e10cSrcweir 
298cdf0e10cSrcweir 
InvalidateCache(const bool bUpdateCache)299cdf0e10cSrcweir void GenericPageCache::InvalidateCache (const bool bUpdateCache)
300cdf0e10cSrcweir {
301cdf0e10cSrcweir     if (mpBitmapCache)
302cdf0e10cSrcweir     {
303cdf0e10cSrcweir         // When the cache is being invalidated then it makes no sense to
304cdf0e10cSrcweir         // continue creating preview bitmaps.  However, this may be
305cdf0e10cSrcweir         // re-started below.
306cdf0e10cSrcweir         mpQueueProcessor->Stop();
307cdf0e10cSrcweir         maRequestQueue.Clear();
308cdf0e10cSrcweir 
309cdf0e10cSrcweir         // Mark the previews in the cache as not being up-to-date anymore.
310cdf0e10cSrcweir         // Depending on the given bUpdateCache flag we start to create new
311cdf0e10cSrcweir         // preview bitmaps.
312cdf0e10cSrcweir         mpBitmapCache->InvalidateCache();
313cdf0e10cSrcweir         if (bUpdateCache)
314cdf0e10cSrcweir             RequestFactory()(maRequestQueue, mpCacheContext);
315cdf0e10cSrcweir     }
316cdf0e10cSrcweir }
317cdf0e10cSrcweir 
318cdf0e10cSrcweir 
319cdf0e10cSrcweir 
320cdf0e10cSrcweir 
SetPreciousFlag(const CacheKey aKey,const bool bIsPrecious)321cdf0e10cSrcweir void GenericPageCache::SetPreciousFlag (
322cdf0e10cSrcweir     const CacheKey aKey,
323cdf0e10cSrcweir     const bool bIsPrecious)
324cdf0e10cSrcweir {
325cdf0e10cSrcweir     ProvideCacheAndProcessor();
326cdf0e10cSrcweir 
327cdf0e10cSrcweir     // Change the request priority class according to the new precious flag.
328cdf0e10cSrcweir     if (bIsPrecious)
329cdf0e10cSrcweir     {
330cdf0e10cSrcweir         if (mpBitmapCache->HasBitmap(mpCacheContext->GetPage(aKey)))
331cdf0e10cSrcweir             maRequestQueue.ChangeClass(aKey,VISIBLE_OUTDATED_PREVIEW);
332cdf0e10cSrcweir         else
333cdf0e10cSrcweir             maRequestQueue.ChangeClass(aKey,VISIBLE_NO_PREVIEW);
334cdf0e10cSrcweir     }
335cdf0e10cSrcweir     else
336cdf0e10cSrcweir     {
337cdf0e10cSrcweir         if (mpBitmapCache->IsFull())
338cdf0e10cSrcweir         {
339cdf0e10cSrcweir             // When the bitmap cache is full then requests for slides that
340cdf0e10cSrcweir             // are not visible are removed.
341cdf0e10cSrcweir             maRequestQueue.RemoveRequest(aKey);
342cdf0e10cSrcweir         }
343cdf0e10cSrcweir         else
344cdf0e10cSrcweir             maRequestQueue.ChangeClass(aKey,NOT_VISIBLE);
345cdf0e10cSrcweir     }
346cdf0e10cSrcweir 
347cdf0e10cSrcweir     mpBitmapCache->SetPrecious(mpCacheContext->GetPage(aKey), bIsPrecious);
348cdf0e10cSrcweir }
349cdf0e10cSrcweir 
350cdf0e10cSrcweir 
351cdf0e10cSrcweir 
352cdf0e10cSrcweir 
Pause(void)353cdf0e10cSrcweir void GenericPageCache::Pause (void)
354cdf0e10cSrcweir {
355cdf0e10cSrcweir     ProvideCacheAndProcessor();
356cdf0e10cSrcweir     if (mpQueueProcessor.get() != NULL)
357cdf0e10cSrcweir         mpQueueProcessor->Pause();
358cdf0e10cSrcweir }
359cdf0e10cSrcweir 
360cdf0e10cSrcweir 
361cdf0e10cSrcweir 
362cdf0e10cSrcweir 
Resume(void)363cdf0e10cSrcweir void GenericPageCache::Resume (void)
364cdf0e10cSrcweir {
365cdf0e10cSrcweir     ProvideCacheAndProcessor();
366cdf0e10cSrcweir     if (mpQueueProcessor.get() != NULL)
367cdf0e10cSrcweir         mpQueueProcessor->Resume();
368cdf0e10cSrcweir }
369cdf0e10cSrcweir 
370cdf0e10cSrcweir 
371cdf0e10cSrcweir 
372cdf0e10cSrcweir } } } // end of namespace ::sd::slidesorter::cache
373cdf0e10cSrcweir 
374cdf0e10cSrcweir 
375cdf0e10cSrcweir 
376