From 0fa6fee0e48af8681f0cd50f6a9471ecc0a46c11 Mon Sep 17 00:00:00 2001 From: Tom Sepez Date: Fri, 18 Dec 2015 14:53:31 -0800 Subject: Remove CFX_MapPtrToPtr in CFX_PageRenderCache Rename CPDF_ImageCache to CPDF_ImageCacheEntry because it represents a single entry, not the entire cache itself. Delete unused ClearRenderCache method, and merge cache entry clear() into its dtor. Fix a broken size calculation. R=thestig@chromium.org Review URL: https://codereview.chromium.org/1539983002 . --- core/src/fpdfapi/fpdf_render/fpdf_render_cache.cpp | 259 +++++++++------------ .../fpdfapi/fpdf_render/fpdf_render_loadimage.cpp | 24 +- core/src/fpdfapi/fpdf_render/render_int.h | 13 +- 3 files changed, 135 insertions(+), 161 deletions(-) (limited to 'core/src') 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); } diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp index 7b34c5721a..fafba95527 100644 --- a/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp +++ b/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp @@ -1560,17 +1560,19 @@ FX_BOOL CPDF_ProgressiveImageLoaderHandle::Start( ret = pCache->StartGetCachedBitmap(pImage->m_pImage->GetStream(), bStdCS, GroupFamily, bLoadMask, pRenderStatus, m_nDownsampleWidth, m_nDownsampleHeight); - if (ret == FALSE) { + if (!ret) { m_pImageLoader->m_bCached = TRUE; - m_pImageLoader->m_pBitmap = pCache->m_pCurImageCache->DetachBitmap(); - m_pImageLoader->m_pMask = pCache->m_pCurImageCache->DetachMask(); - m_pImageLoader->m_MatteColor = pCache->m_pCurImageCache->m_MatteColor; + m_pImageLoader->m_pBitmap = + pCache->GetCurImageCacheEntry()->DetachBitmap(); + m_pImageLoader->m_pMask = pCache->GetCurImageCacheEntry()->DetachMask(); + m_pImageLoader->m_MatteColor = + pCache->GetCurImageCacheEntry()->m_MatteColor; } } else { ret = pImage->m_pImage->StartLoadDIBSource(pRenderStatus->m_pFormResource, pRenderStatus->m_pPageResource, bStdCS, GroupFamily, bLoadMask); - if (ret == FALSE) { + if (!ret) { m_pImageLoader->m_bCached = FALSE; m_pImageLoader->m_pBitmap = m_pImage->m_pImage->DetachBitmap(); m_pImageLoader->m_pMask = m_pImage->m_pImage->DetachMask(); @@ -1583,15 +1585,17 @@ FX_BOOL CPDF_ProgressiveImageLoaderHandle::Continue(IFX_Pause* pPause) { FX_BOOL ret; if (m_pCache) { ret = m_pCache->Continue(pPause); - if (ret == FALSE) { + if (!ret) { m_pImageLoader->m_bCached = TRUE; - m_pImageLoader->m_pBitmap = m_pCache->m_pCurImageCache->DetachBitmap(); - m_pImageLoader->m_pMask = m_pCache->m_pCurImageCache->DetachMask(); - m_pImageLoader->m_MatteColor = m_pCache->m_pCurImageCache->m_MatteColor; + m_pImageLoader->m_pBitmap = + m_pCache->GetCurImageCacheEntry()->DetachBitmap(); + m_pImageLoader->m_pMask = m_pCache->GetCurImageCacheEntry()->DetachMask(); + m_pImageLoader->m_MatteColor = + m_pCache->GetCurImageCacheEntry()->m_MatteColor; } } else { ret = m_pImage->m_pImage->Continue(pPause); - if (ret == FALSE) { + if (!ret) { m_pImageLoader->m_bCached = FALSE; m_pImageLoader->m_pBitmap = m_pImage->m_pImage->DetachBitmap(); m_pImageLoader->m_pMask = m_pImage->m_pImage->DetachMask(); diff --git a/core/src/fpdfapi/fpdf_render/render_int.h b/core/src/fpdfapi/fpdf_render/render_int.h index c4bfa28ff7..80cf6ca9ff 100644 --- a/core/src/fpdfapi/fpdf_render/render_int.h +++ b/core/src/fpdfapi/fpdf_render/render_int.h @@ -14,7 +14,7 @@ #include "third_party/base/nonstd_unique_ptr.h" class CFX_GlyphBitmap; -class CPDF_ImageCache; +class CPDF_ImageCacheEntry; class ICodec_ScanlineDecoder; #define TYPE3_MAX_BLUES 16 @@ -186,7 +186,7 @@ class CPDF_RenderStatus { FX_ARGB fill_argb, int bitmap_alpha, const CFX_Matrix* pImage2Device, - CPDF_ImageCache* pImageCache, + CPDF_ImageCacheEntry* pImageCache, FX_DWORD flags); void CompositeDIBitmap(CFX_DIBitmap* pDIBitmap, int left, @@ -424,10 +424,10 @@ class CPDF_DeviceBuffer { CFX_Matrix m_Matrix; }; -class CPDF_ImageCache { +class CPDF_ImageCacheEntry { public: - CPDF_ImageCache(CPDF_Document* pDoc, CPDF_Stream* pStream); - ~CPDF_ImageCache(); + CPDF_ImageCacheEntry(CPDF_Document* pDoc, CPDF_Stream* pStream); + ~CPDF_ImageCacheEntry(); void ClearImageData(); void Reset(const CFX_DIBitmap* pBitmap); FX_BOOL GetCachedBitmap(CFX_DIBSource*& pBitmap, @@ -456,7 +456,6 @@ class CPDF_ImageCache { int32_t downsampleWidth = 0, int32_t downsampleHeight = 0); int Continue(IFX_Pause* pPause); - int ContinueGetCachedBitmap(); CFX_DIBSource* DetachBitmap(); CFX_DIBSource* DetachMask(); CFX_DIBSource* m_pCurBitmap; @@ -465,6 +464,8 @@ class CPDF_ImageCache { CPDF_RenderStatus* m_pRenderStatus; protected: + void ContinueGetCachedBitmap(); + CPDF_Document* m_pDocument; CPDF_Stream* m_pStream; CFX_DIBSource* m_pCachedBitmap; -- cgit v1.2.3