Make emscripten work with draw limits

This commit is contained in:
Tamás Bálint Misius
2025-01-23 23:59:55 +01:00
parent e87f404d90
commit ea93bae302
6 changed files with 50 additions and 37 deletions

View File

@@ -82,7 +82,11 @@ int main(int argc, char * argv[])
while (engine.Running()) while (engine.Running())
{ {
EngineProcess(); auto delay = EngineProcess();
if (delay.has_value())
{
SDL_Delay(std::max(*delay, UINT64_C(1)));
}
} }
Platform::Exit(0); Platform::Exit(0);
return 0; return 0;

View File

@@ -319,7 +319,7 @@ void SDLSetScreen()
SDL_SetWindowSize(sdl_window, size.X, size.Y); SDL_SetWindowSize(sdl_window, size.X, size.Y);
LoadWindowPosition(); LoadWindowPosition();
} }
UpdateFpsLimit(); ApplyFpsLimit();
if (newFrameOpsNorm.fullscreen) if (newFrameOpsNorm.fullscreen)
{ {
SDL_RaiseWindow(sdl_window); SDL_RaiseWindow(sdl_window);
@@ -450,7 +450,7 @@ static void EventProcess(const SDL_Event &event)
} }
} }
void EngineProcess() std::optional<uint64_t> EngineProcess()
{ {
auto &engine = ui::Engine::Ref(); auto &engine = ui::Engine::Ref();
auto correctedFrameTime = tickSchedule.GetFrameTime(); auto correctedFrameTime = tickSchedule.GetFrameTime();
@@ -509,8 +509,5 @@ void EngineProcess()
delay = tickSchedule.Arm(fpsLimitExplicit->value) / UINT64_C(1'000'000); delay = tickSchedule.Arm(fpsLimitExplicit->value) / UINT64_C(1'000'000);
} }
} }
if (delay.has_value()) return delay;
{
SDL_Delay(std::max(*delay, UINT64_C(1)));
}
} }

View File

@@ -6,6 +6,7 @@
#include <cstdint> #include <cstdint>
#include <SDL.h> #include <SDL.h>
#include <variant> #include <variant>
#include <optional>
extern int desktopWidth; extern int desktopWidth;
extern int desktopHeight; extern int desktopHeight;
@@ -25,7 +26,7 @@ extern bool calculatedInitialMouse;
extern bool hasMouseMoved; extern bool hasMouseMoved;
void MainLoop(); void MainLoop();
void EngineProcess(); std::optional<uint64_t> EngineProcess();
void StartTextInput(); void StartTextInput();
void StopTextInput(); void StopTextInput();
void SetTextInputRect(int x, int y, int w, int h); void SetTextInputRect(int x, int y, int w, int h);
@@ -37,9 +38,8 @@ void blit(pixel *vid);
void SDLOpen(); void SDLOpen();
void SDLClose(); void SDLClose();
void SDLSetScreen(); void SDLSetScreen();
void SetFpsLimit(FpsLimit newFpsLimit);
void LoadWindowPosition(); void LoadWindowPosition();
void SaveWindowPosition(); void SaveWindowPosition();
void LargeScreenDialog(); void LargeScreenDialog();
void TickClient(); void TickClient();
void UpdateFpsLimit(); void ApplyFpsLimit();

View File

@@ -5,14 +5,14 @@ void MainLoop()
{ {
while (ui::Engine::Ref().Running()) while (ui::Engine::Ref().Running())
{ {
EngineProcess(); auto delay = EngineProcess();
if (delay.has_value())
{
SDL_Delay(std::max(*delay, UINT64_C(1)));
}
} }
} }
void SetFpsLimit(FpsLimit newFpsLimit) void ApplyFpsLimit()
{
}
void UpdateFpsLimit()
{ {
} }

View File

@@ -14,7 +14,7 @@ static void MainLoopBody()
Platform::MaybeTriggerSyncFs(); Platform::MaybeTriggerSyncFs();
} }
void SetFpsLimit(FpsLimit newFpsLimit) void ApplyFpsLimit()
{ {
static bool mainLoopSet = false; static bool mainLoopSet = false;
if (!mainLoopSet) if (!mainLoopSet)
@@ -22,31 +22,43 @@ void SetFpsLimit(FpsLimit newFpsLimit)
emscripten_set_main_loop(MainLoopBody, 0, 0); emscripten_set_main_loop(MainLoopBody, 0, 0);
mainLoopSet = true; mainLoopSet = true;
} }
// if (std::get_if<FpsLimitVsync>(&newFpsLimit)) // TODO: DrawLimitVsync // this generally attempts to replicate the behaviour of EngineProcess
std::optional<float> drawLimit;
auto &engine = ui::Engine::Ref();
auto fpsLimit = engine.GetFpsLimit();
if (auto *fpsLimitExplicit = std::get_if<FpsLimitExplicit>(&fpsLimit))
{
drawLimit = fpsLimitExplicit->value;
}
else if (std::holds_alternative<FpsLimitFollowDraw>(fpsLimit))
{
auto effectiveDrawLimit = engine.GetEffectiveDrawCap();
if (effectiveDrawLimit)
{
drawLimit = float(*effectiveDrawLimit);
}
// else // TODO: DrawLimitVsync
// {
// if (std::holds_alternative<DrawLimitVsync>(engine.GetDrawingFrequencyLimit()))
// { // {
// emscripten_set_main_loop_timing(EM_TIMING_RAF, 1); // emscripten_set_main_loop_timing(EM_TIMING_RAF, 1);
// std::cerr << "implicit fps limit via vsync" << std::endl; // std::cerr << "implicit fps limit via vsync" << std::endl;
// return;
// } // }
// else // }
// { }
auto delay = 0; int delay = 0; // no cap
if (auto *fpsLimitExplicit = std::get_if<FpsLimitExplicit>(&newFpsLimit)) if (drawLimit.has_value())
{ {
delay = int(1000.f / fpsLimitExplicit->value); delay = int(1000.f / *drawLimit);
} }
emscripten_set_main_loop_timing(EM_TIMING_SETTIMEOUT, delay); emscripten_set_main_loop_timing(EM_TIMING_SETTIMEOUT, delay);
std::cerr << "explicit fps limit: " << delay << "ms delays" << std::endl; std::cerr << "explicit fps limit: " << delay << "ms delays" << std::endl;
// }
}
void UpdateFpsLimit()
{
SetFpsLimit(ui::Engine::Ref().GetFpsLimit());
} }
// Is actually only called once at startup, the real main loop body is MainLoopBody. // Is actually only called once at startup, the real main loop body is MainLoopBody.
void MainLoop() void MainLoop()
{ {
UpdateFpsLimit(); ApplyFpsLimit();
MainLoopBody(); MainLoopBody();
} }

View File

@@ -39,7 +39,7 @@ Engine::~Engine()
void Engine::ApplyFpsLimit() void Engine::ApplyFpsLimit()
{ {
::SetFpsLimit(GetFpsLimit()); ::ApplyFpsLimit();
} }
void Engine::Begin() void Engine::Begin()