gpu: add sync mode config

This allows the additional OFF mode which has the client manage its own
frame rate target without the use of vsync. On lower end systems which
have a hard time delivering a frame in the vsync interval this can give
a noticible performance improvement since it doesn't stall the cpu
waiting for the next vblank when a frame is skipped
This commit is contained in:
Adam
2021-11-14 13:41:07 -05:00
parent 759565e331
commit 13ecfc0a9e
3 changed files with 67 additions and 10 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -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;
}
}