diff options
author | RSDuck <RSDuck@users.noreply.github.com> | 2021-02-02 15:31:32 +0100 |
---|---|---|
committer | RSDuck <RSDuck@users.noreply.github.com> | 2021-02-02 15:33:45 +0100 |
commit | 40aae154cf77e0611057a05702f28d9cf17b08f4 (patch) | |
tree | faefea325f6fc7beabf7cbf073310296981bec4b /src/frontend | |
parent | b5e601bb88858b124b0cc41a4ee7eb6896dee8d3 (diff) |
prevent race condition around framebuffers
Diffstat (limited to 'src/frontend')
-rw-r--r-- | src/frontend/qt_sdl/main.cpp | 101 | ||||
-rw-r--r-- | src/frontend/qt_sdl/main.h | 4 |
2 files changed, 65 insertions, 40 deletions
diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 6766252..5aa4959 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -490,13 +490,18 @@ void EmuThread::run() // emulate u32 nlines = NDS::RunFrame(); + FrontBufferLock.lock(); #ifdef OGLRENDERER_ENABLED - // this is hacky but this is the easiest way to call - // this function without dealling with a ton of - // macro mess if (videoRenderer == 1) - epoxy_glFlush(); + { + // this is hacky but this is the easiest way to call + // this function without dealling with a ton of + // macro mess + epoxy_glFinish(); + } #endif + FrontBuffer = GPU::FrontBuffer; + FrontBufferLock.unlock(); #ifdef MELONCAP MelonCap::Update(); @@ -824,11 +829,17 @@ void ScreenPanelNative::paintEvent(QPaintEvent* event) // fill background painter.fillRect(event->rect(), QColor::fromRgb(0, 0, 0)); - int frontbuf = GPU::FrontBuffer; - if (!GPU::Framebuffer[frontbuf][0] || !GPU::Framebuffer[frontbuf][1]) return; + emuThread->FrontBufferLock.lock(); + int frontbuf = emuThread->FrontBuffer; + if (!GPU::Framebuffer[frontbuf][0] || !GPU::Framebuffer[frontbuf][1]) + { + emuThread->FrontBufferLock.unlock(); + return; + } memcpy(screen[0].scanLine(0), GPU::Framebuffer[frontbuf][0], 256*192*4); memcpy(screen[1].scanLine(0), GPU::Framebuffer[frontbuf][1], 256*192*4); + emuThread->FrontBufferLock.unlock(); painter.setRenderHint(QPainter::SmoothPixmapTransform, Config::ScreenFilter!=0); @@ -988,53 +999,63 @@ void ScreenPanelGL::paintGL() glViewport(0, 0, w*factor, h*factor); - screenShader->bind(); + if (emuThread) + { + screenShader->bind(); - screenShader->setUniformValue("uScreenSize", (float)w*factor, (float)h*factor); + screenShader->setUniformValue("uScreenSize", (float)w*factor, (float)h*factor); - int frontbuf = GPU::FrontBuffer; - glActiveTexture(GL_TEXTURE0); + emuThread->FrontBufferLock.lock(); + int frontbuf = emuThread->FrontBuffer; + glActiveTexture(GL_TEXTURE0); -#ifdef OGLRENDERER_ENABLED - if (GPU::Renderer != 0) - { - // hardware-accelerated render - GPU::GLCompositor::BindOutputTexture(); - } - else -#endif - { - // regular render - glBindTexture(GL_TEXTURE_2D, screenTexture); - - if (GPU::Framebuffer[frontbuf][0] && GPU::Framebuffer[frontbuf][1]) + #ifdef OGLRENDERER_ENABLED + if (GPU::Renderer != 0) { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192, GL_RGBA, - GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192+2, 256, 192, GL_RGBA, - GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); + // hardware-accelerated render + GPU::GLCompositor::BindOutputTexture(frontbuf); } - } + else + #endif + { + // regular render + glBindTexture(GL_TEXTURE_2D, screenTexture); - GLint filter = Config::ScreenFilter ? GL_LINEAR : GL_NEAREST; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); + if (GPU::Framebuffer[frontbuf][0] && GPU::Framebuffer[frontbuf][1]) + { + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192, GL_RGBA, + GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192+2, 256, 192, GL_RGBA, + GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); + } + } - glBindBuffer(GL_ARRAY_BUFFER, screenVertexBuffer); - glBindVertexArray(screenVertexArray); + GLint filter = Config::ScreenFilter ? GL_LINEAR : GL_NEAREST; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); - GLint transloc = screenShader->uniformLocation("uTransform"); + glBindBuffer(GL_ARRAY_BUFFER, screenVertexBuffer); + glBindVertexArray(screenVertexArray); - for (int i = 0; i < numScreens; i++) - { - glUniformMatrix2x3fv(transloc, 1, GL_TRUE, screenMatrix[i]); - glDrawArrays(GL_TRIANGLES, screenKind[i] == 0 ? 0 : 2*3, 2*3); - } + GLint transloc = screenShader->uniformLocation("uTransform"); - screenShader->release(); + for (int i = 0; i < numScreens; i++) + { + glUniformMatrix2x3fv(transloc, 1, GL_TRUE, screenMatrix[i]); + glDrawArrays(GL_TRIANGLES, screenKind[i] == 0 ? 0 : 2*3, 2*3); + } + + screenShader->release(); + } OSD::Update(this); OSD::DrawGL(this, w*factor, h*factor); + + if (emuThread) + { + glFinish(); + emuThread->FrontBufferLock.unlock(); + } } void ScreenPanelGL::resizeEvent(QResizeEvent* event) diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index c226fbc..9bfcd0a 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -26,6 +26,7 @@ #include <QImage> #include <QActionGroup> #include <QTimer> +#include <QMutex> #include <QOffscreenSurface> #include <QOpenGLWidget> @@ -59,6 +60,9 @@ public: bool emuIsRunning(); + int FrontBuffer = 0; + QMutex FrontBufferLock; + signals: void windowUpdate(); void windowTitleChange(QString title); |