Title: [230630] trunk/Source/WebCore
Revision
230630
Author
[email protected]
Date
2018-04-13 08:19:00 -0700 (Fri, 13 Apr 2018)

Log Message

[WebVR][OpenVR] Implement requestPresent()/exitPresent() and getLayers()
https://bugs.webkit.org/show_bug.cgi?id=184530

Reviewed by Žan Doberšek.

WebVR apps should invoke requestPresent() to start presenting contents of a VRLayerInit
(right now a HTML canvas with a WebGL context) on the VRDisplay. This request might fail for
a variety of reasons and can be eventually cancelled with exitPresent(). Once we are
presenting we could access the presenting layers (right now just one) with getLayers().

Note that we are not presenting anything to the HMD yet, that will be done later in a follow
up patch.

I took the chance to correct a mistak in the VRDisplayCapabilities object which has a method
that should be called maxLayers instead of maxLayer.

* Modules/webvr/VRDisplay.cpp:
(WebCore::VRDisplay::requestPresent):
(WebCore::VRDisplay::stopPresenting):
(WebCore::VRDisplay::exitPresent):
(WebCore::VRDisplay::getLayers const):
(WebCore::VRDisplay::isPresenting const): Deleted. Implemented in the header file.
* Modules/webvr/VRDisplay.h:
(WebCore::VRDisplay::isPresenting const):
* Modules/webvr/VRDisplayCapabilities.h:
(WebCore::VRDisplayCapabilities::maxLayers const): Renamed from maxLayer().
(WebCore::VRDisplayCapabilities::maxLayer const): Deleted.
* Modules/webvr/VRDisplayCapabilities.idl:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (230629 => 230630)


--- trunk/Source/WebCore/ChangeLog	2018-04-13 13:18:29 UTC (rev 230629)
+++ trunk/Source/WebCore/ChangeLog	2018-04-13 15:19:00 UTC (rev 230630)
@@ -1,3 +1,34 @@
+2018-04-13  Sergio Villar Senin  <[email protected]>
+
+        [WebVR][OpenVR] Implement requestPresent()/exitPresent() and getLayers()
+        https://bugs.webkit.org/show_bug.cgi?id=184530
+
+        Reviewed by Žan Doberšek.
+
+        WebVR apps should invoke requestPresent() to start presenting contents of a VRLayerInit
+        (right now a HTML canvas with a WebGL context) on the VRDisplay. This request might fail for
+        a variety of reasons and can be eventually cancelled with exitPresent(). Once we are
+        presenting we could access the presenting layers (right now just one) with getLayers().
+
+        Note that we are not presenting anything to the HMD yet, that will be done later in a follow
+        up patch.
+
+        I took the chance to correct a mistak in the VRDisplayCapabilities object which has a method
+        that should be called maxLayers instead of maxLayer.
+
+        * Modules/webvr/VRDisplay.cpp:
+        (WebCore::VRDisplay::requestPresent):
+        (WebCore::VRDisplay::stopPresenting):
+        (WebCore::VRDisplay::exitPresent):
+        (WebCore::VRDisplay::getLayers const):
+        (WebCore::VRDisplay::isPresenting const): Deleted. Implemented in the header file.
+        * Modules/webvr/VRDisplay.h:
+        (WebCore::VRDisplay::isPresenting const):
+        * Modules/webvr/VRDisplayCapabilities.h:
+        (WebCore::VRDisplayCapabilities::maxLayers const): Renamed from maxLayer().
+        (WebCore::VRDisplayCapabilities::maxLayer const): Deleted.
+        * Modules/webvr/VRDisplayCapabilities.idl:
+
 2018-04-13  Miguel Gomez  <[email protected]>
 
         REGRESSION(r230627): [GTK][WPE] Possible deadlock when destroying the player in non AC mode

Modified: trunk/Source/WebCore/Modules/webvr/VRDisplay.cpp (230629 => 230630)


