Qt: Make renderer able to be changed while running
@@ -22,6 +22,8 @@ - Qt: Fix missing OSD messages
- 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 @@ gba->allowOpposingDirections = fakeBool;
} return; } + + struct GBACore* gbacore = (struct GBACore*) core; #if defined(BUILD_GLES2) || defined(BUILD_GLES3) - struct GBACore* gbacore = (struct GBACore*) core; if (strcmp("videoScale", option) == 0) { if (config != &core->config) { mCoreConfigCopyValue(&core->config, config, "videoScale");@@ -361,6 +362,31 @@ }
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 @@ }
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 @@
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 @@ }
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 @@ connect(this, &CoreController::logPosted, m_log, &LogController::postLog);
} 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,10 +856,22 @@
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); } }
@@ -493,12 +493,13 @@ emit languageChanged();
} 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 @@ connect(settingsWindow, &SettingsView::displayDriverChanged, this, &Window::reloadDisplayDriver);
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::reloadDisplayDriver() { if (m_controller) { - if (m_controller->hardwareAccelerated()) { - mustRestart(); - return; - } m_display->stopDrawing(); detachWidget(m_display.get()); }@@ -924,14 +920,7 @@ }
#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);@@ -960,6 +949,27 @@ m_audioProcessor->requestSampleRate(opts->sampleRate);
m_audioProcessor->start(); connect(m_controller.get(), &CoreController::stopping, m_audioProcessor.get(), &AudioProcessor::stop); 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() {@@ -1810,17 +1820,6 @@ if (!m_display) {
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 @@ connect(m_controller.get(), &CoreController::unpaused, [this]() {
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);@@ -1922,6 +1914,18 @@ if (m_pendingPause) {
m_controller->setPaused(true); m_pendingPause = false; } +} + +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)
@@ -130,6 +130,7 @@ void unimplementedBiosCall(int);
void reloadAudioDriver(); void reloadDisplayDriver(); + void changeRenderer(); void tryMakePortable(); void mustRestart();@@ -155,6 +156,7 @@ void clearMRU();
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);