⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 230630 in webkit


Ignore:
Timestamp:
Apr 13, 2018, 8:19:00 AM (8 years ago)
Author:
svillar@igalia.com
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:
Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r230629 r230630  
     12018-04-13  Sergio Villar Senin  <svillar@igalia.com>
     2
     3        [WebVR][OpenVR] Implement requestPresent()/exitPresent() and getLayers()
     4        https://bugs.webkit.org/show_bug.cgi?id=184530
     5
     6        Reviewed by Žan Doberšek.
     7
     8        WebVR apps should invoke requestPresent() to start presenting contents of a VRLayerInit
     9        (right now a HTML canvas with a WebGL context) on the VRDisplay. This request might fail for
     10        a variety of reasons and can be eventually cancelled with exitPresent(). Once we are
     11        presenting we could access the presenting layers (right now just one) with getLayers().
     12
     13        Note that we are not presenting anything to the HMD yet, that will be done later in a follow
     14        up patch.
     15
     16        I took the chance to correct a mistak in the VRDisplayCapabilities object which has a method
     17        that should be called maxLayers instead of maxLayer.
     18
     19        * Modules/webvr/VRDisplay.cpp:
     20        (WebCore::VRDisplay::requestPresent):
     21        (WebCore::VRDisplay::stopPresenting):
     22        (WebCore::VRDisplay::exitPresent):
     23        (WebCore::VRDisplay::getLayers const):
     24        (WebCore::VRDisplay::isPresenting const): Deleted. Implemented in the header file.
     25        * Modules/webvr/VRDisplay.h:
     26        (WebCore::VRDisplay::isPresenting const):
     27        * Modules/webvr/VRDisplayCapabilities.h:
     28        (WebCore::VRDisplayCapabilities::maxLayers const): Renamed from maxLayer().
     29        (WebCore::VRDisplayCapabilities::maxLayer const): Deleted.
     30        * Modules/webvr/VRDisplayCapabilities.idl:
     31
    1322018-04-13  Miguel Gomez  <magomez@igalia.com>
    233
  • trunk/Source/WebCore/Modules/webvr/VRDisplay.cpp

    r230428 r230630  
    2727#include "VRDisplay.h"
    2828
     29#include "CanvasRenderingContext.h"
    2930#include "Chrome.h"
     31#include "DOMException.h"
    3032#include "Page.h"
    3133#include "ScriptedAnimationController.h"
     34#include "UserGestureIndicator.h"
    3235#include "VRDisplayCapabilities.h"
    3336#include "VREyeParameters.h"
     
    6770
    6871    return m_display->getDisplayInfo().isConnected();
    69 }
    70 
    71 bool VRDisplay::isPresenting() const
    72 {
    73     return false;
    7472}
    7573
     
    133131}
    134132
    135 void VRDisplay::requestPresent(const Vector<VRLayerInit>&, Ref<DeferredPromise>&&)
    136 {
    137 }
    138 
    139 void VRDisplay::exitPresent(Ref<DeferredPromise>&&)
    140 {
    141 }
    142 
    143 const Vector<VRLayerInit>& VRDisplay::getLayers() const
    144 {
    145     static auto mockLayers = makeNeverDestroyed(Vector<VRLayerInit> { });
    146     return mockLayers;
     133void VRDisplay::requestPresent(const Vector<VRLayerInit>& layers, Ref<DeferredPromise>&& promise)
     134{
     135    auto rejectRequestAndStopPresenting = [this, &promise] (ExceptionCode exceptionCode, ASCIILiteral message) {
     136        promise->reject(Exception { exceptionCode, message });
     137        if (m_presentingLayer)
     138            stopPresenting();
     139    };
     140
     141    if (!m_capabilities->canPresent()) {
     142        rejectRequestAndStopPresenting(NotSupportedError, ASCIILiteral("VRDisplay cannot present"));
     143        return;
     144    }
     145
     146    if (!layers.size() || layers.size() > m_capabilities->maxLayers()) {
     147        rejectRequestAndStopPresenting(InvalidStateError, ASCIILiteral(layers.size() ? "Too many layers" : "Not enough layers"));
     148        return;
     149    }
     150
     151    if (!m_presentingLayer && !UserGestureIndicator::processingUserGesture()) {
     152        rejectRequestAndStopPresenting(InvalidAccessError, ASCIILiteral("Must request presentation from a user gesture handler."));
     153        return;
     154    }
     155
     156    RELEASE_ASSERT(layers.size() == 1);
     157    auto layer = layers[0];
     158
     159    if (!layer.source) {
     160        rejectRequestAndStopPresenting(InvalidStateError, ASCIILiteral("Layer does not contain any source"));
     161        return;
     162    }
     163
     164    auto* canvasContext = layer.source->getContext("webgl");
     165    if (!canvasContext || !canvasContext->isWebGL()) {
     166        rejectRequestAndStopPresenting(NotSupportedError, ASCIILiteral("WebVR requires VRLayerInit with WebGL context."));
     167        return;
     168    }
     169
     170    if ((layer.leftBounds.size() && layer.leftBounds.size() != 4)
     171        || (layer.rightBounds.size() && layer.rightBounds.size() != 4)) {
     172        rejectRequestAndStopPresenting(InvalidStateError, ASCIILiteral("Layer bounds must be either 0 or 4"));
     173        return;
     174    }
     175
     176    m_presentingLayer = layer;
     177    promise->resolve();
     178}
     179
     180void VRDisplay::stopPresenting()
     181{
     182    m_presentingLayer = std::nullopt;
     183}
     184
     185void VRDisplay::exitPresent(Ref<DeferredPromise>&& promise)
     186{
     187    if (!m_presentingLayer) {
     188        promise->reject(Exception { InvalidStateError, ASCIILiteral("VRDisplay is not presenting") });
     189        return;
     190    }
     191
     192    stopPresenting();
     193}
     194
     195Vector<VRLayerInit> VRDisplay::getLayers() const
     196{
     197    Vector<VRLayerInit> layers;
     198    if (m_presentingLayer)
     199        layers.append(m_presentingLayer.value());
     200    return layers;
    147201}
    148202
  • trunk/Source/WebCore/Modules/webvr/VRDisplay.h

    r230428 r230630  
    3030#include "JSDOMPromiseDeferred.h"
    3131#include "VREye.h"
     32#include "VRLayerInit.h"
    3233#include <wtf/RefCounted.h>
    3334
    3435namespace WebCore {
    3536
     37enum ExceptionCode;
    3638class RequestAnimationFrameCallback;
    3739class ScriptedAnimationController;
     
    4244class VRPose;
    4345class VRStageParameters;
    44 struct VRLayerInit;
    4546
    4647class VRDisplay : public RefCounted<VRDisplay>, public EventTargetWithInlineData, public ActiveDOMObject {
     
    5455
    5556    bool isConnected() const;
    56     bool isPresenting() const;
     57    bool isPresenting() const { return !!m_presentingLayer; };
    5758
    5859    const VRDisplayCapabilities& capabilities() const;
     
    8081    void exitPresent(Ref<DeferredPromise>&&);
    8182
    82     const Vector<VRLayerInit>& getLayers() const;
     83    Vector<VRLayerInit> getLayers() const;
    8384
    8485    void submitFrame();
     
    99100    void stop() override;
    100101
     102    void stopPresenting();
     103
    101104    WeakPtr<VRPlatformDisplay> m_display;
    102105
     
    115118
    116119    RefPtr<ScriptedAnimationController> m_scriptedAnimationController;
     120
     121    std::optional<VRLayerInit> m_presentingLayer;
    117122};
    118123
  • trunk/Source/WebCore/Modules/webvr/VRDisplayCapabilities.h

    r230502 r230630  
    4444    bool hasExternalDisplay() const { return m_flags & VRDisplayCapabilityFlagExternalDisplay; }
    4545    bool canPresent() const { return m_flags & VRDisplayCapabilityFlagPresent; }
    46     unsigned maxLayer() const { return canPresent() ? 1 : 0; }
     46    unsigned maxLayers() const { return canPresent() ? 1 : 0; }
    4747
    4848private:
  • trunk/Source/WebCore/Modules/webvr/VRDisplayCapabilities.idl

    r221966 r230630  
    3232    readonly attribute boolean hasExternalDisplay;
    3333    readonly attribute boolean canPresent;
    34     readonly attribute unsigned long maxLayer;
     34    readonly attribute unsigned long maxLayers;
    3535};
Note: See TracChangeset for help on using the changeset viewer.