Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 25 additions & 21 deletions app/src/main/runtime/display/XServerDisplayActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -624,17 +624,9 @@ private int getGlobalRefreshRateOverride() {
return Math.max(0, preferences.getInt("refresh_rate_override", 0));
}

private int getDxvkFrameRateOverride() {
int perGameRate = getPerGameRefreshRateOverride();
if (perGameRate > 0) {
return perGameRate;
}

int globalRate = getGlobalRefreshRateOverride();
if (globalRate > 0) {
return globalRate;
}
return 0;
// FPS-limit slider takes priority over the refresh-rate override.
private int getEffectiveFpsLimit() {
return runtimeFpsLimit > 0 ? runtimeFpsLimit : getRefreshRateOverride();
}

private int parsePositiveInt(String value) {
Expand Down Expand Up @@ -680,10 +672,11 @@ private void applyPreferredRefreshRate() {
Runnable applyRefresh = () -> {
if (isFinishing() || isDestroyed()) return;

float hz = RefreshRateUtils.applyPreferredRefreshRate(this, getRefreshRateOverride(), runtimeFpsLimit);
int effectiveFpsLimit = getEffectiveFpsLimit();
float hz = RefreshRateUtils.applyPreferredRefreshRate(this, getRefreshRateOverride(), effectiveFpsLimit);
if (xServer != null) {
xServer.getFramePaceClock().setDisplayRefreshHz(hz);
xServer.getFramePaceClock().setCapActive(runtimeFpsLimit > 0);
xServer.getFramePaceClock().setCapActive(effectiveFpsLimit > 0);
}
};

Expand Down Expand Up @@ -2334,11 +2327,23 @@ private void handleCapturedPointer(MotionEvent event) {
}

private int[] getCapturedPointerDelta(MotionEvent event) {
float dx = event.getAxisValue(MotionEvent.AXIS_RELATIVE_X);
float dy = event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y);
// Sum batched samples; skipping history drops movement at low refresh rates.
final int historySize = event.getHistorySize();
float dx = 0.0f;
float dy = 0.0f;
for (int i = 0; i < historySize; i++) {
dx += event.getHistoricalAxisValue(MotionEvent.AXIS_RELATIVE_X, i);
dy += event.getHistoricalAxisValue(MotionEvent.AXIS_RELATIVE_Y, i);
}
dx += event.getAxisValue(MotionEvent.AXIS_RELATIVE_X);
dy += event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y);
if (dx == 0.0f && dy == 0.0f) {
dx = event.getX();
dy = event.getY();
for (int i = 0; i < historySize; i++) {
dx += event.getHistoricalX(i);
dy += event.getHistoricalY(i);
}
dx += event.getX();
dy += event.getY();
}
dx *= globalCursorSpeed;
dy *= globalCursorSpeed;
Expand Down Expand Up @@ -4274,7 +4279,7 @@ public void onGyroscopeCardExpandedChanged(boolean expanded) {
public void onFPSLimitChanged(int limit) {
runtimeFpsLimit = Math.max(0, limit);
if (xServerView != null) {
xServerView.getRenderer().setFpsLimit(runtimeFpsLimit);
xServerView.getRenderer().setFpsLimit(getEffectiveFpsLimit());
}
applyPreferredRefreshRate();
if (shortcut != null) {
Expand Down Expand Up @@ -6963,11 +6968,11 @@ private void setupUI() {
String savedFpsLimit = shortcut.getExtra("fpsLimit", "0");
try {
runtimeFpsLimit = Integer.parseInt(savedFpsLimit);
renderer.setFpsLimit(runtimeFpsLimit);
} catch (NumberFormatException e) {
runtimeFpsLimit = 0;
}
}
renderer.setFpsLimit(getEffectiveFpsLimit());

applyScreenEffects();
xServer.setRenderer(renderer);
Expand Down Expand Up @@ -7560,8 +7565,7 @@ private void extractGraphicsDriverFiles() {
File rootDir = imageFs.getRootDir();

if (dxwrapper.contains("dxvk")) {
int refreshRateOverride = getDxvkFrameRateOverride();
DXVKConfigUtils.setEnvVars(this, dxwrapperConfig, envVars, refreshRateOverride);
DXVKConfigUtils.setEnvVars(this, dxwrapperConfig, envVars);
String version = dxwrapperConfig.get("version");
if (version.equals("1.11.1-sarek")) {
Log.d("GraphicsDriverExtraction", "Disabling Wrapper PATCH_OPCONSTCOMP SPIR-V pass");
Expand Down
22 changes: 17 additions & 5 deletions app/src/main/runtime/display/renderer/VulkanRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ public VulkanRenderer(XServerSurfaceView view, XServer xServer) {
this.xServer = xServer;
this.effectComposer = new EffectComposer(this);
this.rootCursorDrawable = createRootCursorDrawable();
this.coalescedRenderCallback = frameTimeNanos -> {
renderRequested.set(false);
xServerView.requestRender();
};
}

public void destroy() {
Expand Down Expand Up @@ -163,13 +167,21 @@ public void destroy() {
}
}

private volatile Choreographer mainChoreographer;
private final Choreographer.FrameCallback coalescedRenderCallback;

public void requestRenderCoalesced() {
if (renderRequested.compareAndSet(false, true)) {
mainHandler.post(() ->
Choreographer.getInstance().postFrameCallback(frameTimeNanos -> {
renderRequested.set(false);
xServerView.requestRender();
}));
// Post directly (thread-safe): a handler hop arms past the next doFrame and halves the visible cursor rate.
Choreographer choreographer = mainChoreographer;
if (choreographer != null) {
choreographer.postFrameCallback(coalescedRenderCallback);
} else {
mainHandler.post(() -> {
mainChoreographer = Choreographer.getInstance();
mainChoreographer.postFrameCallback(coalescedRenderCallback);
});
}
}
}

Expand Down
3 changes: 2 additions & 1 deletion app/src/main/shared/android/RefreshRateUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,8 @@ public static float applyPreferredRefreshRate(Activity activity, int requestedHz
int modeId = resolvePreferredDisplayModeId(activity, effectiveRequestedHz);
float refreshRate = resolvePreferredRefreshRate(activity, effectiveRequestedHz);
params.preferredDisplayModeId = modeId;
params.preferredRefreshRate = refreshRate;
// Must be 0 when a modeId is set.
params.preferredRefreshRate = modeId != 0 ? 0f : refreshRate;
activity.getWindow().setAttributes(params);
Log.d(
TAG,
Expand Down