Qt: Better handle switching between software and hardware renderers

This commit is contained in:
Vicki Pfau 2020-11-09 22:27:50 -08:00
parent 558cb2015e
commit 7be68ffd1d
4 changed files with 33 additions and 5 deletions

View File

@ -81,7 +81,9 @@ CoreController::CoreController(mCore* core, QObject* parent)
controller->m_resetActions.clear(); controller->m_resetActions.clear();
context->core->setVideoBuffer(context->core, reinterpret_cast<color_t*>(controller->m_activeBuffer.data()), controller->screenDimensions().width()); if (!controller->m_hwaccel) {
context->core->setVideoBuffer(context->core, reinterpret_cast<color_t*>(controller->m_activeBuffer.data()), controller->screenDimensions().width());
}
QMetaObject::invokeMethod(controller, "didReset"); QMetaObject::invokeMethod(controller, "didReset");
controller->finishFrame(); controller->finishFrame();
@ -265,14 +267,20 @@ void CoreController::loadConfig(ConfigController* config) {
mCoreConfigCopyValue(&m_threadContext.core->config, config->config(), "mute"); mCoreConfigCopyValue(&m_threadContext.core->config, config->config(), "mute");
QSize sizeBefore = screenDimensions(); QSize sizeBefore = screenDimensions();
m_activeBuffer.resize(256 * 224 * sizeof(color_t));
m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast<color_t*>(m_activeBuffer.data()), sizeBefore.width());
mCoreLoadForeignConfig(m_threadContext.core, config->config()); mCoreLoadForeignConfig(m_threadContext.core, config->config());
QSize sizeAfter = screenDimensions(); QSize sizeAfter = screenDimensions();
m_activeBuffer.resize(sizeAfter.width() * sizeAfter.height() * sizeof(color_t));
m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast<color_t*>(m_activeBuffer.data()), sizeAfter.width());
if (hasStarted()) { if (hasStarted()) {
updateFastForward(); updateFastForward();
mCoreThreadRewindParamsChanged(&m_threadContext); mCoreThreadRewindParamsChanged(&m_threadContext);
} }
if (sizeBefore != sizeAfter) { if (sizeBefore != sizeAfter) {
m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast<color_t*>(m_activeBuffer.data()), sizeAfter.width());
#ifdef M_CORE_GB #ifdef M_CORE_GB
mCoreConfigSetIntValue(&m_threadContext.core->config, "sgb.borders", 0); mCoreConfigSetIntValue(&m_threadContext.core->config, "sgb.borders", 0);
m_threadContext.core->reloadConfigOption(m_threadContext.core, "sgb.borders", nullptr); m_threadContext.core->reloadConfigOption(m_threadContext.core, "sgb.borders", nullptr);
@ -368,7 +376,7 @@ void CoreController::setLogger(LogController* logger) {
} }
void CoreController::start() { void CoreController::start() {
QSize size(256, 224); QSize size(screenDimensions());
m_activeBuffer.resize(size.width() * size.height() * sizeof(color_t)); m_activeBuffer.resize(size.width() * size.height() * sizeof(color_t));
m_activeBuffer.fill(0xFF); m_activeBuffer.fill(0xFF);
m_completeBuffer = m_activeBuffer; m_completeBuffer = m_activeBuffer;
@ -909,6 +917,9 @@ void CoreController::setFramebufferHandle(int fb) {
} }
if (hasStarted()) { if (hasStarted()) {
m_threadContext.core->reloadConfigOption(m_threadContext.core, "hwaccelVideo", NULL); m_threadContext.core->reloadConfigOption(m_threadContext.core, "hwaccelVideo", NULL);
if (!m_hwaccel) {
m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast<color_t*>(m_activeBuffer.data()), screenDimensions().width());
}
} }
} }
@ -939,7 +950,7 @@ void CoreController::finishFrame() {
m_threadContext.core->desiredVideoDimensions(m_threadContext.core, &width, &height); m_threadContext.core->desiredVideoDimensions(m_threadContext.core, &width, &height);
QMutexLocker locker(&m_bufferMutex); 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); QMutexLocker locker(&m_actionMutex);

View File

@ -341,6 +341,15 @@ PainterGL::~PainterGL() {
#if defined(_WIN32) && defined(USE_EPOXY) #if defined(_WIN32) && defined(USE_EPOXY)
epoxy_handle_external_wglMakeCurrent(); epoxy_handle_external_wglMakeCurrent();
#endif #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 #ifdef BUILD_GLES2
if (m_shader.passes) { if (m_shader.passes) {
mGLES2ShaderFree(&m_shader); mGLES2ShaderFree(&m_shader);

View File

@ -36,6 +36,13 @@ void VideoProxy::attach(CoreController* controller) {
controller->thread()->core->videoLogger = &m_logger.d; 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() { void VideoProxy::processData() {
mVideoLoggerRendererRun(&m_logger.d, false); mVideoLoggerRendererRun(&m_logger.d, false);
m_fromThreadCond.wakeAll(); m_fromThreadCond.wakeAll();

View File

@ -23,6 +23,7 @@ public:
VideoProxy(); VideoProxy();
void attach(CoreController*); void attach(CoreController*);
void detach(CoreController*);
signals: signals:
void dataAvailable(); void dataAvailable();