瀏覽代碼

Added reuse stamps optimization

Krzysztof Krysiński 3 周之前
父節點
當前提交
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 startPos;
     private int lastAppliedPointIndex = -1;
+    private VecI lastCachedTexturePaintableSize = VecI.Zero;
+    private TexturePaintable? lastCachedTexturePaintable = null;
 
     private bool drawnOnce = false;
 
@@ -246,16 +248,19 @@ public class BrushEngine : IDisposable
 
         bool autoPosition = brushNode.AutoPosition.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 contentTexture = brushNode.ContentTexture;
         bool antiAliasing = brushData.AntiAliasing;
         var fill = brushNode.Fill.Value;
         var stroke = brushNode.Stroke.Value;
         bool snapToPixels = brushNode.SnapToPixels.Value;
+        bool canReuseStamps = brushNode.CanReuseStamps.Value;
 
         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;
         }
@@ -264,7 +269,7 @@ public class BrushEngine : IDisposable
     public bool PaintBrush(ChunkyImage target, bool autoPosition, ShapeVectorData vectorShape,
         RectD rect, bool fitToStrokeSize, float pressure, Painter? content,
         Texture? contentTexture, DrawingApiBlendMode blendMode, bool antiAliasing, Paintable fill, Paintable stroke,
-        bool snapToPixels)
+        bool snapToPixels, bool canReuseStamps)
     {
         var path = vectorShape.ToPath(true);
         if (path == null)
@@ -311,8 +316,24 @@ public class BrushEngine : IDisposable
         {
             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);
             }
         }
@@ -495,5 +516,6 @@ public class BrushEngine : IDisposable
     public void 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> SnapToPixels { 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; }
 
@@ -78,6 +80,7 @@ public class BrushOutputNode : Node
             Drawie.Backend.Core.Surfaces.BlendMode.SrcOver);
         StampBlendMode = CreateInput<Drawie.Backend.Core.Surfaces.BlendMode>("StampBlendMode", "STAMP_BLEND_MODE",
             Drawie.Backend.Core.Surfaces.BlendMode.SrcOver);
+        CanReuseStamps = CreateInput<bool>("CanReuseStamps", "CAN_REUSE_STAMPS", false);
 
         Pressure = CreateInput<float>("Pressure", "PRESSURE", 1f);
         Spacing = CreateInput<float>("Spacing", "SPACING", 0);

二進制
src/PixiEditor/Data/Brushes/Basic.pixi


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

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