Browse Source

Fixed layer node and improved performance once again

flabbet 1 year ago
parent
commit
5ed1f62df7

+ 26 - 28
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/ImageLayerNode.cs

@@ -15,10 +15,10 @@ public class ImageLayerNode : LayerNode, IReadOnlyImageNode
 
     private List<ImageFrame> frames = new List<ImageFrame>();
     private VecI size;
-    
+
     private Paint blendPaint = new Paint();
     private Paint maskPaint = new Paint() { BlendMode = DrawingApi.Core.Surface.BlendMode.DstIn };
-    
+
     private Dictionary<ChunkResolution, Surface> workingSurfaces = new Dictionary<ChunkResolution, Surface>();
 
     // Handled by overriden CacheChanged
@@ -61,7 +61,7 @@ public class ImageLayerNode : LayerNode, IReadOnlyImageNode
         var renderedSurface = RenderImage(frameImage, context);
 
         Output.Value = renderedSurface;
-        
+
         return Output.Value;
     }
 
@@ -70,23 +70,20 @@ public class ImageLayerNode : LayerNode, IReadOnlyImageNode
         ChunkResolution targetResolution = context.Resolution ?? ChunkResolution.Full;
         bool hasSurface = workingSurfaces.TryGetValue(targetResolution, out Surface workingSurface);
         VecI targetSize = (VecI)(frameImage.LatestSize * context.Resolution!.Value.Multiplier());
-        
-        if (!hasSurface || workingSurface.Size != targetSize)
-        {
-            workingSurfaces[context.Resolution ?? ChunkResolution.Full] = new Surface(targetSize);
-            workingSurface = workingSurfaces[context.Resolution ?? ChunkResolution.Full];
-        }
 
         if (Background.Value != null)
         {
-            RectD sourceRect = CalculateSourceRect(Background.Value, targetSize, context);
-            workingSurface.DrawingSurface.Canvas.DrawSurface(Background.Value.DrawingSurface, (int)sourceRect.X, (int)sourceRect.Y, blendPaint);
+            workingSurface = Background.Value;
             blendPaint.BlendMode = RenderingContext.GetDrawingBlendMode(BlendMode.Value);
         }
+        else if (!hasSurface || workingSurface.Size != targetSize)
+        {
+            workingSurfaces[targetResolution] = new Surface(targetSize);
+            workingSurface = workingSurfaces[targetResolution];
+        }
 
-        
         DrawLayer(frameImage, context, workingSurface);
-            
+
         ApplyMaskIfPresent(workingSurface, context);
         ApplyRasterClip(workingSurface, context);
         return workingSurface;
@@ -94,7 +91,7 @@ public class ImageLayerNode : LayerNode, IReadOnlyImageNode
 
     private void DrawLayer(ChunkyImage frameImage, RenderingContext context, Surface workingSurface)
     {
-        if(context.ChunkToUpdate == null)
+        if (context.ChunkToUpdate == null)
         {
             frameImage.DrawMostUpToDateRegionOn(
                 new RectI(0, 0, frameImage.LatestSize.X, frameImage.LatestSize.Y),
@@ -103,9 +100,9 @@ public class ImageLayerNode : LayerNode, IReadOnlyImageNode
         else
         {
             frameImage.DrawMostUpToDateChunkOn(
-                context.ChunkToUpdate.Value, 
+                context.ChunkToUpdate.Value,
                 context.Resolution.Value,
-                workingSurface.DrawingSurface, 
+                workingSurface.DrawingSurface,
                 context.ChunkToUpdate.Value * context.Resolution.Value.PixelSize(),
                 blendPaint);
         }
@@ -115,7 +112,7 @@ public class ImageLayerNode : LayerNode, IReadOnlyImageNode
     {
         return Mask.Value != null && MaskIsVisible.Value && !Mask.Value.LatestOrCommittedChunkExists();
     }
-    
+
     private void ApplyRasterClip(Surface surface, RenderingContext context)
     {
         if (ClipToPreviousMember.Value)
@@ -127,6 +124,7 @@ public class ImageLayerNode : LayerNode, IReadOnlyImageNode
                 VecI size = new VecI(context.Resolution.Value.PixelSize());
                 clippingRect = new RectI(chunkStart, size);
             }
+
             OperationHelper.ClampAlpha(surface.DrawingSurface, Background.Value, clippingRect);
         }
     }
@@ -146,9 +144,9 @@ public class ImageLayerNode : LayerNode, IReadOnlyImageNode
             if (context.Resolution.HasValue && context.ChunkToUpdate.HasValue)
             {
                 mask.DrawMostUpToDateChunkOn(
-                    context.ChunkToUpdate.Value, 
+                    context.ChunkToUpdate.Value,
                     context.Resolution.Value,
-                    surface.DrawingSurface, 
+                    surface.DrawingSurface,
                     context.ChunkToUpdate.Value * context.Resolution.Value.PixelSize(),
                     maskPaint);
             }
@@ -160,23 +158,23 @@ public class ImageLayerNode : LayerNode, IReadOnlyImageNode
             }
         }
     }
-    
+
     private RectD CalculateSourceRect(Surface image, VecI targetSize, RenderingContext context)
     {
-        if(context.Resolution == null || context.ChunkToUpdate == null)
+        if (context.Resolution == null || context.ChunkToUpdate == null)
         {
             return new RectD(0, 0, image.Size.X, image.Size.Y);
         }
-        
+
         float multiplierToFit = image.Size.X / (float)targetSize.X;
-        int chunkSize = context.Resolution.Value.PixelSize(); 
+        int chunkSize = context.Resolution.Value.PixelSize();
         VecI chunkPos = context.ChunkToUpdate.Value;
-        
+
         int x = (int)(chunkPos.X * chunkSize * multiplierToFit);
         int y = (int)(chunkPos.Y * chunkSize * multiplierToFit);
         int width = (int)(chunkSize * multiplierToFit);
         int height = (int)(chunkSize * multiplierToFit);
-        
+
         return new RectD(x, y, width, height);
     }
 
@@ -192,7 +190,7 @@ public class ImageLayerNode : LayerNode, IReadOnlyImageNode
         var imageFrame = GetFrameImage(context.FrameTime);
         if (imageFrame is not null && imageFrame.RequiresUpdate)
         {
-            imageFrame.RequiresUpdate = false; 
+            imageFrame.RequiresUpdate = false;
         }
     }
 
@@ -329,9 +327,9 @@ class ImageFrame
     public int StartFrame { get; set; }
     public int Duration { get; set; }
     public ChunkyImage Image { get; set; }
-    
+
     private int lastCommitCounter = 0;
-    
+
     public bool RequiresUpdate
     {
         get