Skip to content

Commit

Permalink
feat: Use XamlRoot.RasterizationScale in GTK renderers
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinZikmund committed Apr 22, 2024
1 parent 1fb6bf3 commit 267be8c
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 22 deletions.
11 changes: 10 additions & 1 deletion src/Uno.UI.Runtime.Skia.Gtk/Helpers/Dpi/DpiHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
using Gtk;
using Uno.Helpers;
using Uno.UI.Runtime.Skia.Gtk.Helpers.Windows;
using Uno.UI.Runtime.Skia.Gtk.UI.Controls;
using Windows.Graphics.Display;

namespace Uno.UI.Runtime.Skia.Gtk.Helpers.Dpi;

internal class DpiHelper
{
private readonly StartStopEventWrapper<EventHandler> _dpiChangedWrapper;
private readonly UnoGtkWindow _window;

private float? _dpi;

Expand All @@ -18,6 +20,11 @@ public DpiHelper()
_dpiChangedWrapper = new(StartDpiChanged, StopDpiChanged);
}

public DpiHelper(UnoGtkWindow window) : this()
{
_window = window;
}

public event EventHandler DpiChanged
{
add => _dpiChangedWrapper.AddHandler(value);
Expand All @@ -43,7 +50,7 @@ private void StopDpiChanged()
GetWindow().Screen.SizeChanged -= OnScreenSizeChanged;
}

private Window GetWindow() => GtkHost.Current.InitialWindow;
private Window GetWindow() => _window ?? GtkHost.Current.InitialWindow;

private void OnWindowConfigure(object o, ConfigureEventArgs args) => CheckDpiUpdate();

Expand Down Expand Up @@ -83,4 +90,6 @@ internal float GetNativeDpi()
}
return dpi;
}

internal float RasterizationScale => (_dpi ?? GetNativeDpi()) / DisplayInformation.BaseDpi;
}
21 changes: 12 additions & 9 deletions src/Uno.UI.Runtime.Skia.Gtk/Rendering/GLRenderSurfaceBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Uno.UI.Hosting;
using Microsoft.UI.Composition;
using Uno.UI.Runtime.Skia.Gtk.Hosting;
using Microsoft.UI.Xaml;

namespace Uno.UI.Runtime.Skia.Gtk
{
Expand All @@ -32,7 +33,6 @@ internal abstract partial class GLRenderSurfaceBase : GLArea, IGtkRenderer
/// </summary>
private const int GuardBand = 1;

private readonly DisplayInformation _displayInformation;
private readonly IGtkXamlRootHost _host;

private float? _scale = 1;
Expand All @@ -47,14 +47,14 @@ internal abstract partial class GLRenderSurfaceBase : GLArea, IGtkRenderer
/// In order to avoid virtual calls to <see cref="ClearOpenGL"/> and <see cref="FlushOpenGL"/> for performance reasons.
/// </remarks>
protected bool _isGLES;
private readonly XamlRoot _xamlRoot;

public SKColor BackgroundColor { get; set; }

public GLRenderSurfaceBase(IGtkXamlRootHost host)
{
var xamlRoot = GtkManager.XamlRootMap.GetRootForHost(host);
_displayInformation = WUX.XamlRoot.GetDisplayInformation(xamlRoot);
_displayInformation.DpiChanged += OnDpiChanged;
_xamlRoot = GtkManager.XamlRootMap.GetRootForHost(host) ?? throw new InvalidOperationException("XamlRoot must not be null when renderer is initialized");
_xamlRoot.Changed += OnXamlRootChanged;
UpdateDpi();

// Set some event handlers
Expand Down Expand Up @@ -180,9 +180,6 @@ private void GLFlush()

protected abstract GRContext TryBuildGRContext();

private void OnDpiChanged(DisplayInformation sender, object args) =>
UpdateDpi();

public void TakeScreenshot(string filePath)
{
if (_surface != null)
Expand All @@ -195,10 +192,16 @@ public void TakeScreenshot(string filePath)
}
}

private void OnXamlRootChanged(XamlRoot sender, XamlRootChangedEventArgs args) => UpdateDpi();

private void UpdateDpi()
{
_scale = (float)_displayInformation.RawPixelsPerViewPixel;
InvalidateRender();
var newScale = (float)_xamlRoot.RasterizationScale;
if (_scale != newScale)
{
_scale = newScale;
InvalidateRender();
}
}
}
}
32 changes: 20 additions & 12 deletions src/Uno.UI.Runtime.Skia.Gtk/Rendering/SoftwareRenderSurface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,21 @@
using Windows.Graphics.Display;
using Microsoft.UI.Xaml;
using Uno.UI.Runtime.Skia.Gtk.Hosting;
using Pango;
using Context = Cairo.Context;

