Преглед изворни кода

Some stuff but no real progress

Krzysztof Krysiński пре 1 дан
родитељ
комит
7cfc5e1154

+ 1 - 1
src/Drawie

@@ -1 +1 @@
-Subproject commit 0823d664bac5bca06e9a2068c4cd05df7ad8a7d0
+Subproject commit 879e852efbd6b8ae91b85282a8a7a34e421ac1f8

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

@@ -76,13 +76,13 @@ internal class SceneRenderer
             {
                 if (DocumentViewModel.SceneTextures.TryGetValue(viewport.Key, out var texture) && texture != rendered)
                 {
-                    texture.Dispose();
+                    texture?.Dispose();
                 }
 
                 DocumentViewModel.SceneTextures[viewport.Key] = rendered;
+                Dispatcher.UIThread.Post(viewport.Value.InvalidateVisual, DispatcherPriority.Render);
             }
 
-            Dispatcher.UIThread.Invoke(() => viewport.Value.InvalidateVisual());
             renderedCount++;
         }
 
@@ -133,6 +133,9 @@ internal class SceneRenderer
 
         IReadOnlyNodeGraph finalGraph = RenderingUtils.SolveFinalNodeGraph(targetOutput, Document);
 
+        if(renderTargetSize.X <= 0 || renderTargetSize.Y <= 0)
+            return null;
+
         float oversizeFactor = 1;
         if (visibleDocumentRegion != null && viewport.IsScene &&
             visibleDocumentRegion.Value != new RectI(0, 0, Document.Size.X, Document.Size.Y))

+ 1 - 1
src/PixiEditor/Views/Main/ViewportControls/FixedViewport.axaml.cs

@@ -125,7 +125,7 @@ internal partial class FixedViewport : UserControl, INotifyPropertyChanged
     private void ForceRefreshFinalImage()
     {
         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SceneTexture)));
-        mainImage.InvalidateVisual();
+        mainImage.QueueNextFrame();
     }
 
     private ViewportInfo GetLocation()

+ 2 - 2
src/PixiEditor/Views/Main/ViewportControls/Viewport.axaml.cs

@@ -467,7 +467,7 @@ internal partial class Viewport : UserControl, INotifyPropertyChanged
 
     private void ForceRefreshFinalImage()
     {
-        Scene.InvalidateVisual();
+        Scene.QueueNextFrame();
     }
 
     private void OnUnload(object? sender, RoutedEventArgs e)
@@ -525,7 +525,7 @@ internal partial class Viewport : UserControl, INotifyPropertyChanged
     private ViewportInfo GetLocation()
     {
         return new(AngleRadians, Center, RealDimensions,
-            Scene.CalculateTransformMatrix((float)Scene.AngleRadians, Scene.FlipX, Scene.FlipY, Scene.Scale, Scene.CanvasPos).ToSKMatrix().ToMatrix3X3(),
+            Scene.CalculateTransformMatrix().ToSKMatrix().ToMatrix3X3(),
             CalculateVisibleRegion(),
             ViewportRenderOutput, Scene.CalculateSampling(), Dimensions, CalculateResolution(), GuidValue, Delayed,
             true, ForceRefreshFinalImage);

+ 65 - 106
src/PixiEditor/Views/Rendering/Scene.cs

@@ -194,8 +194,8 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
     private VecI lastSize = VecI.Zero;
     private Cursor lastCursor;
     private VecD lastMousePosition;
+    private bool needsRedraw;
 
-    private IDisposable? toPresent;
 
     public static readonly StyledProperty<string> RenderOutputProperty =
         AvaloniaProperty.Register<Scene, string>("RenderOutput");
@@ -340,71 +340,44 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
         }
     }
 
