From d7203ffd322d00447db21643304828e7316e6c32 Mon Sep 17 00:00:00 2001 From: sinamas Date: Fri, 26 Dec 2008 17:50:13 +0000 Subject: [PATCH] QGLBlitter: Do a cheap front blit rather than a vsynced flip if audio buffers are low. Allow BlitterWidgets to opt in to get paintEvents while unpaused. Do so for QGLBlitter since it may need to clear buffers afterwards. QGLBlitter: Try to blit right after sync in the case of single buffering. git-svn-id: https://gambatte.svn.sourceforge.net/svnroot/gambatte@206 9dfb2916-2d38-0410-aef4-c5fe6c9ffc24 --- gambatte_qt/src/framework/blitterwidget.cpp | 3 +- gambatte_qt/src/framework/blitterwidget.h | 10 ++- .../framework/blitterwidgets/qglblitter.cpp | 65 +++++++++++++------ .../src/framework/blitterwidgets/qglblitter.h | 1 + gambatte_qt/src/framework/mainwindow.cpp | 10 +-- 5 files changed, 61 insertions(+), 28 deletions(-) diff --git a/gambatte_qt/src/framework/blitterwidget.cpp b/gambatte_qt/src/framework/blitterwidget.cpp index 39d2c67e..c9d851cd 100644 --- a/gambatte_qt/src/framework/blitterwidget.cpp +++ b/gambatte_qt/src/framework/blitterwidget.cpp @@ -139,7 +139,8 @@ impl(new Impl), ft(1000000/60), setPixelBuffer(setPixelBuffer), nameString(name), -integerOnlyScaler(integerOnlyScaler) +integerOnlyScaler(integerOnlyScaler), +paused(true) { setMouseTracking(true); } diff --git a/gambatte_qt/src/framework/blitterwidget.h b/gambatte_qt/src/framework/blitterwidget.h index 5d560bb6..9ae7a6a6 100644 --- a/gambatte_qt/src/framework/blitterwidget.h +++ b/gambatte_qt/src/framework/blitterwidget.h @@ -56,7 +56,7 @@ class BlitterWidget : public QWidget { protected: PixelBufferSetter setPixelBuffer; - + public: struct Estimate { long est; @@ -65,12 +65,20 @@ public: const QString nameString; const bool integerOnlyScaler; + +private: + bool paused; + + virtual void privSetPaused(const bool paused) { setUpdatesEnabled(paused); } +public: BlitterWidget(PixelBufferSetter setPixelBuffer, const QString &name, bool integerOnlyScaler = false, QWidget *parent = 0); virtual ~BlitterWidget(); + bool isPaused() const { return paused; } + void setPaused(const bool paused) { this->paused = paused; privSetPaused(paused); } virtual void init() {} virtual void uninit() {} diff --git a/gambatte_qt/src/framework/blitterwidgets/qglblitter.cpp b/gambatte_qt/src/framework/blitterwidgets/qglblitter.cpp index 77040890..926d6ff3 100644 --- a/gambatte_qt/src/framework/blitterwidgets/qglblitter.cpp +++ b/gambatte_qt/src/framework/blitterwidgets/qglblitter.cpp @@ -59,11 +59,11 @@ protected: void resizeGL(int w, int h); public: - SubWidget(unsigned swapInterval, bool bf, QWidget *parent = 0); + SubWidget(unsigned swapInterval, bool bf, QGLBlitter *parent); ~SubWidget(); void blit(); -// void blitFront(); + void blitFront(); unsigned getInWidth() const { return inWidth; @@ -102,7 +102,7 @@ static const QGLFormat getQGLFormat(const unsigned swapInterval) { return f; } -QGLBlitter::SubWidget::SubWidget(const unsigned swapInterval_in, const bool bf_in, QWidget *parent) : +QGLBlitter::SubWidget::SubWidget(const unsigned swapInterval_in, const bool bf_in, QGLBlitter *parent) : QGLWidget(getQGLFormat(swapInterval_in), parent), corrected_w(160), corrected_h(144), @@ -180,24 +180,41 @@ void QGLBlitter::SubWidget::initializeGL() { initialized = true; } -/*void QGLBlitter::SubWidget::blitFront() { - GLint drawBuffer; +void QGLBlitter::SubWidget::blitFront() { + GLint drawBuffer = GL_BACK; glGetIntegerv(GL_DRAW_BUFFER, &drawBuffer); + + if (clear) { + --clear; + glClear(GL_COLOR_BUFFER_BIT); + } + glDrawBuffer(GL_FRONT); - blit(); + + if (clear) { + --clear; + glClear(GL_COLOR_BUFFER_BIT); + } + + glCallList(1); glDrawBuffer(drawBuffer); -}*/ + glFlush(); +} void QGLBlitter::SubWidget::paintGL() { clear = 2; + if (reinterpret_cast(parentWidget())->isPaused()) { // if (swapInterval) // blitFront(); // else { - blit(); + if (!blitted) + blit(); + swapBuffers(); blitted = false; // } + } } void QGLBlitter::SubWidget::resizeGL(const int w, const int h) { @@ -408,23 +425,29 @@ const BlitterWidget::Estimate QGLBlitter::frameTimeEst() const { }*/ long QGLBlitter::sync(const long ft) { - if (!subWidget->getSwapInterval()) - BlitterWidget::sync(ft); - + const bool vsyncing = subWidget->getSwapInterval(); + subWidget->makeCurrent(); -// if (subWidget->getSwapInterval() && turbo) -// subWidget->blitFront(); -// else { - if (!subWidget->blitted) - subWidget->blit(); + if (vsyncing && ft + (ft >> 2) < frameTime()) { + subWidget->blitFront(); + } else { + if (subWidget->doubleBuffer() && !subWidget->blitted) + subWidget->blit(); + + if (!vsyncing) + BlitterWidget::sync(ft); + + subWidget->swapBuffers(); + + if (vsyncing) + ftEst.update(getusecs()); + + if (!subWidget->blitted) + subWidget->blit(); + } - subWidget->swapBuffers(); subWidget->blitted = false; -// } - - if (subWidget->getSwapInterval()) - ftEst.update(getusecs()); return 0; } diff --git a/gambatte_qt/src/framework/blitterwidgets/qglblitter.h b/gambatte_qt/src/framework/blitterwidgets/qglblitter.h index 0a0c12d4..6fce649f 100644 --- a/gambatte_qt/src/framework/blitterwidgets/qglblitter.h +++ b/gambatte_qt/src/framework/blitterwidgets/qglblitter.h @@ -40,6 +40,7 @@ class QGLBlitter : public BlitterWidget { bool bf; void resetSubWidget(); + void privSetPaused(const bool /*paused*/) {} protected: void resizeEvent(QResizeEvent *event); diff --git a/gambatte_qt/src/framework/mainwindow.cpp b/gambatte_qt/src/framework/mainwindow.cpp index dff2f6e5..01d22299 100644 --- a/gambatte_qt/src/framework/mainwindow.cpp +++ b/gambatte_qt/src/framework/mainwindow.cpp @@ -359,11 +359,11 @@ void MainWindow::videoSettingsChange() { if (blitterContainer->blitter() != blitters[engineIndex]) { bool visible = false; - bool updatesEnabled = false; + bool paused = false; if (blitterContainer->blitter()) { visible = blitterContainer->blitter()->isVisible(); - updatesEnabled = blitterContainer->blitter()->updatesEnabled(); + paused = blitterContainer->blitter()->isPaused(); disconnect(fullModeToggler.get(), SIGNAL(rateChange(int)), blitterContainer->blitter(), SLOT(rateChange(int))); if (running) @@ -377,7 +377,7 @@ void MainWindow::videoSettingsChange() { connect(fullModeToggler.get(), SIGNAL(rateChange(int)), blitterContainer->blitter(), SLOT(rateChange(int))); fullModeToggler->emitRate(); blitterContainer->blitter()->setVisible(visible); - blitterContainer->blitter()->setUpdatesEnabled(updatesEnabled); + blitterContainer->blitter()->setPaused(paused); if (running) blitterContainer->blitter()->init(); @@ -632,7 +632,7 @@ void MainWindow::doPause() { killTimer(timerId); timerId = 0; jsTimer->start(); - blitterContainer->blitter()->setUpdatesEnabled(true); + blitterContainer->blitter()->setPaused(true); } void MainWindow::doUnpause() { @@ -641,7 +641,7 @@ void MainWindow::doUnpause() { jsTimer->stop(); timerId = startTimer(0); - blitterContainer->blitter()->setUpdatesEnabled(false); + blitterContainer->blitter()->setPaused(false); } void MainWindow::pause() {