| Index: core/src/fpdfapi/fpdf_render/fpdf_render_cache.cpp
|
| diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render_cache.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render_cache.cpp
|
| index 8d0568e7196393394f784071eb9fcd4a45944b71..3e5e27088fb965d6297b2ee83755642f04a31e89 100644
|
| --- a/core/src/fpdfapi/fpdf_render/fpdf_render_cache.cpp
|
| +++ b/core/src/fpdfapi/fpdf_render/fpdf_render_cache.cpp
|
| @@ -15,95 +15,65 @@ struct CACHEINFO {
|
| FX_DWORD time;
|
| CPDF_Stream* pStream;
|
| };
|
| +
|
| extern "C" {
|
| static int compare(const void* data1, const void* data2) {
|
| return ((CACHEINFO*)data1)->time - ((CACHEINFO*)data2)->time;
|
| }
|
| -};
|
| -void CPDF_Page::ClearRenderCache() {
|
| - if (m_pPageRender) {
|
| - m_pPageRender->ClearAll();
|
| - }
|
| -}
|
| -void CPDF_PageRenderCache::ClearAll() {
|
| - FX_POSITION pos = m_ImageCaches.GetStartPosition();
|
| - while (pos) {
|
| - void* key;
|
| - void* value;
|
| - m_ImageCaches.GetNextAssoc(pos, key, value);
|
| - delete (CPDF_ImageCache*)value;
|
| - }
|
| - m_ImageCaches.RemoveAll();
|
| - m_nCacheSize = 0;
|
| - m_nTimeCount = 0;
|
| +} // extern "C"
|
| +
|
| +CPDF_PageRenderCache::~CPDF_PageRenderCache() {
|
| + for (const auto& it : m_ImageCache)
|
| + delete it.second;
|
| }
|
| void CPDF_PageRenderCache::CacheOptimization(int32_t dwLimitCacheSize) {
|
| - if (m_nCacheSize <= (FX_DWORD)dwLimitCacheSize) {
|
| + if (m_nCacheSize <= (FX_DWORD)dwLimitCacheSize)
|
| return;
|
| - }
|
| - int nCount = m_ImageCaches.GetCount();
|
| - CACHEINFO* pCACHEINFO =
|
| - (CACHEINFO*)FX_Alloc2D(uint8_t, sizeof(CACHEINFO), nCount);
|
| - FX_POSITION pos = m_ImageCaches.GetStartPosition();
|
| - int i = 0;
|
| - while (pos) {
|
| - void* key;
|
| - void* value;
|
| - m_ImageCaches.GetNextAssoc(pos, key, value);
|
| - pCACHEINFO[i].time = ((CPDF_ImageCache*)value)->GetTimeCount();
|
| - pCACHEINFO[i++].pStream = ((CPDF_ImageCache*)value)->GetStream();
|
| +
|
| + size_t nCount = m_ImageCache.size();
|
| + CACHEINFO* pCACHEINFO = FX_Alloc(CACHEINFO, nCount);
|
| + size_t i = 0;
|
| + for (const auto& it : m_ImageCache) {
|
| + pCACHEINFO[i].time = it.second->GetTimeCount();
|
| + pCACHEINFO[i++].pStream = it.second->GetStream();
|
| }
|
| FXSYS_qsort(pCACHEINFO, nCount, sizeof(CACHEINFO), compare);
|
| FX_DWORD nTimeCount = m_nTimeCount;
|
| +
|
| + // Check if time value is about to roll over and reset all entries.
|
| + // The comparision is legal because FX_DWORD is an unsigned type.
|
| if (nTimeCount + 1 < nTimeCount) {
|
| - for (i = 0; i < nCount; i++) {
|
| - ((CPDF_ImageCache*)(m_ImageCaches[pCACHEINFO[i].pStream]))
|
| - ->m_dwTimeCount = i;
|
| - }
|
| + for (i = 0; i < nCount; i++)
|
| + m_ImageCache[pCACHEINFO[i].pStream]->m_dwTimeCount = i;
|
| m_nTimeCount = nCount;
|
| }
|
| +
|
| i = 0;
|
| - while (nCount > 15) {
|
| - ClearImageCache(pCACHEINFO[i++].pStream);
|
| - nCount--;
|
| - }
|
| - while (m_nCacheSize > (FX_DWORD)dwLimitCacheSize) {
|
| - ClearImageCache(pCACHEINFO[i++].pStream);
|
| - }
|
| + while (i + 15 < nCount)
|
| + ClearImageCacheEntry(pCACHEINFO[i++].pStream);
|
| +
|
| + while (i < nCount && m_nCacheSize > (FX_DWORD)dwLimitCacheSize)
|
| + ClearImageCacheEntry(pCACHEINFO[i++].pStream);
|
| +
|
| FX_Free(pCACHEINFO);
|
| }
|
| -void CPDF_PageRenderCache::ClearImageCache(CPDF_Stream* pStream) {
|
| - void* value = m_ImageCaches.GetValueAt(pStream);
|
| - if (!value) {
|
| - m_ImageCaches.RemoveKey(pStream);
|
| +void CPDF_PageRenderCache::ClearImageCacheEntry(CPDF_Stream* pStream) {
|
| + auto it = m_ImageCache.find(pStream);
|
| + if (it == m_ImageCache.end())
|
| return;
|
| - }
|
| - m_nCacheSize -= ((CPDF_ImageCache*)value)->EstimateSize();
|
| - delete (CPDF_ImageCache*)value;
|
| - m_ImageCaches.RemoveKey(pStream);
|
| +
|
| + m_nCacheSize -= it->second->EstimateSize();
|
| + delete it->second;
|
| + m_ImageCache.erase(it);
|
| }
|
| FX_DWORD CPDF_PageRenderCache::EstimateSize() {
|
| FX_DWORD dwSize = 0;
|
| - FX_POSITION pos = m_ImageCaches.GetStartPosition();
|
| - while (pos) {
|
| - void* key;
|
| - void* value;
|
| - m_ImageCaches.GetNextAssoc(pos, key, value);
|
| - dwSize += ((CPDF_ImageCache*)value)->EstimateSize();
|
| - }
|
| + for (const auto& it : m_ImageCache)
|
| + dwSize += it.second->EstimateSize();
|
| +
|
| m_nCacheSize = dwSize;
|
| return dwSize;
|
| }
|
| -FX_DWORD CPDF_PageRenderCache::GetCachedSize(CPDF_Stream* pStream) const {
|
| - if (!pStream) {
|
| - return m_nCacheSize;
|
| - }
|
| - CPDF_ImageCache* pImageCache;
|
| - if (!m_ImageCaches.Lookup(pStream, (void*&)pImageCache)) {
|
| - return 0;
|
| - }
|
| - return pImageCache->EstimateSize();
|
| -}
|
| void CPDF_PageRenderCache::GetCachedBitmap(CPDF_Stream* pStream,
|
| CFX_DIBSource*& pBitmap,
|
| CFX_DIBSource*& pMask,
|
| @@ -114,21 +84,24 @@ void CPDF_PageRenderCache::GetCachedBitmap(CPDF_Stream* pStream,
|
| CPDF_RenderStatus* pRenderStatus,
|
| int32_t downsampleWidth,
|
| int32_t downsampleHeight) {
|
| - CPDF_ImageCache* pImageCache;
|
| - FX_BOOL bFind = m_ImageCaches.Lookup(pStream, (void*&)pImageCache);
|
| - if (!bFind) {
|
| - pImageCache = new CPDF_ImageCache(m_pPage->m_pDocument, pStream);
|
| - }
|
| + CPDF_ImageCacheEntry* pEntry;
|
| + const auto it = m_ImageCache.find(pStream);
|
| + FX_BOOL bFound = it != m_ImageCache.end();
|
| + if (bFound)
|
| + pEntry = it->second;
|
| + else
|
| + pEntry = new CPDF_ImageCacheEntry(m_pPage->m_pDocument, pStream);
|
| +
|
| m_nTimeCount++;
|
| - FX_BOOL bCached = pImageCache->GetCachedBitmap(
|
| + FX_BOOL bAlreadyCached = pEntry->GetCachedBitmap(
|
| pBitmap, pMask, MatteColor, m_pPage->m_pPageResources, bStdCS,
|
| GroupFamily, bLoadMask, pRenderStatus, downsampleWidth, downsampleHeight);
|
| - if (!bFind) {
|
| - m_ImageCaches.SetAt(pStream, pImageCache);
|
| - }
|
| - if (!bCached) {
|
| - m_nCacheSize += pImageCache->EstimateSize();
|
| - }
|
| +
|
| + if (!bFound)
|
| + m_ImageCache[pStream] = pEntry;
|
| +
|
| + if (!bAlreadyCached)
|
| + m_nCacheSize += pEntry->EstimateSize();
|
| }
|
| FX_BOOL CPDF_PageRenderCache::StartGetCachedBitmap(
|
| CPDF_Stream* pStream,
|
| @@ -138,54 +111,58 @@ FX_BOOL CPDF_PageRenderCache::StartGetCachedBitmap(
|
| CPDF_RenderStatus* pRenderStatus,
|
| int32_t downsampleWidth,
|
| int32_t downsampleHeight) {
|
| - m_bCurFindCache = m_ImageCaches.Lookup(pStream, (void*&)m_pCurImageCache);
|
| - if (!m_bCurFindCache) {
|
| - m_pCurImageCache = new CPDF_ImageCache(m_pPage->m_pDocument, pStream);
|
| + const auto it = m_ImageCache.find(pStream);
|
| + m_bCurFindCache = it != m_ImageCache.end();
|
| + if (m_bCurFindCache) {
|
| + m_pCurImageCacheEntry = it->second;
|
| + } else {
|
| + m_pCurImageCacheEntry =
|
| + new CPDF_ImageCacheEntry(m_pPage->m_pDocument, pStream);
|
| }
|
| - int ret = m_pCurImageCache->StartGetCachedBitmap(
|
| + int ret = m_pCurImageCacheEntry->StartGetCachedBitmap(
|
| pRenderStatus->m_pFormResource, m_pPage->m_pPageResources, bStdCS,
|
| GroupFamily, bLoadMask, pRenderStatus, downsampleWidth, downsampleHeight);
|
| - if (ret == 2) {
|
| + if (ret == 2)
|
| return TRUE;
|
| - }
|
| +
|
| m_nTimeCount++;
|
| - if (!m_bCurFindCache) {
|
| - m_ImageCaches.SetAt(pStream, m_pCurImageCache);
|
| - }
|
| - if (!ret) {
|
| - m_nCacheSize += m_pCurImageCache->EstimateSize();
|
| - }
|
| + if (!m_bCurFindCache)
|
| + m_ImageCache[pStream] = m_pCurImageCacheEntry;
|
| +
|
| + if (!ret)
|
| + m_nCacheSize += m_pCurImageCacheEntry->EstimateSize();
|
| +
|
| return FALSE;
|
| }
|
| FX_BOOL CPDF_PageRenderCache::Continue(IFX_Pause* pPause) {
|
| - int ret = m_pCurImageCache->Continue(pPause);
|
| - if (ret == 2) {
|
| + int ret = m_pCurImageCacheEntry->Continue(pPause);
|
| + if (ret == 2)
|
| return TRUE;
|
| - }
|
| m_nTimeCount++;
|
| - if (!m_bCurFindCache) {
|
| - m_ImageCaches.SetAt(m_pCurImageCache->GetStream(), m_pCurImageCache);
|
| - }
|
| - if (!ret) {
|
| - m_nCacheSize += m_pCurImageCache->EstimateSize();
|
| - }
|
| + if (!m_bCurFindCache)
|
| + m_ImageCache[m_pCurImageCacheEntry->GetStream()] = m_pCurImageCacheEntry;
|
| + if (!ret)
|
| + m_nCacheSize += m_pCurImageCacheEntry->EstimateSize();
|
| return FALSE;
|
| }
|
| void CPDF_PageRenderCache::ResetBitmap(CPDF_Stream* pStream,
|
| const CFX_DIBitmap* pBitmap) {
|
| - CPDF_ImageCache* pImageCache;
|
| - if (!m_ImageCaches.Lookup(pStream, (void*&)pImageCache)) {
|
| - if (!pBitmap) {
|
| + CPDF_ImageCacheEntry* pEntry;
|
| + const auto it = m_ImageCache.find(pStream);
|
| + if (it == m_ImageCache.end()) {
|
| + if (!pBitmap)
|
| return;
|
| - }
|
| - pImageCache = new CPDF_ImageCache(m_pPage->m_pDocument, pStream);
|
| - m_ImageCaches.SetAt(pStream, pImageCache);
|
| + pEntry = new CPDF_ImageCacheEntry(m_pPage->m_pDocument, pStream);
|
| + m_ImageCache[pStream] = pEntry;
|
| + } else {
|
| + pEntry = it->second;
|
| }
|
| - int oldsize = pImageCache->EstimateSize();
|
| - pImageCache->Reset(pBitmap);
|
| - m_nCacheSize = pImageCache->EstimateSize() - oldsize;
|
| + m_nCacheSize -= pEntry->EstimateSize();
|
| + pEntry->Reset(pBitmap);
|
| + m_nCacheSize += pEntry->EstimateSize();
|
| }
|
| -CPDF_ImageCache::CPDF_ImageCache(CPDF_Document* pDoc, CPDF_Stream* pStream)
|
| +CPDF_ImageCacheEntry::CPDF_ImageCacheEntry(CPDF_Document* pDoc,
|
| + CPDF_Stream* pStream)
|
| : m_dwTimeCount(0),
|
| m_pCurBitmap(NULL),
|
| m_pCurMask(NULL),
|
| @@ -196,13 +173,11 @@ CPDF_ImageCache::CPDF_ImageCache(CPDF_Document* pDoc, CPDF_Stream* pStream)
|
| m_pCachedBitmap(NULL),
|
| m_pCachedMask(NULL),
|
| m_dwCacheSize(0) {}
|
| -CPDF_ImageCache::~CPDF_ImageCache() {
|
| +CPDF_ImageCacheEntry::~CPDF_ImageCacheEntry() {
|
| delete m_pCachedBitmap;
|
| - m_pCachedBitmap = NULL;
|
| delete m_pCachedMask;
|
| - m_pCachedMask = NULL;
|
| }
|
| -void CPDF_ImageCache::Reset(const CFX_DIBitmap* pBitmap) {
|
| +void CPDF_ImageCacheEntry::Reset(const CFX_DIBitmap* pBitmap) {
|
| delete m_pCachedBitmap;
|
| m_pCachedBitmap = NULL;
|
| if (pBitmap) {
|
| @@ -211,15 +186,10 @@ void CPDF_ImageCache::Reset(const CFX_DIBitmap* pBitmap) {
|
| CalcSize();
|
| }
|
| void CPDF_PageRenderCache::ClearImageData() {
|
| - FX_POSITION pos = m_ImageCaches.GetStartPosition();
|
| - while (pos) {
|
| - void* key;
|
| - void* value;
|
| - m_ImageCaches.GetNextAssoc(pos, key, value);
|
| - ((CPDF_ImageCache*)value)->ClearImageData();
|
| - }
|
| + for (const auto& it : m_ImageCache)
|
| + it.second->ClearImageData();
|
| }
|
| -void CPDF_ImageCache::ClearImageData() {
|
| +void CPDF_ImageCacheEntry::ClearImageData() {
|
| if (m_pCachedBitmap && !m_pCachedBitmap->GetBuffer()) {
|
| ((CPDF_DIBSource*)m_pCachedBitmap)->ClearImageData();
|
| }
|
| @@ -230,16 +200,16 @@ static FX_DWORD FPDF_ImageCache_EstimateImageSize(const CFX_DIBSource* pDIB) {
|
| (FX_DWORD)pDIB->GetPaletteSize() * 4
|
| : 0;
|
| }
|
| -FX_BOOL CPDF_ImageCache::GetCachedBitmap(CFX_DIBSource*& pBitmap,
|
| - CFX_DIBSource*& pMask,
|
| - FX_DWORD& MatteColor,
|
| - CPDF_Dictionary* pPageResources,
|
| - FX_BOOL bStdCS,
|
| - FX_DWORD GroupFamily,
|
| - FX_BOOL bLoadMask,
|
| - CPDF_RenderStatus* pRenderStatus,
|
| - int32_t downsampleWidth,
|
| - int32_t downsampleHeight) {
|
| +FX_BOOL CPDF_ImageCacheEntry::GetCachedBitmap(CFX_DIBSource*& pBitmap,
|
| + CFX_DIBSource*& pMask,
|
| + FX_DWORD& MatteColor,
|
| + CPDF_Dictionary* pPageResources,
|
| + FX_BOOL bStdCS,
|
| + FX_DWORD GroupFamily,
|
| + FX_BOOL bLoadMask,
|
| + CPDF_RenderStatus* pRenderStatus,
|
| + int32_t downsampleWidth,
|
| + int32_t downsampleHeight) {
|
| if (m_pCachedBitmap) {
|
| pBitmap = m_pCachedBitmap;
|
| pMask = m_pCachedMask;
|
| @@ -278,24 +248,24 @@ FX_BOOL CPDF_ImageCache::GetCachedBitmap(CFX_DIBSource*& pBitmap,
|
| CalcSize();
|
| return FALSE;
|
| }
|
| -CFX_DIBSource* CPDF_ImageCache::DetachBitmap() {
|
| +CFX_DIBSource* CPDF_ImageCacheEntry::DetachBitmap() {
|
| CFX_DIBSource* pDIBSource = m_pCurBitmap;
|
| m_pCurBitmap = NULL;
|
| return pDIBSource;
|
| }
|
| -CFX_DIBSource* CPDF_ImageCache::DetachMask() {
|
| +CFX_DIBSource* CPDF_ImageCacheEntry::DetachMask() {
|
| CFX_DIBSource* pDIBSource = m_pCurMask;
|
| m_pCurMask = NULL;
|
| return pDIBSource;
|
| }
|
| -int CPDF_ImageCache::StartGetCachedBitmap(CPDF_Dictionary* pFormResources,
|
| - CPDF_Dictionary* pPageResources,
|
| - FX_BOOL bStdCS,
|
| - FX_DWORD GroupFamily,
|
| - FX_BOOL bLoadMask,
|
| - CPDF_RenderStatus* pRenderStatus,
|
| - int32_t downsampleWidth,
|
| - int32_t downsampleHeight) {
|
| +int CPDF_ImageCacheEntry::StartGetCachedBitmap(CPDF_Dictionary* pFormResources,
|
| + CPDF_Dictionary* pPageResources,
|
| + FX_BOOL bStdCS,
|
| + FX_DWORD GroupFamily,
|
| + FX_BOOL bLoadMask,
|
| + CPDF_RenderStatus* pRenderStatus,
|
| + int32_t downsampleWidth,
|
| + int32_t downsampleHeight) {
|
| if (m_pCachedBitmap) {
|
| m_pCurBitmap = m_pCachedBitmap;
|
| m_pCurMask = m_pCachedMask;
|
| @@ -321,7 +291,7 @@ int CPDF_ImageCache::StartGetCachedBitmap(CPDF_Dictionary* pFormResources,
|
| ContinueGetCachedBitmap();
|
| return 0;
|
| }
|
| -int CPDF_ImageCache::ContinueGetCachedBitmap() {
|
| +void CPDF_ImageCacheEntry::ContinueGetCachedBitmap() {
|
| m_MatteColor = ((CPDF_DIBSource*)m_pCurBitmap)->m_MatteColor;
|
| m_pCurMask = ((CPDF_DIBSource*)m_pCurBitmap)->DetachMask();
|
| CPDF_RenderContext* pContext = m_pRenderStatus->GetContext();
|
| @@ -343,9 +313,8 @@ int CPDF_ImageCache::ContinueGetCachedBitmap() {
|
| m_pCurBitmap = m_pCachedBitmap;
|
| m_pCurMask = m_pCachedMask;
|
| CalcSize();
|
| - return 0;
|
| }
|
| -int CPDF_ImageCache::Continue(IFX_Pause* pPause) {
|
| +int CPDF_ImageCacheEntry::Continue(IFX_Pause* pPause) {
|
| int ret = ((CPDF_DIBSource*)m_pCurBitmap)->ContinueLoadDIBSource(pPause);
|
| if (ret == 2) {
|
| return ret;
|
| @@ -358,7 +327,7 @@ int CPDF_ImageCache::Continue(IFX_Pause* pPause) {
|
| ContinueGetCachedBitmap();
|
| return 0;
|
| }
|
| -void CPDF_ImageCache::CalcSize() {
|
| +void CPDF_ImageCacheEntry::CalcSize() {
|
| m_dwCacheSize = FPDF_ImageCache_EstimateImageSize(m_pCachedBitmap) +
|
| FPDF_ImageCache_EstimateImageSize(m_pCachedMask);
|
| }
|
|
|