Settings of cache size

This commit is contained in:
Jakub Melka
2019-12-15 19:28:25 +01:00
parent 3cd2dd5104
commit 7dbae1c3dc
17 changed files with 467 additions and 24 deletions

View File

@ -92,6 +92,11 @@ void PDFAsynchronousPageCompiler::reset()
start();
}
void PDFAsynchronousPageCompiler::setCacheLimit(int limit)
{
m_cache.setMaxCost(limit);
}
const PDFPrecompiledPage* PDFAsynchronousPageCompiler::getCompiledPage(PDFInteger pageIndex, bool compile)
{
if (m_state != State::Active || !m_proxy->getDocument())
@ -112,6 +117,7 @@ const PDFPrecompiledPage* PDFAsynchronousPageCompiler::getCompiledPage(PDFIntege
return compiledPage;
};
m_proxy->getFontCache()->setCacheShrinkEnabled(false);
CompileTask& task = m_tasks[pageIndex];
task.taskFuture = QtConcurrent::run(compilePage);
task.taskWatcher = new QFutureWatcher<PDFPrecompiledPage>(this);
@ -160,6 +166,9 @@ void PDFAsynchronousPageCompiler::onPageCompiled()
}
}
// We allow font cache shrinking, when we aren't doing something in parallel.
m_proxy->getFontCache()->setCacheShrinkEnabled(m_tasks.empty());
if (!compiledPages.empty())
{
Q_ASSERT(std::is_sorted(compiledPages.cbegin(), compiledPages.cend()));

View File

@ -53,6 +53,10 @@ public:
/// Resets the engine - calls stop and then calls start.
void reset();
/// Sets cache limit in bytes
/// \param limit Cache limit [bytes]
void setCacheLimit(int limit);
enum class State
{
Inactive,

View File

@ -58,6 +58,10 @@ static constexpr const char* PDF_OBJECT_END_MARK = "endobj";
// Colors
static constexpr const int PDF_MAX_COLOR_COMPONENTS = 32;
// Cache limits
static constexpr size_t DEFAULT_FONT_CACHE_LIMIT = 32;
static constexpr size_t DEFAULT_REALIZED_FONT_CACHE_LIMIT = 128;
} // namespace pdf
#endif // PDFCONSTANTS_H

View File

@ -21,6 +21,7 @@
#include "pdfrenderer.h"
#include "pdfpainter.h"
#include "pdfcompiler.h"
#include "pdfconstants.h"
#include <QPainter>
@ -34,7 +35,7 @@ PDFDrawSpaceController::PDFDrawSpaceController(QObject* parent) :
m_pageLayoutMode(PageLayout::OneColumn),
m_verticalSpacingMM(5.0),
m_horizontalSpacingMM(1.0),
m_fontCache(FONT_CACHE_LIMIT, REALIZED_FONT_CACHE_LIMIT)
m_fontCache(DEFAULT_FONT_CACHE_LIMIT, DEFAULT_REALIZED_FONT_CACHE_LIMIT)
{
}

View File

@ -103,6 +103,9 @@ public:
/// Returns the font cache
const PDFFontCache* getFontCache() const { return &m_fontCache; }
/// Returns the font cache
PDFFontCache* getFontCache() { return &m_fontCache; }
/// Returns optional content activity
const PDFOptionalContentActivity* getOptionalContentActivity() const { return m_optionalContentActivity; }
@ -136,9 +139,6 @@ private:
using BlockItems = std::vector<LayoutBlock>;
static constexpr size_t FONT_CACHE_LIMIT = 32;
static constexpr size_t REALIZED_FONT_CACHE_LIMIT = 128;
const PDFDocument* m_document;
const PDFOptionalContentActivity* m_optionalContentActivity;
@ -267,10 +267,11 @@ public:
static constexpr PDFReal ZOOM_STEP = 1.2;
const PDFDocument* getDocument() const { return m_controller->getDocument(); }
const PDFFontCache* getFontCache() const { return m_controller->getFontCache(); }
PDFFontCache* getFontCache() const { return m_controller->getFontCache(); }
const PDFOptionalContentActivity* getOptionalContentActivity() const { return m_controller->getOptionalContentActivity(); }
PDFRenderer::Features getFeatures() const;
const PDFMeshQualitySettings& getMeshQualitySettings() const { return m_meshQualitySettings; }
PDFAsynchronousPageCompiler* getCompiler() const { return m_compiler; }
void setFeatures(PDFRenderer::Features features);
void setPreferredMeshResolutionRatio(PDFReal ratio);

View File

@ -17,11 +17,13 @@
#include "pdfdrawwidget.h"
#include "pdfdrawspacecontroller.h"
#include "pdfcompiler.h"
#include <QPainter>
#include <QGridLayout>
#include <QKeyEvent>
#include <QApplication>
#include <QPixmapCache>
namespace pdf
{
@ -96,6 +98,13 @@ void PDFWidget::updateRenderer(RendererEngine engine, int samplesCount)
updateRendererImpl();
}
void PDFWidget::updateCacheLimits(int compiledPageCacheLimit, int thumbnailsCacheLimit, int fontCacheLimit, int instancedFontCacheLimit)
{
m_proxy->getCompiler()->setCacheLimit(compiledPageCacheLimit);
QPixmapCache::setCacheLimit(thumbnailsCacheLimit);
m_proxy->getFontCache()->setCacheLimits(fontCacheLimit, instancedFontCacheLimit);
}
int PDFWidget::getPageRenderingErrorCount() const
{
int count = 0;

View File

@ -67,6 +67,13 @@ public:
/// \param samplesCount Samples count for rendering engine MSAA antialiasing
void updateRenderer(RendererEngine engine, int samplesCount);
/// Updates cache limits
/// \param compiledPageCacheLimit Compiled page cache limit [bytes]
/// \param thumbnailsCacheLimit Thumbnail image cache limit [kB]
/// \param fontCacheLimit Font cache limit [-]
/// \param instancedFontCacheLimit Instanced font cache limit [-]
void updateCacheLimits(int compiledPageCacheLimit, int thumbnailsCacheLimit, int fontCacheLimit, int instancedFontCacheLimit);
IDrawWidget* getDrawWidget() const { return m_drawWidget; }
QScrollBar* getHorizontalScrollbar() const { return m_horizontalScrollBar; }
QScrollBar* getVerticalScrollbar() const { return m_verticalScrollBar; }

View File

@ -1399,7 +1399,7 @@ PDFFontPointer PDFFontCache::getFont(const PDFObject& fontObject) const
// We must create the font
PDFFontPointer font = PDFFont::createFont(fontObject, m_document);
if (m_fontCache.size() >= m_fontCacheLimit)
if (m_fontCacheShrinkEnabled && m_fontCache.size() >= m_fontCacheLimit)
{
// We have exceeded the cache limit. Clear the cache.
m_fontCache.clear();
@ -1427,7 +1427,7 @@ PDFRealizedFontPointer PDFFontCache::getRealizedFont(const PDFFontPointer& font,
// We must create the realized font
PDFRealizedFontPointer realizedFont = PDFRealizedFont::createRealizedFont(font, size, reporter);
if (m_realizedFontCache.size() >= m_realizedFontCacheLimit)
if (m_fontCacheShrinkEnabled && m_realizedFontCache.size() >= m_realizedFontCacheLimit)
{
m_realizedFontCache.clear();
}
@ -1438,6 +1438,41 @@ PDFRealizedFontPointer PDFFontCache::getRealizedFont(const PDFFontPointer& font,
return it->second;
}
void PDFFontCache::setCacheShrinkEnabled(bool enabled)
{
if (m_fontCacheShrinkEnabled != enabled)
{
m_fontCacheShrinkEnabled = enabled;
shrink();
}
}
void PDFFontCache::setCacheLimits(int fontCacheLimit, int instancedFontCacheLimit)
{
if (m_fontCacheLimit != fontCacheLimit || m_realizedFontCacheLimit != instancedFontCacheLimit)
{
m_fontCacheLimit = fontCacheLimit;
m_realizedFontCacheLimit = instancedFontCacheLimit;
shrink();
}
}
void PDFFontCache::shrink()
{
if (m_fontCacheShrinkEnabled)
{
QMutexLocker lock(&m_mutex);
if (m_fontCache.size() >= m_fontCacheLimit)
{
m_fontCache.clear();
}
if (m_realizedFontCache.size() >= m_realizedFontCacheLimit)
{
m_realizedFontCache.clear();
}
}
}
const QByteArray* FontDescriptor::getEmbeddedFontData() const
{
if (!fontFile.isEmpty())

View File

@ -373,6 +373,7 @@ class PDFFontCache
{
public:
inline explicit PDFFontCache(size_t fontCacheLimit, size_t realizedFontCacheLimit) :
m_fontCacheShrinkEnabled(true),
m_fontCacheLimit(fontCacheLimit),
m_realizedFontCacheLimit(realizedFontCacheLimit),
m_document(nullptr)
@ -396,9 +397,20 @@ public:
/// \param reporter Error reporter
PDFRealizedFontPointer getRealizedFont(const PDFFontPointer& font, PDFReal size, PDFRenderErrorReporter* reporter) const;
/// Sets or unsets font shrinking (i.e. font can be deleted from the cache). In multithreading environment,
/// font deletion is not thread safe. For this reason, disable font deletion by calling this function.
void setCacheShrinkEnabled(bool enabled);
/// Set font cache limits
void setCacheLimits(int fontCacheLimit, int instancedFontCacheLimit);
/// If shrinking is enabled, then erase font, if cache limit is exceeded.
void shrink();
private:
const size_t m_fontCacheLimit;
const size_t m_realizedFontCacheLimit;
bool m_fontCacheShrinkEnabled;
size_t m_fontCacheLimit;
size_t m_realizedFontCacheLimit;
mutable QMutex m_mutex;
const PDFDocument* m_document;
mutable std::map<PDFObjectReference, PDFFontPointer> m_fontCache;