Hi
In a WPF app i use skiasharp to write spokes to a circle via the GPU, i create my grcontext all works allrigth
but if do not update the Canvas that i get in PaintSurface from SKElement, every operation on the surface created from grcontext consumes memory without releaseing it.
se code
<wpf:SKElement x:Name="BitmapHost" PaintSurface="OnPaintCanvas" />
private void OnPaintCanvas(object sender, SKPaintSurfaceEventArgs e)
{
SKCanvas canvas = e.Surface.Canvas;
int width = e.Info.Width;
int height = e.Info.Height;
if (SendScreenImage)
{
var canvasSize = new SKSize(width, height);
if (_screenCanvasSize != canvasSize)
{
_surface?.Dispose();
_grContext?.Dispose();
_grContext = GRContext.Create(GRBackend.OpenGL);
_surface = SKSurface.Create(_grContext, true, new SKImageInfo(width, height));
_screenCanvasSize = canvasSize;
}
MY_Skia_PaintSurfaceCommonNew(TheTarget, _surface, false, ref FirstPaint, QueuDrawings, ref Range, ref LastSend, signalrConnection, sendSpan, broadcastImageArray, false, listOfAllW);
_surface.Canvas.Flush();
// if this is not called memory does not get relased (can it have to with garbage collection??
if (ShowScreenUpdate)
{
canvas.DrawSurface(_surface, new SKPoint(0f, 0f));
}
}
}
Thank You
What version of SkiaSharp are you using? Is this .NET Core or Full Framework?
Also, is it possible to attach a sample that I can have a look at?
You code n this issue seems to be correct, so I can't say what might be causing the issue. What I can say is try not disposing and recreating the GRContext - that is fine to reuse as long as you are still using the same OpenGL context. You just need to re-create the surface.
What happens if you also just draw a blank screen for the GPU - say clear with red. Does it still leak?
Hi Matthew
Thank you for you answer
It is a .NET Core 3.1
SkiaSharp.Views.WPF v1.68.3
SkiaSharp.Views.WindowsForms v1.68.3
SkiaSharp.Views v1.68.3
SkiaSharp.Svg v1.60.0
SkiaSharp.Extended v1.60.0
It's a bit complex aplication, but i will include the code section that causes the trouble. The memory consumption is really fast!
it is really obvious where memory consumes. If I comment out the line in the code surface.Canvas.DrawCircle((int)x, (int)y, 1f, paint); memory is not consumed.
And if i include the above line and call canvas.DrawSurface(_surface, new SKPoint(0f, 0f)); after the call to Skia_PaintSurfaceCommonNeWMinimal it is not consumed.
If i replace the line surface.Canvas.DrawCircle((int)x, (int)y, 1f, paint); with surface.Canvas.Clear( SKColors.Red); memory is NOT consumed
Thank You Peder
I get the _grContext from SkiaOpengl (.NET Framework 4.7.2) like this: private readonly WglContext _glContext = new WglContext();
The SkiaOpengl is part of the soulution and also use the latest SkiaSharp nugets and latest OpenTK 3.2.0.
public static void Skia_PaintSurfaceCommonNeWMinimal( SKSurface surface, bool highResolution, ref bool isFirstPaint, ConcurrentQueue<drawingDataNew> queuDrawings, ref float range, ref DateTime lastSend, HubConnection signalrConnection, TimeSpan sendSpan, bool brodcast = false, bool UseRotateXY = false, List<WeatherObject> weather = null)
{
lock (LockingPaintThread)
{
// var canvas = surface.Canvas;
int width, height;
bool retValue;
drawingDataNew drawdata;
if (highResolution)
{
height = 2048;
width = 2048;
}
else
{
height = 1024;
width = 1024;
}
float canvasHeight = surface.Canvas.LocalClipBounds.Height;
float canvasWidth = surface.Canvas.LocalClipBounds.Width;
if (isFirstPaint)
{
isFirstPaint = false;
}
{
int oldzoom = 0;
int oldangle = 0;
int imgw = 1024;
int imgh = 1024;
int midx, midy;
float scale = 1;
int[] pixel = new int[3];
midx = width / 2 + xOffset;
midy = height / 2 + yOffset;
while (queuDrawings.Count > 0)
{
retValue = queuDrawings.TryDequeue(out drawdata);
if (retValue)
{
if (range != drawdata.range)
{
surface.Canvas.DrawCircle(width / 2f + xOffset, height / 2f + yOffset, width / 2, radarBackGroundPaint);
surface.Canvas.DrawCircle(width / 2f + xOffset, height / 2f + yOffset, 2f, blue);
Skia_WriteRange(surface.Canvas, (int)drawdata.range, "Aldrich-Regular.ttf", new SKPoint(100, 20));
range = drawdata.range;
}
byte[] spoke = new byte[512];
if (highResolution)
spoke = drawdata.dataHighRes;
else
spoke = drawdata.data;
var angle = drawdata.degree;
double rad = ToRadian(angle);
double radcos = Math.Cos(rad);
double radsin = Math.Sin(rad);
int dataLength = 512;
if (highResolution)
dataLength = 1024;
for (int k = 0; k < dataLength; k++)
{
int valpunkt = spoke[k];
{
var paint = theColorWeak;
if (valpunkt == 0)
paint = radarBackGroundPaint;
else if (valpunkt > ThresholdRed)
paint = theColorStrong;
else if (valpunkt > ThresholdGreen)
paint = theColorIntermediate;
float r = k;//*scale;
float x = (float)(midx + radcos * r);
float y = (float)(midy + radsin * r);
paint.IsAntialias = true;
surface.Canvas.DrawCircle((int)x, (int)y, 1f, paint); //// Comment out and memory stops beeing consumed
}
}
spoke = null;
}
drawdata = null;
}
}
}
}
I have the same issue
Same issue here: and found out that calling DrawText seems fine, calling DrawPath causes memory leak.
Most helpful comment
Hi Matthew
Thank you for you answer
It is a .NET Core 3.1
SkiaSharp.Views.WPF v1.68.3
SkiaSharp.Views.WindowsForms v1.68.3
SkiaSharp.Views v1.68.3
SkiaSharp.Svg v1.60.0
SkiaSharp.Extended v1.60.0
It's a bit complex aplication, but i will include the code section that causes the trouble. The memory consumption is really fast!
it is really obvious where memory consumes. If I comment out the line in the code surface.Canvas.DrawCircle((int)x, (int)y, 1f, paint); memory is not consumed.
And if i include the above line and call canvas.DrawSurface(_surface, new SKPoint(0f, 0f)); after the call to Skia_PaintSurfaceCommonNeWMinimal it is not consumed.
If i replace the line surface.Canvas.DrawCircle((int)x, (int)y, 1f, paint); with surface.Canvas.Clear( SKColors.Red); memory is NOT consumed
Thank You Peder
I get the _grContext from SkiaOpengl (.NET Framework 4.7.2) like this: private readonly WglContext _glContext = new WglContext();
The SkiaOpengl is part of the soulution and also use the latest SkiaSharp nugets and latest OpenTK 3.2.0.