diff --git a/CHANGES b/CHANGES index 10831f0c2..ae7e136e4 100644 --- a/CHANGES +++ b/CHANGES @@ -57,6 +57,7 @@ Other fixes: - Qt: Fix some hangs when using the debugger console - Qt: Fix crash when clicking past last tile in viewer - Qt: Fix preloading for ROM replacing + - Qt: Fix screen not displaying on Wayland (fixes mgba.io/i/2190) - VFS: Failed file mapping should return NULL on POSIX Misc: - Core: Suspend runloop when a core crashes diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 221acffc0..dd683b781 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -56,10 +56,13 @@ uint qHash(const QSurfaceFormat& format, uint seed) { } void mGLWidget::initializeGL() { - m_vao.create(); - m_program.create(); + m_vao = std::make_unique(); + m_vao->create(); - m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, R"(#version 150 core + m_program = std::make_unique(); + m_program->create(); + + m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, R"(#version 150 core in vec4 position; out vec2 texCoord; void main() { @@ -67,7 +70,7 @@ void mGLWidget::initializeGL() { texCoord = (position.st + 1.0) * 0.5; })"); - m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, R"(#version 150 core + m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, R"(#version 150 core in vec2 texCoord; out vec4 color; uniform sampler2D tex; @@ -75,9 +78,9 @@ void mGLWidget::initializeGL() { color = vec4(texture(tex, texCoord).rgb, 1.0); })"); - m_program.link(); - m_program.setUniformValue("tex", 0); - m_positionLocation = m_program.attributeLocation("position"); + m_program->link(); + m_program->setUniformValue("tex", 0); + m_positionLocation = m_program->attributeLocation("position"); connect(&m_refresh, &QTimer::timeout, this, static_cast(&QWidget::update)); } @@ -85,11 +88,11 @@ void mGLWidget::initializeGL() { void mGLWidget::finalizeVAO() { QOpenGLFunctions_Baseline* fn = context()->versionFunctions(); fn->glGetError(); // Clear the error - m_vao.bind(); + m_vao->bind(); fn->glBindBuffer(GL_ARRAY_BUFFER, m_vbo); fn->glEnableVertexAttribArray(m_positionLocation); fn->glVertexAttribPointer(m_positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); - m_vao.release(); + m_vao->release(); if (fn->glGetError() == GL_NO_ERROR) { m_vaoDone = true; } @@ -100,13 +103,13 @@ void mGLWidget::paintGL() { finalizeVAO(); } QOpenGLFunctions_Baseline* fn = context()->versionFunctions(); - m_program.bind(); - m_vao.bind(); + m_program->bind(); + m_vao->bind(); fn->glBindTexture(GL_TEXTURE_2D, m_tex); fn->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); fn->glBindTexture(GL_TEXTURE_2D, 0); - m_vao.release(); - m_program.release(); + m_vao->release(); + m_program->release(); // TODO: Better timing ++m_refreshResidue; diff --git a/src/platform/qt/DisplayGL.h b/src/platform/qt/DisplayGL.h index 54256ed30..a75f1a8dd 100644 --- a/src/platform/qt/DisplayGL.h +++ b/src/platform/qt/DisplayGL.h @@ -32,6 +32,7 @@ #include #include +#include #include "CoreController.h" #include "VideoProxy.h" @@ -62,8 +63,8 @@ private: GLuint m_vbo; bool m_vaoDone = false; - QOpenGLVertexArrayObject m_vao; - QOpenGLShaderProgram m_program; + std::unique_ptr m_vao; + std::unique_ptr m_program; GLuint m_positionLocation; QTimer m_refresh; diff --git a/src/platform/qt/LoadSaveState.cpp b/src/platform/qt/LoadSaveState.cpp index aa76ed523..3198a4c90 100644 --- a/src/platform/qt/LoadSaveState.cpp +++ b/src/platform/qt/LoadSaveState.cpp @@ -9,6 +9,7 @@ #include "GamepadAxisEvent.h" #include "GamepadButtonEvent.h" #include "VFileDevice.h" +#include "utils.h" #include #include @@ -251,6 +252,10 @@ void LoadSaveState::focusInEvent(QFocusEvent*) { void LoadSaveState::paintEvent(QPaintEvent*) { QPainter painter(this); + + painter.setRenderHint(QPainter::SmoothPixmapTransform, true); QRect full(QPoint(), size()); + painter.fillRect(full, Qt::black); + painter.drawPixmap(clampSize(m_dims, size(), m_lockAspectRatio, m_lockIntegerScaling), m_background); painter.fillRect(full, QColor(0, 0, 0, 128)); } diff --git a/src/platform/qt/LoadSaveState.h b/src/platform/qt/LoadSaveState.h index 5596c1b10..f74e5b24b 100644 --- a/src/platform/qt/LoadSaveState.h +++ b/src/platform/qt/LoadSaveState.h @@ -32,6 +32,10 @@ public: void setInputController(InputController* controller); void setMode(LoadSave mode); + void setBackground(const QPixmap& pixmap) { m_background = pixmap; } + void setDimensions(const QSize& dims) { m_dims = dims; } + void setLockIntegerScaling(bool lockIntegerScaling) { m_lockIntegerScaling = lockIntegerScaling; } + void setLockAspectRatio(bool lockApsectRatio) { m_lockAspectRatio = lockApsectRatio; } signals: void closed(); @@ -54,6 +58,11 @@ private: int m_currentFocus; QPixmap m_currentImage; + QPixmap m_background; + + QSize m_dims; + bool m_lockAspectRatio; + bool m_lockIntegerScaling; }; } diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index c32662fb8..9a2551503 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #ifdef USE_SQLITE3 @@ -58,7 +57,6 @@ #include "TileView.h" #include "VideoProxy.h" #include "VideoView.h" -#include "utils.h" #ifdef USE_DISCORD_RPC #include "DiscordCoordinator.h" @@ -113,14 +111,12 @@ Window::Window(CoreManager* manager, ConfigController* config, int playerId, QWi m_libraryView = new LibraryController(nullptr, ConfigController::configDir() + "/library.sqlite3", m_config); ConfigOption* showLibrary = m_config->addOption("showLibrary"); showLibrary->connect([this](const QVariant& value) { - if (value.toBool()) { - if (m_controller) { - m_screenWidget->layout()->addWidget(m_libraryView); - } else { + if (!m_controller) { + if (value.toBool()) { attachWidget(m_libraryView); + } else { + attachWidget(m_screenWidget); } - } else { - detachWidget(m_libraryView); } }, this); m_config->updateOption("showLibrary"); @@ -150,7 +146,6 @@ Window::Window(CoreManager* manager, ConfigController* config, int playerId, QWi resizeFrame(QSize(GB_VIDEO_HORIZONTAL_PIXELS * i, GB_VIDEO_VERTICAL_PIXELS * i)); #endif setLogo(); - setCentralWidget(m_screenWidget); connect(this, &Window::shutdown, m_logView, &QWidget::hide); connect(&m_fpsTimer, &QTimer::timeout, this, &Window::showFPS); @@ -883,7 +878,6 @@ void Window::gameStarted() { action.value()->setEnabled(m_controller->platform() == action.key()); } QSize size = m_controller->screenDimensions(); - m_screenWidget->setDimensions(size.width(), size.height()); m_config->updateOption("lockIntegerScaling"); m_config->updateOption("lockAspectRatio"); m_config->updateOption("interframeBlending"); @@ -977,7 +971,6 @@ void Window::gameStopped() { m_audioProcessor.reset(); } m_display->stopDrawing(); - detachWidget(m_display.get()); setLogo(); if (m_display) { #ifdef M_CORE_GB @@ -988,6 +981,7 @@ void Window::gameStopped() { } m_controller.reset(); + detachWidget(); updateTitle(); if (m_pendingClose) { @@ -1039,7 +1033,7 @@ void Window::unimplementedBiosCall(int) { void Window::reloadDisplayDriver() { if (m_controller) { m_display->stopDrawing(); - detachWidget(m_display.get()); + detachWidget(); } m_display = std::unique_ptr(Display::create(this)); if (!m_display) { @@ -1054,7 +1048,7 @@ void Window::reloadDisplayDriver() { #endif connect(m_display.get(), &QGBA::Display::hideCursor, [this]() { - if (static_cast(m_screenWidget->layout())->currentWidget() == m_display.get()) { + if (centralWidget() == m_display.get()) { m_screenWidget->setCursor(Qt::BlankCursor); } }); @@ -1215,15 +1209,13 @@ void Window::openStateWindow(LoadSave ls) { m_stateWindow = new LoadSaveState(m_controller); connect(this, &Window::shutdown, m_stateWindow, &QWidget::close); connect(m_stateWindow, &LoadSaveState::closed, [this]() { - detachWidget(m_stateWindow); - static_cast(m_screenWidget->layout())->setCurrentWidget(m_display.get()); + attachWidget(m_display.get()); m_stateWindow = nullptr; QMetaObject::invokeMethod(this, "setFocus", Qt::QueuedConnection); }); if (!wasPaused) { m_controller->setPaused(true); connect(m_stateWindow, &LoadSaveState::closed, [this]() { - m_screenWidget->filter(m_config->getOption("resampleVideo").toInt()); if (m_controller) { m_controller->setPaused(false); } @@ -1232,6 +1224,10 @@ void Window::openStateWindow(LoadSave ls) { m_stateWindow->setAttribute(Qt::WA_DeleteOnClose); m_stateWindow->setMode(ls); + m_stateWindow->setDimensions(m_controller->screenDimensions()); + m_config->updateOption("lockAspectRatio"); + m_config->updateOption("lockIntegerScaling"); + QImage still(m_controller->getPixels()); if (still.format() != QImage::Format_RGB888) { still = still.convertToFormat(QImage::Format_RGB888); @@ -1249,8 +1245,7 @@ void Window::openStateWindow(LoadSave ls) { QPixmap pixmap; pixmap.convertFromImage(output); - m_screenWidget->setPixmap(pixmap); - m_screenWidget->filter(true); + m_stateWindow->setBackground(pixmap); #ifndef Q_OS_MAC menuBar()->show(); @@ -1536,8 +1531,8 @@ void Window::setupMenu(QMenuBar* menubar) { if (m_display) { m_display->lockAspectRatio(value.toBool()); } - if (m_controller) { - m_screenWidget->setLockAspectRatio(value.toBool()); + if (m_stateWindow) { + m_stateWindow->setLockAspectRatio(value.toBool()); } }, this); m_config->updateOption("lockAspectRatio"); @@ -1548,8 +1543,8 @@ void Window::setupMenu(QMenuBar* menubar) { if (m_display) { m_display->lockIntegerScaling(value.toBool()); } - if (m_controller) { - m_screenWidget->setLockIntegerScaling(value.toBool()); + if (m_stateWindow) { + m_stateWindow->setLockIntegerScaling(value.toBool()); } }, this); m_config->updateOption("lockIntegerScaling"); @@ -1569,9 +1564,6 @@ void Window::setupMenu(QMenuBar* menubar) { if (m_display) { m_display->filter(value.toBool()); } - if (m_controller) { - m_screenWidget->filter(value.toBool()); - } }, this); m_config->updateOption("resampleVideo"); @@ -1894,13 +1886,12 @@ void Window::setupOptions() { } void Window::attachWidget(QWidget* widget) { - m_screenWidget->layout()->addWidget(widget); - m_screenWidget->unsetCursor(); - static_cast(m_screenWidget->layout())->setCurrentWidget(widget); + takeCentralWidget(); + setCentralWidget(widget); } -void Window::detachWidget(QWidget* widget) { - m_screenWidget->layout()->removeWidget(widget); +void Window::detachWidget() { + m_config->updateOption("showLibrary"); } void Window::appendMRU(const QString& fname) { @@ -1996,7 +1987,7 @@ void Window::focusCheck() { } void Window::updateFrame() { - if (static_cast(m_screenWidget->layout())->currentWidget() != m_display.get()) { + if (!m_controller) { return; } QPixmap pixmap; @@ -2171,17 +2162,12 @@ void Window::updateMute() { void Window::setLogo() { m_screenWidget->setPixmap(m_logo); m_screenWidget->setDimensions(m_logo.width(), m_logo.height()); - m_screenWidget->setLockIntegerScaling(false); - m_screenWidget->setLockAspectRatio(true); - m_screenWidget->filter(true); m_screenWidget->unsetCursor(); } WindowBackground::WindowBackground(QWidget* parent) : QWidget(parent) { - setLayout(new QStackedLayout()); - layout()->setContentsMargins(0, 0, 0, 0); } void WindowBackground::setPixmap(const QPixmap& pmap) { @@ -2202,24 +2188,12 @@ void WindowBackground::setDimensions(int width, int height) { m_aspectHeight = height; } -void WindowBackground::setLockIntegerScaling(bool lock) { - m_lockIntegerScaling = lock; -} - -void WindowBackground::setLockAspectRatio(bool lock) { - m_lockAspectRatio = lock; -} - -void WindowBackground::filter(bool filter) { - m_filter = filter; -} - void WindowBackground::paintEvent(QPaintEvent* event) { QWidget::paintEvent(event); const QPixmap& logo = pixmap(); QPainter painter(this); - painter.setRenderHint(QPainter::SmoothPixmapTransform, m_filter); + painter.setRenderHint(QPainter::SmoothPixmapTransform, true); painter.fillRect(QRect(QPoint(), size()), Qt::black); - QRect full(clampSize(QSize(m_aspectWidth, m_aspectHeight), size(), m_lockAspectRatio, m_lockIntegerScaling)); + QRect full(clampSize(QSize(m_aspectWidth, m_aspectHeight), size(), true, false)); painter.drawPixmap(full, logo); } diff --git a/src/platform/qt/Window.h b/src/platform/qt/Window.h index f129c44e5..696604773 100644 --- a/src/platform/qt/Window.h +++ b/src/platform/qt/Window.h @@ -167,7 +167,7 @@ private: void openStateWindow(LoadSave); void attachWidget(QWidget* widget); - void detachWidget(QWidget* widget); + void detachWidget(); void appendMRU(const QString& fname); void clearMRU(); @@ -277,7 +277,6 @@ public: void setDimensions(int width, int height); void setLockIntegerScaling(bool lock); void setLockAspectRatio(bool lock); - void filter(bool filter); const QPixmap& pixmap() const { return m_pixmap; } @@ -289,9 +288,6 @@ private: QSize m_sizeHint; int m_aspectWidth; int m_aspectHeight; - bool m_lockAspectRatio; - bool m_lockIntegerScaling; - bool m_filter; }; }