diff --git a/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj b/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj
index fe0d10d184..785baeba8a 100644
--- a/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj
+++ b/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj
@@ -44,6 +44,7 @@
KeyTransform.cs
+
diff --git a/src/Gtk/Avalonia.Gtk3/FramebufferManager.cs b/src/Gtk/Avalonia.Gtk3/FramebufferManager.cs
index c2685e8791..0a0a8fe0a6 100644
--- a/src/Gtk/Avalonia.Gtk3/FramebufferManager.cs
+++ b/src/Gtk/Avalonia.Gtk3/FramebufferManager.cs
@@ -10,7 +10,6 @@ namespace Avalonia.Gtk3
class FramebufferManager : IFramebufferPlatformSurface, IDisposable
{
private readonly TopLevelImpl _window;
- private ImageSurfaceFramebuffer _fb;
public FramebufferManager(TopLevelImpl window)
{
_window = window;
@@ -18,25 +17,16 @@ namespace Avalonia.Gtk3
public void Dispose()
{
- _fb?.Deallocate();
+ //
}
public ILockedFramebuffer Lock()
{
if(_window.CurrentCairoContext == IntPtr.Zero)
throw new InvalidOperationException("Window is not in drawing state");
-
- var ctx = _window.CurrentCairoContext;
var width = (int) _window.ClientSize.Width;
var height = (int) _window.ClientSize.Height;
- if (_fb == null || _fb.Width != width ||
- _fb.Height != height)
- {
- _fb?.Dispose();
- _fb = new ImageSurfaceFramebuffer(width, height);
- }
- _fb.Prepare(ctx);
- return _fb;
+ return new ImageSurfaceFramebuffer(_window.CurrentCairoContext, width, height);
}
}
}
diff --git a/src/Gtk/Avalonia.Gtk3/ImageSurfaceFramebuffer.cs b/src/Gtk/Avalonia.Gtk3/ImageSurfaceFramebuffer.cs
index a2b06d0d5e..d1964bf05d 100644
--- a/src/Gtk/Avalonia.Gtk3/ImageSurfaceFramebuffer.cs
+++ b/src/Gtk/Avalonia.Gtk3/ImageSurfaceFramebuffer.cs
@@ -13,10 +13,11 @@ namespace Avalonia.Gtk3
class ImageSurfaceFramebuffer : ILockedFramebuffer
{
private IntPtr _context;
- private IntPtr _surface;
+ private CairoSurface _surface;
- public ImageSurfaceFramebuffer(int width, int height)
+ public ImageSurfaceFramebuffer(IntPtr context, int width, int height)
{
+ _context = context;
_surface = Native.CairoImageSurfaceCreate(1, width, height);
Width = width;
Height = height;
@@ -24,27 +25,17 @@ namespace Avalonia.Gtk3
RowBytes = Native.CairoImageSurfaceGetStride(_surface);
Native.CairoSurfaceFlush(_surface);
}
-
- public void Prepare(IntPtr context)
- {
- _context = context;
- }
-
- public void Deallocate()
- {
- Native.CairoSurfaceDestroy(_surface);
- _surface = IntPtr.Zero;
- }
-
+
public void Dispose()
{
- if(_context == IntPtr.Zero || _surface == IntPtr.Zero)
+ if(_context == IntPtr.Zero || _surface == null)
return;
Native.CairoSurfaceMarkDirty(_surface);
Native.CairoSetSourceSurface(_context, _surface, 0, 0);
Native.CairoPaint(_context);
_context = IntPtr.Zero;
-
+ _surface.Dispose();
+ _surface = null;
}
public IntPtr Address { get; }
diff --git a/src/Gtk/Avalonia.Gtk3/Interop/CairoSurface.cs b/src/Gtk/Avalonia.Gtk3/Interop/CairoSurface.cs
new file mode 100644
index 0000000000..7838be9305
--- /dev/null
+++ b/src/Gtk/Avalonia.Gtk3/Interop/CairoSurface.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Avalonia.Gtk3.Interop
+{
+ class CairoSurface : SafeHandle
+ {
+ public CairoSurface() : base(IntPtr.Zero, true)
+ {
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ Native.CairoSurfaceDestroy(handle);
+ return true;
+ }
+
+ public override bool IsInvalid => handle == IntPtr.Zero;
+ }
+}
diff --git a/src/Gtk/Avalonia.Gtk3/Interop/Native.cs b/src/Gtk/Avalonia.Gtk3/Interop/Native.cs
index bf66ef0cbb..cffdebeeab 100644
--- a/src/Gtk/Avalonia.Gtk3/Interop/Native.cs
+++ b/src/Gtk/Avalonia.Gtk3/Interop/Native.cs
@@ -110,25 +110,25 @@ namespace Avalonia.Gtk3.Interop
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)]
- public delegate IntPtr cairo_image_surface_create(int format, int width, int height);
+ public delegate CairoSurface cairo_image_surface_create(int format, int width, int height);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)]
- public delegate IntPtr cairo_image_surface_get_data(IntPtr surface);
+ public delegate IntPtr cairo_image_surface_get_data(CairoSurface surface);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)]
- public delegate int cairo_image_surface_get_stride(IntPtr surface);
+ public delegate int cairo_image_surface_get_stride(CairoSurface surface);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)]
- public delegate void cairo_surface_mark_dirty(IntPtr surface);
+ public delegate void cairo_surface_mark_dirty(CairoSurface surface);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)]
- public delegate void cairo_surface_flush(IntPtr surface);
+ public delegate void cairo_surface_flush(CairoSurface surface);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)]
public delegate void cairo_surface_destroy(IntPtr surface);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)]
- public delegate void cairo_set_source_surface(IntPtr cr, IntPtr surface, double x, double y);
+ public delegate void cairo_set_source_surface(IntPtr cr, CairoSurface surface, double x, double y);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)]
public delegate void cairo_paint(IntPtr context);