Bug 1392216 - Part 4: Move drawing black layer commaneds to Compositor thread when stopping presentation; r?kip
MozReview-Commit-ID: 6YmQ9DYp79O
--- a/gfx/vr/VRDisplayHost.cpp
+++ b/gfx/vr/VRDisplayHost.cpp
@@ -347,17 +347,17 @@ VRDisplayHost::SubmitFrame(VRLayerParent
* fallback "watchdog" code in VRDisplayHost::NotifyVSync() will cause
* frames to continue at a lower refresh rate until frame submission
* succeeds again.
*/
VRManager* vm = VRManager::Get();
MessageLoop* loop = VRListenerThreadHolder::Loop();
loop->PostTask(NewRunnableMethod<const uint32_t>(
- "gfx::VRLayerParent::SubmitFrame",
+ "gfx::VRManager::NotifyVRVsync",
vm, &VRManager::NotifyVRVsync, mDisplayInfo.mDisplayID
));
#endif
}
bool
VRDisplayHost::CheckClearDisplayInfoDirty()
{
--- a/gfx/vr/gfxVROculus.cpp
+++ b/gfx/vr/gfxVROculus.cpp
@@ -13,16 +13,17 @@
#include "prlink.h"
#include "prenv.h"
#include "gfxPrefs.h"
#include "nsString.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/Preferences.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/gfx/DeviceManagerDx.h"
+#include "mozilla/layers/CompositorThread.h"
#include "ipc/VRLayerParent.h"
#include "mozilla/gfx/Quaternion.h"
#include <d3d11.h>
#include "CompositorD3D11.h"
#include "TextureD3D11.h"
@@ -193,16 +194,17 @@ FromFovPort(const ovrFovPort& aFOV)
} // namespace
VROculusSession::VROculusSession()
: mOvrLib(nullptr)
, mSession(nullptr)
, mInitFlags((ovrInitFlags)0)
, mTextureSet(nullptr)
, mPresenting(false)
+ , mDrawBlack(false)
{
}
ovrSession
VROculusSession::Get()
{
MOZ_ASSERT(mSession);
return mSession;
@@ -316,18 +318,24 @@ VROculusSession::StopLib()
{
if (mInitFlags) {
ovr_Shutdown();
mInitFlags = (ovrInitFlags)0;
}
}
void
-VROculusSession::Refresh()
+VROculusSession::Refresh(bool aForceRefresh)
{
+ // We are waiting for drawing the black layer command for
+ // Compositor thread. Ignore Refresh() calls from other threads.
+ if (mDrawBlack && !aForceRefresh) {
+ return;
+ }
+
ovrInitFlags flags = (ovrInitFlags)(ovrInit_RequestVersion | ovrInit_MixedRendering);
bool bInvisible = true;
if (mPresenting) {
bInvisible = false;
} else if (!mLastPresentationEnd.IsNull()) {
TimeDuration duration = TimeStamp::Now() - mLastPresentationEnd;
TimeDuration timeout = TimeDuration::FromMilliseconds(gfxPrefs::VROculusPresentTimeout());
if (timeout > TimeDuration(0) && duration < timeout) {
@@ -335,21 +343,35 @@ VROculusSession::Refresh()
// the end of a VR presentation. Waiting for the configured duraction
// ensures that the user will not drop to Oculus Home during VR link
// traversal.
bInvisible = false;
// While we are waiting for either the timeout or a new presentation,
// fill the HMD with black / no layers.
if (mSession && mTextureSet) {
+ if (!aForceRefresh) {
+ // ovr_SubmitFrame is only allowed been run at Compositor thread,
+ // 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;
+ }
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;
}
}
}
if (bInvisible) {
flags = (ovrInitFlags)(flags | ovrInit_Invisible);
}
if (mInitFlags != flags) {
--- a/gfx/vr/gfxVROculus.h
+++ b/gfx/vr/gfxVROculus.h
@@ -35,17 +35,17 @@ enum class OculusControllerAxisType : ui
};
class VROculusSession
{
NS_INLINE_DECL_REFCOUNTING(VROculusSession);
friend class VRDisplayOculus;
public:
VROculusSession();
- void Refresh();
+ void Refresh(bool aForceRefresh = false);
bool IsTrackingReady() const;
bool IsRenderReady() const;
ovrSession Get();
void StartPresentation(const IntSize& aSize);
void StopPresentation();
void StopTracking();
bool IsQuitTimeoutActive();
already_AddRefed<layers::CompositingRenderTargetD3D11> GetNextRenderTarget();
@@ -60,16 +60,17 @@ private:
IntSize mPresentationSize;
RefPtr<ID3D11Device> mDevice;
// The timestamp of the last time Oculus set ShouldQuit to true.
TimeStamp mLastShouldQuit;
// The timestamp of the last ending presentation
TimeStamp mLastPresentationEnd;
VRTelemetry mTelemetry;
bool mPresenting;
+ bool mDrawBlack;
~VROculusSession();
void Uninitialize(bool aUnloadLib);
bool Initialize(ovrInitFlags aFlags);
bool LoadOvrLib();
void UnloadOvrLib();
bool StartSession();
void StopSession();