Sfoglia il codice sorgente

Added frame debugger

Krzysztof Krysiński 1 mese fa
parent
commit
0322ab9c84

+ 12 - 2
src/PixiEditor/Models/DocumentModels/ActionAccumulator.cs

@@ -125,6 +125,8 @@ internal class ActionAccumulator
                     toExecute.Any(static action => action.action is RefreshPreview_PassthroughAction);
                 bool changeFrameRequest =
                     toExecute.Any(static action => action.action is SetActiveFrame_PassthroughAction);
+                bool debugRecordRequest =
+                    toExecute.Any(static action => action.action is DebugRecordFrame_PassthroughAction);
 
                 foreach (IChangeInfo info in optimizedChanges)
                 {
@@ -168,8 +170,16 @@ internal class ActionAccumulator
                 if(internals.Tracker.IsDisposed)
                     return;
 
-                await document.SceneRenderer.RenderAsync(internals.State.Viewports, affectedAreas.MainImageArea,
-                    !previewsDisabled && updateDelayed, previewTextures, immediateRender);
+                if (debugRecordRequest)
+                {
+                    await document.SceneRenderer.RecordRender(internals.State.Viewports, affectedAreas.MainImageArea,
+                        !previewsDisabled && updateDelayed, previewTextures, immediateRender);
+                }
+                else
+                {
+                    await document.SceneRenderer.RenderAsync(internals.State.Viewports, affectedAreas.MainImageArea,
+                        !previewsDisabled && updateDelayed, previewTextures, immediateRender);
+                }
 
                 NotifyUpdatedPreviews(updatePreviewActions);
             }

+ 5 - 0
src/PixiEditor/Models/DocumentModels/Public/DocumentOperationsModule.cs

@@ -1094,4 +1094,9 @@ internal class DocumentOperationsModule : IDocumentOperations
 
         Internals.ActionAccumulator.AddFinishedActions(new UpdatePropertyValue_Action(guid, propertyName, value), new EndUpdatePropertyValue_Action());
     }
+
+    public void RecordFrame()
+    {
+        Internals.ActionAccumulator.AddFinishedActions(new DebugRecordFrame_PassthroughAction());
+    }
 }

+ 8 - 0
src/PixiEditor/Models/DocumentPassthroughActions/DebugRecordFrame_PassthroughAction.cs

@@ -0,0 +1,8 @@
+using PixiEditor.ChangeableDocument.Actions;
+
+namespace PixiEditor.Models.DocumentPassthroughActions;
+
+public class DebugRecordFrame_PassthroughAction : IAction
+{
+
+}

+ 35 - 11
src/PixiEditor/Models/Rendering/SceneRenderer.cs

@@ -46,28 +46,35 @@ internal class SceneRenderer
         DocumentViewModel = documentViewModel;
     }
 
+    public async Task RecordRender(Dictionary<Guid, ViewportInfo> stateViewports, AffectedArea affectedArea,
+        bool updateDelayed, Dictionary<Guid, List<PreviewRenderRequest>>? previewTextures, bool immediateRender)
+    {
+        Render(stateViewports, affectedArea, updateDelayed, true, previewTextures);
+    }
+
     public async Task RenderAsync(Dictionary<Guid, ViewportInfo> stateViewports, AffectedArea affectedArea,
         bool updateDelayed, Dictionary<Guid, List<PreviewRenderRequest>>? previewTextures, bool immediateRender)
     {
         if (immediateRender)
         {
-            Render(stateViewports, affectedArea, updateDelayed, previewTextures);
+            Render(stateViewports, affectedArea, updateDelayed, false, previewTextures);
             return;
         }
 
         await DrawingBackendApi.Current.RenderingDispatcher.InvokeInBackgroundAsync(() =>
         {
-            Render(stateViewports, affectedArea, updateDelayed, previewTextures);
+            Render(stateViewports, affectedArea, updateDelayed, false, previewTextures);
         });
     }
 
     public void RenderSync(Dictionary<Guid, ViewportInfo> stateViewports, AffectedArea affectedAreasMainImageArea,
         bool updateDelayed, Dictionary<Guid, List<PreviewRenderRequest>>? previewTextures)
     {
-        Render(stateViewports, affectedAreasMainImageArea, updateDelayed, previewTextures);
+        Render(stateViewports, affectedAreasMainImageArea, updateDelayed, false, previewTextures);
     }
 
     private void Render(Dictionary<Guid, ViewportInfo> stateViewports, AffectedArea affectedArea, bool updateDelayed,
+        bool debugRecord,
         Dictionary<Guid, List<PreviewRenderRequest>>? previewTextures)
     {
         using var ctx = DrawingBackendApi.Current.RenderingDispatcher.EnsureContext();
@@ -79,9 +86,10 @@ internal class SceneRenderer
                 continue;
             }
 
-            if (viewport.Value.RealDimensions.ShortestAxis <= 0 || Math.Abs(viewport.Value.RealDimensions.LongestAxis - double.MaxValue) < double.Epsilon) continue;
+            if (viewport.Value.RealDimensions.ShortestAxis <= 0 ||
+                Math.Abs(viewport.Value.RealDimensions.LongestAxis - double.MaxValue) < double.Epsilon) continue;
 
