@@ -1421,28 +1421,33 @@ BrowserWorld::TickImmersive() {
14211421 m.externalVR ->SetCompositorEnabled (false );
14221422 m.device ->SetRenderMode (device::RenderMode::Immersive);
14231423
1424- DeviceDelegate::FramePrediction prediction = DeviceDelegate::FramePrediction::NO_FRAME_AHEAD;
1425- if (m.device ->SupportsFramePrediction (DeviceDelegate::FramePrediction::ONE_FRAME_AHEAD)
1426- && m.externalVR ->GetVRState () == ExternalVR::VRState::Rendering) {
1427- prediction = DeviceDelegate::FramePrediction::ONE_FRAME_AHEAD;
1428- }
1429-
1424+ const bool supportsFrameAhead = m.device ->SupportsFramePrediction (DeviceDelegate::FramePrediction::ONE_FRAME_AHEAD);
14301425 VRB_GL_CHECK (glDepthMask (GL_FALSE));
1431- if (prediction == DeviceDelegate::FramePrediction::NO_FRAME_AHEAD) {
1432- m.device ->StartFrame (prediction);
1426+ if (!supportsFrameAhead || (m.externalVR ->GetVRState () != ExternalVR::VRState::Rendering)) {
1427+ // Do not use one frame ahead prediction if not supported or we are rendering the spinner.
1428+ m.device ->StartFrame (DeviceDelegate::FramePrediction::NO_FRAME_AHEAD);
14331429 m.externalVR ->PushFramePoses (m.device ->GetHeadTransform (), m.controllers ->GetControllers (),
14341430 m.context ->GetTimestamp ());
14351431 }
14361432 int32_t surfaceHandle, textureWidth, textureHeight = 0 ;
14371433 device::EyeRect leftEye, rightEye;
14381434 bool aDiscardFrame = !m.externalVR ->WaitFrameResult ();
14391435 m.externalVR ->GetFrameResult (surfaceHandle, textureWidth, textureHeight, leftEye, rightEye);
1440- if (prediction == DeviceDelegate::FramePrediction::ONE_FRAME_AHEAD) {
1441- m.device ->StartFrame (prediction);
1436+ ExternalVR::VRState state = m.externalVR ->GetVRState ();
1437+ if (supportsFrameAhead) {
1438+ if (m.externalVR ->WasFirstPresentingFrame ()) {
1439+ // StartFrame() has been already called to render the spinner, do not call it again.
1440+ // Instead, repeat the XR frame and render the spinner while we transition
1441+ // to one frame ahead prediction.
1442+ state = ExternalVR::VRState::Loading;
1443+ } else {
1444+ // Predict poses for one frame ahead and push the data to shmem so Gecko
1445+ // can start the next XR RAF ASAP.
1446+ m.device ->StartFrame (DeviceDelegate::FramePrediction::ONE_FRAME_AHEAD);
1447+ }
14421448 m.externalVR ->PushFramePoses (m.device ->GetHeadTransform (), m.controllers ->GetControllers (),
14431449 m.context ->GetTimestamp ());
14441450 }
1445- ExternalVR::VRState state = m.externalVR ->GetVRState ();
14461451 if (state == ExternalVR::VRState::Rendering) {
14471452 if (!aDiscardFrame) {
14481453 if (textureWidth > 0 && textureHeight > 0 ) {
0 commit comments