Bug 1148009; [webvr] Move gfx vr code to gfx/vr; r=jrmuizel
authorVladimir Vukicevic <vladimir@pobox.com>
Wed, 01 Apr 2015 16:02:20 -0400
changeset 237091 d9063bc41c68403f1775068f535fe568e1b8c0cc
parent 237090 345dda450c52f8ad41ba84461b2e257b99aa830f
child 237092 250695bd9883399ded1180bfdb4ec88b571d7435
push idunknown
push userunknown
push dateunknown
reviewersjrmuizel
bugs1148009
milestone40.0a1
Bug 1148009; [webvr] Move gfx vr code to gfx/vr; r=jrmuizel
gfx/moz.build
gfx/thebes/gfxVR.cpp
gfx/thebes/gfxVR.h
gfx/thebes/moz.build
gfx/thebes/ovr_capi_dynamic.h
gfx/vr/gfxVR.cpp
gfx/vr/gfxVR.h
gfx/vr/moz.build
gfx/vr/ovr_capi_dynamic.h
--- a/gfx/moz.build
+++ b/gfx/moz.build
@@ -18,16 +18,17 @@ DIRS += [
     'qcms',
     'gl',
     'layers',
     'graphite2/src',
     'harfbuzz/src',
     'ots/src',
     'thebes',
     'ipc',
+    'vr',
 ]
 
 if CONFIG['MOZ_ENABLE_SKIA']:
     DIRS += ['skia']
 
 if CONFIG['ENABLE_TESTS']:
     DIRS += ['tests/gtest']
 
