소스 검색

Initial software rendering impl

Krzysztof Krysiński 3 주 전
부모
커밋
7d54cb3f4f
3개의 변경된 파일49개의 추가작업 그리고 10개의 파일을 삭제
  1. 1 1
      src/Drawie
  2. 2 2
      src/PixiEditor.Desktop/Program.cs
  3. 46 7
      src/PixiEditor/Views/Rendering/Scene.cs

+ 1 - 1
src/Drawie

@@ -1 +1 @@
-Subproject commit 753784f70c3a455dce172ad2e92be63329f9d4c3
+Subproject commit ac1cd2878f724d275a36af5c889fa9c97e6c5b71

+ 2 - 2
src/PixiEditor.Desktop/Program.cs

@@ -44,12 +44,12 @@ public class Program
             .UsePlatformDetect()
             .With(new Win32PlatformOptions()
             {
-                RenderingMode = openGlPreferred ? [ Win32RenderingMode.Wgl, Win32RenderingMode.Vulkan] : [ Win32RenderingMode.Vulkan, Win32RenderingMode.Wgl],
+                RenderingMode = openGlPreferred ? [ Win32RenderingMode.Wgl, Win32RenderingMode.Vulkan, Win32RenderingMode.AngleEgl, Win32RenderingMode.Software] : [ Win32RenderingMode.Vulkan, Win32RenderingMode.Wgl, Win32RenderingMode.AngleEgl, Win32RenderingMode.Software],
                 OverlayPopups = true,
             })
             .With(new X11PlatformOptions()
             {
-                RenderingMode = openGlPreferred ? [ X11RenderingMode.Glx, X11RenderingMode.Vulkan] : [ X11RenderingMode.Vulkan, X11RenderingMode.Glx],
+                RenderingMode = openGlPreferred ? [ X11RenderingMode.Glx, X11RenderingMode.Vulkan, X11RenderingMode.Egl, X11RenderingMode.Software] : [ X11RenderingMode.Vulkan, X11RenderingMode.Glx, X11RenderingMode.Egl, X11RenderingMode.Software],
                 OverlayPopups = true,
             })
             .With(new SkiaOptions()

+ 46 - 7
src/PixiEditor/Views/Rendering/Scene.cs

@@ -268,7 +268,14 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
     protected override void OnLoaded(RoutedEventArgs e)
     {
         base.OnLoaded(e);
-        InitializeComposition();
+        if (DrawingBackendApi.Current.IsHardwareAccelerated)
+        {
+            InitializeComposition();
+        }
+        else
+        {
+            InitializeSoftwareRendering();
+        }
     }
 
     protected override async void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
@@ -319,9 +326,15 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
         }
     }
 
+    private void InitializeSoftwareRendering()
+    {
+        resources = new SoftwareRenderApiResources(new InteropData());
+    }
+
     public new void InvalidateVisual()
     {
         QueueNextFrame();
+        base.InvalidateVisual();
     }
 
     public void Draw(DrawingSurface texture)
@@ -348,14 +361,14 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
         DrawOverlays(texture, bounds, OverlayRenderSorting.Background);
         try
         {
-            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().ToSKMatrix().ToMatrix3X3();
-            if(!Document.SceneTextures.TryGetValue(ViewportId, out var cachedTexture))
+            if (!Document.SceneTextures.TryGetValue(ViewportId, out var cachedTexture))
                 return;
 
             Matrix3X3 matrixDiff = SolveMatrixDiff(matrix, cachedTexture);
@@ -376,6 +389,7 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
                 {
                     renderedResolution = SceneRenderer.LastRenderedStates[ViewportId].ChunkResolution;
                 }
+
                 texture.Canvas.SetMatrix(matrixDiff);
                 texture.Canvas.Scale((float)renderedResolution.InvertedMultiplier());
                 hasSaved = true;
@@ -890,13 +904,12 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
     {
         if (change.Property == BoundsProperty)
         {
-            QueueNextFrame();
+            QueueRender();
         }
 
         base.OnPropertyChanged(change);
     }
 
-
     private Matrix3X3 SolveMatrixDiff(Matrix3X3 matrix, Texture cachedTexture)
     {
         Matrix3X3 old = cachedTexture.DrawingSurface.Canvas.TotalMatrix;
@@ -923,7 +936,8 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
     {
         try
         {
-            resources = IDrawieInteropContext.Current.CreateResources(compositionDrawingSurface, interop);
+            resources = IDrawieInteropContext.Current.CreateResources(new InteropData(compositionDrawingSurface,
+                interop));
         }
         catch (Exception e)
         {
@@ -943,6 +957,31 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
                     Brushes.White),
                 center);
         }
+
+        if (DrawingBackendApi.Current != null && !DrawingBackendApi.Current.IsHardwareAccelerated)
+            RenderSoftware(context);
+    }
+
+    private void RenderSoftware(DrawingContext context)
+    {
+        if (double.IsNaN(Bounds.Width) || double.IsNaN(Bounds.Height) || Bounds.Width <= 0 || Bounds.Height <= 0)
+            return;
+        RenderFrame(new PixelSize((int)Bounds.Width, (int)Bounds.Height));
+        if (resources?.Texture is AvaloniaBitmapTexture bmp)
+        {
+            unsafe
+            {
+                using var locked = bmp.Bitmap.Lock();
+
+                using var pixmap = framebuffer.PeekPixels();
+                Buffer.MemoryCopy(pixmap.GetPixels().ToPointer(),
+                    locked.Address.ToPointer(),
+                    locked.Size.Width * locked.Size.Height * 4,
+                    pixmap.BytesSize);
+
+                context.DrawImage(bmp.Bitmap, new Rect(0, 0, bmp.Bitmap.PixelSize.Width, bmp.Bitmap.PixelSize.Height));
+            }
+        }
     }
 
     protected async Task FreeGraphicsResources()