main loop improvements

This commit is contained in:
ohyzha
2024-08-25 16:21:31 +03:00
parent f002ea2eca
commit 32ffd21076
3 changed files with 44 additions and 6 deletions

View File

@@ -9,6 +9,7 @@
#include <cstdint>
#include <algorithm>
#include <array>
#include "Base/Event.hpp"
#undef max
namespace OpenVulkano
@@ -34,10 +35,19 @@ namespace OpenVulkano
void SetVSync(bool vSync) { m_vSync = vSync; }
[[nodiscard]] int32_t GetFpsCap() const { return m_fpsCap; }
void SetFpsCap(int32_t fpsCap) { m_fpsCap = fpsCap; }
void SetFpsCap(int32_t fpsCap)
{
if (m_fpsCap != fpsCap)
{
m_fpsCap = fpsCap;
OnFpsCapChanged(fpsCap);
}
}
[[nodiscard]] uint32_t GetPrefferedSwapChainImageCount() const { return m_preferredImageCount; }
void SetPrefferedSwapChainImageCount(uint32_t preferredImageCount) { m_preferredImageCount = preferredImageCount; }
public:
Event<int32_t> OnFpsCapChanged;
private:
EngineConfiguration();
@@ -48,7 +58,7 @@ namespace OpenVulkano
bool m_preferFramebufferFormatSRGB = true;
bool m_lazyRendering = false;
bool m_vSync = false;
int32_t m_fpsCap = 500; // -1 = no fps cap. 0 = fps cap if vsync, no cap otherwise. > 0 = set fps cap
int32_t m_fpsCap = -1; // -1 = no fps cap. 0 = fps cap if vsync, no cap otherwise. > 0 = set fps cap
#ifdef __APPLE__
uint32_t m_preferredImageCount = 3;
#else

View File

@@ -41,6 +41,12 @@ namespace OpenVulkano
window->SetWindowHandler(this);
inputManager = Input::InputManager::GetInstance();
engineConfig = EngineConfiguration::GetEngineConfiguration();
engineConfig->OnFpsCapChanged += EventHandler(this, &GraphicsAppManager::UpdateCappedFpsInfo);
// set initial values
if (engineConfig->GetFpsCap() > 0)
{
UpdateCappedFpsInfo(engineConfig->GetFpsCap());
}
}
GraphicsAppManager::GraphicsAppManager(IGraphicsApp* app, IWindow* window, RenderAPI::RenderApi renderApi)
@@ -63,19 +69,38 @@ namespace OpenVulkano
window->SetWindowHandler(this);
inputManager = OpenVulkano::Input::InputManager::GetInstance();
engineConfig = OpenVulkano::EngineConfiguration::GetEngineConfiguration();
engineConfig->OnFpsCapChanged += EventHandler(this, &GraphicsAppManager::UpdateCappedFpsInfo);
// set initial values
if (engineConfig->GetFpsCap() > 0)
{
UpdateCappedFpsInfo(engineConfig->GetFpsCap());
}
}
void GraphicsAppManager::UpdateCappedFpsInfo(int32_t newFpsCap)
{
if (newFpsCap < 0)
{
cappedFrameTime = std::chrono::milliseconds(0);
}
else
{
cappedFrameTime = std::chrono::milliseconds(1000 / newFpsCap);
}
}
void GraphicsAppManager::OnCappedFPS(const auto& frameStartTime)
{
int32_t fpsCap = engineConfig->GetFpsCap();
fpsCapRemainder += 1000 % fpsCap;
auto frameTime = std::chrono::milliseconds(1000 / fpsCap);
auto expectedFrameTime = cappedFrameTime;
if (fpsCapRemainder >= fpsCap)
{
frameTime += std::chrono::milliseconds(1);
expectedFrameTime += std::chrono::milliseconds(1);
fpsCapRemainder -= fpsCap;
}
while (clock::now() < frameStartTime + frameTime)
auto frameEndTime = frameStartTime + expectedFrameTime;
while (clock::now() < frameEndTime)
{
std::this_thread::yield();
}
@@ -84,6 +109,7 @@ namespace OpenVulkano
GraphicsAppManager::~GraphicsAppManager() noexcept
{
if (windowTitleFormat.empty()) return;
engineConfig->OnFpsCapChanged -= EventHandler(this, &GraphicsAppManager::UpdateCappedFpsInfo);
ShutDown();
}
@@ -165,7 +191,7 @@ namespace OpenVulkano
inputManager->Tick();
app->Tick();
if (CURRENT_FRAME.needsRedraw) renderer->Tick();
if (engineConfig->GetFpsCap() > 0 && !engineConfig->GetVSync())
if (cappedFrameTime.count())
{
OnCappedFPS(start);
}

View File

@@ -38,6 +38,7 @@ namespace OpenVulkano
bool paused = false, running = false;
float fpsTimer = 0, avgFps = 0, avgFrameTime = 0;
uint64_t frameCount = 0, lastFrameCount = 0, fpsCapRemainder = 0;
std::chrono::milliseconds cappedFrameTime = std::chrono::milliseconds(0);
Timer frameTimer;
std::string windowTitleFormat;
Input::InputManager* inputManager;
@@ -45,6 +46,7 @@ namespace OpenVulkano
private:
void OnCappedFPS(const auto& frameStartTime);
void UpdateCappedFpsInfo(int32_t newFpsCap);
public:
explicit GraphicsAppManager(IGraphicsApp* app, RenderAPI::RenderApi renderApi = RenderAPI::Vulkan);