From 122128eae56840775132bd2bbe1f856149db5aa3 Mon Sep 17 00:00:00 2001 From: Adam Higerd Date: Tue, 19 Nov 2024 17:20:48 -0600 Subject: [PATCH] Qt: load unpacked shaders, warn on shader load error --- src/platform/qt/Display.h | 2 +- src/platform/qt/DisplayGL.cpp | 16 +++++++++----- src/platform/qt/DisplayGL.h | 4 ++-- src/platform/qt/DisplayQt.h | 2 +- src/platform/qt/ShaderSelector.cpp | 34 ++++++++++++++++++++---------- 5 files changed, 38 insertions(+), 20 deletions(-) diff --git a/src/platform/qt/Display.h b/src/platform/qt/Display.h index 3cc2fc61f..ef525162f 100644 --- a/src/platform/qt/Display.h +++ b/src/platform/qt/Display.h @@ -81,7 +81,7 @@ public slots: virtual void filter(bool filter); virtual void swapInterval(int interval) = 0; virtual void framePosted() = 0; - virtual void setShaders(struct VDir*) = 0; + virtual bool setShaders(struct VDir*) = 0; virtual void clearShaders() = 0; virtual void resizeContext() = 0; diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index e62e9685e..b3a7d62c8 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -462,8 +462,10 @@ void DisplayGL::framePosted() { QMetaObject::invokeMethod(m_painter.get(), "draw"); } -void DisplayGL::setShaders(struct VDir* shaders) { - QMetaObject::invokeMethod(m_painter.get(), "setShaders", Qt::BlockingQueuedConnection, Q_ARG(struct VDir*, shaders)); +bool DisplayGL::setShaders(struct VDir* shaders) { + bool success = false; + QMetaObject::invokeMethod(m_painter.get(), "setShaders", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, success), Q_ARG(struct VDir*, shaders)); + return success; } void DisplayGL::clearShaders() { @@ -996,10 +998,11 @@ void PainterGL::interrupt() { m_interrupter.interrupt(m_context); } -void PainterGL::setShaders(struct VDir* dir) { +bool PainterGL::setShaders(struct VDir* dir) { if (!supportsShaders()) { - return; + return false; } + bool success = false; #if defined(BUILD_GLES2) || defined(BUILD_GLES3) if (!m_started) { makeCurrent(); @@ -1009,7 +1012,9 @@ void PainterGL::setShaders(struct VDir* dir) { mGLES2ShaderDetach(reinterpret_cast(m_backend)); mGLES2ShaderFree(&m_shader); } - if (mGLES2ShaderLoad(&m_shader, dir)) { + + success = mGLES2ShaderLoad(&m_shader, dir); + if (success) { mGLES2ShaderAttach(reinterpret_cast(m_backend), static_cast(m_shader.passes), m_shader.nPasses); } @@ -1017,6 +1022,7 @@ void PainterGL::setShaders(struct VDir* dir) { m_gl->doneCurrent(); } #endif + return success; } void PainterGL::clearShaders() { diff --git a/src/platform/qt/DisplayGL.h b/src/platform/qt/DisplayGL.h index 5b0aab2cd..18a7f7911 100644 --- a/src/platform/qt/DisplayGL.h +++ b/src/platform/qt/DisplayGL.h @@ -113,7 +113,7 @@ public slots: void filter(bool filter) override; void swapInterval(int interval) override; void framePosted() override; - void setShaders(struct VDir*) override; + bool setShaders(struct VDir*) override; void clearShaders() override; void resizeContext() override; void setVideoScale(int scale) override; @@ -184,7 +184,7 @@ public slots: void resizeContext(); void setBackgroundImage(const QImage&); - void setShaders(struct VDir*); + bool setShaders(struct VDir*); void clearShaders(); VideoShader* shaders(); QSize contentSize() const; diff --git a/src/platform/qt/DisplayQt.h b/src/platform/qt/DisplayQt.h index a6816a18b..8a3ec988e 100644 --- a/src/platform/qt/DisplayQt.h +++ b/src/platform/qt/DisplayQt.h @@ -41,7 +41,7 @@ public slots: void swapInterval(int) override {}; void filter(bool filter) override; void framePosted() override; - void setShaders(struct VDir*) override {} + bool setShaders(struct VDir*) override { return false; } void clearShaders() override {} void resizeContext() override; void setBackgroundImage(const QImage&) override; diff --git a/src/platform/qt/ShaderSelector.cpp b/src/platform/qt/ShaderSelector.cpp index 473b1d7e9..204ad7252 100644 --- a/src/platform/qt/ShaderSelector.cpp +++ b/src/platform/qt/ShaderSelector.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -50,7 +51,7 @@ ShaderSelector::~ShaderSelector() { } void ShaderSelector::saveSettings() { - QString oldPath = config->getOption("shader"); + QString oldPath = m_config->getOption("shader"); if (oldPath != m_shaderPath) { if (m_shaderPath.isEmpty()) { clearShader(true); @@ -88,7 +89,8 @@ void ShaderSelector::selectShader() { #if !defined(USE_LIBZIP) && !defined(USE_MINIZIP) QString name = GBAApp::app()->getOpenDirectoryName(this, tr("Load shader"), path.absolutePath()); #else - QString name = GBAApp::app()->getOpenFileName(this, tr("Load shader"), "mGBA Shaders (*.shader)", path.absolutePath()); + QString filters = QStringLiteral("%1 (*.shader manifest.ini)").arg(tr("mGBA Shaders")); + QString name = GBAApp::app()->getOpenFileName(this, tr("Load shader"), filters, path.absolutePath()); #endif if (!name.isNull()) { loadShader(name); @@ -97,18 +99,28 @@ void ShaderSelector::selectShader() { } void ShaderSelector::loadShader(const QString& path, bool saveToSettings) { - VDir* shader = VFileDevice::openDir(path); - if (!shader) { - shader = VFileDevice::openArchive(path); + static const QString manifestIni = "/manifest.ini"; + QString shaderPath = path; + if (shaderPath.endsWith(manifestIni)) { + shaderPath.chop(manifestIni.length()); } + VDir* shader = VFileDevice::openDir(shaderPath); if (!shader) { - return; + shader = VFileDevice::openArchive(shaderPath); } - m_display->setShaders(shader); - shader->close(shader); - m_shaderPath = path; - if (saveToSettings) { - m_config->setOption("shader", path); + bool error = !shader || !m_display->setShaders(shader); + if (!error) { + if (saveToSettings) { + m_config->setOption("shader", shaderPath); + } + m_shaderPath = shaderPath; + refreshShaders(); + } + if (shader) { + shader->close(shader); + } + if (error) { + QMessageBox::warning(this, tr("Error loading shader"), tr("The shader \"%1\" could not be loaded successfully.").arg(shaderPath)); } }