-    private float angleRadians;
-    private bool flipX;
-    private bool flipY;
-    private float scale;
-    private VecD canvasPos;
-    private DocumentViewModel doc;
-    string renderOutput;
-    private void PrepareToDraw()
-    {
-        angleRadians = (float)AngleRadians;
-        flipX = FlipX;
-        flipY = FlipY;
-        scale = (float)Scale;
-        canvasPos = CanvasPos;
-        doc = Document;
-        renderOutput = RenderOutput;
-    }
-
     public void Draw(DrawingSurface texture)
     {
         texture.Canvas.Save();
-        var matrix = CalculateTransformMatrix(angleRadians, flipX, flipY, scale, canvasPos);
+        var matrix = CalculateTransformMatrix();
 
         texture.Canvas.SetMatrix(matrix.ToSKMatrix().ToMatrix3X3());
 
-        VecI outputSize = FindOutputSize(doc, renderOutput);
+        VecI outputSize = FindOutputSize(Document, RenderOutput);
 
         RectD dirtyBounds = new RectD(0, 0, outputSize.X, outputSize.Y);
-        RenderScene(texture, dirtyBounds, doc, angleRadians, flipX, flipY, scale, canvasPos);
+        RenderScene(texture, dirtyBounds);
 
         texture.Canvas.Restore();
     }
 
