Skip to content

Commit

Permalink
Chroma - perf improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
diogotr7 committed Apr 11, 2024
1 parent 8a71772 commit 19944c5
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
<Platforms>x64</Platforms>
<EnableDynamicLoading>true</EnableDynamicLoading>
<Nullable>enable</Nullable>
<NoWarn>CA1416</NoWarn>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="ArtemisRGB.UI.Shared" IncludeAssets="compile;build;buildTransitive" Version="1.2024.302.1" />
<PackageReference Include="RazerSdkReader" Version="1.11.0" />
<PackageReference Include="RazerSdkReader" Version="2.2.0" />
</ItemGroup>

<ItemGroup>
Expand Down
17 changes: 11 additions & 6 deletions src/Artemis.Plugins.LayerBrushes.Chroma/Module/ChromaDataModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,24 @@
using SkiaSharp;
using System;
using System.Collections.Generic;
using Artemis.Plugins.LayerBrushes.Chroma.Services;

namespace Artemis.Plugins.LayerBrushes.Chroma.Module;

public class ChromaDataModel : DataModel
{
public bool IsActive { get; set; }
public string? CurrentApplication { get; set; }
public List<string> ApplicationList { get; internal set; } = new();
public List<int> PidList { get; internal set; } = new();
public string[] PriorityList { get; internal set; } = Array.Empty<string>();
public bool IsActive => Service.IsActive;
public string? CurrentApplication => Service.CurrentApp;
public string[] ApplicationList => Service.AppNames;
public uint[] PidList => Service.AppIds;
public string[] PriorityList { get; internal set; } = [];

internal ChromaService Service { get; set; } = null!;
}

public class ChromaDeviceDataModel : DataModel { }
public class ChromaDeviceDataModel : DataModel
{
}

