Skip to content

Comments

feat: [Windows] 支持自动使用高性能显卡#5420

Open
CiiLu wants to merge 4 commits intoHMCL-dev:mainfrom
CiiLu:soms
Open

feat: [Windows] 支持自动使用高性能显卡#5420
CiiLu wants to merge 4 commits intoHMCL-dev:mainfrom
CiiLu:soms

Conversation

@CiiLu
Copy link
Contributor

@CiiLu CiiLu commented Feb 4, 2026

No description provided.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an optional Windows-only launch behavior to prefer the high-performance GPU by temporarily writing UserGpuPreferences registry values, exposed via a new launcher setting.

Changes:

  • Extend the Windows registry helper (WinReg/JNA) to support setting and deleting REG_SZ values.
  • Add a new persisted config flag and settings UI toggle for “high-performance GPU” on Windows.
  • Hook game launch flow to create (and later remove) the relevant UserGpuPreferences registry entry.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/windows/WinReg.java Adds setValue / deleteValue APIs and JNA implementations for registry writes.
HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/windows/WinConstants.java Adds registry access/constants needed for write/delete operations.
HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/windows/Advapi32.java Adds JNA signatures for RegCreateKeyExW / RegSetValueExW / RegDeleteValueW.
HMCL/src/main/resources/assets/lang/I18N*.properties Adds i18n strings for the new Windows GPU preference setting.
HMCL/src/main/java/org/jackhuang/hmcl/ui/main/SettingsPage.java Adds a new toggle to the settings UI bound to the new config property.
HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java Persists the new windowsHighPerformance flag.
HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java Writes/deletes the GPU preference registry value around the launch lifecycle.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +91 to +93
public abstract boolean setValue(HKEY root, String key, String valueName, String value);

public abstract boolean deleteValue(HKEY root, String key, String valueName);
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New WinReg mutation APIs (setValue/deleteValue) are introduced, but the existing WinRegTest only covers querying. Please add JUnit coverage for setting a REG_SZ value and deleting it (including verifying behavior when the value/key does not exist), so regressions in JNA signatures/encoding are caught.

Copilot uses AI. Check for mistakes.
Comment on lines 850 to 854
WinReg.INSTANCE.deleteValue(
WinReg.HKEY.HKEY_CURRENT_USER,
"Software\\Microsoft\\DirectX\\UserGpuPreferences",
process.getProcess().info().command().orElseThrow()
);
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The registry value name used for cleanup should match exactly the value name used when setting it. Here the value name is derived from javaVersionRef.get().getBinary() during setValue, but cleanup uses process.getProcess().info().command().orElseThrow(), which may differ (quoting/canonicalization) or be empty and throw, leaving the registry entry behind or breaking finishLaunch. Store the exact value name string you used for setValue and reuse it for deletion, and avoid orElseThrow() here.

Suggested change
WinReg.INSTANCE.deleteValue(
WinReg.HKEY.HKEY_CURRENT_USER,
"Software\\Microsoft\\DirectX\\UserGpuPreferences",
process.getProcess().info().command().orElseThrow()
);
String valueName = null;
JavaRuntime javaRuntime = javaVersionRef.get();
if (javaRuntime != null && javaRuntime.getBinary() != null) {
valueName = javaRuntime.getBinary().toString();
}
if (valueName != null) {
WinReg.INSTANCE.deleteValue(
WinReg.HKEY.HKEY_CURRENT_USER,
"Software\\Microsoft\\DirectX\\UserGpuPreferences",
valueName
);
}

Copilot uses AI. Check for mistakes.
Comment on lines 847 to 854
try {
Thread.sleep(5000L);
} catch (InterruptedException ignored) {}
WinReg.INSTANCE.deleteValue(
WinReg.HKEY.HKEY_CURRENT_USER,
"Software\\Microsoft\\DirectX\\UserGpuPreferences",
process.getProcess().info().command().orElseThrow()
);
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

finishLaunch() performs a 5s Thread.sleep and ignores interrupts. This method is invoked from onLog() while holding lock (see onLog around the finishLaunch() call), so sleeping here can block log processing and hold the lock for 5 seconds. Consider scheduling the delayed registry cleanup asynchronously (after releasing the lock), and if catching InterruptedException, restore the interrupt flag with Thread.currentThread().interrupt().

Suggested change
try {
Thread.sleep(5000L);
} catch (InterruptedException ignored) {}
WinReg.INSTANCE.deleteValue(
WinReg.HKEY.HKEY_CURRENT_USER,
"Software\\Microsoft\\DirectX\\UserGpuPreferences",
process.getProcess().info().command().orElseThrow()
);
CompletableFuture.runAsync(() -> {
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
WinReg.INSTANCE.deleteValue(
WinReg.HKEY.HKEY_CURRENT_USER,
"Software\\Microsoft\\DirectX\\UserGpuPreferences",
process.getProcess().info().command().orElseThrow()
);
});

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant