1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2026-01-02 10:43:31 +00:00

Changed the way effects are rendered to improve performance

This commit is contained in:
Darth Affe 2016-06-13 21:22:59 +02:00
parent e438340705
commit 436eb365a1
10 changed files with 106 additions and 148 deletions

View File

@ -99,6 +99,7 @@ namespace Artemis.DeviceProviders.Corsair
// For STRAFE, stretch the image on row 2.
if (_keyboard.DeviceInfo.Model == "STRAFE RGB")
{
//TODO DarthAffe 13.06.2016: This might leak memory since it's not disposed, but I don't want to change it without the ability to test if it still works
var strafeBitmap = new Bitmap(22, 8);
using (var g = Graphics.FromImage(strafeBitmap))
{

View File

@ -16,6 +16,7 @@ namespace Artemis.Managers
private readonly EffectManager _effectManager;
private readonly ILogger _logger;
private readonly Timer _loopTimer;
private Bitmap _keyboardBitmap;
public LoopManager(ILogger logger, EffectManager effectManager, DeviceManager deviceManager)
{
@ -38,6 +39,7 @@ namespace Artemis.Managers
{
_loopTimer.Stop();
_loopTimer.Dispose();
_keyboardBitmap?.Dispose();
}
public void Start()
@ -67,6 +69,9 @@ namespace Artemis.Managers
_effectManager.ChangeEffect(lastEffect);
}
// I assume that it's safe to use ActiveKeyboard and ActifeEffect here since both is checked above
_keyboardBitmap = _deviceManager.ActiveKeyboard.KeyboardBitmap(_effectManager.ActiveEffect.KeyboardScale);
Running = true;
}
@ -79,6 +84,8 @@ namespace Artemis.Managers
Running = false;
_deviceManager.ReleaseActiveKeyboard();
_keyboardBitmap?.Dispose();
_keyboardBitmap = null;
}
private void Render(object sender, ElapsedEventArgs e)
@ -117,20 +124,26 @@ namespace Artemis.Managers
renderEffect.Update();
// Get ActiveEffect's bitmap
Bitmap bitmap = null;
Brush mouseBrush = null;
Brush headsetBrush = null;
var mice = _deviceManager.MiceProviders.Where(m => m.CanUse).ToList();
var headsets = _deviceManager.HeadsetProviders.Where(m => m.CanUse).ToList();
using (Graphics keyboardGraphics = Graphics.FromImage(_keyboardBitmap))
{
// Fill the bitmap's background with black to avoid trailing colors on some keyboards
keyboardGraphics.Clear(Color.Black);
if (renderEffect.Initialized)
renderEffect.Render(out bitmap, out mouseBrush, out headsetBrush, mice.Any(), headsets.Any());
renderEffect.Render(keyboardGraphics, out mouseBrush, out headsetBrush, mice.Any(),
headsets.Any());
// Draw enabled overlays on top of the renderEffect
foreach (var overlayModel in _effectManager.EnabledOverlays)
{
overlayModel.Update();
overlayModel.RenderOverlay(ref bitmap, ref mouseBrush, ref headsetBrush, mice.Any(), headsets.Any());
overlayModel.RenderOverlay(keyboardGraphics, ref mouseBrush, ref headsetBrush, mice.Any(),
headsets.Any());
}
// Update mice and headsets
@ -138,26 +151,10 @@ namespace Artemis.Managers
mouse.UpdateDevice(mouseBrush);
foreach (var headset in headsets)
headset.UpdateDevice(headsetBrush);
// If no bitmap was generated this frame is done
if (bitmap == null)
return;
// Fill the bitmap's background with black to avoid trailing colors on some keyboards
// Bitmaps needs to be disposd!
using (var fixedBmp = new Bitmap(bitmap.Width, bitmap.Height))
{
using (var g = Graphics.FromImage(fixedBmp))
{
g.Clear(Color.Black);
g.DrawImage(bitmap, 0, 0);
}
bitmap = fixedBmp;
// Update the keyboard
_deviceManager.ActiveKeyboard?.DrawBitmap(bitmap);
}
_deviceManager.ActiveKeyboard?.DrawBitmap(_keyboardBitmap);
}
}
}

View File

@ -13,9 +13,10 @@ namespace Artemis.Models
{
public delegate void SettingsUpdateHandler(EffectSettings settings);
public bool Initialized;
public MainManager MainManager;
public string Name;
public bool Initialized { get; set; }
public MainManager MainManager { get; set; }
public string Name { get; set; }
public int KeyboardScale { get; set; } = 4;
protected EffectModel(MainManager mainManager, IDataModel dataModel)
{
@ -36,10 +37,8 @@ namespace Artemis.Models
public abstract void Update();
// Called after every update
public virtual void Render(out Bitmap keyboard, out Brush mouse, out Brush headset, bool renderMice,
bool renderHeadsets)
public virtual void Render(Graphics keyboard, out Brush mouse, out Brush headset, bool renderMice, bool renderHeadsets)
{
keyboard = null;
mouse = null;
headset = null;
@ -50,8 +49,7 @@ namespace Artemis.Models
var renderLayers = GetRenderLayers(renderMice, renderHeadsets);
// Render the keyboard layer-by-layer
keyboard = Profile.GenerateBitmap(renderLayers, DataModel,
MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(4), false, true);
Profile.DrawProfile(keyboard, renderLayers, DataModel, MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale), false, true);
// Render the first enabled mouse (will default to null if renderMice was false)
mouse = Profile.GenerateBrush(renderLayers.LastOrDefault(l => l.LayerType == LayerType.Mouse), DataModel);
// Render the first enabled headset (will default to null if renderHeadsets was false)

View File

@ -29,7 +29,7 @@ namespace Artemis.Models
}
}
public abstract void RenderOverlay(ref Bitmap keyboard, ref Brush mouse, ref Brush headset, bool renderMice,
public abstract void RenderOverlay(Graphics keyboard, ref Brush mouse, ref Brush headset, bool renderMice,
bool renderHeadsets);
}
}

View File

@ -66,7 +66,7 @@ namespace Artemis.Models.Profiles
Layers[i].Order = i;
}
public Bitmap GenerateBitmap<T>(Rect keyboardRect, IDataModel dataModel, bool preview,
public void DrawProfile<T>(Graphics keyboard, Rect keyboardRect, IDataModel dataModel, bool preview,
bool updateAnimations)
{
var visual = new DrawingVisual();
@ -84,7 +84,10 @@ namespace Artemis.Models.Profiles
c.Pop();
}
return ImageUtilities.DrawinVisualToBitmap(visual, keyboardRect);
//TODO DarthAffe 13.06.2016: This is just to make it work
//It would be better to somehow draw directly but I don't really understand dat visual stuff right now :p
using (Bitmap bmp = ImageUtilities.DrawinVisualToBitmap(visual, keyboardRect))
keyboard.DrawImage(bmp, new PointF(0, 0));
}
public Brush GenerateBrush<T>(IDataModel dataModel, LayerType type, bool preview, bool updateAnimations)
@ -173,15 +176,15 @@ namespace Artemis.Models.Profiles
}
/// <summary>
/// Generates a bitmap showing all the provided layers of type Keyboard and KeyboardGif
/// Draw all the provided layers of type Keyboard and KeyboardGif
/// </summary>
/// <param name="keyboard">The graphics to draw on</param>
/// <param name="renderLayers">The layers to render</param>
/// <param name="dataModel">The data model to base the layer's properties on</param>
/// <param name="keyboardRect">A rectangle matching the current keyboard's size on a scale of 4, used for clipping</param>
/// <param name="preview">Indicates wheter the layer is drawn as a preview, ignoring dynamic properties</param>
/// <param name="updateAnimations">Wheter or not to update the layer's animations</param>
/// <returns>The generated bitmap</returns>
internal Bitmap GenerateBitmap(List<LayerModel> renderLayers, IDataModel dataModel, Rect keyboardRect,
internal void DrawProfile(Graphics keyboard, List<LayerModel> renderLayers, IDataModel dataModel, Rect keyboardRect,
bool preview,
bool updateAnimations)
{
@ -204,7 +207,10 @@ namespace Artemis.Models.Profiles
c.Pop();
}
return ImageUtilities.DrawinVisualToBitmap(visual, keyboardRect);
//TODO DarthAffe 13.06.2016: This is just to make it work
//It would be better to somehow draw directly but I don't really understand dat visual stuff right now :p
using (Bitmap bmp = ImageUtilities.DrawinVisualToBitmap(visual, keyboardRect))
keyboard.DrawImage(bmp, new PointF(0, 0));
}
/// <summary>

