mirror of https://github.com/mgba-emu/mgba.git
Qt: Simplify Window drawing (fixes #2190)
This commit is contained in:
parent
97cb18d3fd
commit
ae0c5e91aa
1
CHANGES
1
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
|
||||
|
|
|
@ -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<QOpenGLVertexArrayObject>();
|
||||
m_vao->create();
|
||||
|
||||
m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, R"(#version 150 core
|
||||
m_program = std::make_unique<QOpenGLShaderProgram>();
|
||||
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<void (QWidget::*)()>(&QWidget::update));
|
||||
}
|
||||
|
@ -85,11 +88,11 @@ void mGLWidget::initializeGL() {
|
|||
void mGLWidget::finalizeVAO() {
|
||||
QOpenGLFunctions_Baseline* fn = context()->versionFunctions<QOpenGLFunctions_Baseline>();
|
||||
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<QOpenGLFunctions_Baseline>();
|
||||
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;
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <QTimer>
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
|
||||
#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<QOpenGLVertexArrayObject> m_vao;
|
||||
std::unique_ptr<QOpenGLShaderProgram> m_program;
|
||||
GLuint m_positionLocation;
|
||||
|
||||
QTimer m_refresh;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "GamepadAxisEvent.h"
|
||||
#include "GamepadButtonEvent.h"
|
||||
#include "VFileDevice.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QDateTime>
|
||||
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include <QMimeData>
|
||||
#include <QPainter>
|
||||
#include <QScreen>
|
||||
#include <QStackedLayout>
|
||||
#include <QWindow>
|
||||
|
||||
#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<QGBA::Display>(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<QStackedLayout*>(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<QStackedLayout*>(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<QStackedLayout*>(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<QStackedLayout*>(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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue