Skip to content

Commit

Permalink
Video|GL: Re-enabled the FPS limiter (cvar “refresh-rate-maximum”)
Browse files Browse the repository at this point in the history
Now comes with a slider in Video Settings.

IssueID #2189
  • Loading branch information
skyjake committed Feb 25, 2017
1 parent d4563d8 commit e761423
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 32 deletions.
4 changes: 2 additions & 2 deletions doomsday/apps/client/include/gl/gl_main.h
Expand Up @@ -145,9 +145,9 @@ de::Matrix4f GL_GetProjectionMatrix();
void GL_SelectTexUnits(int count);

/**
* Swaps buffers / blits the back buffer to the front.
* Finish the frame being rendered. Applies the FPS limiter, if enabled.
*/
void GL_DoUpdate();
void GL_FinishFrame();

/**
* Set the current GL blending mode.
Expand Down
Expand Up @@ -49,7 +49,8 @@ list {
}

dialog {
rule gap { constant $= UNIT * 2 }
rule gap { constant $= UNIT * 2 }
rule separator { constant $= UNIT * 4 }

rule about.width { constant $= UNIT * 80 }
rule message.width { constant $= UNIT * 115 }
Expand Down
14 changes: 7 additions & 7 deletions doomsday/apps/client/src/dd_loop.cpp
Expand Up @@ -74,7 +74,7 @@ using namespace de;

dfloat frameTimePos; ///< 0...1: fractional part for sharp game tics.

dint maxFrameRate = 120; ///< Zero means 'unlimited'.
dint maxFrameRate = 0; ///< Zero means 'unlimited'.
// Refresh frame count (independant of the viewport-specific frameCount).
dint rFrameCount;
byte devShowFrameTimeDeltas;
Expand Down Expand Up @@ -329,7 +329,7 @@ void DD_WaitForOptimalUpdateTime()
/// so we can't use fractions of a millisecond.
duint const optimalDelta = (::maxFrameRate > 0 ? 1000 / ::maxFrameRate : 1);

if(Sys_IsShuttingDown()) return; // No need for finesse.
if (Sys_IsShuttingDown()) return; // No need for finesse.

// This is when we would ideally like to make the update.
duint const targetUpdateTime = prevUpdateTime + optimalDelta;
Expand All @@ -338,12 +338,12 @@ void DD_WaitForOptimalUpdateTime()
duint nowTime = Timer_RealMilliseconds();
duint elapsed = nowTime - prevUpdateTime;

if(elapsed < optimalDelta)
if (elapsed < optimalDelta)
{
duint const needSleepMs = optimalDelta - elapsed;

// We need to wait until the optimal time has passed.
if(needSleepMs > 5)
if (needSleepMs > 5)
{
// Longer sleep, yield to other threads.
Sys_Sleep(needSleepMs - 3); // Leave some room for inaccuracies.
Expand All @@ -359,7 +359,7 @@ void DD_WaitForOptimalUpdateTime()
// The time for this update.
prevUpdateTime = nowTime;

timeDeltaStatistics(dint( elapsed ) - dint( optimalDelta ));
timeDeltaStatistics(dint(elapsed) - dint(optimalDelta));
}

timespan_t DD_LatestRunTicsStartTime()
Expand Down Expand Up @@ -436,12 +436,12 @@ void Loop_RunTics()
// Various global variables are used for counting time.
advanceTime(::ticLength);
}
}
}

void DD_RegisterLoop()
{
C_VAR_BYTE("input-sharp-lateprocessing", &::processSharpEventsAfterTickers, 0, 0, 1);
C_VAR_INT ("refresh-rate-maximum", &::maxFrameRate, 0, 35, 1000);
C_VAR_INT ("refresh-rate-maximum", &::maxFrameRate, 0, 0, 1000);
C_VAR_INT ("rend-dev-framecount", &::rFrameCount, CVF_NO_ARCHIVE | CVF_PROTECTED, 0, 0);
C_VAR_BYTE("rend-info-deltas-frametime", &::devShowFrameTimeDeltas, CVF_NO_ARCHIVE, 0, 1);
}
12 changes: 6 additions & 6 deletions doomsday/apps/client/src/gl/gl_main.cpp
Expand Up @@ -196,7 +196,7 @@ void GL_SetGamma()
GL_SetGammaRamp(&myramp);
}

void GL_DoUpdate()
void GL_FinishFrame()
{
if(ClientApp::vr().mode() == VRConfig::OculusRift) return;

Expand All @@ -211,8 +211,8 @@ void GL_DoUpdate()

// Wait until the right time to show the frame so that the realized
// frame rate is exactly right.
//glFlush();
//DD_WaitForOptimalUpdateTime();
LIBGUI_GL.glFlush();
DD_WaitForOptimalUpdateTime();

// Blit screen to video.
//ClientWindow::main().swapBuffers();
Expand Down Expand Up @@ -322,15 +322,15 @@ void GL_Shutdown()
// artefacts during video context switches on some displays.
//
// Render a few black frames before we continue.
if(!novideo)
/*if(!novideo)
{
dint i = 0;
do
{
LIBGUI_GL.glClear(GL_COLOR_BUFFER_BIT);
GL_DoUpdate();
GL_FinishFrame();
} while(++i < 3);
}
}*/
ClientApp::renderSystem().glDeinit();
GL_ShutdownDeferredTask();
FR_Shutdown();
Expand Down
2 changes: 1 addition & 1 deletion doomsday/apps/client/src/render/rendersystem.cpp
Expand Up @@ -233,7 +233,7 @@ DENG2_PIMPL(RenderSystem)
typedef ConfigProfiles SReg;

