mirror of https://github.com/JakubMelka/PDF4QT.git
Issue #46: Program does not launch/freezes on Windows 10/Windows Server 2022 (x64)
This commit is contained in:
parent
66c6e23346
commit
6224f226b2
|
@ -44,7 +44,7 @@ PDFWidget::PDFWidget(const PDFCMSManager* cmsManager, RendererEngine engine, int
|
||||||
m_verticalScrollBar(nullptr),
|
m_verticalScrollBar(nullptr),
|
||||||
m_proxy(nullptr)
|
m_proxy(nullptr)
|
||||||
{
|
{
|
||||||
m_drawWidget = createDrawWidget(engine, samplesCount);
|
m_drawWidget = createDrawWidget(getEffectiveRenderer(engine), samplesCount);
|
||||||
m_horizontalScrollBar = new QScrollBar(Qt::Horizontal, this);
|
m_horizontalScrollBar = new QScrollBar(Qt::Horizontal, this);
|
||||||
m_verticalScrollBar = new QScrollBar(Qt::Vertical, this);
|
m_verticalScrollBar = new QScrollBar(Qt::Vertical, this);
|
||||||
|
|
||||||
|
@ -90,6 +90,8 @@ void PDFWidget::setDocument(const PDFModifiedDocument& document)
|
||||||
|
|
||||||
void PDFWidget::updateRenderer(RendererEngine engine, int samplesCount)
|
void PDFWidget::updateRenderer(RendererEngine engine, int samplesCount)
|
||||||
{
|
{
|
||||||
|
engine = getEffectiveRenderer(engine);
|
||||||
|
|
||||||
PDFOpenGLDrawWidget* openglDrawWidget = qobject_cast<PDFOpenGLDrawWidget*>(m_drawWidget->getWidget());
|
PDFOpenGLDrawWidget* openglDrawWidget = qobject_cast<PDFOpenGLDrawWidget*>(m_drawWidget->getWidget());
|
||||||
PDFDrawWidget* softwareDrawWidget = qobject_cast<PDFDrawWidget*>(m_drawWidget->getWidget());
|
PDFDrawWidget* softwareDrawWidget = qobject_cast<PDFDrawWidget*>(m_drawWidget->getWidget());
|
||||||
|
|
||||||
|
@ -207,6 +209,16 @@ void PDFWidget::addInputInterface(IDrawWidgetInputInterface* inputInterface)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RendererEngine PDFWidget::getEffectiveRenderer(RendererEngine rendererEngine)
|
||||||
|
{
|
||||||
|
if (rendererEngine == RendererEngine::OpenGL && !pdf::PDFRendererInfo::isHardwareAccelerationSupported())
|
||||||
|
{
|
||||||
|
return RendererEngine::Software;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rendererEngine;
|
||||||
|
}
|
||||||
|
|
||||||
PDFFormManager* PDFWidget::getFormManager() const
|
PDFFormManager* PDFWidget::getFormManager() const
|
||||||
{
|
{
|
||||||
return m_formManager;
|
return m_formManager;
|
||||||
|
@ -590,10 +602,13 @@ void PDFOpenGLDrawWidget::initializeGL()
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFOpenGLDrawWidget::paintGL()
|
void PDFOpenGLDrawWidget::paintGL()
|
||||||
|
{
|
||||||
|
if (this->isValid())
|
||||||
{
|
{
|
||||||
QPainter painter(this);
|
QPainter painter(this);
|
||||||
getPDFWidget()->getDrawWidgetProxy()->draw(&painter, this->rect());
|
getPDFWidget()->getDrawWidgetProxy()->draw(&painter, this->rect());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PDFDrawWidget::PDFDrawWidget(PDFWidget* widget, QWidget* parent) :
|
PDFDrawWidget::PDFDrawWidget(PDFWidget* widget, QWidget* parent) :
|
||||||
BaseClass(widget, parent)
|
BaseClass(widget, parent)
|
||||||
|
|
|
@ -106,6 +106,8 @@ signals:
|
||||||
void pageRenderingErrorsChanged(pdf::PDFInteger pageIndex, int errorsCount);
|
void pageRenderingErrorsChanged(pdf::PDFInteger pageIndex, int errorsCount);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
RendererEngine getEffectiveRenderer(RendererEngine rendererEngine);
|
||||||
|
|
||||||
void updateRendererImpl();
|
void updateRendererImpl();
|
||||||
void onRenderingError(PDFInteger pageIndex, const QList<PDFRenderError>& errors);
|
void onRenderingError(PDFInteger pageIndex, const QList<PDFRenderError>& errors);
|
||||||
void onPageImageChanged(bool all, const std::vector<PDFInteger>& pages);
|
void onPageImageChanged(bool all, const std::vector<PDFInteger>& pages);
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <QOffscreenSurface>
|
#include <QOffscreenSurface>
|
||||||
#include <QOpenGLPaintDevice>
|
#include <QOpenGLPaintDevice>
|
||||||
#include <QOpenGLFramebufferObject>
|
#include <QOpenGLFramebufferObject>
|
||||||
|
#include <QOpenGLFunctions>
|
||||||
|
|
||||||
namespace pdf
|
namespace pdf
|
||||||
{
|
{
|
||||||
|
@ -204,6 +205,12 @@ PDFRasterizer::~PDFRasterizer()
|
||||||
|
|
||||||
void PDFRasterizer::reset(bool useOpenGL, const QSurfaceFormat& surfaceFormat)
|
void PDFRasterizer::reset(bool useOpenGL, const QSurfaceFormat& surfaceFormat)
|
||||||
{
|
{
|
||||||
|
if (!PDFRendererInfo::isHardwareAccelerationSupported())
|
||||||
|
{
|
||||||
|
m_features.setFlag(FailedOpenGL, true);
|
||||||
|
m_features.setFlag(ValidOpenGL, false);
|
||||||
|
}
|
||||||
|
|
||||||
if (useOpenGL != m_features.testFlag(UseOpenGL) || surfaceFormat != m_surfaceFormat)
|
if (useOpenGL != m_features.testFlag(UseOpenGL) || surfaceFormat != m_surfaceFormat)
|
||||||
{
|
{
|
||||||
// In either case, we must reset OpenGL
|
// In either case, we must reset OpenGL
|
||||||
|
@ -927,4 +934,78 @@ PDFRasterizerPool::PDFRasterizerPool(const PDFDocument* document,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PDFCachedItem<PDFRendererInfo::Info> PDFRendererInfo::s_info;
|
||||||
|
|
||||||
|
const PDFRendererInfo::Info& PDFRendererInfo::getHardwareAccelerationSupportedInfo()
|
||||||
|
{
|
||||||
|
auto getInfo = []()
|
||||||
|
{
|
||||||
|
Info info;
|
||||||
|
|
||||||
|
QOffscreenSurface surface;
|
||||||
|
surface.create();
|
||||||
|
|
||||||
|
if (!surface.isValid())
|
||||||
|
{
|
||||||
|
info.renderer = PDFTranslationContext::tr("Unknown Device");
|
||||||
|
info.version = PDFTranslationContext::tr("?.?");
|
||||||
|
info.vendor = PDFTranslationContext::tr("Generic");
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
QOpenGLContext context;
|
||||||
|
|
||||||
|
if (!context.create())
|
||||||
|
{
|
||||||
|
info.renderer = PDFTranslationContext::tr("Unknown Device");
|
||||||
|
info.version = PDFTranslationContext::tr("?.?");
|
||||||
|
info.vendor = PDFTranslationContext::tr("Generic");
|
||||||
|
surface.destroy();
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!context.makeCurrent(&surface))
|
||||||
|
{
|
||||||
|
info.renderer = PDFTranslationContext::tr("Unknown Device");
|
||||||
|
info.version = PDFTranslationContext::tr("?.?");
|
||||||
|
info.vendor = PDFTranslationContext::tr("Generic");
|
||||||
|
surface.destroy();
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* versionStr = reinterpret_cast<const char*>(context.functions()->glGetString(GL_VERSION));
|
||||||
|
const char* vendorStr = reinterpret_cast<const char*>(context.functions()->glGetString(GL_VENDOR));
|
||||||
|
const char* rendererStr = reinterpret_cast<const char*>(context.functions()->glGetString(GL_RENDERER));
|
||||||
|
|
||||||
|
QString versionString = QString::fromLocal8Bit(versionStr, std::strlen(versionStr));
|
||||||
|
QString vendorString = QString::fromLocal8Bit(vendorStr, std::strlen(vendorStr));
|
||||||
|
QString rendererString = QString::fromLocal8Bit(rendererStr, std::strlen(rendererStr));
|
||||||
|
|
||||||
|
context.doneCurrent();
|
||||||
|
surface.destroy();
|
||||||
|
|
||||||
|
info.vendor = vendorString;
|
||||||
|
info.renderer = rendererString;
|
||||||
|
info.version = versionString;
|
||||||
|
|
||||||
|
QStringList versionStrSplitted = versionString.split('.', Qt::KeepEmptyParts);
|
||||||
|
|
||||||
|
if (versionStrSplitted.size() >= 2)
|
||||||
|
{
|
||||||
|
info.majorOpenGLVersion = versionStrSplitted[0].toInt();
|
||||||
|
info.minorOpenGLVersion = versionStrSplitted[1].toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
};
|
||||||
|
|
||||||
|
return s_info.get(getInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PDFRendererInfo::isHardwareAccelerationSupported()
|
||||||
|
{
|
||||||
|
const Info& info = getHardwareAccelerationSupportedInfo();
|
||||||
|
return std::make_pair(info.majorOpenGLVersion, info.minorOpenGLVersion) >= std::make_pair(REQUIRED_OPENGL_MAJOR_VERSION, REQUIRED_OPENGL_MINOR_VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace pdf
|
} // namespace pdf
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "pdfexception.h"
|
#include "pdfexception.h"
|
||||||
#include "pdfoperationcontrol.h"
|
#include "pdfoperationcontrol.h"
|
||||||
#include "pdfmeshqualitysettings.h"
|
#include "pdfmeshqualitysettings.h"
|
||||||
|
#include "pdfutils.h"
|
||||||
|
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
#include <QSemaphore>
|
#include <QSemaphore>
|
||||||
|
@ -44,6 +45,30 @@ class PDFPrecompiledPage;
|
||||||
class PDFAnnotationManager;
|
class PDFAnnotationManager;
|
||||||
class PDFOptionalContentActivity;
|
class PDFOptionalContentActivity;
|
||||||
|
|
||||||
|
class PDF4QTLIBSHARED_EXPORT PDFRendererInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PDFRendererInfo() = delete;
|
||||||
|
|
||||||
|
struct Info
|
||||||
|
{
|
||||||
|
QString vendor;
|
||||||
|
QString renderer;
|
||||||
|
QString version;
|
||||||
|
int majorOpenGLVersion = 0;
|
||||||
|
int minorOpenGLVersion = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const Info& getHardwareAccelerationSupportedInfo();
|
||||||
|
static bool isHardwareAccelerationSupported();
|
||||||
|
|
||||||
|
static constexpr int REQUIRED_OPENGL_MAJOR_VERSION = 3;
|
||||||
|
static constexpr int REQUIRED_OPENGL_MINOR_VERSION = 2;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static PDFCachedItem<Info> s_info;
|
||||||
|
};
|
||||||
|
|
||||||
/// Renders the PDF page on the painter, or onto an image.
|
/// Renders the PDF page on the painter, or onto an image.
|
||||||
class PDF4QTLIBSHARED_EXPORT PDFRenderer
|
class PDF4QTLIBSHARED_EXPORT PDFRenderer
|
||||||
{
|
{
|
||||||
|
@ -144,8 +169,9 @@ public:
|
||||||
|
|
||||||
/// Resets the renderer. This function must be called from main GUI thread,
|
/// Resets the renderer. This function must be called from main GUI thread,
|
||||||
/// it cannot be called from deferred threads, because it can create hidden
|
/// it cannot be called from deferred threads, because it can create hidden
|
||||||
/// window (offscreen surface).
|
/// window (offscreen surface). If hardware renderer is required, and
|
||||||
/// \param useOpenGL Use OpenGL for rendering
|
/// none is available, then software renderer is used.
|
||||||
|
/// \param useOpenGL Use OpenGL for rendering (ignored if not available)
|
||||||
/// \param surfaceFormat Surface format to render
|
/// \param surfaceFormat Surface format to render
|
||||||
void reset(bool useOpenGL, const QSurfaceFormat& surfaceFormat);
|
void reset(bool useOpenGL, const QSurfaceFormat& surfaceFormat);
|
||||||
|
|
||||||
|
|
|
@ -2028,6 +2028,20 @@ void PDFProgramController::resetSettings()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PDFProgramController::checkHardwareOpenGLAvailability()
|
||||||
|
{
|
||||||
|
if (m_settings->getRendererEngine() == pdf::RendererEngine::OpenGL &&
|
||||||
|
!pdf::PDFRendererInfo::isHardwareAccelerationSupported())
|
||||||
|
{
|
||||||
|
pdf::PDFRendererInfo::Info info = pdf::PDFRendererInfo::getHardwareAccelerationSupportedInfo();
|
||||||
|
QMessageBox::warning(m_mainWindow, tr("Warning"),
|
||||||
|
tr("Hardware acceleration is not supported on this device. "
|
||||||
|
"OpenGL version at least 3.2 is required. Software rendering is used instead. "
|
||||||
|
"Available OpenGL is %1 using %2. You can turn off hardware acceleration "
|
||||||
|
"in 'Tools' menu using 'Options' item to stop displaying this message.").arg(info.version, info.renderer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PDFProgramController::onActionOptionsTriggered()
|
void PDFProgramController::onActionOptionsTriggered()
|
||||||
{
|
{
|
||||||
PDFViewerSettingsDialog::OtherSettings otherSettings;
|
PDFViewerSettingsDialog::OtherSettings otherSettings;
|
||||||
|
|
|
@ -276,6 +276,8 @@ public:
|
||||||
void writeSettings();
|
void writeSettings();
|
||||||
void resetSettings();
|
void resetSettings();
|
||||||
|
|
||||||
|
void checkHardwareOpenGLAvailability();
|
||||||
|
|
||||||
void performPrint();
|
void performPrint();
|
||||||
void performSave();
|
void performSave();
|
||||||
void performSaveAs();
|
void performSaveAs();
|
||||||
|
|
|
@ -523,6 +523,7 @@ void PDFViewerMainWindow::showEvent(QShowEvent* event)
|
||||||
{
|
{
|
||||||
QMainWindow::showEvent(event);
|
QMainWindow::showEvent(event);
|
||||||
m_progressTaskbarIndicator->setWindow(windowHandle());
|
m_progressTaskbarIndicator->setWindow(windowHandle());
|
||||||
|
QTimer::singleShot(0, this, [this] { m_programController->checkHardwareOpenGLAvailability(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFViewerMainWindow::dragEnterEvent(QDragEnterEvent* event)
|
void PDFViewerMainWindow::dragEnterEvent(QDragEnterEvent* event)
|
||||||
|
|
|
@ -412,8 +412,9 @@ void PDFViewerMainWindowLite::closeEvent(QCloseEvent* event)
|
||||||
|
|
||||||
void PDFViewerMainWindowLite::showEvent(QShowEvent* event)
|
void PDFViewerMainWindowLite::showEvent(QShowEvent* event)
|
||||||
{
|
{
|
||||||
Q_UNUSED(event);
|
QMainWindow::showEvent(event);
|
||||||
m_progressTaskbarIndicator->setWindow(windowHandle());
|
m_progressTaskbarIndicator->setWindow(windowHandle());
|
||||||
|
QTimer::singleShot(0, this, [this] { m_programController->checkHardwareOpenGLAvailability(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFViewerMainWindowLite::dragEnterEvent(QDragEnterEvent* event)
|
void PDFViewerMainWindowLite::dragEnterEvent(QDragEnterEvent* event)
|
||||||
|
|
Loading…
Reference in New Issue