I am just starting to learn SkiaSharp to use as an alternative to GDI+ with WinForms on Windows 10. I specifically wanted GPU accelerated 2D graphics, and managed to get SkiaSharp examples running with a GLControl and CreateNativeGlInterface.
The PC is Windows 10, 10-core i7-6950X, with a GTX-1080 ti Founders edition graphics card and a 4K screen.
I started performance testing SkiaSharp by drawing 1000 random lines with random colors, and noticed that when the GLControl is resized to include more than appox 3.145 million pixels, the rendering speed suddenly slowed from 1ms to over 100ms !!!
The length vs width can vary so long as the pixel count doesn't exceed approx 3.145 million pixels ( it's not a height or width limit, it's a pixel limit ).
Example rendering times while slowly expanding the window:
ms: 1, w: 1914, h: 1637, pixels: 3133218
ms: 1, w: 1915, h: 1637, pixels: 3134855
ms: 1, w: 1916, h: 1637, pixels: 3136492
ms: 1, w: 1917, h: 1637, pixels: 3138129
ms: 1, w: 1919, h: 1637, pixels: 3141403
ms: 3, w: 1920, h: 1637, pixels: 3143040
ms: 210, w: 1924, h: 1637, pixels: 3149588
ms: 196, w: 1931, h: 1637, pixels: 3161047
ms: 122, w: 1935, h: 1637, pixels: 3167595
ms: 122, w: 1938, h: 1637, pixels: 3172506
ms: 124, w: 1940, h: 1637, pixels: 3175780
ms: 190, w: 1940, h: 1637, pixels: 3175780
Questions:
Are there any SkiaSharp settings that will prevent such a slow down for drawings in the 2K to 4K size range ?
I want to be able to maximize a drawing screen like this on a 4K monitor, but I don't actually need this much resolution. A blocky looking 1080p stretched drawing would be fine for this app, however the Windows desktop must be native 4K with 100% scaling. How can I lower the pixel resolution of the drawing and scale it to fit a very large canvas without the huge slow down in rendering time ?
Thanks for any suggestions !!
The SKGLControl example source code is here: GitHub SKGLControl
My Source Code:
private void SkglControl1_PaintSurface(object sender, SkiaSharp.Views.Desktop.SKPaintGLSurfaceEventArgs e)
{
var paintStroke = new SKPaint
{
IsAntialias = true,
Style = SKPaintStyle.Stroke,
Color = SKColors.Purple,
StrokeWidth = 1
};
var rand = new Random();
var sw = new Stopwatch();
sw.Start();
e.Surface.Canvas.Clear();
var width = (int)skglControl1.CanvasSize.Width;
var height = (int)skglControl1.CanvasSize.Height;
for (int i = 0; i < 1000; i++)
{
var x1 = rand.Next(width);
var x2 = rand.Next(width);
var y1 = rand.Next(height);
var y2 = rand.Next(height);
paintStroke.Color = new SKColor((byte)rand.Next(255), (byte)rand.Next(255), (byte)rand.Next(255));
e.Surface.Canvas.DrawLine(new SKPoint(x1, y1), new SKPoint(x2, y2), paintStroke);
}
sw.Stop();
Console.WriteLine($"ms: {sw.ElapsedMilliseconds}, w: {width}, h: {height}, pixels: {width * height}");
}