Bug 1296446 - Do not render VR frames until a WebGLContext has returned a mirroring layer draft
authorkearwood
Thu, 08 Sep 2016 14:16:07 -0700
changeset 411814 0428f028ddc9aab60219d1d81cc6ed70de2e53b1
parent 411657 938ce16be25f9c551c19ef8938e8717ed3d41ff5
child 530832 d788b33a6c433196a4e6399ae13af5b490cd00d0
push id29001
push userkgilbert@mozilla.com
push dateThu, 08 Sep 2016 21:16:43 +0000
bugs1296446
milestone51.0a1
Bug 1296446 - Do not render VR frames until a WebGLContext has returned a mirroring layer - Fixes a crash that occurred when WebVR frames were rendered prior to setting up the WebGLContext for mirroring back to the 2d display. MozReview-Commit-ID: Fq4c2287KBL
dom/canvas/WebGLContext.cpp
dom/canvas/WebGLContext.h
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -114,16 +114,17 @@ WebGLContextOptions::WebGLContextOptions
 /*static*/ const uint32_t WebGLContext::kMinMaxDrawBuffers = 4;
 
 WebGLContext::WebGLContext()
     : WebGLContextUnchecked(nullptr)
     , mBufferFetchingIsVerified(false)
     , mBufferFetchingHasPerVertex(false)
     , mMaxFetchedVertices(0)
     , mMaxFetchedInstances(0)
+    , mLayerIsMirror(false)
     , mBypassShaderValidation(false)
     , mContextLossHandler(this)
     , mNeedsFakeNoAlpha(false)
     , mNeedsFakeNoDepth(false)
     , mNeedsFakeNoStencil(false)
     , mNeedsEmulatedLoneDepthStencil(false)
 {
     mGeneration = 0;
@@ -1378,16 +1379,20 @@ WebGLContext::GetCanvasLayer(nsDisplayLi
     data.mIsMirror = aMirror;
 
     canvasLayer->Initialize(data);
     uint32_t flags = gl->Caps().alpha ? 0 : Layer::CONTENT_OPAQUE;
     canvasLayer->SetContentFlags(flags);
     canvasLayer->Updated();
 
     mResetLayer = false;
+    // We only wish to update mLayerIsMirror when a new layer is returned.
+    // If a cached layer is returned above, aMirror is not changing since
+    // the last cached layer was created and mLayerIsMirror is still valid.
+    mLayerIsMirror = aMirror;
 
     return canvasLayer.forget();
 }
 
 layers::LayersBackend
 WebGLContext::GetCompositorBackendType() const
 {
     if (mCanvasElement) {
@@ -2349,16 +2354,24 @@ WebGLContext::GetUnpackSize(bool isFunc3
     totalBytes += usedBytesPerRow;
 
     return totalBytes;
 }
 
 already_AddRefed<layers::SharedSurfaceTextureClient>
 WebGLContext::GetVRFrame()
 {
+    if (!mLayerIsMirror) {
+        /**
+         * Do not allow VR frame submission until a mirroring canvas layer has
+         * been returned by GetCanvasLayer
+         */
+        return nullptr;
+    }
+
     VRManagerChild* vrmc = VRManagerChild::Get();
     if (!vrmc) {
         return nullptr;
     }
 
     /**
      * Swap buffers as though composition has occurred.
      * We will then share the resulting front buffer to be submitted to the VR
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -1082,16 +1082,17 @@ protected:
 
     CheckedUint32 mGeneration;
 
     WebGLContextOptions mOptions;
 
     bool mInvalidated;
     bool mCapturedFrameInvalidated;
     bool mResetLayer;
+    bool mLayerIsMirror;
     bool mOptionsFrozen;
     bool mMinCapability;
     bool mDisableExtensions;
     bool mIsMesa;
     bool mLoseContextOnMemoryPressure;
     bool mCanLoseContextInForeground;
     bool mRestoreWhenVisible;
     bool mShouldPresent;