Page prefetching, bugfixing

This commit is contained in:
Jakub Melka
2019-12-15 17:46:58 +01:00
parent 618f334e5d
commit 3cd2dd5104
10 changed files with 94 additions and 24 deletions

View File

@@ -92,7 +92,7 @@ void PDFAsynchronousPageCompiler::reset()
start();
}
const PDFPrecompiledPage* PDFAsynchronousPageCompiler::getPrecompiledCache(PDFInteger pageIndex, bool compile)
const PDFPrecompiledPage* PDFAsynchronousPageCompiler::getCompiledPage(PDFInteger pageIndex, bool compile)
{
if (m_state != State::Active || !m_proxy->getDocument())
{
@@ -115,9 +115,8 @@ const PDFPrecompiledPage* PDFAsynchronousPageCompiler::getPrecompiledCache(PDFIn
CompileTask& task = m_tasks[pageIndex];
task.taskFuture = QtConcurrent::run(compilePage);
task.taskWatcher = new QFutureWatcher<PDFPrecompiledPage>(this);
task.taskWatcher->setFuture(task.taskFuture);
connect(task.taskWatcher, &QFutureWatcher<PDFPrecompiledPage>::finished, this, &PDFAsynchronousPageCompiler::onPageCompiled);
onPageCompiled();
task.taskWatcher->setFuture(task.taskFuture);
}
return page;

View File

@@ -66,7 +66,7 @@ public:
/// task is performed.
/// \param pageIndex Index of page
/// \param compile Compile the page, if it is not found in the cache
const PDFPrecompiledPage* getPrecompiledCache(PDFInteger pageIndex, bool compile);
const PDFPrecompiledPage* getCompiledPage(PDFInteger pageIndex, bool compile);
signals:
void pageImageChanged(bool all, const std::vector<PDFInteger>& pages);

View File

@@ -606,7 +606,7 @@ void PDFDrawWidgetProxy::draw(QPainter* painter, QRect rect)
// Clear the page space by white color
painter->fillRect(placedRect, Qt::white);
const PDFPrecompiledPage* compiledPage = m_compiler->getPrecompiledCache(item.pageIndex, true);
const PDFPrecompiledPage* compiledPage = m_compiler->getCompiledPage(item.pageIndex, true);
if (compiledPage && compiledPage->isValid())
{
QElapsedTimer timer;
@@ -676,7 +676,7 @@ QImage PDFDrawWidgetProxy::drawThumbnailImage(PDFInteger pageIndex, int pixelSiz
if (imageSize.isValid())
{
const PDFPrecompiledPage* compiledPage = m_compiler->getPrecompiledCache(pageIndex, true);
const PDFPrecompiledPage* compiledPage = m_compiler->getCompiledPage(pageIndex, true);
if (compiledPage && compiledPage->isValid())
{
// Rasterize the image.
@@ -957,6 +957,41 @@ void PDFDrawWidgetProxy::updateRenderer(bool useOpenGL, const QSurfaceFormat& su
m_rasterizer->reset(useOpenGL, surfaceFormat);
}
void PDFDrawWidgetProxy::prefetchPages(PDFInteger pageIndex)
{
// Determine number of pages, which should be prefetched. In case of two or more pages,
// we need to prefetch more pages (for example, two for two columns/two pages display mode).
int prefetchCount = 0;
switch (m_controller->getPageLayout())
{
case PageLayout::OneColumn:
case PageLayout::SinglePage:
prefetchCount = 1;
break;
case PageLayout::TwoPagesLeft:
case PageLayout::TwoPagesRight:
case PageLayout::TwoColumnLeft:
case PageLayout::TwoColumnRight:
prefetchCount = 2;
break;
default:
Q_ASSERT(false);
break;
}
if (const PDFDocument* document = getDocument())
{
const PDFInteger pageCount = document->getCatalog()->getPageCount();
const PDFInteger pageEnd = qMin(pageCount, pageIndex + prefetchCount + 1);
for (PDFInteger i = pageIndex + 1; i < pageEnd; ++i)
{
m_compiler->getCompiledPage(i, true);
}
}
}
void PDFDrawWidgetProxy::onHorizontalScrollbarValueChanged(int value)
{
if (!m_updateDisabled && !m_horizontalScrollbar->isHidden())

View File

@@ -260,6 +260,10 @@ public:
/// \param surfaceFormat Surface format for OpenGL rendering
void updateRenderer(bool useOpenGL, const QSurfaceFormat& surfaceFormat);
/// Prefetches (prerenders) pages after page with pageIndex, i.e., prepares
/// for non-flickering scroll operation.
void prefetchPages(PDFInteger pageIndex);
static constexpr PDFReal ZOOM_STEP = 1.2;
const PDFDocument* getDocument() const { return m_controller->getDocument(); }

View File

@@ -241,7 +241,7 @@ QImage PDFRasterizer::render(const PDFPage* page, const PDFPrecompiledPage* comp
compiledPage->draw(&painter, page->getCropBox(), matrix, features);
}
// Convert the image into format Format_ARGB32_Premultiplied for fast drawing.
// Jakub Melka: Convert the image into format Format_ARGB32_Premultiplied for fast drawing.
// If this format is used, then no image conversion is performed while drawing.
if (image.format() != QImage::Format_ARGB32_Premultiplied)
{
@@ -304,13 +304,15 @@ void PDFRasterizer::releaseOpenGL()
if (m_surface)
{
Q_ASSERT(m_context);
Q_ASSERT(m_fbo);
// Delete framebuffer
m_context->makeCurrent(m_surface);
delete m_fbo;
m_fbo = nullptr;
m_context->doneCurrent();
if (m_fbo)
{
m_context->makeCurrent(m_surface);
delete m_fbo;
m_fbo = nullptr;
m_context->doneCurrent();
}
// Delete OpenGL context
delete m_context;