AvaloniaUI / Avalonia.Labs

Experimental Controls for Avalonia
MIT License
194 stars 25 forks source link

Any guidance on how to create a rendering loop with SKCanvasView? #73

Closed kpko closed 2 months ago

kpko commented 3 months ago

Hi!

The SkiaSharp.Views.Blazor SKCanvasView has a property "UseRenderLoop" that can be set to true, so that the control renders with the screen refresh rate if visible.

Avalonias experimental SKCanvasView doesn't yet have such a property, I've tried implementing it myself in a very naive way using a PeriodicTimer.

// MainWindow with a SKCanvasView named "CanvasView"
private PeriodicTimer _timer = new(TimeSpan.FromSeconds(1) / 60);
private void Control_OnLoaded(object? sender, RoutedEventArgs e)
{
    Task.Run(async () =>
    {
        while (await _timer.WaitForNextTickAsync(_cts.Token))
        {
            CanvasView.InvalidateSurface();
        }
    });
}

This way skyrockets the cpu usage of the application to 50% on my Macbook Pro M1 which makes me think the method still has a bit overhead. Are my assumptions wrong? Is there a way the method could be called repeatedly without suffering high cpu usage?

Also, are there any plans to "promote" the SKCanvasView to a regular Avalonia control? It would be great to have the same SKCanvasView and maybe the SKGLView that also exist in other SkiaSharp Views implementations.

Thank you very much!

maxkatz6 commented 3 months ago

Consider using build-in skia interop using ICustomDrawOperation + ISkiaSharpApiLeaseFeature. See https://github.com/AvaloniaUI/Avalonia/blob/master/samples/RenderDemo/Pages/CustomSkiaPage.cs

But instead of Dispatcher.UIThread.InvokeAsync(InvalidateVisual, DispatcherPriority.Background); it might be better now to use TopLevel.GetTopLevel(this).RequestAnimationFrame(_ => InvalidateVisual()) (top level can be cached/reused from OnAttachedToVisualTree method).

Also, are there any plans to "promote" the SKCanvasView to a regular Avalonia control

Not really, as we don't want to depend on SkiaSharp in base projects. It can be a separated package though.

kpko commented 2 months ago

I see how depending on SkiaSharp would not be helpful in the base projects. A separate package with a Control that brings the CustomSkiaPage example and the existing SKCanvasView together would be great to give new users a better starting point for custom drawing. I will close this issue as I'm totally fine using the suggested solution, thank you!