Bug 1465816 - Add initial code needed to support gfxVRExternal on android r=kip,jchen
authorRandall Barker <rbarker@mozilla.com>
Mon, 04 Jun 2018 15:45:04 -0700
changeset 421529 b077ffd9a84dc57a0dcadaede41b7ff8760f519f
parent 421528 355fe159b162e11b4dd54b8b4b119f974adfe4ed
child 421530 633a10eff02a2ada758db8459dc9927bbce31df5
push id34096
push usernbeleuzu@mozilla.com
push dateWed, 06 Jun 2018 09:37:23 +0000
treeherdermozilla-central@cec4a3cecc29 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskip, jchen
bugs1465816
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1465816 - Add initial code needed to support gfxVRExternal on android r=kip,jchen MozReview-Commit-ID: 9rXXqIvyvhp
gfx/vr/VRDisplayClient.cpp
gfx/vr/VRDisplayHost.cpp
gfx/vr/VRDisplayHost.h
gfx/vr/VRManager.cpp
gfx/vr/external_api/moz_external_vr.h
gfx/vr/gfxVR.h
gfx/vr/gfxVRExternal.cpp
gfx/vr/gfxVRExternal.h
gfx/vr/gfxVRGVR.cpp
gfx/vr/gfxVRGVR.h
gfx/vr/gfxVRGVRAPI.h
gfx/vr/gfxVROSVR.cpp
gfx/vr/gfxVROSVR.h
gfx/vr/gfxVRPuppet.cpp
gfx/vr/gfxVRPuppet.h
gfx/vr/ipc/VRManagerChild.cpp
gfx/vr/ipc/VRMessageUtils.h
gfx/vr/jni/gfxGVRJNI.cpp
gfx/vr/moz.build
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoVRManager.java
widget/android/GeckoVRManager.h
widget/android/nsAppShell.cpp
--- a/gfx/vr/VRDisplayClient.cpp
+++ b/gfx/vr/VRDisplayClient.cpp
@@ -76,27 +76,27 @@ VRDisplayClient::SetGroupMask(uint32_t a
 {
   VRManagerChild *vm = VRManagerChild::Get();
   vm->SendSetGroupMask(mDisplayInfo.mDisplayID, aGroupMask);
 }
 
 bool
 VRDisplayClient::IsPresentationGenerationCurrent() const
 {
-  if (mLastPresentingGeneration != mDisplayInfo.mPresentingGeneration) {
+  if (mLastPresentingGeneration != mDisplayInfo.mDisplayState.mPresentingGeneration) {
     return false;
   }
 
   return true;
 }
 
 void
 VRDisplayClient::MakePresentationGenerationCurrent()
 {
-  mLastPresentingGeneration = mDisplayInfo.mPresentingGeneration;
+  mLastPresentingGeneration = mDisplayInfo.mDisplayState.mPresentingGeneration;
 }
 
 void
 VRDisplayClient::FireEvents()
 {
   VRManagerChild *vm = VRManagerChild::Get();
   // Only fire these events for non-chrome VR sessions
   bool isPresenting = (mDisplayInfo.mPresentingGroups & kVRGroupContent) != 0;
--- a/gfx/vr/VRDisplayHost.cpp
+++ b/gfx/vr/VRDisplayHost.cpp
@@ -21,19 +21,19 @@
 #include "mozilla/layers/TextureD3D11.h"
 
 #elif defined(XP_MACOSX)
 
 #include "mozilla/gfx/MacIOSurface.h"
 
 #endif
 
-#if defined(MOZ_ANDROID_GOOGLE_VR)
+#if defined(MOZ_WIDGET_ANDROID)
 #include "mozilla/layers/CompositorThread.h"
-#endif // defined(MOZ_ANDROID_GOOGLE_VR)
+#endif // defined(MOZ_WIDGET_ANDROID)
 
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 using namespace mozilla::layers;
 
 VRDisplayHost::AutoRestoreRenderState::AutoRestoreRenderState(VRDisplayHost* aDisplay)
   : mDisplay(aDisplay)
@@ -72,17 +72,17 @@ VRDisplayHost::VRDisplayHost(VRDeviceTyp
  , mFrameStarted(false)
 {
   MOZ_COUNT_CTOR(VRDisplayHost);
   mDisplayInfo.mType = aType;
   mDisplayInfo.mDisplayID = VRSystemManager::AllocateDisplayID();
   mDisplayInfo.mPresentingGroups = 0;
   mDisplayInfo.mGroupMask = kVRGroupContent;
   mDisplayInfo.mFrameId = 0;
-  mDisplayInfo.mPresentingGeneration = 0;
+  mDisplayInfo.mDisplayState.mPresentingGeneration = 0;
   mDisplayInfo.mDisplayState.mDisplayName[0] = '\0';
 }
 
 VRDisplayHost::~VRDisplayHost()
 {
   if (mSubmitThread) {
     mSubmitThread->Shutdown();
     mSubmitThread = nullptr;
@@ -263,19 +263,19 @@ VRDisplayHost::NotifyVSync()
 }
 
 void
 VRDisplayHost::SubmitFrameInternal(const layers::SurfaceDescriptor &aTexture,
                                    uint64_t aFrameId,
                                    const gfx::Rect& aLeftEyeRect,
                                    const gfx::Rect& aRightEyeRect)
 {
-#if !defined(MOZ_ANDROID_GOOGLE_VR)
+#if !defined(MOZ_WIDGET_ANDROID)
   MOZ_ASSERT(mSubmitThread->GetThread() == NS_GetCurrentThread());
-#endif // !defined(MOZ_ANDROID_GOOGLE_VR)
+#endif // !defined(MOZ_WIDGET_ANDROID)
   AUTO_PROFILER_TRACING("VR", "SubmitFrameAtVRDisplayHost");
 
   mFrameStarted = false;
   switch (aTexture.type()) {
 
 #if defined(XP_WIN)
     case SurfaceDescriptor::TSurfaceDescriptorD3D10: {
       if (!CreateD3DObjects()) {
@@ -332,32 +332,32 @@ VRDisplayHost::SubmitFrameInternal(const
       }
       IntSize texSize = gfx::IntSize(surf->GetDevicePixelWidth(),
                                      surf->GetDevicePixelHeight());
       if (!SubmitFrame(surf, texSize, aLeftEyeRect, aRightEyeRect)) {
         return;
       }
       break;
     }
-#elif defined(MOZ_ANDROID_GOOGLE_VR)
-    case SurfaceDescriptor::TEGLImageDescriptor: {
-      const EGLImageDescriptor& desc = aTexture.get_EGLImageDescriptor();
-      if (!SubmitFrame(&desc, aLeftEyeRect, aRightEyeRect)) {
+#elif defined(MOZ_WIDGET_ANDROID)
+    case SurfaceDescriptor::TSurfaceTextureDescriptor: {
+      const SurfaceTextureDescriptor& desc = aTexture.get_SurfaceTextureDescriptor();
+      if (!SubmitFrame(desc, aLeftEyeRect, aRightEyeRect)) {
         return;
       }
       break;
     }
 #endif
     default: {
       NS_WARNING("Unsupported SurfaceDescriptor type for VR layer texture");
       return;
     }
   }
 
-#if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_ANDROID_GOOGLE_VR)
+#if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_WIDGET_ANDROID)
 
   /**
    * Trigger the next VSync immediately after we are successfully
    * submitting frames.  As SubmitFrame is responsible for throttling
    * the render loop, if we don't successfully call it, we shouldn't trigger
    * NotifyVRVsync immediately, as it will run unbounded.
    * If NotifyVRVsync is not called here due to SubmitFrame failing, the
    * fallback "watchdog" code in VRDisplayHost::NotifyVSync() will cause
@@ -376,43 +376,43 @@ VRDisplayHost::SubmitFrameInternal(const
 
 void
 VRDisplayHost::SubmitFrame(VRLayerParent* aLayer,
                            const layers::SurfaceDescriptor &aTexture,
                            uint64_t aFrameId,
                            const gfx::Rect& aLeftEyeRect,
                            const gfx::Rect& aRightEyeRect)
 {
-#if !defined(MOZ_ANDROID_GOOGLE_VR)
+#if !defined(MOZ_WIDGET_ANDROID)
   if (!mSubmitThread) {
     mSubmitThread = new VRThread(NS_LITERAL_CSTRING("VR_SubmitFrame"));
   }
-#endif // !defined(MOZ_ANDROID_GOOGLE_VR)
+#endif // !defined(MOZ_WIDGET_ANDROID)
 
   if ((mDisplayInfo.mGroupMask & aLayer->GetGroup()) == 0) {
     // Suppress layers hidden by the group mask
     return;
   }
 
   // Ensure that we only accept the first SubmitFrame call per RAF cycle.
   if (!mFrameStarted || aFrameId != mDisplayInfo.mFrameId) {
     return;
   }
 
   RefPtr<Runnable> submit =
     NewRunnableMethod<StoreCopyPassByConstLRef<layers::SurfaceDescriptor>, uint64_t,
       StoreCopyPassByConstLRef<gfx::Rect>, StoreCopyPassByConstLRef<gfx::Rect>>(
       "gfx::VRDisplayHost::SubmitFrameInternal", this, &VRDisplayHost::SubmitFrameInternal,
       aTexture, aFrameId, aLeftEyeRect, aRightEyeRect);
-#if !defined(MOZ_ANDROID_GOOGLE_VR)
+#if !defined(MOZ_WIDGET_ANDROID)
   mSubmitThread->Start();
   mSubmitThread->PostTask(submit.forget());
 #else
   CompositorThreadHolder::Loop()->PostTask(submit.forget());
-#endif // defined(MOZ_ANDROID_GOOGLE_VR)
+#endif // defined(MOZ_WIDGET_ANDROID)
 }
 
 bool
 VRDisplayHost::CheckClearDisplayInfoDirty()
 {
   if (mDisplayInfo == mLastUpdateDisplayInfo) {
     return false;
   }
--- a/gfx/vr/VRDisplayHost.h
+++ b/gfx/vr/VRDisplayHost.h
@@ -81,18 +81,18 @@ protected:
                            const IntSize& aSize,
                            const gfx::Rect& aLeftEyeRect,
                            const gfx::Rect& aRightEyeRect) = 0;
 #elif defined(XP_MACOSX)
   virtual bool SubmitFrame(MacIOSurface* aMacIOSurface,
                            const IntSize& aSize,
                            const gfx::Rect& aLeftEyeRect,
                            const gfx::Rect& aRightEyeRect) = 0;
-#elif defined(MOZ_ANDROID_GOOGLE_VR)
-  virtual bool SubmitFrame(const mozilla::layers::EGLImageDescriptor* aDescriptor,
+#elif defined(MOZ_WIDGET_ANDROID)
+  virtual bool SubmitFrame(const mozilla::layers::SurfaceTextureDescriptor& aSurface,
                            const gfx::Rect& aLeftEyeRect,
                            const gfx::Rect& aRightEyeRect) = 0;
 #endif
 
   VRDisplayInfo mDisplayInfo;
 
   nsTArray<VRLayerParent *> mLayers;
   // Weak reference to mLayers entries are cleared in
--- a/gfx/vr/VRManager.cpp
+++ b/gfx/vr/VRManager.cpp
@@ -21,19 +21,16 @@
 #include "gfxVRExternal.h"
 #if defined(XP_WIN)
 #include "gfxVROculus.h"
 #endif
 #if defined(XP_WIN) || defined(XP_MACOSX) || (defined(XP_LINUX) && !defined(MOZ_WIDGET_ANDROID))
 #include "gfxVROpenVR.h"
 #include "gfxVROSVR.h"
 #endif
-#if defined(MOZ_ANDROID_GOOGLE_VR)
-#include "gfxVRGVR.h"
-#endif // MOZ_ANDROID_GOOGLE_VR
 
 #include "gfxVRPuppet.h"
 #include "ipc/VRLayerParent.h"
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 using namespace mozilla::layers;
 using namespace mozilla::gl;
@@ -99,23 +96,16 @@ VRManager::VRManager()
 
   // OSVR is cross platform compatible
   mgr = VRSystemManagerOSVR::Create();
   if (mgr) {
       mManagers.AppendElement(mgr);
   }
 #endif
 
-#if defined(MOZ_ANDROID_GOOGLE_VR)
-   mgr = VRSystemManagerGVR::Create();
-   if (mgr) {
-     mManagers.AppendElement(mgr);
-   }
-#endif // defined(MOZ_ANDROID_GOOGLE_VR)
-
   // Enable gamepad extensions while VR is enabled.
   // Preference only can be set at the Parent process.
   if (XRE_IsParentProcess() && gfxPrefs::VREnabled()) {
     Preferences::SetBool("dom.gamepad.extensions.enabled", true);
   }
 }
 
 VRManager::~VRManager()
--- a/gfx/vr/external_api/moz_external_vr.h
+++ b/gfx/vr/external_api/moz_external_vr.h
@@ -11,24 +11,30 @@
 #include <stdint.h>
 #include <type_traits>
 
 #ifdef MOZILLA_INTERNAL_API
 #include "mozilla/TypedEnumBits.h"
 #include "mozilla/gfx/2D.h"
 #endif // MOZILLA_INTERNAL_API
 
+#if defined(__ANDROID__)
+#include <pthread.h>
+#endif // defined(__ANDROID__)
+
 namespace mozilla {
 #ifdef MOZILLA_INTERNAL_API
 namespace dom {
   enum class GamepadHand : uint8_t;
 }
 #endif //  MOZILLA_INTERNAL_API
 namespace gfx {
 
+static const int32_t kVRExternalVersion = 0;
+
 // We assign VR presentations to groups with a bitmask.
 // Currently, we will only display either content or chrome.
 // Later, we will have more groups to support VR home spaces and
 // multitasking environments.
 // These values are not exposed to regular content and only affect
 // chrome-only API's.  They may be changed at any time.
 static const uint32_t kVRGroupNone = 0;
 static const uint32_t kVRGroupContent = 1 << 0;
@@ -211,26 +217,30 @@ struct VRFieldOfView {
 struct VRDisplayState
 {
   enum Eye {
     Eye_Left,
     Eye_Right,
     NumEyes
   };
 
+#if defined(__ANDROID__)
+  bool shutdown;
+#endif // defined(__ANDROID__)
   char mDisplayName[kVRDisplayNameMaxLen];
   VRDisplayCapabilityFlags mCapabilityFlags;
   VRFieldOfView mEyeFOV[VRDisplayState::NumEyes];
   Point3D_POD mEyeTranslation[VRDisplayState::NumEyes];
   IntSize_POD mEyeResolution;
   bool mIsConnected;
   bool mIsMounted;
   FloatSize_POD mStageSize;
   // We can't use a Matrix4x4 here unless we ensure it's a POD type
   float mSittingToStandingTransform[16];
+  uint32_t mPresentingGeneration;
 };
 
 struct VRControllerState
 {
   char mControllerName[kVRControllerNameMaxLen];
 #ifdef MOZILLA_INTERNAL_API
   dom::GamepadHand mHand;
 #else
@@ -291,34 +301,49 @@ struct VRLayerState
   union {
     VRLayer_2D_Content layer_2d_content;
     VRLayer_Stereo_Immersive layer_stereo_immersive;
   };
 };
 
 struct VRBrowserState
 {
+#if defined(__ANDROID__)
+  bool shutdown;
+#endif // defined(__ANDROID__)
   VRLayerState layerState[kVRLayerMaxCount];
 };
 
 struct VRSystemState
 {
+  uint32_t presentingGeneration;
   VRDisplayState displayState;
   VRHMDSensorState sensorState;
   VRControllerState controllerState[kVRControllerMaxCount];
 };
 
 struct VRExternalShmem
 {
+  int32_t version;
+  int32_t size;
+#if defined(__ANDROID__)
+  pthread_mutex_t systemMutex;
+  pthread_mutex_t browserMutex;
+#else
   int64_t generationA;
+#endif // defined(__ANDROID__)
   VRSystemState state;
+#if !defined(__ANDROID__)
   int64_t generationB;
   int64_t browserGenerationA;
+#endif // !defined(__ANDROID__)
   VRBrowserState browserState;
+#if !defined(__ANDROID__)
   int64_t browserGenerationB;
+#endif // !defined(__ANDROID__)
 };
 
 // As we are memcpy'ing VRExternalShmem and its members around, it must be a POD type
 static_assert(std::is_pod<VRExternalShmem>::value, "VRExternalShmem must be a POD type.");
 
 } // namespace gfx
 } // namespace mozilla
 
--- a/gfx/vr/gfxVR.h
+++ b/gfx/vr/gfxVR.h
@@ -54,17 +54,16 @@ enum class VRDeviceType : uint16_t {
 
 struct VRDisplayInfo
 {
   uint32_t mDisplayID;
   VRDeviceType mType;
   uint32_t mPresentingGroups;
   uint32_t mGroupMask;
   uint64_t mFrameId;
-  uint32_t mPresentingGeneration;
   VRDisplayState mDisplayState;
 
   VRHMDSensorState mLastSensorState[kVRMaxLatencyFrames];
   const VRHMDSensorState& GetSensorState() const
   {
     return mLastSensorState[mFrameId % kVRMaxLatencyFrames];
   }
 
@@ -91,18 +90,17 @@ struct VRDisplayInfo
       }
     }
     // Note that mDisplayState is asserted to be a POD type, so memcmp is safe
     return mType == other.mType &&
            mDisplayID == other.mDisplayID &&
            memcmp(&mDisplayState, &other.mDisplayState, sizeof(VRDisplayState)) == 0 &&
            mPresentingGroups == other.mPresentingGroups &&
            mGroupMask == other.mGroupMask &&
-           mFrameId == other.mFrameId &&
-           mPresentingGeneration == other.mPresentingGeneration;
+           mFrameId == other.mFrameId;
   }
 
   bool operator!=(const VRDisplayInfo& other) const {
     return !(*this == other);
   }
 };
 
 struct VRSubmitFrameResultInfo
--- a/gfx/vr/gfxVRExternal.cpp
+++ b/gfx/vr/gfxVRExternal.cpp
@@ -19,17 +19,21 @@
 static const char* kShmemName = "moz.gecko.vr_ext.0.0.1";
 #elif defined(XP_MACOSX)
 #include "mozilla/gfx/MacIOSurface.h"
 #include <sys/mman.h>
 #include <sys/stat.h>        /* For mode constants */
 #include <fcntl.h>           /* For O_* constants */
 #include <errno.h>
 static const char* kShmemName = "/moz.gecko.vr_ext.0.0.1";
-#endif
+#elif defined(MOZ_WIDGET_ANDROID)
+#include <string.h>
+#include <pthread.h>
+#include "GeckoVRManager.h"
+#endif // defined(MOZ_WIDGET_ANDROID)
 
 #include "gfxVRExternal.h"
 #include "VRManagerParent.h"
 #include "VRManager.h"
 #include "VRThread.h"
 
 #include "nsServiceManagerUtils.h"
 #include "nsIScreenManager.h"
@@ -167,16 +171,26 @@ VRDisplayExternal::SubmitFrame(MacIOSurf
   if (ioSurface == nullptr) {
     NS_WARNING("VRDisplayExternal::SubmitFrame() could not get an IOSurface");
   } else {
     // FINDME!  Implement this
   }
   return result;
 }
 
+#elif defined(MOZ_WIDGET_ANDROID)
+
+bool
+VRDisplayExternal::SubmitFrame(const layers::SurfaceTextureDescriptor& aSurface,
+                               const gfx::Rect& aLeftEyeRect,
+                               const gfx::Rect& aRightEyeRect) {
+
+  return false;
+}
+
 #endif
 
 VRControllerExternal::VRControllerExternal(dom::GamepadHand aHand, uint32_t aDisplayID,
                                        uint32_t aNumButtons, uint32_t aNumTriggers,
                                        uint32_t aNumAxes, const nsCString& aId)
   : VRControllerHost(VRDeviceType::External, aHand, aDisplayID)
 {
   MOZ_COUNT_CTOR_INHERITED(VRControllerExternal, VRControllerHost);
@@ -196,33 +210,39 @@ VRControllerExternal::~VRControllerExter
 
 VRSystemManagerExternal::VRSystemManagerExternal()
  : mExternalShmem(nullptr)
 {
 #if defined(XP_MACOSX)
   mShmemFD = 0;
 #elif defined(XP_WIN)
   mShmemFile = NULL;
+#elif defined(MOZ_WIDGET_ANDROID)
+  mDoShutdown = false;
+  mExternalStructFailed = false;
 #endif
 }
 
 VRSystemManagerExternal::~VRSystemManagerExternal()
 {
   CloseShmem();
 }
 
 void
 VRSystemManagerExternal::OpenShmem()
 {
   if (mExternalShmem) {
     return;
+#if defined(MOZ_WIDGET_ANDROID)
+  } else if (mExternalStructFailed) {
+    return;
+#endif // defined(MOZ_WIDGET_ANDROID)
   }
 
 #if defined(XP_MACOSX)
-
   if (mShmemFD == 0) {
     mShmemFD = shm_open(kShmemName, O_RDWR, S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH);
   }
   if (mShmemFD <= 0) {
     mShmemFD = 0;
     return;
   }
 
@@ -239,17 +259,16 @@ VRSystemManagerExternal::OpenShmem()
   if (mExternalShmem == MAP_FAILED) {
     // TODO - Implement logging
     mExternalShmem = NULL;
     CloseShmem();
     return;
   }
 
 #elif defined(XP_WIN)
-
   if (mShmemFile == NULL) {
     mShmemFile = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, kShmemName);
     if (mShmemFile == NULL) {
       // TODO - Implement logging
       CloseShmem();
       return;
     }
   }
@@ -261,53 +280,74 @@ VRSystemManagerExternal::OpenShmem()
     0,
     length.QuadPart);
 
   if (mExternalShmem == NULL) {
     // TODO - Implement logging
     CloseShmem();
     return;
   }
+#elif defined(MOZ_WIDGET_ANDROID)
+  mExternalShmem = (VRExternalShmem*)mozilla::GeckoVRManager::GetExternalContext();
+  if (!mExternalShmem) {
+    return;
+  }
+  if (mExternalShmem->version != kVRExternalVersion) {
+    mExternalShmem = nullptr;
+    mExternalStructFailed = true;
+    return;
+  }
+  if (mExternalShmem->size != sizeof(VRExternalShmem)) {
+    mExternalShmem = nullptr;
+    mExternalStructFailed = true;
+    return;
+  }
 #endif
   CheckForShutdown();
 }
 
 void
 VRSystemManagerExternal::CheckForShutdown()
 {
+#if defined(MOZ_WIDGET_ANDROID)
+  if (mDoShutdown) {
+    Shutdown();
+  }
+#else
   if (mExternalShmem) {
     if (mExternalShmem->generationA == -1 && mExternalShmem->generationB == -1) {
       Shutdown();
     }
   }
+#endif // defined(MOZ_WIDGET_ANDROID)
 }
 
 void
 VRSystemManagerExternal::CloseShmem()
 {
 #if defined(XP_MACOSX)
-  
   if (mExternalShmem) {
     munmap((void *)mExternalShmem, sizeof(VRExternalShmem));
     mExternalShmem = NULL;
   }
   if (mShmemFD) {
     close(mShmemFD);
   }
   mShmemFD = 0;
-  
 #elif defined(XP_WIN)
   if (mExternalShmem) {
     UnmapViewOfFile((void *)mExternalShmem);
     mExternalShmem = NULL;
   }
   if (mShmemFile) {
     CloseHandle(mShmemFile);
     mShmemFile = NULL;
   }
+#elif defined(MOZ_WIDGET_ANDROID)
+  mExternalShmem = NULL;
 #endif
 }
 
 /*static*/ already_AddRefed<VRSystemManagerExternal>
 VRSystemManagerExternal::Create()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
@@ -328,16 +368,19 @@ VRSystemManagerExternal::Destroy()
 void
 VRSystemManagerExternal::Shutdown()
 {
   if (mDisplay) {
     mDisplay = nullptr;
   }
   RemoveControllers();
   CloseShmem();
+#if defined(MOZ_WIDGET_ANDROID)
+  mDoShutdown = false;
+#endif
 }
 
 void
 VRSystemManagerExternal::NotifyVSync()
 {
   VRSystemManager::NotifyVSync();
 
   CheckForShutdown();
@@ -445,19 +488,29 @@ VRSystemManagerExternal::RemoveControlle
   mControllerCount = 0;
 }
 
 void
 VRSystemManagerExternal::PullState(VRDisplayState* aDisplayState, VRHMDSensorState* aSensorState /* = nullptr */)
 {
   MOZ_ASSERT(mExternalShmem);
   if (mExternalShmem) {
-    // TODO - Add locking here for non-x86 platforms
+#if defined(MOZ_WIDGET_ANDROID)
+    if (pthread_mutex_lock((pthread_mutex_t*)&(mExternalShmem->systemMutex)) == 0) {
+        memcpy(aDisplayState, (void*)&(mExternalShmem->state.displayState), sizeof(VRDisplayState));
+        if (aSensorState) {
+          memcpy(aSensorState, (void*)&(mExternalShmem->state.sensorState), sizeof(VRHMDSensorState));
+        }
+        pthread_mutex_unlock((pthread_mutex_t*)&(mExternalShmem->systemMutex));
+        mDoShutdown = aDisplayState->shutdown;
+    }
+#else
     VRExternalShmem tmp;
     memcpy(&tmp, (void *)mExternalShmem, sizeof(VRExternalShmem));
     if (tmp.generationA == tmp.generationB && tmp.generationA != 0 && tmp.generationA != -1) {
       memcpy(aDisplayState, &tmp.state.displayState, sizeof(VRDisplayState));
       if (aSensorState) {
         memcpy(aSensorState, &tmp.state.sensorState, sizeof(VRHMDSensorState));
       }
     }
+#endif // defined(MOZ_WIDGET_ANDROID)
   }
 }
--- a/gfx/vr/gfxVRExternal.h
+++ b/gfx/vr/gfxVRExternal.h
@@ -41,16 +41,20 @@ protected:
                            const IntSize& aSize,
                            const gfx::Rect& aLeftEyeRect,
                            const gfx::Rect& aRightEyeRect) override;
 #elif defined(XP_MACOSX)
   virtual bool SubmitFrame(MacIOSurface* aMacIOSurface,
                            const IntSize& aSize,
                            const gfx::Rect& aLeftEyeRect,
                            const gfx::Rect& aRightEyeRect) override;
+#elif defined(MOZ_WIDGET_ANDROID)
+  bool SubmitFrame(const layers::SurfaceTextureDescriptor& aSurface,
+                           const gfx::Rect& aLeftEyeRect,
+                           const gfx::Rect& aRightEyeRect) override;
 #endif
 
 public:
   explicit VRDisplayExternal(const VRDisplayState& aDisplayState);
   void Refresh();
 protected:
   virtual ~VRDisplayExternal();
   void Destroy();
@@ -101,22 +105,25 @@ public:
 protected:
   VRSystemManagerExternal();
   virtual ~VRSystemManagerExternal();
 
 private:
   // there can only be one
   RefPtr<impl::VRDisplayExternal> mDisplay;
   nsTArray<RefPtr<impl::VRControllerExternal>> mExternalController;
-
 #if defined(XP_MACOSX)
   int mShmemFD;
 #elif defined(XP_WIN)
   HANDLE mShmemFile;
+#elif defined(MOZ_WIDGET_ANDROID)
+  bool mDoShutdown;
+  bool mExternalStructFailed;
 #endif
+
   volatile VRExternalShmem* mExternalShmem;
 
   void OpenShmem();
   void CloseShmem();
   void CheckForShutdown();
 };
 
 } // namespace gfx
deleted file mode 100644
--- a/gfx/vr/gfxVRGVR.cpp
+++ /dev/null
@@ -1,816 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include <math.h>
-
-#include "GLBlitHelper.h"
-#include "GLContextEGL.h"
-#include "GLContextProvider.h"
-#include "GLContextTypes.h"
-#include "GLImages.h"
-#include "GLLibraryEGL.h"
-
-#include "gfxPrefs.h"
-#include "gfxVRGVRAPI.h"
-#include "gfxVRGVR.h"
-
-#include "mozilla/dom/GamepadEventTypes.h"
-#include "mozilla/dom/GamepadBinding.h"
-#include "mozilla/gfx/Matrix.h"
-#include "mozilla/gfx/Quaternion.h"
-#include "mozilla/jni/Utils.h"
-#include "mozilla/layers/CompositorThread.h"
-#include "mozilla/layers/TextureHostOGL.h"
-#include "mozilla/Preferences.h"
-
-#include "GeckoVRManager.h"
-#include "nsString.h"
-
-#include "SurfaceTypes.h"
-
-#include "VRManager.h"
-
-#define MOZ_CHECK_GVR_ERRORS
-
-#if defined(MOZ_CHECK_GVR_ERRORS)
-#define GVR_LOGTAG "GeckoWebVR"
-#include <android/log.h>
-#define GVR_CHECK(X) X; \
-{ \
-  gvr_context* context = (mPresentingContext ? mPresentingContext : GetNonPresentingContext()); \
-  if (context && (gvr_get_error(context) != GVR_ERROR_NONE)) { \
-     __android_log_print(ANDROID_LOG_ERROR, GVR_LOGTAG, \
-                         "GVR ERROR: %s at:%s:%s:%d", \
-                         gvr_get_error_string(gvr_get_error(context)), \
-                         __FILE__, __FUNCTION__, __LINE__); \
-    gvr_clear_error(context); \
-  } else if (!context) { \
-    __android_log_print(ANDROID_LOG_ERROR, GVR_LOGTAG, \
-                        "UNABLE TO CHECK GVR ERROR: NO CONTEXT"); \
-  } \
-}
-#define GVR_LOG(format, ...) __android_log_print(ANDROID_LOG_INFO, GVR_LOGTAG, format, ##__VA_ARGS__);
-#else
-#define GVR_CHECK(X) X
-#define GVR_LOG(...)
-#endif
-
-using namespace mozilla;
-using namespace mozilla::gl;
-using namespace mozilla::gfx;
-using namespace mozilla::gfx::impl;
-using namespace mozilla::layers;
-using namespace mozilla::dom;
-
-namespace {
-static VRDisplayGVR* sContextObserver;
-static RefPtr<GLContextEGL> sGLContextEGL;
-static gvr_context* sNonPresentingContext;
-
-gvr_context*
-GetNonPresentingContext() {
-  if (!sNonPresentingContext) {
-    // Try and restore if it has been lost
-    sNonPresentingContext = (gvr_context*)GeckoVRManager::CreateGVRNonPresentingContext();
-  }
-  return sNonPresentingContext;
-}
-
-class SynchronousRunnable : public nsIRunnable {
-public:
-  enum class Type {
-    PresentingContext,
-    NonPresentingContext,
-    Pause,
-    Resume
-  };
-  SynchronousRunnable(const Type aType, void* aContext)
-  : mType(aType)
-  , mContext(aContext)
-  , mUpdateMonitor(new Monitor("SynchronousRunnable_for_Android"))
-  , mUpdated(false)
-  {}
-  NS_DECL_THREADSAFE_ISUPPORTS
-  nsresult Run() override
-  {
-    MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
-    MonitorAutoLock lock(*mUpdateMonitor);
-    if (mType == Type::PresentingContext) {
-      SetGVRPresentingContext(mContext);
-    } else if (mType == Type::NonPresentingContext) {
-      CleanupGVRNonPresentingContext();
-    } else if (mType == Type::Pause) {
-      SetGVRPaused(true);
-    } else if (mType == Type::Resume) {
-      SetGVRPaused(false);
-    } else {
-      GVR_LOG("UNKNOWN SynchronousRunnable::Type!");
-    }
-    mUpdated = true;
-    lock.NotifyAll();
-    return NS_OK;
-  }
-  void Wait()
-  {
-    MonitorAutoLock lock(*mUpdateMonitor);
-    while(!mUpdated) {
-      lock.Wait();
-    }
-  }
-
-  static bool Dispatch(const Type aType, void* aContext)
-  {
-    if (!CompositorThreadHolder::IsInCompositorThread()) {
-      RefPtr<SynchronousRunnable> runnable = new SynchronousRunnable(aType, aContext);
-      CompositorThreadHolder::Loop()->PostTask(do_AddRef(runnable));
-      runnable->Wait();
-      return true;
-    }
-
-    return false;
-  }
-
-protected:
-  virtual ~SynchronousRunnable()
-  {
-    delete mUpdateMonitor;
-  }
-
-  Type mType;
-  void* mContext;
-  Monitor* mUpdateMonitor;
-  bool mUpdated;
-};
-
-}
-
-NS_IMPL_ISUPPORTS(SynchronousRunnable, nsIRunnable)
-
-void
-mozilla::gfx::SetGVRPresentingContext(void* aGVRPresentingContext)
-{
-  if (SynchronousRunnable::Dispatch(SynchronousRunnable::Type::PresentingContext, aGVRPresentingContext)) {
-    GVR_LOG("Done waiting for compositor thread to set presenting context.");
-    return;
-  }
-
-  MOZ_ASSERT(sContextObserver);
-  if (!sGLContextEGL && aGVRPresentingContext) {
-    CreateContextFlags flags = CreateContextFlags::NONE;
-    SurfaceCaps caps = SurfaceCaps::ForRGBA();
-    nsCString str;
-    sGLContextEGL = GLContextEGL::CreateEGLPBufferOffscreenContext(flags, IntSize(4, 4), caps, &str);
-    if (!sGLContextEGL->MakeCurrent()) {
-      GVR_LOG("Failed to make GL context current");
-    }
-  }
-  sContextObserver->SetPresentingContext(aGVRPresentingContext);
-}
-
-void
-mozilla::gfx::CleanupGVRNonPresentingContext()
-{
-  if (SynchronousRunnable::Dispatch(SynchronousRunnable::Type::NonPresentingContext, nullptr)) {
-    GVR_LOG("Done waiting for compositor thread to set non presenting context.");
-    return;
-  }
-
-  if (sNonPresentingContext) {
-    sNonPresentingContext = nullptr;
-    GeckoVRManager::DestroyGVRNonPresentingContext();
-  }
-}
-
-void
-mozilla::gfx::SetGVRPaused(const bool aPaused)
-{
-  if (SynchronousRunnable::Dispatch((aPaused ? SynchronousRunnable::Type::Pause : SynchronousRunnable::Type::Resume), nullptr)) {
-    GVR_LOG("Done waiting for GVR in compositor to: %s",(aPaused ? "Pause" : "Resume"));
-    return;
-  }
-  MOZ_ASSERT(sContextObserver);
-  sContextObserver->SetPaused(aPaused);
-}
-
-VRDisplayGVR::VRDisplayGVR()
-  : VRDisplayHost(VRDeviceType::GVR)
-  , mIsPresenting(false)
-  , mControllerAdded(false)
-  , mPresentingContext(nullptr)
-  , mControllerContext(nullptr)
-  , mControllerState(nullptr)
-  , mViewportList(nullptr)
-  , mLeftViewport(nullptr)
-  , mRightViewport(nullptr)
-  , mSwapChain(nullptr)
-  , mFrameBufferSize{0, 0}
-{
-  MOZ_COUNT_CTOR_INHERITED(VRDisplayGVR, VRDisplayHost);
-  MOZ_ASSERT(GetNonPresentingContext());
-  MOZ_ASSERT(!sContextObserver); // There can be only one GVR display at a time.
-  sContextObserver = this;
-
-  strncpy(mDisplayInfo.mDisplayName, "GVR HMD", kVRDisplayNameMaxLen);
-  mDisplayInfo.mIsConnected = true;
-  mDisplayInfo.mIsMounted = true;
-  mDisplayInfo.mCapabilityFlags = VRDisplayCapabilityFlags::Cap_None |
-                                  VRDisplayCapabilityFlags::Cap_Orientation |
-                                  VRDisplayCapabilityFlags::Cap_Position | // Not yet...
-                                  VRDisplayCapabilityFlags::Cap_Present;
-
-  GVR_CHECK(gvr_refresh_viewer_profile(GetNonPresentingContext()));
-  mViewportList = GVR_CHECK(gvr_buffer_viewport_list_create(GetNonPresentingContext()));
-  mLeftViewport = GVR_CHECK(gvr_buffer_viewport_create(GetNonPresentingContext()));
-  mRightViewport = GVR_CHECK(gvr_buffer_viewport_create(GetNonPresentingContext()));
-  UpdateViewport();
-
-  dom::GamepadHand hand = dom::GamepadHand::Right;
-  const gvr_user_prefs* prefs = GVR_CHECK(gvr_get_user_prefs(GetNonPresentingContext()));
-  if (prefs) {
-    hand = ((gvr_user_prefs_get_controller_handedness(prefs) == GVR_CONTROLLER_RIGHT_HANDED) ?
-             dom::GamepadHand::Right : dom::GamepadHand::Left);
-  }
-  mController = new VRControllerGVR(hand, mDisplayInfo.mDisplayID);
-}
-
-VRDisplayGVR::~VRDisplayGVR()
-{
-  MOZ_COUNT_DTOR_INHERITED(VRDisplayGVR, VRDisplayHost);
-}
-
-void
-VRDisplayGVR::ZeroSensor()
-{
-}
-
-void
-VRDisplayGVR::StartPresentation()
-{
-  if (mIsPresenting) {
-    return;
-  }
-
-  mIsPresenting = true;
-  GeckoVRManager::EnableVRMode();
-}
-
-void
-VRDisplayGVR::StopPresentation()
-{
-  if (!mIsPresenting) {
-    return;
-  }
-
-  mIsPresenting = false;
-  GeckoVRManager::DisableVRMode();
-}
-
-bool
-VRDisplayGVR::SubmitFrame(const mozilla::layers::EGLImageDescriptor* aDescriptor,
-                          const gfx::Rect& aLeftEyeRect,
-                          const gfx::Rect& aRightEyeRect)
-{
-  if (!mPresentingContext) {
-    GVR_LOG("Unable to submit frame. No presenting context")
-    return false;
-  }
-
-  if (!sGLContextEGL) {
-    GVR_LOG("Unable to submit frame. No GL Context");
-    return false;
-  }
-
-  if (!sGLContextEGL->MakeCurrent()) {
-    GVR_LOG("Failed to make GL context current");
-    return false;
-  }
-
-  EGLImage image = (EGLImage)aDescriptor->image();
-  EGLSync sync = (EGLSync)aDescriptor->fence();
-  gfx::IntSize size = aDescriptor->size();
-  MOZ_ASSERT(mSwapChain);
-  GVR_CHECK(gvr_get_recommended_buffer_viewports(mPresentingContext, mViewportList));
-  if ((size.width != mFrameBufferSize.width) || (size.height != mFrameBufferSize.height)) {
-    mFrameBufferSize.width = size.width;
-    mFrameBufferSize.height = size.height;
-    GVR_CHECK(gvr_swap_chain_resize_buffer(mSwapChain, 0, mFrameBufferSize));
-    GVR_LOG("Resize Swap Chain %d,%d", mFrameBufferSize.width, mFrameBufferSize.height);
-  }
-  gvr_frame* frame = GVR_CHECK(gvr_swap_chain_acquire_frame(mSwapChain));
-  if (!frame) {
-    // Sometimes the swap chain seems to not initialized correctly so that
-    // frames can not be acquired. Recreating the swap chain seems to fix the
-    // issue.
-    GVR_LOG("Unable to acquire GVR frame. Recreating swap chain.");
-    RecreateSwapChain();
-    return false;
-  }
-  GVR_CHECK(gvr_frame_bind_buffer(frame, 0));
-
-  EGLint status = LOCAL_EGL_CONDITION_SATISFIED;
-  auto* egl = gl::GLLibraryEGL::Get();
-
-  if (sync) {
-    MOZ_ASSERT(egl->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync));
-    status = egl->fClientWaitSync(EGL_DISPLAY(), sync, 0, LOCAL_EGL_FOREVER);
-  }
-
-  if (status != LOCAL_EGL_CONDITION_SATISFIED) {
-    MOZ_ASSERT(status != 0,
-               "ClientWaitSync generated an error. Has sync already been destroyed?");
-    return false;
-  }
-
-  if (image) {
-    GLuint tex = 0;
-    sGLContextEGL->fGenTextures(1, &tex);
-
-    const ScopedSaveMultiTex saveTex(sGLContextEGL, 1, LOCAL_GL_TEXTURE_2D);
-    sGLContextEGL->fBindTexture(LOCAL_GL_TEXTURE_2D, tex);
-    sGLContextEGL->TexParams_SetClampNoMips();
-    sGLContextEGL->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, image);
-    sGLContextEGL->BlitHelper()->DrawBlitTextureToFramebuffer(tex, gfx::IntSize(size.width, size.height), gfx::IntSize(mFrameBufferSize.width,  mFrameBufferSize.height));
-    sGLContextEGL->fDeleteTextures(1, &tex);
-  } else {
-    GVR_LOG("Unable to submit frame. Unable to extract EGLImage");
-    return false;
-  }
-  GVR_CHECK(gvr_frame_unbind(frame));
-  GVR_CHECK(gvr_frame_submit(&frame, mViewportList, mHeadMatrix));
-  return true;
-}
-
-static void
-FillMatrix(gfx::Matrix4x4 &target, const gvr_mat4f& source)
-{
-  target._11 = source.m[0][0];
-  target._12 = source.m[0][1];
-  target._13 = source.m[0][2];
-  target._14 = source.m[0][3];
-  target._21 = source.m[1][0];
-  target._22 = source.m[1][1];
-  target._23 = source.m[1][2];
-  target._24 = source.m[1][3];
-  target._31 = source.m[2][0];
-  target._32 = source.m[2][1];
-  target._33 = source.m[2][2];
-  target._34 = source.m[2][3];
-  target._41 = source.m[3][0];
-  target._42 = source.m[3][1];
-  target._43 = source.m[3][2];
-  target._44 = source.m[3][3];
-}
-
-VRHMDSensorState
-VRDisplayGVR::GetSensorState()
-{
-  VRHMDSensorState result{};
-
-  gvr_context* context = (mPresentingContext ? mPresentingContext : GetNonPresentingContext());
-
-  if (!context) {
-    GVR_LOG("Unable to get sensor state. Context is null");
-    return result;
-  }
-
-  gvr_clock_time_point when = GVR_CHECK(gvr_get_time_point_now());
-  if (mIsPresenting) {
-    // 50ms into the future is what GVR docs recommends using for head rotation
-    // prediction.
-    when.monotonic_system_time_nanos += 50000000;
-  }
-  mHeadMatrix = GVR_CHECK(gvr_get_head_space_from_start_space_rotation(context, when));
-  gvr_mat4f neck = GVR_CHECK(gvr_apply_neck_model(context, mHeadMatrix, 1.0));;
-
-  gfx::Matrix4x4 m;
-
-  FillMatrix(m, neck);
-  m.Invert();
-  gfx::Quaternion rot;
-  rot.SetFromRotationMatrix(m);
-
-  result.flags |= VRDisplayCapabilityFlags::Cap_Orientation;
-  result.orientation[0] = rot.x;
-  result.orientation[1] = rot.y;
-  result.orientation[2] = rot.z;
-  result.orientation[3] = rot.w;
-  result.angularVelocity[0] = 0.0f;
-  result.angularVelocity[1] = 0.0f;
-  result.angularVelocity[2] = 0.0f;
-
-  result.flags |= VRDisplayCapabilityFlags::Cap_Position;
-  result.position[0] = m._14;
-  result.position[1] = m._24;
-  result.position[2] = m._34;
-  result.linearVelocity[0] = 0.0f;
-  result.linearVelocity[1] = 0.0f;
-  result.linearVelocity[2] = 0.0f;
-
-  UpdateHeadToEye(context);
-  CalcViewMatrices(&result, mHeadToEyes);
-
-  return result;
-}
-
-void
-VRDisplayGVR::SetPaused(const bool aPaused)
-{
-  if (aPaused) {
-    if (mPresentingContext) {
-      GVR_CHECK(gvr_pause_tracking(mPresentingContext));
-    } else if (sNonPresentingContext) {
-      GVR_CHECK(gvr_pause_tracking(sNonPresentingContext));
-    }
-
-    if (mControllerContext) {
-      GVR_CHECK(gvr_controller_pause(mControllerContext));
-    }
-  } else {
-    if (mPresentingContext) {
-      GVR_CHECK(gvr_refresh_viewer_profile(mPresentingContext));
-      GVR_CHECK(gvr_resume_tracking(mPresentingContext));
-    } else if (sNonPresentingContext) {
-      GVR_CHECK(gvr_resume_tracking(sNonPresentingContext));
-    }
-
-    if (mControllerContext) {
-      GVR_CHECK(gvr_controller_resume(mControllerContext));
-    }
-  }
-}
-
-void
-VRDisplayGVR::SetPresentingContext(void* aGVRPresentingContext)
-{
-  MOZ_ASSERT(sGLContextEGL);
-  sGLContextEGL->MakeCurrent();
-  mPresentingContext = (gvr_context*)aGVRPresentingContext;
-  if (mPresentingContext) {
-    GVR_CHECK(gvr_initialize_gl(mPresentingContext));
-    RecreateSwapChain();
-  } else {
-
-    if (mSwapChain) {
-      // gvr_swap_chain_destroy will set the pointer to null
-      GVR_CHECK(gvr_swap_chain_destroy(&mSwapChain));
-      MOZ_ASSERT(!mSwapChain);
-    }
-
-    // The presentation context has been destroy, probably by the user so increment the presenting
-    // generation if we are presenting so that the DOM knows to end the current presentation.
-    if (mIsPresenting) {
-      mDisplayInfo.mPresentingGeneration++;
-    }
-  }
-}
-
-void
-VRDisplayGVR::UpdateHeadToEye(gvr_context* aContext)
-{
-  if (!aContext) {
-    return;
-  }
-
-  for (uint32_t eyeIndex = 0; eyeIndex < 2; eyeIndex++) {
-    gvr_mat4f eye = GVR_CHECK(gvr_get_eye_from_head_matrix(aContext, eyeIndex));
-    mDisplayInfo.mEyeTranslation[eyeIndex].x = -eye.m[0][3];
-    mDisplayInfo.mEyeTranslation[eyeIndex].y = -eye.m[1][3];
-    mDisplayInfo.mEyeTranslation[eyeIndex].z = -eye.m[2][3];
-    mHeadToEyes[eyeIndex] = gfx::Matrix4x4();
-    mHeadToEyes[eyeIndex].PreTranslate(eye.m[0][3], eye.m[1][3], eye.m[2][3]);
-  }
-}
-
-void
-VRDisplayGVR::UpdateViewport()
-{
-  gvr_context* context = (mPresentingContext ? mPresentingContext : GetNonPresentingContext());
-
-  if (!context) {
-    return;
-  }
-
-  GVR_CHECK(gvr_get_recommended_buffer_viewports(context, mViewportList));
-  GVR_CHECK(gvr_buffer_viewport_list_get_item(mViewportList, 0, mLeftViewport));
-  GVR_CHECK(gvr_buffer_viewport_list_get_item(mViewportList, 1, mRightViewport));
-
-  gvr_rectf fov = GVR_CHECK(gvr_buffer_viewport_get_source_fov(mLeftViewport));
-  mDisplayInfo.mEyeFOV[VRDisplayInfo::Eye_Left] = VRFieldOfView(fov.top, fov.right, fov.bottom, fov.left);
-  GVR_LOG("FOV:L top:%f right:%f bottom:%f left:%f",(float)fov.top, (float)fov.left, (float)fov.bottom, (float)fov.right);
-
-  fov = GVR_CHECK(gvr_buffer_viewport_get_source_fov(mRightViewport));
-  mDisplayInfo.mEyeFOV[VRDisplayInfo::Eye_Right] = VRFieldOfView(fov.top, fov.right, fov.bottom, fov.left);
-  GVR_LOG("FOV:R top:%f right:%f bottom:%f left:%f",(float)fov.top, (float)fov.left, (float)fov.bottom, (float)fov.right);
-
-  gvr_sizei size = GVR_CHECK(gvr_get_maximum_effective_render_target_size(context));
-  mDisplayInfo.mEyeResolution = IntSize(size.width / 2, size.height);
-  GVR_LOG("Eye Resolution: %dx%d",mDisplayInfo.mEyeResolution.width,mDisplayInfo.mEyeResolution.height);
-
-  UpdateHeadToEye(context);
-}
-
-void
-VRDisplayGVR::RecreateSwapChain()
-{
-  MOZ_ASSERT(sGLContextEGL);
-  sGLContextEGL->MakeCurrent();
-  if (mSwapChain) {
-    // gvr_swap_chain_destroy will set the pointer to null
-    GVR_CHECK(gvr_swap_chain_destroy(&mSwapChain));
-    MOZ_ASSERT(!mSwapChain);
-  }
-  gvr_buffer_spec* spec = GVR_CHECK(gvr_buffer_spec_create(mPresentingContext));
-  mFrameBufferSize = GVR_CHECK(gvr_get_maximum_effective_render_target_size(mPresentingContext));
-  GVR_CHECK(gvr_buffer_spec_set_size(spec, mFrameBufferSize));
-  GVR_CHECK(gvr_buffer_spec_set_samples(spec, 0));
-  GVR_CHECK(gvr_buffer_spec_set_color_format(spec, GVR_COLOR_FORMAT_RGBA_8888));
-  GVR_CHECK(gvr_buffer_spec_set_depth_stencil_format(spec, GVR_DEPTH_STENCIL_FORMAT_NONE));
-  mSwapChain = GVR_CHECK(gvr_swap_chain_create(mPresentingContext, (const gvr_buffer_spec**)&spec, 1));
-  GVR_CHECK(gvr_buffer_spec_destroy(&spec));
-}
-
-void
-VRDisplayGVR::EnableControllers(const bool aEnable, VRSystemManager* aManager)
-{
-  if (aEnable && !mControllerAdded) {
-    // Sometimes the gamepad doesn't get removed cleanly so just try to remove it before adding it.
-    aManager->RemoveGamepad(mController->GetControllerInfo().mControllerID);
-    aManager->AddGamepad(mController->GetControllerInfo());
-    mControllerAdded = true;
-  } else if (!aEnable && mControllerAdded) {
-    mControllerAdded = false;
-    aManager->RemoveGamepad(mController->GetControllerInfo().mControllerID);
-  }
-
-  gvr_context* context = mPresentingContext;
-
-  if (!context) {
-    if (mControllerContext) {
-      GVR_CHECK(gvr_controller_destroy(&mControllerContext));
-    }
-    return;
-  }
-
-  if ((aEnable && mControllerContext) || (!aEnable && !mControllerContext)) {
-    return;
-  }
-
-  if (aEnable) {
-    if (!mControllerContext) {
-      int32_t options = GVR_CHECK(gvr_controller_get_default_options());
-      options |= GVR_CONTROLLER_ENABLE_GYRO | GVR_CONTROLLER_ENABLE_ACCEL | GVR_CONTROLLER_ENABLE_ARM_MODEL;
-      mControllerContext = GVR_CHECK(gvr_controller_create_and_init(options, context));
-      GVR_CHECK(gvr_controller_resume(mControllerContext));
-    }
-    if (!mControllerState) {
-      mControllerState = GVR_CHECK(gvr_controller_state_create());
-    }
-  } else {
-    GVR_CHECK(gvr_controller_pause(mControllerContext));
-    GVR_CHECK(gvr_controller_destroy(&mControllerContext));
-  }
-}
-
-void
-VRDisplayGVR::UpdateControllers(VRSystemManager* aManager)
-{
-  if (!mControllerContext) {
-    return;
-  }
-
-  GVR_CHECK(gvr_controller_apply_arm_model(mControllerContext, 0, mController->GetHand() == dom::GamepadHand::Right ? GVR_CONTROLLER_RIGHT_HANDED : GVR_CONTROLLER_LEFT_HANDED, GVR_ARM_MODEL_FOLLOW_GAZE, mHeadMatrix));
-  GVR_CHECK(gvr_controller_state_update(mControllerContext, 0, mControllerState));
-  mController->Update(mControllerState, aManager);
-}
-
-
-void
-VRDisplayGVR::GetControllers(nsTArray<RefPtr<VRControllerHost> >& aControllerResult)
-{
-  aControllerResult.AppendElement(mController.get());
-}
-
-VRControllerGVR::VRControllerGVR(dom::GamepadHand aHand, uint32_t aDisplayID)
-  : VRControllerHost(VRDeviceType::GVR, aHand, aDisplayID)
-{
-  MOZ_COUNT_CTOR_INHERITED(VRControllerGVR, VRControllerHost);
-
-  VRControlerState& state = mControllerInfo.mControllerState;
-  strncpy(state.mControllerName, "Daydream Controller", kVRControllerNameMaxLen);
-
-  // The gvr_controller_button enum starts with GVR_CONTROLLER_BUTTON_NONE at index zero
-  // so the GVR controller has one less button than GVR_CONTROLLER_BUTTON_COUNT specifies.
-  state.mNumButtons = GVR_CONTROLLER_BUTTON_COUNT - 1; // Skip dummy none button
-  state.mNumAxes = 2;
-  state.mNumHaptics = 0;
-}
-
-VRControllerGVR::~VRControllerGVR()
-{
-  MOZ_COUNT_DTOR_INHERITED(VRControllerGVR, VRControllerHost);
-}
-
-void
-VRControllerGVR::Update(gvr_controller_state* aState, VRSystemManager* aManager)
-{
-  mPose.Clear();
-
-  if (gvr_controller_state_get_connection_state(aState) != GVR_CONTROLLER_CONNECTED) {
-    return;
-  }
-  const uint64_t previousPressMask = GetButtonPressed();
-  const uint64_t previousTouchMask = GetButtonTouched();
-  uint64_t currentPressMask = 0;
-  uint64_t currentTouchMask = 0;
-  // Index 0 is the dummy button so skip it.
-  for (int ix = 1; ix < GVR_CONTROLLER_BUTTON_COUNT; ix++) {
-    const uint64_t buttonMask = 0x01 << (ix - 1);
-    bool pressed = gvr_controller_state_get_button_state(aState, ix);
-    bool touched = pressed;
-    if (ix == GVR_CONTROLLER_BUTTON_CLICK) {
-       touched = gvr_controller_state_is_touching(aState);
-       double xAxis = 0.0;
-       double yAxis = 0.0;
-       if (touched) {
-         gvr_vec2f axes = gvr_controller_state_get_touch_pos(aState);
-         xAxis = (axes.x * 2.0) - 1.0;
-         yAxis = (axes.y * 2.0) - 1.0;
-       }
-       aManager->NewAxisMove(0, 0, xAxis);
-       aManager->NewAxisMove(0, 1, yAxis);
-    }
-    if (pressed) {
-      currentPressMask |= buttonMask;
-    }
-    if (touched) {
-      currentTouchMask |= buttonMask;
-    }
-    if (((currentPressMask & buttonMask) ^ (previousPressMask & buttonMask)) ||
-        ((currentTouchMask & buttonMask) ^ (previousTouchMask & buttonMask))) {
-      aManager->NewButtonEvent(0, ix - 1, pressed, touched, pressed ? 1.0 : 0.0);
-    }
-  }
-  SetButtonPressed(currentPressMask);
-  SetButtonTouched(currentTouchMask);
-
-  mPose.flags = dom::GamepadCapabilityFlags::Cap_Orientation | dom::GamepadCapabilityFlags::Cap_Position | dom::GamepadCapabilityFlags::Cap_LinearAcceleration;
-
-  gvr_quatf ori = gvr_controller_state_get_orientation(aState);
-  mPose.orientation[0] = ori.qx;
-  mPose.orientation[1] = ori.qy;
-  mPose.orientation[2] = ori.qz;
-  mPose.orientation[3] = ori.qw;
-  mPose.isOrientationValid = true;
-
-  gvr_vec3f acc = gvr_controller_state_get_accel(aState);
-  mPose.linearAcceleration[0] = acc.x;
-  mPose.linearAcceleration[1] = acc.y;
-  mPose.linearAcceleration[2] = acc.z;
-
-  gvr_vec3f vel = gvr_controller_state_get_gyro(aState);
-  mPose.angularVelocity[0] = vel.x;
-  mPose.angularVelocity[1] = vel.y;
-  mPose.angularVelocity[2] = vel.z;
-
-  gvr_vec3f pos =  gvr_controller_state_get_position(aState);
-  mPose.position[0] = pos.x;
-  mPose.position[1] = pos.y;
-  mPose.position[2] = pos.z;
-
-  aManager->NewPoseState(0, mPose);
-}
-
-/*static*/ already_AddRefed<VRSystemManagerGVR>
-VRSystemManagerGVR::Create()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (!gfxPrefs::VREnabled()) {
-    return nullptr;
-  }
-
-  RefPtr<VRSystemManagerGVR> manager = new VRSystemManagerGVR();
-  return manager.forget();
-}
-
-void
-VRSystemManagerGVR::Destroy()
-{
-
-}
-
-void
-VRSystemManagerGVR::Shutdown()
-{
-
-}
-
-void
-VRSystemManagerGVR::Enumerate()
-{
-  if (!GeckoVRManager::IsGVRPresent()) {
-    return;
-  }
-
-  if (!mGVRHMD) {
-    mGVRHMD = new VRDisplayGVR();
-  }
-}
-
-bool
-VRSystemManagerGVR::ShouldInhibitEnumeration()
-{
-  if (VRSystemManager::ShouldInhibitEnumeration()) {
-    return true;
-  }
-  if (mGVRHMD) {
-    // When we find an a VR device, don't
-    // allow any further enumeration as it
-    // may get picked up redundantly by other
-    // API's.
-    return true;
-  }
-  return false;
-}
-
-void
-VRSystemManagerGVR::GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult)
-{
-  if (mGVRHMD) {
-    aHMDResult.AppendElement(mGVRHMD);
-  }
-}
-
-bool
-VRSystemManagerGVR::GetIsPresenting()
-{
-  if (!mGVRHMD) {
-    return false;
-  }
-
-  VRDisplayInfo displayInfo(mGVRHMD->GetDisplayInfo());
-  return displayInfo.GetPresentingGroups() != kVRGroupNone;
-}
-
-void
-VRSystemManagerGVR::HandleInput()
-{
-  if (mGVRHMD) {
-    mGVRHMD->UpdateControllers(this);
-  }
-}
-
-void
-VRSystemManagerGVR::GetControllers(nsTArray<RefPtr<VRControllerHost>>& aControllerResult)
-{
-  if (mGVRHMD) {
-    mGVRHMD->GetControllers(aControllerResult);
-  }
-}
-
-void
-VRSystemManagerGVR::ScanForControllers()
-{
-  if (mGVRHMD) {
-    mGVRHMD->EnableControllers(true, this);
-  }
-}
-
-void
-VRSystemManagerGVR::RemoveControllers()
-{
-  if (mGVRHMD) {
-    mGVRHMD->EnableControllers(false, this);
-  }
-}
-
-void
-VRSystemManagerGVR::VibrateHaptic(uint32_t aControllerIdx,
-                                  uint32_t aHapticIndex,
-                                  double aIntensity,
-                                  double aDuration,
-                                  const VRManagerPromise& aPromise)
-{
-
-}
-
-void
-VRSystemManagerGVR::StopVibrateHaptic(uint32_t aControllerIdx)
-{
-
-}
-
-VRSystemManagerGVR::VRSystemManagerGVR()
-  : mGVRHMD(nullptr)
-{
-
-}
-
-VRSystemManagerGVR::~VRSystemManagerGVR()
-{
-
-}
-
deleted file mode 100644
--- a/gfx/vr/gfxVRGVR.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef GFX_VR_GVR_H
-#define GFX_VR_GVR_H
-
-#include "gfxVR.h"
-
-#include <memory>
-
-#include "mozilla/EnumeratedArray.h"
-#include "mozilla/gfx/2D.h"
-#include "mozilla/gfx/Matrix.h"
-#include "mozilla/RefPtr.h"
-#include "mozilla/UniquePtr.h"
-
-#include "nsTArray.h"
-#include "nsIRunnable.h"
-#include "nsIScreen.h"
-#include "nsCOMPtr.h"
-
-#include "VRDisplayHost.h"
-
-#pragma GCC system_header
-#pragma GCC visibility push(default)
-#include "vr/gvr/capi/include/gvr.h"
-#include "vr/gvr/capi/include/gvr_controller.h"
-#pragma GCC visibility pop
-
-
-namespace mozilla {
-namespace gl {
-class GLContextEGL;
-} // namespace gl
-namespace layers {
-class EGLImageDescriptor;
-} // namespace layers
-namespace gfx {
-namespace impl {
-
-class VRControllerGVR : public VRControllerHost
-{
-public:
-  explicit VRControllerGVR(dom::GamepadHand aHand, uint32_t aDisplayID);
-  virtual ~VRControllerGVR();
-  void Update(gvr_controller_state* aState, VRSystemManager* aManager);
-};
-
-class VRDisplayGVR : public VRDisplayHost
-{
-public:
-  VRDisplayGVR();
-
-  // BEGIN VRDisplayHost interface
-  void ZeroSensor() override;
-  void StartPresentation() override;
-  void StopPresentation() override;
-  bool SubmitFrame(const mozilla::layers::EGLImageDescriptor* aDescriptor,
-                   const gfx::Rect& aLeftEyeRect,
-                   const gfx::Rect& aRightEyeRect) override;
-protected:
-  virtual VRHMDSensorState GetSensorState() override;
-  // END VRDisplayHost interface
-
-public:
-  void SetPaused(const bool aPaused);
-  void SetPresentingContext(void* aGVRPresentingContext);
-  void EnableControllers(const bool aEnable, VRSystemManager* aManager);
-  void UpdateControllers(VRSystemManager* aManager);
-  void GetControllers(nsTArray<RefPtr<VRControllerHost> >& aControllerResult);
-
-protected:
-  virtual ~VRDisplayGVR();
-  void UpdateHeadToEye(gvr_context* aContext);
-  void UpdateViewport();
-  void RecreateSwapChain();
-
-  bool mIsPresenting;
-  bool mControllerAdded;
-
-  gfx::Matrix4x4 mHeadToEyes[2];
-  gvr_context* mPresentingContext;
-  gvr_controller_context* mControllerContext;
-  gvr_controller_state* mControllerState;
-  gvr_buffer_viewport_list* mViewportList;
-  gvr_buffer_viewport* mLeftViewport;
-  gvr_buffer_viewport* mRightViewport;
-  gvr_mat4f mHeadMatrix;
-  gvr_swap_chain* mSwapChain;
-  gvr_sizei mFrameBufferSize;
-
-  RefPtr<VRControllerGVR> mController;
-};
-
-
-} // namespace impl
-
-class VRSystemManagerGVR : public VRSystemManager
-{
-public:
-  static already_AddRefed<VRSystemManagerGVR> Create();
-
-  void Destroy() override;
-  void Shutdown() override;
-  void Enumerate() override;
-  bool ShouldInhibitEnumeration() override;
-  void GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult) override;
-  bool GetIsPresenting() override;
-  void HandleInput() override;
-  void GetControllers(nsTArray<RefPtr<VRControllerHost>>&
-                      aControllerResult) override;
-  void ScanForControllers() override;
-  void RemoveControllers() override;
-  void VibrateHaptic(uint32_t aControllerIdx,
-                     uint32_t aHapticIndex,
-                     double aIntensity,
-                     double aDuration,
-                     const VRManagerPromise& aPromise) override;
-  void StopVibrateHaptic(uint32_t aControllerIdx) override;
-
-protected:
-  VRSystemManagerGVR();
-  virtual ~VRSystemManagerGVR();
-
-private:
-  RefPtr<impl::VRDisplayGVR> mGVRHMD;
-};
-
-} // namespace gfx
-} // namespace mozilla
-
-
-#endif /* GFX_VR_GVR_H */
deleted file mode 100644
--- a/gfx/vr/gfxVRGVRAPI.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef GFX_VR_GVR_API_H
-#define GFX_VR_GVR_API_H
-namespace mozilla {
-namespace gfx {
-
-void SetGVRPresentingContext(void* aGVRPresentingContext);
-void CleanupGVRNonPresentingContext();
-void SetGVRPaused(const bool aPaused);
-
-} // namespace gfx
-} // namespace mozilla
-#endif // GFX_VR_GVR_API_H
--- a/gfx/vr/gfxVROSVR.cpp
+++ b/gfx/vr/gfxVROSVR.cpp
@@ -360,28 +360,16 @@ VRDisplayOSVR::SubmitFrame(MacIOSurface*
                            const gfx::Rect& aLeftEyeRect,
                            const gfx::Rect& aRightEyeRect)
 {
   // XXX Add code to submit frame
   MOZ_ASSERT(mSubmitThread->GetThread() == NS_GetCurrentThread());
   return false;
 }
 
-#elif defined(MOZ_ANDROID_GOOGLE_VR)
-
-bool
-VRDisplayOSVR::SubmitFrame(const mozilla::layers::EGLImageDescriptor*,
-                           const gfx::Rect& aLeftEyeRect,
-                           const gfx::Rect& aRightEyeRect)
-{
-  // XXX Add code to submit frame
-  MOZ_ASSERT(mSubmitThread->GetThread() == NS_GetCurrentThread());
-  return false;
-}
-
 #endif
 
 void
 VRDisplayOSVR::StartPresentation()
 {
   // XXX Add code to start VR Presentation
 }
 
--- a/gfx/vr/gfxVROSVR.h
+++ b/gfx/vr/gfxVROSVR.h
@@ -41,20 +41,16 @@ protected:
                            const IntSize& aSize,
                            const gfx::Rect& aLeftEyeRect,
                            const gfx::Rect& aRightEyeRect) override;
 #elif defined(XP_MACOSX)
   virtual bool SubmitFrame(MacIOSurface* aMacIOSurface,
                            const IntSize& aSize,
                            const gfx::Rect& aLeftEyeRect,
                            const gfx::Rect& aRightEyeRect) override;
-#elif defined(MOZ_ANDROID_GOOGLE_VR)
-  virtual bool SubmitFrame(const mozilla::layers::EGLImageDescriptor*,
-                           const gfx::Rect& aLeftEyeRect,
-                           const gfx::Rect& aRightEyeRect) override;
 #endif
 
 public:
   explicit VRDisplayOSVR(OSVR_ClientContext* context,
                          OSVR_ClientInterface* iface,
                          OSVR_DisplayConfig* display);
 
 protected:
