Qt: load unpacked shaders, warn on shader load error

This commit is contained in:
Adam Higerd 2024-11-19 17:20:48 -06:00 committed by Vicki Pfau
parent a2e7e5b902
commit 122128eae5
5 changed files with 38 additions and 20 deletions

View File

@ -81,7 +81,7 @@ public slots:
virtual void filter(bool filter); virtual void filter(bool filter);
virtual void swapInterval(int interval) = 0; virtual void swapInterval(int interval) = 0;
virtual void framePosted() = 0; virtual void framePosted() = 0;
virtual void setShaders(struct VDir*) = 0; virtual bool setShaders(struct VDir*) = 0;
virtual void clearShaders() = 0; virtual void clearShaders() = 0;
virtual void resizeContext() = 0; virtual void resizeContext() = 0;

View File

@ -462,8 +462,10 @@ void DisplayGL::framePosted() {
QMetaObject::invokeMethod(m_painter.get(), "draw"); QMetaObject::invokeMethod(m_painter.get(), "draw");
} }
void DisplayGL::setShaders(struct VDir* shaders) { bool DisplayGL::setShaders(struct VDir* shaders) {
QMetaObject::invokeMethod(m_painter.get(), "setShaders", Qt::BlockingQueuedConnection, Q_ARG(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() { void DisplayGL::clearShaders() {
@ -996,10 +998,11 @@ void PainterGL::interrupt() {
m_interrupter.interrupt(m_context); m_interrupter.interrupt(m_context);
} }
void PainterGL::setShaders(struct VDir* dir) { bool PainterGL::setShaders(struct VDir* dir) {
if (!supportsShaders()) { if (!supportsShaders()) {
return; return false;
} }
bool success = false;
#if defined(BUILD_GLES2) || defined(BUILD_GLES3) #if defined(BUILD_GLES2) || defined(BUILD_GLES3)
if (!m_started) { if (!m_started) {
makeCurrent(); makeCurrent();
@ -1009,7 +1012,9 @@ void PainterGL::setShaders(struct VDir* dir) {
mGLES2ShaderDetach(reinterpret_cast<mGLES2Context*>(m_backend)); mGLES2ShaderDetach(reinterpret_cast<mGLES2Context*>(m_backend));
mGLES2ShaderFree(&m_shader); mGLES2ShaderFree(&m_shader);
} }
if (mGLES2ShaderLoad(&m_shader, dir)) {
success = mGLES2ShaderLoad(&m_shader, dir);
if (success) {
mGLES2ShaderAttach(reinterpret_cast<mGLES2Context*>(m_backend), static_cast<mGLES2Shader*>(m_shader.passes), m_shader.nPasses); mGLES2ShaderAttach(reinterpret_cast<mGLES2Context*>(m_backend), static_cast<mGLES2Shader*>(m_shader.passes), m_shader.nPasses);
} }
@ -1017,6 +1022,7 @@ void PainterGL::setShaders(struct VDir* dir) {
m_gl->doneCurrent(); m_gl->doneCurrent();
} }
#endif #endif
return success;
} }
void PainterGL::clearShaders() { void PainterGL::clearShaders() {

View File

@ -113,7 +113,7 @@ public slots:
void filter(bool filter) override; void filter(bool filter) override;
void swapInterval(int interval) override; void swapInterval(int interval) override;
void framePosted() override; void framePosted() override;
void setShaders(struct VDir*) override; bool setShaders(struct VDir*) override;
void clearShaders() override; void clearShaders() override;
void resizeContext() override; void resizeContext() override;
void setVideoScale(int scale) override; void setVideoScale(int scale) override;
@ -184,7 +184,7 @@ public slots:
void resizeContext(); void resizeContext();
void setBackgroundImage(const QImage&); void setBackgroundImage(const QImage&);
void setShaders(struct VDir*); bool setShaders(struct VDir*);
void clearShaders(); void clearShaders();
VideoShader* shaders(); VideoShader* shaders();
QSize contentSize() const; QSize contentSize() const;

View File

@ -41,7 +41,7 @@ public slots:
void swapInterval(int) override {}; void swapInterval(int) override {};
void filter(bool filter) override; void filter(bool filter) override;
void framePosted() override; void framePosted() override;
void setShaders(struct VDir*) override {} bool setShaders(struct VDir*) override { return false; }
void clearShaders() override {} void clearShaders() override {}
void resizeContext() override; void resizeContext() override;
void setBackgroundImage(const QImage&) override; void setBackgroundImage(const QImage&) override;

View File

@ -16,6 +16,7 @@
#include <QFileDialog> #include <QFileDialog>
#include <QFormLayout> #include <QFormLayout>
#include <QGridLayout> #include <QGridLayout>
#include <QMessageBox>
#include <QSpinBox> #include <QSpinBox>
#include <mgba/core/version.h> #include <mgba/core/version.h>
@ -50,7 +51,7 @@ ShaderSelector::~ShaderSelector() {
} }
void ShaderSelector::saveSettings() { void ShaderSelector::saveSettings() {
QString oldPath = config->getOption("shader"); QString oldPath = m_config->getOption("shader");
if (oldPath != m_shaderPath) { if (oldPath != m_shaderPath) {
if (m_shaderPath.isEmpty()) { if (m_shaderPath.isEmpty()) {
clearShader(true); clearShader(true);
@ -88,7 +89,8 @@ void ShaderSelector::selectShader() {
#if !defined(USE_LIBZIP) && !defined(USE_MINIZIP) #if !defined(USE_LIBZIP) && !defined(USE_MINIZIP)
QString name = GBAApp::app()->getOpenDirectoryName(this, tr("Load shader"), path.absolutePath()); QString name = GBAApp::app()->getOpenDirectoryName(this, tr("Load shader"), path.absolutePath());
#else #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 #endif
if (!name.isNull()) { if (!name.isNull()) {
loadShader(name); loadShader(name);
@ -97,18 +99,28 @@ void ShaderSelector::selectShader() {
} }
void ShaderSelector::loadShader(const QString& path, bool saveToSettings) { void ShaderSelector::loadShader(const QString& path, bool saveToSettings) {
VDir* shader = VFileDevice::openDir(path); static const QString manifestIni = "/manifest.ini";
if (!shader) { QString shaderPath = path;
shader = VFileDevice::openArchive(path); if (shaderPath.endsWith(manifestIni)) {
shaderPath.chop(manifestIni.length());
} }
VDir* shader = VFileDevice::openDir(shaderPath);
if (!shader) { if (!shader) {
return; shader = VFileDevice::openArchive(shaderPath);
} }
m_display->setShaders(shader); bool error = !shader || !m_display->setShaders(shader);
shader->close(shader); if (!error) {
m_shaderPath = path; if (saveToSettings) {
if (saveToSettings) { m_config->setOption("shader", shaderPath);
m_config->setOption("shader", path); }
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));
} }
} }