Open JaggerJo opened 10 months ago
Do you log unhandled excepctions already? https://docs.avaloniaui.net/docs/next/concepts/unhandledexceptions
If I debug your sample, I get
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
So I think due to fast resizing some memory is not yet freed.
If I debug your sample, I get
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
So I think due to fast resizing some memory is not yet freed.
Yeah, that's it.
Do you think the error (memory not yet freed) is in my code or in Avalonia?
Any tips on how to proceed?
Thanks Tim!
Could even be an issue in SkiaSharp. Tbh, I have no clue where to best fix that issue. If I were you, I'd clone the Avalonia source and place the sample you have into src/samples/Sandbox
. Then you could try to debug it there and see if the debugger stops anywhere in the Avalonia source.
Also you could try to dispose the objects asap. means instead of using var ...
you may want to wrap all into using blocks. See: https://www.damirscorner.com/blog/posts/20200103-BeCarefulWithUsingDeclarationsInCSharp8.html
To help debugging: add a GC.Collect()
call at the end of the custom rendering code to force finalizers to run. Then resize your window: the crash should reproduce immediately. (It's usually in SKImage
's finalizer, so it looks like a double free issue.)
With this, you should be able to trim down your code to narrow down the part causing the crash.
@MrJul adding GC.Collect()
does not make it fail instantly.
Sorry, put it right after the if (_acrylicNoiseShader == null)
block, like this:
Then resize, 100% repro here (on Windows though).
I thought at first it was the SKBitmap
from the acrylic noise shader being disposed when the shader is drawn, but removing the using doesn't solve the problem. At least you should have a base to debug now :)
@MrJul aha, yeah - also fails immediately when I resize on macOS.
@MrJul It really is the bitmap. But even keeping the bitmap around (as a class field, never disposing it) still crashes.
Can you try not to dispose it via using pattern? You can also try not the load the bitmap on each render. And just load it in your control once.
@Gillibald loading the SKBitmap only once (in the constructor) and keeping a reference to it in a private field still crashes.
Probably some SkiaSharp bug. Can you try to wrap the stream inside some SKData
instance and use that for SKBitmap.Decode
?
I can not test this myself at the moment. Try to keep that SKData alive.
@Gillibald still crashes immediately after resizing
@JaggerJo I'm sharing this sample as I like the design very much. Maybe someone finds even the solution :-). I hope you don't mind.
I see that the exception occurs on the following line but I don't understand why.
I'm getting an access violation error from SkiaApi. I downgraded Avalonia to 11.0.4 and the error has gone. 11.0.5 uses SkiaSharp 2.88.6 and 11.0.4 uses 2.88.3. I guess SkiaSharp 2.88.6 is causing the problems.
@calee88 probably yes. In that case it is a bug in a dependency. Due to a vulnerability we had to upgrade in a short time. See #13109 for reference.
Can you double-check using this PR? #12729
https://github.com/mono/SkiaSharp/issues/2456 seems to be the root cause to me
any updates? without a fix it's impossible to use ICustomDrawOperation
@FoggyFinder please ask this in the linked dependency issue.
@FoggyFinder please ask this in the linked dependency issue.
@timunie not confident issue you've mentioned is related. TS wrote - "If i make the method synchronous by taking out the await, then I cannot reproduce the error".
SKBitmap bitmap = ImageMethods.Instance.Create8BitSKBitmapFromSingleArray(singleArray, 0, width * height, colorTable);
await DisplayAlert("Something", "Ask Something", "Yes");
return bitmap.Copy();
So at least there was easy workaround. Pretty sure snippet above can be easily rewritten in thread-safe manner as well.
Q: how to execute something on render thread ?
public void Render(ImmediateDrawingContext context)
{
var leaseFeature = context.TryGetFeature<ISkiaSharpApiLeaseFeature>();
if (leaseFeature is not null)
{
using var lease = leaseFeature.Lease();
lease.SkCanvas.Clear(SKColors.Green);
// Do something on Ui thread with canvas - access violation
// resize window to speed up crash
Dispatcher.UIThread.InvokeAsync(() => { lease.SkCanvas.Clear(SKColors.Red); });
}
}
so Q is: how to ensure operation is executed on render thread?
I tried to add .With(new Win32PlatformOptions { ShouldRenderOnUIThread = true })
but it didn't work
Describe the bug
Custom render operation throws access violation exception. Can't figure out if/ what I'm doing wrong.
To Reproduce
Run the attached project and resize the window for a while. Sometimes it fails after a few seconds, sometimes it takes a few minutes. (you need to keep resizing).
At some point the app crashes.
Expected behavior
I'd expect the app to not crash, or an exception I can work with :D
Screenshots
Environment
Additional context
I'm probably doing something wrong in the custom drawing operation. I just have no clue where to look.
Archive.zip