Skip to content

[BUG] Scale of ManipulationDelta never changes when using SKSwapChainPanel on IOS #3148

Open
@VRage

Description

Description

There is a weird behaviour when using SKSwapChainPanel on IOS every ManipulationDelta of the Scale is 1. If SKXamlCanvas is used everything works just fine on every platform.

Even though the event is not registered directly on SKSwapChainPanel the e.Delta.Scale is 1.

Code

Codesample is based on the SkiaSharptest sample of uno platform:

SKSwapChainPanelIOS.zip

using Microsoft.UI.Xaml.Input;
using Windows.Foundation;
using SkiaSharp;
using SkiaSharp.Views.Windows;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409

namespace SkiaSharpTest
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        private Point _currentPosition;

        public MainPage()
        {
#if !WINDOWS
            SKSwapChainPanel.RaiseOnUnsupported = false;
#endif

            this.ManipulationDelta += MainPage_ManipulationDelta;

            this.ManipulationMode = ManipulationModes.TranslateX | ManipulationModes.TranslateY | ManipulationModes.Scale;

            this.InitializeComponent();

#if HAS_UNO_SKIA || WINDOWS
            notSupported.Visibility = Visibility.Visible;
#endif
        }

        public float Zoom { get; set; } = 1;

        private void MainPage_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
        {
            Zoom *= e.Delta.Scale;

            if(e.Delta.Scale != 1)
            {
                if (hwAcceleration.IsChecked ?? false)
                {
    #if !WINDOWS
                    swapChain.Invalidate();
    #endif
                }
                else
                {
                    canvas.Invalidate();
                }
            }
        }

        private Visibility Not(bool? value) => (!value ?? false) ? Visibility.Visible : Visibility.Collapsed;

        private void OnPaintSwapChain(object sender, SKPaintGLSurfaceEventArgs e)
        {
            // the the canvas and properties
            var canvas = e.Surface.Canvas;
            var info = e.Info;

            Render(canvas, new Size(info.Width, info.Height), SKColors.Green, "SkiaSharp Hardware Rendering");
            //canvas.Scale(Zoom);

        }

        private void OnPaintSurface(object sender, SKPaintSurfaceEventArgs e)
        {
            // the the canvas and properties
            var canvas = e.Surface.Canvas;
            var info = e.Info;

            Render(canvas, new Size(info.Width, info.Height), SKColors.Yellow, "SkiaSharp Software Rendering");

            //canvas.Scale(Zoom);
        }

        private void OnSurfacePointerMoved(object sender, PointerRoutedEventArgs e)
        {
            _currentPosition = e.GetCurrentPoint(panelGrid).Position;
            currentPositionText.Text = _currentPosition.ToString();
            
            if (hwAcceleration.IsChecked ?? false)
            {
#if !WINDOWS
                swapChain.Invalidate();
#endif
            }
            else
            {
                canvas.Invalidate();
            }
        }

        private void Render(SKCanvas canvas, Size size, SKColor color, string text)
        {
            // get the screen density for scaling
            var scale = (float)this.XamlRoot.RasterizationScale;
            var scaledSize = new SKSize((float)size.Width / scale, (float)size.Height / scale);

            // handle the device screen density
            canvas.Scale(scale*Zoom);

            // make sure the canvas is blank
            canvas.Clear(color);

            // draw some text
            var paint = new SKPaint
            {
                Color = SKColors.Black,
                IsAntialias = true,
                Style = SKPaintStyle.Fill,
                TextAlign = SKTextAlign.Center,
                TextSize = 24
            };
            var coord = new SKPoint(scaledSize.Width / 2, (scaledSize.Height + paint.TextSize) / 2);
            canvas.DrawText(text, coord, paint);

            var circlePaint = new SKPaint
            {
                Style = SKPaintStyle.Fill,
                Color = SKColors.Red
            };

            canvas.DrawCircle((float)_currentPosition.X, (float)_currentPosition.Y, 5, circlePaint);
        }

    }
}

You can also share some XAML:

<Page x:Class="SkiaSharpTest.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:not_win="http://uno.ui/not_win"
      xmlns:local="using:SkiaSharpTest"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:sk="using:SkiaSharp.Views.Windows"
      mc:Ignorable="d not_win"
      Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <StackPanel>
            <CheckBox Content="Hardware Accelerated"
                      x:Name="hwAcceleration" />
            <TextBlock x:Name="currentPositionText" />
        </StackPanel>
        <Grid x:Name="panelGrid"
              Grid.Row="1">
            <not_win:Border>
                <sk:SKSwapChainPanel x:Name="swapChain"
                                     PaintSurface="OnPaintSwapChain"
                                     PointerMoved="{x:Bind OnSurfacePointerMoved}"
                                     
                                     not_win:Background="Transparent"
                                     Visibility="{x:Bind hwAcceleration.IsChecked, Mode=OneWay}" />
            </not_win:Border>
            <TextBlock x:Name="notSupported"
                       Visibility="Collapsed"
                       Text="SKSwapChainPanel is not supported on this platform" />
            <sk:SKXamlCanvas x:Name="canvas"
                             PaintSurface="OnPaintSurface"
                             PointerMoved="{x:Bind OnSurfacePointerMoved}"
                             not_win:Background="Transparent"
                             Visibility="{x:Bind Not(hwAcceleration.IsChecked), Mode=OneWay}" />
        </Grid>
    </Grid>
</Page>

Expected Behavior

No response

Actual Behavior

No response

Version of SkiaSharp

2.88.9 (Previous)

Last Known Good Version of SkiaSharp

Other (Please indicate in the description)

IDE / Editor

Visual Studio (Windows)

Platform / Operating System

iOS

Platform / Operating System Version

iOS 18.0 - 18.3

Devices

No response

Relevant Screenshots

No response

Relevant Log Output

Code of Conduct

  • I agree to follow this project's Code of Conduct

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions