Skip to content
This repository was archived by the owner on Jul 22, 2024. It is now read-only.

Commit 7b7aeab

Browse files
committed
Fix discarded frames during the transition to one frame ahead prediction
1 parent 5506288 commit 7b7aeab

3 files changed

Lines changed: 23 additions & 11 deletions

File tree

app/src/main/cpp/BrowserWorld.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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) {

app/src/main/cpp/ExternalVR.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ struct ExternalVR::State {
127127
vrb::Vector eyeOffsets[device::EyeCount];
128128
uint64_t lastFrameId = 0;
129129
bool firstPresentingFrame = false;
130+
bool wasFirstPresentingFrame = false;
130131
bool compositorEnabled = false;
131132
bool waitingForExit = false;
132133

@@ -455,6 +456,7 @@ ExternalVR::WaitFrameResult() {
455456
m.PullBrowserStateWhileLocked();
456457
while (true) {
457458
if (!IsPresenting() || m.browser.layerState[0].layer_stereo_immersive.frameId != m.lastFrameId) {
459+
m.wasFirstPresentingFrame = m.firstPresentingFrame;
458460
m.firstPresentingFrame = false;
459461
m.system.displayState.lastSubmittedFrameSuccessful = true;
460462
m.system.displayState.lastSubmittedFrameId = m.browser.layerState[0].layer_stereo_immersive.frameId;
@@ -480,6 +482,10 @@ ExternalVR::WaitFrameResult() {
480482
return true;
481483
}
482484

485+
bool ExternalVR::WasFirstPresentingFrame() const {
486+
return m.wasFirstPresentingFrame;
487+
}
488+
483489
void
484490
ExternalVR::CompleteEnumeration()
485491
{

app/src/main/cpp/ExternalVR.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class ExternalVR : public ImmersiveDisplay {
5555
VRState GetVRState() const;
5656
void PushFramePoses(const vrb::Matrix& aHeadTransform, const std::vector<Controller>& aControllers, const double aTimestamp);
5757
bool WaitFrameResult();
58+
bool WasFirstPresentingFrame() const;
5859
void GetFrameResult(int32_t& aSurfaceHandle,
5960
int32_t& aTextureWidth,
6061
int32_t& aTextureHeight,

0 commit comments

Comments
 (0)