Skip to content

Commit 15ff1ef

Browse files
authored
Readds all the std::chrono calls back into the game loop. (#85)
Move from QueryPerformanceCounter to std::chrono::steady_clock for multiplatforming
1 parent a6129d4 commit 15ff1ef

File tree

9 files changed

+109
-31
lines changed

9 files changed

+109
-31
lines changed

src/Core/Core.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include <cstdint>
4+
#include <chrono>
45

56
namespace Vortex {
67

@@ -51,7 +52,7 @@ struct TimingData;
5152
typedef const String& StringRef;
5253
typedef uint64_t TextureHandle;
5354

54-
extern float deltaTime;
55+
extern std::chrono::duration<double> deltaTime;
5556

5657
extern void HudNote(const char* fmt, ...);
5758
extern void HudInfo(const char* fmt, ...);

src/Core/TextDraw.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,8 +321,6 @@ void Text::draw(vec2i textPos)
321321
}
322322
batch.flush();
323323
}
324-
325-
VortexCheckGlError();
326324
}
327325

328326
};

src/Editor/Editor.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -894,13 +894,13 @@ void tick()
894894
gTextOverlay->handleInputs(events);
895895

896896
GuiMain::setViewSize(r.w, r.h);
897-
GuiMain::frameStart(deltaTime, events);
897+
GuiMain::frameStart(deltaTime.count(), events);
898898

899899
vec2i view = gSystem->getWindowSize();
900900

901901
handleDialogs();
902902

903-
gui_->tick({ 0, 0, view.x, view.y }, deltaTime, events);
903+
gui_->tick({ 0, 0, view.x, view.y }, deltaTime.count(), events);
904904