--- a/gfx/vr/gfxVRPuppet.cpp
+++ b/gfx/vr/gfxVRPuppet.cpp
@@ -553,22 +553,22 @@ VRDisplayPuppet::SubmitFrame(MacIOSurfac
       MOZ_ASSERT(false, "No support for showing VR frames on MacOSX yet.");
       break;
     }
   }
 
   return false;
 }
 
-#elif defined(MOZ_ANDROID_GOOGLE_VR)
+#elif defined(MOZ_WIDGET_ANDROID)
 
 bool
-VRDisplayPuppet::SubmitFrame(const mozilla::layers::EGLImageDescriptor* aDescriptor,
-                           const gfx::Rect& aLeftEyeRect,
-                           const gfx::Rect& aRightEyeRect)
+VRDisplayPuppet::SubmitFrame(const mozilla::layers::SurfaceTextureDescriptor& aDescriptor,
+                             const gfx::Rect& aLeftEyeRect,
+                             const gfx::Rect& aRightEyeRect)
 {
   MOZ_ASSERT(mSubmitThread->GetThread() == NS_GetCurrentThread());
   return false;
 }
 
 #endif
 
 void
--- a/gfx/vr/gfxVRPuppet.h
+++ b/gfx/vr/gfxVRPuppet.h
@@ -37,18 +37,18 @@ protected:
                            const IntSize& aSize,
                            const gfx::Rect& aLeftEyeRect,
                            const gfx::Rect& aRightEyeRect) override;
 #elif defined(XP_MACOSX)
   virtual bool SubmitFrame(MacIOSurface* aMacIOSurface,
                            const IntSize& aSize,
                            const gfx::Rect& aLeftEyeRect,
                            const gfx::Rect& aRightEyeRect) override;
