mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Rendering - Made the way layering is rendered 99.5% less stupid
This commit is contained in:
parent
c444ff4e59
commit
fa49424cf6
16
src/Artemis.Core/Extensions/SKPaintExtensions.cs
Normal file
16
src/Artemis.Core/Extensions/SKPaintExtensions.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using SkiaSharp;
|
||||||
|
|
||||||
|
namespace Artemis.Core
|
||||||
|
{
|
||||||
|
internal static class SKPaintExtensions
|
||||||
|
{
|
||||||
|
internal static void DisposeSelfAndProperties(this SKPaint paint)
|
||||||
|
{
|
||||||
|
paint.ImageFilter?.Dispose();
|
||||||
|
paint.ColorFilter?.Dispose();
|
||||||
|
paint.MaskFilter?.Dispose();
|
||||||
|
paint.Shader?.Dispose();
|
||||||
|
paint.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -168,7 +168,7 @@ namespace Artemis.Core
|
|||||||
#region Rendering
|
#region Rendering
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Render(SKCanvas canvas)
|
public override void Render(SKCanvas canvas, SKPoint basePosition)
|
||||||
{
|
{
|
||||||
if (Disposed)
|
if (Disposed)
|
||||||
throw new ObjectDisposedException("Folder");
|
throw new ObjectDisposedException("Folder");
|
||||||
@ -189,41 +189,38 @@ namespace Artemis.Core
|
|||||||
baseLayerEffect.Update(Timeline.Delta.TotalSeconds);
|
baseLayerEffect.Update(Timeline.Delta.TotalSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SKPaint layerPaint = new();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
canvas.Save();
|
SKRect rendererBounds = SKRect.Create(0, 0, Path.Bounds.Width, Path.Bounds.Height);
|
||||||
Renderer.Open(Path, Parent as Folder);
|
|
||||||
if (Renderer.Surface == null || Renderer.Path == null || Renderer.Paint == null)
|
|
||||||
throw new ArtemisCoreException("Failed to open folder render context");
|
|
||||||
|
|
||||||
SKRect rendererBounds = Renderer.Path.Bounds;
|
|
||||||
foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled))
|
foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled))
|
||||||
baseLayerEffect.PreProcess(Renderer.Surface.Canvas, rendererBounds, Renderer.Paint);
|
baseLayerEffect.PreProcess(canvas, rendererBounds, layerPaint);
|
||||||
|
|
||||||
|
canvas.SaveLayer(layerPaint);
|
||||||
|
canvas.Translate(Path.Bounds.Left - basePosition.X, Path.Bounds.Top - basePosition.Y);
|
||||||
|
|
||||||
// If required, apply the opacity override of the module to the root folder
|
// If required, apply the opacity override of the module to the root folder
|
||||||
if (IsRootFolder && Profile.Module.OpacityOverride < 1)
|
if (IsRootFolder && Profile.Module.OpacityOverride < 1)
|
||||||
{
|
{
|
||||||
double multiplier = Easings.SineEaseInOut(Profile.Module.OpacityOverride);
|
double multiplier = Easings.SineEaseInOut(Profile.Module.OpacityOverride);
|
||||||
Renderer.Paint.Color = Renderer.Paint.Color.WithAlpha((byte) (Renderer.Paint.Color.Alpha * multiplier));
|
layerPaint.Color = layerPaint.Color.WithAlpha((byte) (layerPaint.Color.Alpha * multiplier));
|
||||||
}
|
}
|
||||||
|
|
||||||
// No point rendering if the alpha was set to zero by one of the effects
|
// No point rendering if the alpha was set to zero by one of the effects
|
||||||
if (Renderer.Paint.Color.Alpha == 0)
|
if (layerPaint.Color.Alpha == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Iterate the children in reverse because the first layer must be rendered last to end up on top
|
// Iterate the children in reverse because the first layer must be rendered last to end up on top
|
||||||
for (int index = Children.Count - 1; index > -1; index--)
|
for (int index = Children.Count - 1; index > -1; index--)
|
||||||
Children[index].Render(Renderer.Surface.Canvas);
|
Children[index].Render(canvas, new SKPoint(Path.Bounds.Left, Path.Bounds.Top));
|
||||||
|
|
||||||
foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled))
|
foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled))
|
||||||
baseLayerEffect.PostProcess(Renderer.Surface.Canvas, rendererBounds, Renderer.Paint);
|
baseLayerEffect.PostProcess(canvas, rendererBounds, layerPaint);
|
||||||
|
|
||||||
canvas.DrawSurface(Renderer.Surface, Renderer.TargetLocation, Renderer.Paint);
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
canvas.Restore();
|
canvas.Restore();
|
||||||
Renderer.Close();
|
layerPaint.DisposeSelfAndProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
Timeline.ClearDelta();
|
Timeline.ClearDelta();
|
||||||
@ -239,7 +236,6 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
foreach (ProfileElement profileElement in Children)
|
foreach (ProfileElement profileElement in Children)
|
||||||
profileElement.Dispose();
|
profileElement.Dispose();
|
||||||
Renderer.Dispose();
|
|
||||||
|
|
||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -154,7 +154,6 @@ namespace Artemis.Core
|
|||||||
_layerBrush?.Dispose();
|
_layerBrush?.Dispose();
|
||||||
_general.Dispose();
|
_general.Dispose();
|
||||||
_transform.Dispose();
|
_transform.Dispose();
|
||||||
Renderer.Dispose();
|
|
||||||
|
|
||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
}
|
}
|
||||||
@ -278,7 +277,7 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Render(SKCanvas canvas)
|
public override void Render(SKCanvas canvas, SKPoint basePosition)
|
||||||
{
|
{
|
||||||
if (Disposed)
|
if (Disposed)
|
||||||
throw new ObjectDisposedException("Layer");
|
throw new ObjectDisposedException("Layer");
|
||||||
@ -290,9 +289,9 @@ namespace Artemis.Core
|
|||||||
if (LayerBrush == null || LayerBrush?.BaseProperties?.PropertiesInitialized == false)
|
if (LayerBrush == null || LayerBrush?.BaseProperties?.PropertiesInitialized == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
RenderTimeline(Timeline, canvas);
|
RenderTimeline(Timeline, canvas, basePosition);
|
||||||
foreach (Timeline extraTimeline in Timeline.ExtraTimelines.ToList())
|
foreach (Timeline extraTimeline in Timeline.ExtraTimelines.ToList())
|
||||||
RenderTimeline(extraTimeline, canvas);
|
RenderTimeline(extraTimeline, canvas, basePosition);
|
||||||
Timeline.ClearDelta();
|
Timeline.ClearDelta();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,7 +312,7 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RenderTimeline(Timeline timeline, SKCanvas canvas)
|
private void RenderTimeline(Timeline timeline, SKCanvas canvas, SKPoint basePosition)
|
||||||
{
|
{
|
||||||
if (Path == null || LayerBrush == null)
|
if (Path == null || LayerBrush == null)
|
||||||
throw new ArtemisCoreException("The layer is not yet ready for rendering");
|
throw new ArtemisCoreException("The layer is not yet ready for rendering");
|
||||||
@ -326,22 +325,27 @@ namespace Artemis.Core
|
|||||||
if (LayerBrush?.BrushType != LayerBrushType.Regular)
|
if (LayerBrush?.BrushType != LayerBrushType.Regular)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
SKPaint layerPaint = new();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
canvas.Save();
|
canvas.Save();
|
||||||
Renderer.Open(Path, Parent as Folder);
|
canvas.Translate(Path.Bounds.Left - basePosition.X, Path.Bounds.Top - basePosition.Y);
|
||||||
if (Renderer.Surface == null || Renderer.Path == null || Renderer.Paint == null)
|
using SKPath clipPath = new(Path);
|
||||||
throw new ArtemisCoreException("Failed to open layer render context");
|
clipPath.Transform(SKMatrix.CreateTranslation(Path.Bounds.Left * -1, Path.Bounds.Top * -1));
|
||||||
|
canvas.ClipPath(clipPath);
|
||||||
|
|
||||||
|
SKRect layerBounds = SKRect.Create(0, 0, Path.Bounds.Width, Path.Bounds.Height);
|
||||||
|
|
||||||
// Apply blend mode and color
|
// Apply blend mode and color
|
||||||
Renderer.Paint.BlendMode = General.BlendMode.CurrentValue;
|
layerPaint.BlendMode = General.BlendMode.CurrentValue;
|
||||||
Renderer.Paint.Color = new SKColor(0, 0, 0, (byte) (Transform.Opacity.CurrentValue * 2.55f));
|
layerPaint.Color = new SKColor(0, 0, 0, (byte) (Transform.Opacity.CurrentValue * 2.55f));
|
||||||
|
|
||||||
using SKPath renderPath = new();
|
using SKPath renderPath = new();
|
||||||
|
|
||||||
if (General.ShapeType.CurrentValue == LayerShapeType.Rectangle)
|
if (General.ShapeType.CurrentValue == LayerShapeType.Rectangle)
|
||||||
renderPath.AddRect(Renderer.Path.Bounds);
|
renderPath.AddRect(layerBounds);
|
||||||
else
|
else
|
||||||
renderPath.AddOval(Renderer.Path.Bounds);
|
renderPath.AddOval(layerBounds);
|
||||||
|
|
||||||
if (General.TransformMode.CurrentValue == LayerTransformMode.Normal)
|
if (General.TransformMode.CurrentValue == LayerTransformMode.Normal)
|
||||||
{
|
{
|
||||||
@ -356,54 +360,50 @@ namespace Artemis.Core
|
|||||||
if (LayerBrush.SupportsTransformation)
|
if (LayerBrush.SupportsTransformation)
|
||||||
{
|
{
|
||||||
SKMatrix rotationMatrix = GetTransformMatrix(true, false, false, true);
|
SKMatrix rotationMatrix = GetTransformMatrix(true, false, false, true);
|
||||||
Renderer.Surface.Canvas.SetMatrix(Renderer.Surface.Canvas.TotalMatrix.PreConcat(rotationMatrix));
|
canvas.SetMatrix(canvas.TotalMatrix.PreConcat(rotationMatrix));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a brush is a bad boy and tries to color outside the lines, ensure that its clipped off
|
DelegateRendering(canvas, renderPath, renderPath.Bounds, layerPaint);
|
||||||
Renderer.Surface.Canvas.ClipPath(renderPath);
|
|
||||||
DelegateRendering(renderPath.Bounds);
|
|
||||||
}
|
}
|
||||||
else if (General.TransformMode.CurrentValue == LayerTransformMode.Clip)
|
else if (General.TransformMode.CurrentValue == LayerTransformMode.Clip)
|
||||||
{
|
{
|
||||||
SKMatrix renderPathMatrix = GetTransformMatrix(true, true, true, true);
|
SKMatrix renderPathMatrix = GetTransformMatrix(true, true, true, true);
|
||||||
renderPath.Transform(renderPathMatrix);
|
renderPath.Transform(renderPathMatrix);
|
||||||
|
|
||||||
// If a brush is a bad boy and tries to color outside the lines, ensure that its clipped off
|
DelegateRendering(canvas, renderPath, layerBounds, layerPaint);
|
||||||
Renderer.Surface.Canvas.ClipPath(renderPath);
|
|
||||||
DelegateRendering(Renderer.Path.Bounds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas.DrawSurface(Renderer.Surface, Renderer.TargetLocation, Renderer.Paint);
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
try
|
canvas.Restore();
|
||||||
{
|
layerPaint.DisposeSelfAndProperties();
|
||||||
canvas.Restore();
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// ignored
|
|
||||||
}
|
|
||||||
|
|
||||||
Renderer.Close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DelegateRendering(SKRect bounds)
|
private void DelegateRendering(SKCanvas canvas, SKPath renderPath, SKRect bounds, SKPaint layerPaint)
|
||||||
{
|
{
|
||||||
if (LayerBrush == null)
|
if (LayerBrush == null)
|
||||||
throw new ArtemisCoreException("The layer is not yet ready for rendering");
|
throw new ArtemisCoreException("The layer is not yet ready for rendering");
|
||||||
if (Renderer.Surface == null || Renderer.Paint == null)
|
|
||||||
throw new ArtemisCoreException("Failed to open layer render context");
|
|
||||||
|
|
||||||
foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled))
|
foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled))
|
||||||
baseLayerEffect.PreProcess(Renderer.Surface.Canvas, bounds, Renderer.Paint);
|
baseLayerEffect.PreProcess(canvas, bounds, layerPaint);
|
||||||
|
|
||||||
LayerBrush.InternalRender(Renderer.Surface.Canvas, bounds, Renderer.Paint);
|
try
|
||||||
|
{
|
||||||
|
canvas.SaveLayer(layerPaint);
|
||||||
|
|
||||||
foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled))
|
// If a brush is a bad boy and tries to color outside the lines, ensure that its clipped off
|
||||||
baseLayerEffect.PostProcess(Renderer.Surface.Canvas, bounds, Renderer.Paint);
|
canvas.ClipPath(renderPath);
|
||||||
|
LayerBrush.InternalRender(canvas, bounds, layerPaint);
|
||||||
|
|
||||||
|
foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled))
|
||||||
|
baseLayerEffect.PostProcess(canvas, bounds, layerPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
canvas.Restore();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void CalculateRenderProperties()
|
internal void CalculateRenderProperties()
|
||||||
|
|||||||
@ -81,7 +81,7 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Render(SKCanvas canvas)
|
public override void Render(SKCanvas canvas, SKPoint basePosition)
|
||||||
{
|
{
|
||||||
lock (_lock)
|
lock (_lock)
|
||||||
{
|
{
|
||||||
@ -91,7 +91,7 @@ namespace Artemis.Core
|
|||||||
throw new ArtemisCoreException($"Cannot render inactive profile: {this}");
|
throw new ArtemisCoreException($"Cannot render inactive profile: {this}");
|
||||||
|
|
||||||
foreach (ProfileElement profileElement in Children)
|
foreach (ProfileElement profileElement in Children)
|
||||||
profileElement.Render(canvas);
|
profileElement.Render(canvas, basePosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -104,7 +104,7 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Renders the element
|
/// Renders the element
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract void Render(SKCanvas canvas);
|
public abstract void Render(SKCanvas canvas, SKPoint basePosition);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resets the internal state of the element
|
/// Resets the internal state of the element
|
||||||
|
|||||||
@ -19,7 +19,6 @@ namespace Artemis.Core
|
|||||||
internal RenderProfileElement(Profile profile) : base(profile)
|
internal RenderProfileElement(Profile profile) : base(profile)
|
||||||
{
|
{
|
||||||
Timeline = new Timeline();
|
Timeline = new Timeline();
|
||||||
Renderer = new Renderer();
|
|
||||||
ExpandedPropertyGroups = new List<string>();
|
ExpandedPropertyGroups = new List<string>();
|
||||||
LayerEffectsList = new List<BaseLayerEffect>();
|
LayerEffectsList = new List<BaseLayerEffect>();
|
||||||
|
|
||||||
@ -127,7 +126,6 @@ namespace Artemis.Core
|
|||||||
{
|
{
|
||||||
base.Parent = value;
|
base.Parent = value;
|
||||||
OnPropertyChanged(nameof(Parent));
|
OnPropertyChanged(nameof(Parent));
|
||||||
Renderer.Invalidate();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +142,6 @@ namespace Artemis.Core
|
|||||||
// I can't really be sure about the performance impact of calling Bounds often but
|
// I can't really be sure about the performance impact of calling Bounds often but
|
||||||
// SkiaSharp calls SkiaApi.sk_path_get_bounds (Handle, &rect); which sounds expensive
|
// SkiaSharp calls SkiaApi.sk_path_get_bounds (Handle, &rect); which sounds expensive
|
||||||
Bounds = value?.Bounds ?? SKRect.Empty;
|
Bounds = value?.Bounds ?? SKRect.Empty;
|
||||||
Renderer.Invalidate();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +154,6 @@ namespace Artemis.Core
|
|||||||
private set => SetAndNotify(ref _bounds, value);
|
private set => SetAndNotify(ref _bounds, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Renderer Renderer { get; }
|
|
||||||
|
|
||||||
#region Property group expansion
|
#region Property group expansion
|
||||||
|
|
||||||
|
|||||||
@ -108,5 +108,11 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
_disposed = true;
|
_disposed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~Renderer()
|
||||||
|
{
|
||||||
|
if (IsOpen)
|
||||||
|
Close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -177,7 +177,7 @@ namespace Artemis.Core.Modules
|
|||||||
lock (_lock)
|
lock (_lock)
|
||||||
{
|
{
|
||||||
// Render the profile
|
// Render the profile
|
||||||
ActiveProfile?.Render(canvas);
|
ActiveProfile?.Render(canvas, SKPoint.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
ProfileRendered(deltaTime, canvas, canvasInfo);
|
ProfileRendered(deltaTime, canvas, canvasInfo);
|
||||||
|
|||||||
@ -30,7 +30,7 @@ namespace Artemis.Core
|
|||||||
public void Render(double deltaTime, SKCanvas canvas)
|
public void Render(double deltaTime, SKCanvas canvas)
|
||||||
{
|
{
|
||||||
AnimationProfile.Update(deltaTime);
|
AnimationProfile.Update(deltaTime);
|
||||||
AnimationProfile.Render(canvas);
|
AnimationProfile.Render(canvas, SKPoint.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Profile CreateIntroProfile()
|
private Profile CreateIntroProfile()
|
||||||
|
|||||||
@ -90,9 +90,24 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
|
|||||||
|
|
||||||
private void CoreServiceOnFrameRendered(object sender, FrameRenderedEventArgs e)
|
private void CoreServiceOnFrameRendered(object sender, FrameRenderedEventArgs e)
|
||||||
{
|
{
|
||||||
|
using SKImage skImage = e.Texture.Surface.Snapshot();
|
||||||
|
SKImageInfo bitmapInfo = e.Texture.ImageInfo;
|
||||||
|
|
||||||
|
if (_frameTargetPath != null)
|
||||||
|
{
|
||||||
|
using (SKData data = skImage.Encode(SKEncodedImageFormat.Png, 100))
|
||||||
|
{
|
||||||
|
using (FileStream stream = File.OpenWrite(_frameTargetPath))
|
||||||
|
{
|
||||||
|
data.SaveTo(stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_frameTargetPath = null;
|
||||||
|
}
|
||||||
|
|
||||||
Execute.OnUIThreadSync(() =>
|
Execute.OnUIThreadSync(() =>
|
||||||
{
|
{
|
||||||
SKImageInfo bitmapInfo = e.Texture.ImageInfo;
|
|
||||||
RenderHeight = bitmapInfo.Height;
|
RenderHeight = bitmapInfo.Height;
|
||||||
RenderWidth = bitmapInfo.Width;
|
RenderWidth = bitmapInfo.Width;
|
||||||
|
|
||||||
@ -103,25 +118,10 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
using SKImage skImage = e.Texture.Surface.Snapshot();
|
|
||||||
|
|
||||||
if (_frameTargetPath != null)
|
|
||||||
{
|
|
||||||
using (SKData data = skImage.Encode(SKEncodedImageFormat.Png, 100))
|
|
||||||
{
|
|
||||||
using (FileStream stream = File.OpenWrite(_frameTargetPath))
|
|
||||||
{
|
|
||||||
data.SaveTo(stream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_frameTargetPath = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
SKImageInfo info = new(skImage.Width, skImage.Height);
|
|
||||||
writable.Lock();
|
writable.Lock();
|
||||||
using (SKPixmap pixmap = new(info, writable.BackBuffer, writable.BackBufferStride))
|
using (SKPixmap pixmap = new(bitmapInfo, writable.BackBuffer, writable.BackBufferStride))
|
||||||
{
|
{
|
||||||
|
// ReSharper disable once AccessToDisposedClosure - Looks fine
|
||||||
skImage.ReadPixels(pixmap, 0, 0);
|
skImage.ReadPixels(pixmap, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,6 +140,7 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
|
|||||||
_frames = 0;
|
_frames = 0;
|
||||||
_frameCountStart = DateTime.Now;
|
_frameCountStart = DateTime.Now;
|
||||||
}
|
}
|
||||||
|
|
||||||
_frames++;
|
_frames++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -225,6 +225,7 @@
|
|||||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAlwaysTreatStructAsNotReorderableMigration/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAlwaysTreatStructAsNotReorderableMigration/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=luma/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=luma/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=pixmap/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=snackbar/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=snackbar/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user