--- trunk/Source/WebCore/Modules/webvr/VRDisplay.cpp	2018-04-13 13:18:29 UTC (rev 230629)
+++ trunk/Source/WebCore/Modules/webvr/VRDisplay.cpp	2018-04-13 15:19:00 UTC (rev 230630)
@@ -26,9 +26,12 @@
 #include "config.h"
 #include "VRDisplay.h"
 
+#include "CanvasRenderingContext.h"
 #include "Chrome.h"
+#include "DOMException.h"
 #include "Page.h"
 #include "ScriptedAnimationController.h"
+#include "UserGestureIndicator.h"
 #include "VRDisplayCapabilities.h"
 #include "VREyeParameters.h"
 #include "VRFrameData.h"
@@ -68,11 +71,6 @@
     return m_display->getDisplayInfo().isConnected();
 }
 
-bool VRDisplay::isPresenting() const
-{
-    return false;
-}
-
 const VRDisplayCapabilities& VRDisplay::capabilities() const
 {
     return *m_capabilities;
@@ -132,20 +130,76 @@
     m_scriptedAnimationController->cancelCallback(id);
 }
 
-void VRDisplay::requestPresent(const Vector<VRLayerInit>&, Ref<DeferredPromise>&&)
+void VRDisplay::requestPresent(const Vector<VRLayerInit>& layers, Ref<DeferredPromise>&& promise)
 {
+    auto rejectRequestAndStopPresenting = [this, &promise] (ExceptionCode exceptionCode, ASCIILiteral message) {
+        promise->reject(Exception { exceptionCode, message });
+        if (m_presentingLayer)
+            stopPresenting();
+    };
+
+    if (!m_capabilities->canPresent()) {
+        rejectRequestAndStopPresenting(NotSupportedError, ASCIILiteral("VRDisplay cannot present"));
+        return;
+    }
+
+    if (!layers.size() || layers.size() > m_capabilities->maxLayers()) {
+        rejectRequestAndStopPresenting(InvalidStateError, ASCIILiteral(layers.size() ? "Too many layers" : "Not enough layers"));
+        return;
+    }
+
+    if (!m_presentingLayer && !UserGestureIndicator::processingUserGesture()) {
+        rejectRequestAndStopPresenting(InvalidAccessError, ASCIILiteral("Must request presentation from a user gesture handler."));
+        return;
+    }
+
+    RELEASE_ASSERT(layers.size() == 1);
+    auto layer = layers[0];
+
+    if (!layer.source) {
+        rejectRequestAndStopPresenting(InvalidStateError, ASCIILiteral("Layer does not contain any source"));
+        return;
+    }
+
+    auto* canvasContext = layer.source->getContext("webgl");
+    if (!canvasContext || !canvasContext->isWebGL()) {
+        rejectRequestAndStopPresenting(NotSupportedError, ASCIILiteral("WebVR requires VRLayerInit with WebGL context."));
+        return;
+    }
+
+    if ((layer.leftBounds.size() && layer.leftBounds.size() != 4)
+        || (layer.rightBounds.size() && layer.rightBounds.size() != 4)) {
+        rejectRequestAndStopPresenting(InvalidStateError, ASCIILiteral("Layer bounds must be either 0 or 4"));
+        return;
+    }
+
+    m_presentingLayer = layer;
+    promise->resolve();
 }
 
-void VRDisplay::exitPresent(Ref<DeferredPromise>&&)
+void VRDisplay::stopPresenting()
 {
+    m_presentingLayer = std::nullopt;
 }
 
-const Vector<VRLayerInit>& VRDisplay::getLayers() const
+void VRDisplay::exitPresent(Ref<DeferredPromise>&& promise)
 {
-    static auto mockLayers = makeNeverDestroyed(Vector<VRLayerInit> { });
-    return mockLayers;
+    if (!m_presentingLayer) {
+        promise->reject(Exception { InvalidStateError, ASCIILiteral("VRDisplay is not presenting") });
+        return;
+    }
+
+    stopPresenting();
 }
 
+Vector<VRLayerInit> VRDisplay::getLayers() const
+{
+    Vector<VRLayerInit> layers;
+    if (m_presentingLayer)
+        layers.append(m_presentingLayer.value());
+    return layers;
+}
+
 void VRDisplay::submitFrame()
 {
 }

