Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XamlRoot.RasterizationScale is 2.88 on iPhone Mini 13 instead of 3 #16793

Open
inforithmics opened this issue May 20, 2024 · 4 comments
Open
Assignees
Labels
area/windowing Categorizes an issue or PR as relevant to window management difficulty/tbd Categorizes an issue for which the difficulty level needs to be defined. kind/bug Something isn't working triage/untriaged Indicates an issue requires triaging or verification

Comments

@inforithmics
Copy link

inforithmics commented May 20, 2024

Current behavior

RasterizationScale is 2.88 instead of 3 causing Touches to be some pixels off on iPhone Mini 13 on iOS 15.5 in the Simulator. On other devices it works.

Expected behavior

RasterizationScale is 3 causing Touches to be at the correct position. Could be an SkiaSharp issue that somehow the Density is calculated different on iPhone Mini 13 in Simulator.

How to reproduce it (as minimally and precisely as possible)

public sealed partial class MainPage : Page
{
    private readonly List<SKPoint> points;
    private readonly SKXamlCanvas _canvas;
    
    public MainPage()
    {
        this.InitializeComponent();
        points = new List<SKPoint>();
        _canvas = new SKXamlCanvas();
        _canvas.PaintSurface += DrawingCanvas_OnPaintSurface;
        _canvas.PointerPressed += DrawingCanvas_PointerPressed;
        _canvas.Background = new SolidColorBrush(Colors.Transparent);
        _canvas.HorizontalAlignment = HorizontalAlignment.Stretch;
        _canvas.VerticalAlignment = VerticalAlignment.Stretch;
        Background = new SolidColorBrush(Colors.White);
        Content = _canvas;
    }
    
    private double GetPixelDensity() => XamlRoot?.RasterizationScale ?? 1d;
    
    private void DrawingCanvas_PointerPressed(object sender, PointerRoutedEventArgs e)
    {
        // Get the position of the mouse click
        var position = e.GetCurrentPoint(_canvas).Position;
        var density = XamlRoot?.RasterizationScale ?? 1d;
        var x = Convert.ToSingle(position.X * density);
        var y = Convert.ToSingle(position.Y * density);
        points.Add(new SKPoint(x, y));
        _canvas.Invalidate();
    }
    
    private void DrawingCanvas_OnPaintSurface(object? sender, SKPaintSurfaceEventArgs e)
    {
        SKSurface surface = e.Surface;
        SKCanvas canvas = surface.Canvas;
        canvas.Clear(SKColors.White);
        using SKPaint paint = new SKPaint();
        paint.Color = SKColors.Blue;
        paint.Style = SKPaintStyle.Fill;
        
        foreach (var point in points) canvas.DrawCircle(point, 5, paint);
    }
}

Workaround

None yet except detecting iPhone Mini and taking 3 instead of 2.88 as the density.

Works on UWP/WinUI

Yes

Environment

Uno.UI / Uno.UI.WebAssembly / Uno.UI.Skia

NuGet package version(s)

5.2.132

Affected platforms

iOS

IDE

Visual Studio 2022

IDE version

17.10

Relevant plugins

Resharper

Anything else we need to know?

Reproduction Sample, Start it in iPhone Mini 13 Simulator comes with 15.5 SDK Devices.
UnoClick.zip

@inforithmics inforithmics added difficulty/tbd Categorizes an issue for which the difficulty level needs to be defined. kind/bug Something isn't working triage/untriaged Indicates an issue requires triaging or verification labels May 20, 2024
@Youssef1313 Youssef1313 added the area/windowing Categorizes an issue or PR as relevant to window management label May 20, 2024
@jeromelaban
Copy link
Member

The NativeScale reported by the OS is 2.88, using the UIScreen.MainScreen.NativeScale. SkiaSharp is using the same density calculation using DisplayInformation.LogicalDpi which returns 2.88 as well.

Not sure where this issue comes from.

@MartinZikmund MartinZikmund self-assigned this May 22, 2024
@MartinZikmund
Copy link
Member

This is something I should look into, but I will get to it on Sunday at the earliest. If someone else has capacity to look into it, I am able to provide some pointers

@MartinZikmund MartinZikmund changed the title XamlRoot.RasterizationScale is 2.88 on iPhone Mini 13 instead of 3 XamlRoot.RasterizationScale is 2.88 on iPhone Mini 13 instead of 3 May 22, 2024
@inforithmics
Copy link
Author

I tested some things out and found a fix / workaround

private void DrawingCanvas_PointerPressed(object sender, PointerRoutedEventArgs e)
{
    // Get the position of the mouse click
    var position = e.GetCurrentPoint(_canvas).Position;
    // var density = XamlRoot?.RasterizationScale ?? 1d;
    var density = _canvas.CanvasSize.Width / _canvas.ActualWidth;
    var x = Convert.ToSingle(position.X * density);
    var y = Convert.ToSingle(position.Y * density);
    points.Add(new SKPoint(x, y));
    _canvas.Invalidate();
}

So the solution / workaround is to calculate the density of the _canvas and then it works, so it seems the SKCanvas has a different density than the RasterizationScale.

@inforithmics
Copy link
Author

inforithmics commented May 22, 2024

When I implemented this workaround / Fix in mapsui I discovered something strange.
When I use the SKSwapChainPanel
var density = _canvas.CanvasSize.Width / _canvas.ActualWidth; is 2.88
As it should be but the Rendering is totally broken, as it seems it doesn't fill out the whole area.

Rendering with Canvas
image
Rendering with SwapChainPanel
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/windowing Categorizes an issue or PR as relevant to window management difficulty/tbd Categorizes an issue for which the difficulty level needs to be defined. kind/bug Something isn't working triage/untriaged Indicates an issue requires triaging or verification
Projects
None yet
Development

No branches or pull requests

4 participants