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 "SlsBitmapCache.hxx"
26 #include <cache/SlsPageCacheManager.hxx>
27 #include <model/SlideSorterModel.hxx>
28 #include <model/SlsPageDescriptor.hxx>
29 #include <controller/SlideSorterController.hxx>
30 #include <tools/debug.hxx>
32 namespace sd
{ namespace slidesorter
{ namespace cache
{
34 GenericPageCache::GenericPageCache (
35 const Size
& rPreviewSize
,
36 const bool bDoSuperSampling
,
37 const SharedCacheContext
& rpCacheContext
)
39 maRequestQueue(rpCacheContext
),
41 mpCacheContext(rpCacheContext
),
42 maPreviewSize(rPreviewSize
),
43 mbDoSuperSampling(bDoSuperSampling
)
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.");
52 GenericPageCache::~GenericPageCache()
54 if (mpQueueProcessor
!= nullptr)
55 mpQueueProcessor
->Stop();
56 maRequestQueue
.Clear();
57 mpQueueProcessor
.reset();
59 if (mpBitmapCache
!= nullptr)
60 PageCacheManager::Instance()->ReleaseCache(mpBitmapCache
);
61 mpBitmapCache
.reset();
64 void GenericPageCache::ProvideCacheAndProcessor()
66 if (mpBitmapCache
== nullptr)
67 mpBitmapCache
= PageCacheManager::Instance()->GetCache(
68 mpCacheContext
->GetModel(),
71 if (mpQueueProcessor
== nullptr)
72 mpQueueProcessor
.reset(new QueueProcessor(
80 void GenericPageCache::ChangePreviewSize (
81 const Size
& rPreviewSize
,
82 const bool bDoSuperSampling
)
84 if (rPreviewSize
==maPreviewSize
&& bDoSuperSampling
==mbDoSuperSampling
)
87 // A large size may indicate an error of the caller. After all we
88 // are creating previews.
89 DBG_ASSERT (maPreviewSize
.Width()<1000 && maPreviewSize
.Height()<1000,
90 "GenericPageCache<>::GetPreviewBitmap(): bitmap requested with large width. "
91 "This may indicate an error.");
93 if (mpBitmapCache
!= nullptr)
95 mpBitmapCache
= PageCacheManager::Instance()->ChangeSize(
96 mpBitmapCache
, maPreviewSize
, rPreviewSize
);
97 if (mpQueueProcessor
!= nullptr)
99 mpQueueProcessor
->SetPreviewSize(rPreviewSize
, bDoSuperSampling
);
100 mpQueueProcessor
->SetBitmapCache(mpBitmapCache
);
103 maPreviewSize
= rPreviewSize
;
104 mbDoSuperSampling
= bDoSuperSampling
;
107 BitmapEx
GenericPageCache::GetPreviewBitmap (
111 assert(aKey
!= nullptr);
114 bool bMayBeUpToDate
= true;
115 ProvideCacheAndProcessor();
116 const SdrPage
* pPage
= mpCacheContext
->GetPage(aKey
);
117 if (mpBitmapCache
->HasBitmap(pPage
))
119 aPreview
= mpBitmapCache
->GetBitmap(pPage
);
120 const Size
aBitmapSize (aPreview
.GetSizePixel());
121 if (aBitmapSize
!= maPreviewSize
)
123 // Scale the bitmap to the desired size when that is possible,
124 // i.e. the bitmap is not empty.
125 if (bResize
&& aBitmapSize
.Width()>0 && aBitmapSize
.Height()>0)
127 aPreview
.Scale(maPreviewSize
);
129 bMayBeUpToDate
= false;
132 bMayBeUpToDate
= true;
135 bMayBeUpToDate
= false;
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 RequestPreviewBitmap(aKey
, bMayBeUpToDate
);
145 BitmapEx
GenericPageCache::GetMarkedPreviewBitmap (
148 assert(aKey
!= nullptr);
150 ProvideCacheAndProcessor();
151 const SdrPage
* pPage
= mpCacheContext
->GetPage(aKey
);
152 BitmapEx
aMarkedPreview (mpBitmapCache
->GetMarkedBitmap(pPage
));
154 return aMarkedPreview
;
157 void GenericPageCache::SetMarkedPreviewBitmap (
159 const BitmapEx
& rMarkedBitmap
)
161 assert(aKey
!= nullptr);
163 ProvideCacheAndProcessor();
164 const SdrPage
* pPage
= mpCacheContext
->GetPage(aKey
);
165 mpBitmapCache
->SetMarkedBitmap(pPage
, rMarkedBitmap
);
168 void GenericPageCache::RequestPreviewBitmap (
170 const bool bMayBeUpToDate
)
172 assert(aKey
!= nullptr);
174 const SdrPage
* pPage
= mpCacheContext
->GetPage(aKey
);
176 ProvideCacheAndProcessor();
178 // Determine if the available bitmap is up to date.
179 bool bIsUpToDate
= false;
181 bIsUpToDate
= mpBitmapCache
->BitmapIsUpToDate (pPage
);
184 const BitmapEx
aPreview (mpBitmapCache
->GetBitmap(pPage
));
185 if (aPreview
.IsEmpty() || aPreview
.GetSizePixel()!=maPreviewSize
)
192 // No, the bitmap is not up-to-date. Request a new one.
193 RequestPriorityClass
ePriorityClass (NOT_VISIBLE
);
194 if (mpCacheContext
->IsVisible(aKey
))
196 if (mpBitmapCache
->HasBitmap(pPage
))
197 ePriorityClass
= VISIBLE_OUTDATED_PREVIEW
;
199 ePriorityClass
= VISIBLE_NO_PREVIEW
;
201 maRequestQueue
.AddRequest(aKey
, ePriorityClass
);
202 mpQueueProcessor
->Start(ePriorityClass
);
205 bool GenericPageCache::InvalidatePreviewBitmap (const CacheKey aKey
)
207 // Invalidate the page in all caches that reference it, not just this one.
208 std::shared_ptr
<cache::PageCacheManager
> pCacheManager (
209 cache::PageCacheManager::Instance());
211 return pCacheManager
->InvalidatePreviewBitmap(
212 mpCacheContext
->GetModel(),
214 else if (mpBitmapCache
!= nullptr)
215 return mpBitmapCache
->InvalidateBitmap(mpCacheContext
->GetPage(aKey
));
220 void GenericPageCache::InvalidateCache ()
225 // When the cache is being invalidated then it makes no sense to
226 // continue creating preview bitmaps. However, this may be
228 mpQueueProcessor
->Stop();
229 maRequestQueue
.Clear();
231 // Mark the previews in the cache as not being up-to-date anymore.
232 // Depending on the given bUpdateCache flag we start to create new
234 mpBitmapCache
->InvalidateCache();
235 RequestFactory()(maRequestQueue
, mpCacheContext
);
238 void GenericPageCache::SetPreciousFlag (
240 const bool bIsPrecious
)
242 ProvideCacheAndProcessor();
244 // Change the request priority class according to the new precious flag.
247 if (mpBitmapCache
->HasBitmap(mpCacheContext
->GetPage(aKey
)))
248 maRequestQueue
.ChangeClass(aKey
,VISIBLE_OUTDATED_PREVIEW
);
250 maRequestQueue
.ChangeClass(aKey
,VISIBLE_NO_PREVIEW
);
254 if (mpBitmapCache
->IsFull())
256 // When the bitmap cache is full then requests for slides that
257 // are not visible are removed.
258 maRequestQueue
.RemoveRequest(aKey
);
261 maRequestQueue
.ChangeClass(aKey
,NOT_VISIBLE
);
264 mpBitmapCache
->SetPrecious(mpCacheContext
->GetPage(aKey
), bIsPrecious
);
267 void GenericPageCache::Pause()
269 ProvideCacheAndProcessor();
270 if (mpQueueProcessor
!= nullptr)
271 mpQueueProcessor
->Pause();
274 void GenericPageCache::Resume()
276 ProvideCacheAndProcessor();
277 if (mpQueueProcessor
!= nullptr)
278 mpQueueProcessor
->Resume();
281 } } } // end of namespace ::sd::slidesorter::cache
283 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */