Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Commit

Permalink
Correct ExternaVR shutdown. Fixes #538
Browse files Browse the repository at this point in the history
  • Loading branch information
MortimerGoro committed Sep 21, 2018
1 parent 34ab2af commit 133fdf7
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 20 deletions.
31 changes: 23 additions & 8 deletions app/src/common/shared/org/mozilla/vrbrowser/VRBrowserActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -180,12 +180,9 @@ protected void onStop() {
@Override
protected void onPause() {
if (mIsPresentingImmersive) {
queueRunnable(new Runnable() {
@Override
public void run() {
exitImmersiveNative();
}
});
// This needs to be sync to ensure that WebVR is correctly paused.
// Also prevents a deadlock in onDestroy when the BrowserWidget is released.
exitImmersiveSync();
}
mAudioEngine.pauseEngine();
SessionStore.get().setActive(false);
Expand Down Expand Up @@ -217,8 +214,6 @@ protected void onDestroy() {

SessionStore.get().clearListeners();
super.onDestroy();
// FIXME: HACK TO KILL GECKO BETWEEN RUNS.
android.os.Process.killProcess(android.os.Process.myPid());
}

@Override
Expand Down Expand Up @@ -277,6 +272,26 @@ public void run() {
}
}

private void exitImmersiveSync() {
Runnable exitImmersive = new Runnable() {
@Override
public void run() {
exitImmersiveNative();
synchronized(this) {
this.notifyAll();
}
}
};
synchronized (exitImmersive) {
queueRunnable(exitImmersive);
try {
exitImmersive.wait();
} catch (InterruptedException e) {
Log.e(LOGTAG, "Waiting for exit immersive onPause interrupted");
}
}
}

@Keep
@SuppressWarnings("unused")
void dispatchCreateWidget(final int aHandle, final SurfaceTexture aTexture, final int aWidth, final int aHeight) {
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/cpp/BrowserWorld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,9 @@ void
BrowserWorld::ShutdownJava() {
ASSERT_ON_RENDER_THREAD();
VRB_LOG("BrowserWorld::ShutdownJava");
if (m.externalVR) {
m.externalVR->Shutdown();
}
GeckoSurfaceTexture::ShutdownJava();
VRBrowser::ShutdownJava();
if (m.env) {
Expand Down
44 changes: 33 additions & 11 deletions app/src/main/cpp/ExternalVR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ class Wait {
namespace crow {

struct ExternalVR::State {
static ExternalVR::State * sState;
mozilla::gfx::VRExternalShmem data;
mozilla::gfx::VRSystemState system;
mozilla::gfx::VRBrowserState browser;
Expand All @@ -132,16 +133,25 @@ struct ExternalVR::State {
bool waitingForExit;

State() : deviceCapabilities(0) {
memset(&data, 0, sizeof(mozilla::gfx::VRExternalShmem));
memset(&system, 0, sizeof(mozilla::gfx::VRSystemState));
memset(&browser, 0, sizeof(mozilla::gfx::VRBrowserState));
data.version = mozilla::gfx::kVRExternalVersion;
data.size = sizeof(mozilla::gfx::VRExternalShmem);
pthread_mutex_init(&data.systemMutex, nullptr);
pthread_mutex_init(&data.browserMutex, nullptr);
pthread_cond_init(&data.systemCond, nullptr);
pthread_cond_init(&data.browserCond, nullptr);
}

~State() {
pthread_mutex_destroy(&(data.systemMutex));
pthread_mutex_destroy(&(data.browserMutex));
pthread_cond_destroy(&(data.systemCond));
pthread_cond_destroy(&(data.browserCond));
}

void Reset() {
memset(&data, 0, sizeof(mozilla::gfx::VRExternalShmem));
memset(&system, 0, sizeof(mozilla::gfx::VRSystemState));
memset(&browser, 0, sizeof(mozilla::gfx::VRBrowserState));
data.version = mozilla::gfx::kVRExternalVersion;
data.size = sizeof(mozilla::gfx::VRExternalShmem);
system.displayState.mIsConnected = true;
system.displayState.mIsMounted = true;
const vrb::Matrix identity = vrb::Matrix::Identity();
Expand All @@ -153,11 +163,12 @@ struct ExternalVR::State {
waitingForExit = false;
}

~State() {
pthread_mutex_destroy(&(data.systemMutex));
pthread_mutex_destroy(&(data.browserMutex));
pthread_cond_destroy(&(data.systemCond));
pthread_cond_destroy(&(data.browserCond));
static ExternalVR::State& Instance() {
if (!sState) {
sState = new State();
}

return *sState;
}

void PullBrowserStateWhileLocked() {
Expand All @@ -179,6 +190,8 @@ struct ExternalVR::State {
}
};

ExternalVR::State * ExternalVR::State::sState = nullptr;

ExternalVRPtr
ExternalVR::Create() {
return std::make_shared<vrb::ConcreteClass<ExternalVR, ExternalVR::State> >();
Expand Down Expand Up @@ -420,7 +433,16 @@ ExternalVR::StopPresenting() {
m.waitingForExit = true;
}

ExternalVR::ExternalVR(State& aState) : m(aState) {
void
ExternalVR::Shutdown() {
m.system.displayState.shutdown = true;
m.system.displayState.mSuppressFrames = true;
PushSystemState();
}


ExternalVR::ExternalVR(State& aState) : m(State::Instance()) {
m.Reset();
PushSystemState();
}

Expand Down
3 changes: 2 additions & 1 deletion app/src/main/cpp/ExternalVR.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class ExternalVR : public ImmersiveDisplay {
const double aBottomDegrees) override;
void SetEyeOffset(const device::Eye aEye, const float aX, const float aY, const float aZ) override;
void SetEyeResolution(const int32_t aX, const int32_t aY) override;
void CompleteEnumeration() override;
// ExternalVR interface
void PushSystemState();
void PullBrowserState();
Expand All @@ -50,7 +51,7 @@ class ExternalVR : public ImmersiveDisplay {
bool WaitFrameResult();
void GetFrameResult(int32_t& aSurfaceHandle, device::EyeRect& aLeftEye, device::EyeRect& aRightEye) const;
void StopPresenting();
void CompleteEnumeration() override;
void Shutdown();
protected:
struct State;
ExternalVR(State& aState);
Expand Down

0 comments on commit 133fdf7

Please sign in to comment.