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
This commit is contained in:
sinamas 2008-12-26 17:50:13 +00:00
parent 6056b96c0e
commit d7203ffd32
5 changed files with 61 additions and 28 deletions

View File

@ -139,7 +139,8 @@ impl(new Impl),
ft(1000000/60),
setPixelBuffer(setPixelBuffer),
nameString(name),
integerOnlyScaler(integerOnlyScaler)
integerOnlyScaler(integerOnlyScaler),
paused(true)
{
setMouseTracking(true);
}

View File

@ -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() {}

View File

@ -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<const QGLBlitter*>(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;
}

View File

@ -40,6 +40,7 @@ class QGLBlitter : public BlitterWidget {
bool bf;
void resetSubWidget();
void privSetPaused(const bool /*paused*/) {}
protected:
void resizeEvent(QResizeEvent *event);

View File

@ -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() {