-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix polyphonic audio streams with id > 1 cannot be stopped or changed (MSVC mis-optimization) #93120
Conversation
This is not an acceptable name for the commit/PR. Please rename it to meaningful one (like "Fix audio streams with id > 1 cannot be stopped or changed") and squash the commits. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this logic is removed, then these two lines in the header should be removed as well:
godot/scene/resources/audio_stream_polyphonic.h
Lines 59 to 60 in 475248d
ID_MASK = 0xFFFFFFFF, | |
INDEX_SHIFT = 32 |
Why was it saving/using index in the first place? It might be performance critical, and in this case it's better to keep it, check index first and then fallback to the full list search instead of removing it completely.
I thought about that for quite a while and my only conclusions was that whoever did it consider some use cases but forgot the delete song case or maybe in the moment it was implemented that case was not possible.
We need serious data for this, and I personally do not have it. I thought of the cases about how I did/will use it in my games and how it will be impacted. So my assumptions were:
If you want to reduce the linear access time, a hash function or AVL tree (or similar) should be used instead. Is there any data about number of streams and how often are they accessed given the id? |
There is a second approach that can be taken which I think it is interesting. The streams vector:
contains elements of type Stream. Here the rules:
Creation will be linear, but all the rest will be constant access. I will be away for a week and I will give it a try on my return. |
The idea in the previous comment is exactly what the author had in mind. So the bug was much deeper. The I would have personally used an struct with two uint32_t and avoid all these masks. There was another issue that was not addressed. When the stream ended, it was not freed until another stream will take its slot, if that ever happened. I do not know if this was intended. I refactored the code to |
See also #86054 for an alternative approach. |
I slightly prefer #86054 as it's more minimal and prevents some extra casting (it seems weird to have a |
Using a class enum was the first thing that came to my mind. But there are two other issues that are still open:
Anyway, as long as the bug works on all the platforms of my game, I am happy with it! |
That's a common practice in the Godot codebase to put helper constants like this in an enum. But indeed it does lead to issues like this one with MSVC being peculiar with enums, so it doesn't hurt to refactor it on a case by case basis.
Yeah there's no Let's go with this approach then :) |
… (MSVC mis-optimization)
Thanks! And congrats for your first merged Godot contribution 🎉 |
It's probably worth documenting in the code itself why it's done this way |
Fixes #86053