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_proxy(nullptr)
|
||||
{
|
||||
m_drawWidget = createDrawWidget(engine, samplesCount);
|
||||
m_drawWidget = createDrawWidget(getEffectiveRenderer(engine), samplesCount);
|
||||
m_horizontalScrollBar = new QScrollBar(Qt::Horizontal, 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)
|
||||
{
|
||||
engine = getEffectiveRenderer(engine);
|
||||
|
||||
PDFOpenGLDrawWidget* openglDrawWidget = qobject_cast<PDFOpenGLDrawWidget*>(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
|
||||
{
|
||||
return m_formManager;
|
||||
|
@ -591,8 +603,11 @@ void PDFOpenGLDrawWidget::initializeGL()
|
|||
|
||||
void PDFOpenGLDrawWidget::paintGL()
|
||||
{
|
||||
if (this->isValid())
|
||||
{
|
||||
QPainter painter(this);
|
||||
getPDFWidget()->getDrawWidgetProxy()->draw(&painter, this->rect());
|
||||
}
|
||||
}
|
||||
|
||||
PDFDrawWidget::PDFDrawWidget(PDFWidget* widget, QWidget* parent) :
|
||||
|
|
|
@ -106,6 +106,8 @@ signals:
|
|||
void pageRenderingErrorsChanged(pdf::PDFInteger pageIndex, int errorsCount);
|
||||
|
||||
private:
|
||||
RendererEngine getEffectiveRenderer(RendererEngine rendererEngine);
|
||||
|
||||
void updateRendererImpl();
|
||||
void onRenderingError(PDFInteger pageIndex, const QList<PDFRenderError>& errors);
|
||||
void onPageImageChanged(bool all, const std::vector<PDFInteger>& pages);
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <QOffscreenSurface>
|
||||
#include <QOpenGLPaintDevice>
|
||||
#include <QOpenGLFramebufferObject>
|
||||
#include <QOpenGLFunctions>
|
||||
|
||||
namespace pdf
|
||||
{
|
||||
|
@ -204,6 +205,12 @@ PDFRasterizer::~PDFRasterizer()
|
|||
|
||||
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)
|
||||
{
|
||||
// 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
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "pdfexception.h"
|
||||
#include "pdfoperationcontrol.h"
|
||||
#include "pdfmeshqualitysettings.h"
|
||||
#include "pdfutils.h"
|
||||
|
||||
#include <QMutex>
|
||||
#include <QSemaphore>
|
||||
|
@ -44,6 +45,30 @@ class PDFPrecompiledPage;
|
|||
class PDFAnnotationManager;
|
||||
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.
|
||||
class PDF4QTLIBSHARED_EXPORT PDFRenderer
|
||||
{
|
||||
|
@ -144,8 +169,9 @@ public:
|
|||
|
||||
/// Resets the renderer. This function must be called from main GUI thread,
|
||||
/// it cannot be called from deferred threads, because it can create hidden
|
||||
/// window (offscreen surface).
|
||||
/// \param useOpenGL Use OpenGL for rendering
|
||||
/// window (offscreen surface). If hardware renderer is required, and
|
||||
/// none is available, then software renderer is used.
|
||||
/// \param useOpenGL Use OpenGL for rendering (ignored if not available)
|
||||
/// \param surfaceFormat Surface format to render
|
||||
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()
|
||||
{
|
||||
PDFViewerSettingsDialog::OtherSettings otherSettings;
|
||||
|
|
|
@ -276,6 +276,8 @@ public:
|
|||
void writeSettings();
|
||||
void resetSettings();
|
||||
|
||||
void checkHardwareOpenGLAvailability();
|
||||
|
||||
void performPrint();
|
||||
void performSave();
|
||||
void performSaveAs();
|
||||
|
|
|
@ -523,6 +523,7 @@ void PDFViewerMainWindow::showEvent(QShowEvent* event)
|
|||
{
|
||||
QMainWindow::showEvent(event);
|
||||
m_progressTaskbarIndicator->setWindow(windowHandle());
|
||||
QTimer::singleShot(0, this, [this] { m_programController->checkHardwareOpenGLAvailability(); });
|
||||
}
|
||||
|
||||
void PDFViewerMainWindow::dragEnterEvent(QDragEnterEvent* event)
|
||||
|
|
|
@ -412,8 +412,9 @@ void PDFViewerMainWindowLite::closeEvent(QCloseEvent* event)
|
|||
|
||||
void PDFViewerMainWindowLite::showEvent(QShowEvent* event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
QMainWindow::showEvent(event);
|
||||
m_progressTaskbarIndicator->setWindow(windowHandle());
|
||||
QTimer::singleShot(0, this, [this] { m_programController->checkHardwareOpenGLAvailability(); });
|
||||
}
|
||||
|
||||
void PDFViewerMainWindowLite::dragEnterEvent(QDragEnterEvent* event)
|
||||
|
|
Loading…
Reference in New Issue