1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "precompiled_sd.hxx"
25 
26 #include "SlsQueueProcessor.hxx"
27 #include "SlsCacheConfiguration.hxx"
28 #include "SlsRequestQueue.hxx"
29 
30 namespace sd { namespace slidesorter { namespace cache {
31 
32 
33 //=====  QueueProcessor  ======================================================
34 
QueueProcessor(RequestQueue & rQueue,const::boost::shared_ptr<BitmapCache> & rpCache,const Size & rPreviewSize,const bool bDoSuperSampling,const SharedCacheContext & rpCacheContext)35 QueueProcessor::QueueProcessor (
36     RequestQueue& rQueue,
37     const ::boost::shared_ptr<BitmapCache>& rpCache,
38     const Size& rPreviewSize,
39     const bool bDoSuperSampling,
40     const SharedCacheContext& rpCacheContext)
41     : maMutex(),
42       maTimer(),
43       mnTimeBetweenHighPriorityRequests (10/*ms*/),
44       mnTimeBetweenLowPriorityRequests (100/*ms*/),
45       mnTimeBetweenRequestsWhenNotIdle (1000/*ms*/),
46       maPreviewSize(rPreviewSize),
47       mbDoSuperSampling(bDoSuperSampling),
48       mpCacheContext(rpCacheContext),
49       mrQueue(rQueue),
50       mpCache(rpCache),
51       maBitmapFactory(),
52       mbIsPaused(false)
53 {
54     // Look into the configuration if there for overriding values.
55     ::com::sun::star::uno::Any aTimeBetweenReqeusts;
56     aTimeBetweenReqeusts = CacheConfiguration::Instance()->GetValue(
57         ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TimeBetweenHighPriorityRequests")));
58     if (aTimeBetweenReqeusts.has<sal_Int32>())
59         aTimeBetweenReqeusts >>= mnTimeBetweenHighPriorityRequests;
60 
61     aTimeBetweenReqeusts = CacheConfiguration::Instance()->GetValue(
62         ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TimeBetweenLowPriorityRequests")));
63     if (aTimeBetweenReqeusts.has<sal_Int32>())
64         aTimeBetweenReqeusts >>= mnTimeBetweenLowPriorityRequests;
65 
66     aTimeBetweenReqeusts = CacheConfiguration::Instance()->GetValue(
67         ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TimeBetweenRequestsDuringShow")));
68     if (aTimeBetweenReqeusts.has<sal_Int32>())
69         aTimeBetweenReqeusts >>= mnTimeBetweenRequestsWhenNotIdle;
70 
71     maTimer.SetTimeoutHdl (LINK(this,QueueProcessor,ProcessRequestHdl));
72     maTimer.SetTimeout (mnTimeBetweenHighPriorityRequests);
73 }
74 
75 
76 
77 
78 
~QueueProcessor(void)79 QueueProcessor::~QueueProcessor (void)
80 {
81 }
82 
83 
84 
85 
Start(int nPriorityClass)86 void QueueProcessor::Start (int nPriorityClass)
87 {
88     if (mbIsPaused)
89         return;
90     if ( ! maTimer.IsActive())
91     {
92         if (nPriorityClass == 0)
93             maTimer.SetTimeout (mnTimeBetweenHighPriorityRequests);
94         else
95             maTimer.SetTimeout (mnTimeBetweenLowPriorityRequests);
96         maTimer.Start();
97     }
98 }
99 
100 
101 
102 
Stop(void)103 void QueueProcessor::Stop (void)
104 {
105     if (maTimer.IsActive())
106         maTimer.Stop();
107 }
108 
109 
110 
111 
Pause(void)112 void QueueProcessor::Pause (void)
113 {
114     mbIsPaused = true;
115 }
116 
117 
118 
119 
Resume(void)120 void QueueProcessor::Resume (void)
121 {
122     mbIsPaused = false;
123     if ( ! mrQueue.IsEmpty())
124         Start(mrQueue.GetFrontPriorityClass());
125 }
126 
127 
128 
129 
Terminate(void)130 void QueueProcessor::Terminate (void)
131 {
132 }
133 
134 
135 
136 
SetPreviewSize(const Size & rPreviewSize,const bool bDoSuperSampling)137 void QueueProcessor::SetPreviewSize (
138     const Size& rPreviewSize,
139     const bool bDoSuperSampling)
140 {
141     maPreviewSize = rPreviewSize;
142     mbDoSuperSampling = bDoSuperSampling;
143 }
144 
145 
146 
147 
IMPL_LINK(QueueProcessor,ProcessRequestHdl,Timer *,EMPTYARG)148 IMPL_LINK(QueueProcessor, ProcessRequestHdl, Timer*, EMPTYARG)
149 {
150     ProcessRequests();
151     return 1;
152 }
153 
154 
155 
156 
ProcessRequests(void)157 void QueueProcessor::ProcessRequests (void)
158 {
159     OSL_ASSERT(mpCacheContext.get()!=NULL);
160 
161     // Never process more than one request at a time in order to prevent the
162     // lock up of the edit view.
163     if ( ! mrQueue.IsEmpty()
164         && ! mbIsPaused
165         &&  mpCacheContext->IsIdle())
166     {
167         CacheKey aKey = NULL;
168         RequestPriorityClass ePriorityClass (NOT_VISIBLE);
169         {
170             ::osl::MutexGuard aGuard (mrQueue.GetMutex());
171 
172             if ( ! mrQueue.IsEmpty())
173             {
174                 // Get the request with the highest priority from the queue.
175                 ePriorityClass = mrQueue.GetFrontPriorityClass();
176                 aKey = mrQueue.GetFront();
177                 mrQueue.PopFront();
178             }
179         }
180 
181         if (aKey != NULL)
182             ProcessOneRequest(aKey, ePriorityClass);
183     }
184 
185     // Schedule the processing of the next element(s).
186     {
187         ::osl::MutexGuard aGuard (mrQueue.GetMutex());
188         if ( ! mrQueue.IsEmpty())
189             Start(mrQueue.GetFrontPriorityClass());
190     }
191 }
192 
193 
194 
195 
ProcessOneRequest(CacheKey aKey,const RequestPriorityClass ePriorityClass)196 void QueueProcessor::ProcessOneRequest (
197     CacheKey aKey,
198     const RequestPriorityClass ePriorityClass)
199 {
200     try
201     {
202         ::osl::MutexGuard aGuard (maMutex);
203 
204         // Create a new preview bitmap and store it in the cache.
205         if (mpCache.get() != NULL
206             && mpCacheContext.get() != NULL)
207         {
208             const SdPage* pSdPage = dynamic_cast<const SdPage*>(mpCacheContext->GetPage(aKey));
209             if (pSdPage != NULL)
210             {
211                 const Bitmap aPreview (
212                     maBitmapFactory.CreateBitmap(*pSdPage, maPreviewSize, mbDoSuperSampling));
213                 mpCache->SetBitmap (pSdPage, aPreview, ePriorityClass!=NOT_VISIBLE);
214 
215                 // Initiate a repaint of the new preview.
216                 mpCacheContext->NotifyPreviewCreation(aKey, aPreview);
217             }
218         }
219     }
220     catch (::com::sun::star::uno::RuntimeException aException)
221     {
222         (void) aException;
223         OSL_ASSERT("RuntimeException caught in QueueProcessor");
224     }
225     catch (::com::sun::star::uno::Exception aException)
226     {
227         (void) aException;
228         OSL_ASSERT("Exception caught in QueueProcessor");
229     }
230 }
231 
232 
233 
234 
RemoveRequest(CacheKey aKey)235 void QueueProcessor::RemoveRequest (CacheKey aKey)
236 {
237     (void)aKey;
238     // See the method declaration above for an explanation why this makes sense.
239     ::osl::MutexGuard aGuard (maMutex);
240 }
241 
242 
243 
244 
SetBitmapCache(const::boost::shared_ptr<BitmapCache> & rpCache)245 void QueueProcessor::SetBitmapCache (
246     const ::boost::shared_ptr<BitmapCache>& rpCache)
247 {
248     mpCache = rpCache;
249 }
250 
251 
252 } } } // end of namespace ::sd::slidesorter::cache
253