Skip to content

Commit 46810df

Browse files
committed
avalonia: introduce flag to switch to SW rendering
Introduce a flag to switch Avalonia to use software rendering rather than hardware/GPU-based. There is an open Avalonia issue[1] on Windows when run on certain ARM64 GPUs. Until this is solved, introduce this workaround flag. [1]: AvaloniaUI/Avalonia#10405
1 parent e1064f3 commit 46810df

File tree

7 files changed

+103
-2
lines changed

7 files changed

+103
-2
lines changed

docs/configuration.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,24 @@ Defaults to enabled.
233233

234234
---
235235

236+
### credential.guiSoftwareRendering
237+
238+
Force the use of software rendering for GUI prompts.
239+
240+
This is currently only applicable on Windows.
241+
242+
#### Example
243+
244+
```shell
245+
git config --global credential.guiSoftwareRendering true
246+
```
247+
248+
Defaults to false (use hardware acceleration where available).
249+
250+
**Also see: [GCM_GUI_SOFTWARE_RENDERING][gcm-gui-software-rendering]**
251+
252+
---
253+
236254
### credential.autoDetectTimeout
237255

238256
Set the maximum length of time, in milliseconds, that GCM should wait for a
@@ -978,6 +996,7 @@ Defaults to disabled.
978996
[gcm-github-authmodes]: environment.md#GCM_GITHUB_AUTHMODES
979997
[gcm-gitlab-authmodes]:environment.md#GCM_GITLAB_AUTHMODES
980998
[gcm-gui-prompt]: environment.md#GCM_GUI_PROMPT
999+
[gcm-gui-software-rendering]: environment.md#GCM_GUI_SOFTWARE_RENDERING
9811000
[gcm-http-proxy]: environment.md#GCM_HTTP_PROXY-deprecated
9821001
[gcm-interactive]: environment.md#GCM_INTERACTIVE
9831002
[gcm-msauth-flow]: environment.md#GCM_MSAUTH_FLOW

docs/environment.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,32 @@ Defaults to enabled.
272272

273273
---
274274

275+
### GCM_GUI_SOFTWARE_RENDERING
276+
277+
Force the use of software rendering for GUI prompts.
278+
279+
This is currently only applicable on Windows.
280+
281+
#### Example
282+
283+
##### Windows
284+
285+
```batch
286+
SET GCM_GUI_SOFTWARE_RENDERING=1
287+
```
288+
289+
##### macOS/Linux
290+
291+
```bash
292+
export GCM_GUI_SOFTWARE_RENDERING=1
293+
```
294+
295+
Defaults to false (use hardware acceleration where available).
296+
297+
**Also see: [credential.guiSoftwareRendering][credential-guisoftwarerendering]**
298+
299+
---
300+
275301
### GCM_AUTODETECT_TIMEOUT
276302

277303
Set the maximum length of time, in milliseconds, that GCM should wait for a
@@ -1111,6 +1137,7 @@ Defaults to disabled.
11111137
[credential-githubauthmodes]: configuration.md#credentialgitHubAuthModes
11121138
[credential-gitlabauthmodes]: configuration.md#credentialgitLabAuthModes
11131139
[credential-guiprompt]: configuration.md#credentialguiprompt
1140+
[credential-guisoftwarerendering]: configuration.md#credentialguisoftwarerendering
11141141
[credential-httpproxy]: configuration.md#credentialhttpProxy-deprecated
11151142
[credential-interactive]: configuration.md#credentialinteractive
11161143
[credential-namespace]: configuration.md#credentialnamespace

src/shared/Core/ApplicationBase.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Text;
55
using System.Threading;
66
using System.Threading.Tasks;
7+
using GitCredentialManager.UI;
78

89
namespace GitCredentialManager
910
{
@@ -74,6 +75,12 @@ public Task<int> RunAsync(string[] args)
7475
Context.Trace.WriteLine("Tracing of secrets is enabled. Trace output may contain sensitive information.");
7576
}
7677

78+
// Set software rendering if defined in settings
79+
if (Context.Settings.UseSoftwareRendering)
80+
{
81+
AvaloniaUi.Initialize(win32SoftwareRendering: true);
82+
}
83+
7784
return RunInternalAsync(args);
7885
}
7986

src/shared/Core/Constants.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ public static class EnvironmentVariables
118118
public const string OAuthClientAuthHeader = "GCM_OAUTH_USE_CLIENT_AUTH_HEADER";
119119
public const string OAuthDefaultUserName = "GCM_OAUTH_DEFAULT_USERNAME";
120120
public const string GcmDevUseLegacyUiHelpers = "GCM_DEV_USELEGACYUIHELPERS";
121+
public const string GcmGuiSoftwareRendering = "GCM_GUI_SOFTWARE_RENDERING";
121122
}
122123

123124
public static class Http
@@ -160,6 +161,7 @@ public static class Credential
160161
public const string UiHelper = "uiHelper";
161162
public const string DevUseLegacyUiHelpers = "devUseLegacyUiHelpers";
162163
public const string MsAuthUseDefaultAccount = "msauthUseDefaultAccount";
164+
public const string GuiSoftwareRendering = "guiSoftwareRendering";
163165

164166
public const string OAuthAuthenticationModes = "oauthAuthModes";
165167
public const string OAuthClientId = "oauthClientId";

src/shared/Core/Settings.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,11 @@ public interface ISettings : IDisposable
184184
/// </summary>
185185
bool UseMsAuthDefaultAccount { get; }
186186

187+
/// <summary>
188+
/// True if software rendering should be used for graphical user interfaces, false otherwise.
189+
/// </summary>
190+
bool UseSoftwareRendering { get; }
191+
187192
/// <summary>
188193
/// Get TRACE2 settings.
189194
/// </summary>
@@ -559,6 +564,17 @@ public bool GetTracingEnabled(out string value) =>
559564
KnownGitCfg.Credential.Trace,
560565
out value) && !value.IsFalsey();
561566

567+
public bool UseSoftwareRendering
568+
{
569+
get
570+
{
571+
return TryGetSetting(KnownEnvars.GcmGuiSoftwareRendering,
572+
KnownGitCfg.Credential.SectionName,
573+
KnownGitCfg.Credential.GuiSoftwareRendering,
574+
out string str) && str.ToBooleanyOrDefault(false);
575+
}
576+
}
577+
562578
public Trace2Settings GetTrace2Settings()
563579
{
564580
var settings = new Trace2Settings();

src/shared/Core/UI/AvaloniaUi.cs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
using System.Threading.Tasks;
44
using Avalonia;
55
using Avalonia.Controls;
6-
using Avalonia.Controls.ApplicationLifetimes;
76
using Avalonia.Threading;
87
using GitCredentialManager.Interop.Windows.Native;
98
using GitCredentialManager.UI.Controls;
@@ -15,6 +14,24 @@ namespace GitCredentialManager.UI
1514
public static class AvaloniaUi
1615
{
1716
private static bool _isAppStarted;
17+
private static bool _win32SoftwareRendering;
18+
19+
/// <summary>
20+
/// Configure the Avalonia application.
21+
/// </summary>
22+
/// <param name="win32SoftwareRendering">True to enable software rendering on Windows, false otherwise.</param>
23+
/// <remarks>
24+
/// This must be invoked before the Avalonia application loop has started.
25+
/// </remarks>
26+
public static void Initialize(bool win32SoftwareRendering)
27+
{
28+
if (_isAppStarted)
29+
{
30+
throw new InvalidOperationException("Setup must be called before the Avalonia application is started.");
31+
}
32+
33+
_win32SoftwareRendering = win32SoftwareRendering;
34+
}
1835

1936
public static Task ShowViewAsync(Func<Control> viewFunc, WindowViewModel viewModel, IntPtr parentHandle, CancellationToken ct) =>
2037
ShowWindowAsync(() => new DialogWindow(viewFunc()), viewModel, parentHandle, ct);
@@ -46,7 +63,18 @@ public static Task ShowWindowAsync(Func<Window> windowFunc, object dataContext,
4663
// This action only returns on our dispatcher shutdown.
4764
Dispatcher.MainThread.Post(appCancelToken =>
4865
{
49-
AppBuilder.Configure<AvaloniaApp>()
66+
var appBuilder = AppBuilder.Configure<AvaloniaApp>();
67+
68+
#if NETFRAMEWORK
69+
// Set custom rendering options and modes if required
70+
if (PlatformUtils.IsWindows() && _win32SoftwareRendering)
71+
{
72+
appBuilder.With(new Win32PlatformOptions
73+
{ RenderingMode = new[] { Win32RenderingMode.Software } });
74+
}
75+
#endif
76+
77+
appBuilder
5078
#if NETFRAMEWORK
5179
.UseWin32()
5280
.UseSkia()

src/shared/TestInfrastructure/Objects/TestSettings.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ ProxyConfiguration ISettings.GetProxyConfiguration()
187187

188188
bool ISettings.UseMsAuthDefaultAccount => UseMsAuthDefaultAccount;
189189

190+
bool ISettings.UseSoftwareRendering => false;
191+
190192
#endregion
191193

192194
#region IDisposable

0 commit comments

Comments
 (0)