Browse Source

Made high dpi rendering more controlled

flabbet 9 months ago
parent
commit
1967f7175e

+ 6 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/IHighDpiRenderNode.cs

@@ -0,0 +1,6 @@
+namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
+
+public interface IHighDpiRenderNode
+{
+    bool AllowHighDpiRendering { get; }
+}

+ 27 - 3
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/RenderNode.cs

@@ -1,17 +1,21 @@
-using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
+using Drawie.Backend.Core;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 using PixiEditor.ChangeableDocument.Rendering;
 using PixiEditor.ChangeableDocument.Rendering;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces;
+using Drawie.Backend.Core.Surfaces.PaintImpl;
 using Drawie.Numerics;
 using Drawie.Numerics;
 
 
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
 
 
-public abstract class RenderNode : Node, IPreviewRenderable
+public abstract class RenderNode : Node, IPreviewRenderable, IHighDpiRenderNode
 {
 {
     public RenderOutputProperty Output { get; }
     public RenderOutputProperty Output { get; }
 
 
+    public bool AllowHighDpiRendering { get; set; } = false;
+
     public RenderNode()
     public RenderNode()
     {
     {
-        Painter painter = new Painter(OnPaint);
+        Painter painter = new Painter(Paint);
         Output = CreateRenderOutput("Output", "OUTPUT",
         Output = CreateRenderOutput("Output", "OUTPUT",
             () => painter,
             () => painter,
             () => this is IRenderInput renderInput ? renderInput.Background.Value : null);
             () => this is IRenderInput renderInput ? renderInput.Background.Value : null);
@@ -27,6 +31,26 @@ public abstract class RenderNode : Node, IPreviewRenderable
             }
             }
         }
         }
     }
     }
+    
+    private void Paint(RenderContext context, DrawingSurface surface)
+    {
+        DrawingSurface target = surface;
+        bool useIntermediate = !AllowHighDpiRendering 
+                               && context.DocumentSize is { X: > 0, Y: > 0 } 
+                               && surface.DeviceClipBounds.Size != context.DocumentSize;
+        if (useIntermediate)
+        {
+            Texture intermediate = RequestTexture(0, context.DocumentSize);
+            target = intermediate.DrawingSurface;
+        }
+
+        OnPaint(context, target);
+        
+        if(useIntermediate)
+        {
+            surface.Canvas.DrawSurface(target, 0, 0);
+        }
+    }
 
 
     protected abstract void OnPaint(RenderContext context, DrawingSurface surface);
     protected abstract void OnPaint(RenderContext context, DrawingSurface surface);
 
 

+ 5 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/VectorLayerNode.cs

@@ -39,6 +39,11 @@ public class VectorLayerNode : LayerNode, ITransformableObject, IReadOnlyVectorN
 
 
     public override VecD GetScenePosition(KeyFrameTime time) => ShapeData?.TransformedAABB.Center ?? VecD.Zero;
     public override VecD GetScenePosition(KeyFrameTime time) => ShapeData?.TransformedAABB.Center ?? VecD.Zero;
     public override VecD GetSceneSize(KeyFrameTime time) => ShapeData?.TransformedAABB.Size ?? VecD.Zero;
     public override VecD GetSceneSize(KeyFrameTime time) => ShapeData?.TransformedAABB.Size ?? VecD.Zero;
+
+    public VectorLayerNode()
+    {
+        AllowHighDpiRendering = true;
+    }
     
     
     protected override VecI GetTargetSize(RenderContext ctx)
     protected override VecI GetTargetSize(RenderContext ctx)
     {
     {

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

@@ -668,7 +668,7 @@ internal class DocumentUpdater
     private void ProcessStructureMemberProperty(PropertyValueUpdated_ChangeInfo info, INodePropertyHandler property)
     private void ProcessStructureMemberProperty(PropertyValueUpdated_ChangeInfo info, INodePropertyHandler property)
     {
     {
         // TODO: This most likely can be handled inside viewmodel itself
         // TODO: This most likely can be handled inside viewmodel itself
-        if (property.Node is IStructureMemberHandler structureMemberHandler)
+        if (property.Node is IStructureMemberHandler structureMemberHandler && info.Value != null)
         {
         {
             if (info.Property == StructureNode.IsVisiblePropertyName)
             if (info.Property == StructureNode.IsVisiblePropertyName)
             {
             {

+ 18 - 2
src/PixiEditor/Models/Rendering/SceneRenderer.cs

@@ -7,6 +7,8 @@ using PixiEditor.ChangeableDocument.Rendering;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
 using Drawie.Numerics;
 using Drawie.Numerics;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
 using PixiEditor.Models.Handlers;
 using PixiEditor.Models.Handlers;
 
 
 namespace PixiEditor.Models.Rendering;
 namespace PixiEditor.Models.Rendering;
@@ -35,7 +37,7 @@ internal class SceneRenderer
         DrawingSurface renderTarget = target;
         DrawingSurface renderTarget = target;
         Texture? texture = null;
         Texture? texture = null;
         
         
-        if (!HighResRendering)
+        if (!HighResRendering || !HighDpiRenderNodePresent(Document.NodeGraph))
         {
         {
             texture = new(Document.Size);
             texture = new(Document.Size);
             renderTarget = texture.DrawingSurface;
             renderTarget = texture.DrawingSurface;
@@ -51,7 +53,21 @@ internal class SceneRenderer
             texture.Dispose();
             texture.Dispose();
         }
         }
     }
     }
-    
+
+    private bool HighDpiRenderNodePresent(IReadOnlyNodeGraph documentNodeGraph)
+    {
+        bool highDpiRenderNodePresent = false;
+        documentNodeGraph.TryTraverse(n =>
+        {
+            if (n is IHighDpiRenderNode { AllowHighDpiRendering: true })
+            {
+                highDpiRenderNodePresent = true;
+            } 
+        });
+        
+        return highDpiRenderNodePresent;
+    }
+
     private void RenderOnionSkin(DrawingSurface target, ChunkResolution resolution)
     private void RenderOnionSkin(DrawingSurface target, ChunkResolution resolution)
     {
     {
         var animationData = Document.AnimationData;
         var animationData = Document.AnimationData;

+ 5 - 0
src/PixiEditor/Views/Rendering/Scene.cs

@@ -199,6 +199,11 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
         try
         try
         {
         {
             var selfVisual = ElementComposition.GetElementVisual(this);
             var selfVisual = ElementComposition.GetElementVisual(this);
+            if (selfVisual == null)
+            {
+                return;
+            }
+            
             compositor = selfVisual.Compositor;
             compositor = selfVisual.Compositor;
 
 
             surface = compositor.CreateDrawingSurface();
             surface = compositor.CreateDrawingSurface();