14d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Copyright 2016 PDFium Authors. All rights reserved. 24d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Use of this source code is governed by a BSD-style license that can be 34d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// found in the LICENSE file. 44d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 54d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 64d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 74d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/render/cpdf_pagerendercache.h" 84d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include <algorithm> 10d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include <vector> 11d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 12d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "core/fpdfapi/page/cpdf_image.h" 134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/page/cpdf_page.h" 144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/render/cpdf_imagecacheentry.h" 154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/render/cpdf_renderstatus.h" 164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannnamespace { 184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannstruct CacheInfo { 20d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann CacheInfo(uint32_t t, CPDF_Stream* stream) : time(t), pStream(stream) {} 21d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t time; 234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann CPDF_Stream* pStream; 244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann bool operator<(const CacheInfo& other) const { return time < other.time; } 26d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}; 274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} // namespace 294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCPDF_PageRenderCache::CPDF_PageRenderCache(CPDF_Page* pPage) 314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann : m_pPage(pPage), 324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_pCurImageCacheEntry(nullptr), 334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_nTimeCount(0), 344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_nCacheSize(0), 354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_bCurFindCache(false) {} 364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCPDF_PageRenderCache::~CPDF_PageRenderCache() { 384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (const auto& it : m_ImageCache) 394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann delete it.second; 404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CPDF_PageRenderCache::CacheOptimization(int32_t dwLimitCacheSize) { 434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (m_nCacheSize <= (uint32_t)dwLimitCacheSize) 444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann size_t nCount = m_ImageCache.size(); 47d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann std::vector<CacheInfo> cache_info; 48d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cache_info.reserve(nCount); 494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (const auto& it : m_ImageCache) { 50d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cache_info.emplace_back(it.second->GetTimeCount(), 51d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann it.second->GetImage()->GetStream()); 524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 53d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann std::sort(cache_info.begin(), cache_info.end()); 544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann // Check if time value is about to roll over and reset all entries. 564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann // The comparision is legal because uint32_t is an unsigned type. 57d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann uint32_t nTimeCount = m_nTimeCount; 584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (nTimeCount + 1 < nTimeCount) { 59d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann for (size_t i = 0; i < nCount; i++) 60d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann m_ImageCache[cache_info[i].pStream]->m_dwTimeCount = i; 614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_nTimeCount = nCount; 624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 64d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann size_t i = 0; 654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (i + 15 < nCount) 66d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann ClearImageCacheEntry(cache_info[i++].pStream); 674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (i < nCount && m_nCacheSize > (uint32_t)dwLimitCacheSize) 69d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann ClearImageCacheEntry(cache_info[i++].pStream); 704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CPDF_PageRenderCache::ClearImageCacheEntry(CPDF_Stream* pStream) { 734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann auto it = m_ImageCache.find(pStream); 744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (it == m_ImageCache.end()) 754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_nCacheSize -= it->second->EstimateSize(); 784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann delete it->second; 794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_ImageCache.erase(it); 804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool CPDF_PageRenderCache::StartGetCachedBitmap( 83d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann const RetainPtr<CPDF_Image>& pImage, 844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool bStdCS, 854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint32_t GroupFamily, 864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool bLoadMask, 87d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann CPDF_RenderStatus* pRenderStatus) { 88d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann CPDF_Stream* pStream = pImage->GetStream(); 894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const auto it = m_ImageCache.find(pStream); 904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_bCurFindCache = it != m_ImageCache.end(); 914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (m_bCurFindCache) { 924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_pCurImageCacheEntry = it->second; 934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } else { 944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_pCurImageCacheEntry = 95d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann new CPDF_ImageCacheEntry(m_pPage->m_pDocument.Get(), pImage); 964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int ret = m_pCurImageCacheEntry->StartGetCachedBitmap( 98d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pRenderStatus->GetFormResource(), m_pPage->m_pPageResources.Get(), bStdCS, 99d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann GroupFamily, bLoadMask, pRenderStatus); 1004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (ret == 2) 1014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return true; 1024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_nTimeCount++; 1044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!m_bCurFindCache) 1054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_ImageCache[pStream] = m_pCurImageCacheEntry; 1064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!ret) 1084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_nCacheSize += m_pCurImageCacheEntry->EstimateSize(); 1094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 1114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 1124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 113d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannbool CPDF_PageRenderCache::Continue(IFX_PauseIndicator* pPause, 114d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann CPDF_RenderStatus* pRenderStatus) { 115d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann int ret = m_pCurImageCacheEntry->Continue(pPause, pRenderStatus); 1164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (ret == 2) 1174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return true; 1184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_nTimeCount++; 120d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (!m_bCurFindCache) { 121d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann m_ImageCache[m_pCurImageCacheEntry->GetImage()->GetStream()] = 122d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann m_pCurImageCacheEntry; 123d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 1244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!ret) 1254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_nCacheSize += m_pCurImageCacheEntry->EstimateSize(); 1264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 1274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 1284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 129d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid CPDF_PageRenderCache::ResetBitmap(const RetainPtr<CPDF_Image>& pImage, 130d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann const RetainPtr<CFX_DIBitmap>& pBitmap) { 1314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann CPDF_ImageCacheEntry* pEntry; 132d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann CPDF_Stream* pStream = pImage->GetStream(); 1334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const auto it = m_ImageCache.find(pStream); 1344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (it == m_ImageCache.end()) { 1354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!pBitmap) 1364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 1374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 138d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pEntry = new CPDF_ImageCacheEntry(m_pPage->m_pDocument.Get(), pImage); 1394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_ImageCache[pStream] = pEntry; 1404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } else { 1414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pEntry = it->second; 1424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_nCacheSize -= pEntry->EstimateSize(); 1444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pEntry->Reset(pBitmap); 1454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_nCacheSize += pEntry->EstimateSize(); 1464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 147