summaryrefslogtreecommitdiff
path: root/core/src/fpdfapi/fpdf_render/fpdf_render_cache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/fpdfapi/fpdf_render/fpdf_render_cache.cpp')
-rw-r--r--core/src/fpdfapi/fpdf_render/fpdf_render_cache.cpp259
1 files changed, 114 insertions, 145 deletions
diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render_cache.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render_cache.cpp
index 8d0568e719..3e5e27088f 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);
}