impr: Don't wake up frame rate limiter thread more often than necessary
This commit is contained in:
parent
4c0e8bc1d6
commit
7879f8b6a4
@ -53,6 +53,9 @@ namespace hex {
|
||||
void drawImGui();
|
||||
void drawWithShader();
|
||||
|
||||
void unlockFrameRate();
|
||||
void forceNewFrame();
|
||||
|
||||
GLFWwindow *m_window = nullptr;
|
||||
|
||||
std::string m_windowTitle, m_windowTitleFull;
|
||||
@ -64,17 +67,22 @@ namespace hex {
|
||||
std::list<std::string> m_popupsToOpen;
|
||||
std::set<int> m_pressedKeys;
|
||||
|
||||
std::atomic<bool> m_unlockFrameRate = true;
|
||||
|
||||
ImGuiExt::ImHexCustomData m_imguiCustomData;
|
||||
|
||||
u32 m_searchBarPosition = 0;
|
||||
bool m_emergencyPopupOpen = false;
|
||||
|
||||
std::jthread m_frameRateThread;
|
||||
std::chrono::duration<double, std::nano> m_remainingUnlockedTime;
|
||||
|
||||
std::mutex m_sleepMutex;
|
||||
std::atomic<bool> m_sleepFlag;
|
||||
std::condition_variable m_sleepCondVar;
|
||||
std::mutex m_sleepMutex;
|
||||
|
||||
std::mutex m_wakeupMutex;
|
||||
std::atomic<bool> m_wakeupFlag;
|
||||
std::condition_variable m_wakeupCondVar;
|
||||
|
||||
|
||||
gl::Shader m_postProcessingShader;
|
||||
};
|
||||
|
@ -618,7 +618,7 @@ namespace hex {
|
||||
|
||||
glfwSetFramebufferSizeCallback(m_window, [](GLFWwindow* window, int width, int height) {
|
||||
auto *win = static_cast<Window *>(glfwGetWindowUserPointer(window));
|
||||
win->m_unlockFrameRate = true;
|
||||
win->unlockFrameRate();
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
ImHexApi::System::impl::setMainWindowSize(width, height);
|
||||
|
@ -311,7 +311,7 @@ namespace hex {
|
||||
|
||||
// Unlock frame rate if any mouse button is being held down to allow drag scrolling to be smooth
|
||||
if (ImGui::IsAnyMouseDown())
|
||||
m_unlockFrameRate = true;
|
||||
this->unlockFrameRate();
|
||||
|
||||
// Unlock frame rate if any modifier key is held down since they don't generate key repeat events
|
||||
if (
|
||||
@ -320,12 +320,12 @@ namespace hex {
|
||||
ImGui::IsKeyPressed(ImGuiKey_LeftSuper) || ImGui::IsKeyPressed(ImGuiKey_RightSuper) ||
|
||||
ImGui::IsKeyPressed(ImGuiKey_LeftAlt) || ImGui::IsKeyPressed(ImGuiKey_RightAlt)
|
||||
) {
|
||||
m_unlockFrameRate = true;
|
||||
this->unlockFrameRate();
|
||||
}
|
||||
|
||||
// Unlock frame rate if there's more than one viewport since these don't call the glfw callbacks registered here
|
||||
if (ImGui::GetPlatformIO().Viewports.size() > 1)
|
||||
m_unlockFrameRate = true;
|
||||
this->unlockFrameRate();
|
||||
}
|
||||
|
||||
// Hide the window as soon as the render loop exits to make the window
|
||||
@ -929,6 +929,23 @@ namespace hex {
|
||||
#endif
|
||||
}
|
||||
|
||||
void Window::unlockFrameRate() {
|
||||
{
|
||||
std::scoped_lock lock(m_wakeupMutex);
|
||||
m_remainingUnlockedTime = std::chrono::seconds(2);
|
||||
}
|
||||
|
||||
this->forceNewFrame();
|
||||
}
|
||||
|
||||
void Window::forceNewFrame() {
|
||||
std::scoped_lock lock(m_wakeupMutex);
|
||||
m_wakeupFlag = true;
|
||||
m_wakeupCondVar.notify_all();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Window::initGLFW() {
|
||||
auto initialWindowProperties = ImHexApi::System::getInitialWindowProperties();
|
||||
glfwSetErrorCallback([](int error, const char *desc) {
|
||||
@ -1029,7 +1046,7 @@ namespace hex {
|
||||
if (win == nullptr)
|
||||
return;
|
||||
|
||||
win->m_unlockFrameRate = true;
|
||||
win->unlockFrameRate();
|
||||
};
|
||||
|
||||
static const auto isMainWindow = [](GLFWwindow *window) {
|
||||
@ -1165,7 +1182,7 @@ namespace hex {
|
||||
Duration passedTime = {};
|
||||
|
||||
std::chrono::steady_clock::time_point startTime = {}, endTime = {};
|
||||
Duration requestedFrameTime = {}, remainingUnlockedTime = {};
|
||||
Duration requestedFrameTime = {};
|
||||
float targetFps = 0;
|
||||
|
||||
const auto nativeFps = []() -> float {
|
||||
@ -1184,32 +1201,36 @@ namespace hex {
|
||||
|
||||
targetFps = ImHexApi::System::getTargetFPS();
|
||||
|
||||
if (m_unlockFrameRate.exchange(false)) {
|
||||
remainingUnlockedTime = std::chrono::seconds(2);
|
||||
}
|
||||
|
||||
// If the target frame rate is below 15, use the current monitor's refresh rate
|
||||
if (targetFps < 15) {
|
||||
targetFps = nativeFps;
|
||||
}
|
||||
|
||||
passedTime += iterationTime;
|
||||
if (remainingUnlockedTime > std::chrono::nanoseconds(0)) {
|
||||
remainingUnlockedTime -= iterationTime;
|
||||
} else {
|
||||
targetFps = 5;
|
||||
}
|
||||
|
||||
requestedFrameTime = (Duration(1.0E9) / targetFps) / 1.3;
|
||||
if (passedTime >= requestedFrameTime) {
|
||||
{
|
||||
std::scoped_lock lock(m_sleepMutex);
|
||||
m_sleepFlag = true;
|
||||
m_sleepCondVar.notify_all();
|
||||
|
||||
passedTime = {};
|
||||
if (m_remainingUnlockedTime > std::chrono::nanoseconds(0)) {
|
||||
m_remainingUnlockedTime -= iterationTime;
|
||||
} else {
|
||||
targetFps = 0.01;
|
||||
}
|
||||
|
||||
requestedFrameTime = (Duration(1.0E9) / targetFps) / 1.3;
|
||||
if (passedTime >= requestedFrameTime) {
|
||||
m_sleepFlag = true;
|
||||
m_sleepCondVar.notify_all();
|
||||
|
||||
passedTime = {};
|
||||
}
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
{
|
||||
std::unique_lock lock(m_wakeupMutex);
|
||||
m_wakeupCondVar.wait_for(lock, requestedFrameTime, [&] {
|
||||
return m_wakeupFlag || stopToken.stop_requested();
|
||||
});
|
||||
}
|
||||
|
||||
endTime = std::chrono::steady_clock::now();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user