@@ -6,9 +6,11 @@ endif | |||||
FLAGS += -MMD | FLAGS += -MMD | ||||
FLAGS += -g | FLAGS += -g | ||||
# Optimization | # Optimization | ||||
FLAGS += -O3 -march=nocona -ffast-math | |||||
FLAGS += -O3 -march=nocona -ffast-math -fno-finite-math-only | |||||
FLAGS += -Wall -Wextra -Wno-unused-parameter | FLAGS += -Wall -Wextra -Wno-unused-parameter | ||||
ifneq ($(ARCH), mac) | |||||
CXXFLAGS += -Wsuggest-override | CXXFLAGS += -Wsuggest-override | ||||
endif | |||||
CXXFLAGS += -std=c++11 | CXXFLAGS += -std=c++11 | ||||
@@ -84,7 +84,7 @@ static void engineRun() { | |||||
// Every time the engine waits and locks a mutex, it steps this many frames | // Every time the engine waits and locks a mutex, it steps this many frames | ||||
const int mutexSteps = 64; | const int mutexSteps = 64; | ||||
// Time in seconds that the engine is rushing ahead of the estimated clock time | // Time in seconds that the engine is rushing ahead of the estimated clock time | ||||
float ahead = 0.0; | |||||
double ahead = 0.0; | |||||
auto lastTime = std::chrono::high_resolution_clock::now(); | auto lastTime = std::chrono::high_resolution_clock::now(); | ||||
while (running) { | while (running) { | ||||
@@ -97,19 +97,19 @@ static void engineRun() { | |||||
} | } | ||||
} | } | ||||
float stepTime = mutexSteps / sampleRate; | |||||
double stepTime = mutexSteps / sampleRate; | |||||
ahead += stepTime; | ahead += stepTime; | ||||
auto currTime = std::chrono::high_resolution_clock::now(); | auto currTime = std::chrono::high_resolution_clock::now(); | ||||
const float aheadFactor = 2.0; | |||||
ahead -= aheadFactor * std::chrono::duration<float>(currTime - lastTime).count(); | |||||
const double aheadFactor = 2.0; | |||||
ahead -= aheadFactor * std::chrono::duration<double>(currTime - lastTime).count(); | |||||
lastTime = currTime; | lastTime = currTime; | ||||
ahead = fmaxf(ahead, 0.0); | ahead = fmaxf(ahead, 0.0); | ||||
// Avoid pegging the CPU at 100% when there are no "blocking" modules like AudioInterface, but still step audio at a reasonable rate | // Avoid pegging the CPU at 100% when there are no "blocking" modules like AudioInterface, but still step audio at a reasonable rate | ||||
// The number of steps to wait before possibly sleeping | // The number of steps to wait before possibly sleeping | ||||
const float aheadMax = 1.0; // seconds | |||||
const double aheadMax = 1.0; // seconds | |||||
if (ahead > aheadMax) { | if (ahead > aheadMax) { | ||||
std::this_thread::sleep_for(std::chrono::duration<float>(stepTime)); | |||||
std::this_thread::sleep_for(std::chrono::duration<double>(stepTime)); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -1,9 +1,11 @@ | |||||
#include <map> | |||||
#include <queue> | |||||
#include "gui.hpp" | #include "gui.hpp" | ||||
#include "app.hpp" | #include "app.hpp" | ||||
#include "asset.hpp" | #include "asset.hpp" | ||||
#include <map> | |||||
#include <queue> | |||||
#include <thread> | |||||
#include "../ext/osdialog/osdialog.h" | #include "../ext/osdialog/osdialog.h" | ||||
#define NANOVG_GL2_IMPLEMENTATION | #define NANOVG_GL2_IMPLEMENTATION | ||||
@@ -223,12 +225,9 @@ void renderGui() { | |||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | ||||
nvgBeginFrame(gVg, width, height, gPixelRatio); | nvgBeginFrame(gVg, width, height, gPixelRatio); | ||||
bool visible = glfwGetWindowAttrib(gWindow, GLFW_VISIBLE) && !glfwGetWindowAttrib(gWindow, GLFW_ICONIFIED); | |||||
if (visible) { | |||||
nvgReset(gVg); | |||||
nvgScale(gVg, gPixelRatio, gPixelRatio); | |||||
gScene->draw(gVg); | |||||
} | |||||
nvgReset(gVg); | |||||
nvgScale(gVg, gPixelRatio, gPixelRatio); | |||||
gScene->draw(gVg); | |||||
nvgEndFrame(gVg); | nvgEndFrame(gVg); | ||||
glfwSwapBuffers(gWindow); | glfwSwapBuffers(gWindow); | ||||
@@ -311,8 +310,8 @@ void guiRun() { | |||||
windowSizeCallback(gWindow, width, height); | windowSizeCallback(gWindow, width, height); | ||||
} | } | ||||
gGuiFrame = 0; | gGuiFrame = 0; | ||||
double lastTime = 0.0; | |||||
while(!glfwWindowShouldClose(gWindow)) { | while(!glfwWindowShouldClose(gWindow)) { | ||||
double startTime = glfwGetTime(); | |||||
gGuiFrame++; | gGuiFrame++; | ||||
// Poll events | // Poll events | ||||
@@ -336,12 +335,20 @@ void guiRun() { | |||||
gScene->step(); | gScene->step(); | ||||
// Render | // Render | ||||
renderGui(); | |||||
bool visible = glfwGetWindowAttrib(gWindow, GLFW_VISIBLE) && !glfwGetWindowAttrib(gWindow, GLFW_ICONIFIED); | |||||
if (visible) { | |||||
renderGui(); | |||||
} | |||||
double currTime = glfwGetTime(); | |||||
// printf("%lf fps\n", 1.0/(currTime - lastTime)); | |||||
lastTime = currTime; | |||||
(void) lastTime; | |||||
// Limit framerate manually if vsync isn't working | |||||
double endTime = glfwGetTime(); | |||||
double frameTime = endTime - startTime; | |||||
double minTime = 1.0 / 90.0; | |||||
if (frameTime < minTime) { | |||||
std::this_thread::sleep_for(std::chrono::duration<double>(minTime - frameTime)); | |||||
} | |||||
endTime = glfwGetTime(); | |||||
// printf("%lf fps\n", 1.0 / (endTime - startTime)); | |||||
} | } | ||||
} | } | ||||