fix: Revert the FPS limiter back to the one used in v1.30.1 (#1247)

As requested on Discord, a PR to revert the FPS limiter back to the one
that was used in v1.30.1.

The new FPS limiter seems to be flawed in that it runs at about half the
speed it is supposed to be.

See this illustration:

![FPS](https://github.com/WerWolv/ImHex/assets/869973/8a101b4c-23d8-4806-8d53-3be7aeb84fed)

Left is v1.30.1, right is the new version (without this fix). See how
long it takes to respectively reach 0xE90.

This is not a performance issue, because when you fully unlock the
framerate on the right, it's just as fluent as on the left.
This commit is contained in:
Lennard Fonteijn
2023-08-11 22:03:30 +02:00
committed by GitHub
parent 65c56a887c
commit df24d1e1e9

View File

@@ -169,42 +169,29 @@ namespace hex {
// If no events have been received in a while, lower the frame rate
{
// If the mouse is down, the mouse is moving or a popup is open, we don't want to lower the frame rate
if (ImGui::IsPopupOpen(ImGuiID(0), ImGuiPopupFlags_AnyPopupId) ||
TaskManager::getRunningTaskCount() > 0 ||
this->m_buttonDown ||
this->m_hadEvent ||
!this->m_pressedKeys.empty())
{
this->m_frameRateTemporarilyUnlocked = true;
}
bool frameRateUnlocked =
ImGui::IsPopupOpen(ImGuiID(0), ImGuiPopupFlags_AnyPopupId) ||
TaskManager::getRunningTaskCount() > 0 ||
this->m_buttonDown ||
this->m_hadEvent ||
!this->m_pressedKeys.empty();
// Calculate the time until the next frame
const double timeout = std::max(0.0, (1.0 / 5.0) - (glfwGetTime() - this->m_lastFrameTime));
// If the frame rate has been unlocked for 5 seconds, lock it again
if ((this->m_lastFrameTime - this->m_frameRateUnlockTime) > 5 && this->m_frameRateTemporarilyUnlocked) {
if ((this->m_lastFrameTime - this->m_frameRateUnlockTime) > 5 && this->m_frameRateTemporarilyUnlocked && !frameRateUnlocked) {
this->m_frameRateTemporarilyUnlocked = false;
this->m_frameRateUnlockTime = this->m_lastFrameTime;
}
// If the frame rate is locked, wait for events with a timeout
const auto targetFps = ImHexApi::System::getTargetFPS();
if (targetFps >= 200) {
// Frame rate is unlocked
} else if (targetFps < 15) {
// Limit frame rate to monitor refresh rate
glfwSwapInterval(1);
} else if (this->m_frameRateTemporarilyUnlocked) {
// Handle regular frame rate when it was temporarily unlocked
// Limit the frame rate to the target frame rate
const double timeout = std::max(0.0, (1.0 / targetFps) - (glfwGetTime() - this->m_lastFrameTime));
std::this_thread::sleep_for(std::chrono::milliseconds(u32(timeout * 1000)));
glfwSwapInterval(0);
if (frameRateUnlocked || this->m_frameRateTemporarilyUnlocked) {
if (!this->m_frameRateTemporarilyUnlocked) {
this->m_frameRateTemporarilyUnlocked = true;
this->m_frameRateUnlockTime = this->m_lastFrameTime;
}
} else {
// Handle frame rate when there's no interaction with the window
// Limit the frame rate to ~5 FPS
const double timeout = std::max(0.0, (1.0 / 5.0) - (glfwGetTime() - this->m_lastFrameTime));
std::this_thread::sleep_for(std::chrono::milliseconds(u32(timeout * 1000)));
glfwSwapInterval(0);
glfwWaitEventsTimeout(timeout);
}
this->m_hadEvent = false;
@@ -215,6 +202,24 @@ namespace hex {
this->frameBegin();
this->frame();
this->frameEnd();
glfwSwapInterval(0);
// Limit frame rate
// If the target FPS are below 15, use the monitor refresh rate, if it's above 200, don't limit the frame rate
const auto targetFPS = ImHexApi::System::getTargetFPS();
if (targetFPS < 15) {
glfwSwapInterval(1);
} else if (targetFPS > 200) {
glfwSwapInterval(0);
} else {
glfwSwapInterval(0);
const auto frameTime = glfwGetTime() - this->m_lastFrameTime;
const auto targetFrameTime = 1.0 / targetFPS;
if (frameTime < targetFrameTime) {
glfwWaitEventsTimeout(targetFrameTime - frameTime);
}
}
}
}