1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-12 21:38:38 +00:00

Core - Simplified and improved render scaling

This commit is contained in:
SpoinkyNL 2020-12-08 22:54:54 +01:00
parent 18359c443f
commit 186d012087
10 changed files with 63 additions and 99 deletions

View File

@ -1,5 +1,6 @@
using System.Text;
using RGB.NET.Core;
using SkiaSharp;
namespace Artemis.Core
{
@ -20,4 +21,17 @@ namespace Artemis.Core
return builder.ToString();
}
}
internal static class RgbRectangleExtensions
{
public static SKRect ToSKRect(this Rectangle rectangle)
{
return SKRect.Create(
(float) rectangle.Location.X,
(float) rectangle.Location.Y,
(float) rectangle.Size.Width,
(float) rectangle.Size.Height
);
}
}
}

View File

@ -417,7 +417,7 @@ namespace Artemis.Core
{
SKPath path = new SKPath {FillType = SKPathFillType.Winding};
foreach (ArtemisLed artemisLed in Leds)
path.AddRect(artemisLed.AbsoluteRenderRectangle);
path.AddRect(artemisLed.AbsoluteRectangle);
Path = path;
}

View File

@ -14,8 +14,8 @@ namespace Artemis.Core
/// </summary>
public class ArtemisDevice : CorePropertyChanged
{
private SKPath? _renderPath;
private SKRect _renderRectangle;
private SKPath? _path;
private SKRect _rectangle;
internal ArtemisDevice(IRGBDevice rgbDevice, DeviceProvider deviceProvider, ArtemisSurface surface)
{
@ -58,21 +58,21 @@ namespace Artemis.Core
}
/// <summary>
/// Gets the rectangle covering the device, sized to match the render scale
/// Gets the rectangle covering the device
/// </summary>
public SKRect RenderRectangle
public SKRect Rectangle
{
get => _renderRectangle;
private set => SetAndNotify(ref _renderRectangle, value);
get => _rectangle;
private set => SetAndNotify(ref _rectangle, value);
}
/// <summary>
/// Gets the path surrounding the device, sized to match the render scale
/// Gets the path surrounding the device
/// </summary>
public SKPath? RenderPath
public SKPath? Path
{
get => _renderPath;
private set => SetAndNotify(ref _renderPath, value);
get => _path;
private set => SetAndNotify(ref _path, value);
}
/// <summary>
@ -239,24 +239,18 @@ namespace Artemis.Core
internal void CalculateRenderProperties()
{
RenderRectangle = SKRect.Create(
(RgbDevice.Location.X * Surface.Scale).RoundToInt(),
(RgbDevice.Location.Y * Surface.Scale).RoundToInt(),
(RgbDevice.DeviceRectangle.Size.Width * Surface.Scale).RoundToInt(),
(RgbDevice.DeviceRectangle.Size.Height * Surface.Scale).RoundToInt()
);
Rectangle = RgbDevice.DeviceRectangle.ToSKRect();
if (!Leds.Any())
return;
foreach (ArtemisLed led in Leds)
led.CalculateRenderRectangle();
led.CalculateRectangles();
SKPath path = new SKPath {FillType = SKPathFillType.Winding};
foreach (ArtemisLed artemisLed in Leds)
path.AddRect(artemisLed.AbsoluteRenderRectangle);
path.AddRect(artemisLed.AbsoluteRectangle);
RenderPath = path;
Path = path;
}
#region Events

View File

@ -8,14 +8,14 @@ namespace Artemis.Core
/// </summary>
public class ArtemisLed : CorePropertyChanged
{
private SKRect _absoluteRenderRectangle;
private SKRect _renderRectangle;
private SKRect _absoluteRectangle;
private SKRect _rectangle;
internal ArtemisLed(Led led, ArtemisDevice device)
{
RgbLed = led;
Device = device;
CalculateRenderRectangle();
CalculateRectangles();
}
/// <summary>
@ -29,38 +29,27 @@ namespace Artemis.Core
public ArtemisDevice Device { get; }
/// <summary>
/// Gets the rectangle covering the LED, sized to match the render scale and positioned relative to the
/// <see cref="Device" />
/// Gets the rectangle covering the LED positioned relative to the<see cref="Device" />
/// </summary>
public SKRect RenderRectangle
public SKRect Rectangle
{
get => _renderRectangle;
private set => SetAndNotify(ref _renderRectangle, value);
get => _rectangle;
private set => SetAndNotify(ref _rectangle, value);
}
/// <summary>
/// Gets the rectangle covering the LED, sized to match the render scale
/// Gets the rectangle covering the LED
/// </summary>
public SKRect AbsoluteRenderRectangle
public SKRect AbsoluteRectangle
{
get => _absoluteRenderRectangle;
private set => SetAndNotify(ref _absoluteRenderRectangle, value);
get => _absoluteRectangle;
private set => SetAndNotify(ref _absoluteRectangle, value);
}
internal void CalculateRenderRectangle()
internal void CalculateRectangles()
{
RenderRectangle = SKRect.Create(
(RgbLed.LedRectangle.Location.X * Device.Surface.Scale).RoundToInt(),
(RgbLed.LedRectangle.Location.Y * Device.Surface.Scale).RoundToInt(),
(RgbLed.LedRectangle.Size.Width * Device.Surface.Scale).RoundToInt(),
(RgbLed.LedRectangle.Size.Height * Device.Surface.Scale).RoundToInt()
);
AbsoluteRenderRectangle = SKRect.Create(
(RgbLed.AbsoluteLedRectangle.Location.X * Device.Surface.Scale).RoundToInt(),
(RgbLed.AbsoluteLedRectangle.Location.Y * Device.Surface.Scale).RoundToInt(),
(RgbLed.AbsoluteLedRectangle.Size.Width * Device.Surface.Scale).RoundToInt(),
(RgbLed.AbsoluteLedRectangle.Size.Height * Device.Surface.Scale).RoundToInt()
);
Rectangle = RgbLed.LedRectangle.ToSKRect();
AbsoluteRectangle = RgbLed.AbsoluteLedRectangle.ToSKRect();
}
/// <inheritdoc />

View File

@ -16,28 +16,25 @@ namespace Artemis.Core
private ReadOnlyDictionary<Led, ArtemisLed> _ledMap = new ReadOnlyDictionary<Led, ArtemisLed>(new Dictionary<Led, ArtemisLed>());
private bool _isActive;
private string _name;
private double _scale;
internal ArtemisSurface(RGBSurface rgbSurface, string name, double scale)
internal ArtemisSurface(RGBSurface rgbSurface, string name)
{
SurfaceEntity = new SurfaceEntity {DeviceEntities = new List<DeviceEntity>()};
EntityId = Guid.NewGuid();
RgbSurface = rgbSurface;
_name = name;
_scale = scale;
_isActive = false;
ApplyToEntity();
}
internal ArtemisSurface(RGBSurface rgbSurface, SurfaceEntity surfaceEntity, double scale)
internal ArtemisSurface(RGBSurface rgbSurface, SurfaceEntity surfaceEntity)
{
SurfaceEntity = surfaceEntity;
EntityId = surfaceEntity.Id;
RgbSurface = rgbSurface;
_scale = scale;
_name = surfaceEntity.Name;
_isActive = surfaceEntity.IsActive;
}
@ -47,15 +44,6 @@ namespace Artemis.Core
/// </summary>
public RGBSurface RgbSurface { get; }
/// <summary>
/// Gets the scale at which this surface is rendered
/// </summary>
public double Scale
{
get => _scale;
private set => SetAndNotify(ref _scale, value);
}
/// <summary>
/// Gets the name of the surface
/// </summary>
@ -96,19 +84,6 @@ namespace Artemis.Core
internal SurfaceEntity SurfaceEntity { get; set; }
internal Guid EntityId { get; set; }
/// <summary>
/// Updates the scale of the surface
/// </summary>
/// <param name="value"></param>
public void UpdateScale(double value)
{
Scale = value;
foreach (ArtemisDevice device in Devices)
device.CalculateRenderProperties();
OnScaleChanged();
}
/// <summary>
/// Attempts to retrieve the <see cref="ArtemisLed" /> that corresponds the provided RGB.NET <see cref="Led" />
/// </summary>

View File

@ -41,7 +41,7 @@ namespace Artemis.Core.LayerBrushes
pointsPath.AddPoly(new[]
{
new SKPoint(0, 0),
new SKPoint(artemisLed.AbsoluteRenderRectangle.Left - Layer.Bounds.Left, artemisLed.AbsoluteRenderRectangle.Top - Layer.Bounds.Top)
new SKPoint(artemisLed.AbsoluteRectangle.Left - Layer.Bounds.Left, artemisLed.AbsoluteRectangle.Top - Layer.Bounds.Top)
});
}
@ -61,10 +61,10 @@ namespace Artemis.Core.LayerBrushes
ledPaint.Color = GetColor(artemisLed, renderPoint);
SKRect ledRectangle = SKRect.Create(
artemisLed.AbsoluteRenderRectangle.Left - Layer.Bounds.Left,
artemisLed.AbsoluteRenderRectangle.Top - Layer.Bounds.Top,
artemisLed.AbsoluteRenderRectangle.Width,
artemisLed.AbsoluteRenderRectangle.Height
artemisLed.AbsoluteRectangle.Left - Layer.Bounds.Left,
artemisLed.AbsoluteRectangle.Top - Layer.Bounds.Top,
artemisLed.AbsoluteRectangle.Width,
artemisLed.AbsoluteRectangle.Height
);
canvas.DrawRect(ledRectangle, ledPaint);

View File

@ -27,13 +27,14 @@ namespace Artemis.Core.Services
private readonly Stopwatch _frameStopWatch;
private readonly ILogger _logger;
private readonly PluginSetting<LogEventLevel> _loggingLevel;
private readonly PluginSetting<double> _renderScale;
private readonly IPluginManagementService _pluginManagementService;
private readonly IProfileService _profileService;
private readonly IRgbService _rgbService;
private readonly ISurfaceService _surfaceService;
private List<BaseDataModelExpansion> _dataModelExpansions = new List<BaseDataModelExpansion>();
private List<Module> _modules = new List<Module>();
// ReSharper disable UnusedParameter.Local - Storage migration and module service are injected early to ensure it runs before anything else
public CoreService(IKernel kernel, ILogger logger, StorageMigrationService _, ISettingsService settingsService, IPluginManagementService pluginManagementService,
IRgbService rgbService, ISurfaceService surfaceService, IProfileService profileService, IModuleService moduleService)
@ -47,6 +48,7 @@ namespace Artemis.Core.Services
_surfaceService = surfaceService;
_profileService = profileService;
_loggingLevel = settingsService.GetSetting("Core.LoggingLevel", LogEventLevel.Debug);
_renderScale = settingsService.GetSetting("Core.RenderScale", 0.5);
_frameStopWatch = new Stopwatch();
UpdatePluginCache();
@ -185,6 +187,7 @@ namespace Artemis.Core.Services
// Render all active modules
using SKCanvas canvas = new SKCanvas(_rgbService.BitmapBrush.Bitmap);
canvas.Scale((float) _renderScale.Value);
canvas.Clear(new SKColor(0, 0, 0));
if (!ModuleRenderingDisabled)
// While non-activated modules may be updated above if they expand the main data model, they may never render

View File

@ -17,6 +17,8 @@ namespace Artemis.Core.Services.Models
MarginTop = margin;
MarginRight = margin;
MarginBottom = margin;
SurfaceArrangement = null!;
}