// Initialize settings.
settings.define(SReg::FloatCVar, "rend-camera-fov", 95.f)
settings.define(SReg::FloatCVar, "rend-camera-fov", 95.f)
.define(SReg::ConfigVariable, "render.pixelDensity")
.define(SReg::IntCVar, "rend-model-mirror-hud", 0)
.define(SReg::IntCVar, "rend-model-precache", 1)
Expand Down
2 changes: 1 addition & 1 deletion doomsday/apps/client/src/ui/clientwindow.cpp
Expand Up @@ -930,7 +930,7 @@ void ClientWindow::postDraw()
{
// Finish GL drawing and swap it on to the screen. Blocks until buffers
// swapped.
GL_DoUpdate();
GL_FinishFrame();
}

BaseWindow::postDraw();
Expand Down
1 change: 1 addition & 0 deletions doomsday/apps/client/src/ui/clientwindowsystem.cpp
Expand Up @@ -50,6 +50,7 @@ DENG2_PIMPL(ClientWindowSystem)
settings.define(SReg::ConfigVariable, "window.main.showFps")
.define(SReg::ConfigVariable, "window.main.fsaa")
.define(SReg::ConfigVariable, "window.main.vsync")
.define(SReg::IntCVar, "refresh-rate-maximum", 0)
.define(SReg::IntCVar, "rend-finale-stretch", SCALEMODE_SMART_STRETCH)
.define(SReg::IntCVar, "rend-hud-stretch", SCALEMODE_SMART_STRETCH)
.define(SReg::IntCVar, "inlude-stretch", SCALEMODE_SMART_STRETCH)
Expand Down
16 changes: 9 additions & 7 deletions doomsday/apps/client/src/ui/dialogs/renderersettingsdialog.cpp
Expand Up @@ -126,9 +126,6 @@ DENG_GUI_PIMPL(RendererSettingsDialog)

void fetch()
{
/// @todo These widgets should be intelligent enough to fetch their
/// cvar values when they need to....

foreach (Widget *child, self().area().childWidgets() + devPopup->content().childWidgets())
{
if (ICVarWidget *w = child->maybeAs<ICVarWidget>())
Expand All @@ -137,6 +134,14 @@ DENG_GUI_PIMPL(RendererSettingsDialog)
}
}
}

void apply()
{
if (texSettingsToggled)
{
GL_TexReset();
}
}
};

RendererSettingsDialog::RendererSettingsDialog(String const &name)
Expand Down Expand Up @@ -231,8 +236,5 @@ void RendererSettingsDialog::finish(int result)
{
DialogWidget::finish(result);

if (d->texSettingsToggled)
{
GL_TexReset();
}
d->apply();
}
52 changes: 45 additions & 7 deletions doomsday/apps/client/src/ui/dialogs/videosettingsdialog.cpp
Expand Up @@ -53,6 +53,8 @@ DENG2_OBSERVES(PersistentGLWindow, AttributeChange)
ToggleWidget *centered;
VariableToggleWidget *fsaa;
VariableToggleWidget *vsync;
ToggleWidget *fpsLimiter = nullptr;
SliderWidget *fpsMax = nullptr;
ChoiceWidget *modes;
ButtonWidget *windowButton;
#ifdef USE_COLOR_DEPTH_CHOICE
Expand Down Expand Up @@ -85,6 +87,21 @@ DENG2_OBSERVES(PersistentGLWindow, AttributeChange)

