Hello, there seems to be some sort of leak when repeatedly using the DrawingContext.DrawGeometry method to fill geometries with different shapes.
To reproduce, add the following Control to an empty Window:
public class TestControl : Control
{
Point mousePosition = new Point();
Random rnd = new Random();
int segmentCount = 20;
double radius = 100;
protected override void OnPointerMoved(PointerEventArgs e)
{
mousePosition = e.GetPosition(this);
this.InvalidateVisual();
}
public override void Render(DrawingContext context)
{
//So that we capture the PointerMoved events
context.FillRectangle(Brushes.White, new Rect(0, 0, this.Bounds.Width, this.Bounds.Height));
PathFigure fig = new PathFigure() { StartPoint = new Point(mousePosition.X + radius, mousePosition.Y) };
for (int i = 0; i < segmentCount; i++)
{
//Geometry always has the same shape: no leak
//fig.Segments.Add(new LineSegment() { Point = new Point(mousePosition.X + radius * Math.Cos(i * 2 * Math.PI / segmentCount), mousePosition.Y + radius * Math.Sin(i * 2 * Math.PI / segmentCount)) });
//Geometry shape changes at every redraw: leak!
fig.Segments.Add(new LineSegment() { Point = new Point(mousePosition.X + radius * Math.Cos(i * 2 * Math.PI / segmentCount) * rnd.NextDouble(), mousePosition.Y + radius * Math.Sin(i * 2 * Math.PI / segmentCount) * rnd.NextDouble()) });
}
fig.IsClosed = true;
PathGeometry testGeometry = new PathGeometry();
testGeometry.Figures.Add(fig);
//Stroke: no leak
//context.DrawGeometry(null, new Pen(Brushes.Blue), testGeometry);
//Fill: leak!
context.DrawGeometry(Brushes.Blue, null, testGeometry);
}
}
Then run the program and quickly move the mouse around in the window. Each time the mouse moves, the control is repainted with a geometry with a different (random) shape; at the same time, the memory usage will go up steadily.
I had a look with the profiler, and it seems to be mostly unmanaged memory:

That Dictionary<IntPtr, WeakReference> SkiaSharp.HandleDictionary.instances looks suspicious...
I first noticed this while using AvaloniaEdit: the SelectionLayer there draws the text selection using DrawGeometry, and this causes the control to use increasing amounts of memory as the user selects text regions with different shapes.
The issue:
geometries dont get disposed @kekekeks @grokys
Hmm, I was unable to repro this on master:

I wonder if it's been fixed at some point?
@danwalmsley is there anything you've committed that might have fixed this?
@arklumpus could you try with current master, or preview 4 if you're unable to? Could be that it's machine dependent somehow?
SKPath isn't registered anywhere so the weak references held in a dictionary can't be an issue. Probably an older SkiaSharp version being used.
Just tried with preview 3 and can indeed repro. Seems to be fixed in preview 4.
Not sure what's changed there, though we have updated SkiaSharp, which I assume must be it as the Dictionary<IntPtr, WeakReference> is in SkiaSharp.
BTW, thanks for the fantasic repro @arklumpus !
Preview 4 fixes it for me too, amazing, thank you!
I think there is still some leak, my code, everything is cached:
Got 57.5MB to 1.6GB memory usage jump in seconds.

Most helpful comment
BTW, thanks for the fantasic repro @arklumpus !