engine icon indicating copy to clipboard operation
engine copied to clipboard

Sound Listener ignores the autoRender property

Open LeXXik opened this issue 10 months ago • 9 comments

I was looking at why we keep losing frame time in our app when the application is paused from rendering (hidden from view). We pause it using app.autoRender = false. However it looks like Sound Listener is ignoring the property, because its update is triggered before that, when application.update(dt) is called:

https://github.com/playcanvas/engine/blob/bf80c95bfaec10d5202f8fc5d91f772ae4c3fab8/src/framework/app-base.js#L2066-L2071

Image

LeXXik avatar Mar 05 '25 10:03 LeXXik

It is not technically rendering, but we want to stop any kind of application updates without destroying the app, as it is not in the view. Wish there would be some sort of a paused property guard at the very beginning of the tick function.

LeXXik avatar Mar 05 '25 11:03 LeXXik

If we ship over the update part, the scripts would not execute, and it'd be tricky to wake up your application again. That would need some special callback maybe or something.

mvaligursky avatar Mar 05 '25 11:03 mvaligursky

If we add AppBase.paused and return early here, then it would be a noop call. Not sure about scripts executing / waking up concern here. What would happen if the update is called after skipping say 100 frames?

if (!application.graphicsDevice || applicaiton.paused) { 
    return;
}

https://github.com/playcanvas/engine/blob/bf80c95bfaec10d5202f8fc5d91f772ae4c3fab8/src/framework/app-base.js#L2000-L2009

LeXXik avatar Mar 05 '25 11:03 LeXXik

I mean, how would you set this AppBase.paused to true? Your scripts would not execute, so not from a script.

maybe we need call back at the start of tick, where you supply true of false to pause the current frame .. so this callback would execute always, the rest of the frame skipped based on what this evaluates to.

mvaligursky avatar Mar 05 '25 11:03 mvaligursky

Ah, I see what you mean. Right, we don't do it from the application script assets, but externally.

LeXXik avatar Mar 05 '25 11:03 LeXXik

Our app has multiple views. In some views, the app is only temporarily hidden. In such views we do need autoRender set to false, but still update the application, as it loads stuff while in background. In other views, the app would remain hidden and not going to show up at all - then we do need a noop tick. I am considering this workaround for now, let me know if I am missing something:

Image

LeXXik avatar Mar 05 '25 12:03 LeXXik

Doesn't requestAnimationFrame only get called when a canvas element is visible?

willeastcott avatar Mar 05 '25 12:03 willeastcott

Doesn't requestAnimationFrame only get called when a canvas element is visible?

No, as requestAnimationFrame is bound to window. It only stops triggering if the browser is minified or tab is hidden.

It is a valid case when Application needs to be completely paused, and usually it is an external need. With some callbacks and up to a user to wake it up in the way they feel needed. Paused rendering - is useful for GPU heavy apps, such as configurators, we pause rendering, but keep update running and queue rendering frames when e.g. camera is rotated, and other cases.

While complete pause of application is useful for external needs, when whole app needs to be paused. It is not a game pause - this is up to a dev to implement it on app logic level.

When app is paused, and then resumed, dt - can still be as is, as when app is paused, just an early return from rAF is sufficient, but rAF still needs to run. It is possible to implement it so rAF would be stopped, but that can create complications when it is resumed.

Maksims avatar Mar 05 '25 13:03 Maksims

related https://github.com/playcanvas/engine/issues/5709

mvaligursky avatar Mar 24 '25 16:03 mvaligursky