if (App_GameLoaded())
{
area.add(fpsLimiter = new ToggleWidget);
fpsLimiter->margins().setTop("dialog.separator");
fpsLimiter->setText(tr("FPS Limiter"));
QObject::connect(fpsLimiter, &ToggleWidget::stateChangedByUser, [this] (ToggleWidget::ToggleState st) {
fpsMax->enable(st == ToggleWidget::Active);
applyFpsMax();
});

area.add(fpsMax = new SliderWidget);
fpsMax->margins().setTop("dialog.separator");
fpsMax->setRange(Ranged(35, 60));
fpsMax->setPrecision(0);
fpsMax->rule().setInput(Rule::Width, centered->rule().width());
QObject::connect(fpsMax, &SliderWidget::valueChangedByUser, [this] (double) { applyFpsMax(); });

stretchChoices
<< new ChoiceItem(tr("Smart"), SCALEMODE_SMART_STRETCH)
<< new ChoiceItem(tr("Original 1:1"), SCALEMODE_NO_STRETCH)
Expand All @@ -96,9 +113,9 @@ DENG2_OBSERVES(PersistentGLWindow, AttributeChange)
area.add(menuAspect = new CVarChoiceWidget("menu-stretch"));

finaleAspect->setItems(stretchChoices);
hudAspect->setItems(stretchChoices);
hudAspect ->setItems(stretchChoices);
inludeAspect->setItems(stretchChoices);
menuAspect->setItems(stretchChoices);
menuAspect ->setItems(stretchChoices);
}
}

Expand Down Expand Up @@ -152,6 +169,15 @@ DENG2_OBSERVES(PersistentGLWindow, AttributeChange)
depths->setSelected(depths->items().findData(win.colorDepthBits()));
#endif

// FPS limit.
if (fpsMax)
{
int const max = CVar_Integer(Con_FindVariable("refresh-rate-maximum"));
fpsLimiter->setActive(max != 0);
fpsMax->enable(max != 0);
fpsMax->setValue(!max ? 35 : max);
}

foreach (Widget *child, self().area().childWidgets())
{
if (ICVarWidget *cw = child->maybeAs<ICVarWidget>())
Expand All @@ -163,6 +189,15 @@ DENG2_OBSERVES(PersistentGLWindow, AttributeChange)
{
fetch();
}

void applyFpsMax()
{
if (fpsMax)
{
CVar_SetInteger(Con_FindVariable("refresh-rate-maximum"),
fpsLimiter->isActive()? int(fpsMax->value()) : 0);
}
}
};

VideoSettingsDialog::VideoSettingsDialog(String const &name)
Expand Down Expand Up @@ -244,16 +279,19 @@ VideoSettingsDialog::VideoSettingsDialog(String const &name)

GridLayout layout(area().contentRule().left(),
area().contentRule().top(), GridLayout::RowFirst);
layout.setGridSize(2, 3);
layout.setGridSize(2, d->fpsLimiter? 4 : 3);
layout.setColumnPadding(rule(RuleBank::UNIT));
layout << *d->showFps
<< *d->fsaa
layout << *d->fsaa
<< *d->vsync
<< *d->fullscreen
<< *d->showFps;
if (d->fpsLimiter) layout << *d->fpsLimiter;
layout << *d->fullscreen
<< *d->maximized
<< *d->centered;
if (d->fpsMax) layout << *d->fpsMax;

GridLayout modeLayout(d->vsync->rule().left(), d->vsync->rule().bottom() + gap);
GridLayout modeLayout(d->vsync->rule().left(),
(d->fpsLimiter? d->fpsLimiter : d->showFps)->rule().bottom() + gap);
modeLayout.setGridSize(2, 0);
modeLayout.setColumnAlignment(0, ui::AlignRight);

Expand Down

0 comments on commit e761423

Please sign in to comment.