Add draw limit variant that mirrors the display's refresh rate

This commit is contained in:
Tamás Bálint Misius
2024-12-21 10:14:05 +01:00
parent 3b70324b78
commit 86fd919699
5 changed files with 73 additions and 11 deletions

View File

@@ -12,3 +12,15 @@ struct FpsLimitExplicit
float value;
};
using FpsLimit = std::variant<FpsLimitVsync, FpsLimitNone, FpsLimitExplicit>;
struct DrawLimitDisplay
{
};
struct DrawLimitNone
{
};
struct DrawLimitExplicit
{
int value;
};
using DrawLimit = std::variant<DrawLimitDisplay, DrawLimitNone, DrawLimitExplicit>;

View File

@@ -156,6 +156,7 @@ void SDLOpen()
SDLSetScreen();
int displayIndex = SDL_GetWindowDisplayIndex(sdl_window);
std::optional<int> refreshRate;
if (displayIndex >= 0)
{
SDL_Rect rect;
@@ -164,7 +165,13 @@ void SDLOpen()
desktopWidth = rect.w;
desktopHeight = rect.h;
}
SDL_DisplayMode displayMode;
if (!SDL_GetCurrentDisplayMode(displayIndex, &displayMode) && displayMode.refresh_rate)
{
refreshRate = displayMode.refresh_rate;
}
}
ui::Engine::Ref().SetRefreshRate(refreshRate);
StopTextInput();
}
@@ -460,15 +467,24 @@ void EngineProcess()
engine.Tick();
{
int drawcap = ui::Engine::Ref().GetDrawingFrequencyLimit();
auto drawLimit = ui::Engine::Ref().GetDrawingFrequencyLimit();
auto nowNs = uint64_t(SDL_GetTicks()) * UINT64_C(1'000'000);
if (!drawcap || drawSchedule.HasElapsed(nowNs))
std::optional<int> effectiveDrawLimit;
if (auto *drawLimitExplicit = std::get_if<DrawLimitExplicit>(&drawLimit))
{
effectiveDrawLimit = drawLimitExplicit->value;
}
if (std::get_if<DrawLimitDisplay>(&drawLimit))
{
effectiveDrawLimit = engine.GetRefreshRate();
}
if (!effectiveDrawLimit || drawSchedule.HasElapsed(nowNs))
{
engine.Draw();
drawSchedule.SetNow(nowNs);
if (drawcap)
if (effectiveDrawLimit)
{
drawSchedule.Arm(float(drawcap));
drawSchedule.Arm(float(*effectiveDrawLimit));
}
SDLSetScreen();
blit(engine.g->Data());

View File

@@ -11,7 +11,7 @@
using namespace ui;
Engine::Engine():
drawingFrequencyLimit(0),
drawingFrequencyLimit(DrawLimitDisplay{}),
FrameIndex(0),
state_(nullptr),
windowTargetPosition(0, 0),

View File

@@ -1,5 +1,6 @@
#pragma once
#include <memory>
#include <optional>
#include <stack>
#include "common/String.h"
#include "common/ExplicitSingleton.h"
@@ -47,8 +48,8 @@ namespace ui
void Exit();
void ConfirmExit();
void SetDrawingFrequencyLimit(int limit) {drawingFrequencyLimit = limit;}
inline int GetDrawingFrequencyLimit() {return drawingFrequencyLimit;}
void SetDrawingFrequencyLimit(DrawLimit limit) {drawingFrequencyLimit = limit;}
inline DrawLimit GetDrawingFrequencyLimit() {return drawingFrequencyLimit;}
void SetFastQuit(bool fastquit) { FastQuit = fastquit; }
inline bool GetFastQuit() {return FastQuit; }
void SetGlobalQuit(bool newGlobalQuit) { GlobalQuit = newGlobalQuit; }
@@ -78,7 +79,7 @@ namespace ui
return fpsLimit;
}
int drawingFrequencyLimit;
DrawLimit drawingFrequencyLimit;
Graphics * g;
bool GraveExitsConsole;
@@ -99,6 +100,7 @@ namespace ui
Window* state_;
Point windowTargetPosition;
bool ignoreEvents = false;
std::optional<int> refreshRate;
// saved appearances of windows that are in the backround and
// thus are not currently being redrawn
@@ -141,5 +143,15 @@ namespace ui
bool GetForceIntegerScaling() const { return windowFrameOps.forceIntegerScaling; }
bool GetResizable () const { return windowFrameOps.resizable; }
bool GetBlurryScaling () const { return windowFrameOps.blurryScaling; }
std::optional<int> GetRefreshRate() const
{
return refreshRate;
}
void SetRefreshRate(std::optional<int> newRefreshRate)
{
refreshRate = newRefreshRate;
}
};
}

View File

@@ -239,13 +239,35 @@ static int drawCap(lua_State *L)
int acount = lua_gettop(L);
if (acount == 0)
{
lua_pushinteger(L, ui::Engine::Ref().GetDrawingFrequencyLimit());
auto drawLimit = ui::Engine::Ref().GetDrawingFrequencyLimit();
if (std::holds_alternative<DrawLimitDisplay>(drawLimit))
{
lua_pushliteral(L, "display");
}
else if (std::holds_alternative<DrawLimitNone>(drawLimit))
{
lua_pushinteger(L, 0);
}
else
{
lua_pushinteger(L, std::get<DrawLimitExplicit>(drawLimit).value);
}
return 1;
}
int drawcap = luaL_checkint(L, 1);
if (lua_isstring(L, 1) && byteStringEqualsLiteral(tpt_lua_toByteString(L, 1), "display"))
{
ui::Engine::Ref().SetDrawingFrequencyLimit(DrawLimitDisplay{});
return 0;
}
int drawcap = luaL_checkinteger(L, 1);
if(drawcap < 0)
return luaL_error(L, "draw cap too small");
ui::Engine::Ref().SetDrawingFrequencyLimit(drawcap);
if (drawcap == 0)
{
ui::Engine::Ref().SetDrawingFrequencyLimit(DrawLimitNone{});
return 0;
}
ui::Engine::Ref().SetDrawingFrequencyLimit(DrawLimitExplicit{ drawcap });
return 0;
}