namespace Uno.UI.Runtime.Skia.Gtk;

internal class SoftwareRenderSurface : DrawingArea, IGtkRenderer
{
private readonly DisplayInformation _displayInformation;
private SKSurface? _surface;
private SKBitmap? _bitmap;
private int _bheight, _bwidth;
private ImageSurface? _gtkSurface;
private int renderCount;

private float _dpi = 1;

private float _scale = 1;
private XamlRoot _xamlRoot;
private readonly SKColorType _colorType;
private readonly IGtkXamlRootHost _host;

Expand All @@ -36,9 +37,8 @@ internal class SoftwareRenderSurface : DrawingArea, IGtkRenderer

public SoftwareRenderSurface(IGtkXamlRootHost host)
{
var xamlRoot = GtkManager.XamlRootMap.GetRootForHost(host);
_displayInformation ??= XamlRoot.GetDisplayInformation(xamlRoot);
_displayInformation.DpiChanged += OnDpiChanged;
_xamlRoot = GtkManager.XamlRootMap.GetRootForHost(host) ?? throw new InvalidOperationException("XamlRoot must not be null when renderer is initialized");
_xamlRoot.Changed += OnXamlRootChanged;
UpdateDpi();

_colorType = SKImageInfo.PlatformColorType;
Expand All @@ -57,8 +57,6 @@ public SoftwareRenderSurface(IGtkXamlRootHost host)

public void InvalidateRender() => QueueDrawArea(0, 0, 10000, 10000);

private void OnDpiChanged(DisplayInformation sender, object args) => UpdateDpi();

protected override bool OnDrawn(Context cr)
{
Stopwatch? sw = null;
Expand All @@ -69,8 +67,8 @@ protected override bool OnDrawn(Context cr)
this.Log().Trace($"Render {renderCount++}");
}

var scaledWidth = (int)(AllocatedWidth * _dpi);
var scaledHeight = (int)(AllocatedHeight * _dpi);
var scaledWidth = (int)(AllocatedWidth * _scale);
var scaledHeight = (int)(AllocatedHeight * _scale);

// reset the surfaces (skia/cairo) and bitmap if the size has changed
if (_surface == null || scaledWidth != _bwidth || scaledHeight != _bheight)
Expand All @@ -93,7 +91,7 @@ protected override bool OnDrawn(Context cr)
using (new SKAutoCanvasRestore(canvas, true))
{
canvas.Clear(BackgroundColor);
canvas.Scale(_dpi);
canvas.Scale(_scale);

if (_host.RootElement?.Visual is { } rootVisual)
{
Expand Down Expand Up @@ -130,5 +128,15 @@ public void TakeScreenshot(string filePath)
_bitmap?.Encode(wstream, SKEncodedImageFormat.Png, 100);
}

private float UpdateDpi() => _dpi = (float)_displayInformation.RawPixelsPerViewPixel;
private void OnXamlRootChanged(XamlRoot sender, XamlRootChangedEventArgs args) => UpdateDpi();

private void UpdateDpi()
{
var newScale = (float)_xamlRoot.RasterizationScale;
if (_scale != newScale)
{
_scale = newScale;
InvalidateRender();
}
}
}

0 comments on commit 267be8c

Please sign in to comment.