avoid issues with failure to create gl surface#1642
Conversation
|
Maybe this could be using some sort of ref counting already happening at the skia level? |
|
BTW, the ref counting seems to completely avoid the error with not being able to create the surface. That appears to be driven by the fact that the shared display was terminated while a panel was still running. When it got a composition scale change it would try to reacquire a surface and its display would be cleaned up, I gather. The remaining issue is that it seems like calling AbandonContext(true) (or Dispose without any context abandonment) results in some sort of resource being cleaned up that another context from the same display needs. I suspect it might be disconnection from the GPU? But I'm uncertain how to detect things have wound up in a bad state to recover. Calling AbandonContext(false) avoids the issue, but I'm not sure what the difference is between:
|
|
I tried with AbandonContext(true) and the memory pressure didn't seem to perform any differently. |
|
Thanks for keeping up with this. Since my GL knowledge is a tad bit low, I see where I went wrong based on what you did here. Looking at the docs:
https://khronos.org/registry/EGL/sdk/docs/man/html/eglGetPlatformDisplay.xhtml So we do need to actually track these... Might just be able to put all this in some ConcurrentDictionary so we don't have to deal with locks and whatnot. I'll have a closer look and see if there is a better way. With regards to
|
|
In fact, looking at the implementation of Since this represents a hardware thing and not windows of physical displays, we can probably do the same thing. Especially since if the smarter people on the WinObjC side used one display, who are we to doubt? Unless in your testing you got more than one display?
https://www.khronos.org/registry/implementers_guide.html#negldisplay |
|
Overall, good work and I am moving this to the next release so we can have a better UWP experience. |
|
Hmm... from what I could tell though, is that if we had two |
|
For the display, I was just coding defensively since I wasn't sure if the handle would be the same in all scenarios. Sounds like it could be static or a singleton then. |
abandonContext(false) when display is stiatc.
|
Ok @mattleibow I changed display to static and I was able to revert to Note, though, that with this change the display will never get terminated, although they didn't seem to be doing that in WinObjC |
|
Hmm... I'll have to double check this later. Find it a bit odd that it worked with true... Maybe the dependency wasn't updating in my sample. |
Must be more too this.
|
yeah, I was right, there is still an issue with AbandonContext(true), seems to be cleaning up something that kills other existing GrContext. |
|
What happens if you don't call abandon? Looking at the comment closer, it says this:
This is not the case for our views. We are disposing |
|
If I skip calling |
|
Interestingly, all initially seems well with the Abandon dropped, but the Dispose retained, until you change the composition scale by applying a render transform (see my repro code). I'm betting that is causing the interleaved timing again that I described in the bug #1573 |
|
@mattleibow is there a special trick to getting it to download the externals as of your change to add the |
|
@gmurray81 I was just tweaking the build script to support a better way of downloading the native bits. However, once CI is green again for main (in a few minutes) then you can run: This will pull the latest native artifacts from the last green build of There are also args to control which branch or sha to use: |
|
I see what you mean with things looking like they still work when using I am also building a Debug skia to see if there are any errors/asserts being thrown from that side. |
|
Sounds good. I had tried to use IsAbandoned to see if anything was possible at that end, but I don't think the downloaded externals included it yet. Still, as I was saying, I would be somewhat concerned that you may have two swap chain panels warring over destroying the resources if we tried to just recover the resources if destroyed, so may be better to just make sure the cleanup happens in the right sequence. |
|
The externals should have it now. There was a problem with CI a few days ago, but that is all fixed now. But with regards to this issue, if these changes in this PR are working for you, then I think I will merge until there is a better fix. I am not quite sure what is going on yet since none of the other platforms need |
|
Yeah, I'd say it may make sense to merge it until something better is found. |
Expand the skill's scan taxonomy from 6 to 12 families, each backed by a real historical SkiaSharp leak fix (finalizer/collection ordering #3796/#3291, Clone double-free #2904, disposing native statics #1863/#4080/#1224, field-not-nulled #1256/#1344, stream/callback/delegate-proxy lifetime #3589/#2916/#996, allocation-failure #1784/#1642). Broaden Phase 1.3 de-dup to search by api/type name (real leaks are filed as [BUG], not [memory-leak]) and add the Blob.FromStream / PR #3473 worked example. Extend the Phase 3.2 fix table to cover all 12 families. Document two verified, un-filed family-6 candidates surfaced by a model-diverse scan (SKRegion.SpanIterator missing parent ref; SKPixmap.ExtractSubset/With* not propagating pixelSource). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Avoiding issues with failure to create GL surface in UWP
Note, I don't think this is complete, but I want to demonstrate what seems to be necessary to avoid the UWP issues with having multiple SKSwapChainPanels with interleaved creation/destruction.
NOTE for demonstration purposes I removed some cleanup of the GrContext from the panel. This is most likely not valid, but I'm demonstrating what was required to make the behavior correct so that someone with more Skia engine knowledge might use that to find the root cause.
Bugs Fixed
API Changes
Behavioral Changes
There is now some ref-counting and locking around obtaining the display within the GL init. This appears to be required because a shared display handle will be returned, and this should not be cleaned up when one of the panels dies if other panels are still alive. I'm not sure if ref counting is the right approach or if the panels should detect that the display is invalid and re-initalize their graphics contexts.
PR Checklist