Bug 1413362 - part 1: Add GeckoVRManager to support GVR WebVR implementation on Android r=jchen,snorp
☠☠ backed out by 0b32504fcef2 ☠ ☠
authorRandall Barker <rbarker@mozilla.com>
Tue, 31 Oct 2017 16:40:41 -0700
changeset 443750 653c66220a5f3c59f2119bb7cea3e722fee6c47c
parent 443749 996440f4c25776f30092caa38051e25d6008faca
child 443751 2d9da0d19d04c54d04f87f8ca5d13cc81f3ba048
push id1618
push userCallek@gmail.com
push dateThu, 11 Jan 2018 17:45:48 +0000
treeherdermozilla-release@882ca853e05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjchen, snorp
bugs1413362
milestone58.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 1413362 - part 1: Add GeckoVRManager to support GVR WebVR implementation on Android r=jchen,snorp MozReview-Commit-ID: C7XTF8N1W9a
mobile/android/base/moz.build
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoVRManager.java
widget/android/GeckoVRManager.h
widget/android/GeneratedJNINatives.h
widget/android/GeneratedJNIWrappers.cpp
widget/android/GeneratedJNIWrappers.h
widget/android/moz.build
widget/android/nsAppShell.cpp
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -384,16 +384,17 @@ gvjar.sources += [geckoview_source_dir +
     'GeckoProfile.java',
     'GeckoProfileDirectories.java',
     'GeckoScreenOrientation.java',
     'GeckoSharedPrefs.java',
     'GeckoThread.java',
     'GeckoView.java',
     'GeckoViewHandler.java',
     'GeckoViewSettings.java',
+    'GeckoVRManager.java',
     'gfx/BitmapUtils.java',
     'gfx/BufferedImage.java',
     'gfx/BufferedImageGLInfo.java',
     'gfx/DynamicToolbarAnimator.java',
     'gfx/FloatSize.java',
     'gfx/FullScreenState.java',
     'gfx/GeckoLayerClient.java',
     'gfx/GeckoSurface.java',
new file mode 100644
--- /dev/null
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoVRManager.java
@@ -0,0 +1,125 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * vim: ts=4 sw=4 expandtab:
+ * 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/. */
+
+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();
+
+    @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();
+    }
+
+    @WrapForJNI
+    /* package */ static void enableVRMode() {
+        if (!ThreadUtils.isOnUiThread()) {
+            ThreadUtils.postToUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    enableVRMode();
+                }
+            });
+            return;
+        }
+
+        if (mGVRDelegate == null) {
+            return;
+        }
+
+        mGVRDelegate.enableVRMode();
+    }
+
+    @WrapForJNI
+    /* package */ static void disableVRMode() {
+        if (!ThreadUtils.isOnUiThread()) {
+            ThreadUtils.postToUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    disableVRMode();
+                }
+            });
+            return;
+        }
+
+        if (mGVRDelegate == null) {
+            return;
+        }
+
+        mGVRDelegate.disableVRMode();
+    }
+}
new file mode 100644
--- /dev/null
+++ b/widget/android/GeckoVRManager.h
@@ -0,0 +1,82 @@
+/* -*- 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 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 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/GeneratedJNINatives.h
+++ b/widget/android/GeneratedJNINatives.h
@@ -253,16 +253,39 @@ const JNINativeMethod GeckoThread::Nativ
             ::template Wrap<&Impl::SpeculativeConnect>),
 
     mozilla::jni::MakeNativeMethod<GeckoThread::WaitOnGecko_t>(
             mozilla::jni::NativeStub<GeckoThread::WaitOnGecko_t, Impl>
             ::template Wrap<&Impl::WaitOnGecko>)
 };
 
 template<class Impl>
+class GeckoVRManager::Natives : public mozilla::jni::NativeImpl<GeckoVRManager, Impl>
+{
+public:
+    static const JNINativeMethod methods[3];
+};
+
+template<class Impl>
+const JNINativeMethod GeckoVRManager::Natives<Impl>::methods[] = {
+
+    mozilla::jni::MakeNativeMethod<GeckoVRManager::CleanupGVRNonPresentingContext_t>(
+            mozilla::jni::NativeStub<GeckoVRManager::CleanupGVRNonPresentingContext_t, Impl>
+            ::template Wrap<&Impl::CleanupGVRNonPresentingContext>),
+
+    mozilla::jni::MakeNativeMethod<GeckoVRManager::SetGVRPaused_t>(
+            mozilla::jni::NativeStub<GeckoVRManager::SetGVRPaused_t, Impl>
+            ::template Wrap<&Impl::SetGVRPaused>),
+
+    mozilla::jni::MakeNativeMethod<GeckoVRManager::SetGVRPresentingContext_t>(
+            mozilla::jni::NativeStub<GeckoVRManager::SetGVRPresentingContext_t, Impl>
+            ::template Wrap<&Impl::SetGVRPresentingContext>)
+};
+
+template<class Impl>
 class GeckoView::Window::Natives : public mozilla::jni::NativeImpl<Window, Impl>
 {
 public:
     static const JNINativeMethod methods[4];
 };
 
 template<class Impl>
 const JNINativeMethod GeckoView::Window::Natives<Impl>::methods[] = {
--- a/widget/android/GeneratedJNIWrappers.cpp
+++ b/widget/android/GeneratedJNIWrappers.cpp
@@ -945,16 +945,68 @@ auto GeckoThread::State::RESTARTING() ->
 constexpr char GeckoThread::State::RUNNING_t::name[];
 constexpr char GeckoThread::State::RUNNING_t::signature[];
 
 auto GeckoThread::State::RUNNING() -> State::LocalRef
 {
     return mozilla::jni::Field<RUNNING_t>::Get(State::Context(), nullptr);
 }
 
+const char GeckoVRManager::name[] =
+        "org/mozilla/gecko/GeckoVRManager";
+
+constexpr char GeckoVRManager::CleanupGVRNonPresentingContext_t::name[];
+constexpr char GeckoVRManager::CleanupGVRNonPresentingContext_t::signature[];
+
+constexpr char GeckoVRManager::CreateGVRNonPresentingContext_t::name[];
+constexpr char GeckoVRManager::CreateGVRNonPresentingContext_t::signature[];
+
+auto GeckoVRManager::CreateGVRNonPresentingContext() -> int64_t
+{
+    return mozilla::jni::Method<CreateGVRNonPresentingContext_t>::Call(GeckoVRManager::Context(), nullptr);
+}
+
+constexpr char GeckoVRManager::DestroyGVRNonPresentingContext_t::name[];
+constexpr char GeckoVRManager::DestroyGVRNonPresentingContext_t::signature[];
+
+auto GeckoVRManager::DestroyGVRNonPresentingContext() -> void
+{
+    return mozilla::jni::Method<DestroyGVRNonPresentingContext_t>::Call(GeckoVRManager::Context(), nullptr);
+}
+
+constexpr char GeckoVRManager::DisableVRMode_t::name[];
+constexpr char GeckoVRManager::DisableVRMode_t::signature[];
+
+auto GeckoVRManager::DisableVRMode() -> void
+{
+    return mozilla::jni::Method<DisableVRMode_t>::Call(GeckoVRManager::Context(), nullptr);
+}
+
+constexpr char GeckoVRManager::EnableVRMode_t::name[];
+constexpr char GeckoVRManager::EnableVRMode_t::signature[];
+
+auto GeckoVRManager::EnableVRMode() -> void
+{
+    return mozilla::jni::Method<EnableVRMode_t>::Call(GeckoVRManager::Context(), nullptr);
+}
+
+constexpr char GeckoVRManager::IsGVRPresent_t::name[];
+constexpr char GeckoVRManager::IsGVRPresent_t::signature[];
+
+auto GeckoVRManager::IsGVRPresent() -> bool
+{
+    return mozilla::jni::Method<IsGVRPresent_t>::Call(GeckoVRManager::Context(), nullptr);
+}
+
+constexpr char GeckoVRManager::SetGVRPaused_t::name[];
+constexpr char GeckoVRManager::SetGVRPaused_t::signature[];
+
+constexpr char GeckoVRManager::SetGVRPresentingContext_t::name[];
+constexpr char GeckoVRManager::SetGVRPresentingContext_t::signature[];
+
 const char GeckoView::name[] =
         "org/mozilla/gecko/GeckoView";
 
 const char GeckoView::State::name[] =
         "org/mozilla/gecko/GeckoView$State";
 
 constexpr char GeckoView::State::INITIAL_t::name[];
 constexpr char GeckoView::State::INITIAL_t::signature[];
--- a/widget/android/GeneratedJNIWrappers.h
+++ b/widget/android/GeneratedJNIWrappers.h
@@ -2823,16 +2823,177 @@ public:
 
     static auto RUNNING() -> State::LocalRef;
 
     static const mozilla::jni::CallingThread callingThread =
             mozilla::jni::CallingThread::ANY;
 
 };
 
+class GeckoVRManager : public mozilla::jni::ObjectBase<GeckoVRManager>
+{
+public:
+    static const char name[];
+
+    explicit GeckoVRManager(const Context& ctx) : ObjectBase<GeckoVRManager>(ctx) {}
+
+    struct CleanupGVRNonPresentingContext_t {
+        typedef GeckoVRManager Owner;
+        typedef void ReturnType;
+        typedef void SetterType;
+        typedef mozilla::jni::Args<> Args;
+        static constexpr char name[] = "cleanupGVRNonPresentingContext";
+        static constexpr char signature[] =
+                "()V";
+        static const bool isStatic = true;
+        static const mozilla::jni::ExceptionMode exceptionMode =
+                mozilla::jni::ExceptionMode::ABORT;
+        static const mozilla::jni::CallingThread callingThread =
+                mozilla::jni::CallingThread::UI;
+        static const mozilla::jni::DispatchTarget dispatchTarget =
+                mozilla::jni::DispatchTarget::CURRENT;
+    };
+
+    struct CreateGVRNonPresentingContext_t {
+        typedef GeckoVRManager Owner;
+        typedef int64_t ReturnType;
+        typedef int64_t SetterType;
+        typedef mozilla::jni::Args<> Args;
+        static constexpr char name[] = "createGVRNonPresentingContext";
+        static constexpr char signature[] =
+                "()J";
+        static const bool isStatic = true;
+        static const mozilla::jni::ExceptionMode exceptionMode =
+                mozilla::jni::ExceptionMode::ABORT;
+        static const mozilla::jni::CallingThread callingThread =
+                mozilla::jni::CallingThread::ANY;
+        static const mozilla::jni::DispatchTarget dispatchTarget =
+                mozilla::jni::DispatchTarget::CURRENT;
+    };
+
+    static auto CreateGVRNonPresentingContext() -> int64_t;
+
+    struct DestroyGVRNonPresentingContext_t {
+        typedef GeckoVRManager Owner;
+        typedef void ReturnType;
+        typedef void SetterType;
+        typedef mozilla::jni::Args<> Args;
+        static constexpr char name[] = "destroyGVRNonPresentingContext";
+        static constexpr char signature[] =
+                "()V";
+        static const bool isStatic = true;
+        static const mozilla::jni::ExceptionMode exceptionMode =
+                mozilla::jni::ExceptionMode::ABORT;
+        static const mozilla::jni::CallingThread callingThread =
+                mozilla::jni::CallingThread::ANY;
+        static const mozilla::jni::DispatchTarget dispatchTarget =
+                mozilla::jni::DispatchTarget::CURRENT;
+    };
+
+    static auto DestroyGVRNonPresentingContext() -> void;
+
+    struct DisableVRMode_t {
+        typedef GeckoVRManager Owner;
+        typedef void ReturnType;
+        typedef void SetterType;
+        typedef mozilla::jni::Args<> Args;
+        static constexpr char name[] = "disableVRMode";
+        static constexpr char signature[] =
+                "()V";
+        static const bool isStatic = true;
+        static const mozilla::jni::ExceptionMode exceptionMode =
+                mozilla::jni::ExceptionMode::ABORT;
+        static const mozilla::jni::CallingThread callingThread =
+                mozilla::jni::CallingThread::ANY;
+        static const mozilla::jni::DispatchTarget dispatchTarget =
+                mozilla::jni::DispatchTarget::CURRENT;
+    };
+
+    static auto DisableVRMode() -> void;
+
+    struct EnableVRMode_t {
+        typedef GeckoVRManager Owner;
+        typedef void ReturnType;
+        typedef void SetterType;
+        typedef mozilla::jni::Args<> Args;
+        static constexpr char name[] = "enableVRMode";
+        static constexpr char signature[] =
+                "()V";
+        static const bool isStatic = true;
+        static const mozilla::jni::ExceptionMode exceptionMode =
+                mozilla::jni::ExceptionMode::ABORT;
+        static const mozilla::jni::CallingThread callingThread =
+                mozilla::jni::CallingThread::ANY;
+        static const mozilla::jni::DispatchTarget dispatchTarget =
+                mozilla::jni::DispatchTarget::CURRENT;
+    };
+
+    static auto EnableVRMode() -> void;
+
+    struct IsGVRPresent_t {
+        typedef GeckoVRManager Owner;
+        typedef bool ReturnType;
+        typedef bool SetterType;
+        typedef mozilla::jni::Args<> Args;
+        static constexpr char name[] = "isGVRPresent";
+        static constexpr char signature[] =
+                "()Z";
+        static const bool isStatic = true;
+        static const mozilla::jni::ExceptionMode exceptionMode =
+                mozilla::jni::ExceptionMode::ABORT;
+        static const mozilla::jni::CallingThread callingThread =
+                mozilla::jni::CallingThread::ANY;
+        static const mozilla::jni::DispatchTarget dispatchTarget =
+                mozilla::jni::DispatchTarget::CURRENT;
+    };
+
+    static auto IsGVRPresent() -> bool;
+
+    struct SetGVRPaused_t {
+        typedef GeckoVRManager Owner;
+        typedef void ReturnType;
+        typedef void SetterType;
+        typedef mozilla::jni::Args<
+                bool> Args;
+        static constexpr char name[] = "setGVRPaused";
+        static constexpr char signature[] =
+                "(Z)V";
+        static const bool isStatic = true;
+        static const mozilla::jni::ExceptionMode exceptionMode =
+                mozilla::jni::ExceptionMode::ABORT;
+        static const mozilla::jni::CallingThread callingThread =
+                mozilla::jni::CallingThread::UI;
+        static const mozilla::jni::DispatchTarget dispatchTarget =
+                mozilla::jni::DispatchTarget::CURRENT;
+    };
+
+    struct SetGVRPresentingContext_t {
+        typedef GeckoVRManager Owner;
+        typedef void ReturnType;
+        typedef void SetterType;
+        typedef mozilla::jni::Args<
+                int64_t> Args;
+        static constexpr char name[] = "setGVRPresentingContext";
+        static constexpr char signature[] =
+                "(J)V";
+        static const bool isStatic = true;
+        static const mozilla::jni::ExceptionMode exceptionMode =
+                mozilla::jni::ExceptionMode::ABORT;
+        static const mozilla::jni::CallingThread callingThread =
+                mozilla::jni::CallingThread::UI;
+        static const mozilla::jni::DispatchTarget dispatchTarget =
+                mozilla::jni::DispatchTarget::CURRENT;
+    };
+
+    static const mozilla::jni::CallingThread callingThread =
+            mozilla::jni::CallingThread::ANY;
+
+    template<class Impl> class Natives;
+};
+
 class GeckoView : public mozilla::jni::ObjectBase<GeckoView>
 {
 public:
     static const char name[];
 
     explicit GeckoView(const Context& ctx) : ObjectBase<GeckoView>(ctx) {}
 
     class State;
--- a/widget/android/moz.build
+++ b/widget/android/moz.build
@@ -61,16 +61,17 @@ include('/ipc/chromium/chromium-config.m
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '/docshell/base',
     '/dom/base',
     '/dom/system/android',
     '/gfx/2d',
+    '/gfx/vr',
     '/layout/painting',
     '/netwerk/base',
     '/netwerk/cache',
     '/widget',
     '/xpcom/threads',
 ]
 
 CXXFLAGS += ['-Wno-error=shadow']
--- a/widget/android/nsAppShell.cpp
+++ b/widget/android/nsAppShell.cpp
@@ -64,16 +64,17 @@
 
 #include "AndroidAlerts.h"
 #include "AndroidUiThread.h"
 #include "ANRReporter.h"
 #include "GeckoBatteryManager.h"
 #include "GeckoNetworkManager.h"
 #include "GeckoProcessManager.h"
 #include "GeckoScreenOrientation.h"
+#include "GeckoVRManager.h"
 #include "PrefsHelper.h"
 #include "fennec/MemoryMonitor.h"
 #include "fennec/Telemetry.h"
 #include "fennec/ThumbnailHelper.h"
 
 #ifdef DEBUG_ANDROID_EVENTS
 #define EVLOG(args...)  ALOG(args)
 #else
@@ -402,16 +403,17 @@ 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()) {
             mozilla::ANRReporter::Init();
             mozilla::MemoryMonitor::Init();
             mozilla::widget::Telemetry::Init();
             mozilla::ThumbnailHelper::Init();
         }