905905
if (!GuiMain::isCapturingText())
906906
{

src/Editor/Music.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <limits.h>
44
#include <stdint.h>
55
#include <math.h>
6+
#include <chrono>
67

78
#include <Core/Vector.h>
89
#include <Core/Reference.h>
@@ -48,7 +49,7 @@ struct MusicImpl : public Music, public MixSource {
4849

4950
Mixer* myMixer;
5051
Sound mySamples;
51-
double myPlayTimer;
52+
std::chrono::steady_clock::time_point myPlayTimer;
5253
TickData myBeatTick, myNoteTick;
5354
String myTitle, myArtist;
5455
int myMusicSpeed;

src/Editor/Sound.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <stdint.h>
1212
#include <limits.h>
13+
#include <chrono>
1314

1415
namespace Vortex {
1516

@@ -93,7 +94,7 @@ class Sound::Thread : public BackgroundThread
9394
int myCurrentFrame;
9495
int myReservedFrames;
9596
uchar myProgress;
96-
double myStartTime;
97+
std::chrono::steady_clock::time_point myStartTime;
9798
};
9899

99100
Sound::Thread::~Thread()

src/Editor/TextOverlay.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ void tickHud()
411411
{
412412
fade += 0.5f;
413413
}
414-
float delta = clamp(deltaTime * fade, 0.0f, 1.0f);
414+
float delta = clamp(deltaTime.count() * fade, 0.0, 1.0);
415415

416416
hudEntries_[i].timeLeft -= delta;
417417
if(hudEntries_[i].timeLeft <= -0.5f) hudEntries_.erase(i);
@@ -625,7 +625,7 @@ void drawAbout()
625625

626626
DrawTitleText("ABOUT", "[ESC] close", nullptr);
627627

628-
auto fps = Str::fmt("%1 FPS").arg(1.0f / max(deltaTime, 0.0001f), 0, 0);
628+
auto fps = Str::fmt("%1 FPS").arg(1.0f / max(deltaTime.count(), 0.0001), 0, 0);
629629
Text::arrange(Text::TR, fps);
630630
Text::draw(vec2i{size.x - 4, 4});
631631
}

src/System/Debug.cpp

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include <io.h>
66
#include <fcntl.h>
77
#include <stdio.h>
8-
#include <time.h>
8+
#include <chrono>
99

1010
#define WIN32_LEAN_AND_MEAN
1111
#include <windows.h>
@@ -17,22 +17,18 @@ namespace Debug {
1717

1818
// ================================================================================================
1919
// Debug :: timing functions.
20+
using namespace std::chrono;
2021

21-
double getElapsedTime()
22+
steady_clock::time_point getElapsedTime()
2223
{
23-
static const double timer = []() {
24-
LARGE_INTEGER freq;
25-
return QueryPerformanceFrequency(&freq) ? 1.0 / static_cast<double>(freq.QuadPart) : 1.0;
26-
}();
27-
28-
LARGE_INTEGER counter;
29-
QueryPerformanceCounter(&counter);
30-
return static_cast<double>(counter.QuadPart) * timer;
24+
return std::chrono::steady_clock::now();
3125
}
3226

33-
double getElapsedTime(double startTime)
27+
double getElapsedTime(steady_clock::time_point startTime)
3428
{
35-
return getElapsedTime() - startTime;
29+
auto currentTime = steady_clock::now();
30+
const duration<double> deltaTime = currentTime - startTime;
31+
return deltaTime.count();
3632
}
3733

3834
// ================================================================================================

src/System/Debug.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <Core/Core.h>
44
#include <assert.h>
5+
#include <chrono>
56

67
#ifndef _DEBUG
78
#define VORTEX_DISABLE_ASSERTS
@@ -15,10 +16,10 @@ namespace Debug
1516
enum Type { INFO, WARNING, ERROR };
1617

1718
/// Returns a timestamp of the current time.
18-
double getElapsedTime();
19+
std::chrono::steady_clock::time_point getElapsedTime();
1920

2021
/// Returns the number of seconds elapsed since the start time.
21-
double getElapsedTime(double startTime);
22+
double getElapsedTime(std::chrono::steady_clock::time_point startTime);
2223

2324
/// Creates a blank log file.
2425
void openLogFile();

src/System/System.cpp

Lines changed: 88 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <gl/gl.h>
2929
#undef ERROR
3030

31+
#include <chrono>
3132
#include <thread>
3233
#include <numeric>
3334
#include <stdio.h>
@@ -45,7 +46,7 @@ processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
4546

4647
namespace Vortex {
4748

48-
float deltaTime; // Defined in <Core/Core.h>
49+
std::chrono::duration<double> deltaTime; // Defined in <Core/Core.h>
4950

5051
namespace {
5152

@@ -222,7 +223,7 @@ struct SystemImpl : public System {
222223

223224
wchar_t* myClassName;
224225
HINSTANCE myInstance;
225-
double myApplicationStartTime;
226+
std::chrono::steady_clock::time_point myApplicationStartTime;
226227
Cursor::Icon myCursor;
227228
Key::Code myKeyMap[256];
228229
InputEvents myEvents;
@@ -398,22 +399,28 @@ void createMenu()
398399

399400
void CALLBACK messageLoop()
400401
{
402+
using namespace std::chrono;
403+
401404
if(!myInitSuccesful) return;
402405

403406
#ifdef DEBUG
404407
long long frames = 0;
405408
auto lowcounts = 0;
406-
std::list<double> fpsList, sleepList, frameList, inputList, waitList;
409+
std::list<double> fpsList, sleepList, frameList, inputList, waitList;
410+
// Adjust frameGuess to your VSync target if you are testing with VSync enabled
407411
auto frameGuess = 960;
408412
#endif
409413

410414
Editor::create();
411415
forwardArgs();
412416
createMenu();
413417

418+
// Non-vsync FPS max target
419+
auto frameTarget = duration<double>(1.0 / 960.0);
420+
414421
// Enter the message loop.
415422
MSG message;
416-
double prevTime = Debug::getElapsedTime();
423+
auto prevTime = Debug::getElapsedTime();
417424
while(!myIsTerminated)
418425
{
419426

@@ -446,15 +453,88 @@ void CALLBACK messageLoop()
446453
// Reset the mouse cursor.
447454
myCursor = Cursor::ARROW;
448455

449-
// Tick function.
450-
double curTime = Debug::getElapsedTime();
451-
deltaTime = (float)min(max(0.00025, curTime - prevTime), 0.25);
452-
prevTime = curTime;
456+
#ifdef DEBUG
457+
auto inputTime = Debug::getElapsedTime();
458+
#endif
459+
460+
VortexCheckGlError();
453461

454462
gEditor->tick();
455463

456464
// Display.
457465
SwapBuffers(myHDC);
466+
467+
#ifdef DEBUG
468+
auto renderTime = Debug::getElapsedTime();
469+
#endif
470+
// Tick function.
471+
duration<double> frameTime = Debug::getElapsedTime() - prevTime;
472+
auto waitTime = frameTarget.count() - frameTime.count();
473+
474+
if (wglSwapInterval)
475+
{
476+
while (Debug::getElapsedTime() - prevTime < frameTarget)
477+
{
478+
std::this_thread::yield();
479+
}
480+
}
481+
482+
// End of frame
483+
auto curTime = Debug::getElapsedTime();
484+
deltaTime = duration<double>((float)min(max(0, duration<double>(curTime - prevTime).count()), 0.25));
485+
prevTime = curTime;
486+
487+
#ifdef DEBUG
488+
// Do frame statistics
489+
// Note that these will be wrong with VSync enabled.
490+
fpsList.push_front(deltaTime.count());
491+
waitList.push_front(duration<double>(curTime - renderTime).count());
492+
frameList.push_front(duration<double>(renderTime - inputTime).count());
493+
inputList.push_front(duration<double>(inputTime - startTime).count());
494+
495+
if (abs(deltaTime.count() - 1.0 / (double)frameGuess) / (1.0 / (double)frameGuess) > 0.01)
496+
{
497+
lowcounts++;
498+
}
499+
if (fpsList.size() >= frameGuess * 2)
500+
{
501+
fpsList.pop_back();
502+
frameList.pop_back();
503+
inputList.pop_back();
504+
waitList.pop_back();
505+
}
506+
auto min = *std::min_element(fpsList.begin(), fpsList.end());
507+
auto max = *std::max_element(fpsList.begin(), fpsList.end());
508+
auto maxIndex = std::distance(fpsList.begin(), std::max_element(fpsList.begin(), fpsList.end()));
509+
auto siz = fpsList.size();
510+
auto avg = std::accumulate(fpsList.begin(), fpsList.end(), 0.0) / siz;
511+
auto varianceFunc = [&avg, &siz](double accumulator, double val) {
512+
return accumulator + (val - avg) * (val - avg);
513+
};
514+
auto std = sqrt(std::accumulate(fpsList.begin(), fpsList.end(), 0.0, varianceFunc) / siz);
515+
auto frameAvg = std::accumulate(frameList.begin(), frameList.end(), 0.0) / frameList.size();
516+
auto frameMax = frameList.begin();
517+
std::advance(frameMax, maxIndex);
518+
auto inputMax = inputList.begin();
519+
std::advance(inputMax, maxIndex);
520+
auto waitMax = waitList.begin();
521+
std::advance(waitMax, maxIndex);
522+
if (frames % (frameGuess * 2) == 0)
523+
{
524+
Debug::log("frame total average: %f, frame render average %f, std dev %f, lowest FPS %f, highest FPS %f, highest FPS render time %f, highest FPS input time %f, highest FPS wait time %f, lag frames %d\n",
525+
avg,
526+
frameAvg,
527+
std,
528+
1.0 / max,
529+
1.0 / min,
530+
*frameMax,
531+
*inputMax,
532+
*waitMax,
533+
lowcounts);
534+
lowcounts = 0;
535+
}
536+
frames++;
537+
#endif
458538
}
459539
Editor::destroy();
460540
}

0 commit comments

Comments
 (0)