Browse Source

minor progress

flabbet 10 months ago
parent
commit
bdf6e121af

+ 0 - 1
src/ChunkyImageLib/ChunkyImage.cs

@@ -458,7 +458,6 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable, ICloneable, ICache
 
     /// <summary>
     /// Tries it's best to return a committed chunk, either if it exists or if it can be created from it's high res version. Returns null if it can't.
-    /// </summary>
     private Chunk? GetCommittedChunk(VecI pos, ChunkResolution resolution)
     {
         var maybeSameRes = MaybeGetCommittedChunk(pos, resolution);

+ 14 - 2
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/ImageLayerNode.cs

@@ -98,10 +98,22 @@ public class ImageLayerNode : LayerNode, IReadOnlyImageNode
                 workingSurface.Canvas.DrawRect((RectD)CalculateDestinationRect(ctx), clearPaint);
             }*/
 
-            for (int y = 0; y < 8; y++)
+            int chunksInDocumentX = (int)((float)ctx.DocumentSize.X / ChunkyImage.FullChunkSize);
+            int chunksInDocumentY = (int)((float)ctx.DocumentSize.Y / ChunkyImage.FullChunkSize);
+
+            chunksInDocumentX = Math.Max(1, chunksInDocumentX);
+            chunksInDocumentY = Math.Max(1, chunksInDocumentY);
+
+            for (int y = 0; y < chunksInDocumentY; y++)
             {
-                for (int x = 0; x < 8; x++)
+                for (int x = 0; x < chunksInDocumentX; x++)
                 {
+                    bool isVisible = ctx.VisibleChunks.Contains(new VecI(x, y));
+                    if (!isVisible)
+                    {
+                        continue;
+                    }
+                    
                     frameImage.DrawMostUpToDateChunkOn(
                         new VecI(x, y),
                         ctx.ChunkResolution,

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

@@ -79,7 +79,7 @@ public abstract class StructureNode : Node, IReadOnlyStructureNode, IBackgroundI
         sceneSurface.Canvas.Translate((float)ScenePosition.X, (float)ScenePosition.Y);
         
         SceneObjectRenderContext renderObjectContext = new SceneObjectRenderContext(sceneSurface, localBounds, 
-            context.FrameTime, context.ChunkResolution, context.DocumentSize) { ChunkToUpdate = context.ChunkToUpdate };
+            context.FrameTime, context.ChunkResolution, context.DocumentSize) { ChunkToUpdate = context.ChunkToUpdate, VisibleChunks = context.VisibleChunks };
         
         Render(renderObjectContext);
         

+ 1 - 0
src/PixiEditor.ChangeableDocument/Rendering/RenderContext.cs

@@ -20,6 +20,7 @@ public class RenderContext : IDisposable
 
     public KeyFrameTime FrameTime { get; }
     public VecI? ChunkToUpdate { get; set; }
+    public HashSet<VecI> VisibleChunks { get; set; } = new();
     public ChunkResolution ChunkResolution { get; }
     public VecI DocumentSize { get; set; }
     

+ 4 - 2
src/PixiEditor.ChangeableDocument/Rendering/SceneRenderer.cs

@@ -8,7 +8,9 @@ namespace PixiEditor.ChangeableDocument.Rendering;
 public class SceneRenderer
 {
     public IReadOnlyDocument Document { get; }
-    
+    public ChunkResolution Resolution { get; set; }
+    public HashSet<VecI> VisibleChunks { get; set; }
+
     private readonly Func<KeyFrameTime> getActiveFrameTime;
     
     public SceneRenderer(IReadOnlyDocument document, Func<KeyFrameTime> getActiveFrameTime)
@@ -19,7 +21,7 @@ public class SceneRenderer
 
     public void RenderScene(DrawingSurface target)
     {
-        using RenderContext ctx = new(target, getActiveFrameTime(), ChunkResolution.Full, Document.Size);
+        using RenderContext ctx = new(target, getActiveFrameTime(), Resolution, Document.Size) { VisibleChunks = this.VisibleChunks};
         Document.NodeGraph.Execute(ctx);
     }
 }

+ 48 - 21
src/PixiEditor/Views/Rendering/Scene.cs

@@ -10,6 +10,7 @@ using Avalonia.Rendering.SceneGraph;
 using Avalonia.Skia;
 using Avalonia.Threading;
 using ChunkyImageLib.DataHolders;
+using ChunkyImageLib.Operations;
 using PixiEditor.ChangeableDocument.Rendering;
 using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.Bridge;
@@ -54,14 +55,16 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
         AvaloniaProperty.Register<Scene, ViewportColorChannels>(
             nameof(Channels));
 
-    public static readonly StyledProperty<SceneRenderer> SceneRendererProperty = AvaloniaProperty.Register<Scene, SceneRenderer>(
-        nameof(SceneRenderer));
+    public static readonly StyledProperty<SceneRenderer> SceneRendererProperty =
+        AvaloniaProperty.Register<Scene, SceneRenderer>(
+            nameof(SceneRenderer));
 
     public SceneRenderer SceneRenderer
     {
         get => GetValue(SceneRendererProperty);
         set => SetValue(SceneRendererProperty, value);
     }
+
     public Cursor DefaultCursor
     {
         get => GetValue(DefaultCursorProperty);
@@ -134,6 +137,30 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
         };
     }
 
+    private ChunkResolution CalculateResolution()
+    {
+        VecD densityVec = Dimensions.Divide(RealDimensions);
+        double density = Math.Min(densityVec.X, densityVec.Y);
+        if (density > 8.01)
+            return ChunkResolution.Eighth;
+        else if (density > 4.01)
+            return ChunkResolution.Quarter;
+        else if (density > 2.01)
+            return ChunkResolution.Half;
+        return ChunkResolution.Full;
+    }
+
+    private HashSet<VecI> FindChunksVisibleOnViewports()
+    {
+        var viewportChunks = OperationHelper.FindChunksTouchingRectangle(
+            Center,
+            Dimensions,
+            -AngleRadians,
+            ChunkResolution.Full.PixelSize());
+
+        return viewportChunks;
+    }
+
     public override void Render(DrawingContext context)
     {
         if (Document == null) return;
@@ -142,10 +169,14 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
 
         float resolutionScale = CalculateResolutionScale();
 
-        RectD dirtyBounds = new RectD(0, 0, Document.Width / resolutionScale, Document.Height / resolutionScale);
+        RectD dirtyBounds = new RectD(0, 0, Document.Width, Document.Height);
         Rect dirtyRect = new Rect(0, 0, Document.Width / resolutionScale, Document.Height / resolutionScale);
 
-        using var operation = new DrawSceneOperation(SceneRenderer.RenderScene, Document, CanvasPos, Scale * resolutionScale,
+        SceneRenderer.Resolution = CalculateResolution();
+        SceneRenderer.VisibleChunks = FindChunksVisibleOnViewports();
+
+        using var operation = new DrawSceneOperation(SceneRenderer.RenderScene, Document, CanvasPos,
+            Scale * resolutionScale,
             resolutionScale, angle,
             FlipX, FlipY,
             dirtyRect,
@@ -156,17 +187,18 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
         context.PushTransform(matrix);
         context.PushRenderOptions(new RenderOptions { BitmapInterpolationMode = BitmapInterpolationMode.None });
 
-        var resolutionTransformation = context.PushTransform(Matrix.CreateScale(resolutionScale, resolutionScale));
+        //var resolutionTransformation = context.PushTransform(Matrix.CreateScale(resolutionScale, resolutionScale));
 
-        DrawCheckerboard(context, dirtyRect, new RectI(0, 0, operation.Document.SizeBindable.X, operation.Document.SizeBindable.Y));
+        DrawCheckerboard(context, dirtyRect,
+            new RectI(0, 0, operation.Document.SizeBindable.X, operation.Document.SizeBindable.Y));
 
-        resolutionTransformation.Dispose();
+        //resolutionTransformation.Dispose();
 
         Cursor = DefaultCursor;
 
         DrawOverlays(context, dirtyBounds, OverlayRenderSorting.Background);
 
-        resolutionTransformation = context.PushTransform(Matrix.CreateScale(resolutionScale, resolutionScale));
+        var resolutionTransformation = context.PushTransform(Matrix.CreateScale(resolutionScale, resolutionScale));
         context.Custom(operation);
 
         resolutionTransformation.Dispose();
@@ -373,14 +405,8 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
 
     private float CalculateResolutionScale()
     {
-        // TODO: Implement;
-        return 1;
-        /*
-        float scaleX = (float)Document.Width / Surface.Size.X;
-        float scaleY = (float)Document.Height / Surface.Size.Y;
-        var scaleUniform = Math.Min(scaleX, scaleY);
-        return scaleUniform;
-    */
+        var resolution = CalculateResolution();
+        return (float)resolution.InvertedMultiplier();
     }
 
     private void CaptureOverlay(Overlay? overlay, IPointer pointer)
@@ -491,16 +517,17 @@ internal class DrawSceneOperation : SkiaDrawOperation
     public bool FlipY { get; set; }
     public Rect ViewportBounds { get; }
 
-    
+
     public Action<DrawingSurface> RenderScene;
 
     private double opacity;
 
-    public DrawSceneOperation(Action<DrawingSurface> renderAction, DocumentViewModel document, VecD contentPosition, double scale,
+    public DrawSceneOperation(Action<DrawingSurface> renderAction, DocumentViewModel document, VecD contentPosition,
+        double scale,
         double resolutionScale,
         double angle, bool flipX, bool flipY, Rect dirtyBounds, Rect viewportBounds, double opacity) : base(dirtyBounds)
     {
-        RenderScene = renderAction; 
+        RenderScene = renderAction;
         Document = document;
         ContentPosition = contentPosition;
         Scale = scale;
@@ -520,7 +547,7 @@ internal class DrawSceneOperation : SkiaDrawOperation
 
         int count = canvas.Save();
 
-        using var ctx = DrawingBackendApi.Current.RenderOnDifferentGrContext(lease.GrContext);
+        //using var ctx = DrawingBackendApi.Current.RenderOnDifferentGrContext(lease.GrContext);
 
         using SKPaint paint = new SKPaint();
         paint.Color = paint.Color.WithAlpha((byte)(opacity * 255));
@@ -529,7 +556,7 @@ internal class DrawSceneOperation : SkiaDrawOperation
 
         DrawingSurface surface = DrawingSurface.FromNative(lease.SkSurface);
         RenderScene?.Invoke(surface);
-        
+
         canvas.RestoreToCount(count);
     }