Browse Source

Fixed bunch of memory leaks

flabbet 1 year ago
parent
commit
cf4e45e8e6

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/CombineSeparate/CombineChannelsNode.cs

@@ -47,7 +47,7 @@ public class CombineChannelsNode : Node
         if (size == VecI.Zero)
             return null;
         
-        var workingSurface = new Texture(size);
+        var workingSurface = RequestTexture(0, size); 
 
         if (Red.Value is { } red)
         {

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/DebugBlendModeNode.cs

@@ -35,7 +35,7 @@ public class DebugBlendModeNode : Node
             return null;
 
         var size = new VecI(Math.Max(src.Size.X, dst.Size.X), int.Max(src.Size.Y, dst.Size.Y));
-        var workingSurface = new Texture(size);
+        var workingSurface = RequestTexture(0, size);
 
         workingSurface.DrawingSurface.Canvas.DrawSurface(dst.DrawingSurface, 0, 0, context.BlendModeOpacityPaint);
 

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/EllipseNode.cs

@@ -52,7 +52,7 @@ public class EllipseNode : Node
             
             workingImage = new ChunkyImage(targetDimensions);
 
-            targetSurface = new Texture(targetDimensions);
+            targetSurface = RequestTexture(0, targetDimensions);
         }
 
         if (radius != _lastRadius || StrokeColor.Value != _lastStrokeColor || FillColor.Value != _lastFillColor ||

+ 2 - 2
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/EmptyImageNode.cs

@@ -31,8 +31,8 @@ public class CreateImageNode : Node
         {
             return null;
         }
-        
-        var surface = new Texture(Size.Value);
+
+        var surface = RequestTexture(0, Size.Value); 
 
         _paint.Color = Fill.Value;
         surface.DrawingSurface.Canvas.DrawPaint(_paint);

+ 16 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/FilterNodes/ColorMatrixFilterNode.cs

@@ -8,12 +8,27 @@ public class ColorMatrixFilterNode : FilterNode
 {
     public InputProperty<ColorMatrix> Matrix { get; }
 
+    private ColorFilter filter;
+    private ColorMatrix lastMatrix;
+    
     public ColorMatrixFilterNode()
     {
         Matrix = CreateInput(nameof(Matrix), "MATRIX", ColorMatrix.Identity);
     }
 
-    protected override ColorFilter? GetColorFilter() => ColorFilter.CreateColorMatrix(Matrix.Value);
+    protected override ColorFilter? GetColorFilter()
+    {
+        if (Matrix.Value.Equals(lastMatrix))
+        {
+            return filter;
+        }
+        
+        lastMatrix = Matrix.Value;
+        filter?.Dispose();
+        
+        filter = ColorFilter.CreateColorMatrix(Matrix.Value);
+        return filter;
+    }
 
     public override Node CreateCopy() => new ColorMatrixFilterNode();
 }

+ 33 - 5
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/FilterNodes/GrayscaleNode.cs

@@ -18,6 +18,13 @@ public class GrayscaleNode : FilterNode
     // TODO: Hide when Mode != Custom
     public InputProperty<VecD3> CustomWeight { get; }
     
+    private GrayscaleMode lastMode;
+    private double lastFactor;
+    private bool lastNormalize;
+    private VecD3 lastCustomWeight;
+    
+    private ColorFilter? filter;
+    
     public GrayscaleNode()
     {
         Mode = CreateInput("Mode", "MODE", GrayscaleMode.Weighted);
@@ -27,12 +34,33 @@ public class GrayscaleNode : FilterNode
         CustomWeight = CreateInput("CustomWeight", "WEIGHT_FACTOR", new VecD3(1, 1, 1));
     }
 
-    protected override ColorFilter GetColorFilter() => ColorFilter.CreateColorMatrix(Mode.Value switch
+    protected override ColorFilter GetColorFilter()
     {
-        GrayscaleMode.Weighted => UseFactor(WeightedMatrix),
-        GrayscaleMode.Average => UseFactor(AverageMatrix),
-        GrayscaleMode.Custom => UseFactor(ColorMatrix.WeightedGrayscale(GetAdjustedCustomWeight()) + ColorMatrix.UseAlpha)
-    });
+        if (Mode.Value == lastMode 
+            && Factor.Value == lastFactor 
+            && Normalize.Value == lastNormalize &&
+            CustomWeight.Value == lastCustomWeight)
+        {
+            return filter;
+        }
+        
+        lastMode = Mode.Value;
+        lastFactor = Factor.Value;
+        lastNormalize = Normalize.Value;
+        lastCustomWeight = CustomWeight.Value;
+        
+        filter?.Dispose();
+        
+        filter = ColorFilter.CreateColorMatrix(Mode.Value switch
+        {
+            GrayscaleMode.Weighted => UseFactor(WeightedMatrix),
+            GrayscaleMode.Average => UseFactor(AverageMatrix),
+            GrayscaleMode.Custom => UseFactor(ColorMatrix.WeightedGrayscale(GetAdjustedCustomWeight()) +
+                                              ColorMatrix.UseAlpha)
+        });
+        
+        return filter;
+    }
 
     private ColorMatrix UseFactor(ColorMatrix target)
     {

+ 12 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/FilterNodes/KernelFilterNode.cs

@@ -19,6 +19,9 @@ public class KernelFilterNode : FilterNode
 
     public InputProperty<bool> OnAlpha { get; }
 
+    private ImageFilter filter;
+    private Kernel lastKernel;
+
     public KernelFilterNode()
     {
         Kernel = CreateInput(nameof(Kernel), "KERNEL", Numerics.Kernel.Identity(3, 3));
@@ -32,9 +35,17 @@ public class KernelFilterNode : FilterNode
     {
         var kernel = Kernel.Value;
         
+        if (kernel.Equals(lastKernel))
+            return filter;
+        
+        lastKernel = kernel;
+        
+        filter?.Dispose();
+        
         var kernelOffset = new VecI(kernel.RadiusX, kernel.RadiusY);
         
-        return ImageFilter.CreateMatrixConvolution(kernel, (float)Gain.Value, (float)Bias.Value, kernelOffset, Tile.Value, OnAlpha.Value);
+        filter = ImageFilter.CreateMatrixConvolution(kernel, (float)Gain.Value, (float)Bias.Value, kernelOffset, Tile.Value, OnAlpha.Value);
+        return filter;
     }
 
     public override Node CreateCopy() => new KernelFilterNode();

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/NoiseNode.cs

@@ -82,7 +82,7 @@ public class NoiseNode : Node
             return null;
         }
         
-        var workingSurface = new Texture(size);
+        var workingSurface = RequestTexture(0, size); 
        
         workingSurface.DrawingSurface.Canvas.DrawPaint(paint);
 

+ 8 - 1
src/PixiEditor.Numerics/Kernel.cs

@@ -2,7 +2,7 @@
 
 namespace PixiEditor.Numerics;
 
-public class Kernel : ICloneable
+public class Kernel : ICloneable, IEquatable<Kernel>
 {
     private KernelArray _buffer;
 
@@ -83,4 +83,11 @@ public class Kernel : ICloneable
         AsSpan().CopyTo(values);
         return new Kernel(Width, Height, values);
     }
+
+    public bool Equals(Kernel? other)
+    {
+        if (ReferenceEquals(null, other)) return false;
+        if (ReferenceEquals(this, other)) return true;
+        return Width == other.Width && Height == other.Height && _buffer.Equals(other._buffer);
+    }
 }

