2
0
Эх сурвалжийг харах

Added reuse stamps optimization

Krzysztof Krysiński 3 долоо хоног өмнө
parent
commit
5e292692db

+ 1 - 1
src/Drawie

@@ -1 +1 @@
-Subproject commit 9a2cdc76832ebe004f553bfa9d6bc6eb731f54ca
+Subproject commit 772b36826e81d70ac0ebc824aa489d6d7d7ef438

+ 27 - 5
src/PixiEditor.ChangeableDocument/Changeables/Brushes/BrushEngine.cs

@@ -25,6 +25,8 @@ public class BrushEngine : IDisposable
     private VecD lastPos;
     private VecD lastPos;
     private VecD startPos;
     private VecD startPos;
     private int lastAppliedPointIndex = -1;
     private int lastAppliedPointIndex = -1;
+    private VecI lastCachedTexturePaintableSize = VecI.Zero;
+    private TexturePaintable? lastCachedTexturePaintable = null;
 
 
     private bool drawnOnce = false;
     private bool drawnOnce = false;
 
 
@@ -246,16 +248,19 @@ public class BrushEngine : IDisposable
 
 
         bool autoPosition = brushNode.AutoPosition.Value;
         bool autoPosition = brushNode.AutoPosition.Value;
         bool fitToStrokeSize = brushNode.FitToStrokeSize.Value;
         bool fitToStrokeSize = brushNode.FitToStrokeSize.Value;
-        float pressure = brushData.ForcePressure && brushNode.Pressure.Connection == null ? context.PointerInfo.Pressure : brushNode.Pressure.Value;
+        float pressure = brushData.ForcePressure && brushNode.Pressure.Connection == null
+            ? context.PointerInfo.Pressure
+            : brushNode.Pressure.Value;
         var content = brushNode.Content.Value;
         var content = brushNode.Content.Value;
         var contentTexture = brushNode.ContentTexture;
         var contentTexture = brushNode.ContentTexture;
         bool antiAliasing = brushData.AntiAliasing;
         bool antiAliasing = brushData.AntiAliasing;
         var fill = brushNode.Fill.Value;
         var fill = brushNode.Fill.Value;
         var stroke = brushNode.Stroke.Value;
         var stroke = brushNode.Stroke.Value;
         bool snapToPixels = brushNode.SnapToPixels.Value;
         bool snapToPixels = brushNode.SnapToPixels.Value;
+        bool canReuseStamps = brushNode.CanReuseStamps.Value;
 
 
         if (PaintBrush(target, autoPosition, vectorShape, rect, fitToStrokeSize, pressure, content, contentTexture,
         if (PaintBrush(target, autoPosition, vectorShape, rect, fitToStrokeSize, pressure, content, contentTexture,
-                brushNode.StampBlendMode.Value, antiAliasing, fill, stroke, snapToPixels))
+                brushNode.StampBlendMode.Value, antiAliasing, fill, stroke, snapToPixels, canReuseStamps))
         {
         {
             lastPos = point;
             lastPos = point;
         }
         }