View File

@ -15,26 +15,23 @@ namespace Artemis.Core.Services
{
private readonly ILogger _logger;
private readonly IPluginManagementService _pluginManagementService;
private readonly PluginSetting<double> _renderScaleSetting;
private readonly IRgbService _rgbService;
private readonly List<ArtemisSurface> _surfaceConfigurations;
private readonly ISurfaceRepository _surfaceRepository;
public SurfaceService(ILogger logger, ISurfaceRepository surfaceRepository, IRgbService rgbService, IPluginManagementService pluginManagementService, ISettingsService settingsService)
public SurfaceService(ILogger logger, ISurfaceRepository surfaceRepository, IRgbService rgbService, IPluginManagementService pluginManagementService)
{
_logger = logger;
_surfaceRepository = surfaceRepository;
_rgbService = rgbService;
_pluginManagementService = pluginManagementService;
_surfaceConfigurations = new List<ArtemisSurface>();
_renderScaleSetting = settingsService.GetSetting("Core.RenderScale", 0.5);
// LoadFromRepository is guaranteed to set the ActiveSurface
ActiveSurface = null!;
LoadFromRepository();
_rgbService.DeviceLoaded += RgbServiceOnDeviceLoaded;
_renderScaleSetting.SettingChanged += RenderScaleSettingOnSettingChanged;
}
public ArtemisSurface ActiveSurface { get; private set; }
@ -43,7 +40,7 @@ namespace Artemis.Core.Services
public ArtemisSurface CreateSurfaceConfiguration(string name)
{
// Create a blank config
ArtemisSurface configuration = new ArtemisSurface(_rgbService.Surface, name, _renderScaleSetting.Value);
ArtemisSurface configuration = new ArtemisSurface(_rgbService.Surface, name);
// Add all current devices
foreach (IRGBDevice rgbDevice in _rgbService.LoadedDevices)
@ -133,7 +130,7 @@ namespace Artemis.Core.Services
foreach (SurfaceEntity surfaceEntity in configs)
{
// Create the surface entity
ArtemisSurface surfaceConfiguration = new ArtemisSurface(_rgbService.Surface, surfaceEntity, _renderScaleSetting.Value);
ArtemisSurface surfaceConfiguration = new ArtemisSurface(_rgbService.Surface, surfaceEntity);
foreach (DeviceEntity position in surfaceEntity.DeviceEntities)
{
IRGBDevice? device = _rgbService.Surface.Devices.FirstOrDefault(d => d.GetDeviceIdentifier() == position.DeviceIdentifier);
@ -225,15 +222,6 @@ namespace Artemis.Core.Services
UpdateSurfaceConfiguration(ActiveSurface, true);
}
private void RenderScaleSettingOnSettingChanged(object? sender, EventArgs e)
{
foreach (ArtemisSurface surfaceConfiguration in SurfaceConfigurations)
{
surfaceConfiguration.UpdateScale(_renderScaleSetting.Value);
OnSurfaceConfigurationUpdated(new SurfaceConfigurationEventArgs(surfaceConfiguration));
}
}
#endregion
#region Events

View File

@ -22,12 +22,11 @@ namespace Artemis.UI.Services
public Rect GetLayerBounds(Layer layer)
{
// Adjust the render rectangle for the difference in render scale
double renderScale = _settingsService.GetSetting("Core.RenderScale", 0.5).Value;
return new Rect(
layer.Bounds.Left / renderScale * 1,
layer.Bounds.Top / renderScale * 1,
Math.Max(0, layer.Bounds.Width / renderScale * 1),
Math.Max(0, layer.Bounds.Height / renderScale * 1)
layer.Bounds.Left,
layer.Bounds.Top,
Math.Max(0, layer.Bounds.Width),
Math.Max(0, layer.Bounds.Height)
);
}