| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| #include "precompiled_sd.hxx" |
| |
| #include "SlsGenericPageCache.hxx" |
| |
| #include "SlsQueueProcessor.hxx" |
| #include "SlsRequestPriorityClass.hxx" |
| #include "SlsRequestFactory.hxx" |
| #include "cache/SlsPageCacheManager.hxx" |
| #include "model/SlideSorterModel.hxx" |
| #include "model/SlsPageDescriptor.hxx" |
| #include "controller/SlideSorterController.hxx" |
| |
| |
| namespace sd { namespace slidesorter { namespace cache { |
| |
| GenericPageCache::GenericPageCache ( |
| const Size& rPreviewSize, |
| const bool bDoSuperSampling, |
| const SharedCacheContext& rpCacheContext) |
| : mpBitmapCache(), |
| maRequestQueue(rpCacheContext), |
| mpQueueProcessor(), |
| mpCacheContext(rpCacheContext), |
| maPreviewSize(rPreviewSize), |
| mbDoSuperSampling(bDoSuperSampling) |
| { |
| // A large size may indicate an error of the caller. After all we |
| // are creating previews. |
| DBG_ASSERT (maPreviewSize.Width()<1000 && maPreviewSize.Height()<1000, |
| "GenericPageCache<>::GetPreviewBitmap(): bitmap requested with large width. " |
| "This may indicate an error."); |
| } |
| |
| |
| |
| |
| GenericPageCache::~GenericPageCache (void) |
| { |
| if (mpQueueProcessor.get() != NULL) |
| mpQueueProcessor->Stop(); |
| maRequestQueue.Clear(); |
| if (mpQueueProcessor.get() != NULL) |
| mpQueueProcessor->Terminate(); |
| mpQueueProcessor.reset(); |
| |
| if (mpBitmapCache.get() != NULL) |
| PageCacheManager::Instance()->ReleaseCache(mpBitmapCache); |
| mpBitmapCache.reset(); |
| } |
| |
| |
| |
| |
| void GenericPageCache::ProvideCacheAndProcessor (void) |
| { |
| if (mpBitmapCache.get() == NULL) |
| mpBitmapCache = PageCacheManager::Instance()->GetCache( |
| mpCacheContext->GetModel(), |
| maPreviewSize); |
| |
| if (mpQueueProcessor.get() == NULL) |
| mpQueueProcessor.reset(new QueueProcessor( |
| maRequestQueue, |
| mpBitmapCache, |
| maPreviewSize, |
| mbDoSuperSampling, |
| mpCacheContext)); |
| } |
| |
| |
| |
| |
| void GenericPageCache::ChangePreviewSize ( |
| const Size& rPreviewSize, |
| const bool bDoSuperSampling) |
| { |
| if (rPreviewSize!=maPreviewSize || bDoSuperSampling!=mbDoSuperSampling) |
| { |
| // A large size may indicate an error of the caller. After all we |
| // are creating previews. |
| DBG_ASSERT (maPreviewSize.Width()<1000 && maPreviewSize.Height()<1000, |
| "GenericPageCache<>::GetPreviewBitmap(): bitmap requested with large width. " |
| "This may indicate an error."); |
| |
| if (mpBitmapCache.get() != NULL) |
| { |
| mpBitmapCache = PageCacheManager::Instance()->ChangeSize( |
| mpBitmapCache, maPreviewSize, rPreviewSize); |
| if (mpQueueProcessor.get() != NULL) |
| { |
| mpQueueProcessor->SetPreviewSize(rPreviewSize, bDoSuperSampling); |
| mpQueueProcessor->SetBitmapCache(mpBitmapCache); |
| } |
| } |
| maPreviewSize = rPreviewSize; |
| mbDoSuperSampling = bDoSuperSampling; |
| } |
| } |
| |
| |
| |
| |
| Bitmap GenericPageCache::GetPreviewBitmap ( |
| const CacheKey aKey, |
| const bool bResize) |
| { |
| OSL_ASSERT(aKey != NULL); |
| |
| Bitmap aPreview; |
| bool bMayBeUpToDate = true; |
| ProvideCacheAndProcessor(); |
| const SdrPage* pPage = mpCacheContext->GetPage(aKey); |
| if (mpBitmapCache->HasBitmap(pPage)) |
| { |
| aPreview = mpBitmapCache->GetBitmap(pPage); |
| const Size aBitmapSize (aPreview.GetSizePixel()); |
| if (aBitmapSize != maPreviewSize) |
| { |
| // Scale the bitmap to the desired size when that is possible, |
| // i.e. the bitmap is not empty. |
| if (bResize && aBitmapSize.Width()>0 && aBitmapSize.Height()>0) |
| { |
| aPreview.Scale(maPreviewSize, BMP_SCALE_FASTESTINTERPOLATE); |
| } |
| bMayBeUpToDate = false; |
| } |
| else |
| bMayBeUpToDate = true; |
| } |
| else |
| bMayBeUpToDate = false; |
| |
| // Request the creation of a correctly sized preview bitmap. We do this |
| // even when the size of the bitmap in the cache is correct because its |
| // content may be not up-to-date anymore. |
| RequestPreviewBitmap(aKey, bMayBeUpToDate); |
| |
| return aPreview; |
| } |
| |
| |
| |
| |
| Bitmap GenericPageCache::GetMarkedPreviewBitmap ( |
| const CacheKey aKey, |
| const bool bResize) |
| { |
| OSL_ASSERT(aKey != NULL); |
| |
| ProvideCacheAndProcessor(); |
| const SdrPage* pPage = mpCacheContext->GetPage(aKey); |
| Bitmap aMarkedPreview (mpBitmapCache->GetMarkedBitmap(pPage)); |
| const Size aBitmapSize (aMarkedPreview.GetSizePixel()); |
| if (bResize && aBitmapSize != maPreviewSize) |
| { |
| // Scale the bitmap to the desired size when that is possible, |
| // i.e. the bitmap is not empty. |
| if (aBitmapSize.Width()>0 && aBitmapSize.Height()>0) |
| { |
| aMarkedPreview.Scale(maPreviewSize, BMP_SCALE_FASTESTINTERPOLATE); |
| } |
| } |
| |
| return aMarkedPreview; |
| } |
| |
| |
| |
| |
| void GenericPageCache::SetMarkedPreviewBitmap ( |
| const CacheKey aKey, |
| const Bitmap& rMarkedBitmap) |
| { |
| OSL_ASSERT(aKey != NULL); |
| |
| ProvideCacheAndProcessor(); |
| const SdrPage* pPage = mpCacheContext->GetPage(aKey); |
| mpBitmapCache->SetMarkedBitmap(pPage, rMarkedBitmap); |
| } |
| |
| |
| |
| |
| void GenericPageCache::RequestPreviewBitmap ( |
| const CacheKey aKey, |
| const bool bMayBeUpToDate) |
| { |
| OSL_ASSERT(aKey != NULL); |
| |
| const SdrPage* pPage = mpCacheContext->GetPage(aKey); |
| |
| ProvideCacheAndProcessor(); |
| |
| // Determine if the available bitmap is up to date. |
| bool bIsUpToDate = false; |
| if (bMayBeUpToDate) |
| bIsUpToDate = mpBitmapCache->BitmapIsUpToDate (pPage); |
| if (bIsUpToDate) |
| { |
| const Bitmap aPreview (mpBitmapCache->GetBitmap(pPage)); |
| if (aPreview.IsEmpty() || aPreview.GetSizePixel()!=maPreviewSize) |
| bIsUpToDate = false; |
| } |
| |
| if ( ! bIsUpToDate) |
| { |
| // No, the bitmap is not up-to-date. Request a new one. |
| RequestPriorityClass ePriorityClass (NOT_VISIBLE); |
| if (mpCacheContext->IsVisible(aKey)) |
| { |
| if (mpBitmapCache->HasBitmap(pPage)) |
| ePriorityClass = VISIBLE_OUTDATED_PREVIEW; |
| else |
| ePriorityClass = VISIBLE_NO_PREVIEW; |
| } |
| maRequestQueue.AddRequest(aKey, ePriorityClass); |
| mpQueueProcessor->Start(ePriorityClass); |
| } |
| } |
| |
| |
| |
| |
| bool GenericPageCache::InvalidatePreviewBitmap (const CacheKey aKey) |
| { |
| // Invalidate the page in all caches that reference it, not just this one. |
| ::boost::shared_ptr<cache::PageCacheManager> pCacheManager ( |
| cache::PageCacheManager::Instance()); |
| if (pCacheManager) |
| return pCacheManager->InvalidatePreviewBitmap( |
| mpCacheContext->GetModel(), |
| aKey); |
| else if (mpBitmapCache.get() != NULL) |
| return mpBitmapCache->InvalidateBitmap(mpCacheContext->GetPage(aKey)); |
| else |
| return false; |
| } |
| |
| |
| |
| |
| void GenericPageCache::ReleasePreviewBitmap (const CacheKey aKey) |
| { |
| if (mpBitmapCache.get() != NULL) |
| { |
| // Suspend the queue processing temporarily to avoid the reinsertion |
| // of the request that is to be deleted. |
| mpQueueProcessor->Stop(); |
| |
| maRequestQueue.RemoveRequest(aKey); |
| mpQueueProcessor->RemoveRequest(aKey); |
| |
| // Resume the queue processing. |
| if ( ! maRequestQueue.IsEmpty()) |
| { |
| try |
| { |
| mpQueueProcessor->Start(maRequestQueue.GetFrontPriorityClass()); |
| } |
| catch (::com::sun::star::uno::RuntimeException) |
| { |
| } |
| } |
| } |
| |
| // We do not relase the preview bitmap that is associated with the page |
| // of the given request data because this method is called when the |
| // request data, typically a view-object-contact object, is destroyed. |
| // The page object usually lives longer than that and thus the preview |
| // bitmap may be used later on. |
| } |
| |
| |
| |
| |
| void GenericPageCache::InvalidateCache (const bool bUpdateCache) |
| { |
| if (mpBitmapCache) |
| { |
| // When the cache is being invalidated then it makes no sense to |
| // continue creating preview bitmaps. However, this may be |
| // re-started below. |
| mpQueueProcessor->Stop(); |
| maRequestQueue.Clear(); |
| |
| // Mark the previews in the cache as not being up-to-date anymore. |
| // Depending on the given bUpdateCache flag we start to create new |
| // preview bitmaps. |
| mpBitmapCache->InvalidateCache(); |
| if (bUpdateCache) |
| RequestFactory()(maRequestQueue, mpCacheContext); |
| } |
| } |
| |
| |
| |
| |
| void GenericPageCache::SetPreciousFlag ( |
| const CacheKey aKey, |
| const bool bIsPrecious) |
| { |
| ProvideCacheAndProcessor(); |
| |
| // Change the request priority class according to the new precious flag. |
| if (bIsPrecious) |
| { |
| if (mpBitmapCache->HasBitmap(mpCacheContext->GetPage(aKey))) |
| maRequestQueue.ChangeClass(aKey,VISIBLE_OUTDATED_PREVIEW); |
| else |
| maRequestQueue.ChangeClass(aKey,VISIBLE_NO_PREVIEW); |
| } |
| else |
| { |
| if (mpBitmapCache->IsFull()) |
| { |
| // When the bitmap cache is full then requests for slides that |
| // are not visible are removed. |
| maRequestQueue.RemoveRequest(aKey); |
| } |
| else |
| maRequestQueue.ChangeClass(aKey,NOT_VISIBLE); |
| } |
| |
| mpBitmapCache->SetPrecious(mpCacheContext->GetPage(aKey), bIsPrecious); |
| } |
| |
| |
| |
| |
| void GenericPageCache::Pause (void) |
| { |
| ProvideCacheAndProcessor(); |
| if (mpQueueProcessor.get() != NULL) |
| mpQueueProcessor->Pause(); |
| } |
| |
| |
| |
| |
| void GenericPageCache::Resume (void) |
| { |
| ProvideCacheAndProcessor(); |
| if (mpQueueProcessor.get() != NULL) |
| mpQueueProcessor->Resume(); |
| } |
| |
| |
| |
| } } } // end of namespace ::sd::slidesorter::cache |
| |
| |
| |