@@ -264,7 +269,7 @@ public class BrushEngine : IDisposable
     public bool PaintBrush(ChunkyImage target, bool autoPosition, ShapeVectorData vectorShape,
     public bool PaintBrush(ChunkyImage target, bool autoPosition, ShapeVectorData vectorShape,
         RectD rect, bool fitToStrokeSize, float pressure, Painter? content,
         RectD rect, bool fitToStrokeSize, float pressure, Painter? content,
         Texture? contentTexture, DrawingApiBlendMode blendMode, bool antiAliasing, Paintable fill, Paintable stroke,
         Texture? contentTexture, DrawingApiBlendMode blendMode, bool antiAliasing, Paintable fill, Paintable stroke,
-        bool snapToPixels)
+        bool snapToPixels, bool canReuseStamps)
     {
     {
         var path = vectorShape.ToPath(true);
         var path = vectorShape.ToPath(true);
         if (path == null)
         if (path == null)
@@ -311,8 +316,24 @@ public class BrushEngine : IDisposable
         {
         {
             if (contentTexture != null)
             if (contentTexture != null)
             {
             {
-                TexturePaintable brushTexturePaintable = new(new Texture(contentTexture), true);
-                target.EnqueueDrawPath(path, brushTexturePaintable, vectorShape.StrokeWidth,
+                TexturePaintable brushPaintable;
+                if (canReuseStamps)
+                {
+                    if (lastCachedTexturePaintableSize != contentTexture.Size || lastCachedTexturePaintable == null)
+                    {
+                        lastCachedTexturePaintable?.Dispose();
+                        lastCachedTexturePaintable = new TexturePaintable(new Texture(contentTexture), false);
+                        lastCachedTexturePaintableSize = contentTexture.Size;
+                    }
+
+                    brushPaintable = lastCachedTexturePaintable;
+                }
+                else
+                {
+                    brushPaintable = new TexturePaintable(new Texture(contentTexture), true);
+                }
+
+                target.EnqueueDrawPath(path, brushPaintable, vectorShape.StrokeWidth,
                     StrokeCap.Butt, blendMode, PaintStyle.Fill, antiAliasing, null);
                     StrokeCap.Butt, blendMode, PaintStyle.Fill, antiAliasing, null);
             }
             }
         }
         }
@@ -495,5 +516,6 @@ public class BrushEngine : IDisposable
     public void Dispose()
     public void Dispose()
     {
     {
         cache.Dispose();
         cache.Dispose();
+        lastCachedTexturePaintable?.Dispose();
     }
     }
 }
 }

+ 3 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Brushes/BrushOutputNode.cs

@@ -47,6 +47,8 @@ public class BrushOutputNode : Node
     public InputProperty<bool> AlwaysClear { get; }
     public InputProperty<bool> AlwaysClear { get; }
     public InputProperty<bool> SnapToPixels { get; }
     public InputProperty<bool> SnapToPixels { get; }
     public InputProperty<string> Tags { get; }
     public InputProperty<string> Tags { get; }
+    // Indicate whether stamps from this brush can be reused when drawing with the same brush again. Optimization option.
+    public InputProperty<bool> CanReuseStamps { get; }
 
 
     public InputProperty<IReadOnlyNodeGraph> Previous { get; }
     public InputProperty<IReadOnlyNodeGraph> Previous { get; }
 
 
@@ -78,6 +80,7 @@ public class BrushOutputNode : Node
             Drawie.Backend.Core.Surfaces.BlendMode.SrcOver);
             Drawie.Backend.Core.Surfaces.BlendMode.SrcOver);
         StampBlendMode = CreateInput<Drawie.Backend.Core.Surfaces.BlendMode>("StampBlendMode", "STAMP_BLEND_MODE",
         StampBlendMode = CreateInput<Drawie.Backend.Core.Surfaces.BlendMode>("StampBlendMode", "STAMP_BLEND_MODE",
             Drawie.Backend.Core.Surfaces.BlendMode.SrcOver);
             Drawie.Backend.Core.Surfaces.BlendMode.SrcOver);
+        CanReuseStamps = CreateInput<bool>("CanReuseStamps", "CAN_REUSE_STAMPS", false);
 
 
         Pressure = CreateInput<float>("Pressure", "PRESSURE", 1f);
         Pressure = CreateInput<float>("Pressure", "PRESSURE", 1f);
         Spacing = CreateInput<float>("Spacing", "SPACING", 0);
         Spacing = CreateInput<float>("Spacing", "SPACING", 0);

BIN
src/PixiEditor/Data/Brushes/Basic.pixi


+ 2 - 1
src/PixiEditor/Data/Localization/Languages/en.json

@@ -1263,5 +1263,6 @@
   "FONT_FAMILY": "Font Family",
   "FONT_FAMILY": "Font Family",
   "TEXTURE": "Texture",
   "TEXTURE": "Texture",
   "PAINTER": "Painter",
   "PAINTER": "Painter",
-  "VECTOR_PATH": "Vector Path"
+  "VECTOR_PATH": "Vector Path",
+  "CAN_REUSE_STAMPS": "Can Reuse Stamps"
 }
 }