Rendering tool + benchmarking tool

This commit is contained in:
Jakub Melka
2020-10-28 16:35:16 +01:00
parent 428e5dc2ad
commit 3c512d0e98
10 changed files with 423 additions and 44 deletions

View File

@ -374,7 +374,7 @@ public:
/// Font cache which caches both fonts, and realized fonts. Cache has individual limit
/// for fonts, and realized fonts.
class PDFFontCache
class PDFFORQTLIBSHARED_EXPORT PDFFontCache
{
public:
inline explicit PDFFontCache(size_t fontCacheLimit, size_t realizedFontCacheLimit) :

View File

@ -400,7 +400,7 @@ void PDFRasterizerPool::render(const std::vector<PDFInteger>& pageIndices,
QElapsedTimer timer;
timer.start();
emit renderError(PDFRenderError(RenderErrorType::Information, PDFTranslationContext::tr("Start at %1...").arg(QTime::currentTime().toString(Qt::TextDate))));
emit renderError(PDFCatalog::INVALID_PAGE_INDEX, PDFRenderError(RenderErrorType::Information, PDFTranslationContext::tr("Start at %1...").arg(QTime::currentTime().toString(Qt::TextDate))));
if (progress)
{
@ -419,19 +419,27 @@ void PDFRasterizerPool::render(const std::vector<PDFInteger>& pageIndices,
{
progress->step();
}
emit renderError(PDFRenderError(RenderErrorType::Error, PDFTranslationContext::tr("Page %1 not found.").arg(pageIndex)));
emit renderError(pageIndex, PDFRenderError(RenderErrorType::Error, PDFTranslationContext::tr("Page %1 not found.").arg(pageIndex)));
return;
}
QElapsedTimer totalPageTimer;
totalPageTimer.start();
QElapsedTimer pageTimer;
pageTimer.start();
// Precompile the page
PDFPrecompiledPage precompiledPage;
PDFCMSPointer cms = m_cmsManager->getCurrentCMS();
PDFRenderer renderer(m_document, m_fontCache, cms.data(), m_optionalContentActivity, m_features, m_meshQualitySettings);
renderer.compile(&precompiledPage, pageIndex);
for (const PDFRenderError error : precompiledPage.getErrors())
qint64 pageCompileTime = pageTimer.restart();
for (const PDFRenderError& error : precompiledPage.getErrors())
{
emit renderError(PDFRenderError(error.type, PDFTranslationContext::tr("Page %1: %2").arg(pageIndex + 1).arg(error.message)));
emit renderError(pageIndex, error);
}
// We can const-cast here, because we do not modify the document in annotation manager.
@ -443,12 +451,22 @@ void PDFRasterizerPool::render(const std::vector<PDFInteger>& pageIndices,
annotationManager.setDocument(modifiedDocument);
// Render page to image
pageTimer.restart();
PDFRasterizer* rasterizer = acquire();
qint64 pageWaitTime = pageTimer.restart();
QImage image = rasterizer->render(pageIndex, page, &precompiledPage, imageSizeGetter(page), m_features, &annotationManager);
qint64 pageRenderTime = pageTimer.elapsed();
release(rasterizer);
// Now, process the image
processImage(pageIndex, qMove(image));
PDFRenderedPageImage renderedPageImage;
renderedPageImage.pageIndex = pageIndex;
renderedPageImage.pageImage = qMove(image);
renderedPageImage.pageCompileTime = pageCompileTime;
renderedPageImage.pageWaitTime = pageWaitTime;
renderedPageImage.pageRenderTime = pageRenderTime;
renderedPageImage.pageTotalTime = totalPageTimer.elapsed();
processImage(renderedPageImage);
if (progress)
{
@ -462,14 +480,19 @@ void PDFRasterizerPool::render(const std::vector<PDFInteger>& pageIndices,
progress->finish();
}
emit renderError(PDFRenderError(RenderErrorType::Information, PDFTranslationContext::tr("Finished at %1...").arg(QTime::currentTime().toString(Qt::TextDate))));
emit renderError(PDFRenderError(RenderErrorType::Information, PDFTranslationContext::tr("%1 miliseconds elapsed to render %2 pages...").arg(timer.nsecsElapsed() / 1000000).arg(pageIndices.size())));
emit renderError(PDFCatalog::INVALID_PAGE_INDEX, PDFRenderError(RenderErrorType::Information, PDFTranslationContext::tr("Finished at %1...").arg(QTime::currentTime().toString(Qt::TextDate))));
emit renderError(PDFCatalog::INVALID_PAGE_INDEX, PDFRenderError(RenderErrorType::Information, PDFTranslationContext::tr("%1 miliseconds elapsed to render %2 pages...").arg(timer.nsecsElapsed() / 1000000).arg(pageIndices.size())));
}
int PDFRasterizerPool::getDefaultRasterizerCount()
{
int hint = QThread::idealThreadCount() / 2;
return qBound(1, hint, 16);
return getCorrectedRasterizerCount(hint);
}
int PDFRasterizerPool::getCorrectedRasterizerCount(int rasterizerCount)
{
return qBound(1, rasterizerCount, 16);
}
PDFImageWriterSettings::PDFImageWriterSettings()
@ -833,7 +856,7 @@ std::vector<PDFInteger> PDFPageImageExportSettings::getPages() const
return result;
}
QString PDFPageImageExportSettings::getOutputFileName(PDFInteger pageIndex, const QByteArray& outputFormat)
QString PDFPageImageExportSettings::getOutputFileName(PDFInteger pageIndex, const QByteArray& outputFormat) const
{
QString fileName = m_fileTemplate;
fileName.replace('%', QString::number(pageIndex + 1));

View File

@ -26,6 +26,7 @@
#include <QSemaphore>
#include <QImageWriter>
#include <QSurfaceFormat>
#include <QImage>
class QPainter;
class QOpenGLContext;
@ -168,6 +169,17 @@ private:
QOpenGLFramebufferObject* m_fbo;
};
/// Simple structure for storing rendered page images
struct PDFRenderedPageImage
{
qint64 pageCompileTime = 0;
qint64 pageWaitTime = 0;
qint64 pageRenderTime = 0;
qint64 pageTotalTime = 0;
PDFInteger pageIndex;
QImage pageImage;
};
/// Pool of page image renderers. It can use predefined number of renderers to
/// render page images asynchronously. You can use this object in two ways -
/// first one is as standard object pool, second one is to directly render
@ -181,8 +193,9 @@ private:
public:
using PageImageSizeGetter = std::function<QSize(const PDFPage*)>;
using ProcessImageMethod = std::function<void(PDFInteger, QImage&&)>;
using ProcessImageMethod = std::function<void(PDFRenderedPageImage&)>;
/// Creates new rasterizer pool
/// \param document Document
@ -229,8 +242,15 @@ public:
/// Returns default rasterizer count
static int getDefaultRasterizerCount();
/// Returns corrected rasterizer count (so, if user
/// select too high or too low rasterizer count, this function
/// corrects it to acceptable number.
/// \param rasterizerCount Requested number of rasterizers
/// \returns Corrected number of rasterizers
static int getCorrectedRasterizerCount(int rasterizerCount);
signals:
void renderError(PDFRenderError error);
void renderError(PDFInteger pageIndex, PDFRenderError error);
private:
const PDFDocument* m_document;
@ -344,7 +364,7 @@ public:
std::vector<PDFInteger> getPages() const;
/// Returns output file name for given page
QString getOutputFileName(PDFInteger pageIndex, const QByteArray& outputFormat);
QString getOutputFileName(PDFInteger pageIndex, const QByteArray& outputFormat) const;
static constexpr int getMinDPIResolution() { return 72; }
static constexpr int getMaxDPIResolution() { return 6000; }