Bug 1406327 - Part 3: VRSystemManager for multi-threads; r?kip draft
authorDaosheng Mu <daoshengmu@gmail.com>
Thu, 26 Oct 2017 17:45:44 +0800
changeset 694066 6cfe3420d920c3dd5015e751acdeeadde29cefd9
parent 694065 eb8ce4aa9017d162567303a57b71d9c5a140b574
child 694067 6cfba4678a8824d89e89f2e3e357d58633bf81ee
push id88034
push userbmo:dmu@mozilla.com
push dateTue, 07 Nov 2017 10:40:18 +0000
reviewerskip
bugs1406327
milestone58.0a1
Bug 1406327 - Part 3: VRSystemManager for multi-threads; r?kip MozReview-Commit-ID: 4bE5hruFcT2
gfx/vr/VRDisplayHost.cpp
gfx/vr/gfxVROculus.cpp
gfx/vr/gfxVROculus.h
gfx/vr/gfxVROpenVR.cpp
gfx/vr/gfxVRPuppet.cpp
--- a/gfx/vr/VRDisplayHost.cpp
+++ b/gfx/vr/VRDisplayHost.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "VRDisplayHost.h"
 #include "gfxPrefs.h"
 #include "gfxVR.h"
 #include "ipc/VRLayerParent.h"
 #include "mozilla/layers/TextureHost.h"
 #include "mozilla/dom/GamepadBinding.h" // For GamepadMappingType
+#include "mozilla/layers/CompositorThread.h"
 #include "VRThread.h"
 
 #if defined(XP_WIN)
 
 #include <d3d11.h>
 #include "gfxWindowsPlatform.h"
 #include "../layers/d3d11/CompositorD3D11.h"
 #include "mozilla/gfx/DeviceManagerDx.h"
@@ -255,16 +256,17 @@ void
 VRDisplayHost::SubmitFrame(VRLayerParent* aLayer,
                            const layers::SurfaceDescriptor &aTexture,
                            uint64_t aFrameId,
                            const gfx::Rect& aLeftEyeRect,
                            const gfx::Rect& aRightEyeRect)
 {
   AUTO_PROFILER_TRACING("VR", "SubmitFrameAtVRDisplayHost");
 
+  MOZ_ASSERT(NS_IsInCompositorThread());
   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;
--- a/gfx/vr/gfxVROculus.cpp
+++ b/gfx/vr/gfxVROculus.cpp
@@ -359,19 +359,20 @@ VROculusSession::Refresh(bool aForceRefr
           // so we post this task to Compositor thread and let it determine
           // if reloading library.
           mDrawBlack = true;
           MessageLoop* loop = layers::CompositorThreadHolder::Loop();
           loop->PostTask(NewRunnableMethod<bool>(
             "gfx::VROculusSession::Refresh",
             this,
             &VROculusSession::Refresh, true));
-
           return;
         }
+        // Calling ovr_SubmitFrame() must be at Compositor thread.
+        MOZ_ASSERT(NS_IsInCompositorThread());
         ovrLayerEyeFov layer;
         memset(&layer, 0, sizeof(layer));
         layer.Header.Type = ovrLayerType_Disabled;
         ovrLayerHeader *layers = &layer.Header;
         ovr_SubmitFrame(mSession, 0, nullptr, &layers, 1);
         mDrawBlack = false;
       }
     }
