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
Note somewhere that you should be always be queueing up the next rAF within rAF #877
Comments
Hm... I don't agree with this, though you bring up a good point about the flash of black. That's unintended. It's a valid technique in some cases to render a single frame (like a splash screen logo) and then skip several frames while other work is happening, letting the device's reprojection system (if it has one) handle any tracking. I don't think we want to prevent that from working here, and so "forcing" developers to keep a full rAF loop scheduled seems problematic. I'd rather that we find some way to express that the compositor should only update it's imagery if the layer framebuffer is modified during the course of the rAF callbacks (not including the initial clear). This is, as far as I recall, what Chrome is doing anyway. |
cc @asajeffrey I suspect that might be pretty tricky to specify? Not sure if webgl gives us the terms necessary to spec that. I'm okay with us specifying that -- it is a nicer solution -- but I'd check in with implementations first. |
Either way, I think we should definitely explicitly spec this if we're going this way, or add the note. |
The WebGL spec already states this pretty clearly:
I'm sure we could use some variant of that. |
Ah, that seems reasonable |
I discussed this a bit with @asajeffrey and a secondary constraint popped up: we should be doing this only at the end of processing an animation frame. I.e if for some reason an rAF callback loops infinitely, doing a bunch of webgl stuff, it should not be reflected on the device until the callback is over. Mostly the distinction will surface in cases where the page code is written terribly, but this is both cleaner for implementations and leads to slightly more logical behavior. This also means that this issue can be fixed with a single "if draw (etc) has been called, render to the device" line at the end of the "process an xr frame" steps |
Always request new XR frames Currently we only request XR frames when there is a rAF callback queued up. This is incorrect, see https://immersive-web.github.io/webxr/#xr-animation-frame With this change we always request updated frame state regardless of whether or not the user has queued up callbacks. In addition to being spec-correct, this means that we can reliably listen for events in the OpenXR backend in the rAF loop itself, instead of having to set up a second spinning loop for when the rAF is inactive. This lets us implement visibility states for openxr without having to worry about the user never receiving the wakeup call because the rAF loop isn't pumping. See also: immersive-web/webxr#877 r? @asajeffrey
We discussed this a bit and want to make these changes: we should be updating things on the compositor only if the layer framebuffer is modified, and only after the end of a rAF call. |
Currently, we run an XR animation frame regardless of whether or not you've triggered rAF.
We also clear framebuffers before each "XR animation frame":
Both of these things are good decisions.
However, put together, this means that an application that does not queue up the next rAF within the current rAF callback will experience flashes of black.
This is kind of different from HTML rAF, in HTML you can choose to not queue up a rAF for a bit and that just makes the scene static until you do, whether your application is moving elements around or canvas stuff. This is less jarring.
It seems to me that the only time you should not queue up a rAF within your rAF callback is when you don't intend to render anything -- e.g. when your visibility state becomes
hidden
.It may be worth noting this non normatively somewhere in the spec, for authors (and doc writers) to pick up.
The text was updated successfully, but these errors were encountered: