-
-
Notifications
You must be signed in to change notification settings - Fork 21.3k
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
Sleep the coreaudio driver in-editor after 15s of silence #45948
Conversation
servers/audio_server.cpp
Outdated
@@ -1032,6 +1048,14 @@ void AudioServer::update() { | |||
for (Set<CallbackItem>::Element *E = update_callbacks.front(); E; E = E->next()) { | |||
E->get().callback(E->get().userdata); | |||
} | |||
|
|||
if (Engine::get_singleton()->is_editor_hint()) { |
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 change should only work for editor, maybe #ifdef TOOLS_ENABLED
should also be added, so it's not included in templates builds?
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.
The main reason I see to do that is export binary size and potentially (slightly) reducing lock contention, which makes me wonder if I should do it elsewhere too. What do you think?
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.
I haven't yet checked the whole PR, but I can already say if you want something to happen only in the editor the current check is better, because it is false
both on tools builds when running a project (vs. running the editor) and on non-tools builds.
Furthermore, in non-tools builds, given the check is known to fail at compile time, I'm quite certain that compilers can optimize out the body.
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.
Well, some places seem to use only Engine::get_singleton()->is_editor_hint()
while others use both Engine::get_singleton()->is_editor_hint()
and TOOLS_ENABLED
checks. Maybe I'm missing something, but if using only Engine::get_singleton()->is_editor_hint()
is preferred it's good to know :)
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.
There's no clear policy, but yes we sometimes put both checks in place to ensure that the editor-specific code (often expensive debug code) is compiled out in the runtime. If @RandomShaper is correct that compiler would do it just fine with is_editor_hint()
only, then we shouldn't need to do that indeed.
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 we want to have access to this feature enabled for any other engine mode in project settings, then I guess TOOLS_ENABLED
isn't needed too.
I'll try testing it once I'm free, but so far changes look okay. |
I'm thinking this could be simpler. Let me explain. We have the Now, godot/servers/audio_server.cpp Line 446 in 2b95372
Because of that, and more importantly, it has a notion about if any channel is playing or none at all. This check can be used to contribute to a local boolean that tells that once the loop has ended: godot/servers/audio_server.cpp Line 403 in 2b95372
My point is: couldn't that be used to make the driver sleep and wake up in a simpler that than all the added code? (The added API to the drivers would still be needed and leveraged.) |
That's similar to the way I wanted to do this fix originally, but that code to check if a bus is active in The CoreAudio driver sets up its own |
Oh, I wasn't aware of that. Makes sense. |
Is this improvement can be available for release build? (useful if you make a software) |
@fab918 I'm hoping this fix will be cherry-picked for 3.2 so those of us who prefer stable builds (like me 😄) can benefit. I don't know if it will make it into 3.2.4 though. It may have to wait until the release after that. It really depends on how many more release candidates there are and what the project maintainers are comfortable cherry picking between release candidates. It would be nice though to get into 3.2.4 but I need to remind myself to be patient sometimes 👍 I'll respond to the most recent round of review comments tomorrow morning UTC-8. |
Tested on M1 MacBook, but I don't think result would be different for Intel based macs. When running Project Editor everything seems to work exactly as described - after some time Edit: |
#38208 would fix this on all platforms 🙂 |
I haven't confirmed this, but I suspect the issue here is that |
Yeah, seems like it. But as @Calinou mentioned #38208 should fix it, so that should be okay. |
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.
I think others need still to give a final review. For me, as far as I'm concerned, this is good enough the way it is now.
Also, @ellenhp, thanks for your patience and nicely accepting the feedback!
No problem! Code review is like, really important for the health of the project and as a user of Godot I care a lot about the health of the project! 😄 I'll work on a sister PR for 3.2. There will be some small changes to mutexes and I think some of the files may have been renamed, but it should largely be the same. I'll leave it in a draft state until this one is merged though. |
Everything seems to work correctly, so LGTM. |
Changes look good to me overall, though it would be good to have a quick review from @reduz as there are changes to AudioServer. Some comments on the form:
|
Regarding the use of This would make it possible to use this in Godot projects too, e.g. when making games without sound, or non-game apps. The sleep threshold could also be made a project setting I guess. I'd suggest waiting for additional feedback from @reduz before implementing such settings though, maybe the current approach is good as is. |
It is |
Some thoughts on this PR..
If the problem is actually not being able to sleep on macs when the editor is turned on, I would probably prefer to not stop the audio thread but stop Coreaudio after some time with silence, and then keep a thread alive checking if there is audio data in order to re-enable coreaudio. This of course would be used in editor or lowpcu mode only. |
I also wonder if this could probably be done in AudioServer directly, so drivers also dont really know whats going on either. When low cpu mode is enabled, turn off the audio driver after X time of silence and start a thread that scans for any audio going on, then re-initializes audio. |
edit again: sorry, I was waking up when I read your comments originally. I think I understand what you're saying. I'll hack away at this a bit more and see if I can come up with something. |
This PR will get way simpler if I manage to implement godotengine/godot-proposals#2299 so I think I'm going to close it. The downside is that the implementation of that proposal will almost certainly not be backported, so fixing this bug will probably be something that only happens in 4.0. |
It looks like this approach would be useful to explore again, with #28039 also occurring on Windows. |
Interesting. This is a much easier fix now after the AudioServer rewrite because we don't have to add code in each player node anymore. The audio server has all the information it needs to toggle the driver on and off. |
Fixes #28039
Should help mitigate #38154 but might not solve the root cause
This PR allows the coreaudio driver to enter a sleep state when the AudioServer requests it to. Mutexes have been added to all audio players and the video player to prevent a play() call acquiring a playback "lock" from racing with a _mix_audio call releasing it. I'm not a C++ expert so maybe there's some fancy RAII way to do this but I figured I'd start simple and avoid overengineering.
How to test:
I have been unable to test video players. They don't seem to work in latest master as far as I can tell.