From 7be68ffd1d648d0e4ca0f5a81e214610291da6ca Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 9 Nov 2020 22:27:50 -0800 Subject: [PATCH] Qt: Better handle switching between software and hardware renderers --- src/platform/qt/CoreController.cpp | 19 +++++++++++++++---- src/platform/qt/DisplayGL.cpp | 9 +++++++++ src/platform/qt/VideoProxy.cpp | 7 +++++++ src/platform/qt/VideoProxy.h | 3 ++- 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index 2f4edb6f5..f3edda5b7 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -81,7 +81,9 @@ CoreController::CoreController(mCore* core, QObject* parent) controller->m_resetActions.clear(); - context->core->setVideoBuffer(context->core, reinterpret_cast(controller->m_activeBuffer.data()), controller->screenDimensions().width()); + if (!controller->m_hwaccel) { + context->core->setVideoBuffer(context->core, reinterpret_cast(controller->m_activeBuffer.data()), controller->screenDimensions().width()); + } QMetaObject::invokeMethod(controller, "didReset"); controller->finishFrame(); @@ -265,14 +267,20 @@ void CoreController::loadConfig(ConfigController* config) { mCoreConfigCopyValue(&m_threadContext.core->config, config->config(), "mute"); QSize sizeBefore = screenDimensions(); + m_activeBuffer.resize(256 * 224 * sizeof(color_t)); + m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer.data()), sizeBefore.width()); + mCoreLoadForeignConfig(m_threadContext.core, config->config()); + QSize sizeAfter = screenDimensions(); + m_activeBuffer.resize(sizeAfter.width() * sizeAfter.height() * sizeof(color_t)); + m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer.data()), sizeAfter.width()); + if (hasStarted()) { updateFastForward(); mCoreThreadRewindParamsChanged(&m_threadContext); } if (sizeBefore != sizeAfter) { - m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer.data()), sizeAfter.width()); #ifdef M_CORE_GB mCoreConfigSetIntValue(&m_threadContext.core->config, "sgb.borders", 0); m_threadContext.core->reloadConfigOption(m_threadContext.core, "sgb.borders", nullptr); @@ -368,7 +376,7 @@ void CoreController::setLogger(LogController* logger) { } void CoreController::start() { - QSize size(256, 224); + QSize size(screenDimensions()); m_activeBuffer.resize(size.width() * size.height() * sizeof(color_t)); m_activeBuffer.fill(0xFF); m_completeBuffer = m_activeBuffer; @@ -909,6 +917,9 @@ void CoreController::setFramebufferHandle(int fb) { } if (hasStarted()) { m_threadContext.core->reloadConfigOption(m_threadContext.core, "hwaccelVideo", NULL); + if (!m_hwaccel) { + m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer.data()), screenDimensions().width()); + } } } @@ -939,7 +950,7 @@ void CoreController::finishFrame() { m_threadContext.core->desiredVideoDimensions(m_threadContext.core, &width, &height); QMutexLocker locker(&m_bufferMutex); - memcpy(m_completeBuffer.data(), m_activeBuffer.constData(), 256 * height * BYTES_PER_PIXEL); + memcpy(m_completeBuffer.data(), m_activeBuffer.constData(), width * height * BYTES_PER_PIXEL); } QMutexLocker locker(&m_actionMutex); diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index be545fe78..93fc2e081 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -341,6 +341,15 @@ PainterGL::~PainterGL() { #if defined(_WIN32) && defined(USE_EPOXY) epoxy_handle_external_wglMakeCurrent(); #endif + if (m_context) { + if (m_videoProxy) { + m_videoProxy->detach(m_context.get()); + } + m_context->setFramebufferHandle(-1); + if (m_videoProxy) { + m_videoProxy->processData(); + } + } #ifdef BUILD_GLES2 if (m_shader.passes) { mGLES2ShaderFree(&m_shader); diff --git a/src/platform/qt/VideoProxy.cpp b/src/platform/qt/VideoProxy.cpp index 3e8549d69..aee19deb4 100644 --- a/src/platform/qt/VideoProxy.cpp +++ b/src/platform/qt/VideoProxy.cpp @@ -36,6 +36,13 @@ void VideoProxy::attach(CoreController* controller) { controller->thread()->core->videoLogger = &m_logger.d; } +void VideoProxy::detach(CoreController* controller) { + CoreController::Interrupter interrupter(controller); + if (controller->thread()->core->videoLogger == &m_logger.d) { + controller->thread()->core->videoLogger = nullptr; + } +} + void VideoProxy::processData() { mVideoLoggerRendererRun(&m_logger.d, false); m_fromThreadCond.wakeAll(); diff --git a/src/platform/qt/VideoProxy.h b/src/platform/qt/VideoProxy.h index e62facca1..0e0f4bd5b 100644 --- a/src/platform/qt/VideoProxy.h +++ b/src/platform/qt/VideoProxy.h @@ -23,6 +23,7 @@ public: VideoProxy(); void attach(CoreController*); + void detach(CoreController*); signals: void dataAvailable(); @@ -68,4 +69,4 @@ private: QWaitCondition m_fromThreadCond; }; -} \ No newline at end of file +}