Преглед на файлове

Fixed non updating nodes and sampling on render node

Krzysztof Krysiński преди 3 седмици
родител
ревизия
94e07f96a9

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

@@ -66,7 +66,15 @@ public abstract class RenderNode : Node, IPreviewRenderable, IHighDpiRenderNode
                 surface.Canvas.Scale((float)context.ChunkResolution.InvertedMultiplier());
             }
 
-            surface.Canvas.DrawSurface(target, 0, 0);
+            if (context.DesiredSamplingOptions != SamplingOptions.Default)
+            {
+                using var snapshot = target.Snapshot();
+                surface.Canvas.DrawImage(snapshot, 0, 0, context.DesiredSamplingOptions);
+            }
+            else
+            {
+                surface.Canvas.DrawSurface(target, 0, 0);
+            }
 
             if (RendersInAbsoluteCoordinates)
             {

+ 15 - 4
src/PixiEditor.ChangeableDocument/Rendering/DocumentRenderer.cs

@@ -19,9 +19,9 @@ namespace PixiEditor.ChangeableDocument.Rendering;
 
 public class DocumentRenderer : IPreviewRenderable, IDisposable
 {
-
     private Queue<RenderRequest> renderRequests = new();
     private Texture renderTexture;
+    private int lastExecutedGraphFrame = -1;
 
     public DocumentRenderer(IReadOnlyDocument document)
     {
@@ -135,7 +135,7 @@ public class DocumentRenderer : IPreviewRenderable, IDisposable
         RenderRequest request = new(tcs, context, renderOn, previewRenderable, elementToRenderName);
 
         renderRequests.Enqueue(request);
-        ExecuteRenderRequests();
+        ExecuteRenderRequests(context.FrameTime);
 
         return await tcs.Task;
     }
@@ -206,6 +206,7 @@ public class DocumentRenderer : IPreviewRenderable, IDisposable
         renderOn.Canvas.Scale((float)context.ChunkResolution.Multiplier());
         context.RenderSurface = renderOn;
         Document.NodeGraph.Execute(context);
+        lastExecutedGraphFrame = context.FrameTime.Frame;
         renderOn.Canvas.RestoreToCount(savedCount);
 
         IsBusy = false;
@@ -240,7 +241,8 @@ public class DocumentRenderer : IPreviewRenderable, IDisposable
             : Document.NodeGraph;
 
         RenderContext context =
-            new(renderTexture.DrawingSurface, frameTime, ChunkResolution.Full, SolveRenderOutputSize(customOutput, graph, Document.Size),
+            new(renderTexture.DrawingSurface, frameTime, ChunkResolution.Full,
+                SolveRenderOutputSize(customOutput, graph, Document.Size),
                 Document.Size, Document.ProcessingColorSpace, SamplingOptions.Default) { FullRerender = true };
 
         if (hasCustomOutput)
@@ -268,19 +270,28 @@ public class DocumentRenderer : IPreviewRenderable, IDisposable
         renderTexture.DrawingSurface.Canvas.Restore();
         toRenderOn.Canvas.Restore();
 
+        lastExecutedGraphFrame = frameTime.Frame;
+
         IsBusy = false;
     }
 
-    private void ExecuteRenderRequests()
+    private void ExecuteRenderRequests(KeyFrameTime frameTime)
     {
         if (isExecuting) return;
 
         isExecuting = true;
         using var ctx = DrawingBackendApi.Current?.RenderingDispatcher.EnsureContext();
+
         while (renderRequests.Count > 0)
         {
             RenderRequest request = renderRequests.Dequeue();
 
+            if (frameTime.Frame != lastExecutedGraphFrame && request.PreviewRenderable != this)
+            {
+                using Texture executeSurface = Texture.ForDisplay(new VecI(1));
+                RenderDocument(executeSurface.DrawingSurface, frameTime, VecI.One);
+            }
+
             try
             {
                 bool result = true;

+ 1 - 1
src/PixiEditor/Models/DocumentModels/ActionAccumulator.cs

@@ -137,7 +137,7 @@ internal class ActionAccumulator
 
                 var affectedAreas = new AffectedAreasGatherer(document.AnimationHandler.ActiveFrameTime,
                     internals.Tracker,
-                    optimizedChanges);
+                    optimizedChanges, refreshPreviewsRequest);
 
                 if (DrawingBackendApi.Current.IsHardwareAccelerated && !allPassthrough)
                 {

+ 21 - 11
src/PixiEditor/Models/Rendering/AffectedAreasGatherer.cs

@@ -41,10 +41,20 @@ internal class AffectedAreasGatherer
     private bool alreadyAddedWholeCanvasToEveryImagePreview = false;
 
     public AffectedAreasGatherer(KeyFrameTime activeFrame, DocumentChangeTracker tracker,
-        IReadOnlyList<IChangeInfo> changes)
+        IReadOnlyList<IChangeInfo> changes, bool refreshAllPreviews)
     {
         this.tracker = tracker;
         ActiveFrame = activeFrame;
+
+        if (refreshAllPreviews)
+        {
+            AddWholeCanvasToMainImage();
+            AddWholeCanvasToEveryImagePreview(false);
+            AddWholeCanvasToEveryMaskPreview();
+            AddAllNodesToImagePreviews();
+            return;
+        }
+
         ProcessChanges(changes);
 
         var outputNode = tracker.Document.NodeGraph.OutputNode;
@@ -103,7 +113,7 @@ internal class AffectedAreasGatherer
                     break;
                 case Size_ChangeInfo:
                     AddWholeCanvasToMainImage();
-                    AddWholeCanvasToEveryImagePreview();
+                    AddWholeCanvasToEveryImagePreview(false);
                     AddWholeCanvasToEveryMaskPreview();
                     break;
                 case StructureMemberMask_ChangeInfo info:
@@ -152,25 +162,25 @@ internal class AffectedAreasGatherer
                     break;
                 case SetActiveFrame_PassthroughAction:
                     AddWholeCanvasToMainImage();
-                    AddWholeCanvasToEveryImagePreview();
+                    AddWholeCanvasToEveryImagePreview(true);
                     AddAllNodesToImagePreviews();
                     IgnoreAnimationPreviews = true;
                     break;
                 case KeyFrameLength_ChangeInfo:
                     AddWholeCanvasToMainImage();
-                    AddWholeCanvasToEveryImagePreview();
+                    AddWholeCanvasToEveryImagePreview(true);
                     break;
                 case DeleteKeyFrame_ChangeInfo:
                     AddWholeCanvasToMainImage();
-                    AddWholeCanvasToEveryImagePreview();
+                    AddWholeCanvasToEveryImagePreview(true);
                     break;
                 case KeyFrameVisibility_ChangeInfo:
                     AddWholeCanvasToMainImage();
-                    AddWholeCanvasToEveryImagePreview();
+                    AddWholeCanvasToEveryImagePreview(true);
                     break;
                 case ConnectProperty_ChangeInfo info:
                     AddWholeCanvasToMainImage();
-                    AddWholeCanvasToEveryImagePreview();
+                    AddWholeCanvasToEveryImagePreview(false);
                     AddToNodePreviews(info.InputNodeId);
                     if (info.OutputNodeId.HasValue)
                     {
@@ -180,7 +190,7 @@ internal class AffectedAreasGatherer
                     break;
                 case PropertyValueUpdated_ChangeInfo info:
                     AddWholeCanvasToMainImage();
-                    AddWholeCanvasToEveryImagePreview();
+                    AddWholeCanvasToEveryImagePreview(false);
                     AddToNodePreviews(info.NodeId);
                     break;
                 case ToggleOnionSkinning_PassthroughAction:
@@ -196,7 +206,7 @@ internal class AffectedAreasGatherer
                     break;
                 case ProcessingColorSpace_ChangeInfo:
                     AddWholeCanvasToMainImage();
-                    AddWholeCanvasToEveryImagePreview();
+                    AddWholeCanvasToEveryImagePreview(false);
                     AddWholeCanvasToEveryMaskPreview();
                     break;
             }
@@ -383,14 +393,14 @@ internal class AffectedAreasGatherer
         }
     }
 
-    private void AddWholeCanvasToEveryImagePreview()
+    private void AddWholeCanvasToEveryImagePreview(bool onlyWithKeyFrames)
     {
         if (alreadyAddedWholeCanvasToEveryImagePreview)
             return;
 
         tracker.Document.ForEveryReadonlyMember((member) =>
         {
-            if (member.KeyFrames.Count > 0)
+            if (!onlyWithKeyFrames || member.KeyFrames.Count > 0)
             {
                 AddWholeCanvasToImagePreviews(member.Id);
             }