Modified: trunk/Source/WebCore/Modules/webvr/VRDisplay.h (230629 => 230630)


--- trunk/Source/WebCore/Modules/webvr/VRDisplay.h	2018-04-13 13:18:29 UTC (rev 230629)
+++ trunk/Source/WebCore/Modules/webvr/VRDisplay.h	2018-04-13 15:19:00 UTC (rev 230630)
@@ -29,10 +29,12 @@
 #include "EventTarget.h"
 #include "JSDOMPromiseDeferred.h"
 #include "VREye.h"
+#include "VRLayerInit.h"
 #include <wtf/RefCounted.h>
 
 namespace WebCore {
 
+enum ExceptionCode;
 class RequestAnimationFrameCallback;
 class ScriptedAnimationController;
 class VRDisplayCapabilities;
@@ -41,7 +43,6 @@
 class VRPlatformDisplay;
 class VRPose;
 class VRStageParameters;
-struct VRLayerInit;
 
 class VRDisplay : public RefCounted<VRDisplay>, public EventTargetWithInlineData, public ActiveDOMObject {
 public:
@@ -53,7 +54,7 @@
     using RefCounted<VRDisplay>::deref;
 
     bool isConnected() const;
-    bool isPresenting() const;
+    bool isPresenting() const { return !!m_presentingLayer; };
 
     const VRDisplayCapabilities& capabilities() const;
     RefPtr<VRStageParameters> stageParameters() const;
@@ -79,7 +80,7 @@
     void requestPresent(const Vector<VRLayerInit>&, Ref<DeferredPromise>&&);
     void exitPresent(Ref<DeferredPromise>&&);
 
-    const Vector<VRLayerInit>& getLayers() const;
+    Vector<VRLayerInit> getLayers() const;
 
     void submitFrame();
 
@@ -98,6 +99,8 @@
     bool canSuspendForDocumentSuspension() const override;
     void stop() override;
 
+    void stopPresenting();
+
     WeakPtr<VRPlatformDisplay> m_display;
 
     RefPtr<VRDisplayCapabilities> m_capabilities;
@@ -114,6 +117,8 @@
     double m_depthFar { 10000 }; // Default value from the specs.
 
     RefPtr<ScriptedAnimationController> m_scriptedAnimationController;
+
+    std::optional<VRLayerInit> m_presentingLayer;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/Modules/webvr/VRDisplayCapabilities.h (230629 => 230630)


--- trunk/Source/WebCore/Modules/webvr/VRDisplayCapabilities.h	2018-04-13 13:18:29 UTC (rev 230629)
+++ trunk/Source/WebCore/Modules/webvr/VRDisplayCapabilities.h	2018-04-13 15:19:00 UTC (rev 230630)
@@ -43,7 +43,7 @@
     bool hasOrientation() const { return m_flags & VRDisplayCapabilityFlagOrientation; }
     bool hasExternalDisplay() const { return m_flags & VRDisplayCapabilityFlagExternalDisplay; }
     bool canPresent() const { return m_flags & VRDisplayCapabilityFlagPresent; }
-    unsigned maxLayer() const { return canPresent() ? 1 : 0; }
+    unsigned maxLayers() const { return canPresent() ? 1 : 0; }
 
 private:
     VRDisplayCapabilities(unsigned capabilityFlags)

Modified: trunk/Source/WebCore/Modules/webvr/VRDisplayCapabilities.idl (230629 => 230630)


--- trunk/Source/WebCore/Modules/webvr/VRDisplayCapabilities.idl	2018-04-13 13:18:29 UTC (rev 230629)
+++ trunk/Source/WebCore/Modules/webvr/VRDisplayCapabilities.idl	2018-04-13 15:19:00 UTC (rev 230630)
@@ -31,5 +31,5 @@
     readonly attribute boolean hasOrientation;
     readonly attribute boolean hasExternalDisplay;
     readonly attribute boolean canPresent;
-    readonly attribute unsigned long maxLayer;
+    readonly attribute unsigned long maxLayers;
 };
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to