1
0
Эх сурвалжийг харах

Use ImageSurface instead of Pixbuf

Nikita Tsukanov 8 жил өмнө
parent
commit
65686fc002

+ 3 - 1
src/Gtk/Avalonia.Gtk/Avalonia.Gtk.csproj

@@ -30,6 +30,8 @@
     <ConsolePause>false</ConsolePause>
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="Mono.Cairo, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+    </Reference>
     <Reference Include="System" />
     <Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
     <Reference Include="atk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
@@ -50,7 +52,7 @@
     <Compile Include="Embedding\GtkAvaloniaControlHost.cs" />
     <Compile Include="FramebufferManager.cs" />
     <Compile Include="IconImpl.cs" />
-    <Compile Include="PixbufFramebuffer.cs" />
+    <Compile Include="SurfaceFramebuffer.cs" />
     <Compile Include="SystemDialogImpl.cs" />
     <Compile Include="CursorFactory.cs" />
     <Compile Include="GtkExtensions.cs" />

+ 3 - 3
src/Gtk/Avalonia.Gtk/FramebufferManager.cs

@@ -6,7 +6,7 @@ namespace Avalonia.Gtk
     class FramebufferManager : IFramebufferPlatformSurface, IDisposable
     {
         private readonly WindowImplBase _window;
-        private PixbufFramebuffer _fb;
+        private SurfaceFramebuffer _fb;
 
         public FramebufferManager(WindowImplBase window)
         {
@@ -29,8 +29,8 @@ namespace Avalonia.Gtk
             if (_fb == null || _fb.Width != width ||
                 _fb.Height != height)
             {
-                _fb?.Dispose();
-                _fb = new PixbufFramebuffer(width, height);
+                _fb?.Deallocate();
+                _fb = new SurfaceFramebuffer(width, height);
             }
             _fb.SetDrawable(drawable);
             return _fb;

+ 0 - 58
src/Gtk/Avalonia.Gtk/PixbufFramebuffer.cs

@@ -1,58 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Avalonia.Controls.Platform.Surfaces;
-using Avalonia.Platform;
-using Gdk;
-
-namespace Avalonia.Gtk
-{
-    class PixbufFramebuffer : ILockedFramebuffer
-    {
-        private Pixbuf _pixbuf;
-        private Drawable _drawable;
-
-        public PixbufFramebuffer(int width, int height)
-        {
-            _pixbuf = new Pixbuf(Gdk.Colorspace.Rgb, false, 8, width, height);
-        }
-
-        public void SetDrawable(Drawable drawable)
-        {
-            _drawable = drawable;
-        }
-
-        public void Deallocate()
-        {
-            _pixbuf.Dispose();
-            _pixbuf = null;
-        }
-
-        public void Dispose()
-        {
-            using (var gc = new Gdk.GC(_drawable))
-                _drawable.DrawPixbuf(gc, _pixbuf, 0, 0, 0, 0, Width, Height, RgbDither.None, 0, 0);
-            _drawable = null;
-        }
-
-        public IntPtr Address => _pixbuf.Pixels;
-        public int Width => _pixbuf.Width;
-        public int Height => _pixbuf.Height;
-        public int RowBytes => _pixbuf.Rowstride;
-        //TODO: Proper DPI detect
-        public Size Dpi => new Size(96, 96);
-        public PixelFormat Format
-        {
-            get
-            {
-                if (AvaloniaLocator.Current.GetService<IRuntimePlatform>().GetRuntimeInfo().OperatingSystem ==
-                    OperatingSystemType.WinNT)
-                    return PixelFormat.Bgra8888;
-                return PixelFormat.Rgba8888;
-            }
-        }
-    }
-}
-

+ 55 - 0
src/Gtk/Avalonia.Gtk/SurfaceFramebuffer.cs

@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Avalonia.Controls.Platform.Surfaces;
+using Avalonia.Platform;
+using Cairo;
+using Gdk;
+
+namespace Avalonia.Gtk
+{
+    class SurfaceFramebuffer : ILockedFramebuffer
+    {
+        private Drawable _drawable;
+        private ImageSurface _surface;
+
+        public SurfaceFramebuffer(int width, int height)
+        {
+            _surface = new ImageSurface(Cairo.Format.RGB24, width, height);
+        }
+
+        public void SetDrawable(Drawable drawable)
+        {
+            _drawable = drawable;
+            _surface.Flush();
+        }
+
+        public void Deallocate()
+        {
+            _surface.Dispose();
+            _surface = null;
+        }
+
+        public void Dispose()
+        {
+            using (var ctx = CairoHelper.Create(_drawable))
+            {
+                _surface.MarkDirty();
+                ctx.SetSourceSurface(_surface, 0, 0);
+                ctx.Paint();
+            }
+            _drawable = null;
+        }
+
+        public IntPtr Address => _surface.DataPtr;
+        public int Width => _surface.Width;
+        public int Height => _surface.Height;
+        public int RowBytes => _surface.Stride;
+        //TODO: Proper DPI detect
+        public Size Dpi => new Size(96, 96);
+        public PixelFormat Format => PixelFormat.Bgra8888;
+    }
+}
+