View File

@ -30,14 +30,11 @@ namespace Artemis.Modules.Effects.AudioVisualizer
Name = "Audiovisualizer";
DeviceIds = new List<string>();
SpectrumData = new List<byte>();
Scale = 4;
Initialized = false;
}
public int Lines { get; set; }
public int Scale { get; set; }
public AudioVisualizerSettings Settings { get; set; }
public List<byte> SpectrumData { get; set; }
public List<KeyboardRectangle> SoundRectangles { get; set; }
@ -80,7 +77,8 @@ namespace Artemis.Modules.Effects.AudioVisualizer
ColorHelpers.ToDrawingColor(Settings.MiddleColor),
ColorHelpers.ToDrawingColor(Settings.BottomColor)
},
LinearGradientMode.Vertical) {ContainedBrush = false, Height = 0});
LinearGradientMode.Vertical)
{ ContainedBrush = false, Height = 0 });
}
_sensitivity = Settings.Sensitivity;
_fromBottom = Settings.FromBottom;
@ -125,17 +123,17 @@ namespace Artemis.Modules.Effects.AudioVisualizer
// Apply Sensitivity setting
height = height * _sensitivity;
var keyboardHeight =
(int) Math.Round(MainManager.DeviceManager.ActiveKeyboard.Height/100.00*height*Scale);
(int)Math.Round(MainManager.DeviceManager.ActiveKeyboard.Height / 100.00 * height * KeyboardScale);
if (keyboardHeight > SoundRectangles[i].Height)
SoundRectangles[i].Height = keyboardHeight;
else
SoundRectangles[i].Height = SoundRectangles[i].Height - Settings.FadeSpeed;
// Apply Bars setting
SoundRectangles[i].X = i*Scale;
SoundRectangles[i].Width = Scale;
SoundRectangles[i].X = i * KeyboardScale;
SoundRectangles[i].Width = KeyboardScale;
if (_fromBottom)
SoundRectangles[i].Y = MainManager.DeviceManager.ActiveKeyboard.Height*Scale -
SoundRectangles[i].Y = MainManager.DeviceManager.ActiveKeyboard.Height * KeyboardScale -
SoundRectangles[i].Height;
}
_generating = false;
@ -190,10 +188,9 @@ namespace Artemis.Modules.Effects.AudioVisualizer
return null;
}
public override void Render(out Bitmap keyboard, out Brush mouse, out Brush headset, bool renderMice,
public override void Render(Graphics keyboard, out Brush mouse, out Brush headset, bool renderMice,
bool renderHeadsets)
{
keyboard = null;
mouse = null;
headset = null;
@ -203,12 +200,8 @@ namespace Artemis.Modules.Effects.AudioVisualizer
// Lock the _spectrumData array while busy with it
_generating = true;
keyboard = MainManager.DeviceManager.ActiveKeyboard.KeyboardBitmap(Scale);
using (var g = Graphics.FromImage(keyboard))
{
foreach (var soundRectangle in SoundRectangles)
soundRectangle.Draw(g);
}
soundRectangle.Draw(keyboard);
_generating = false;
}

View File

@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows;
using Artemis.Managers;
using Artemis.Models;
@ -17,10 +16,7 @@ namespace Artemis.Modules.Effects.Bubbles
private static readonly Random _random = new Random();
private const int SCALE = 25;
private readonly List<Bubble> _bubbles = new List<Bubble>();
private Bitmap _bitmap;
public BubblesSettings Settings { get; }
@ -32,6 +28,7 @@ namespace Artemis.Modules.Effects.Bubbles
: base(mainManager, null)
{
Name = "Bubbles";
KeyboardScale = 25;
Settings = settings;
Initialized = false;
}
@ -42,8 +39,7 @@ namespace Artemis.Modules.Effects.Bubbles
public override void Enable()
{
Rect rect = MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(SCALE);
_bitmap = MainManager.DeviceManager.ActiveKeyboard.KeyboardBitmap(SCALE);
Rect rect = MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale);
for (int i = 0; i < Settings.BubbleCount; i++)
{
@ -62,14 +58,13 @@ namespace Artemis.Modules.Effects.Bubbles
public override void Dispose()
{
_bitmap?.Dispose();
_bubbles.Clear();
Initialized = false;
}
public override void Update()
{
Rect keyboardRectangle = MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(SCALE);
Rect keyboardRectangle = MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale);
foreach (Bubble bubble in _bubbles)
{
if (Settings.IsShiftColors)
@ -80,20 +75,13 @@ namespace Artemis.Modules.Effects.Bubbles
}
}
public override void Render(out Bitmap keyboard, out Brush mouse, out Brush headset, bool renderMice, bool renderHeadsets)
public override void Render(Graphics keyboard, out Brush mouse, out Brush headset, bool renderMice, bool renderHeadsets)
{
keyboard = _bitmap;
mouse = null;
headset = null;
using (Graphics g = Graphics.FromImage(keyboard))
{
g.Clear(Color.Transparent);
g.SmoothingMode = SmoothingMode.None;
foreach (Bubble bubble in _bubbles)
bubble.Draw(g);
}
bubble.Draw(keyboard);
}
public override List<LayerModel> GetRenderLayers(bool renderMice, bool renderHeadsets)

View File

@ -35,10 +35,9 @@ namespace Artemis.Modules.Effects.ProfilePreview
return Profile.GetRenderLayers<ProfilePreviewDataModel>(DataModel, renderMice, renderHeadsets, true);
}
public override void Render(out Bitmap keyboard, out Brush mouse, out Brush headset, bool renderMice,
public override void Render(Graphics keyboard, out Brush mouse, out Brush headset, bool renderMice,
bool renderHeadsets)
{
keyboard = null;
mouse = null;
headset = null;
@ -49,8 +48,7 @@ namespace Artemis.Modules.Effects.ProfilePreview
var renderLayers = GetRenderLayers(renderMice, renderHeadsets);
// Render the keyboard layer-by-layer
keyboard = Profile?.GenerateBitmap(renderLayers, DataModel,
MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(4), true, true);
Profile?.DrawProfile(keyboard, renderLayers, DataModel, MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale), true, true);
// Render the first enabled mouse (will default to null if renderMice was false)
mouse = Profile?.GenerateBrush(renderLayers.LastOrDefault(l => l.LayerType == LayerType.Mouse), DataModel);
// Render the first enabled headset (will default to null if renderHeadsets was false)

View File

@ -25,11 +25,8 @@ namespace Artemis.Modules.Effects.TypeWave
_randomColor = Color.Red;
Settings = settings;
Initialized = false;
Scale = 4;
}
public int Scale { get; set; }
public TypeWaveSettings Settings { get; set; }
public override void Dispose()
@ -49,8 +46,8 @@ namespace Artemis.Modules.Effects.TypeWave
return;
_waves.Add(Settings.IsRandomColors
? new Wave(new Point(keyMatch.PosX*Scale, keyMatch.PosY*Scale), 0, _randomColor)
: new Wave(new Point(keyMatch.PosX*Scale, keyMatch.PosY*Scale), 0,
? new Wave(new Point(keyMatch.PosX * KeyboardScale, keyMatch.PosY * KeyboardScale), 0, _randomColor)
: new Wave(new Point(keyMatch.PosX * KeyboardScale, keyMatch.PosY * KeyboardScale), 0,
ColorHelpers.ToDrawingColor(Settings.WaveColor)));
}
@ -74,7 +71,7 @@ namespace Artemis.Modules.Effects.TypeWave
// TODO: Get from settings
var fps = 25;
_waves[i].Size += Settings.SpreadSpeed*Scale;
_waves[i].Size += Settings.SpreadSpeed * KeyboardScale;
if (Settings.IsShiftColors)
_waves[i].Color = ColorHelpers.ShiftColor(_waves[i].Color, Settings.ShiftColorSpeed);
@ -98,22 +95,15 @@ namespace Artemis.Modules.Effects.TypeWave
return null;
}
public override void Render(out Bitmap keyboard, out Brush mouse, out Brush headset, bool renderMice,
public override void Render(Graphics keyboard, out Brush mouse, out Brush headset, bool renderMice,
bool renderHeadsets)
{
keyboard = null;
mouse = null;
headset = null;
if (_waves.Count == 0)
return;
keyboard = MainManager.DeviceManager.ActiveKeyboard.KeyboardBitmap(Scale);
using (var g = Graphics.FromImage(keyboard))
{
g.Clear(Color.Transparent);
g.SmoothingMode = SmoothingMode.HighQuality;
// Don't want a for-each, collection is changed in different thread
// ReSharper disable once ForCanBeConvertedToForeach
for (var i = 0; i < _waves.Count; i++)
@ -136,16 +126,15 @@ namespace Artemis.Modules.Effects.TypeWave
CenterColor = fillColor
};
g.FillPath(pthGrBrush, path);
keyboard.FillPath(pthGrBrush, path);
pthGrBrush.FocusScales = new PointF(0.3f, 0.8f);
g.FillPath(pthGrBrush, path);
g.DrawEllipse(new Pen(pthGrBrush, 1), _waves[i].Point.X - _waves[i].Size/2,
keyboard.FillPath(pthGrBrush, path);
keyboard.DrawEllipse(new Pen(pthGrBrush, 1), _waves[i].Point.X - _waves[i].Size / 2,
_waves[i].Point.Y - _waves[i].Size / 2, _waves[i].Size, _waves[i].Size);
}
}
}
}
public class Wave
{

View File

@ -64,19 +64,6 @@ namespace Artemis.Modules.Overlays.VolumeDisplay
}
}
public Bitmap GenerateBitmap(Bitmap bitmap)
{
if (VolumeDisplay == null)
return bitmap;
if (VolumeDisplay.Ttl < 1)
return bitmap;
using (var g = Graphics.FromImage(bitmap))
VolumeDisplay.Draw(g);
return bitmap;
}
public override List<LayerModel> GetRenderLayers(bool renderMice, bool renderHeadsets)
{
return null;
@ -91,10 +78,11 @@ namespace Artemis.Modules.Overlays.VolumeDisplay
VolumeDisplay.Transparancy = 255;
}
public override void RenderOverlay(ref Bitmap keyboard, ref Brush mouse, ref Brush headset, bool renderMice,
public override void RenderOverlay(Graphics keyboard, ref Brush mouse, ref Brush headset, bool renderMice,
bool renderHeadsets)
{
keyboard = GenerateBitmap(keyboard ?? MainManager.DeviceManager.ActiveKeyboard.KeyboardBitmap(4));
if (VolumeDisplay != null && VolumeDisplay.Ttl >= 1)
VolumeDisplay.Draw(keyboard);
}
}
}