--- a/gfx/vr/gfxVROculus.h
+++ b/gfx/vr/gfxVROculus.h
@@ -32,17 +32,17 @@ namespace impl {
 enum class OculusControllerAxisType : uint16_t {
   ThumbstickXAxis,
   ThumbstickYAxis,
   NumVRControllerAxisType
 };
 
 class VROculusSession
 {
-  NS_INLINE_DECL_REFCOUNTING(VROculusSession);
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VROculusSession);
   friend class VRDisplayOculus;
 public:
   VROculusSession();
   void Refresh(bool aForceRefresh = false);
   bool IsTrackingReady() const;
   bool IsRenderReady() const;
   ovrSession Get();
   void StartPresentation(const IntSize& aSize);
--- a/gfx/vr/gfxVROpenVR.cpp
+++ b/gfx/vr/gfxVROpenVR.cpp
@@ -631,16 +631,23 @@ VRSystemManagerOpenVR::Shutdown()
   }
   RemoveControllers();
   mVRSystem = nullptr;
 }
 
 bool
 VRSystemManagerOpenVR::GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult)
 {
+  // When running VR tests on local machines which have SteamVR runtime.
+  // VR_IsHmdPresent() would have chance to be true. Then, it makes us can't
+  // get the VRPuppet display.
+  if (gfxPrefs::VRPuppetEnabled()) {
+    return false;
+  }
+
   if (!::vr::VR_IsHmdPresent() ||
       (mOpenVRHMD && !mOpenVRHMD->GetIsHmdPresent())) {
     // OpenVR runtime could be quit accidentally,
     // and we make it re-initialize.
     mOpenVRHMD = nullptr;
     mVRSystem = nullptr;
   } else if (mOpenVRHMD == nullptr) {
     ::vr::HmdError err;
--- a/gfx/vr/gfxVRPuppet.cpp
+++ b/gfx/vr/gfxVRPuppet.cpp
@@ -9,21 +9,21 @@
 #include "TextureD3D11.h"
 #include "mozilla/gfx/DeviceManagerDx.h"
 #elif defined(XP_MACOSX)
 #include "mozilla/gfx/MacIOSurface.h"
 #endif
 
 #include "mozilla/Base64.h"
 #include "mozilla/gfx/DataSurfaceHelpers.h"
+#include "mozilla/layers/CompositorThread.h"
 #include "gfxPrefs.h"
 #include "gfxUtils.h"
 #include "gfxVRPuppet.h"
 #include "VRManager.h"
-#include "VRThread.h"
 
 #include "mozilla/dom/GamepadEventTypes.h"
 #include "mozilla/dom/GamepadBinding.h"
 
 // See CompositorD3D11Shaders.h
 namespace mozilla {
 namespace layers {
 struct ShaderBytes { const void* mData; size_t mLength; };
@@ -382,21 +382,17 @@ VRDisplayPuppet::SubmitFrame(ID3D11Textu
       nsCString rawString(Substring(srcData, mapInfo.RowPitch * desc.Height));
 
       if (Base64Encode(rawString, result.mBase64Image) != NS_OK) {
         MOZ_ASSERT(false, "Failed to encode base64 images.");
       }
       mContext->Unmap(mappedTexture, 0);
       // Dispatch the base64 encoded string to the DOM side. Then, it will be decoded
       // and convert to a PNG image there.
-      MessageLoop* loop = VRListenerThreadHolder::Loop();
-      loop->PostTask(NewRunnableMethod<const uint32_t, VRSubmitFrameResultInfo>(
-        "VRManager::DispatchSubmitFrameResult",
-        vm, &VRManager::DispatchSubmitFrameResult, mDisplayInfo.mDisplayID, result
-      ));
+      vm->DispatchSubmitFrameResult(mDisplayInfo.mDisplayID, result);
       break;
     }
     case 2:
     {
       // The VR compositor sumbmit frame to the screen window,
       // the current coordinate is at (0, 0, width, height).
       Matrix viewMatrix = Matrix::Translation(-1.0, 1.0);
       viewMatrix.PreScale(2.0f / float(aSize.width), 2.0f / float(aSize.height));
@@ -527,21 +523,17 @@ VRDisplayPuppet::SubmitFrame(MacIOSurfac
         }
         dataSurf->Unmap();
 
         if (Base64Encode(rawString, result.mBase64Image) != NS_OK) {
           MOZ_ASSERT(false, "Failed to encode base64 images.");
         }
         // Dispatch the base64 encoded string to the DOM side. Then, it will be decoded
         // and convert to a PNG image there.
-        MessageLoop* loop = VRListenerThreadHolder::Loop();
-        loop->PostTask(NewRunnableMethod<const uint32_t, VRSubmitFrameResultInfo>(
-          "VRManager::DispatchSubmitFrameResult",
-          vm, &VRManager::DispatchSubmitFrameResult, mDisplayInfo.mDisplayID, result
-        ));
+        vm->DispatchSubmitFrameResult(mDisplayInfo.mDisplayID, result);
       }
       break;
     }
     case 2:
     {
       MOZ_ASSERT(false, "No support for showing VR frames on MacOSX yet.");
       break;
     }