+ 7 - 1
src/PixiEditor.Numerics/KernelArray.cs

@@ -1,6 +1,6 @@
 namespace PixiEditor.Numerics;
 
-public class KernelArray
+public class KernelArray : IEquatable<KernelArray>
 {
     private readonly float[] _buffer;
     
@@ -49,4 +49,10 @@ public class KernelArray
     }
 
     public ReadOnlySpan<float> AsSpan() => _buffer.AsSpan();
+    public bool Equals(KernelArray? other)
+    {
+        if (ReferenceEquals(null, other)) return false;
+        if (ReferenceEquals(this, other)) return true;
+        return _buffer.SequenceEqual(other._buffer) && Width == other.Width && Height == other.Height;
+    }
 }

+ 2 - 8
src/PixiEditor/Models/DocumentModels/DocumentUpdater.cs

@@ -358,7 +358,7 @@ internal class DocumentUpdater
         {
             surf.Dispose();
             VecI size = (VecI)(info.Size * res.Multiplier());
-            doc.Surfaces[res] = new Texture(new VecI(Math.Max(size.X, 1), Math.Max(size.Y, 1))); //TODO: Bgra8888 was here
+            doc.Surfaces[res] = new Texture(new VecI(Math.Max(size.X, 1), Math.Max(size.Y, 1)));
         }
 
         doc.SetSize(info.Size);
@@ -367,13 +367,7 @@ internal class DocumentUpdater
 
         VecI documentPreviewSize = StructureHelpers.CalculatePreviewSize(info.Size);
         doc.PreviewSurface.Dispose();
-        doc.PreviewSurface = new Texture(documentPreviewSize); //TODO: Bgra8888 was here
-
-        // TODO: Make sure property changed events are raised internally
-        // UPDATE: I think I did, but I'll leave it commented out for now
-        /*doc.OnPropertyChanged(nameof(doc.LazyBitmaps));
-        doc.OnPropertyChanged(nameof(doc.PreviewBitmap));
-        doc.InternalRaiseSizeChanged(new DocumentSizeChangedEventArgs(doc, oldSize, info.Size));*/
+        doc.PreviewSurface = new Texture(documentPreviewSize);
     }
 
     private void ProcessCreateStructureMember(CreateStructureMember_ChangeInfo info)