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 <tools/debug.hxx>
28 #include <unomodel.hxx>
30 namespace sd::slidesorter::cache
{
32 GenericPageCache::GenericPageCache (
33 const Size
& rPreviewSize
,
34 const bool bDoSuperSampling
,
35 const SharedCacheContext
& rpCacheContext
)
36 : maRequestQueue(rpCacheContext
),
37 mpCacheContext(rpCacheContext
),
38 maPreviewSize(rPreviewSize
),
39 mbDoSuperSampling(bDoSuperSampling
)
41 // A large size may indicate an error of the caller. After all we
42 // are creating previews.
43 DBG_ASSERT (maPreviewSize
.Width()<1000 && maPreviewSize
.Height()<1000,
44 "GenericPageCache<>::GetPreviewBitmap(): bitmap requested with large width. "
45 "This may indicate an error.");
48 GenericPageCache::~GenericPageCache()
50 if (mpQueueProcessor
!= nullptr)
51 mpQueueProcessor
->Stop();
52 maRequestQueue
.Clear();
53 mpQueueProcessor
.reset();
55 if (mpBitmapCache
!= nullptr)
56 PageCacheManager::Instance()->ReleaseCache(mpBitmapCache
);
57 mpBitmapCache
.reset();
60 void GenericPageCache::ProvideCacheAndProcessor()
62 if (mpBitmapCache
== nullptr)
63 mpBitmapCache
= PageCacheManager::Instance()->GetCache(
64 mpCacheContext
->GetModel(),
67 if (mpQueueProcessor
== nullptr)
68 mpQueueProcessor
.reset(new QueueProcessor(
76 void GenericPageCache::ChangePreviewSize (
77 const Size
& rPreviewSize
,
78 const bool bDoSuperSampling
)
80 if (rPreviewSize
==maPreviewSize
&& bDoSuperSampling
==mbDoSuperSampling
)
83 // A large size may indicate an error of the caller. After all we
84 // are creating previews.
85 DBG_ASSERT (maPreviewSize
.Width()<1000 && maPreviewSize
.Height()<1000,
86 "GenericPageCache<>::GetPreviewBitmap(): bitmap requested with large width. "
87 "This may indicate an error.");
89 if (mpBitmapCache
!= nullptr)
91 mpBitmapCache
= PageCacheManager::Instance()->ChangeSize(
92 mpBitmapCache
, maPreviewSize
, rPreviewSize
);
93 if (mpQueueProcessor
!= nullptr)
95 mpQueueProcessor
->SetPreviewSize(rPreviewSize
, bDoSuperSampling
);
96 mpQueueProcessor
->SetBitmapCache(mpBitmapCache
);
99 maPreviewSize
= rPreviewSize
;
100 mbDoSuperSampling
= bDoSuperSampling
;
103 BitmapEx
GenericPageCache::GetPreviewBitmap (
107 assert(aKey
!= nullptr);
110 bool bMayBeUpToDate
= true;
111 ProvideCacheAndProcessor();
112 const SdrPage
* pPage
= mpCacheContext
->GetPage(aKey
);
113 if (mpBitmapCache
->HasBitmap(pPage
))
115 aPreview
= mpBitmapCache
->GetBitmap(pPage
);
116 const Size
aBitmapSize (aPreview
.GetSizePixel());
117 if (aBitmapSize
!= maPreviewSize
)
119 // Scale the bitmap to the desired size when that is possible,
120 // i.e. the bitmap is not empty.
121 if (bResize
&& !aBitmapSize
.IsEmpty())
123 aPreview
.Scale(maPreviewSize
);
125 bMayBeUpToDate
= false;
128 bMayBeUpToDate
= true;
131 bMayBeUpToDate
= false;
133 // Request the creation of a correctly sized preview bitmap. We do this
134 // even when the size of the bitmap in the cache is correct because its
135 // content may be not up-to-date anymore.
136 RequestPreviewBitmap(aKey
, bMayBeUpToDate
);
141 BitmapEx
GenericPageCache::GetMarkedPreviewBitmap (
144 assert(aKey
!= nullptr);
146 ProvideCacheAndProcessor();
147 const SdrPage
* pPage
= mpCacheContext
->GetPage(aKey
);
148 BitmapEx
aMarkedPreview (mpBitmapCache
->GetMarkedBitmap(pPage
));
150 return aMarkedPreview
;
153 void GenericPageCache::SetMarkedPreviewBitmap (
155 const BitmapEx
& rMarkedBitmap
)
157 assert(aKey
!= nullptr);
159 ProvideCacheAndProcessor();
160 const SdrPage
* pPage
= mpCacheContext
->GetPage(aKey
);
161 mpBitmapCache
->SetMarkedBitmap(pPage
, rMarkedBitmap
);
164 void GenericPageCache::RequestPreviewBitmap (
166 const bool bMayBeUpToDate
)
168 assert(aKey
!= nullptr);
170 const SdrPage
* pPage
= mpCacheContext
->GetPage(aKey
);
172 ProvideCacheAndProcessor();
174 // Determine if the available bitmap is up to date.
175 bool bIsUpToDate
= false;
177 bIsUpToDate
= mpBitmapCache
->BitmapIsUpToDate (pPage
);
180 const BitmapEx
aPreview (mpBitmapCache
->GetBitmap(pPage
));
181 if (aPreview
.IsEmpty() || aPreview
.GetSizePixel()!=maPreviewSize
)
188 // No, the bitmap is not up-to-date. Request a new one.
189 RequestPriorityClass
ePriorityClass (NOT_VISIBLE
);
190 if (mpCacheContext
->IsVisible(aKey
))
192 if (mpBitmapCache
->HasBitmap(pPage
))
193 ePriorityClass
= VISIBLE_OUTDATED_PREVIEW
;
195 ePriorityClass
= VISIBLE_NO_PREVIEW
;
197 maRequestQueue
.AddRequest(aKey
, ePriorityClass
);
198 mpQueueProcessor
->Start(ePriorityClass
);
201 bool GenericPageCache::InvalidatePreviewBitmap (const CacheKey aKey
)
203 // Invalidate the page in all caches that reference it, not just this one.
204 std::shared_ptr
<cache::PageCacheManager
> pCacheManager (
205 cache::PageCacheManager::Instance());
207 return pCacheManager
->InvalidatePreviewBitmap(
208 mpCacheContext
->GetModel(),
210 else if (mpBitmapCache
!= nullptr)
211 return mpBitmapCache
->InvalidateBitmap(mpCacheContext
->GetPage(aKey
));
216 void GenericPageCache::InvalidateCache ()
221 // When the cache is being invalidated then it makes no sense to
222 // continue creating preview bitmaps. However, this may be
224 mpQueueProcessor
->Stop();
225 maRequestQueue
.Clear();
227 // Mark the previews in the cache as not being up-to-date anymore.
228 // Depending on the given bUpdateCache flag we start to create new
230 mpBitmapCache
->InvalidateCache();
231 RequestFactory()(maRequestQueue
, mpCacheContext
);
234 void GenericPageCache::SetPreciousFlag (
236 const bool bIsPrecious
)
238 ProvideCacheAndProcessor();
240 // Change the request priority class according to the new precious flag.
243 if (mpBitmapCache
->HasBitmap(mpCacheContext
->GetPage(aKey
)))
244 maRequestQueue
.ChangeClass(aKey
,VISIBLE_OUTDATED_PREVIEW
);
246 maRequestQueue
.ChangeClass(aKey
,VISIBLE_NO_PREVIEW
);
250 if (mpBitmapCache
->IsFull())
252 // When the bitmap cache is full then requests for slides that
253 // are not visible are removed.
254 maRequestQueue
.RemoveRequest(aKey
);
257 maRequestQueue
.ChangeClass(aKey
,NOT_VISIBLE
);
260 mpBitmapCache
->SetPrecious(mpCacheContext
->GetPage(aKey
), bIsPrecious
);
263 void GenericPageCache::Pause()
265 ProvideCacheAndProcessor();
266 if (mpQueueProcessor
!= nullptr)
267 mpQueueProcessor
->Pause();
270 void GenericPageCache::Resume()
272 ProvideCacheAndProcessor();
273 if (mpQueueProcessor
!= nullptr)
274 mpQueueProcessor
->Resume();
277 } // end of namespace ::sd::slidesorter::cache
279 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */