Fix : Fix controller Stick visualizer perfomance (#119)

This PR aims to fix a bug inside the settings window that caused the Controller Stick visualizer to run at extremely degraded performance when the selected profile had a rainbow LED configuration:
Old behaviour : <video src="/attachments/1915ab74-6e1b-4e2f-9182-820cbed5359b" title="Screen Recording 2026-05-30 105859" controls></video>
New / updated behaviour : <video src="/attachments/dd293402-19e7-439e-8aa6-114d4ee22404" title="Screen Recording 2026-05-30 110338" controls></video>

The issue was that the input settings page automatically subscribed controllers to rainbow LED updates when a saved profile with rainbow LEDs enabled was loaded.
Reopening input settings on a non-default controller profile could immediately start the rainbow LED update loop from the settings UI, which caused the stick visualizer to become sluggish or jittery on affected controllers. The preview handler is now only registered when the rainbow LED option is changed in the settings UI, and it uses a stable handler so duplicate callbacks are not stacked.

Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/119
This commit is contained in:
Babib3l
2026-05-30 20:33:50 +00:00
committed by sh0inx
parent 7be1708146
commit 824643e143
2 changed files with 32 additions and 22 deletions

View File

@@ -2,6 +2,7 @@ using Avalonia.Svg.Skia;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using Ryujinx.Ava.UI.Models.Input; using Ryujinx.Ava.UI.Models.Input;
using Ryujinx.Ava.UI.Views.Input; using Ryujinx.Ava.UI.Views.Input;
using Ryujinx.Common.Helper;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using Ryujinx.UI.Views.Input; using Ryujinx.UI.Views.Input;
@@ -59,32 +60,46 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public partial SvgImage Image { get; set; } public partial SvgImage Image { get; set; }
public InputViewModel ParentModel { get; } public InputViewModel ParentModel { get; }
private readonly RefEvent<System.Drawing.Color>.Handler _rainbowLedHandler;
public ControllerInputViewModel(InputViewModel model, GamepadInputConfig config, StickVisualizer visualizer) public ControllerInputViewModel(InputViewModel model, GamepadInputConfig config, StickVisualizer visualizer)
{ {
ParentModel = model; ParentModel = model;
Visualizer = visualizer; Visualizer = visualizer;
_rainbowLedHandler = SetRainbowLed;
model.NotifyChangesEvent += OnParentModelChanged; model.NotifyChangesEvent += OnParentModelChanged;
OnParentModelChanged(); OnParentModelChanged();
config.PropertyChanged += (_, args) => config.PropertyChanged += OnConfigPropertyChanged;
{
if (args.PropertyName is nameof(Config.UseRainbowLed))
{
if (Config is { UseRainbowLed: true, TurnOffLed: false, EnableLedChanging: true })
Rainbow.Updated += (ref color) => ParentModel.SelectedGamepad.SetLed((uint)color.ToArgb());
else
{
Rainbow.Reset();
if (Config.TurnOffLed)
ParentModel.SelectedGamepad.ClearLed();
else
ParentModel.SelectedGamepad.SetLed(Config.LedColor.ToUInt32());
}
}
};
Config = config; Config = config;
} }
private void OnConfigPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs args)
{
if (args.PropertyName is nameof(Config.UseRainbowLed))
{
if (Config is { UseRainbowLed: true, TurnOffLed: false, EnableLedChanging: true })
{
Rainbow.Updated -= _rainbowLedHandler;
Rainbow.Updated += _rainbowLedHandler;
}
else
{
Rainbow.Reset();
if (Config.TurnOffLed)
ParentModel.SelectedGamepad.ClearLed();
else
ParentModel.SelectedGamepad.SetLed(Config.LedColor.ToUInt32());
}
}
}
private void SetRainbowLed(ref System.Drawing.Color color)
{
ParentModel.SelectedGamepad.SetLed((uint)color.ToArgb());
}
public async void ShowMotionConfig() public async void ShowMotionConfig()
{ {
await MotionInputView.Show(this); await MotionInputView.Show(this);

View File

@@ -23,7 +23,6 @@ using Ryujinx.Input.SDL3;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Drawing;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text.Json; using System.Text.Json;
@@ -81,10 +80,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
field = value; field = value;
if ((field?.Features & GamepadFeaturesFlag.Led) != 0 &&
ConfigViewModel is ControllerInputViewModel { Config.UseRainbowLed: true })
Rainbow.Updated += (ref Color color) => field.SetLed((uint)color.ToArgb());
OnPropertiesChanged(nameof(HasLed), nameof(CanClearLed)); OnPropertiesChanged(nameof(HasLed), nameof(CanClearLed));
} }
} }