mirror of https://github.com/mgba-emu/mgba.git
Qt: Make renderer able to be changed while running
This commit is contained in:
parent
74af414b96
commit
b922cecc61
2
CHANGES
2
CHANGES
|
@ -22,6 +22,8 @@ Other fixes:
|
|||
- Qt: Fix crash unloading shaders
|
||||
- Qt: Fix toggled actions on gamepads (fixes mgba.io/i/1650)
|
||||
- Qt: Fix extraneous dialog (fixes mgba.io/i/1654)
|
||||
Misc:
|
||||
- Qt: Renderer can be changed while a game is running
|
||||
|
||||
0.8.0: (2020-01-21)
|
||||
Features:
|
||||
|
|
|
@ -347,8 +347,9 @@ static void _GBACoreReloadConfigOption(struct mCore* core, const char* option, c
|
|||
}
|
||||
return;
|
||||
}
|
||||
#if defined(BUILD_GLES2) || defined(BUILD_GLES3)
|
||||
|
||||
struct GBACore* gbacore = (struct GBACore*) core;
|
||||
#if defined(BUILD_GLES2) || defined(BUILD_GLES3)
|
||||
if (strcmp("videoScale", option) == 0) {
|
||||
if (config != &core->config) {
|
||||
mCoreConfigCopyValue(&core->config, config, "videoScale");
|
||||
|
@ -361,6 +362,31 @@ static void _GBACoreReloadConfigOption(struct mCore* core, const char* option, c
|
|||
return;
|
||||
}
|
||||
#endif
|
||||
if (strcmp("hwaccelVideo", option) == 0) {
|
||||
struct GBAVideoRenderer* renderer = NULL;
|
||||
if (gbacore->renderer.outputBuffer) {
|
||||
renderer = &gbacore->renderer.d;
|
||||
}
|
||||
int fakeBool;
|
||||
#if defined(BUILD_GLES2) || defined(BUILD_GLES3)
|
||||
if (gbacore->glRenderer.outputTex != (unsigned) -1 && mCoreConfigGetIntValue(&core->config, "hwaccelVideo", &fakeBool) && fakeBool) {
|
||||
mCoreConfigGetIntValue(&core->config, "videoScale", &gbacore->glRenderer.scale);
|
||||
renderer = &gbacore->glRenderer.d;
|
||||
} else {
|
||||
gbacore->glRenderer.scale = 1;
|
||||
}
|
||||
#endif
|
||||
#ifndef MINIMAL_CORE
|
||||
if (renderer && core->videoLogger) {
|
||||
gbacore->proxyRenderer.logger = core->videoLogger;
|
||||
GBAVideoProxyRendererCreate(&gbacore->proxyRenderer, renderer);
|
||||
renderer = &gbacore->proxyRenderer.d;
|
||||
}
|
||||
#endif
|
||||
if (renderer) {
|
||||
GBAVideoAssociateRenderer(&gba->video, renderer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void _GBACoreDesiredVideoDimensions(struct mCore* core, unsigned* width, unsigned* height) {
|
||||
|
@ -529,8 +555,10 @@ static void _GBACoreReset(struct mCore* core) {
|
|||
int fakeBool;
|
||||
#if defined(BUILD_GLES2) || defined(BUILD_GLES3)
|
||||
if (gbacore->glRenderer.outputTex != (unsigned) -1 && mCoreConfigGetIntValue(&core->config, "hwaccelVideo", &fakeBool) && fakeBool) {
|
||||
renderer = &gbacore->glRenderer.d;
|
||||
mCoreConfigGetIntValue(&core->config, "videoScale", &gbacore->glRenderer.scale);
|
||||
renderer = &gbacore->glRenderer.d;
|
||||
} else {
|
||||
gbacore->glRenderer.scale = 1;
|
||||
}
|
||||
#endif
|
||||
#ifndef DISABLE_THREADING
|
||||
|
|
|
@ -143,8 +143,8 @@ void GBAVideoProxyRendererDeinit(struct GBAVideoRenderer* renderer) {
|
|||
if (!proxyRenderer->logger->block) {
|
||||
proxyRenderer->backend->deinit(proxyRenderer->backend);
|
||||
} else {
|
||||
proxyRenderer->logger->postEvent(proxyRenderer->logger, LOGGER_EVENT_DEINIT);
|
||||
mVideoLoggerRendererFlush(proxyRenderer->logger);
|
||||
proxyRenderer->logger->postEvent(proxyRenderer->logger, LOGGER_EVENT_DEINIT);
|
||||
}
|
||||
|
||||
mVideoLoggerRendererDeinit(proxyRenderer->logger);
|
||||
|
|
|
@ -81,9 +81,7 @@ CoreController::CoreController(mCore* core, QObject* parent)
|
|||
|
||||
controller->m_resetActions.clear();
|
||||
|
||||
if (!controller->m_hwaccel) {
|
||||
context->core->setVideoBuffer(context->core, reinterpret_cast<color_t*>(controller->m_activeBuffer.data()), controller->screenDimensions().width());
|
||||
}
|
||||
context->core->setVideoBuffer(context->core, reinterpret_cast<color_t*>(controller->m_activeBuffer.data()), controller->screenDimensions().width());
|
||||
|
||||
QMetaObject::invokeMethod(controller, "didReset");
|
||||
controller->finishFrame();
|
||||
|
@ -358,14 +356,12 @@ void CoreController::setLogger(LogController* logger) {
|
|||
}
|
||||
|
||||
void CoreController::start() {
|
||||
if (!m_hwaccel) {
|
||||
QSize size(256, 224);
|
||||
m_activeBuffer.resize(size.width() * size.height() * sizeof(color_t));
|
||||
m_activeBuffer.fill(0xFF);
|
||||
m_completeBuffer = m_activeBuffer;
|
||||
QSize size(256, 224);
|
||||
m_activeBuffer.resize(size.width() * size.height() * sizeof(color_t));
|
||||
m_activeBuffer.fill(0xFF);
|
||||
m_completeBuffer = m_activeBuffer;
|
||||
|
||||
m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast<color_t*>(m_activeBuffer.data()), size.width());
|
||||
}
|
||||
m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast<color_t*>(m_activeBuffer.data()), size.width());
|
||||
|
||||
if (!m_patched) {
|
||||
mCoreAutoloadPatch(m_threadContext.core);
|
||||
|
@ -860,11 +856,23 @@ void CoreController::endVideoLog(bool closeVf) {
|
|||
void CoreController::setFramebufferHandle(int fb) {
|
||||
Interrupter interrupter(this);
|
||||
if (fb < 0) {
|
||||
if (!m_hwaccel) {
|
||||
return;
|
||||
}
|
||||
mCoreConfigSetIntValue(&m_threadContext.core->config, "hwaccelVideo", 0);
|
||||
m_threadContext.core->setVideoGLTex(m_threadContext.core, -1);
|
||||
m_hwaccel = false;
|
||||
} else {
|
||||
mCoreConfigSetIntValue(&m_threadContext.core->config, "hwaccelVideo", 1);
|
||||
m_threadContext.core->setVideoGLTex(m_threadContext.core, fb);
|
||||
if (m_hwaccel) {
|
||||
return;
|
||||
}
|
||||
m_hwaccel = true;
|
||||
}
|
||||
if (hasStarted()) {
|
||||
m_threadContext.core->reloadConfigOption(m_threadContext.core, "hwaccelVideo", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void CoreController::updateKeys() {
|
||||
|
|
|
@ -493,12 +493,13 @@ void SettingsView::updateConfig() {
|
|||
}
|
||||
|
||||
int videoScale = m_controller->getOption("videoScale", 1).toInt();
|
||||
saveSetting("videoScale", m_ui.videoScale);
|
||||
|
||||
int hwaccelVideo = m_controller->getOption("hwaccelVideo").toInt();
|
||||
saveSetting("hwaccelVideo", m_ui.hwaccelVideo->currentIndex());
|
||||
if (hwaccelVideo != m_ui.hwaccelVideo->currentIndex()) {
|
||||
emit videoRendererChanged();
|
||||
}
|
||||
saveSetting("videoScale", m_ui.videoScale);
|
||||
saveSetting("hwaccelVideo", m_ui.hwaccelVideo->currentIndex());
|
||||
|
||||
m_logModel.save(m_controller);
|
||||
m_logModel.logger()->setLogFile(m_ui.logFile->text());
|
||||
|
|
|
@ -461,7 +461,7 @@ void Window::openSettingsWindow() {
|
|||
connect(settingsWindow, &SettingsView::audioDriverChanged, this, &Window::reloadAudioDriver);
|
||||
connect(settingsWindow, &SettingsView::cameraDriverChanged, this, &Window::mustRestart);
|
||||
connect(settingsWindow, &SettingsView::cameraChanged, &m_inputController, &InputController::setCamera);
|
||||
connect(settingsWindow, &SettingsView::videoRendererChanged, this, &Window::mustRestart);
|
||||
connect(settingsWindow, &SettingsView::videoRendererChanged, this, &Window::changeRenderer);
|
||||
connect(settingsWindow, &SettingsView::languageChanged, this, &Window::mustRestart);
|
||||
connect(settingsWindow, &SettingsView::pathsChanged, this, &Window::reloadConfig);
|
||||
#ifdef USE_SQLITE3
|
||||
|
@ -883,10 +883,6 @@ void Window::unimplementedBiosCall(int call) {
|
|||
|
||||
void Window::reloadDisplayDriver() {
|
||||
if (m_controller) {
|
||||
if (m_controller->hardwareAccelerated()) {
|
||||
mustRestart();
|
||||
return;
|
||||
}
|
||||
m_display->stopDrawing();
|
||||
detachWidget(m_display.get());
|
||||
}
|
||||
|
@ -924,14 +920,7 @@ void Window::reloadDisplayDriver() {
|
|||
#endif
|
||||
|
||||
if (m_controller) {
|
||||
connect(m_controller.get(), &CoreController::stateLoaded, m_display.get(), &Display::resizeContext);
|
||||
connect(m_controller.get(), &CoreController::stateLoaded, m_display.get(), &Display::forceDraw);
|
||||
connect(m_controller.get(), &CoreController::rewound, m_display.get(), &Display::forceDraw);
|
||||
connect(m_controller.get(), &CoreController::paused, m_display.get(), &Display::pauseDrawing);
|
||||
connect(m_controller.get(), &CoreController::unpaused, m_display.get(), &Display::unpauseDrawing);
|
||||
connect(m_controller.get(), &CoreController::frameAvailable, m_display.get(), &Display::framePosted);
|
||||
connect(m_controller.get(), &CoreController::statusPosted, m_display.get(), &Display::showMessage);
|
||||
connect(m_controller.get(), &CoreController::didReset, m_display.get(), &Display::resizeContext);
|
||||
attachDisplay();
|
||||
|
||||
attachWidget(m_display.get());
|
||||
m_display->startDrawing(m_controller);
|
||||
|
@ -962,6 +951,27 @@ void Window::reloadAudioDriver() {
|
|||
connect(m_controller.get(), &CoreController::fastForwardChanged, m_audioProcessor.get(), &AudioProcessor::inputParametersChanged);
|
||||
}
|
||||
|
||||
void Window::changeRenderer() {
|
||||
if (!m_controller) {
|
||||
return;
|
||||
}
|
||||
if (m_config->getOption("hwaccelVideo").toInt() && m_display->supportsShaders() && m_controller->supportsFeature(CoreController::Feature::OPENGL)) {
|
||||
std::shared_ptr<VideoProxy> proxy = m_display->videoProxy();
|
||||
if (!proxy) {
|
||||
proxy = std::make_shared<VideoProxy>();
|
||||
}
|
||||
m_display->setVideoProxy(proxy);
|
||||
proxy->attach(m_controller.get());
|
||||
|
||||
int fb = m_display->framebufferHandle();
|
||||
if (fb >= 0) {
|
||||
m_controller->setFramebufferHandle(fb);
|
||||
}
|
||||
} else {
|
||||
m_controller->setFramebufferHandle(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void Window::tryMakePortable() {
|
||||
QMessageBox* confirm = new QMessageBox(QMessageBox::Question, tr("Really make portable?"),
|
||||
tr("This will make the emulator load its configuration from the same directory as the executable. Do you want to continue?"),
|
||||
|
@ -1810,17 +1820,6 @@ void Window::setController(CoreController* controller, const QString& fname) {
|
|||
reloadDisplayDriver();
|
||||
}
|
||||
|
||||
if (m_config->getOption("hwaccelVideo").toInt() && m_display->supportsShaders() && controller->supportsFeature(CoreController::Feature::OPENGL)) {
|
||||
std::shared_ptr<VideoProxy> proxy = std::make_shared<VideoProxy>();
|
||||
m_display->setVideoProxy(proxy);
|
||||
proxy->attach(controller);
|
||||
|
||||
int fb = m_display->framebufferHandle();
|
||||
if (fb >= 0) {
|
||||
controller->setFramebufferHandle(fb);
|
||||
}
|
||||
}
|
||||
|
||||
m_controller = std::shared_ptr<CoreController>(controller);
|
||||
m_inputController.recalibrateAxes();
|
||||
m_controller->setInputController(&m_inputController);
|
||||
|
@ -1860,14 +1859,7 @@ void Window::setController(CoreController* controller, const QString& fname) {
|
|||
emit paused(false);
|
||||
});
|
||||
|
||||
connect(m_controller.get(), &CoreController::stateLoaded, m_display.get(), &Display::resizeContext);
|
||||
connect(m_controller.get(), &CoreController::stateLoaded, m_display.get(), &Display::forceDraw);
|
||||
connect(m_controller.get(), &CoreController::rewound, m_display.get(), &Display::forceDraw);
|
||||
connect(m_controller.get(), &CoreController::paused, m_display.get(), &Display::pauseDrawing);
|
||||
connect(m_controller.get(), &CoreController::unpaused, m_display.get(), &Display::unpauseDrawing);
|
||||
connect(m_controller.get(), &CoreController::frameAvailable, m_display.get(), &Display::framePosted);
|
||||
connect(m_controller.get(), &CoreController::statusPosted, m_display.get(), &Display::showMessage);
|
||||
connect(m_controller.get(), &CoreController::didReset, m_display.get(), &Display::resizeContext);
|
||||
attachDisplay();
|
||||
|
||||
connect(m_controller.get(), &CoreController::unpaused, &m_inputController, &InputController::suspendScreensaver);
|
||||
connect(m_controller.get(), &CoreController::frameAvailable, this, &Window::recordFrame);
|
||||
|
@ -1924,6 +1916,18 @@ void Window::setController(CoreController* controller, const QString& fname) {
|
|||
}
|
||||
}
|
||||
|
||||
void Window::attachDisplay() {
|
||||
connect(m_controller.get(), &CoreController::stateLoaded, m_display.get(), &Display::resizeContext);
|
||||
connect(m_controller.get(), &CoreController::stateLoaded, m_display.get(), &Display::forceDraw);
|
||||
connect(m_controller.get(), &CoreController::rewound, m_display.get(), &Display::forceDraw);
|
||||
connect(m_controller.get(), &CoreController::paused, m_display.get(), &Display::pauseDrawing);
|
||||
connect(m_controller.get(), &CoreController::unpaused, m_display.get(), &Display::unpauseDrawing);
|
||||
connect(m_controller.get(), &CoreController::frameAvailable, m_display.get(), &Display::framePosted);
|
||||
connect(m_controller.get(), &CoreController::statusPosted, m_display.get(), &Display::showMessage);
|
||||
connect(m_controller.get(), &CoreController::didReset, m_display.get(), &Display::resizeContext);
|
||||
changeRenderer();
|
||||
}
|
||||
|
||||
WindowBackground::WindowBackground(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
|
|
|
@ -130,6 +130,7 @@ private slots:
|
|||
|
||||
void reloadAudioDriver();
|
||||
void reloadDisplayDriver();
|
||||
void changeRenderer();
|
||||
|
||||
void tryMakePortable();
|
||||
void mustRestart();
|
||||
|
@ -155,6 +156,7 @@ private:
|
|||
void updateMRU();
|
||||
|
||||
void openView(QWidget* widget);
|
||||
void attachDisplay();
|
||||
|
||||
template <typename T, typename... A> std::function<void()> openTView(A... arg);
|
||||
template <typename T, typename... A> std::function<void()> openControllerTView(A... arg);
|
||||
|
|
Loading…
Reference in New Issue