-    private void RenderScene(DrawingSurface texture, RectD bounds, DocumentViewModel document,
-        float angleRadians, bool flipX, bool flipY, float scale, VecD canvasPos)
+    private void RenderScene(DrawingSurface texture, RectD bounds)
     {
-        //var renderOutput = RenderOutput == "DEFAULT" ? null : RenderOutput;
-        //DrawCheckerboard(texture, bounds);
-        //DrawOverlays(texture, bounds, OverlayRenderSorting.Background);
+        var renderOutput = RenderOutput == "DEFAULT" ? null : RenderOutput;
+        DrawCheckerboard(texture, bounds);
+        DrawOverlays(texture, bounds, OverlayRenderSorting.Background);
         try
         {
-            Guid viewportId = default;
-            VecD realDimensions = VecD.Zero;
-            Dispatcher.UIThread.Invoke(() =>
-            {
-                viewportId = ViewportId;
-                realDimensions = RealDimensions;
-            });
-
-            if (document == null || document.SceneTextures.TryGetValue(viewportId, out var tex) == false)
+            if (Document == null || Document.SceneTextures.TryGetValue(ViewportId, out var tex) == false)
                 return;
 
             bool hasSaved = false;
             int saved = -1;
 
-            var matrix = CalculateTransformMatrix(angleRadians, flipX, flipY, scale, canvasPos).ToSKMatrix()
+            var matrix = CalculateTransformMatrix().ToSKMatrix()
                 .ToMatrix3X3();
-            if (!document.SceneTextures.TryGetValue(viewportId, out var cachedTexture))
+            if (!Document.SceneTextures.TryGetValue(ViewportId, out var cachedTexture))
                 return;
 
             Matrix3X3 matrixDiff =
-                SolveMatrixDiff(matrix, document.SceneRenderer.LastRenderedStates[viewportId].Matrix);
+                SolveMatrixDiff(matrix, Document.SceneRenderer.LastRenderedStates[ViewportId].Matrix);
             var target = cachedTexture;
 
-            if (tex.Size == (VecI)realDimensions || tex.Size == (VecI)(realDimensions * SceneRenderer.OversizeFactor))
+            if (tex.Size == (VecI)RealDimensions || tex.Size == (VecI)(RealDimensions * SceneRenderer.OversizeFactor))
             {
                 saved = texture.Canvas.Save();
                 texture.Canvas.ClipRect(bounds);
@@ -415,9 +388,9 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
             {
                 saved = texture.Canvas.Save();
                 ChunkResolution renderedResolution = ChunkResolution.Full;
-                if (SceneRenderer != null && SceneRenderer.LastRenderedStates.ContainsKey(viewportId))
+                if (SceneRenderer != null && SceneRenderer.LastRenderedStates.ContainsKey(ViewportId))
                 {
-                    renderedResolution = SceneRenderer.LastRenderedStates[viewportId].ChunkResolution;
+                    renderedResolution = SceneRenderer.LastRenderedStates[ViewportId].ChunkResolution;
                 }
 
                 texture.Canvas.SetMatrix(matrixDiff);
@@ -442,11 +415,11 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
             using Font defaultSizedFont = Font.CreateDefault();
             defaultSizedFont.Size = 24;
 
-            texture.Canvas.DrawText(new LocalizedString("ERROR_GRAPH"), intermediateSurface.Size / 2f,
+            texture.Canvas.DrawText(new LocalizedString("ERROR_GRAPH"), RealDimensions / 2f,
                 TextAlign.Center, defaultSizedFont, paint);
         }
 
-        //DrawOverlays(texture, bounds, OverlayRenderSorting.Foreground);
+        DrawOverlays(texture, bounds, OverlayRenderSorting.Foreground);
     }
 
     private void DrawCheckerboard(DrawingSurface surface, RectD dirtyBounds)
@@ -805,18 +778,18 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
 
     private VecD ToCanvasSpace(Point scenePosition)
     {
-        Matrix transform = CalculateTransformMatrix((float)AngleRadians, FlipX, FlipY, (float)Scale, CanvasPos);
+        Matrix transform = CalculateTransformMatrix();
         Point transformed = transform.Invert().Transform(scenePosition);
         return new VecD(transformed.X, transformed.Y);
     }
 
-    internal Matrix CalculateTransformMatrix(float angleRadians, bool flipX, bool flipY, double scale, VecD canvasPos)
+    internal Matrix CalculateTransformMatrix()
     {
         Matrix transform = Matrix.Identity;
-        transform = transform.Append(Matrix.CreateRotation(angleRadians));
-        transform = transform.Append(Matrix.CreateScale(flipX ? -1 : 1, flipY ? -1 : 1));
-        transform = transform.Append(Matrix.CreateScale((float)scale, (float)scale));
-        transform = transform.Append(Matrix.CreateTranslation(canvasPos.X, canvasPos.Y));
+        transform = transform.Append(Matrix.CreateRotation(AngleRadians));
+        transform = transform.Append(Matrix.CreateScale(FlipX ? -1 : 1, FlipY ? -1 : 1));
+        transform = transform.Append(Matrix.CreateScale((float)Scale, (float)Scale));
+        transform = transform.Append(Matrix.CreateTranslation(CanvasPos.X, CanvasPos.Y));
         return transform;
     }
 
@@ -889,7 +862,7 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
 
         try
         {
-            RenderFrame();
+            RenderFrame(new PixelSize((int)Bounds.Width, (int)Bounds.Height));
             info = string.Empty;
         }
         catch (Exception e)
@@ -900,39 +873,66 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
         }
     }
 
-    private void RenderFrame()
+    private void RenderFrame(PixelSize pixelSize)
     {
-        toPresent?.Dispose();
-        toPresent = null;
+        if (!needsRedraw)
+            return;
+
+        VecI size = new VecI(pixelSize.Width, pixelSize.Height);
+
+        if (resources is { IsDisposed: false })
+        {
+            using var ctx = IDrawieInteropContext.Current.EnsureContext();
+            if (size.X == 0 || size.Y == 0)
+            {
+                return;
+            }
+
+            if (lastSize != size || framebuffer == null || framebuffer.IsDisposed ||
+                framebuffer.DeviceClipBounds.Size != size)
+            {
+                resources.CreateTemporalObjects(size);
+
+                framebuffer?.Dispose();
+                framebuffer =
+                    DrawingBackendApi.Current.CreateRenderSurface(size, resources.Texture, SurfaceOrigin.BottomLeft);
+
+                lastSize = size;
+            }
+
+            using var _ = resources.Render(size, () =>
+            {
+                framebuffer.Canvas.Clear();
+                Draw(framebuffer);
+                framebuffer.Canvas.Flush();
+            });
+
+            needsRedraw = false;
+        }
     }
 
     public void QueueNextFrame()
     {
         if (initialized && !updateQueued && compositor != null && surface is { IsDisposed: false })
         {
+            updateQueued = true;
             QueueFrameRequested();
-            RequestBlit();
         }
     }
 
-
     protected void QueueFrameRequested()
     {
         if (Bounds.Width <= 0 || Bounds.Height <= 0 || double.IsNaN(Bounds.Width) || double.IsNaN(Bounds.Height))
             return;
 
-        PrepareToDraw();
-        DrawingBackendApi.Current.RenderingDispatcher.QueueRender(() =>
-        {
-            BeginDraw(new VecI((int)Bounds.Width, (int)Bounds.Height));
-            Dispatcher.UIThread.Post(RequestBlit);
-        });
+        needsRedraw = true;
+        RequestBlit();
+        InvalidateVisual();
     }
 
-    private void RequestBlit()
+    protected void RequestBlit()
     {
-        updateQueued = true;
-        compositor.RequestCompositionUpdate(update);
+        DrawingBackendApi.Current.RenderingDispatcher.EnqueueUIUpdate(update);
     }
 
     protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
@@ -1006,47 +1006,6 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
         resources = null;
     }
 