-#elif defined(MOZ_ANDROID_GOOGLE_VR)
-  virtual bool SubmitFrame(const mozilla::layers::EGLImageDescriptor* aDescriptor,
+#elif defined(MOZ_WIDGET_ANDROID)
+  virtual bool SubmitFrame(const mozilla::layers::SurfaceTextureDescriptor& aDescriptor,
                            const gfx::Rect& aLeftEyeRect,
                            const gfx::Rect& aRightEyeRect) override;
 #endif
 
 public:
   explicit VRDisplayPuppet();
   void Refresh();
 
--- a/gfx/vr/ipc/VRManagerChild.cpp
+++ b/gfx/vr/ipc/VRManagerChild.cpp
@@ -15,16 +15,18 @@
 #include "mozilla/dom/VREventObserver.h"
 #include "mozilla/dom/WindowBinding.h" // for FrameRequestCallback
 #include "mozilla/dom/ContentChild.h"
 #include "nsContentUtils.h"
 #include "mozilla/dom/GamepadManager.h"
 #include "mozilla/dom/VRServiceTest.h"
 #include "mozilla/layers/SyncObject.h"
 
+using namespace mozilla::dom;
+
 namespace {
 const nsTArray<RefPtr<dom::VREventObserver>>::index_type kNoIndex =
   nsTArray<RefPtr<dom::VREventObserver> >::NoIndex;
 } // namespace
 
 namespace mozilla {
 namespace gfx {
 
--- a/gfx/vr/ipc/VRMessageUtils.h
+++ b/gfx/vr/ipc/VRMessageUtils.h
@@ -42,16 +42,17 @@ struct ParamTraits<mozilla::gfx::VRDispl
     WriteParam(aMsg, displayName);
     WriteParam(aMsg, aParam.mCapabilityFlags);
     WriteParam(aMsg, aParam.mEyeResolution.width);
     WriteParam(aMsg, aParam.mEyeResolution.height);
     WriteParam(aMsg, aParam.mIsConnected);
     WriteParam(aMsg, aParam.mIsMounted);
     WriteParam(aMsg, aParam.mStageSize.width);
     WriteParam(aMsg, aParam.mStageSize.height);
+    WriteParam(aMsg, aParam.mPresentingGeneration);
     for (int i = 0; i < 16; i++) {
       // TODO - Should probably memcpy the whole array or
       // convert Maxtrix4x4 to a POD type and use it
       // instead
       WriteParam(aMsg, aParam.mSittingToStandingTransform[i]);
     }
     for (int i = 0; i < mozilla::gfx::VRDisplayState::NumEyes; i++) {
       WriteParam(aMsg, aParam.mEyeFOV[i]);
@@ -66,17 +67,18 @@ struct ParamTraits<mozilla::gfx::VRDispl
     nsCString displayName;
     if (!ReadParam(aMsg, aIter, &(displayName)) ||
         !ReadParam(aMsg, aIter, &(aResult->mCapabilityFlags)) ||
         !ReadParam(aMsg, aIter, &(aResult->mEyeResolution.width)) ||
         !ReadParam(aMsg, aIter, &(aResult->mEyeResolution.height)) ||
         !ReadParam(aMsg, aIter, &(aResult->mIsConnected)) ||
         !ReadParam(aMsg, aIter, &(aResult->mIsMounted)) ||
         !ReadParam(aMsg, aIter, &(aResult->mStageSize.width)) ||
-        !ReadParam(aMsg, aIter, &(aResult->mStageSize.height))) {
+        !ReadParam(aMsg, aIter, &(aResult->mStageSize.height)) ||
+        !ReadParam(aMsg, aIter, &(aResult->mPresentingGeneration))) {
       return false;
     }
     for (int i = 0; i < 16; i++) {
       if (!ReadParam(aMsg, aIter, &(aResult->mSittingToStandingTransform[i]))) {
         return false;
       }
     }
     strncpy(aResult->mDisplayName, displayName.BeginReading(), mozilla::gfx::kVRDisplayNameMaxLen);
@@ -99,31 +101,29 @@ struct ParamTraits<mozilla::gfx::VRDispl
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mType);
     WriteParam(aMsg, aParam.mDisplayID);
     WriteParam(aMsg, aParam.mPresentingGroups);
     WriteParam(aMsg, aParam.mGroupMask);
     WriteParam(aMsg, aParam.mFrameId);
-    WriteParam(aMsg, aParam.mPresentingGeneration);
     WriteParam(aMsg, aParam.mDisplayState);
     for (int i = 0; i < mozilla::gfx::kVRMaxLatencyFrames; i++) {
       WriteParam(aMsg, aParam.mLastSensorState[i]);
     }
   }
 
   static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->mType)) ||
         !ReadParam(aMsg, aIter, &(aResult->mDisplayID)) ||
         !ReadParam(aMsg, aIter, &(aResult->mPresentingGroups)) ||
         !ReadParam(aMsg, aIter, &(aResult->mGroupMask)) ||
         !ReadParam(aMsg, aIter, &(aResult->mFrameId)) ||
