csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
4.6 KiB
144 lines
4.6 KiB
using System;
|
|
using Avalonia.Gtk3.Interop;
|
|
using Avalonia.Platform;
|
|
using Avalonia.Threading;
|
|
|
|
|
|
namespace Avalonia.Gtk3
|
|
{
|
|
class ImageSurfaceFramebuffer : ILockedFramebuffer
|
|
{
|
|
private readonly WindowBaseImpl _impl;
|
|
private readonly GtkWidget _widget;
|
|
private ManagedCairoSurface _surface;
|
|
private int _factor;
|
|
private object _lock = new object();
|
|
public ImageSurfaceFramebuffer(WindowBaseImpl impl, int width, int height, int factor)
|
|
{
|
|
_impl = impl;
|
|
_widget = impl.GtkWidget;
|
|
_factor = factor;
|
|
width *= _factor;
|
|
height *= _factor;
|
|
_surface = new ManagedCairoSurface(width, height);
|
|
|
|
Size = new PixelSize(width, height);
|
|
Address = _surface.Buffer;
|
|
RowBytes = _surface.Stride;
|
|
Native.CairoSurfaceFlush(_surface.Surface);
|
|
}
|
|
|
|
static void Draw(IntPtr context, CairoSurface surface, double factor)
|
|
{
|
|
|
|
Native.CairoSurfaceMarkDirty(surface);
|
|
Native.CairoScale(context, 1d / factor, 1d / factor);
|
|
Native.CairoSetSourceSurface(context, surface, 0, 0);
|
|
Native.CairoPaint(context);
|
|
|
|
}
|
|
/*
|
|
static Stopwatch St =Stopwatch.StartNew();
|
|
private static int _frames;
|
|
private static int _fps;*/
|
|
static void DrawToWidget(GtkWidget widget, CairoSurface surface, int width, int height, double factor)
|
|
{
|
|
if(surface == null || widget.IsClosed)
|
|
return;
|
|
var window = Native.GtkWidgetGetWindow(widget);
|
|
if(window == IntPtr.Zero)
|
|
return;
|
|
var rc = new GdkRectangle {Width = width, Height = height};
|
|
Native.GdkWindowBeginPaintRect(window, ref rc);
|
|
var context = Native.GdkCairoCreate(window);
|
|
Draw(context, surface, factor);
|
|
/*
|
|
_frames++;
|
|
var el = St.Elapsed;
|
|
if (el.TotalSeconds > 1)
|
|
{
|
|
_fps = (int) (_frames / el.TotalSeconds);
|
|
_frames = 0;
|
|
St = Stopwatch.StartNew();
|
|
}
|
|
|
|
Native.CairoSetSourceRgba(context, 1, 0, 0, 1);
|
|
Native.CairoMoveTo(context, 20, 20);
|
|
Native.CairoSetFontSize(context, 30);
|
|
using (var txt = new Utf8Buffer("FPS: " + _fps))
|
|
Native.CairoShowText(context, txt);
|
|
*/
|
|
|
|
Native.CairoDestroy(context);
|
|
Native.GdkWindowEndPaint(window);
|
|
}
|
|
|
|
class RenderOp : IDeferredRenderOperation
|
|
{
|
|
private readonly GtkWidget _widget;
|
|
private ManagedCairoSurface _surface;
|
|
private readonly double _factor;
|
|
private readonly int _width;
|
|
private readonly int _height;
|
|
|
|
public RenderOp(GtkWidget widget, ManagedCairoSurface surface, double factor, int width, int height)
|
|
{
|
|
_widget = widget;
|
|
_surface = surface ?? throw new ArgumentNullException(nameof(surface));
|
|
_factor = factor;
|
|
_width = width;
|
|
_height = height;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_surface?.Dispose();
|
|
_surface = null;
|
|
}
|
|
|
|
public void RenderNow(IntPtr? ctx)
|
|
{
|
|
if(ctx.HasValue)
|
|
Draw(ctx.Value, _surface.Surface, _factor);
|
|
else
|
|
DrawToWidget(_widget, _surface.Surface, _width, _height, _factor);
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
lock (_lock)
|
|
{
|
|
if (Dispatcher.UIThread.CheckAccess())
|
|
{
|
|
if (_impl.CurrentCairoContext != IntPtr.Zero)
|
|
Draw(_impl.CurrentCairoContext, _surface.Surface, _factor);
|
|
else
|
|
DrawToWidget(_widget, _surface.Surface, Size.Width, Size.Height, _factor);
|
|
_surface.Dispose();
|
|
}
|
|
else
|
|
_impl.SetNextRenderOperation(new RenderOp(_widget, _surface, _factor, Size.Width, Size.Height));
|
|
_surface = null;
|
|
}
|
|
}
|
|
|
|
public IntPtr Address { get; }
|
|
public PixelSize Size { get; }
|
|
public int RowBytes { get; }
|
|
|
|
|
|
public Vector Dpi
|
|
{
|
|
get
|
|
{
|
|
return new Vector(96, 96) * _factor;
|
|
}
|
|
}
|
|
|
|
public PixelFormat Format => PixelFormat.Bgra8888;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|