Bug 1479424 - Fix VRManager NotifyVSync not called when compositor is paused on Android;
MozReview-Commit-ID: JY8xyCSKIgv
--- a/gfx/vr/gfxVRExternal.cpp
+++ b/gfx/vr/gfxVRExternal.cpp
@@ -112,21 +112,55 @@ VRDisplayExternal::StartPresentation()
mTelemetry.Clear();
mTelemetry.mPresentationStart = TimeStamp::Now();
// Indicate that we are ready to start immersive mode
mBrowserState.presentationActive = true;
mBrowserState.layerState[0].type = VRLayerType::LayerType_Stereo_Immersive;
PushState();
+#if defined(MOZ_WIDGET_ANDROID)
+ /**
+ * Android compositor is paused when presentation starts. That causes VRManager::NotifyVsync() not to be called.
+ * We post a VRTask to call VRManager::NotifyVsync() while the compositor is paused on Android.
+ * VRManager::NotifyVsync() should be called constinuosly while the compositor is paused because Gecko WebVR Architecture
+ * relies on that to act as a "watchdog" in order to avoid render loop stalls and recover from SubmitFrame call timeouts.
+ */
+ PostVRTask();
+#endif
// TODO - Implement telemetry:
// mTelemetry.mLastDroppedFrameCount = stats.m_nNumReprojectedFrames;
}
+#if defined(MOZ_WIDGET_ANDROID)
+void
+VRDisplayExternal::PostVRTask() {
+ MessageLoop * vrLoop = VRListenerThreadHolder::Loop();
+ if (!vrLoop || !mBrowserState.presentationActive) {
+ return;
+ }
+ RefPtr<Runnable> task = NewRunnableMethod(
+ "VRDisplayExternal::RunVRTask",
+ this,
+ &VRDisplayExternal::RunVRTask);
+ VRListenerThreadHolder::Loop()->PostDelayedTask(task.forget(), 50);
+}
+
+void
+VRDisplayExternal::RunVRTask() {
+ if (mBrowserState.presentationActive) {
+ VRManager *vm = VRManager::Get();
+ vm->NotifyVsync(TimeStamp::Now());
+ PostVRTask();
+ }
+}
+
+#endif // defined(MOZ_WIDGET_ANDROID)
+
void
VRDisplayExternal::StopPresentation()
{
if (!mBrowserState.presentationActive) {
return;
}
sPushIndex = 0;
--- a/gfx/vr/gfxVRExternal.h
+++ b/gfx/vr/gfxVRExternal.h
@@ -55,16 +55,18 @@ protected:
private:
bool PopulateLayerTexture(const layers::SurfaceDescriptor& aTexture,
VRLayerTextureType* aTextureType,
VRLayerTextureHandle* aTextureHandle);
void PushState(bool aNotifyCond = false);
#if defined(MOZ_WIDGET_ANDROID)
bool PullState(const std::function<bool()>& aWaitCondition = nullptr);
+ void PostVRTask();
+ void RunVRTask();
#else
bool PullState();
#endif
VRTelemetry mTelemetry;
TimeStamp mVRNavigationTransitionEnd;
VRBrowserState mBrowserState;
VRHMDSensorState mLastSensorState;