qt: Fix crashes and freezes when switching to/from Direct3D 9

This commit is contained in:
Cacodemon345
2022-06-24 15:41:24 +06:00
parent e04df80d97
commit 74f86753dd
3 changed files with 23 additions and 8 deletions

View File

@@ -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);
}

View File

@@ -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<std::atomic_flag *>(imagebufs[currentBuf])->test_and_set()) {
if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || imagebufs.empty() || std::get<std::atomic_flag *>(imagebufs[currentBuf])->test_and_set() || blitDummied) {
video_blit_complete();
return;
}

View File

@@ -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<QWidget> current;
std::atomic<bool> directBlitting{false};
std::atomic<bool> directBlitting{false}, blitDummied{false};
};
#endif // QT_RENDERERCONTAINER_HPP