From 74f86753dd0b7d00880a4c9d1c595d780df6eac9 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 24 Jun 2022 15:41:24 +0600 Subject: [PATCH 1/2] qt: Fix crashes and freezes when switching to/from Direct3D 9 --- src/qt/qt_d3d9renderer.cpp | 2 +- src/qt/qt_rendererstack.cpp | 26 ++++++++++++++++++++------ src/qt/qt_rendererstack.hpp | 3 ++- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/qt/qt_d3d9renderer.cpp b/src/qt/qt_d3d9renderer.cpp index 7908b7b9b..856032017 100644 --- a/src/qt/qt_d3d9renderer.cpp +++ b/src/qt/qt_d3d9renderer.cpp @@ -142,6 +142,7 @@ void D3D9Renderer::blit(int x, int y, int w, int h) video_blit_complete(); return; } + surfaceInUse = true; source.setRect(x, y, w, h); RECT srcRect; D3DLOCKED_RECT lockRect; @@ -150,7 +151,6 @@ void D3D9Renderer::blit(int x, int y, int w, int h) srcRect.left = source.left(); srcRect.right = source.right(); - surfaceInUse = true; if (screenshots) { video_screenshot((uint32_t *) &(buffer32->line[y][x]), 0, 0, 2048); } diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 5efd013cc..f8532c78e 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -226,20 +226,27 @@ RendererStack::switchRenderer(Renderer renderer) { startblit(); if (current) { + rendererWindow->finalize(); if (rendererWindow->hasBlitFunc()) { while (directBlitting) {} + connect(this, &RendererStack::blit, this, &RendererStack::blitDummy, Qt::DirectConnection); disconnect(this, &RendererStack::blit, this, &RendererStack::blitRenderer); - video_blit_complete(); + } else { + connect(this, &RendererStack::blit, this, &RendererStack::blitDummy, Qt::DirectConnection); + disconnect(this, &RendererStack::blit, this, &RendererStack::blitCommon); } - rendererWindow->finalize(); removeWidget(current.get()); disconnect(this, &RendererStack::blitToRenderer, nullptr, nullptr); /* Create new renderer only after previous is destroyed! */ - connect(current.get(), &QObject::destroyed, [this, renderer](QObject *) { video_blit_complete(); createRenderer(renderer); video_blit_complete(); }); + connect(current.get(), &QObject::destroyed, [this, renderer](QObject *) { + createRenderer(renderer); + disconnect(this, &RendererStack::blit, this, &RendererStack::blitDummy); + blitDummied = false; + }); - current.release()->deleteLater(); + rendererWindow->hasBlitFunc() ? current.reset() : current.release()->deleteLater(); } else { createRenderer(renderer); } @@ -318,7 +325,6 @@ RendererStack::createRenderer(Renderer renderer) }); connect(hw, &D3D9Renderer::initialized, this, [this]() { - qDebug() << "initialized"; endblit(); emit rendererChanged(); }); @@ -388,9 +394,17 @@ RendererStack::createRenderer(Renderer renderer) } } +void +RendererStack::blitDummy(int x, int y, int w, int h) +{ + video_blit_complete(); + blitDummied = true; +} + void RendererStack::blitRenderer(int x, int y, int w, int h) { + if (blitDummied) { blitDummied = false; video_blit_complete(); return; } directBlitting = true; rendererWindow->blit(x, y, w, h); directBlitting = false; @@ -400,7 +414,7 @@ RendererStack::blitRenderer(int x, int y, int w, int h) void RendererStack::blitCommon(int x, int y, int w, int h) { - if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || imagebufs.empty() || std::get(imagebufs[currentBuf])->test_and_set()) { + if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || imagebufs.empty() || std::get(imagebufs[currentBuf])->test_and_set() || blitDummied) { video_blit_complete(); return; } diff --git a/src/qt/qt_rendererstack.hpp b/src/qt/qt_rendererstack.hpp index f54cd6f66..ab8e160ec 100644 --- a/src/qt/qt_rendererstack.hpp +++ b/src/qt/qt_rendererstack.hpp @@ -79,6 +79,7 @@ signals: public slots: void blitCommon(int x, int y, int w, int h); void blitRenderer(int x, int y, int w, int h); + void blitDummy(int x, int y, int w, int h); void mousePoll(); private: @@ -101,7 +102,7 @@ private: RendererCommon *rendererWindow { nullptr }; std::unique_ptr current; - std::atomic directBlitting{false}; + std::atomic directBlitting{false}, blitDummied{false}; }; #endif // QT_RENDERERCONTAINER_HPP From d9ee5d43bbecb544b3467c54a4d79feee3e43005 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 24 Jun 2022 17:15:40 +0600 Subject: [PATCH 2/2] qt: Fix crashes on loading non-existent ZIP/MO images --- src/qt/qt_machinestatus.cpp | 13 +++++++------ src/qt/qt_mediamenu.cpp | 2 ++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/qt/qt_machinestatus.cpp b/src/qt/qt_machinestatus.cpp index 39c98b6aa..bd0e491f1 100644 --- a/src/qt/qt_machinestatus.cpp +++ b/src/qt/qt_machinestatus.cpp @@ -583,24 +583,25 @@ void MachineStatus::updateTip(int tag) { int category = tag & 0xfffffff0; int item = tag & 0xf; + if (!MediaMenu::ptr) return; switch (category) { case SB_CASSETTE: - d->cassette.label->setToolTip(MediaMenu::ptr->cassetteMenu->title()); + if (d->cassette.label && MediaMenu::ptr->cassetteMenu) d->cassette.label->setToolTip(MediaMenu::ptr->cassetteMenu->title()); break; case SB_CARTRIDGE: - d->cartridge[item].label->setToolTip(MediaMenu::ptr->cartridgeMenus[item]->title()); + if (d->cartridge[item].label && MediaMenu::ptr->cartridgeMenus[item]) d->cartridge[item].label->setToolTip(MediaMenu::ptr->cartridgeMenus[item]->title()); break; case SB_FLOPPY: - d->fdd[item].label->setToolTip(MediaMenu::ptr->floppyMenus[item]->title()); + if (d->fdd[item].label && MediaMenu::ptr->floppyMenus[item]) d->fdd[item].label->setToolTip(MediaMenu::ptr->floppyMenus[item]->title()); break; case SB_CDROM: - d->cdrom[item].label->setToolTip(MediaMenu::ptr->cdromMenus[item]->title()); + if (d->cdrom[item].label && MediaMenu::ptr->cdromMenus[item]) d->cdrom[item].label->setToolTip(MediaMenu::ptr->cdromMenus[item]->title()); break; case SB_ZIP: - d->zip[item].label->setToolTip(MediaMenu::ptr->zipMenus[item]->title()); + if (d->zip[item].label && MediaMenu::ptr->zipMenus[item]) d->zip[item].label->setToolTip(MediaMenu::ptr->zipMenus[item]->title()); break; case SB_MO: - d->mo[item].label->setToolTip(MediaMenu::ptr->moMenus[item]->title()); + if (d->mo[item].label && MediaMenu::ptr->moMenus[item]) d->mo[item].label->setToolTip(MediaMenu::ptr->moMenus[item]->title()); break; case SB_HDD: break; diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index 3fe09ee45..3dcac9f2a 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -501,6 +501,7 @@ void MediaMenu::zipEject(int i) { zip_t *dev = (zip_t *) zip_drives[i].priv; zip_disk_close(dev); + zip_drives[i].image_path[0] = 0; if (zip_drives[i].bus_type) { /* Signal disk change to the emulated machine. */ zip_insert(dev); @@ -600,6 +601,7 @@ void MediaMenu::moEject(int i) { mo_t *dev = (mo_t *) mo_drives[i].priv; mo_disk_close(dev); + mo_drives[i].image_path[0] = 0; if (mo_drives[i].bus_type) { /* Signal disk change to the emulated machine. */ mo_insert(dev);