-    public void BeginDraw(VecI size)
-    {
-        if (resources is { IsDisposed: false })
-        {
-            using var ctx = IDrawieInteropContext.Current.EnsureContext();
-            if (size.X == 0 || size.Y == 0)
-            {
-                return;
-            }
-
-            if (framebuffer == null || lastSize != size)
-            {
-                resources.CreateTemporalObjects(size);
-
-                VecI sizeVec = new VecI(size.X, size.Y);
-
-                framebuffer?.Dispose();
-
-                framebuffer =
-                    DrawingBackendApi.Current.CreateRenderSurface(sizeVec,
-                        resources.Texture, SurfaceOrigin.BottomLeft);
-
-                intermediateSurface?.Dispose();
-                intermediateSurface = Texture.ForDisplay(sizeVec);
-
-                lastSize = size;
-            }
-
-            toPresent = resources.Render(size, () =>
-            {
-                framebuffer.Canvas.Clear();
-                intermediateSurface?.DrawingSurface.Canvas.Clear();
-
-                Draw(intermediateSurface.DrawingSurface);
-                framebuffer.Canvas.DrawSurface(intermediateSurface.DrawingSurface, 0, 0);
-
-                //framebuffer.Flush();
-            });
-        }
-    }
-
     #endregion
 
     public void RefreshCursor()

+ 10 - 3
src/PixiEditor/Views/Visuals/PixiFilePreviewImage.cs

@@ -1,6 +1,7 @@
 using Avalonia;
 using Avalonia.Threading;
 using Drawie.Backend.Core;
+using Drawie.Backend.Core.Bridge;
 using Drawie.Backend.Core.Surfaces;
 using PixiEditor.Extensions.Exceptions;
 using PixiEditor.Helpers;
@@ -74,16 +75,22 @@ internal class PixiFilePreviewImage : TextureControl
             return;
         }
 
-        Dispatcher.UIThread.Post(() =>
+        DrawingBackendApi.Current.RenderingDispatcher.QueueRender(() =>
         {
             try
             {
                 var surface = LoadTexture(imageBytes);
-                SetImage(surface);
+                Dispatcher.UIThread.Post(() =>
+                {
+                    SetImage(surface);
+                });
             }
             catch (Exception e)
             {
-                SetCorrupt();
+                Dispatcher.UIThread.Post(() =>
+                {
+                    SetCorrupt();
+                });
             }
         });
     }

+ 4 - 10
src/PixiEditor/Views/Visuals/PreviewTextureControl.cs

@@ -3,6 +3,7 @@ using Avalonia.Threading;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Interop.Avalonia.Core.Controls;
 using Drawie.Numerics;
+using Drawie.RenderApi;
 using PixiEditor.ViewModels.Document;
 
 namespace PixiEditor.Views.Visuals;
@@ -19,7 +20,6 @@ public class PreviewTextureControl : DrawieControl
         set => SetValue(TexturePreviewProperty, value);
     }
 
-    private TexturePreview? preview;
     private Rect bounds;
 
     static PreviewTextureControl()
@@ -58,20 +58,14 @@ public class PreviewTextureControl : DrawieControl
             TexturePreview.TextureUpdated -= QueueNextFrame;
     }
 
-    protected override void PrepareToDraw()
-    {
-        preview = TexturePreview;
-        bounds = Bounds;
-    }
-
     public override void Draw(DrawingSurface surface)
     {
-        if (preview is { Preview: not null } && preview.Preview is { IsDisposed: false })
+        if (TexturePreview is { Preview: { IsDisposed: false } })
         {
-            VecD scaling = new(bounds.Size.Width / preview.Preview.Size.X, bounds.Size.Height / preview.Preview.Size.Y);
+            VecD scaling = new(bounds.Size.Width / TexturePreview.Preview.Size.X, bounds.Size.Height / TexturePreview.Preview.Size.Y);
             surface.Canvas.Save();
             surface.Canvas.Scale((float)scaling.X, (float)scaling.Y);
-            surface.Canvas.DrawSurface(preview.Preview.DrawingSurface, 0, 0);
+            surface.Canvas.DrawSurface(TexturePreview.Preview.DrawingSurface, 0, 0);
             surface.Canvas.Restore();
         }
     }