diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index 4f38b13c0c..5f1175fcdd 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -1953,6 +1953,7 @@ public interface Client extends GameEngine ClanSettings getClanSettings(int clanId); void setUnlockedFps(boolean unlock); + void setUnlockedFpsTarget(int fps); /** * Gets the ambient sound effects diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java index b9900a988e..b275fd7d4e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java @@ -394,9 +394,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks this.gl = glContext.getGL().getGL4(); - final boolean unlockFps = this.config.unlockFps(); - client.setUnlockedFps(unlockFps); - gl.setSwapInterval(unlockFps ? -1 : 0); + setupSyncMode(); if (log.isDebugEnabled()) { @@ -556,18 +554,43 @@ public class GpuPlugin extends Plugin implements DrawCallbacks { if (configChanged.getGroup().equals(GpuPluginConfig.GROUP)) { - if (configChanged.getKey().equals("unlockFps")) + if (configChanged.getKey().equals("unlockFps") + || configChanged.getKey().equals("vsyncMode") + || configChanged.getKey().equals("fpsTarget")) { - boolean unlockFps = Boolean.parseBoolean(configChanged.getNewValue()); - clientThread.invokeLater(() -> - { - client.setUnlockedFps(unlockFps); - invokeOnMainThread(() -> gl.setSwapInterval(unlockFps ? -1 : 0)); - }); + log.debug("Rebuilding sync mode"); + clientThread.invokeLater(() -> invokeOnMainThread(this::setupSyncMode)); } } } + private void setupSyncMode() + { + final boolean unlockFps = config.unlockFps(); + client.setUnlockedFps(unlockFps); + + // Without unlocked fps, the client manages sync on its 20ms timer + GpuPluginConfig.SyncMode syncMode = unlockFps + ? this.config.syncMode() + : GpuPluginConfig.SyncMode.OFF; + + switch (syncMode) + { + case ON: + gl.setSwapInterval(1); + client.setUnlockedFpsTarget(0); + break; + case OFF: + gl.setSwapInterval(0); + client.setUnlockedFpsTarget(config.fpsTarget()); // has no effect with unlockFps=false + break; + case ADAPTIVE: + gl.setSwapInterval(-1); + client.setUnlockedFpsTarget(0); + break; + } + } + private void initProgram() throws ShaderException { String versionHeader = OSType.getOSType() == OSType.Linux ? LINUX_VERSION_HEADER : WINDOWS_VERSION_HEADER; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPluginConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPluginConfig.java index ff69cd80e8..3d5f1095ea 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPluginConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPluginConfig.java @@ -159,4 +159,37 @@ public interface GpuPluginConfig extends Config { return false; } + + enum SyncMode + { + OFF, + ON, + ADAPTIVE + } + + @ConfigItem( + keyName = "vsyncMode", + name = "Vsync Mode", + description = "Method to synchronize frame rate with refresh rate", + position = 11 + ) + default SyncMode syncMode() + { + return SyncMode.ADAPTIVE; + } + + @ConfigItem( + keyName = "fpsTarget", + name = "FPS Target", + description = "Target FPS when unlock FPS is enabled and Vsync mode is OFF", + position = 12 + ) + @Range( + min = 1, + max = 999 + ) + default int fpsTarget() + { + return 60; + } }