Browse Source

[GTK3] Fixed DPI support for DeferredRenderer

repro/dynamic-resource-bug
Nikita Tsukanov 9 years ago
parent
commit
088fc6fc56
  1. 2
      src/Gtk/Avalonia.Gtk3/FramebufferManager.cs
  2. 26
      src/Gtk/Avalonia.Gtk3/ImageSurfaceFramebuffer.cs
  3. 6
      src/Gtk/Avalonia.Gtk3/Interop/Native.cs
  4. 3
      src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs

2
src/Gtk/Avalonia.Gtk3/FramebufferManager.cs

@ -27,7 +27,7 @@ namespace Avalonia.Gtk3
var s = _window.ClientSize; var s = _window.ClientSize;
var width = (int) s.Width; var width = (int) s.Width;
var height = (int) s.Height; var height = (int) s.Height;
return new ImageSurfaceFramebuffer(_window, width, height); return new ImageSurfaceFramebuffer(_window, width, height, _window.LastKnownScaleFactor);
} }
} }
} }

26
src/Gtk/Avalonia.Gtk3/ImageSurfaceFramebuffer.cs

@ -19,11 +19,11 @@ namespace Avalonia.Gtk3
private CairoSurface _surface; private CairoSurface _surface;
private int _factor; private int _factor;
private object _lock = new object(); private object _lock = new object();
public ImageSurfaceFramebuffer(WindowBaseImpl impl, int width, int height) public ImageSurfaceFramebuffer(WindowBaseImpl impl, int width, int height, int factor)
{ {
_impl = impl; _impl = impl;
_widget = impl.GtkWidget; _widget = impl.GtkWidget;
_factor = (int)(Native.GtkWidgetGetScaleFactor?.Invoke(_widget) ?? 1u); _factor = factor;
width *= _factor; width *= _factor;
height *= _factor; height *= _factor;
_surface = Native.CairoImageSurfaceCreate(1, width, height); _surface = Native.CairoImageSurfaceCreate(1, width, height);
@ -32,23 +32,21 @@ namespace Avalonia.Gtk3
Height = height; Height = height;
Address = Native.CairoImageSurfaceGetData(_surface); Address = Native.CairoImageSurfaceGetData(_surface);
RowBytes = Native.CairoImageSurfaceGetStride(_surface); RowBytes = Native.CairoImageSurfaceGetStride(_surface);
Native.CairoSurfaceSetDeviceScale(_surface, factor, factor);
Native.CairoSurfaceFlush(_surface); Native.CairoSurfaceFlush(_surface);
} }
static void Draw(IntPtr context, CairoSurface surface, double factor) static void Draw(IntPtr context, CairoSurface surface)
{ {
Native.CairoSurfaceMarkDirty(surface); Native.CairoSurfaceMarkDirty(surface);
Native.CairoScale(context, 1d / factor, 1d / factor);
Native.CairoSetSourceSurface(context, surface, 0, 0); Native.CairoSetSourceSurface(context, surface, 0, 0);
Native.CairoPaint(context); Native.CairoPaint(context);
} }
/* /*
static Stopwatch St =Stopwatch.StartNew(); static Stopwatch St =Stopwatch.StartNew();
private static int _frames; private static int _frames;
private static int _fps;*/ private static int _fps;*/
static void DrawToWidget(GtkWidget widget, CairoSurface surface, int width, int height, double factor) static void DrawToWidget(GtkWidget widget, CairoSurface surface, int width, int height)
{ {
if(surface == null || widget.IsClosed) if(surface == null || widget.IsClosed)
return; return;
@ -58,7 +56,7 @@ namespace Avalonia.Gtk3
var rc = new GdkRectangle {Width = width, Height = height}; var rc = new GdkRectangle {Width = width, Height = height};
Native.GdkWindowBeginPaintRect(window, ref rc); Native.GdkWindowBeginPaintRect(window, ref rc);
var context = Native.GdkCairoCreate(window); var context = Native.GdkCairoCreate(window);
Draw(context, surface, factor); Draw(context, surface);
/* /*
_frames++; _frames++;
var el = St.Elapsed; var el = St.Elapsed;
@ -84,15 +82,13 @@ namespace Avalonia.Gtk3
{ {
private readonly GtkWidget _widget; private readonly GtkWidget _widget;
private CairoSurface _surface; private CairoSurface _surface;
private readonly double _factor;
private readonly int _width; private readonly int _width;
private readonly int _height; private readonly int _height;
public RenderOp(GtkWidget widget, CairoSurface _surface, double factor, int width, int height) public RenderOp(GtkWidget widget, CairoSurface _surface, int width, int height)
{ {
_widget = widget; _widget = widget;
this._surface = _surface; this._surface = _surface;
_factor = factor;
_width = width; _width = width;
_height = height; _height = height;
} }
@ -105,7 +101,7 @@ namespace Avalonia.Gtk3
public void RenderNow() public void RenderNow()
{ {
DrawToWidget(_widget, _surface, _width, _height, _factor); DrawToWidget(_widget, _surface, _width, _height);
} }
} }
@ -116,13 +112,13 @@ namespace Avalonia.Gtk3
if (Dispatcher.UIThread.CheckAccess()) if (Dispatcher.UIThread.CheckAccess())
{ {
if (_impl.CurrentCairoContext != IntPtr.Zero) if (_impl.CurrentCairoContext != IntPtr.Zero)
Draw(_impl.CurrentCairoContext, _surface, _factor); Draw(_impl.CurrentCairoContext, _surface);
else else
DrawToWidget(_widget, _surface, Width, Height, _factor); DrawToWidget(_widget, _surface, Width, Height);
_surface.Dispose(); _surface.Dispose();
} }
else else
_impl.SetNextRenderOperation(new RenderOp(_widget, _surface, _factor, Width, Height)); _impl.SetNextRenderOperation(new RenderOp(_widget, _surface, Width, Height));
_surface = null; _surface = null;
} }
} }

6
src/Gtk/Avalonia.Gtk3/Interop/Native.cs

@ -178,7 +178,10 @@ namespace Avalonia.Gtk3.Interop
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)]
public delegate void cairo_surface_destroy(IntPtr surface); public delegate void cairo_surface_destroy(IntPtr surface);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)]
public delegate void cairo_surface_set_device_scale(CairoSurface surface, double sx, double sy);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)]
public delegate void cairo_set_source_surface(IntPtr cr, CairoSurface surface, double x, double y); public delegate void cairo_set_source_surface(IntPtr cr, CairoSurface surface, double x, double y);
@ -465,6 +468,7 @@ namespace Avalonia.Gtk3.Interop
public static D.cairo_surface_write_to_png CairoSurfaceWriteToPng; public static D.cairo_surface_write_to_png CairoSurfaceWriteToPng;
public static D.cairo_surface_flush CairoSurfaceFlush; public static D.cairo_surface_flush CairoSurfaceFlush;
public static D.cairo_surface_destroy CairoSurfaceDestroy; public static D.cairo_surface_destroy CairoSurfaceDestroy;
public static D.cairo_surface_set_device_scale CairoSurfaceSetDeviceScale;
public static D.cairo_set_source_surface CairoSetSourceSurface; public static D.cairo_set_source_surface CairoSetSourceSurface;
public static D.cairo_set_source_rgba CairoSetSourceRgba; public static D.cairo_set_source_rgba CairoSetSourceRgba;
public static D.cairo_scale CairoScale; public static D.cairo_scale CairoScale;

3
src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs

@ -306,7 +306,7 @@ namespace Avalonia.Gtk3
public IMouseDevice MouseDevice => Gtk3Platform.Mouse; public IMouseDevice MouseDevice => Gtk3Platform.Mouse;
public double Scaling => (double) 1 / (Native.GtkWidgetGetScaleFactor?.Invoke(GtkWidget) ?? 1); public double Scaling => LastKnownScaleFactor = (int) (Native.GtkWidgetGetScaleFactor?.Invoke(GtkWidget) ?? 1);
public IPlatformHandle Handle => this; public IPlatformHandle Handle => this;
@ -387,6 +387,7 @@ namespace Avalonia.Gtk3
public Size ClientSize { get; private set; } public Size ClientSize { get; private set; }
public int LastKnownScaleFactor { get; private set; }
public void Resize(Size value) public void Resize(Size value)
{ {

Loading…
Cancel
Save