An extension of this question. I'm using SkiaSharp
to draw shapes with OpenGL
. Most of code samples for WPF suggest using SKElement
control and get reference to the drawing surface inside PaintSurface
event. I need reference to drawing surface al the time, not only inside of this event, so I'm using SKBitmap
and SKCanvas
and send the output to Image
control in WPF.
XAML
<Canvas x:Name="ScreenControl" />
CS
var bmp = new SKBitmap((int)ScreenControl.ActualWidth, (int)ScreenControl.ActualHeight);
var canvas = new SKCanvas(bmp);
var image = new Image
{
Stretch = Stretch.Fill
};
canvas.DrawText("Demo", new SKPoint(20, 20), new SKPaint { TextSize = 20 });
var index = 0;
var clock = new Timer();
var wrt = bmp.ToWriteableBitmap();
image.Source = wrt;
clock.Interval = 100;
clock.Elapsed += (object sender, ElapsedEventArgs e) =>
{
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
var wrt = bmp.ToWriteableBitmap(); // Potentially slow line #1
canvas.Clear();
canvas.DrawText((index++).ToString(), new SKPoint(20, 20), new SKPaint { TextSize = 20 });
image.Source = wrt; // Potentially slow line #2
image.InvalidateVisual();
}));
};
clock.Start();
ScreenControl.Children.Clear();
ScreenControl.Children.Add(image);
Project
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net5.0-windows</TargetFramework>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SkiaSharp.Views.WPF" Version="2.80.3-preview.18" />
</ItemGroup>
</Project>
Question
Is there a way to draw faster, specifically, without recreating bitmap bmp.ToWriteableBitmap()
and without changing image source every time image.Source = wrt
? Back buffer or something related?
SKElement
, in that element's PaintSurface event. Something likeprotected override void OnPaintSurface(SKPaintSurfaceEventArgs e) { e.Surface.Canvas.DrawBitmap(bmp, 0, 0); }
– Waybill