-            var rendered = RenderScene(viewport.Value, affectedArea, previewTextures);
+            var rendered = RenderScene(viewport.Value, affectedArea, debugRecord && viewport.Value.IsScene, previewTextures);
             if (DocumentViewModel.SceneTextures.TryGetValue(viewport.Key, out var texture) && texture != rendered)
             {
                 texture.Dispose();
@@ -114,11 +122,12 @@ internal class SceneRenderer
             Delayed = false
         };
 
-        var rendered = RenderScene(previewGenerationViewport, affectedArea, previewTextures);
+        var rendered = RenderScene(previewGenerationViewport, affectedArea, false, previewTextures);
         rendered.Dispose();
     }
 
     public Texture? RenderScene(ViewportInfo viewport, AffectedArea affectedArea,
+        bool debugRecord = false,
         Dictionary<Guid, List<PreviewRenderRequest>>? previewTextures = null)
     {
         /*if (Document.Renderer.IsBusy || DocumentViewModel.Busy ||
@@ -174,7 +183,7 @@ internal class SceneRenderer
         bool shouldRerender =
             ShouldRerender(renderTargetSize, isFullViewportRender ? Matrix3X3.Identity : targetMatrix, resolution,
                 viewportId, targetOutput, finalGraph,
-                previewTextures, visibleDocumentRegion, oversizeFactor, out bool fullAffectedArea);
+                previewTextures, visibleDocumentRegion, oversizeFactor, out bool fullAffectedArea) || debugRecord;
 
         if (shouldRerender)
         {
@@ -184,7 +193,7 @@ internal class SceneRenderer
                 : affectedArea;
             return RenderGraph(renderTargetSize, targetMatrix, viewportId, resolution, samplingOptions, affectedArea,
                 visibleDocumentRegion, targetOutput, viewport.IsScene, oversizeFactor,
-                pointerInfo, keyboardInfo, editorData, viewport.ViewportData, finalGraph, previewTextures);
+                pointerInfo, keyboardInfo, editorData, viewport.ViewportData, debugRecord, finalGraph, previewTextures);
         }
 
         var cachedTexture = DocumentViewModel.SceneTextures[viewportId];
@@ -203,6 +212,7 @@ internal class SceneRenderer
         KeyboardInfo keyboardInfo,
         EditorData editorData,
         ViewportData viewportData,
+        bool debugRecord,
         IReadOnlyNodeGraph finalGraph, Dictionary<Guid, List<PreviewRenderRequest>>? previewTextures)
     {
         DrawingSurface renderTarget = null;
@@ -234,8 +244,7 @@ internal class SceneRenderer
             else
             {
                 var bufferedSize = (VecI)(renderTargetSize * oversizeFactor);
-                renderTexture = textureCache.RequestTexture(viewportId.GetHashCode(), bufferedSize,
-                    Document.ProcessingColorSpace);
+                renderTexture = textureCache.RequestTexture(viewportId.GetHashCode(), bufferedSize, Document.ProcessingColorSpace);
 
                 var bufferedMatrix = targetMatrix.PostConcat(Matrix3X3.CreateTranslation(
                     (bufferedSize.X - renderTargetSize.X) / 2.0,
@@ -283,7 +292,22 @@ internal class SceneRenderer
         context.VisibleDocumentRegion = visibleDocumentRegion;
         context.PreviewTextures = previewTextures;
         context.ViewportData = viewportData;
-        finalGraph.Execute(context);
+        if (debugRecord)
+        {
+            using DrawingRecorder recorder = new DrawingRecorder();
+            var recordingCanvas = recorder.BeginRecording(new RectD(0, 0, renderTargetSize.X, renderTargetSize.Y));
+            recordingCanvas.SetMatrix(context.RenderSurface.TotalMatrix);
+            context.RenderSurface = recordingCanvas;
+            finalGraph.Execute(context);
+            var picture = recorder.EndRecordingImmutable();
+            using FileStream fs = new FileStream("data.skp", FileMode.Create, FileAccess.Write);
+            picture.Serialize(fs);
+        }
+        else
+        {
+            finalGraph.Execute(context);
+        }
+
         ExecuteBrushOutputPreviews(finalGraph, previewTextures, context);
 
         if (renderOnionSkinning)

+ 8 - 0
src/PixiEditor/ViewModels/SubViewModels/DebugViewModel.cs

@@ -20,6 +20,7 @@ using PixiEditor.Helpers;
 using PixiEditor.Models.Commands.Attributes.Commands;
 using PixiEditor.Models.Commands.Templates.Providers.Parsers;
 using PixiEditor.Models.Dialogs;
+using PixiEditor.Models.DocumentModels;
 using PixiEditor.Models.IO;
 using PixiEditor.OperatingSystem;
 using PixiEditor.UI.Common.Fonts;
@@ -131,6 +132,13 @@ internal class DebugViewModel : SubViewModel<ViewModelMain>
         OpenFolder(path);
     }
 
+    [Command.Debug("PixiEditor.Debug.RecordGraphRender", "RECORD_GRAPH_RENDER", "RECORD_GRAPH_RENDER",
+        AnalyticsTrack = true)]
+    public void RecordGraphRender()
+    {
+        Owner.DocumentManagerSubViewModel.ActiveDocument.Operations.RecordFrame();
+    }
+
     [Command.Debug("PixiEditor.Debug.DumpGPUDiagnostics", "DUMP_GPU_DIAGNOSTICS", "DUMP_GPU_DIAGNOSTICS",
         AnalyticsTrack = true)]
     public async Task DumpGpuDiagnostics()