-        !ReadParam(aMsg, aIter, &(aResult->mPresentingGeneration)) ||
         !ReadParam(aMsg, aIter, &(aResult->mDisplayState))) {
       return false;
     }
     for (int i = 0; i < mozilla::gfx::kVRMaxLatencyFrames; i++) {
       if (!ReadParam(aMsg, aIter, &(aResult->mLastSensorState[i]))) {
         return false;
       }
     }
deleted file mode 100644
--- a/gfx/vr/jni/gfxGVRJNI.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include <jni.h>
-
-extern "C" __attribute__((visibility("default"))) jlong
-Java_com_google_vr_cardboard_DisplaySynchronizer_nativeCreate(
-    JNIEnv* env,
-    jobject jcaller,
-    jclass classLoader,
-    jobject appContext);
-
-// Step 2: method stubs.
-extern "C" __attribute__((visibility("default"))) void
-Java_com_google_vr_cardboard_DisplaySynchronizer_nativeDestroy(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeDisplaySynchronizer);
-
-extern "C" __attribute__((visibility("default"))) void
-Java_com_google_vr_cardboard_DisplaySynchronizer_nativeReset(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeDisplaySynchronizer,
-    jlong expectedInterval,
-    jlong vsyncOffset);
-
-extern "C" __attribute__((visibility("default"))) void
-Java_com_google_vr_cardboard_DisplaySynchronizer_nativeUpdate(
-    JNIEnv* env,
-    jobject jcaller,
-    jlong nativeDisplaySynchronizer,
-    jlong syncTime,
-    jint currentRotation);
-
-namespace {
-
-bool
-check(JNIEnv* env) {
-  if (env->ExceptionCheck()) {
-    env->ExceptionDescribe();
-    env->ExceptionClear();
-    return false;
-  }
-  return true;
-}
-
-const char kDisplaySynchronizerClassPath[] = "com/google/vr/cardboard/DisplaySynchronizer";
-
-static const JNINativeMethod kMethodsDisplaySynchronizer[] = {
-    {"nativeCreate",
-     "("
-     "Ljava/lang/ClassLoader;"
-     "Landroid/content/Context;"
-     ")"
-     "J",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_cardboard_DisplaySynchronizer_nativeCreate)},
-    {"nativeDestroy",
-     "("
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_cardboard_DisplaySynchronizer_nativeDestroy)},
-    {"nativeReset",
-     "("
-     "J"
-     "J"
-     "J"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_cardboard_DisplaySynchronizer_nativeReset)},
-    {"nativeUpdate",
-     "("
-     "J"
-     "J"
-     "I"
-     ")"
-     "V",
-     reinterpret_cast<void*>(
-         Java_com_google_vr_cardboard_DisplaySynchronizer_nativeUpdate)},
-};
-}
-
-bool
-SetupGVRJNI(JNIEnv* env)
-{
-  jclass displaySynchronizerClazz = env->FindClass(kDisplaySynchronizerClassPath);
-  if (!check(env)) { return false; }
-  if (displaySynchronizerClazz == nullptr) {
-    return false;
-  }
-  env->RegisterNatives(displaySynchronizerClazz, kMethodsDisplaySynchronizer, sizeof(kMethodsDisplaySynchronizer) / sizeof(kMethodsDisplaySynchronizer[0]));
-  if (!check(env)) { return false; }
-  env->DeleteLocalRef(displaySynchronizerClazz);
-  if (!check(env)) { return false; }
-
-  return true;
-}
-
--- a/gfx/vr/moz.build
+++ b/gfx/vr/moz.build
@@ -20,27 +20,31 @@ EXPORTS += [
 LOCAL_INCLUDES += [
     '/dom/base',
     '/gfx/layers/d3d11',
     '/gfx/thebes',
 ]
 
 UNIFIED_SOURCES += [
     'gfxVR.cpp',
-    'gfxVROSVR.cpp',
     'ipc/VRLayerChild.cpp',
     'ipc/VRLayerParent.cpp',
     'ipc/VRManagerChild.cpp',
     'ipc/VRManagerParent.cpp',
     'VRDisplayClient.cpp',
     'VRDisplayPresentation.cpp',
     'VRManager.cpp',
     'VRThread.cpp',
 ]
 
+if CONFIG['OS_TARGET'] != 'Android':
+    UNIFIED_SOURCES += [
+        'gfxVROSVR.cpp',
+    ]
+
 # VRDisplayHost includes MacIOSurface.h which includes Mac headers
 # which define Size and Points types in the root namespace that
 # often conflict with our own types.
 SOURCES += [
     'gfxVRExternal.cpp',
     'gfxVRPuppet.cpp',
     'VRDisplayHost.cpp',
 ]
@@ -54,22 +58,17 @@ if CONFIG['OS_TARGET'] in ('WINNT', 'Lin
         'gfxVROpenVR.cpp',
     ]
 
 if CONFIG['OS_TARGET'] == 'WINNT':
     SOURCES += [
         'gfxVROculus.cpp',
     ]
 
-if CONFIG['MOZ_ANDROID_GOOGLE_VR']:
-    SOURCES += [
-        'gfxVRGVR.cpp',
-        'jni/gfxGVRJNI.cpp',
-    ]
-    CXXFLAGS += ['-I%s' % CONFIG['MOZ_ANDROID_GOOGLE_VR_INCLUDE']]
+if CONFIG['OS_TARGET'] == 'Android':
     LOCAL_INCLUDES += ['/widget/android']
 
 IPDL_SOURCES = [
     'ipc/PVRLayer.ipdl',
     'ipc/PVRManager.ipdl',
 ]
 
 # For building with the real SDK instead of our local hack
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoVRManager.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoVRManager.java
@@ -5,121 +5,20 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko;
 
 import org.mozilla.gecko.annotation.WrapForJNI;
 import org.mozilla.gecko.util.ThreadUtils;
 
 public class GeckoVRManager {
-    /**
-     * GeckoView applications implement this interface to provide GVR support for WebVR.
-     */
-    public interface GVRDelegate {
-        /**
-         * Creates non-presenting context. Will be invoked in the compositor thread.
-         */
-        long createNonPresentingContext();
-        /**
-         * Destroys non-presenting context. Will be invoked in the compositor thread.
-         */
-        void destroyNonPresentingContext();
-        /**
-         * Called when WebVR needs a presenting context. Will be invoked in the UI thread.
-         */
-        boolean enableVRMode();
-        /**
-         * Called when WebVR has finished presenting. Will be invoked in the UI thread.
-         */
-        void disableVRMode();
-    }
-
-    private static GVRDelegate mGVRDelegate;
-
-    /**
-     * Set the GVR Delegate for GeckoView.
-     * @param delegate GVRDelegate instance or null to unset.
-     */
-    public static void setGVRDelegate(GVRDelegate delegate) {
-        mGVRDelegate = delegate;
-    }
-
-    /**
-     * Set the GVR paused state.
-     * @param aPaused True if the application is being paused, False if the
-     * application is resuming.
-     */
-    @WrapForJNI(calledFrom = "ui")
-    public static native void setGVRPaused(final boolean aPaused);
-
-    /**
-     * Set the GVR presenting context.
-     * @param aContext GVR context to use when WebVR starts to present. Pass in
-     * zero to stop presenting.
-     */
-    @WrapForJNI(calledFrom = "ui")
-    public static native void setGVRPresentingContext(final long aContext);
-
-    /**
-     * Inform WebVR that the non-presenting context needs to be destroyed.
-     */
-    @WrapForJNI(calledFrom = "ui")
-    public static native void cleanupGVRNonPresentingContext();
+    private static long mExternalContext;
 
     @WrapForJNI
-    /* package */ static boolean isGVRPresent() {
-        return mGVRDelegate != null;
-    }
-
-    @WrapForJNI
-    /* package */ static long createGVRNonPresentingContext() {
-        if (mGVRDelegate == null) {
-            return 0;
-        }
-        return mGVRDelegate.createNonPresentingContext();
-    }
-
-    @WrapForJNI
-    /* package */ static void destroyGVRNonPresentingContext() {
-        if (mGVRDelegate == null) {
-            return;
-        }
-        mGVRDelegate.destroyNonPresentingContext();
+    public static synchronized long getExternalContext() {
+      return mExternalContext;
     }
 
-    @WrapForJNI
-    /* package */ static void enableVRMode() {
-        if (!ThreadUtils.isOnUiThread()) {
-            ThreadUtils.postToUiThread(new Runnable() {
-                @Override
-                public void run() {
-                    enableVRMode();
-                }
-            });
-            return;
-        }
-
-        if (mGVRDelegate == null) {
-            return;
-        }
-
-        mGVRDelegate.enableVRMode();
+    public static synchronized void setExternalContext(final long externalContext) {
+        mExternalContext = externalContext;
     }
 
-    @WrapForJNI
-    /* package */ static void disableVRMode() {
-        if (!ThreadUtils.isOnUiThread()) {
-            ThreadUtils.postToUiThread(new Runnable() {
-                @Override
-                public void run() {
-                    disableVRMode();
-                }
-            });
-            return;
-        }
-
-        if (mGVRDelegate == null) {
-            return;
-        }
-
-        mGVRDelegate.disableVRMode();
-    }
 }
--- a/widget/android/GeckoVRManager.h
+++ b/widget/android/GeckoVRManager.h
@@ -4,79 +4,21 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_GeckoVRManager_h_
 #define mozilla_GeckoVRManager_h_
 
 #include "GeneratedJNINatives.h"
 #include "mozilla/jni/Utils.h"
 
-#if defined(MOZ_ANDROID_GOOGLE_VR)
-#include "gfxVRGVRAPI.h"
-extern bool SetupGVRJNI(JNIEnv* env);
-#endif // defined(MOZ_ANDROID_GOOGLE_VR)
-
 namespace mozilla {
 
 class GeckoVRManager
-    : public mozilla::java::GeckoVRManager::Natives<mozilla::GeckoVRManager>
 {
-  typedef mozilla::java::GeckoVRManager::Natives<mozilla::GeckoVRManager> Super;
 public:
-  static void Init()
-  {
-    Super::Init();
-#if defined(MOZ_ANDROID_GOOGLE_VR)
-    SetupGVRJNI(jni::GetGeckoThreadEnv());
-#endif // defined(MOZ_ANDROID_GOOGLE_VR)
-  }
-
-  static void SetGVRPresentingContext(const int64_t aContext)
-  {
-#if defined(MOZ_ANDROID_GOOGLE_VR)
-    mozilla::gfx::SetGVRPresentingContext((void*)aContext);
-#endif // defined(MOZ_ANDROID_GOOGLE_VR)
-  }
-
-  static void CleanupGVRNonPresentingContext()
-  {
-#if defined(MOZ_ANDROID_GOOGLE_VR)
-    mozilla::gfx::CleanupGVRNonPresentingContext();
-#endif // defined(MOZ_ANDROID_GOOGLE_VR)
+  static void* GetExternalContext() {
+    return reinterpret_cast<void*>(mozilla::java::GeckoVRManager::GetExternalContext());
   }
-
-  static void SetGVRPaused(const bool aPaused)
-  {
-#if defined(MOZ_ANDROID_GOOGLE_VR)
-    mozilla::gfx::SetGVRPaused(aPaused);
-#endif // defined(MOZ_ANDROID_GOOGLE_VR)
-  }
-
-  static void* CreateGVRNonPresentingContext()
-  {
-    return (void*)mozilla::java::GeckoVRManager::CreateGVRNonPresentingContext();
-  }
-
-  static void DestroyGVRNonPresentingContext()
-  {
-    mozilla::java::GeckoVRManager::DestroyGVRNonPresentingContext();
-  }
-
-  static void EnableVRMode()
-  {
-    mozilla::java::GeckoVRManager::EnableVRMode();
-  }
-
-  static void DisableVRMode()
-  {
-    mozilla::java::GeckoVRManager::DisableVRMode();
-  }
-
-  static bool IsGVRPresent()
-  {
-    return mozilla::java::GeckoVRManager::IsGVRPresent();
-  }
-
 };
 
 } // namespace mozilla
 
 #endif // mozilla_GeckoVRManager_h_
--- a/widget/android/nsAppShell.cpp
+++ b/widget/android/nsAppShell.cpp
@@ -420,17 +420,16 @@ nsAppShell::nsAppShell()
         AndroidBridge::ConstructBridge();
         GeckoAppShellSupport::Init();
         GeckoThreadSupport::Init();
         mozilla::GeckoBatteryManager::Init();
         mozilla::GeckoNetworkManager::Init();
         mozilla::GeckoProcessManager::Init();
         mozilla::GeckoScreenOrientation::Init();
         mozilla::PrefsHelper::Init();
-        mozilla::GeckoVRManager::Init();
         nsWindow::InitNatives();
 
         if (jni::IsFennec()) {
             BrowserLocaleManagerSupport::Init();
             mozilla::ANRReporter::Init();
             mozilla::MemoryMonitor::Init();
             mozilla::widget::Telemetry::Init();
             mozilla::ThumbnailHelper::Init();