public class ChromaLedDataModel : DataModel
{
Expand Down
26 changes: 10 additions & 16 deletions src/Artemis.Plugins.LayerBrushes.Chroma/Module/ChromaModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@
using SkiaSharp;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Artemis.Plugins.LayerBrushes.Chroma.Module;

[PluginFeature(Name = "Chroma")]
public class ChromaModule : Module<ChromaDataModel>
{
public override List<IModuleActivationRequirement> ActivationRequirements { get; } = new();
public override List<IModuleActivationRequirement> ActivationRequirements { get; } = [];

private readonly ILogger _logger;
private readonly ChromaService _chroma;
Expand All @@ -29,20 +28,25 @@ public ChromaModule(ChromaService chroma, ChromaRegistryService registry, ILogge

public override void Enable()
{
DataModel.Service = _chroma;

CreateStructure();

_chroma.MatrixUpdated += OnMatrixUpdated;
_chroma.AppListUpdated += OnAppListUpdated;
OnAppListUpdated(this, EventArgs.Empty);

try
{
DataModel.PriorityList = _registry.GetRazerSdkInfo().PriorityList;
var artemis = DataModel.PriorityList.IndexOf("Artemis.UI.Windows.exe");
if (artemis != -1 && artemis != DataModel.PriorityList.Length - 1)
{
_logger.Error("Artemis is not the last item in the Razer Chroma SDK priority list, the Chroma grabber may not work correctly.");
}
}
catch (Exception e)
{
_logger.Error(e, "Error setting priority list.");
DataModel.PriorityList = Array.Empty<string>();
DataModel.PriorityList = [];
}

AddDefaultProfile(DefaultCategoryName.Games, Plugin.ResolveRelativePath("profile.zip"));
Expand All @@ -51,21 +55,12 @@ public override void Enable()
public override void Disable()
{
_chroma.MatrixUpdated -= OnMatrixUpdated;
_chroma.AppListUpdated -= OnAppListUpdated;
}

public override void Update(double deltaTime)
{
}

private void OnAppListUpdated(object? sender, EventArgs args)
{
DataModel.IsActive = _chroma.IsActive;
DataModel.CurrentApplication = _chroma.CurrentApp;
DataModel.ApplicationList = _chroma.AppNames.ToList();
DataModel.PidList = _chroma.AppIds.Select(p => (int)p).ToList();
}

private void OnMatrixUpdated(object? sender, MatrixUpdatedEventArgs e)
{
var (deviceType, colors) = e;
Expand All @@ -90,9 +85,8 @@ private void CreateStructure()
var deviceDataModel = DataModel.AddDynamicChild(rzDeviceType.ToStringFast(), new ChromaDeviceDataModel());

var map = DefaultChromaLedMap.GetDeviceMap(rzDeviceType);
for (var i = 0; i < map.Length; i++)
foreach (var ledId in map)
{
var ledId = map[i];
if (ledId == LedId.Invalid)
continue;

Expand Down
70 changes: 35 additions & 35 deletions src/Artemis.Plugins.LayerBrushes.Chroma/Services/ChromaService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,47 @@
using SkiaSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using Artemis.Core;
using RazerSdkReader;
using RazerSdkReader.Structures;

namespace Artemis.Plugins.LayerBrushes.Chroma.Services;

public readonly record struct MatrixUpdatedEventArgs(RzDeviceType DeviceType, SKColor[] Matrix);
public record MatrixUpdatedEventArgs(RzDeviceType DeviceType, SKColor[] Matrix);

// ReSharper disable once ClassNeverInstantiated.Global
public sealed class ChromaService : IPluginService, IDisposable
{
private readonly SKColor[][] _matrices;
private readonly List<string> _apps;
private readonly List<uint> _pids;
private readonly ChromaReader _reader;
private readonly Profiler _profiler;
private readonly object _lock;

private readonly MatrixUpdatedEventArgs[] _matrixUpdatedEventArgs;

public event EventHandler<MatrixUpdatedEventArgs>? MatrixUpdated;
public event EventHandler? AppListUpdated;

public bool IsActive => !string.IsNullOrWhiteSpace(CurrentApp) && CurrentApp != "Artemis.UI.Windows.exe";
public string? CurrentApp { get; private set; }
public uint? CurrentAppId { get; private set; }
public IEnumerable<string> AppNames => _apps;
public IEnumerable<uint> AppIds => _pids;
public string[] AppNames { get; }
public uint[] AppIds { get; }

public ChromaService(Plugin plugin)
{
_profiler = plugin.GetProfiler("Chroma Service");
_lock = new object();
_apps = [];
_pids = [];
AppNames = new string[50];
AppIds = new uint[50];

var deviceTypes = Enum.GetValues<RzDeviceType>();
_matrices = new SKColor[deviceTypes.Length][];
for (var i = 0; i < _matrices.Length; i++)
_matrices[i] = new SKColor[deviceTypes[i].GetLength()];
_matrices = deviceTypes.Select(deviceType => new SKColor[deviceType.GetLength()]).ToArray();
_matrixUpdatedEventArgs = deviceTypes.Select(deviceType => new MatrixUpdatedEventArgs(deviceType, _matrices[(int)deviceType])).ToArray();

_reader = new();
_reader = new ChromaReader();
_reader.KeyboardUpdated += RazerEmulatorReaderOnKeyboardUpdated;
_reader.MouseUpdated += RazerEmulatorReaderOnMouseUpdated;
_reader.MousepadUpdated += RazerEmulatorReaderOnMousepadUpdated;
Expand All @@ -65,46 +67,44 @@ public ChromaService(Plugin plugin)

private void RazerEmulatorReaderOnKeyboardUpdated(object? sender, in ChromaKeyboard e) => UpdateMatrix(RzDeviceType.Keyboard, in e);

private void UpdateMatrix<T>(RzDeviceType deviceType, in T data) where T : IColorProvider
private void UpdateMatrix<T>(RzDeviceType deviceType, in T data) where T : IColorProvider
{
var profilerName = deviceType.ToStringFast();

_profiler.StartMeasurement(profilerName);

lock (_lock)
{
var matrix = _matrices[(int) deviceType];

Span<ChromaColor> colors = stackalloc ChromaColor[matrix.Length];

var matrix = _matrices[(int)deviceType];
//SKColor and ChromaColor are the same size and layout,
//so we can just write to it directly.
var colors = MemoryMarshal.Cast<SKColor, ChromaColor>(matrix);
data.GetColors(colors);

for (var i = 0; i < colors.Length; i++)
{
var rzColor = colors[i];
matrix[i] = new SKColor(rzColor.R, rzColor.G, rzColor.B);
}

MatrixUpdated?.Invoke(this, new MatrixUpdatedEventArgs(deviceType, matrix));
MatrixUpdated?.Invoke(this, _matrixUpdatedEventArgs[(int)deviceType]);
}

_profiler.StopMeasurement(profilerName);
}

private void UpdateAppListData(in ChromaAppData app)
{
_apps.Clear();
_pids.Clear();

_profiler.StartMeasurement("AppList");

CurrentAppId = app.CurrentAppId;
CurrentApp = app.CurrentAppName;

foreach(ref readonly var appInfo in app.AppInfo)

ReadOnlySpan<ChromaAppInfo> apps = app.AppInfo;
for (var i = 0; i < apps.Length; i++)
{
_apps.Add(appInfo.AppName);
_pids.Add(appInfo.AppId);
ref readonly var appInfo = ref apps[i];
AppNames[i] = appInfo.AppName;
AppIds[i] = appInfo.AppId;
}

AppListUpdated?.Invoke(this, EventArgs.Empty);

_profiler.StopMeasurement("AppList");
}

public void Dispose()
Expand Down
2 changes: 1 addition & 1 deletion src/Artemis.Plugins.LayerBrushes.Chroma/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"Author": "diogotr7",
"Icon": "Snake",
"Description": "Provides a layer that displays lighting from Razer Chroma supported games on all devices Artemis supports.",
"Version": "1.2.0.1",
"Version": "1.3.0.0",
"Main": "Artemis.Plugins.LayerBrushes.Chroma.dll",
"Platforms": "Windows"
}

0 comments on commit 19944c5

Please sign in to comment.