From aa7fbd03292a6441ec3d154ea6d4ea1a378efc8b Mon Sep 17 00:00:00 2001
From: Matt Weber <30441572+mweber15@users.noreply.github.com>
Date: Mon, 15 Mar 2021 00:36:27 -0400
Subject: [PATCH 1/4] Add foreground FPS limit
As reported in issue #13, PoB tends to use significant CPU and GPU resources
while in the foreground. This change exposes a foreground frame rate limit that
can be configured via a CVar (vid_fgfps) that defaults to a 30 FPS limit and
allows a 5-120 FPS range. A setting of 30 feels responsive and reduces the
resource usage by a modest amount. CPU usage hovers around 4% on my 16-core
system with this change, as opposed to 6% usage with the current build.
Similarly, GPU usage hovers around 18-20% with the 30 FPS limit and around
25-28% with the current build.
There may be a better place to situate the sleep that is introduced for this,
but this seemed like a reasonable place for someone who is not very familiar
with this code.
I also removed the reference to tiff.lib in the Debug configuration since that
is unused and not a vcpkg dependency.
---
SimpleGraphic.vcxproj | 2 +-
config.h | 1 +
engine/core/core_video.cpp | 3 +++
engine/system/sys_video.h | 2 ++
engine/system/win/sys_main.cpp | 11 +++++++++++
engine/system/win/sys_video.cpp | 2 ++
6 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/SimpleGraphic.vcxproj b/SimpleGraphic.vcxproj
index 16f239c..8cdfba3 100644
--- a/SimpleGraphic.vcxproj
+++ b/SimpleGraphic.vcxproj
@@ -120,7 +120,7 @@
true
false
$(SolutionDir)vcpkg\installed\x86-windows-static\lib;%(AdditionalLibraryDirectories)LuaJIT/src;%(AdditionalLibraryDirectories)
- gif.lib;jpeg.lib;lzma.lib;libpng16.lib;lua51.lib;tiff.lib;zlib.lib;opengl32.lib;winmm.lib;%(AdditionalDependencies)
+ gif.lib;jpeg.lib;lzma.lib;libpng16.lib;lua51.lib;zlib.lib;opengl32.lib;winmm.lib;%(AdditionalDependencies)
diff --git a/config.h b/config.h
index f484d5a..6d466dc 100644
--- a/config.h
+++ b/config.h
@@ -18,5 +18,6 @@
#define CFG_VID_DEFDISPLAY "-1"
#define CFG_VID_DEFFULLSCREEN "0"
#define CFG_VID_DEFRESIZABLE "0"
+#define CFG_VID_DEFFGFPS "30"
#define CFG_VID_MINWIDTH 1280
#define CFG_VID_MINHEIGHT 720
\ No newline at end of file
diff --git a/engine/core/core_video.cpp b/engine/core/core_video.cpp
index f6bfcf1..e347d6d 100644
--- a/engine/core/core_video.cpp
+++ b/engine/core/core_video.cpp
@@ -48,6 +48,7 @@ class core_video_c: public core_IVideo, public conCmdHandler_c {
conVar_c* vid_fullscreen;
conVar_c* vid_resizable;
conVar_c* vid_last;
+ conVar_c* vid_fgfps;
void C_Vid_Apply(IConsole* conHnd, args_c &args);
void C_Vid_ModeList(IConsole* conHnd, args_c &args);
@@ -71,6 +72,7 @@ core_video_c::core_video_c(sys_IMain* sysHnd)
vid_fullscreen = sys->con->Cvar_Add("vid_fullscreen", CV_ARCHIVE, CFG_VID_DEFFULLSCREEN);
vid_resizable = sys->con->Cvar_Add("vid_resizable", CV_ARCHIVE|CV_CLAMP, CFG_VID_DEFRESIZABLE, 0, 3);
vid_last = sys->con->Cvar_Add("vid_last", CV_ARCHIVE, "");
+ vid_fgfps = sys->con->Cvar_Add("vid_fgfps", CV_ARCHIVE|CV_CLAMP, CFG_VID_DEFFGFPS, 5, 120);
Cmd_Add("vid_apply", 0, "", this, &core_video_c::C_Vid_Apply);
Cmd_Add("vid_modeList", 0, "", this, &core_video_c::C_Vid_ModeList);
@@ -111,6 +113,7 @@ void core_video_c::Apply(bool shown)
set.depth = 0;
set.minSize[0] = CFG_VID_MINWIDTH;
set.minSize[1] = CFG_VID_MINHEIGHT;
+ set.fgfps = vid_fgfps->intVal;
sys->video->Apply(&set);
}
diff --git a/engine/system/sys_video.h b/engine/system/sys_video.h
index 461a95e..1e8a39b 100644
--- a/engine/system/sys_video.h
+++ b/engine/system/sys_video.h
@@ -22,6 +22,7 @@ struct sys_vidSave_s {
int size[2] = {};
int pos[2] = {};
bool maximised = false;
+ int fgfps = 0;
};
// Video settings structure
@@ -32,6 +33,7 @@ struct sys_vidSet_s {
int mode[2] = {}; // Resolution or window size
int depth = 0; // Bit depth
int minSize[2] = {}; // Minimum size for resizable windows
+ int fgfps = 0; // Foreground FPS limit
sys_vidSave_s save; // Saved state
};
diff --git a/engine/system/win/sys_main.cpp b/engine/system/win/sys_main.cpp
index 84ab748..42504ec 100644
--- a/engine/system/win/sys_main.cpp
+++ b/engine/system/win/sys_main.cpp
@@ -11,6 +11,9 @@
#include
+#include
+#include
+
// ======
// Locals
// ======
@@ -777,7 +780,15 @@ bool sys_main_c::Run(int argc, char** argv)
while (exitFlag == false) {
RunMessages();
+ const auto frameStart = std::chrono::high_resolution_clock::now();
core->Frame();
+ const auto frameEnd = std::chrono::high_resolution_clock::now();
+ using FpMilliseconds = std::chrono::duration;
+ const auto frameDuration = std::chrono::duration_cast(frameEnd - frameStart);
+ const auto minimumFrameDuration = FpMilliseconds(1000.0f / video->vid.fgfps);
+ if (frameDuration < minimumFrameDuration) {
+ std::this_thread::sleep_for(minimumFrameDuration - frameDuration);
+ }
if (threadError) {
Error(threadError);
diff --git a/engine/system/win/sys_video.cpp b/engine/system/win/sys_video.cpp
index 6d8d81b..891c8a7 100644
--- a/engine/system/win/sys_video.cpp
+++ b/engine/system/win/sys_video.cpp
@@ -275,6 +275,8 @@ int sys_video_c::Apply(sys_vidSet_s* set)
vid.size[0] = wrec.right;
vid.size[1] = wrec.bottom;
+ vid.fgfps = cur.fgfps;
+
// Process any messages generated during application
sys->RunMessages();
From 2dec7930bf1171d4a22ed3b7642bd20c62c85d04 Mon Sep 17 00:00:00 2001
From: Matt Weber <30441572+mweber15@users.noreply.github.com>
Date: Tue, 16 Mar 2021 05:01:18 -0400
Subject: [PATCH 2/4] Revert tiff.lib removal
---
SimpleGraphic.vcxproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/SimpleGraphic.vcxproj b/SimpleGraphic.vcxproj
index 8cdfba3..16f239c 100644
--- a/SimpleGraphic.vcxproj
+++ b/SimpleGraphic.vcxproj
@@ -120,7 +120,7 @@
true
false
$(SolutionDir)vcpkg\installed\x86-windows-static\lib;%(AdditionalLibraryDirectories)LuaJIT/src;%(AdditionalLibraryDirectories)
- gif.lib;jpeg.lib;lzma.lib;libpng16.lib;lua51.lib;zlib.lib;opengl32.lib;winmm.lib;%(AdditionalDependencies)
+ gif.lib;jpeg.lib;lzma.lib;libpng16.lib;lua51.lib;tiff.lib;zlib.lib;opengl32.lib;winmm.lib;%(AdditionalDependencies)
From ab3f87db23dea1294ce550f2a95067bfab25796c Mon Sep 17 00:00:00 2001
From: Matt Weber <30441572+mweber15@users.noreply.github.com>
Date: Tue, 16 Mar 2021 05:25:51 -0400
Subject: [PATCH 3/4] Incorporate review feedback
---
config.h | 1 +
engine/core/core_video.cpp | 3 +++
engine/system/sys_video.h | 2 ++
engine/system/win/sys_main.cpp | 11 -----------
engine/system/win/sys_video.cpp | 1 +
ui_main.cpp | 20 ++++++++++++++++----
6 files changed, 23 insertions(+), 15 deletions(-)
diff --git a/config.h b/config.h
index 6d466dc..21f388b 100644
--- a/config.h
+++ b/config.h
@@ -19,5 +19,6 @@
#define CFG_VID_DEFFULLSCREEN "0"
#define CFG_VID_DEFRESIZABLE "0"
#define CFG_VID_DEFFGFPS "30"
+#define CFG_VID_DEFBGFPS "5"
#define CFG_VID_MINWIDTH 1280
#define CFG_VID_MINHEIGHT 720
\ No newline at end of file
diff --git a/engine/core/core_video.cpp b/engine/core/core_video.cpp
index e347d6d..fbe0b25 100644
--- a/engine/core/core_video.cpp
+++ b/engine/core/core_video.cpp
@@ -49,6 +49,7 @@ class core_video_c: public core_IVideo, public conCmdHandler_c {
conVar_c* vid_resizable;
conVar_c* vid_last;
conVar_c* vid_fgfps;
+ conVar_c* vid_bgfps;
void C_Vid_Apply(IConsole* conHnd, args_c &args);
void C_Vid_ModeList(IConsole* conHnd, args_c &args);
@@ -73,6 +74,7 @@ core_video_c::core_video_c(sys_IMain* sysHnd)
vid_resizable = sys->con->Cvar_Add("vid_resizable", CV_ARCHIVE|CV_CLAMP, CFG_VID_DEFRESIZABLE, 0, 3);
vid_last = sys->con->Cvar_Add("vid_last", CV_ARCHIVE, "");
vid_fgfps = sys->con->Cvar_Add("vid_fgfps", CV_ARCHIVE|CV_CLAMP, CFG_VID_DEFFGFPS, 5, 120);
+ vid_bgfps = sys->con->Cvar_Add("vid_bgfps", CV_ARCHIVE | CV_CLAMP, CFG_VID_DEFBGFPS, 5, 120);
Cmd_Add("vid_apply", 0, "", this, &core_video_c::C_Vid_Apply);
Cmd_Add("vid_modeList", 0, "", this, &core_video_c::C_Vid_ModeList);
@@ -114,6 +116,7 @@ void core_video_c::Apply(bool shown)
set.minSize[0] = CFG_VID_MINWIDTH;
set.minSize[1] = CFG_VID_MINHEIGHT;
set.fgfps = vid_fgfps->intVal;
+ set.bgfps = vid_bgfps->intVal;
sys->video->Apply(&set);
}
diff --git a/engine/system/sys_video.h b/engine/system/sys_video.h
index 1e8a39b..b5bff56 100644
--- a/engine/system/sys_video.h
+++ b/engine/system/sys_video.h
@@ -23,6 +23,7 @@ struct sys_vidSave_s {
int pos[2] = {};
bool maximised = false;
int fgfps = 0;
+ int bgfps = 0;
};
// Video settings structure
@@ -34,6 +35,7 @@ struct sys_vidSet_s {
int depth = 0; // Bit depth
int minSize[2] = {}; // Minimum size for resizable windows
int fgfps = 0; // Foreground FPS limit
+ int bgfps = 0; // Background FPS limit
sys_vidSave_s save; // Saved state
};
diff --git a/engine/system/win/sys_main.cpp b/engine/system/win/sys_main.cpp
index 42504ec..84ab748 100644
--- a/engine/system/win/sys_main.cpp
+++ b/engine/system/win/sys_main.cpp
@@ -11,9 +11,6 @@
#include
-#include
-#include
-
// ======
// Locals
// ======
@@ -780,15 +777,7 @@ bool sys_main_c::Run(int argc, char** argv)
while (exitFlag == false) {
RunMessages();
- const auto frameStart = std::chrono::high_resolution_clock::now();
core->Frame();
- const auto frameEnd = std::chrono::high_resolution_clock::now();
- using FpMilliseconds = std::chrono::duration;
- const auto frameDuration = std::chrono::duration_cast(frameEnd - frameStart);
- const auto minimumFrameDuration = FpMilliseconds(1000.0f / video->vid.fgfps);
- if (frameDuration < minimumFrameDuration) {
- std::this_thread::sleep_for(minimumFrameDuration - frameDuration);
- }
if (threadError) {
Error(threadError);
diff --git a/engine/system/win/sys_video.cpp b/engine/system/win/sys_video.cpp
index 891c8a7..6eedae3 100644
--- a/engine/system/win/sys_video.cpp
+++ b/engine/system/win/sys_video.cpp
@@ -276,6 +276,7 @@ int sys_video_c::Apply(sys_vidSet_s* set)
vid.size[1] = wrec.bottom;
vid.fgfps = cur.fgfps;
+ vid.bgfps = cur.bgfps;
// Process any messages generated during application
sys->RunMessages();
diff --git a/ui_main.cpp b/ui_main.cpp
index f9622e0..17be353 100644
--- a/ui_main.cpp
+++ b/ui_main.cpp
@@ -6,6 +6,9 @@
#include "ui_local.h"
+#include
+#include
+
// ======
// Locals
// ======
@@ -373,6 +376,8 @@ void ui_main_c::ScriptInit()
void ui_main_c::Frame()
{
+ const auto frameStart = std::chrono::high_resolution_clock::now();
+ auto fpsLimit = sys->video->vid.fgfps;
if (!sys->video->IsVisible() || sys->conWin->IsVisible() || restartFlag || didExit) {
framesSinceWindowHidden = 0;
}
@@ -380,8 +385,7 @@ void ui_main_c::Frame()
framesSinceWindowHidden++;
}
else if (!sys->video->IsActive() && !sys->video->IsCursorOverWindow()) {
- sys->Sleep(100);
- return;
+ fpsLimit = sys->video->vid.bgfps;
}
if (renderer) {
@@ -425,8 +429,8 @@ void ui_main_c::Frame()
}
//sys->con->Printf("Finishing up...\n");
- if ( !sys->video->IsActive() ) {
- sys->Sleep(100);
+ if ( sys->video->IsActive() ) {
+ fpsLimit = sys->video->vid.fgfps;
}
while (restartFlag) {
@@ -436,6 +440,14 @@ void ui_main_c::Frame()
}
ScriptInit();
}
+
+ using FpMilliseconds = std::chrono::duration;
+ const auto minimumFrameDuration = FpMilliseconds(1000.0f / fpsLimit);
+ const auto frameEnd = std::chrono::high_resolution_clock::now();
+ const auto frameDuration = std::chrono::duration_cast(frameEnd - frameStart);
+ if (frameDuration < minimumFrameDuration) {
+ std::this_thread::sleep_for(minimumFrameDuration - frameDuration);
+ }
}
void ui_main_c::ScriptShutdown()
From 9f28e3ee80c9dd8dbf5a0b30007af7650cdd0e96 Mon Sep 17 00:00:00 2001
From: Matt Weber <30441572+mweber15@users.noreply.github.com>
Date: Tue, 16 Mar 2021 05:30:26 -0400
Subject: [PATCH 4/4] Formatting
---
engine/core/core_video.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/engine/core/core_video.cpp b/engine/core/core_video.cpp
index fbe0b25..2e1b630 100644
--- a/engine/core/core_video.cpp
+++ b/engine/core/core_video.cpp
@@ -74,7 +74,7 @@ core_video_c::core_video_c(sys_IMain* sysHnd)
vid_resizable = sys->con->Cvar_Add("vid_resizable", CV_ARCHIVE|CV_CLAMP, CFG_VID_DEFRESIZABLE, 0, 3);
vid_last = sys->con->Cvar_Add("vid_last", CV_ARCHIVE, "");
vid_fgfps = sys->con->Cvar_Add("vid_fgfps", CV_ARCHIVE|CV_CLAMP, CFG_VID_DEFFGFPS, 5, 120);
- vid_bgfps = sys->con->Cvar_Add("vid_bgfps", CV_ARCHIVE | CV_CLAMP, CFG_VID_DEFBGFPS, 5, 120);
+ vid_bgfps = sys->con->Cvar_Add("vid_bgfps", CV_ARCHIVE|CV_CLAMP, CFG_VID_DEFBGFPS, 5, 120);
Cmd_Add("vid_apply", 0, "", this, &core_video_c::C_Vid_Apply);
Cmd_Add("vid_modeList", 0, "", this, &core_video_c::C_Vid_ModeList);