deleted file mode 100644
--- a/gfx/thebes/gfxVR.cpp
+++ /dev/null
@@ -1,658 +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 <math.h>
-
-#include "prlink.h"
-#include "prmem.h"
-#include "prenv.h"
-#include "gfxPrefs.h"
-#include "gfxVR.h"
-#include "nsString.h"
-#include "mozilla/Preferences.h"
-
-#include "ovr_capi_dynamic.h"
-
-#include "nsServiceManagerUtils.h"
-#include "nsIScreenManager.h"
-
-#ifdef XP_WIN
-#include "gfxWindowsPlatform.h" // for gfxWindowsPlatform::GetDPIScale
-#endif
-
-#ifndef M_PI
-# define M_PI 3.14159265358979323846
-#endif
-
-namespace {
-
-#ifdef OVR_CAPI_LIMITED_MOZILLA
-static pfn_ovr_Initialize ovr_Initialize = nullptr;
-static pfn_ovr_Shutdown ovr_Shutdown = nullptr;
-static pfn_ovrHmd_Detect ovrHmd_Detect = nullptr;
-static pfn_ovrHmd_Create ovrHmd_Create = nullptr;
-static pfn_ovrHmd_Destroy ovrHmd_Destroy = nullptr;
-static pfn_ovrHmd_CreateDebug ovrHmd_CreateDebug = nullptr;
-static pfn_ovrHmd_GetLastError ovrHmd_GetLastError = nullptr;
-static pfn_ovrHmd_AttachToWindow ovrHmd_AttachToWindow = nullptr;
-static pfn_ovrHmd_GetEnabledCaps ovrHmd_GetEnabledCaps = nullptr;
-static pfn_ovrHmd_SetEnabledCaps ovrHmd_SetEnabledCaps = nullptr;
-static pfn_ovrHmd_ConfigureTracking ovrHmd_ConfigureTracking = nullptr;
-static pfn_ovrHmd_RecenterPose ovrHmd_RecenterPose = nullptr;
-static pfn_ovrHmd_GetTrackingState ovrHmd_GetTrackingState = nullptr;
-static pfn_ovrHmd_GetFovTextureSize ovrHmd_GetFovTextureSize = nullptr;
-static pfn_ovrHmd_GetRenderDesc ovrHmd_GetRenderDesc = nullptr;
-static pfn_ovrHmd_CreateDistortionMesh ovrHmd_CreateDistortionMesh = nullptr;
-static pfn_ovrHmd_DestroyDistortionMesh ovrHmd_DestroyDistortionMesh = nullptr;
-static pfn_ovrHmd_GetRenderScaleAndOffset ovrHmd_GetRenderScaleAndOffset = nullptr;
-static pfn_ovrHmd_GetFrameTiming ovrHmd_GetFrameTiming = nullptr;
-static pfn_ovrHmd_BeginFrameTiming ovrHmd_BeginFrameTiming = nullptr;
-static pfn_ovrHmd_EndFrameTiming ovrHmd_EndFrameTiming = nullptr;
-static pfn_ovrHmd_ResetFrameTiming ovrHmd_ResetFrameTiming = nullptr;
-static pfn_ovrHmd_GetEyePoses ovrHmd_GetEyePoses = nullptr;
-static pfn_ovrHmd_GetHmdPosePerEye ovrHmd_GetHmdPosePerEye = nullptr;
-static pfn_ovrHmd_GetEyeTimewarpMatrices ovrHmd_GetEyeTimewarpMatrices = nullptr;
-static pfn_ovrMatrix4f_Projection ovrMatrix4f_Projection = nullptr;
-static pfn_ovrMatrix4f_OrthoSubProjection ovrMatrix4f_OrthoSubProjection = nullptr;
-static pfn_ovr_GetTimeInSeconds ovr_GetTimeInSeconds = nullptr;
-
-#if defined(XP_WIN)
-# ifdef HAVE_64BIT_BUILD
-#  define OVR_LIB_NAME "libovr64.dll"
-# else
-#  define OVR_LIB_NAME "libovr.dll"
-# endif
-#elif defined(XP_MACOSX)
-# define OVR_LIB_NAME "libovr.dylib"
-#else
-# define OVR_LIB_NAME 0
-#endif
-
-static bool
-InitializeOculusCAPI()
-{
-  static PRLibrary *ovrlib = nullptr;
-
-  if (!ovrlib) {
-    const char *libName = OVR_LIB_NAME;
-
-    // If the pref is present, we override libName
-    nsAdoptingCString prefLibName = mozilla::Preferences::GetCString("dom.vr.ovr_lib_path");
-    if (prefLibName && prefLibName.get()) {
-      libName = prefLibName.get();
-    }
-
-    // If the env var is present, we override libName
-    if (PR_GetEnv("OVR_LIB_NAME")) {
-      libName = PR_GetEnv("OVR_LIB_NAME");
-    }
-
-    if (!libName) {
-      printf_stderr("Don't know how to find Oculus VR library; missing dom.vr.ovr_lib_path or OVR_LIB_NAME\n");
-      return false;
-    }
-
-    ovrlib = PR_LoadLibrary(libName);
-
-    if (!ovrlib) {
-      // Not found? Try harder. Needed mainly on OSX/etc. where
-      // the binary location is not in the search path.
-      const char *xulName = "libxul.so";
-#if defined(XP_MACOSX)
-      xulName = "XUL";
-#endif
-
-      char *xulpath = PR_GetLibraryFilePathname(xulName, (PRFuncPtr) &InitializeOculusCAPI);
-      if (xulpath) {
-        char *xuldir = strrchr(xulpath, '/');
-        if (xuldir) {
-          *xuldir = 0;
-          xuldir = xulpath;
-
-          char *ovrpath = PR_GetLibraryName(xuldir, libName);
-          ovrlib = PR_LoadLibrary(ovrpath);
-          PR_Free(ovrpath);
-        }
-        PR_Free(xulpath);
-      }
-    }
-
-    if (!ovrlib) {
-      printf_stderr("Failed to load Oculus VR library, tried '%s'\n", libName);
-      return false;
-    }
-  }
-
-  // was it already initialized?
-  if (ovr_Initialize)
-    return true;
-
-#define REQUIRE_FUNCTION(_x) do { \
-    *(void **)&_x = (void *) PR_FindSymbol(ovrlib, #_x);                \
-    if (!_x) { printf_stderr(#_x " symbol missing\n"); goto fail; }       \
-  } while (0)
-
-  REQUIRE_FUNCTION(ovr_Initialize);
-  REQUIRE_FUNCTION(ovr_Shutdown);
-  REQUIRE_FUNCTION(ovrHmd_Detect);
-  REQUIRE_FUNCTION(ovrHmd_Create);
-  REQUIRE_FUNCTION(ovrHmd_Destroy);
-  REQUIRE_FUNCTION(ovrHmd_CreateDebug);
-  REQUIRE_FUNCTION(ovrHmd_GetLastError);
-  REQUIRE_FUNCTION(ovrHmd_AttachToWindow);
-  REQUIRE_FUNCTION(ovrHmd_GetEnabledCaps);
-  REQUIRE_FUNCTION(ovrHmd_SetEnabledCaps);
-  REQUIRE_FUNCTION(ovrHmd_ConfigureTracking);
-  REQUIRE_FUNCTION(ovrHmd_RecenterPose);
-  REQUIRE_FUNCTION(ovrHmd_GetTrackingState);
-
-  REQUIRE_FUNCTION(ovrHmd_GetFovTextureSize);
-  REQUIRE_FUNCTION(ovrHmd_GetRenderDesc);
-  REQUIRE_FUNCTION(ovrHmd_CreateDistortionMesh);
-  REQUIRE_FUNCTION(ovrHmd_DestroyDistortionMesh);
-  REQUIRE_FUNCTION(ovrHmd_GetRenderScaleAndOffset);
-  REQUIRE_FUNCTION(ovrHmd_GetFrameTiming);
-  REQUIRE_FUNCTION(ovrHmd_BeginFrameTiming);
-  REQUIRE_FUNCTION(ovrHmd_EndFrameTiming);
-  REQUIRE_FUNCTION(ovrHmd_ResetFrameTiming);
-  REQUIRE_FUNCTION(ovrHmd_GetEyePoses);
-  REQUIRE_FUNCTION(ovrHmd_GetHmdPosePerEye);
-  REQUIRE_FUNCTION(ovrHmd_GetEyeTimewarpMatrices);
-  REQUIRE_FUNCTION(ovrMatrix4f_Projection);
-  REQUIRE_FUNCTION(ovrMatrix4f_OrthoSubProjection);
-  REQUIRE_FUNCTION(ovr_GetTimeInSeconds);
-
-#undef REQUIRE_FUNCTION
-
-  return true;
-
- fail:
-  ovr_Initialize = nullptr;
-  return false;
-}
-
-#else
-// we're statically linked; it's available
-static bool InitializeOculusCAPI()
-{
-  return true;
-}
-#endif
-
-} // anonymous namespace
-
-using namespace mozilla::gfx;
-
-// Dummy nsIScreen implementation, for when we just need to specify a size
-class FakeScreen : public nsIScreen
-{
-public:
-  explicit FakeScreen(const IntRect& aScreenRect)
-    : mScreenRect(aScreenRect)
-  { }
-
-  NS_DECL_ISUPPORTS
-
-  NS_IMETHOD GetRect(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override {
-    *l = mScreenRect.x;
-    *t = mScreenRect.y;
-    *w = mScreenRect.width;
-    *h = mScreenRect.height;
-    return NS_OK;
-  }
-  NS_IMETHOD GetAvailRect(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override {
-    return GetRect(l, t, w, h);
-  }
-  NS_IMETHOD GetRectDisplayPix(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override {
-    return GetRect(l, t, w, h);
-  }
-  NS_IMETHOD GetAvailRectDisplayPix(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override {
-    return GetAvailRect(l, t, w, h);
-  }
-
-  NS_IMETHOD GetId(uint32_t* aId) override { *aId = (uint32_t)-1; return NS_OK; }
-  NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth) override { *aPixelDepth = 24; return NS_OK; }
-  NS_IMETHOD GetColorDepth(int32_t* aColorDepth) override { *aColorDepth = 24; return NS_OK; }
-
-  NS_IMETHOD LockMinimumBrightness(uint32_t aBrightness) override { return NS_ERROR_NOT_AVAILABLE; }
-  NS_IMETHOD UnlockMinimumBrightness(uint32_t aBrightness) override { return NS_ERROR_NOT_AVAILABLE; }
-  NS_IMETHOD GetRotation(uint32_t* aRotation) override {
-    *aRotation = nsIScreen::ROTATION_0_DEG;
-    return NS_OK;
-  }
-  NS_IMETHOD SetRotation(uint32_t aRotation) override { return NS_ERROR_NOT_AVAILABLE; }
-  NS_IMETHOD GetContentsScaleFactor(double* aContentsScaleFactor) override {
-    *aContentsScaleFactor = 1.0;
-    return NS_OK;
-  }
-
-protected:
-  virtual ~FakeScreen() {}
-
-  IntRect mScreenRect;
-};
-
-NS_IMPL_ISUPPORTS(FakeScreen, nsIScreen)
-
-class HMDInfoOculus : public VRHMDInfo {
-  friend class VRHMDManagerOculusImpl;
-public:
-  explicit HMDInfoOculus(ovrHmd aHMD);
-
-  bool SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight,
-              double zNear, double zFar) override;
-
-  bool StartSensorTracking() override;
-  VRHMDSensorState GetSensorState(double timeOffset) override;
-  void StopSensorTracking() override;
-  void ZeroSensor() override;
-
-  void FillDistortionConstants(uint32_t whichEye,
-                               const IntSize& textureSize, const IntRect& eyeViewport,
-                               const Size& destViewport, const Rect& destRect,
-                               VRDistortionConstants& values) override;
-
-  void Destroy();
-
-protected:
-  virtual ~HMDInfoOculus() {
-      Destroy();
-      MOZ_COUNT_DTOR_INHERITED(HMDInfoOculus, VRHMDInfo);
-  }
-
-  ovrHmd mHMD;
-  ovrFovPort mFOVPort[2];
-  uint32_t mStartCount;
-};
-
-static ovrFovPort
-ToFovPort(const VRFieldOfView& aFOV)
-{
-  ovrFovPort fovPort;
-  fovPort.LeftTan = tan(aFOV.leftDegrees * M_PI / 180.0);
-  fovPort.RightTan = tan(aFOV.rightDegrees * M_PI / 180.0);
-  fovPort.UpTan = tan(aFOV.upDegrees * M_PI / 180.0);
-  fovPort.DownTan = tan(aFOV.downDegrees * M_PI / 180.0);
-  return fovPort;
-}
-
-static VRFieldOfView
-FromFovPort(const ovrFovPort& aFOV)
-{
-  VRFieldOfView fovInfo;
-  fovInfo.leftDegrees = atan(aFOV.LeftTan) * 180.0 / M_PI;
-  fovInfo.rightDegrees = atan(aFOV.RightTan) * 180.0 / M_PI;
-  fovInfo.upDegrees = atan(aFOV.UpTan) * 180.0 / M_PI;
-  fovInfo.downDegrees = atan(aFOV.DownTan) * 180.0 / M_PI;
-  return fovInfo;
-}
-
-HMDInfoOculus::HMDInfoOculus(ovrHmd aHMD)
-  : VRHMDInfo(VRHMDType::Oculus)
-  , mHMD(aHMD)
-  , mStartCount(0)
-{
-  MOZ_COUNT_CTOR_INHERITED(HMDInfoOculus, VRHMDInfo);
-
-  mSupportedSensorBits = 0;
-  if (mHMD->TrackingCaps & ovrTrackingCap_Orientation)
-    mSupportedSensorBits |= State_Orientation;
-  if (mHMD->TrackingCaps & ovrTrackingCap_Position)
-    mSupportedSensorBits |= State_Position;
-
-  mRecommendedEyeFOV[Eye_Left] = FromFovPort(mHMD->DefaultEyeFov[ovrEye_Left]);
-  mRecommendedEyeFOV[Eye_Right] = FromFovPort(mHMD->DefaultEyeFov[ovrEye_Right]);
-
-  mMaximumEyeFOV[Eye_Left] = FromFovPort(mHMD->MaxEyeFov[ovrEye_Left]);
-  mMaximumEyeFOV[Eye_Right] = FromFovPort(mHMD->MaxEyeFov[ovrEye_Right]);
-
-  SetFOV(mRecommendedEyeFOV[Eye_Left], mRecommendedEyeFOV[Eye_Right], 0.01, 10000.0);
-
-  nsCOMPtr<nsIScreenManager> screenmgr = do_GetService("@mozilla.org/gfx/screenmanager;1");
-  if (screenmgr) {
-    screenmgr->ScreenForRect(mHMD->WindowsPos.x, mHMD->WindowsPos.y,
-                             mHMD->Resolution.w, mHMD->Resolution.h,
-                             getter_AddRefs(mScreen));
-  }
-}
-
-void
-HMDInfoOculus::Destroy()
-{
-  if (mHMD) {
-    ovrHmd_Destroy(mHMD);
-    mHMD = nullptr;
-  }
-}
-
-bool
-HMDInfoOculus::SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight,
-                      double zNear, double zFar)
-{
-  float pixelsPerDisplayPixel = 1.0;
-  ovrSizei texSize[2];
-
-  uint32_t caps = ovrDistortionCap_Chromatic | ovrDistortionCap_Vignette; // XXX TODO add TimeWarp
-
-  // get eye parameters and create the mesh
-  for (uint32_t eye = 0; eye < NumEyes; eye++) {
-    mEyeFOV[eye] = eye == 0 ? aFOVLeft : aFOVRight;
-    mFOVPort[eye] = ToFovPort(mEyeFOV[eye]);
-
-    ovrEyeRenderDesc renderDesc = ovrHmd_GetRenderDesc(mHMD, (ovrEyeType) eye, mFOVPort[eye]);
-
-    // these values are negated so that content can add the adjustment to its camera position,
-    // instead of subtracting
-    mEyeTranslation[eye] = Point3D(-renderDesc.ViewAdjust.x, -renderDesc.ViewAdjust.y, -renderDesc.ViewAdjust.z);
-
-    // note that we are using a right-handed coordinate system here, to match CSS
-    ovrMatrix4f projMatrix = ovrMatrix4f_Projection(mFOVPort[eye], zNear, zFar, true);
-
-    // XXX this is gross, we really need better methods on Matrix4x4
-    memcpy(&mEyeProjectionMatrix[eye], projMatrix.M, sizeof(ovrMatrix4f));
-    mEyeProjectionMatrix[eye].Transpose();
-
-    texSize[eye] = ovrHmd_GetFovTextureSize(mHMD, (ovrEyeType) eye, mFOVPort[eye], pixelsPerDisplayPixel);
-
-    ovrDistortionMesh mesh;
-    bool ok = ovrHmd_CreateDistortionMesh(mHMD, (ovrEyeType) eye, mFOVPort[eye], caps, &mesh);
-    if (!ok)
-      return false;
-
-    mDistortionMesh[eye].mVertices.SetLength(mesh.VertexCount);
-    mDistortionMesh[eye].mIndices.SetLength(mesh.IndexCount);
-
-    ovrDistortionVertex *srcv = mesh.pVertexData;
-    VRDistortionVertex *destv = mDistortionMesh[eye].mVertices.Elements();
-    memset(destv, 0, mesh.VertexCount * sizeof(VRDistortionVertex));
-    for (uint32_t i = 0; i < mesh.VertexCount; ++i) {
-      destv[i].pos[0] = srcv[i].ScreenPosNDC.x;
-      destv[i].pos[1] = srcv[i].ScreenPosNDC.y;
-
-      destv[i].texR[0] = srcv[i].TanEyeAnglesR.x;
-      destv[i].texR[1] = srcv[i].TanEyeAnglesR.y;
-      destv[i].texG[0] = srcv[i].TanEyeAnglesG.x;
-      destv[i].texG[1] = srcv[i].TanEyeAnglesG.y;
-      destv[i].texB[0] = srcv[i].TanEyeAnglesB.x;
-      destv[i].texB[1] = srcv[i].TanEyeAnglesB.y;
-
-      destv[i].genericAttribs[0] = srcv[i].VignetteFactor;
-      destv[i].genericAttribs[1] = srcv[i].TimeWarpFactor;
-    }
-
-    memcpy(mDistortionMesh[eye].mIndices.Elements(), mesh.pIndexData, mesh.IndexCount * sizeof(uint16_t));
-    ovrHmd_DestroyDistortionMesh(&mesh);
-  }
-
-  // take the max of both for eye resolution
-  mEyeResolution.width = std::max(texSize[Eye_Left].w, texSize[Eye_Right].w);
-  mEyeResolution.height = std::max(texSize[Eye_Left].h, texSize[Eye_Right].h);
-
-  mConfiguration.hmdType = mType;
-  mConfiguration.value = 0;
-  mConfiguration.fov[0] = aFOVLeft;
-  mConfiguration.fov[1] = aFOVRight;
-
-  return true;
-  //* need to call this during rendering each frame I think? */
-  //ovrHmd_GetRenderScaleAndOffset(fovPort, texSize, renderViewport, uvScaleOffsetOut);
-}
-
-void
-HMDInfoOculus::FillDistortionConstants(uint32_t whichEye,
-                                       const IntSize& textureSize,
-                                       const IntRect& eyeViewport,
-                                       const Size& destViewport,
-                                       const Rect& destRect,
-                                       VRDistortionConstants& values)
-{
-  ovrSizei texSize = { textureSize.width, textureSize.height };
-  ovrRecti eyePort = { { eyeViewport.x, eyeViewport.y }, { eyeViewport.width, eyeViewport.height } };
-  ovrVector2f scaleOut[2];
-
-  ovrHmd_GetRenderScaleAndOffset(mFOVPort[whichEye], texSize, eyePort, scaleOut);
-
-  values.eyeToSourceScaleAndOffset[0] = scaleOut[0].x;
-  values.eyeToSourceScaleAndOffset[1] = scaleOut[0].y;
-  values.eyeToSourceScaleAndOffset[2] = scaleOut[1].x;
-  values.eyeToSourceScaleAndOffset[3] = scaleOut[1].y;
-
-  // These values are in clip space [-1..1] range, but we're providing
-  // scaling in the 0..2 space for sanity.
-
-  // this is the destRect in clip space
-  float x0 = destRect.x / destViewport.width * 2.0 - 1.0;
-  float x1 = (destRect.x + destRect.width) / destViewport.width * 2.0 - 1.0;
-
-  float y0 = destRect.y / destViewport.height * 2.0 - 1.0;
-  float y1 = (destRect.y + destRect.height) / destViewport.height * 2.0 - 1.0;
-
-  // offset
-  values.destinationScaleAndOffset[0] = (x0+x1) / 2.0;
-  values.destinationScaleAndOffset[1] = (y0+y1) / 2.0;
-  // scale
-  values.destinationScaleAndOffset[2] = destRect.width / destViewport.width;
-  values.destinationScaleAndOffset[3] = destRect.height / destViewport.height;
-}
-
-bool
-HMDInfoOculus::StartSensorTracking()
-{
-  if (mStartCount == 0) {
-    bool ok = ovrHmd_ConfigureTracking(mHMD, ovrTrackingCap_Orientation | ovrTrackingCap_Position, 0);
-    if (!ok)
-      return false;
-  }
-
-  mStartCount++;
-  return true;
-}
-
-void
-HMDInfoOculus::StopSensorTracking()
-{
-  if (--mStartCount == 0) {
-    ovrHmd_ConfigureTracking(mHMD, 0, 0);
-  }
-}
-
-void
-HMDInfoOculus::ZeroSensor()
-{
-  ovrHmd_RecenterPose(mHMD);
-}
-
-VRHMDSensorState
-HMDInfoOculus::GetSensorState(double timeOffset)
-{
-  VRHMDSensorState result;
-  result.Clear();
-
-  // XXX this is the wrong time base for timeOffset; we need to figure out how to synchronize
-  // the Oculus time base and the browser one.
-  ovrTrackingState state = ovrHmd_GetTrackingState(mHMD, ovr_GetTimeInSeconds() + timeOffset);
-  ovrPoseStatef& pose(state.HeadPose);
-
-  result.timestamp = pose.TimeInSeconds;
-
-  if (state.StatusFlags & ovrStatus_OrientationTracked) {
-    result.flags |= State_Orientation;
-
-    result.orientation[0] = pose.ThePose.Orientation.x;
-    result.orientation[1] = pose.ThePose.Orientation.y;
-    result.orientation[2] = pose.ThePose.Orientation.z;
-    result.orientation[3] = pose.ThePose.Orientation.w;
-    
-    result.angularVelocity[0] = pose.AngularVelocity.x;
-    result.angularVelocity[1] = pose.AngularVelocity.y;
-    result.angularVelocity[2] = pose.AngularVelocity.z;
-
-    result.angularAcceleration[0] = pose.AngularAcceleration.x;
-    result.angularAcceleration[1] = pose.AngularAcceleration.y;
-    result.angularAcceleration[2] = pose.AngularAcceleration.z;
-  }
-
-  if (state.StatusFlags & ovrStatus_PositionTracked) {
-    result.flags |= State_Position;
-
-    result.position[0] = pose.ThePose.Position.x;
-    result.position[1] = pose.ThePose.Position.y;
-    result.position[2] = pose.ThePose.Position.z;
-    
-    result.linearVelocity[0] = pose.LinearVelocity.x;
-    result.linearVelocity[1] = pose.LinearVelocity.y;
-    result.linearVelocity[2] = pose.LinearVelocity.z;
-
-    result.linearAcceleration[0] = pose.LinearAcceleration.x;
-    result.linearAcceleration[1] = pose.LinearAcceleration.y;
-    result.linearAcceleration[2] = pose.LinearAcceleration.z;
-  }
-
-  return result;
-}
-
-namespace mozilla {
-namespace gfx {
-
-class VRHMDManagerOculusImpl {
-public:
-  VRHMDManagerOculusImpl() : mOculusInitialized(false), mOculusPlatformInitialized(false)
-  { }
-
-  bool PlatformInit();
-  bool Init();
-  void Destroy();
-  void GetOculusHMDs(nsTArray<nsRefPtr<VRHMDInfo> >& aHMDResult);
-protected:
-  nsTArray<nsRefPtr<HMDInfoOculus>> mOculusHMDs;
-  bool mOculusInitialized;
-  bool mOculusPlatformInitialized;
-};
-
-} // namespace gfx
-} // namespace mozilla
-
-VRHMDManagerOculusImpl *VRHMDManagerOculus::mImpl = nullptr;
-
-// These just forward to the Impl class, to have a non-static container for various
-// objects.
-
-bool
-VRHMDManagerOculus::PlatformInit()
-{
-  if (!mImpl) {
-    mImpl = new VRHMDManagerOculusImpl;
-  }
-  return mImpl->PlatformInit();
-}
-
-bool
-VRHMDManagerOculus::Init()
-{
-  if (!mImpl) {
-    mImpl = new VRHMDManagerOculusImpl;
-  }
-  return mImpl->Init();
-}
-
-void
-VRHMDManagerOculus::GetOculusHMDs(nsTArray<nsRefPtr<VRHMDInfo>>& aHMDResult)
-{
-  if (!mImpl) {
-    mImpl = new VRHMDManagerOculusImpl;
-  }
-  mImpl->GetOculusHMDs(aHMDResult);
-}
-
-void
-VRHMDManagerOculus::Destroy()
-{
-  if (!mImpl)
-    return;
-  mImpl->Destroy();
-  delete mImpl;
-  mImpl = nullptr;
-}
-
-bool
-VRHMDManagerOculusImpl::PlatformInit()
-{
-  if (mOculusPlatformInitialized)
-    return true;
-
-  if (!gfxPrefs::VREnabled())
-    return false;
-
-  if (!InitializeOculusCAPI())
-    return false;
-
-  bool ok = ovr_Initialize();
-
-  if (!ok)
-    return false;
-
-  mOculusPlatformInitialized = true;
-  return true;
-}
-
-bool
-VRHMDManagerOculusImpl::Init()
-{
-  if (mOculusInitialized)
-    return true;
-
-  if (!PlatformInit())
-    return false;
-
-  int count = ovrHmd_Detect();
-
-  for (int i = 0; i < count; ++i) {
-    ovrHmd hmd = ovrHmd_Create(i);
-    if (!hmd)
-      continue;
-    nsRefPtr<HMDInfoOculus> oc = new HMDInfoOculus(hmd);
-    mOculusHMDs.AppendElement(oc);
-  }
-
-  // VRAddTestDevices == 1: add test device only if no real devices present
-  // VRAddTestDevices == 2: add test device always
-  if ((count == 0 && gfxPrefs::VRAddTestDevices() == 1) ||
-      (gfxPrefs::VRAddTestDevices() == 2))
-  {
-    ovrHmd hmd = ovrHmd_CreateDebug(ovrHmd_DK2);
-    if (hmd) {
-      nsRefPtr<HMDInfoOculus> oc = new HMDInfoOculus(hmd);
-      mOculusHMDs.AppendElement(oc);
-    }
-  }
-
-  mOculusInitialized = true;
-  return true;
-}
-
-void
-VRHMDManagerOculusImpl::Destroy()
-{
-  if (!mOculusInitialized)
-    return;
-
-  for (size_t i = 0; i < mOculusHMDs.Length(); ++i) {
-    mOculusHMDs[i]->Destroy();
-  }
-
-  mOculusHMDs.Clear();
-
-  ovr_Shutdown();
-  mOculusInitialized = false;
-}
-
-void
-VRHMDManagerOculusImpl::GetOculusHMDs(nsTArray<nsRefPtr<VRHMDInfo>>& aHMDResult)
-{
-  Init();
-  for (size_t i = 0; i < mOculusHMDs.Length(); ++i) {
-    aHMDResult.AppendElement(mOculusHMDs[i]);
-  }
-}
deleted file mode 100644
--- a/gfx/thebes/gfxVR.h
+++ /dev/null
@@ -1,217 +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/. */
-
-#ifndef GFX_VR_H
-#define GFX_VR_H
-
-#include "nsTArray.h"
-#include "nsIScreen.h"
-#include "nsCOMPtr.h"
-#include "nsRefPtr.h"
-
-#include "mozilla/gfx/2D.h"
-#include "mozilla/EnumeratedArray.h"
-
-namespace mozilla {
-namespace gfx {
-
-enum class VRHMDType : uint16_t {
-  Oculus,
-  NumHMDTypes
-};
-
-struct VRFieldOfView {
-  static VRFieldOfView FromCSSPerspectiveInfo(double aPerspectiveDistance,
-                                              const Point& aPerspectiveOrigin,
-                                              const Point& aTransformOrigin,
-                                              const Rect& aContentRectangle)
-  {
-    /**/
-    return VRFieldOfView();
-  }
-
-  VRFieldOfView() {}
-  VRFieldOfView(double up, double right, double down, double left)
-    : upDegrees(up), rightDegrees(right), downDegrees(down), leftDegrees(left)
-  {}
-
-  bool operator==(const VRFieldOfView& other) const {
-    return other.upDegrees == upDegrees &&
-           other.downDegrees == downDegrees &&
-           other.rightDegrees == rightDegrees &&
-           other.leftDegrees == leftDegrees;
-  }
-
-  bool operator!=(const VRFieldOfView& other) const {
-    return !(*this == other);
-  }
-
-  bool IsZero() const {
-    return upDegrees == 0.0 ||
-      rightDegrees == 0.0 ||
-      downDegrees == 0.0 ||
-      leftDegrees == 0.0;
-  }
-
-  double upDegrees;
-  double rightDegrees;
-  double downDegrees;
-  double leftDegrees;
-};
-
-// 12 floats per vertex. Position, tex coordinates
-// for each channel, and 4 generic attributes
-struct VRDistortionConstants {
-  float eyeToSourceScaleAndOffset[4];
-  float destinationScaleAndOffset[4];
-};
-
-struct VRDistortionVertex {
-  float pos[2];
-  float texR[2];
-  float texG[2];
-  float texB[2];
-  float genericAttribs[4];
-};
-
-struct VRDistortionMesh {
-  nsTArray<VRDistortionVertex> mVertices;
-  nsTArray<uint16_t> mIndices;
-};
-
-struct VRHMDSensorState {
-  double timestamp;
-  uint32_t flags;
-  float orientation[4];
-  float position[3];
-  float angularVelocity[3];
-  float angularAcceleration[3];
-  float linearVelocity[3];
-  float linearAcceleration[3];
-
-  void Clear() {
-    memset(this, 0, sizeof(VRHMDSensorState));
-  }
-};
-
-/* A pure data struct that can be used to see if
- * the configuration of one HMDInfo matches another; for rendering purposes,
- * really asking "can the rendering details of this one be used for the other"
- */
-struct VRHMDConfiguration {
-  VRHMDConfiguration() : hmdType(VRHMDType::NumHMDTypes) {}
-
-  bool operator==(const VRHMDConfiguration& other) const {
-    return hmdType == other.hmdType &&
-      value == other.value &&
-      fov[0] == other.fov[0] &&
-      fov[1] == other.fov[1];
-  }
-
-  bool operator!=(const VRHMDConfiguration& other) const {
-    return hmdType != other.hmdType ||
-      value != other.value ||
-      fov[0] != other.fov[0] ||
-      fov[1] != other.fov[1];
-  }
-
-  bool IsValid() const {
-    return hmdType != VRHMDType::NumHMDTypes;
-  }
-
-  VRHMDType hmdType;
-  uint32_t value;
-  VRFieldOfView fov[2];
-};
-
-class VRHMDInfo {
-public:
-  enum Eye {
-    Eye_Left,
-    Eye_Right,
-    NumEyes
-  };
-
-  enum StateValidFlags {
-    State_Position = 1 << 1,
-    State_Orientation = 1 << 2
-  };
-
-public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VRHMDInfo)
-
-  VRHMDType GetType() const { return mType; }
-
-  virtual const VRFieldOfView& GetRecommendedEyeFOV(uint32_t whichEye) { return mRecommendedEyeFOV[whichEye]; }
-  virtual const VRFieldOfView& GetMaximumEyeFOV(uint32_t whichEye) { return mMaximumEyeFOV[whichEye]; }
-
-  const VRHMDConfiguration& GetConfiguration() const { return mConfiguration; }
-
-  /* set the FOV for this HMD unit; this triggers a computation of all the remaining bits.  Returns false if it fails */
-  virtual bool SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight,
-                      double zNear, double zFar) = 0;
-  const VRFieldOfView& GetEyeFOV(uint32_t whichEye)  { return mEyeFOV[whichEye]; }
-
-  /* Suggested resolution for rendering a single eye.
-   * Assumption is that left/right rendering will be 2x of this size.
-   * XXX fix this for vertical displays
-   */
-  const IntSize& SuggestedEyeResolution() const { return mEyeResolution; }
-  const Point3D& GetEyeTranslation(uint32_t whichEye) const { return mEyeTranslation[whichEye]; }
-  const Matrix4x4& GetEyeProjectionMatrix(uint32_t whichEye) const { return mEyeProjectionMatrix[whichEye]; }
-
-  virtual uint32_t GetSupportedSensorStateBits() { return mSupportedSensorBits; }
-  virtual bool StartSensorTracking() = 0;
-  virtual VRHMDSensorState GetSensorState(double timeOffset = 0.0) = 0;
-  virtual void StopSensorTracking() = 0;
-
-  virtual void ZeroSensor() = 0;
-
-  virtual void FillDistortionConstants(uint32_t whichEye,
-                                       const IntSize& textureSize, // the full size of the texture
-                                       const IntRect& eyeViewport, // the viewport within the texture for the current eye
-                                       const Size& destViewport,   // the size of the destination viewport
-                                       const Rect& destRect,       // the rectangle within the dest viewport that this should be rendered
-                                       VRDistortionConstants& values) = 0;
-
-  virtual const VRDistortionMesh& GetDistortionMesh(uint32_t whichEye) const { return mDistortionMesh[whichEye]; }
-
-  // The nsIScreen that represents this device
-  virtual nsIScreen* GetScreen() { return mScreen; }
-
-protected:
-  explicit VRHMDInfo(VRHMDType aType) : mType(aType) { MOZ_COUNT_CTOR(VRHMDInfo); }
-  virtual ~VRHMDInfo() { MOZ_COUNT_DTOR(VRHMDInfo); }
-
-  VRHMDType mType;
-  VRHMDConfiguration mConfiguration;
-
-  VRFieldOfView mEyeFOV[NumEyes];
-  IntSize mEyeResolution;
-  Point3D mEyeTranslation[NumEyes];
-  Matrix4x4 mEyeProjectionMatrix[NumEyes];
-  VRDistortionMesh mDistortionMesh[NumEyes];
-  uint32_t mSupportedSensorBits;
-
-  VRFieldOfView mRecommendedEyeFOV[NumEyes];
-  VRFieldOfView mMaximumEyeFOV[NumEyes];
-
-  nsCOMPtr<nsIScreen> mScreen;
-};
-
-class VRHMDManagerOculusImpl;
-class VRHMDManagerOculus {
-  static VRHMDManagerOculusImpl *mImpl;
-public:
-  static bool PlatformInit();
-  static bool Init();
-  static void Destroy();
-  static void GetOculusHMDs(nsTArray<nsRefPtr<VRHMDInfo> >& aHMDResult);
-};
-
-} // namespace gfx
-} // namespace mozilla
-
-#endif /* GFX_VR_H */
--- a/gfx/thebes/moz.build
+++ b/gfx/thebes/moz.build
@@ -44,17 +44,16 @@ EXPORTS += [
     'gfxSharedQuartzSurface.h',
     'gfxSkipChars.h',
     'gfxSVGGlyphs.h',
     'gfxTeeSurface.h',
     'gfxTextRun.h',
     'gfxTypes.h',
     'gfxUserFontSet.h',
     'gfxUtils.h',
-    'gfxVR.h',
     'GraphicsFilter.h',
     'RoundedRect.h',
     'SoftwareVsyncSource.h',
     'VsyncSource.h',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
     EXPORTS += [
@@ -239,17 +238,16 @@ UNIFIED_SOURCES += [
     'gfxReusableSharedImageSurfaceWrapper.cpp',
     'gfxScriptItemizer.cpp',
     'gfxSkipChars.cpp',
     'gfxSVGGlyphs.cpp',
     'gfxTeeSurface.cpp',
     'gfxTextRun.cpp',
     'gfxUserFontSet.cpp',
     'gfxUtils.cpp',
-    'gfxVR.cpp',
     'nsUnicodeRange.cpp',
     'SoftwareVsyncSource.cpp',
     'VsyncSource.cpp',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     UNIFIED_SOURCES += [
         'gfxMacPlatformFontList.mm',
deleted file mode 100644
--- a/gfx/thebes/ovr_capi_dynamic.h
+++ /dev/null
@@ -1,228 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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/. */
-
-/* This file contains just the needed struct definitions for
- * interacting with the Oculus VR C API, without needing to #include
- * OVR_CAPI.h directly.  Note that it uses the same type names as the
- * CAPI, and cannot be #included at the same time as OVR_CAPI.h.  It
- * does not include the entire C API, just want's needed.
- */
-
-#ifdef OVR_CAPI_h
-#warning OVR_CAPI.h included before ovr_capi_dynamic.h, skpping this
-#define mozilla_ovr_capi_dynamic_h_
-#endif
-
-#ifndef mozilla_ovr_capi_dynamic_h_
-#define mozilla_ovr_capi_dynamic_h_
-
-#define OVR_CAPI_LIMITED_MOZILLA 1
-
-#ifdef __cplusplus 
-extern "C" {
-#endif
-
-typedef char ovrBool;
-typedef struct { int x, y; } ovrVector2i;
-typedef struct { int w, h; } ovrSizei;
-typedef struct { ovrVector2i Pos; ovrSizei Size; } ovrRecti;
-typedef struct { float x, y, z, w; } ovrQuatf;
-typedef struct { float x, y; } ovrVector2f;
-typedef struct { float x, y, z; } ovrVector3f;
-typedef struct { float M[4][4]; } ovrMatrix4f;
-
-typedef struct {
-  ovrQuatf Orientation;
-  ovrVector3f Position;
-} ovrPosef;
-
-typedef struct {
-  ovrPosef ThePose;
-  ovrVector3f AngularVelocity;
-  ovrVector3f LinearVelocity;
-  ovrVector3f AngularAcceleration;
-  ovrVector3f LinearAcceleration;
-  double TimeInSeconds;
-} ovrPoseStatef;
-
-typedef struct {
-  float UpTan;
-  float DownTan;
-  float LeftTan;
-  float RightTan;
-} ovrFovPort;
-
-typedef enum {
-  ovrHmd_None             = 0,    
-  ovrHmd_DK1              = 3,
-  ovrHmd_DKHD             = 4,
-  ovrHmd_DK2              = 6,
-  ovrHmd_Other
-} ovrHmdType;
-
-typedef enum {
-  ovrHmdCap_Present           = 0x0001,
-  ovrHmdCap_Available         = 0x0002,
-  ovrHmdCap_Captured          = 0x0004,
-  ovrHmdCap_ExtendDesktop     = 0x0008,
-  ovrHmdCap_DisplayOff        = 0x0040,
-  ovrHmdCap_LowPersistence    = 0x0080,
-  ovrHmdCap_DynamicPrediction = 0x0200,
-  ovrHmdCap_NoVSync           = 0x1000,
-  ovrHmdCap_NoMirrorToWindow  = 0x2000
-} ovrHmdCapBits;
-
-typedef enum
-{
-  ovrTrackingCap_Orientation      = 0x0010,
-  ovrTrackingCap_MagYawCorrection = 0x0020,
-  ovrTrackingCap_Position         = 0x0040,
-  ovrTrackingCap_Idle             = 0x0100
-} ovrTrackingCaps;
-
-typedef enum {
-  ovrDistortionCap_Chromatic = 0x01,
-  ovrDistortionCap_TimeWarp  = 0x02,
-  ovrDistortionCap_Vignette  = 0x08,
-  ovrDistortionCap_NoRestore = 0x10,
-  ovrDistortionCap_FlipInput = 0x20,
-  ovrDistortionCap_SRGB      = 0x40,
-  ovrDistortionCap_Overdrive = 0x80,
-  ovrDistortionCap_ProfileNoTimewarpSpinWaits = 0x10000
-} ovrDistortionCaps;
-
-typedef enum {
-  ovrEye_Left  = 0,
-  ovrEye_Right = 1,
-  ovrEye_Count = 2
-} ovrEyeType;
-
-typedef struct ovrHmdDesc_ {
-  void* Handle;
-  ovrHmdType  Type;
-  const char* ProductName;    
-  const char* Manufacturer;
-  short VendorId;
-  short ProductId;
-  char SerialNumber[24];
-  short FirmwareMajor;
-  short FirmwareMinor;
-  float CameraFrustumHFovInRadians;
-  float CameraFrustumVFovInRadians;
-  float CameraFrustumNearZInMeters;
-  float CameraFrustumFarZInMeters;
-
-  unsigned int HmdCaps;
-  unsigned int TrackingCaps;
-  unsigned int DistortionCaps;
-
-  ovrFovPort  DefaultEyeFov[ovrEye_Count];
-  ovrFovPort  MaxEyeFov[ovrEye_Count];
-  ovrEyeType  EyeRenderOrder[ovrEye_Count];
-
-  ovrSizei    Resolution;
-  ovrVector2i WindowsPos;
-
-  const char* DisplayDeviceName;
-  int         DisplayId;
-} ovrHmdDesc;
-
-typedef const ovrHmdDesc* ovrHmd;
-
-typedef enum {
-  ovrStatus_OrientationTracked    = 0x0001,
-  ovrStatus_PositionTracked       = 0x0002,
-  ovrStatus_CameraPoseTracked     = 0x0004,
-  ovrStatus_PositionConnected     = 0x0020,
-  ovrStatus_HmdConnected          = 0x0080
-} ovrStatusBits;
-
-typedef struct ovrSensorData_ {
-  ovrVector3f    Accelerometer;
-  ovrVector3f    Gyro;
-  ovrVector3f    Magnetometer;
-  float          Temperature;
-  float          TimeInSeconds;
-} ovrSensorData;
-
-
-typedef struct ovrTrackingState_ {
-  ovrPoseStatef HeadPose;
-  ovrPosef CameraPose;
-  ovrPosef LeveledCameraPose;
-  ovrSensorData RawSensorData;
-  unsigned int StatusFlags;
-  double LastVisionProcessingTime;
-  double LastVisionFrameLatency;
-  uint32_t LastCameraFrameCounter;
-} ovrTrackingState;
-
-typedef struct ovrFrameTiming_ {
-  float DeltaSeconds;
-  double ThisFrameSeconds;
-  double TimewarpPointSeconds;
-  double NextFrameSeconds;
-  double ScanoutMidpointSeconds;
-  double EyeScanoutSeconds[2];    
-} ovrFrameTiming;
-
-typedef struct ovrEyeRenderDesc_ {
-  ovrEyeType  Eye;        
-  ovrFovPort  Fov;
-  ovrRecti DistortedViewport;
-  ovrVector2f PixelsPerTanAngleAtCenter;
-  ovrVector3f ViewAdjust;
-} ovrEyeRenderDesc;
-
-typedef struct ovrDistortionVertex_ {
-  ovrVector2f ScreenPosNDC;
-  float       TimeWarpFactor;
-  float       VignetteFactor;
-  ovrVector2f TanEyeAnglesR;
-  ovrVector2f TanEyeAnglesG;
-  ovrVector2f TanEyeAnglesB;    
-} ovrDistortionVertex;
-
-typedef struct ovrDistortionMesh_ {
-  ovrDistortionVertex* pVertexData;
-  unsigned short*      pIndexData;
-  unsigned int         VertexCount;
-  unsigned int         IndexCount;
-} ovrDistortionMesh;
-
-typedef ovrBool (*pfn_ovr_Initialize)();
-typedef void (*pfn_ovr_Shutdown)();
-typedef int (*pfn_ovrHmd_Detect)();
-typedef ovrHmd (*pfn_ovrHmd_Create)(int index);
-typedef void (*pfn_ovrHmd_Destroy)(ovrHmd hmd);
-typedef ovrHmd (*pfn_ovrHmd_CreateDebug)(ovrHmdType type);
-typedef const char* (*pfn_ovrHmd_GetLastError)(ovrHmd hmd);
-typedef ovrBool (*pfn_ovrHmd_AttachToWindow)(ovrHmd hmd, void* window, const ovrRecti* destMirrorRect, const ovrRecti* sourceRenderTargetRect);
-typedef unsigned int (*pfn_ovrHmd_GetEnabledCaps)(ovrHmd hmd);
-typedef void (*pfn_ovrHmd_SetEnabledCaps)(ovrHmd hmd, unsigned int hmdCaps);
-typedef ovrBool (*pfn_ovrHmd_ConfigureTracking)(ovrHmd hmd, unsigned int supportedTrackingCaps, unsigned int requiredTrackingCaps); 
-typedef void (*pfn_ovrHmd_RecenterPose)(ovrHmd hmd);
-typedef ovrTrackingState (*pfn_ovrHmd_GetTrackingState)(ovrHmd hmd, double absTime);
-typedef ovrSizei (*pfn_ovrHmd_GetFovTextureSize)(ovrHmd hmd, ovrEyeType eye, ovrFovPort fov, float pixelsPerDisplayPixel);
-typedef ovrEyeRenderDesc (*pfn_ovrHmd_GetRenderDesc)(ovrHmd hmd, ovrEyeType eyeType, ovrFovPort fov);
-typedef ovrBool (*pfn_ovrHmd_CreateDistortionMesh)(ovrHmd hmd, ovrEyeType eyeType, ovrFovPort fov, unsigned int distortionCaps, ovrDistortionMesh *meshData);
-typedef void (*pfn_ovrHmd_DestroyDistortionMesh)(ovrDistortionMesh* meshData);
-typedef void (*pfn_ovrHmd_GetRenderScaleAndOffset)(ovrFovPort fov, ovrSizei textureSize, ovrRecti renderViewport, ovrVector2f uvScaleOffsetOut[2]);
-typedef ovrFrameTiming (*pfn_ovrHmd_GetFrameTiming)(ovrHmd hmd, unsigned int frameIndex);
-typedef ovrFrameTiming (*pfn_ovrHmd_BeginFrameTiming)(ovrHmd hmd, unsigned int frameIndex);
-typedef void (*pfn_ovrHmd_EndFrameTiming)(ovrHmd hmd);
-typedef void (*pfn_ovrHmd_ResetFrameTiming)(ovrHmd hmd, unsigned int frameIndex, bool vsync);
-typedef void (*pfn_ovrHmd_GetEyePoses)(ovrHmd hmd, unsigned int frameIndex, ovrVector3f hmdToEyeViewOffset[2], ovrPosef outEyePoses[2], ovrTrackingState* outHmdTrackingState);
-typedef ovrPosef (*pfn_ovrHmd_GetHmdPosePerEye)(ovrHmd hmd, ovrEyeType eye);
-typedef void (*pfn_ovrHmd_GetEyeTimewarpMatrices)(ovrHmd hmd, ovrEyeType eye, ovrPosef renderPose, ovrMatrix4f twmOut[2]);
-typedef ovrMatrix4f (*pfn_ovrMatrix4f_Projection) (ovrFovPort fov, float znear, float zfar, ovrBool rightHanded );
-typedef ovrMatrix4f (*pfn_ovrMatrix4f_OrthoSubProjection) (ovrFovPort fov, ovrVector2f orthoScale, float orthoDistance, float eyeViewAdjustX);
-typedef double (*pfn_ovr_GetTimeInSeconds)();
-
-#ifdef __cplusplus 
-}
-#endif
-
-#endif /* mozilla_ovr_capi_dynamic_h_ */
new file mode 100644
--- /dev/null
+++ b/gfx/vr/gfxVR.cpp
@@ -0,0 +1,658 @@
+/* -*- 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 <math.h>
+
+#include "prlink.h"
+#include "prmem.h"
+#include "prenv.h"
+#include "gfxPrefs.h"
+#include "gfxVR.h"
+#include "nsString.h"
+#include "mozilla/Preferences.h"
+
+#include "ovr_capi_dynamic.h"
+
+#include "nsServiceManagerUtils.h"
+#include "nsIScreenManager.h"
+
+#ifdef XP_WIN
+#include "gfxWindowsPlatform.h" // for gfxWindowsPlatform::GetDPIScale
+#endif
+
+#ifndef M_PI
+# define M_PI 3.14159265358979323846
+#endif
+
+namespace {
+
+#ifdef OVR_CAPI_LIMITED_MOZILLA
+static pfn_ovr_Initialize ovr_Initialize = nullptr;
+static pfn_ovr_Shutdown ovr_Shutdown = nullptr;
+static pfn_ovrHmd_Detect ovrHmd_Detect = nullptr;
+static pfn_ovrHmd_Create ovrHmd_Create = nullptr;
+static pfn_ovrHmd_Destroy ovrHmd_Destroy = nullptr;
+static pfn_ovrHmd_CreateDebug ovrHmd_CreateDebug = nullptr;
+static pfn_ovrHmd_GetLastError ovrHmd_GetLastError = nullptr;
+static pfn_ovrHmd_AttachToWindow ovrHmd_AttachToWindow = nullptr;
+static pfn_ovrHmd_GetEnabledCaps ovrHmd_GetEnabledCaps = nullptr;
+static pfn_ovrHmd_SetEnabledCaps ovrHmd_SetEnabledCaps = nullptr;
+static pfn_ovrHmd_ConfigureTracking ovrHmd_ConfigureTracking = nullptr;
+static pfn_ovrHmd_RecenterPose ovrHmd_RecenterPose = nullptr;
+static pfn_ovrHmd_GetTrackingState ovrHmd_GetTrackingState = nullptr;
+static pfn_ovrHmd_GetFovTextureSize ovrHmd_GetFovTextureSize = nullptr;
+static pfn_ovrHmd_GetRenderDesc ovrHmd_GetRenderDesc = nullptr;
+static pfn_ovrHmd_CreateDistortionMesh ovrHmd_CreateDistortionMesh = nullptr;
+static pfn_ovrHmd_DestroyDistortionMesh ovrHmd_DestroyDistortionMesh = nullptr;
+static pfn_ovrHmd_GetRenderScaleAndOffset ovrHmd_GetRenderScaleAndOffset = nullptr;
+static pfn_ovrHmd_GetFrameTiming ovrHmd_GetFrameTiming = nullptr;
+static pfn_ovrHmd_BeginFrameTiming ovrHmd_BeginFrameTiming = nullptr;
+static pfn_ovrHmd_EndFrameTiming ovrHmd_EndFrameTiming = nullptr;
+static pfn_ovrHmd_ResetFrameTiming ovrHmd_ResetFrameTiming = nullptr;
+static pfn_ovrHmd_GetEyePoses ovrHmd_GetEyePoses = nullptr;
+static pfn_ovrHmd_GetHmdPosePerEye ovrHmd_GetHmdPosePerEye = nullptr;
+static pfn_ovrHmd_GetEyeTimewarpMatrices ovrHmd_GetEyeTimewarpMatrices = nullptr;
+static pfn_ovrMatrix4f_Projection ovrMatrix4f_Projection = nullptr;
+static pfn_ovrMatrix4f_OrthoSubProjection ovrMatrix4f_OrthoSubProjection = nullptr;
+static pfn_ovr_GetTimeInSeconds ovr_GetTimeInSeconds = nullptr;
+
+#if defined(XP_WIN)
+# ifdef HAVE_64BIT_BUILD
+#  define OVR_LIB_NAME "libovr64.dll"
+# else
+#  define OVR_LIB_NAME "libovr.dll"
+# endif
+#elif defined(XP_MACOSX)
+# define OVR_LIB_NAME "libovr.dylib"
+#else
+# define OVR_LIB_NAME 0
+#endif
+
+static bool
+InitializeOculusCAPI()
+{
+  static PRLibrary *ovrlib = nullptr;
+
+  if (!ovrlib) {
+    const char *libName = OVR_LIB_NAME;
+
+    // If the pref is present, we override libName
+    nsAdoptingCString prefLibName = mozilla::Preferences::GetCString("dom.vr.ovr_lib_path");
+    if (prefLibName && prefLibName.get()) {
+      libName = prefLibName.get();
+    }
+
+    // If the env var is present, we override libName
+    if (PR_GetEnv("OVR_LIB_NAME")) {
+      libName = PR_GetEnv("OVR_LIB_NAME");
+    }
+
+    if (!libName) {
+      printf_stderr("Don't know how to find Oculus VR library; missing dom.vr.ovr_lib_path or OVR_LIB_NAME\n");
+      return false;
+    }
+
+    ovrlib = PR_LoadLibrary(libName);
+
+    if (!ovrlib) {
+      // Not found? Try harder. Needed mainly on OSX/etc. where
+      // the binary location is not in the search path.
+      const char *xulName = "libxul.so";
+#if defined(XP_MACOSX)
+      xulName = "XUL";
+#endif
+
+      char *xulpath = PR_GetLibraryFilePathname(xulName, (PRFuncPtr) &InitializeOculusCAPI);
+      if (xulpath) {
+        char *xuldir = strrchr(xulpath, '/');
+        if (xuldir) {
+          *xuldir = 0;
+          xuldir = xulpath;
+
+          char *ovrpath = PR_GetLibraryName(xuldir, libName);
+          ovrlib = PR_LoadLibrary(ovrpath);
+          PR_Free(ovrpath);
+        }
+        PR_Free(xulpath);
+      }
+    }
+
+    if (!ovrlib) {
+      printf_stderr("Failed to load Oculus VR library, tried '%s'\n", libName);
+      return false;
+    }
+  }
+
+  // was it already initialized?
+  if (ovr_Initialize)
+    return true;
+
+#define REQUIRE_FUNCTION(_x) do { \
+    *(void **)&_x = (void *) PR_FindSymbol(ovrlib, #_x);                \
+    if (!_x) { printf_stderr(#_x " symbol missing\n"); goto fail; }       \
+  } while (0)
+
+  REQUIRE_FUNCTION(ovr_Initialize);
+  REQUIRE_FUNCTION(ovr_Shutdown);
+  REQUIRE_FUNCTION(ovrHmd_Detect);
+  REQUIRE_FUNCTION(ovrHmd_Create);
+  REQUIRE_FUNCTION(ovrHmd_Destroy);
+  REQUIRE_FUNCTION(ovrHmd_CreateDebug);
+  REQUIRE_FUNCTION(ovrHmd_GetLastError);
+  REQUIRE_FUNCTION(ovrHmd_AttachToWindow);
+  REQUIRE_FUNCTION(ovrHmd_GetEnabledCaps);
+  REQUIRE_FUNCTION(ovrHmd_SetEnabledCaps);
+  REQUIRE_FUNCTION(ovrHmd_ConfigureTracking);
+  REQUIRE_FUNCTION(ovrHmd_RecenterPose);
+  REQUIRE_FUNCTION(ovrHmd_GetTrackingState);
+
+  REQUIRE_FUNCTION(ovrHmd_GetFovTextureSize);
+  REQUIRE_FUNCTION(ovrHmd_GetRenderDesc);
+  REQUIRE_FUNCTION(ovrHmd_CreateDistortionMesh);
+  REQUIRE_FUNCTION(ovrHmd_DestroyDistortionMesh);
+  REQUIRE_FUNCTION(ovrHmd_GetRenderScaleAndOffset);
+  REQUIRE_FUNCTION(ovrHmd_GetFrameTiming);
+  REQUIRE_FUNCTION(ovrHmd_BeginFrameTiming);
+  REQUIRE_FUNCTION(ovrHmd_EndFrameTiming);
+  REQUIRE_FUNCTION(ovrHmd_ResetFrameTiming);
+  REQUIRE_FUNCTION(ovrHmd_GetEyePoses);
+  REQUIRE_FUNCTION(ovrHmd_GetHmdPosePerEye);
+  REQUIRE_FUNCTION(ovrHmd_GetEyeTimewarpMatrices);
+  REQUIRE_FUNCTION(ovrMatrix4f_Projection);
+  REQUIRE_FUNCTION(ovrMatrix4f_OrthoSubProjection);
+  REQUIRE_FUNCTION(ovr_GetTimeInSeconds);
+
+#undef REQUIRE_FUNCTION
+
+  return true;
+
+ fail:
+  ovr_Initialize = nullptr;
+  return false;
+}
+
+#else
+// we're statically linked; it's available
+static bool InitializeOculusCAPI()
+{
+  return true;
+}
+#endif
+
+} // anonymous namespace
+
+using namespace mozilla::gfx;
+
+// Dummy nsIScreen implementation, for when we just need to specify a size
+class FakeScreen : public nsIScreen
+{
+public:
+  explicit FakeScreen(const IntRect& aScreenRect)
+    : mScreenRect(aScreenRect)
+  { }
+
+  NS_DECL_ISUPPORTS
+
+  NS_IMETHOD GetRect(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override {
+    *l = mScreenRect.x;
+    *t = mScreenRect.y;
+    *w = mScreenRect.width;
+    *h = mScreenRect.height;
+    return NS_OK;
+  }
+  NS_IMETHOD GetAvailRect(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override {
+    return GetRect(l, t, w, h);
+  }
+  NS_IMETHOD GetRectDisplayPix(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override {
+    return GetRect(l, t, w, h);
+  }
+  NS_IMETHOD GetAvailRectDisplayPix(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override {
+    return GetAvailRect(l, t, w, h);
+  }
+
+  NS_IMETHOD GetId(uint32_t* aId) override { *aId = (uint32_t)-1; return NS_OK; }
+  NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth) override { *aPixelDepth = 24; return NS_OK; }
+  NS_IMETHOD GetColorDepth(int32_t* aColorDepth) override { *aColorDepth = 24; return NS_OK; }
+
+  NS_IMETHOD LockMinimumBrightness(uint32_t aBrightness) override { return NS_ERROR_NOT_AVAILABLE; }
+  NS_IMETHOD UnlockMinimumBrightness(uint32_t aBrightness) override { return NS_ERROR_NOT_AVAILABLE; }
+  NS_IMETHOD GetRotation(uint32_t* aRotation) override {
+    *aRotation = nsIScreen::ROTATION_0_DEG;
+    return NS_OK;
+  }
+  NS_IMETHOD SetRotation(uint32_t aRotation) override { return NS_ERROR_NOT_AVAILABLE; }
+  NS_IMETHOD GetContentsScaleFactor(double* aContentsScaleFactor) override {
+    *aContentsScaleFactor = 1.0;
+    return NS_OK;
+  }
+
+protected:
+  virtual ~FakeScreen() {}
+
+  IntRect mScreenRect;
+};
+
+NS_IMPL_ISUPPORTS(FakeScreen, nsIScreen)
+
+class HMDInfoOculus : public VRHMDInfo {
+  friend class VRHMDManagerOculusImpl;
+public:
+  explicit HMDInfoOculus(ovrHmd aHMD);
+
+  bool SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight,
+              double zNear, double zFar) override;
+
+  bool StartSensorTracking() override;
+  VRHMDSensorState GetSensorState(double timeOffset) override;
+  void StopSensorTracking() override;
+  void ZeroSensor() override;
+
+  void FillDistortionConstants(uint32_t whichEye,
+                               const IntSize& textureSize, const IntRect& eyeViewport,
+                               const Size& destViewport, const Rect& destRect,
+                               VRDistortionConstants& values) override;
+
+  void Destroy();
+
+protected:
+  virtual ~HMDInfoOculus() {
+      Destroy();
+      MOZ_COUNT_DTOR_INHERITED(HMDInfoOculus, VRHMDInfo);
+  }
+
+  ovrHmd mHMD;
+  ovrFovPort mFOVPort[2];
+  uint32_t mStartCount;
+};
+
+static ovrFovPort
+ToFovPort(const VRFieldOfView& aFOV)
+{
+  ovrFovPort fovPort;
+  fovPort.LeftTan = tan(aFOV.leftDegrees * M_PI / 180.0);
+  fovPort.RightTan = tan(aFOV.rightDegrees * M_PI / 180.0);
+  fovPort.UpTan = tan(aFOV.upDegrees * M_PI / 180.0);
+  fovPort.DownTan = tan(aFOV.downDegrees * M_PI / 180.0);
+  return fovPort;
+}
+
+static VRFieldOfView
+FromFovPort(const ovrFovPort& aFOV)
+{
+  VRFieldOfView fovInfo;
+  fovInfo.leftDegrees = atan(aFOV.LeftTan) * 180.0 / M_PI;
+  fovInfo.rightDegrees = atan(aFOV.RightTan) * 180.0 / M_PI;
+  fovInfo.upDegrees = atan(aFOV.UpTan) * 180.0 / M_PI;
+  fovInfo.downDegrees = atan(aFOV.DownTan) * 180.0 / M_PI;
+  return fovInfo;
+}
+
+HMDInfoOculus::HMDInfoOculus(ovrHmd aHMD)
+  : VRHMDInfo(VRHMDType::Oculus)
+  , mHMD(aHMD)
+  , mStartCount(0)
+{
+  MOZ_COUNT_CTOR_INHERITED(HMDInfoOculus, VRHMDInfo);
+
+  mSupportedSensorBits = 0;
+  if (mHMD->TrackingCaps & ovrTrackingCap_Orientation)
+    mSupportedSensorBits |= State_Orientation;
+  if (mHMD->TrackingCaps & ovrTrackingCap_Position)
+    mSupportedSensorBits |= State_Position;
+
+  mRecommendedEyeFOV[Eye_Left] = FromFovPort(mHMD->DefaultEyeFov[ovrEye_Left]);
+  mRecommendedEyeFOV[Eye_Right] = FromFovPort(mHMD->DefaultEyeFov[ovrEye_Right]);
+
+  mMaximumEyeFOV[Eye_Left] = FromFovPort(mHMD->MaxEyeFov[ovrEye_Left]);
+  mMaximumEyeFOV[Eye_Right] = FromFovPort(mHMD->MaxEyeFov[ovrEye_Right]);
+
+  SetFOV(mRecommendedEyeFOV[Eye_Left], mRecommendedEyeFOV[Eye_Right], 0.01, 10000.0);
+
+  nsCOMPtr<nsIScreenManager> screenmgr = do_GetService("@mozilla.org/gfx/screenmanager;1");
+  if (screenmgr) {
+    screenmgr->ScreenForRect(mHMD->WindowsPos.x, mHMD->WindowsPos.y,
+                             mHMD->Resolution.w, mHMD->Resolution.h,
+                             getter_AddRefs(mScreen));
+  }
+}
+
+void
+HMDInfoOculus::Destroy()
+{
+  if (mHMD) {
+    ovrHmd_Destroy(mHMD);
+    mHMD = nullptr;
+  }
+}
+
+bool
+HMDInfoOculus::SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight,
+                      double zNear, double zFar)
+{
+  float pixelsPerDisplayPixel = 1.0;
+  ovrSizei texSize[2];
+
+  uint32_t caps = ovrDistortionCap_Chromatic | ovrDistortionCap_Vignette; // XXX TODO add TimeWarp
+
+  // get eye parameters and create the mesh
+  for (uint32_t eye = 0; eye < NumEyes; eye++) {
+    mEyeFOV[eye] = eye == 0 ? aFOVLeft : aFOVRight;
+    mFOVPort[eye] = ToFovPort(mEyeFOV[eye]);
+
+    ovrEyeRenderDesc renderDesc = ovrHmd_GetRenderDesc(mHMD, (ovrEyeType) eye, mFOVPort[eye]);
+
+    // these values are negated so that content can add the adjustment to its camera position,
+    // instead of subtracting
+    mEyeTranslation[eye] = Point3D(-renderDesc.ViewAdjust.x, -renderDesc.ViewAdjust.y, -renderDesc.ViewAdjust.z);
+
+    // note that we are using a right-handed coordinate system here, to match CSS
+    ovrMatrix4f projMatrix = ovrMatrix4f_Projection(mFOVPort[eye], zNear, zFar, true);
+
+    // XXX this is gross, we really need better methods on Matrix4x4
+    memcpy(&mEyeProjectionMatrix[eye], projMatrix.M, sizeof(ovrMatrix4f));
+    mEyeProjectionMatrix[eye].Transpose();
+
+    texSize[eye] = ovrHmd_GetFovTextureSize(mHMD, (ovrEyeType) eye, mFOVPort[eye], pixelsPerDisplayPixel);
+
+    ovrDistortionMesh mesh;
+    bool ok = ovrHmd_CreateDistortionMesh(mHMD, (ovrEyeType) eye, mFOVPort[eye], caps, &mesh);
+    if (!ok)
+      return false;
+
+    mDistortionMesh[eye].mVertices.SetLength(mesh.VertexCount);
+    mDistortionMesh[eye].mIndices.SetLength(mesh.IndexCount);
+
+    ovrDistortionVertex *srcv = mesh.pVertexData;
+    VRDistortionVertex *destv = mDistortionMesh[eye].mVertices.Elements();
+    memset(destv, 0, mesh.VertexCount * sizeof(VRDistortionVertex));
+    for (uint32_t i = 0; i < mesh.VertexCount; ++i) {
+      destv[i].pos[0] = srcv[i].ScreenPosNDC.x;
+      destv[i].pos[1] = srcv[i].ScreenPosNDC.y;
+
+      destv[i].texR[0] = srcv[i].TanEyeAnglesR.x;
+      destv[i].texR[1] = srcv[i].TanEyeAnglesR.y;
+      destv[i].texG[0] = srcv[i].TanEyeAnglesG.x;
+      destv[i].texG[1] = srcv[i].TanEyeAnglesG.y;
+      destv[i].texB[0] = srcv[i].TanEyeAnglesB.x;
+      destv[i].texB[1] = srcv[i].TanEyeAnglesB.y;
+
+      destv[i].genericAttribs[0] = srcv[i].VignetteFactor;
+      destv[i].genericAttribs[1] = srcv[i].TimeWarpFactor;
+    }
+
+    memcpy(mDistortionMesh[eye].mIndices.Elements(), mesh.pIndexData, mesh.IndexCount * sizeof(uint16_t));
+    ovrHmd_DestroyDistortionMesh(&mesh);
+  }
+
+  // take the max of both for eye resolution
+  mEyeResolution.width = std::max(texSize[Eye_Left].w, texSize[Eye_Right].w);
+  mEyeResolution.height = std::max(texSize[Eye_Left].h, texSize[Eye_Right].h);
+
+  mConfiguration.hmdType = mType;
+  mConfiguration.value = 0;
+  mConfiguration.fov[0] = aFOVLeft;
+  mConfiguration.fov[1] = aFOVRight;
+
+  return true;
+  //* need to call this during rendering each frame I think? */
+  //ovrHmd_GetRenderScaleAndOffset(fovPort, texSize, renderViewport, uvScaleOffsetOut);
+}
+
+void
+HMDInfoOculus::FillDistortionConstants(uint32_t whichEye,
+                                       const IntSize& textureSize,
+                                       const IntRect& eyeViewport,
+                                       const Size& destViewport,
+                                       const Rect& destRect,
+                                       VRDistortionConstants& values)
+{
+  ovrSizei texSize = { textureSize.width, textureSize.height };
+  ovrRecti eyePort = { { eyeViewport.x, eyeViewport.y }, { eyeViewport.width, eyeViewport.height } };
+  ovrVector2f scaleOut[2];
+
+  ovrHmd_GetRenderScaleAndOffset(mFOVPort[whichEye], texSize, eyePort, scaleOut);
+
+  values.eyeToSourceScaleAndOffset[0] = scaleOut[0].x;
+  values.eyeToSourceScaleAndOffset[1] = scaleOut[0].y;
+  values.eyeToSourceScaleAndOffset[2] = scaleOut[1].x;
+  values.eyeToSourceScaleAndOffset[3] = scaleOut[1].y;
+
+  // These values are in clip space [-1..1] range, but we're providing
+  // scaling in the 0..2 space for sanity.
+
+  // this is the destRect in clip space
+  float x0 = destRect.x / destViewport.width * 2.0 - 1.0;
+  float x1 = (destRect.x + destRect.width) / destViewport.width * 2.0 - 1.0;
+
+  float y0 = destRect.y / destViewport.height * 2.0 - 1.0;
+  float y1 = (destRect.y + destRect.height) / destViewport.height * 2.0 - 1.0;
+
+  // offset
+  values.destinationScaleAndOffset[0] = (x0+x1) / 2.0;
+  values.destinationScaleAndOffset[1] = (y0+y1) / 2.0;
+  // scale
+  values.destinationScaleAndOffset[2] = destRect.width / destViewport.width;
+  values.destinationScaleAndOffset[3] = destRect.height / destViewport.height;
+}
+
+bool
+HMDInfoOculus::StartSensorTracking()
+{
+  if (mStartCount == 0) {
+    bool ok = ovrHmd_ConfigureTracking(mHMD, ovrTrackingCap_Orientation | ovrTrackingCap_Position, 0);
+    if (!ok)
+      return false;
+  }
+
+  mStartCount++;
+  return true;
+}
+
+void
+HMDInfoOculus::StopSensorTracking()
+{
+  if (--mStartCount == 0) {
+    ovrHmd_ConfigureTracking(mHMD, 0, 0);
+  }
+}
+
+void
+HMDInfoOculus::ZeroSensor()
+{
+  ovrHmd_RecenterPose(mHMD);
+}
+
+VRHMDSensorState
+HMDInfoOculus::GetSensorState(double timeOffset)
+{
+  VRHMDSensorState result;
+  result.Clear();
+
+  // XXX this is the wrong time base for timeOffset; we need to figure out how to synchronize
+  // the Oculus time base and the browser one.
+  ovrTrackingState state = ovrHmd_GetTrackingState(mHMD, ovr_GetTimeInSeconds() + timeOffset);
+  ovrPoseStatef& pose(state.HeadPose);
+
+  result.timestamp = pose.TimeInSeconds;
+
+  if (state.StatusFlags & ovrStatus_OrientationTracked) {
+    result.flags |= State_Orientation;
+
+    result.orientation[0] = pose.ThePose.Orientation.x;
+    result.orientation[1] = pose.ThePose.Orientation.y;
+    result.orientation[2] = pose.ThePose.Orientation.z;
+    result.orientation[3] = pose.ThePose.Orientation.w;
+    
+    result.angularVelocity[0] = pose.AngularVelocity.x;
+    result.angularVelocity[1] = pose.AngularVelocity.y;
+    result.angularVelocity[2] = pose.AngularVelocity.z;
+
+    result.angularAcceleration[0] = pose.AngularAcceleration.x;
+    result.angularAcceleration[1] = pose.AngularAcceleration.y;
+    result.angularAcceleration[2] = pose.AngularAcceleration.z;
+  }
+
+  if (state.StatusFlags & ovrStatus_PositionTracked) {
+    result.flags |= State_Position;
+
+    result.position[0] = pose.ThePose.Position.x;
+    result.position[1] = pose.ThePose.Position.y;
+    result.position[2] = pose.ThePose.Position.z;
+    
+    result.linearVelocity[0] = pose.LinearVelocity.x;
+    result.linearVelocity[1] = pose.LinearVelocity.y;
+    result.linearVelocity[2] = pose.LinearVelocity.z;
+
+    result.linearAcceleration[0] = pose.LinearAcceleration.x;
+    result.linearAcceleration[1] = pose.LinearAcceleration.y;
+    result.linearAcceleration[2] = pose.LinearAcceleration.z;
+  }
+
+  return result;
+}
+
+namespace mozilla {
+namespace gfx {
+
+class VRHMDManagerOculusImpl {
+public:
+  VRHMDManagerOculusImpl() : mOculusInitialized(false), mOculusPlatformInitialized(false)
+  { }
+
+  bool PlatformInit();
+  bool Init();
+  void Destroy();
+  void GetOculusHMDs(nsTArray<nsRefPtr<VRHMDInfo> >& aHMDResult);
+protected:
+  nsTArray<nsRefPtr<HMDInfoOculus>> mOculusHMDs;
+  bool mOculusInitialized;
+  bool mOculusPlatformInitialized;
+};
+
+} // namespace gfx
+} // namespace mozilla
+
+VRHMDManagerOculusImpl *VRHMDManagerOculus::mImpl = nullptr;
+
+// These just forward to the Impl class, to have a non-static container for various
+// objects.
+
+bool
+VRHMDManagerOculus::PlatformInit()
+{
+  if (!mImpl) {
+    mImpl = new VRHMDManagerOculusImpl;
+  }
+  return mImpl->PlatformInit();
+}
+
+bool
+VRHMDManagerOculus::Init()
+{
+  if (!mImpl) {
+    mImpl = new VRHMDManagerOculusImpl;
+  }
+  return mImpl->Init();
+}
+
+void
+VRHMDManagerOculus::GetOculusHMDs(nsTArray<nsRefPtr<VRHMDInfo>>& aHMDResult)
+{
+  if (!mImpl) {
+    mImpl = new VRHMDManagerOculusImpl;
+  }
+  mImpl->GetOculusHMDs(aHMDResult);
+}
+
+void
+VRHMDManagerOculus::Destroy()
+{
+  if (!mImpl)
+    return;
+  mImpl->Destroy();
+  delete mImpl;
+  mImpl = nullptr;
+}
+
+bool
+VRHMDManagerOculusImpl::PlatformInit()
+{
+  if (mOculusPlatformInitialized)
+    return true;
+
+  if (!gfxPrefs::VREnabled())
+    return false;
+
+  if (!InitializeOculusCAPI())
+    return false;
+
+  bool ok = ovr_Initialize();
+
+  if (!ok)
+    return false;
+
+  mOculusPlatformInitialized = true;
+  return true;
+}
+
+bool
+VRHMDManagerOculusImpl::Init()
+{
+  if (mOculusInitialized)
+    return true;
+
+  if (!PlatformInit())
+    return false;
+
+  int count = ovrHmd_Detect();
+
+  for (int i = 0; i < count; ++i) {
+    ovrHmd hmd = ovrHmd_Create(i);
+    if (!hmd)
+      continue;
+    nsRefPtr<HMDInfoOculus> oc = new HMDInfoOculus(hmd);
+    mOculusHMDs.AppendElement(oc);
+  }
+
+  // VRAddTestDevices == 1: add test device only if no real devices present
+  // VRAddTestDevices == 2: add test device always
+  if ((count == 0 && gfxPrefs::VRAddTestDevices() == 1) ||
+      (gfxPrefs::VRAddTestDevices() == 2))
+  {
+    ovrHmd hmd = ovrHmd_CreateDebug(ovrHmd_DK2);
+    if (hmd) {
+      nsRefPtr<HMDInfoOculus> oc = new HMDInfoOculus(hmd);
+      mOculusHMDs.AppendElement(oc);
+    }
+  }
+
+  mOculusInitialized = true;
+  return true;
+}
+
+void
+VRHMDManagerOculusImpl::Destroy()
+{
+  if (!mOculusInitialized)
+    return;
+
+  for (size_t i = 0; i < mOculusHMDs.Length(); ++i) {
+    mOculusHMDs[i]->Destroy();
+  }
+
+  mOculusHMDs.Clear();
+
+  ovr_Shutdown();
+  mOculusInitialized = false;
+}
+
+void
+VRHMDManagerOculusImpl::GetOculusHMDs(nsTArray<nsRefPtr<VRHMDInfo>>& aHMDResult)
+{
+  Init();
+  for (size_t i = 0; i < mOculusHMDs.Length(); ++i) {
+    aHMDResult.AppendElement(mOculusHMDs[i]);
+  }
+}
new file mode 100644
--- /dev/null
+++ b/gfx/vr/gfxVR.h
@@ -0,0 +1,217 @@
+/* -*- 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/. */
+
+#ifndef GFX_VR_H
+#define GFX_VR_H
+
+#include "nsTArray.h"
+#include "nsIScreen.h"
+#include "nsCOMPtr.h"
+#include "nsRefPtr.h"
+
+#include "mozilla/gfx/2D.h"
+#include "mozilla/EnumeratedArray.h"
+
+namespace mozilla {
+namespace gfx {
+
+enum class VRHMDType : uint16_t {
+  Oculus,
+  NumHMDTypes
+};
+
+struct VRFieldOfView {
+  static VRFieldOfView FromCSSPerspectiveInfo(double aPerspectiveDistance,
+                                              const Point& aPerspectiveOrigin,
+                                              const Point& aTransformOrigin,
+                                              const Rect& aContentRectangle)
+  {
+    /**/
+    return VRFieldOfView();
+  }
+
+  VRFieldOfView() {}
+  VRFieldOfView(double up, double right, double down, double left)
+    : upDegrees(up), rightDegrees(right), downDegrees(down), leftDegrees(left)
+  {}
+
+  bool operator==(const VRFieldOfView& other) const {
+    return other.upDegrees == upDegrees &&
+           other.downDegrees == downDegrees &&
+           other.rightDegrees == rightDegrees &&
+           other.leftDegrees == leftDegrees;
+  }
+
+  bool operator!=(const VRFieldOfView& other) const {
+    return !(*this == other);
+  }
+
+  bool IsZero() const {
+    return upDegrees == 0.0 ||
+      rightDegrees == 0.0 ||
+      downDegrees == 0.0 ||
+      leftDegrees == 0.0;
+  }
+
+  double upDegrees;
+  double rightDegrees;
+  double downDegrees;
+  double leftDegrees;
+};
+
+// 12 floats per vertex. Position, tex coordinates
+// for each channel, and 4 generic attributes
+struct VRDistortionConstants {
+  float eyeToSourceScaleAndOffset[4];
+  float destinationScaleAndOffset[4];
+};
+
+struct VRDistortionVertex {
+  float pos[2];
+  float texR[2];
+  float texG[2];
+  float texB[2];
+  float genericAttribs[4];
+};
+
+struct VRDistortionMesh {
+  nsTArray<VRDistortionVertex> mVertices;
+  nsTArray<uint16_t> mIndices;
+};
+
+struct VRHMDSensorState {
+  double timestamp;
+  uint32_t flags;
+  float orientation[4];
+  float position[3];
+  float angularVelocity[3];
+  float angularAcceleration[3];
+  float linearVelocity[3];
+  float linearAcceleration[3];
+
+  void Clear() {
+    memset(this, 0, sizeof(VRHMDSensorState));
+  }
+};
+
+/* A pure data struct that can be used to see if
+ * the configuration of one HMDInfo matches another; for rendering purposes,
+ * really asking "can the rendering details of this one be used for the other"
+ */
+struct VRHMDConfiguration {
+  VRHMDConfiguration() : hmdType(VRHMDType::NumHMDTypes) {}
+
+  bool operator==(const VRHMDConfiguration& other) const {
+    return hmdType == other.hmdType &&
+      value == other.value &&
+      fov[0] == other.fov[0] &&
+      fov[1] == other.fov[1];
+  }
+
+  bool operator!=(const VRHMDConfiguration& other) const {
+    return hmdType != other.hmdType ||
+      value != other.value ||
+      fov[0] != other.fov[0] ||
+      fov[1] != other.fov[1];
+  }
+
+  bool IsValid() const {
+    return hmdType != VRHMDType::NumHMDTypes;
+  }
+
+  VRHMDType hmdType;
+  uint32_t value;
+  VRFieldOfView fov[2];
+};
+
+class VRHMDInfo {
+public:
+  enum Eye {
+    Eye_Left,
+    Eye_Right,
+    NumEyes
+  };
+
+  enum StateValidFlags {
+    State_Position = 1 << 1,
+    State_Orientation = 1 << 2
+  };
+
+public:
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VRHMDInfo)
+
+  VRHMDType GetType() const { return mType; }
+
+  virtual const VRFieldOfView& GetRecommendedEyeFOV(uint32_t whichEye) { return mRecommendedEyeFOV[whichEye]; }
+  virtual const VRFieldOfView& GetMaximumEyeFOV(uint32_t whichEye) { return mMaximumEyeFOV[whichEye]; }
+
+  const VRHMDConfiguration& GetConfiguration() const { return mConfiguration; }
+
+  /* set the FOV for this HMD unit; this triggers a computation of all the remaining bits.  Returns false if it fails */
+  virtual bool SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight,
+                      double zNear, double zFar) = 0;
+  const VRFieldOfView& GetEyeFOV(uint32_t whichEye)  { return mEyeFOV[whichEye]; }
+
+  /* Suggested resolution for rendering a single eye.
+   * Assumption is that left/right rendering will be 2x of this size.
+   * XXX fix this for vertical displays
+   */
+  const IntSize& SuggestedEyeResolution() const { return mEyeResolution; }
+  const Point3D& GetEyeTranslation(uint32_t whichEye) const { return mEyeTranslation[whichEye]; }
+  const Matrix4x4& GetEyeProjectionMatrix(uint32_t whichEye) const { return mEyeProjectionMatrix[whichEye]; }
+
+  virtual uint32_t GetSupportedSensorStateBits() { return mSupportedSensorBits; }
+  virtual bool StartSensorTracking() = 0;
+  virtual VRHMDSensorState GetSensorState(double timeOffset = 0.0) = 0;
+  virtual void StopSensorTracking() = 0;
+
+  virtual void ZeroSensor() = 0;
+
+  virtual void FillDistortionConstants(uint32_t whichEye,
+                                       const IntSize& textureSize, // the full size of the texture
+                                       const IntRect& eyeViewport, // the viewport within the texture for the current eye
+                                       const Size& destViewport,   // the size of the destination viewport
+                                       const Rect& destRect,       // the rectangle within the dest viewport that this should be rendered
+                                       VRDistortionConstants& values) = 0;
+
+  virtual const VRDistortionMesh& GetDistortionMesh(uint32_t whichEye) const { return mDistortionMesh[whichEye]; }
+
+  // The nsIScreen that represents this device
+  virtual nsIScreen* GetScreen() { return mScreen; }
+
+protected:
+  explicit VRHMDInfo(VRHMDType aType) : mType(aType) { MOZ_COUNT_CTOR(VRHMDInfo); }
+  virtual ~VRHMDInfo() { MOZ_COUNT_DTOR(VRHMDInfo); }
+
+  VRHMDType mType;
+  VRHMDConfiguration mConfiguration;
+
+  VRFieldOfView mEyeFOV[NumEyes];
+  IntSize mEyeResolution;
+  Point3D mEyeTranslation[NumEyes];
+  Matrix4x4 mEyeProjectionMatrix[NumEyes];
+  VRDistortionMesh mDistortionMesh[NumEyes];
+  uint32_t mSupportedSensorBits;
+
+  VRFieldOfView mRecommendedEyeFOV[NumEyes];
+  VRFieldOfView mMaximumEyeFOV[NumEyes];
+
+  nsCOMPtr<nsIScreen> mScreen;
+};
+
+class VRHMDManagerOculusImpl;
+class VRHMDManagerOculus {
+  static VRHMDManagerOculusImpl *mImpl;
+public:
+  static bool PlatformInit();
+  static bool Init();
+  static void Destroy();
+  static void GetOculusHMDs(nsTArray<nsRefPtr<VRHMDInfo> >& aHMDResult);
+};
+
+} // namespace gfx
+} // namespace mozilla
+
+#endif /* GFX_VR_H */
new file mode 100644
--- /dev/null
+++ b/gfx/vr/moz.build
@@ -0,0 +1,31 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+EXPORTS += [
+    'gfxVR.h',
+]
+
+LOCAL_INCLUDES += [
+    '/gfx/thebes',
+]
+
+UNIFIED_SOURCES += [
+    'gfxVR.cpp',
+]
+
+CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
+CXXFLAGS += CONFIG['TK_CFLAGS']
+CFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
+CFLAGS += CONFIG['TK_CFLAGS']
+
+FAIL_ON_WARNINGS = not CONFIG['_MSC_VER']
+
+MSVC_ENABLE_PGO = True
+
+include('/ipc/chromium/chromium-config.mozbuild')
+
+FINAL_LIBRARY = 'xul'
+
new file mode 100644
--- /dev/null
+++ b/gfx/vr/ovr_capi_dynamic.h
@@ -0,0 +1,228 @@
+/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
+/* 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/. */
+
+/* This file contains just the needed struct definitions for
+ * interacting with the Oculus VR C API, without needing to #include
+ * OVR_CAPI.h directly.  Note that it uses the same type names as the
+ * CAPI, and cannot be #included at the same time as OVR_CAPI.h.  It
+ * does not include the entire C API, just want's needed.
+ */
+
+#ifdef OVR_CAPI_h
+#warning OVR_CAPI.h included before ovr_capi_dynamic.h, skpping this
+#define mozilla_ovr_capi_dynamic_h_
+#endif
+
+#ifndef mozilla_ovr_capi_dynamic_h_
+#define mozilla_ovr_capi_dynamic_h_
+
+#define OVR_CAPI_LIMITED_MOZILLA 1
+
+#ifdef __cplusplus 
+extern "C" {
+#endif
+
+typedef char ovrBool;
+typedef struct { int x, y; } ovrVector2i;
+typedef struct { int w, h; } ovrSizei;
+typedef struct { ovrVector2i Pos; ovrSizei Size; } ovrRecti;
+typedef struct { float x, y, z, w; } ovrQuatf;
+typedef struct { float x, y; } ovrVector2f;
+typedef struct { float x, y, z; } ovrVector3f;
+typedef struct { float M[4][4]; } ovrMatrix4f;
+
+typedef struct {
+  ovrQuatf Orientation;
+  ovrVector3f Position;
+} ovrPosef;
+
+typedef struct {
+  ovrPosef ThePose;
+  ovrVector3f AngularVelocity;
+  ovrVector3f LinearVelocity;
+  ovrVector3f AngularAcceleration;
+  ovrVector3f LinearAcceleration;
+  double TimeInSeconds;
+} ovrPoseStatef;
+
+typedef struct {
+  float UpTan;
+  float DownTan;
+  float LeftTan;
+  float RightTan;
+} ovrFovPort;
+
+typedef enum {
+  ovrHmd_None             = 0,    
+  ovrHmd_DK1              = 3,
+  ovrHmd_DKHD             = 4,
+  ovrHmd_DK2              = 6,
+  ovrHmd_Other
+} ovrHmdType;
+
+typedef enum {
+  ovrHmdCap_Present           = 0x0001,
+  ovrHmdCap_Available         = 0x0002,
+  ovrHmdCap_Captured          = 0x0004,
+  ovrHmdCap_ExtendDesktop     = 0x0008,
+  ovrHmdCap_DisplayOff        = 0x0040,
+  ovrHmdCap_LowPersistence    = 0x0080,
+  ovrHmdCap_DynamicPrediction = 0x0200,
+  ovrHmdCap_NoVSync           = 0x1000,
+  ovrHmdCap_NoMirrorToWindow  = 0x2000
+} ovrHmdCapBits;
+
+typedef enum
+{
+  ovrTrackingCap_Orientation      = 0x0010,
+  ovrTrackingCap_MagYawCorrection = 0x0020,
+  ovrTrackingCap_Position         = 0x0040,
+  ovrTrackingCap_Idle             = 0x0100
+} ovrTrackingCaps;
+
+typedef enum {
+  ovrDistortionCap_Chromatic = 0x01,
+  ovrDistortionCap_TimeWarp  = 0x02,
+  ovrDistortionCap_Vignette  = 0x08,
+  ovrDistortionCap_NoRestore = 0x10,
+  ovrDistortionCap_FlipInput = 0x20,
+  ovrDistortionCap_SRGB      = 0x40,
+  ovrDistortionCap_Overdrive = 0x80,
+  ovrDistortionCap_ProfileNoTimewarpSpinWaits = 0x10000
+} ovrDistortionCaps;
+
+typedef enum {
+  ovrEye_Left  = 0,
+  ovrEye_Right = 1,
+  ovrEye_Count = 2
+} ovrEyeType;
+
+typedef struct ovrHmdDesc_ {
+  void* Handle;
+  ovrHmdType  Type;
+  const char* ProductName;    
+  const char* Manufacturer;
+  short VendorId;
+  short ProductId;
+  char SerialNumber[24];
+  short FirmwareMajor;
+  short FirmwareMinor;
+  float CameraFrustumHFovInRadians;
+  float CameraFrustumVFovInRadians;
+  float CameraFrustumNearZInMeters;
+  float CameraFrustumFarZInMeters;
+
+  unsigned int HmdCaps;
+  unsigned int TrackingCaps;
+  unsigned int DistortionCaps;
+
+  ovrFovPort  DefaultEyeFov[ovrEye_Count];
+  ovrFovPort  MaxEyeFov[ovrEye_Count];
+  ovrEyeType  EyeRenderOrder[ovrEye_Count];
+
+  ovrSizei    Resolution;
+  ovrVector2i WindowsPos;
+
+  const char* DisplayDeviceName;
+  int         DisplayId;
+} ovrHmdDesc;
+
+typedef const ovrHmdDesc* ovrHmd;
+
+typedef enum {
+  ovrStatus_OrientationTracked    = 0x0001,
+  ovrStatus_PositionTracked       = 0x0002,
+  ovrStatus_CameraPoseTracked     = 0x0004,
+  ovrStatus_PositionConnected     = 0x0020,
+  ovrStatus_HmdConnected          = 0x0080
+} ovrStatusBits;
+
+typedef struct ovrSensorData_ {
+  ovrVector3f    Accelerometer;
+  ovrVector3f    Gyro;
+  ovrVector3f    Magnetometer;
+  float          Temperature;
+  float          TimeInSeconds;
+} ovrSensorData;
+
+
+typedef struct ovrTrackingState_ {
+  ovrPoseStatef HeadPose;
+  ovrPosef CameraPose;
+  ovrPosef LeveledCameraPose;
+  ovrSensorData RawSensorData;
+  unsigned int StatusFlags;
+  double LastVisionProcessingTime;
+  double LastVisionFrameLatency;
+  uint32_t LastCameraFrameCounter;
+} ovrTrackingState;
+
+typedef struct ovrFrameTiming_ {
+  float DeltaSeconds;
+  double ThisFrameSeconds;
+  double TimewarpPointSeconds;
+  double NextFrameSeconds;
+  double ScanoutMidpointSeconds;
+  double EyeScanoutSeconds[2];    
+} ovrFrameTiming;
+
+typedef struct ovrEyeRenderDesc_ {
+  ovrEyeType  Eye;        
+  ovrFovPort  Fov;
+  ovrRecti DistortedViewport;
+  ovrVector2f PixelsPerTanAngleAtCenter;
+  ovrVector3f ViewAdjust;
+} ovrEyeRenderDesc;
+
+typedef struct ovrDistortionVertex_ {
+  ovrVector2f ScreenPosNDC;
+  float       TimeWarpFactor;
+  float       VignetteFactor;
+  ovrVector2f TanEyeAnglesR;
+  ovrVector2f TanEyeAnglesG;
+  ovrVector2f TanEyeAnglesB;    
+} ovrDistortionVertex;
+
+typedef struct ovrDistortionMesh_ {
+  ovrDistortionVertex* pVertexData;
+  unsigned short*      pIndexData;
+  unsigned int         VertexCount;
+  unsigned int         IndexCount;
+} ovrDistortionMesh;
+
+typedef ovrBool (*pfn_ovr_Initialize)();
+typedef void (*pfn_ovr_Shutdown)();
+typedef int (*pfn_ovrHmd_Detect)();
+typedef ovrHmd (*pfn_ovrHmd_Create)(int index);
+typedef void (*pfn_ovrHmd_Destroy)(ovrHmd hmd);
+typedef ovrHmd (*pfn_ovrHmd_CreateDebug)(ovrHmdType type);
+typedef const char* (*pfn_ovrHmd_GetLastError)(ovrHmd hmd);
+typedef ovrBool (*pfn_ovrHmd_AttachToWindow)(ovrHmd hmd, void* window, const ovrRecti* destMirrorRect, const ovrRecti* sourceRenderTargetRect);
+typedef unsigned int (*pfn_ovrHmd_GetEnabledCaps)(ovrHmd hmd);
+typedef void (*pfn_ovrHmd_SetEnabledCaps)(ovrHmd hmd, unsigned int hmdCaps);
+typedef ovrBool (*pfn_ovrHmd_ConfigureTracking)(ovrHmd hmd, unsigned int supportedTrackingCaps, unsigned int requiredTrackingCaps); 
+typedef void (*pfn_ovrHmd_RecenterPose)(ovrHmd hmd);
+typedef ovrTrackingState (*pfn_ovrHmd_GetTrackingState)(ovrHmd hmd, double absTime);
+typedef ovrSizei (*pfn_ovrHmd_GetFovTextureSize)(ovrHmd hmd, ovrEyeType eye, ovrFovPort fov, float pixelsPerDisplayPixel);
+typedef ovrEyeRenderDesc (*pfn_ovrHmd_GetRenderDesc)(ovrHmd hmd, ovrEyeType eyeType, ovrFovPort fov);
+typedef ovrBool (*pfn_ovrHmd_CreateDistortionMesh)(ovrHmd hmd, ovrEyeType eyeType, ovrFovPort fov, unsigned int distortionCaps, ovrDistortionMesh *meshData);
+typedef void (*pfn_ovrHmd_DestroyDistortionMesh)(ovrDistortionMesh* meshData);
+typedef void (*pfn_ovrHmd_GetRenderScaleAndOffset)(ovrFovPort fov, ovrSizei textureSize, ovrRecti renderViewport, ovrVector2f uvScaleOffsetOut[2]);
+typedef ovrFrameTiming (*pfn_ovrHmd_GetFrameTiming)(ovrHmd hmd, unsigned int frameIndex);
+typedef ovrFrameTiming (*pfn_ovrHmd_BeginFrameTiming)(ovrHmd hmd, unsigned int frameIndex);
+typedef void (*pfn_ovrHmd_EndFrameTiming)(ovrHmd hmd);
+typedef void (*pfn_ovrHmd_ResetFrameTiming)(ovrHmd hmd, unsigned int frameIndex, bool vsync);
+typedef void (*pfn_ovrHmd_GetEyePoses)(ovrHmd hmd, unsigned int frameIndex, ovrVector3f hmdToEyeViewOffset[2], ovrPosef outEyePoses[2], ovrTrackingState* outHmdTrackingState);
+typedef ovrPosef (*pfn_ovrHmd_GetHmdPosePerEye)(ovrHmd hmd, ovrEyeType eye);
+typedef void (*pfn_ovrHmd_GetEyeTimewarpMatrices)(ovrHmd hmd, ovrEyeType eye, ovrPosef renderPose, ovrMatrix4f twmOut[2]);
+typedef ovrMatrix4f (*pfn_ovrMatrix4f_Projection) (ovrFovPort fov, float znear, float zfar, ovrBool rightHanded );
+typedef ovrMatrix4f (*pfn_ovrMatrix4f_OrthoSubProjection) (ovrFovPort fov, ovrVector2f orthoScale, float orthoDistance, float eyeViewAdjustX);
+typedef double (*pfn_ovr_GetTimeInSeconds)();
+
+#ifdef __cplusplus 
+}
+#endif
+
+#endif /* mozilla_ovr_capi_dynamic_h_ */