From 01358407fd3cda10859bc2835fab0fe1d4879f82 Mon Sep 17 00:00:00 2001 From: harry Date: Wed, 31 Jan 2024 06:49:54 -0500 Subject: [PATCH] For Qt GUI, changed onFrameFinished callback to only update video buffer. Don't do any input processing as this will mess up when running turbo mode. Added a draw timer to SDL video renderer to better align is scheduling with the next vsync. --- src/drivers/Qt/ConsoleViewerSDL.cpp | 23 ++++++++++++++++++++ src/drivers/Qt/ConsoleViewerSDL.h | 4 +++- src/drivers/Qt/ConsoleWindow.cpp | 33 +++++++++++++++-------------- src/drivers/Qt/ConsoleWindow.h | 3 ++- 4 files changed, 45 insertions(+), 18 deletions(-) diff --git a/src/drivers/Qt/ConsoleViewerSDL.cpp b/src/drivers/Qt/ConsoleViewerSDL.cpp index 31cccffb..6e76136f 100644 --- a/src/drivers/Qt/ConsoleViewerSDL.cpp +++ b/src/drivers/Qt/ConsoleViewerSDL.cpp @@ -82,6 +82,11 @@ ConsoleViewSDL_t::ConsoleViewSDL_t(QWidget *parent) vsyncEnabled = false; mouseButtonMask = 0; + drawTimer = new QTimer(this); + drawTimer->setInterval(14); + drawTimer->setSingleShot(true); + drawTimer->setTimerType(Qt::PreciseTimer); + connect(drawTimer, &QTimer::timeout, this, &ConsoleViewSDL_t::onDrawSignal); localBufSize = (4 * GL_NES_WIDTH) * (4 * GL_NES_HEIGHT) * sizeof(uint32_t); @@ -123,6 +128,8 @@ ConsoleViewSDL_t::ConsoleViewSDL_t(QWidget *parent) ConsoleViewSDL_t::~ConsoleViewSDL_t(void) { //printf("Destroying SDL Viewport\n"); + drawTimer->stop(); + delete drawTimer; if ( localBuf ) { @@ -585,6 +592,19 @@ void ConsoleViewSDL_t::getNormalizedCursorPos( double &x, double &y ) //printf("Normalized Cursor (%f,%f) \n", x, y ); } +void ConsoleViewSDL_t::queueRedraw(void) +{ + if (!drawTimer->isActive()) + { + render(); + } +} + +void ConsoleViewSDL_t::onDrawSignal(void) +{ + render(); +} + void ConsoleViewSDL_t::render(void) { int nesWidth = GL_NES_WIDTH; @@ -707,5 +727,8 @@ void ConsoleViewSDL_t::render(void) videoBufferSwapMark(); + // Schedule draw timing inline with vsync + drawTimer->start(); + nes_shm->render_count++; } diff --git a/src/drivers/Qt/ConsoleViewerSDL.h b/src/drivers/Qt/ConsoleViewerSDL.h index 7aa3ffdf..153f7e32 100644 --- a/src/drivers/Qt/ConsoleViewerSDL.h +++ b/src/drivers/Qt/ConsoleViewerSDL.h @@ -24,7 +24,7 @@ class ConsoleViewSDL_t : public QWidget, public ConsoleViewerBase void reset(void); void cleanup(void); void render(void); - void queueRedraw(void){ render(); }; + void queueRedraw(void); int driver(void){ return VIDEO_DRIVER_SDL; }; void transfer2LocalBuffer(void); @@ -83,6 +83,7 @@ class ConsoleViewSDL_t : public QWidget, public ConsoleViewerBase bool forceAspect; bool autoScaleEna; QColor *bgColor; + QTimer *drawTimer; uint32_t *localBuf; uint32_t localBufSize; @@ -95,5 +96,6 @@ class ConsoleViewSDL_t : public QWidget, public ConsoleViewerBase //SDL_Rect sdlViewport; private slots: + void onDrawSignal(); }; diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index 8c4dcdfc..fc324712 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -154,6 +154,7 @@ consoleWin_t::consoleWin_t(QWidget *parent) mainMenuEmuWasPaused = false; mainMenuPauseWhenActv = false; autoHideMenuFullscreen = false; + redrawVideoRequest = false; createMainMenu(); @@ -412,7 +413,7 @@ void consoleWin_t::winScreenChanged(QScreen *scr) return; } refreshRate = scr->refreshRate(); - //printf("Screen Refresh Rate: %f\n", scr->refreshRate() ); + printf("Screen Refresh Rate: %f\n", scr->refreshRate() ); //printf("Screen Changed: %p\n", scr ); if ( viewport_GL != NULL ) @@ -4555,9 +4556,8 @@ int consoleWin_t::getPeriodicInterval(void) return gameTimer->interval(); } -void consoleWin_t::transferVideoBuffer(void) +void consoleWin_t::transferVideoBuffer(bool allowRedraw) { - bool redraw = false; FCEU_PROFILE_FUNC(prof, "VideoXfer"); { @@ -4569,21 +4569,22 @@ void consoleWin_t::transferVideoBuffer(void) if (viewport_Interface != nullptr) { viewport_Interface->transfer2LocalBuffer(); - redraw = true; + redrawVideoRequest = true; } } } // Don't queue redraw in mutex lock scope - if (redraw && (viewport_Interface != nullptr)) + if (allowRedraw && redrawVideoRequest && (viewport_Interface != nullptr)) { viewport_Interface->queueRedraw(); + redrawVideoRequest = false; } } void consoleWin_t::emuFrameFinish(void) { - static bool eventProcessingInProg = false; + //static bool eventProcessingInProg = false; guiSignalRecvMark(); @@ -4592,16 +4593,16 @@ void consoleWin_t::emuFrameFinish(void) // return; //} // Prevent recursion as processEvents function can double back on us - if ( !eventProcessingInProg ) - { - eventProcessingInProg = true; - // Process all events before attempting to render viewport - QCoreApplication::processEvents(); - eventProcessingInProg = false; - } + //if ( !eventProcessingInProg ) + //{ + // eventProcessingInProg = true; + // // Process all events before attempting to render viewport + // QCoreApplication::processEvents(); + // eventProcessingInProg = false; + //} // Update Input Devices - FCEUD_UpdateInput(); + //FCEUD_UpdateInput(); //printf("EMU Frame Finish\n"); @@ -4609,7 +4610,7 @@ void consoleWin_t::emuFrameFinish(void) // QtScriptManager::getInstance()->frameFinishedUpdate(); //#endif - transferVideoBuffer(); + transferVideoBuffer(false); } void consoleWin_t::updatePeriodic(void) @@ -4634,7 +4635,7 @@ void consoleWin_t::updatePeriodic(void) FCEUD_UpdateInput(); // RePaint Game Viewport - transferVideoBuffer(); + transferVideoBuffer(true); // Low Rate Updates if ( (updateCounter % 30) == 0 ) diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index 96a5600a..22d02dfe 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -278,6 +278,7 @@ class consoleWin_t : public QMainWindow bool contextMenuEnable; bool soundUseGlobalFocus; bool autoHideMenuFullscreen; + bool redrawVideoRequest; std::list romList; std::vector afActList; @@ -313,7 +314,7 @@ class consoleWin_t : public QMainWindow void changeState(int slot); void saveState(int slot); void loadState(int slot); - void transferVideoBuffer(void); + void transferVideoBuffer(bool allowRedraw); void syncAutoFirePatternMenu(void); std::string findHelpFile(void);