From 87b765e618f04701faf8792dd28d872184276b31 Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Fri, 21 Apr 2023 15:23:10 +0100 Subject: [PATCH] properly adhere to fps limits --- .../Application/CWallpaperApplication.cpp | 28 +++++++++---------- .../Render/Drivers/CWaylandOpenGLDriver.cpp | 9 ++++++ .../Render/Drivers/CWaylandOpenGLDriver.h | 1 + 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/WallpaperEngine/Application/CWallpaperApplication.cpp b/src/WallpaperEngine/Application/CWallpaperApplication.cpp index 38119b7..a5a7e78 100644 --- a/src/WallpaperEngine/Application/CWallpaperApplication.cpp +++ b/src/WallpaperEngine/Application/CWallpaperApplication.cpp @@ -334,7 +334,16 @@ namespace WallpaperEngine::Application } else { #endif while (!videoDriver->closeRequested () && this->m_context.state.general.keepRunning) { + static float startTime, endTime, minimumTime = 1.0f / this->m_context.settings.render.maximumFPS; + // get the start time of the frame + startTime = videoDriver->getRenderTime (); renderFrame(); + // get the end time of the frame + endTime = videoDriver->getRenderTime (); + + // ensure the frame time is correct to not overrun FPS + if ((endTime - startTime) < minimumTime) + usleep ((minimumTime - (endTime - startTime)) * CLOCKS_PER_SEC); } #ifdef ENABLE_WAYLAND } @@ -349,8 +358,6 @@ namespace WallpaperEngine::Application } void CWallpaperApplication::renderFrame() { - - static float startTime, endTime, minimumTime = 1.0f / this->m_context.settings.render.maximumFPS; static time_t seconds; static struct tm* timeinfo; @@ -359,24 +366,17 @@ namespace WallpaperEngine::Application timeinfo = localtime(&seconds); g_Daytime = ((timeinfo->tm_hour * 60) + timeinfo->tm_min) / (24.0 * 60.0); - // update audio recorder - audioDriver->update (); - // update input information - inputContext->update (); // keep track of the previous frame's time g_TimeLast = g_Time; // calculate the current time value g_Time = videoDriver->getRenderTime (); - // get the start time of the frame - startTime = g_Time; + + // update audio recorder + audioDriver->update (); + // update input information + inputContext->update (); // render the scene context->render (); - // get the end time of the frame - endTime = videoDriver->getRenderTime (); - - // ensure the frame time is correct to not overrun FPS - if ((endTime - startTime) < minimumTime) - usleep ((minimumTime - (endTime - startTime)) * CLOCKS_PER_SEC); if (!this->m_context.settings.screenshot.take || videoDriver->getFrameCounter () != 5) return; diff --git a/src/WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.cpp b/src/WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.cpp index 13369d9..2cfe536 100644 --- a/src/WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.cpp +++ b/src/WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.cpp @@ -269,6 +269,13 @@ static void surfaceFrameCallback(void *data, struct wl_callback *cb, uint32_t ti PLS->output->rendering = true; PLS->output->driver->wallpaperApplication->renderFrame(); PLS->output->rendering = false; + + float renderTime = PLS->output->driver->getRenderTime(); + + if ((renderTime - PLS->lastTime) < PLS->minimumTime) + usleep ((PLS->minimumTime - (renderTime - PLS->lastTime)) * CLOCKS_PER_SEC); + + PLS->lastTime = renderTime; } const struct wl_callback_listener frameListener = { @@ -316,6 +323,8 @@ CLayerSurface::CLayerSurface(CWaylandOpenGLDriver* pDriver, SWaylandOutput* pOut if (eglMakeCurrent(pDriver->eglContext.display, eglSurface, eglSurface, pDriver->eglContext.context) == EGL_FALSE) sLog.exception("Failed to make egl current"); + + minimumTime = 1.0f / pDriver->wallpaperApplication->getContext().settings.render.maximumFPS; } CLayerSurface::~CLayerSurface() { diff --git a/src/WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.h b/src/WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.h index 8eb02b0..2ffb1ca 100644 --- a/src/WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.h +++ b/src/WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.h @@ -56,6 +56,7 @@ namespace WallpaperEngine::Render::Drivers wl_cursor* pointer = nullptr; wl_surface* cursorSurface = nullptr; bool callbackInitialized = false; + float lastTime, minimumTime; }; class CWaylandOpenGLDriver : public CVideoDriver