Changeset 263346 in webkit


Ignore:
Timestamp:
Jun 22, 2020 5:28:08 AM (4 years ago)
Author:
svillar@igalia.com
Message:

[WebXR] Add a preliminary implementation of XRWebGLLayer
https://bugs.webkit.org/show_bug.cgi?id=213022

Reviewed by Carlos Garcia Campos.

LayoutTests/imported/w3c:

Added new expectations.

  • web-platform-tests/webxr/xrWebGLLayer_constructor.https-expected.txt: Added.
  • web-platform-tests/webxr/xrWebGLLayer_framebuffer_sameObject.https-expected.txt: Added.

Source/WebCore:

Added a preliminary implementation of XRWebGLLayer. It does not have any functionality at the moment so
it cannot be used to render WebXR stuff. This patch adds all the machinery required to create and properly
initialize the layer according to the spec.

Two new wpt tests are passing now.

  • Modules/webxr/WebXRSession.h: Expose session mode.
  • Modules/webxr/WebXRWebGLLayer.cpp:

(WebCore::WebXRWebGLLayer::create): Implemented spec for XRWebGLLayer creation.
(WebCore::WebXRWebGLLayer::computeNativeWebGLFramebufferResolution): Added with mock implementation.
(WebCore::WebXRWebGLLayer::computeRecommendedWebGLFramebufferResolution): Added.
(WebCore::WebXRWebGLLayer::WebXRWebGLLayer):
(WebCore::WebXRWebGLLayer::framebuffer const): Returned type should be a pointer.
(WebCore::WebXRWebGLLayer::framebufferWidth const): Return framebuffer width if available, otherwise return
the base context width.
(WebCore::WebXRWebGLLayer::framebufferHeight const): Ditto but with heights.
(WebCore::WebXRWebGLLayer::getNativeFramebufferScaleFactor): Implemented.

  • Modules/webxr/WebXRWebGLLayer.h: New methods and type adjustments.

LayoutTests:

  • platform/wpe/TestExpectations: Added 2 more tests that are passing now.
Location:
trunk
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r263343 r263346  
     12020-06-10  Sergio Villar Senin  <svillar@igalia.com>
     2
     3        [WebXR] Add a preliminary implementation of XRWebGLLayer
     4        https://bugs.webkit.org/show_bug.cgi?id=213022
     5
     6        Reviewed by Carlos Garcia Campos.
     7
     8        * platform/wpe/TestExpectations: Added 2 more tests that are passing now.
     9
    1102020-06-22  Carlos Garcia Campos  <cgarcia@igalia.com>
    211
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r263345 r263346  
     12020-06-10  Sergio Villar Senin  <svillar@igalia.com>
     2
     3        [WebXR] Add a preliminary implementation of XRWebGLLayer
     4        https://bugs.webkit.org/show_bug.cgi?id=213022
     5
     6        Reviewed by Carlos Garcia Campos.
     7
     8        Added new expectations.
     9
     10        * web-platform-tests/webxr/xrWebGLLayer_constructor.https-expected.txt: Added.
     11        * web-platform-tests/webxr/xrWebGLLayer_framebuffer_sameObject.https-expected.txt: Added.
     12
    1132020-06-22  Rob Buis  <rbuis@igalia.com>
    214
  • trunk/LayoutTests/platform/wpe/TestExpectations

    r263265 r263346  
    942942webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/ar-module/xrDevice_isSessionSupported_immersive-ar.https.html [ Pass ]
    943943webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/ar-module/xrDevice_requestSession_immersive-ar.https.html [ Pass ]
     944webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrWebGLLayer_constructor.https.html [ Pass ]
     945webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrWebGLLayer_framebuffer_sameObject.https.html [ Pass ]
    944946
    945947# Passing since r259532.
  • trunk/Source/WebCore/ChangeLog

    r263345 r263346  
     12020-06-10  Sergio Villar Senin  <svillar@igalia.com>
     2
     3        [WebXR] Add a preliminary implementation of XRWebGLLayer
     4        https://bugs.webkit.org/show_bug.cgi?id=213022
     5
     6        Reviewed by Carlos Garcia Campos.
     7
     8        Added a preliminary implementation of XRWebGLLayer. It does not have any functionality at the moment so
     9        it cannot be used to render WebXR stuff. This patch adds all the machinery required to create and properly
     10        initialize the layer according to the spec.
     11
     12        Two new wpt tests are passing now.
     13
     14        * Modules/webxr/WebXRSession.h: Expose session mode.
     15        * Modules/webxr/WebXRWebGLLayer.cpp:
     16        (WebCore::WebXRWebGLLayer::create): Implemented spec for XRWebGLLayer creation.
     17        (WebCore::WebXRWebGLLayer::computeNativeWebGLFramebufferResolution): Added with mock implementation.
     18        (WebCore::WebXRWebGLLayer::computeRecommendedWebGLFramebufferResolution): Added.
     19        (WebCore::WebXRWebGLLayer::WebXRWebGLLayer):
     20        (WebCore::WebXRWebGLLayer::framebuffer const): Returned type should be a pointer.
     21        (WebCore::WebXRWebGLLayer::framebufferWidth const): Return framebuffer width if available, otherwise return
     22        the base context width.
     23        (WebCore::WebXRWebGLLayer::framebufferHeight const): Ditto but with heights.
     24        (WebCore::WebXRWebGLLayer::getNativeFramebufferScaleFactor): Implemented.
     25        * Modules/webxr/WebXRWebGLLayer.h: New methods and type adjustments.
     26
    1272020-06-22  Rob Buis  <rbuis@igalia.com>
    228
  • trunk/Source/WebCore/Modules/webxr/WebXRSession.h

    r263256 r263346  
    8181    bool ended() const { return m_ended; }
    8282
     83    XRSessionMode mode() const { return m_mode; }
     84
    8385private:
    8486    WebXRSession(Document&, WebXRSystem&, XRSessionMode, PlatformXR::Device&);
  • trunk/Source/WebCore/Modules/webxr/WebXRWebGLLayer.cpp

    r258498 r263346  
    2929#if ENABLE(WEBXR)
    3030
     31#include "IntSize.h"
    3132#include "WebGLFramebuffer.h"
    3233#include "WebGLRenderingContext.h"
     
    3435#include "WebGL2RenderingContext.h"
    3536#endif
     37#include "WebGLRenderingContextBase.h"
    3638#include "WebXRSession.h"
    3739#include "WebXRViewport.h"
    3840#include "XRWebGLLayerInit.h"
     41#include <wtf/Scope.h>
    3942
    4043namespace WebCore {
    4144
    42 ExceptionOr<Ref<WebXRWebGLLayer>> WebXRWebGLLayer::create(const WebXRSession& session, WebXRRenderingContext&& context, const XRWebGLLayerInit& init)
    43 {
    44     // The XRWebGLLayer(session, context, layerInit) constructor MUST perform the following steps when invoked:
    45     //   1. Let layer be a new XRWebGLLayer
    46 
    47     //   2. If session’s ended value is true, throw an InvalidStateError and abort these steps.
     45// https://immersive-web.github.io/webxr/#dom-xrwebgllayer-xrwebgllayer
     46ExceptionOr<Ref<WebXRWebGLLayer>> WebXRWebGLLayer::create(WebXRSession& session, WebXRRenderingContext&& context, const XRWebGLLayerInit& init)
     47{
     48    // 1. Let layer be a new XRWebGLLayer
     49    // 2. If session’s ended value is true, throw an InvalidStateError and abort these steps.
    4850    if (session.ended())
    4951        return Exception { InvalidStateError };
    5052
    51     //   3. If context is lost, throw an InvalidStateError and abort these steps.
    52     //   4. If context’s XR compatible boolean is false, throw an InvalidStateError and abort these steps.
    53     // FIXME: TODO
    54 
    55     //   5. Initialize layer’s context to context.
    56     //   6. Initialize layer’s antialias to layerInit’s antialias value.
    57     //   7. If layerInit’s ignoreDepthValues value is false and the XR Compositor will make use of depth values, Initialize layer’s ignoreDepthValues to false.
    58     //   8. Else Initialize layer’s ignoreDepthValues to true
    59     //   9. Initialize layer’s framebuffer to a new opaque framebuffer created with context.
    60     //   10. Initialize the layer’s swap chain.
    61     //   11. If layer’s swap chain was unable to be created for any reason, throw an OperationError and abort these steps.
    62     // FIXME: TODO
    63 
    64     //   12. Return layer.
    65     return adoptRef(*new WebXRWebGLLayer(session, WTFMove(context), init));
    66 }
    67 
    68 WebXRWebGLLayer::WebXRWebGLLayer(const WebXRSession&, WebXRRenderingContext&& context, const XRWebGLLayerInit& init)
    69     : m_context(WTFMove(context))
    70     , m_antialias(init.antialias)
    71     , m_ignoreDepthValues(init.ignoreDepthValues)
    72 {
    73     m_framebuffer.object = WTF::switchOn(m_context,
    74         [](const RefPtr<WebGLRenderingContext>& context)
     53    // 3. If context is lost, throw an InvalidStateError and abort these steps.
     54    // 4. If session is an immersive session and context’s XR compatible boolean is false, throw
     55    //    an InvalidStateError and abort these steps.
     56    return WTF::switchOn(context,
     57        [&](const RefPtr<WebGLRenderingContextBase>& baseContext) -> ExceptionOr<Ref<WebXRWebGLLayer>>
    7558        {
    76             RefPtr<WebGLFramebuffer> frameBuffer = WebGLFramebuffer::create(*context);
    77             return frameBuffer;
     59            if (baseContext->isContextLost())
     60                return Exception { InvalidStateError };
     61
     62            auto mode = session.mode();
     63            if ((mode == XRSessionMode::ImmersiveAr || mode == XRSessionMode::ImmersiveVr) && !baseContext->isXRCompatible())
     64                return Exception { InvalidStateError };
     65
     66
     67            // 5. Initialize layer’s context to context. (see constructor)
     68            // 6. Initialize layer’s session to session. (see constructor)
     69            // 7. Initialize layer’s ignoreDepthValues as follows. (see constructor)
     70            // 8. Initialize layer’s composition disabled boolean as follows. (see constructor)
     71            // 9. (see constructor except for the resources initialization step which is handled in the if block below)
     72            auto layer = adoptRef(*new WebXRWebGLLayer(session, WTFMove(context), init));
     73
     74            if (layer->m_isCompositionDisabled) {
     75                // 9.4. Allocate and initialize resources compatible with session’s XR device, including GPU accessible memory buffers,
     76                //      as required to support the compositing of layer.
     77                // 9.5. If layer’s resources were unable to be created for any reason, throw an OperationError and abort these steps.
     78                // TODO: Initialize layer's resources or issue an OperationError.
     79            }
     80
     81            // 10. Return layer.
     82            return layer;
    7883        },
    79 #if ENABLE(WEBGL2)
    80         [](const RefPtr<WebGL2RenderingContext>& context)
    81         {
    82             RefPtr<WebGLFramebuffer> frameBuffer = WebGLFramebuffer::create(*context);
    83             return frameBuffer;
    84         },
    85 #endif
    8684        [](WTF::Monostate) {
    8785            ASSERT_NOT_REACHED();
    88             return nullptr;
     86            return Exception { InvalidStateError };
    8987        }
    9088    );
    9189}
    9290
     91// https://immersive-web.github.io/webxr/#native-webgl-framebuffer-resolution
     92IntSize WebXRWebGLLayer::computeNativeWebGLFramebufferResolution()
     93{
     94    // FIXME: implement this
     95    return { 1, 1 };
     96}
     97
     98// https://immersive-web.github.io/webxr/#recommended-webgl-framebuffer-resolution
     99IntSize WebXRWebGLLayer::computeRecommendedWebGLFramebufferResolution()
     100{
     101    return computeNativeWebGLFramebufferResolution();
     102}
     103
     104WebXRWebGLLayer::WebXRWebGLLayer(WebXRSession& session, WebXRRenderingContext&& context, const XRWebGLLayerInit& init)
     105    : m_session(makeRef(session))
     106    , m_context(WTFMove(context))
     107{
     108    // 7. Initialize layer’s ignoreDepthValues as follows:
     109    //   7.1 If layerInit’s ignoreDepthValues value is false and the XR Compositor will make use of depth values,
     110    //       Initialize layer’s ignoreDepthValues to false.
     111    //   7.2. Else Initialize layer’s ignoreDepthValues to true
     112    // TODO: ask XR compositor for depth value usages
     113    m_ignoreDepthValues = init.ignoreDepthValues;
     114
     115    // 8. Initialize layer's composition disabled boolean as follows:
     116    //  If session is an inline session -> Initialize layer's composition disabled to true
     117    //  Otherwise -> Initialize layer's composition disabled boolean to false
     118    m_isCompositionDisabled = m_session->mode() == XRSessionMode::Inline;
     119
     120    // 9. If layer’s composition disabled boolean is false:
     121    if (m_isCompositionDisabled) {
     122        //  1. Initialize layer’s antialias to layerInit’s antialias value.
     123        m_antialias = init.antialias;
     124
     125        //  2. Let framebufferSize be the recommended WebGL framebuffer resolution multiplied by layerInit's framebufferScaleFactor.
     126        IntSize recommendedSize = computeRecommendedWebGLFramebufferResolution();
     127        m_framebuffer.width = recommendedSize.width() * init.framebufferScaleFactor;
     128        m_framebuffer.height = recommendedSize.height() * init.framebufferScaleFactor;
     129
     130        //  3. Initialize layer’s framebuffer to a new opaque framebuffer with the dimensions framebufferSize
     131        //       created with context, session initialized to session, and layerInit’s depth, stencil, and alpha values.
     132        // For steps 4 & 5 see the create() method as resources initialization is handled outside the constructor as it might trigger
     133        // an OperationError.
     134        // FIXME: create a proper opaque framebuffer.
     135        m_framebuffer.object = WTF::switchOn(m_context,
     136            [](const RefPtr<WebGLRenderingContextBase>& baseContext)
     137            {
     138                return WebGLFramebuffer::create(*baseContext);
     139            }
     140        );
     141    } else {
     142        // 1. Initialize layer’s antialias to layer’s context's actual context parameters antialias value.
     143        m_antialias = WTF::switchOn(m_context,
     144            [](const RefPtr<WebGLRenderingContextBase>& context)
     145            {
     146                if (auto attributes = context->getContextAttributes())
     147                    return attributes.value().antialias;
     148                return false;
     149            }
     150        );
     151        // 2. Initialize layer’s framebuffer to null.
     152        m_framebuffer.object = nullptr;
     153    }
     154}
     155
    93156WebXRWebGLLayer::~WebXRWebGLLayer() = default;
    94157
     
    103166}
    104167
    105 const WebGLFramebuffer& WebXRWebGLLayer::framebuffer() const
    106 {
    107     return *m_framebuffer.object;
     168WebGLFramebuffer* WebXRWebGLLayer::framebuffer() const
     169{
     170    return m_framebuffer.object.get();
    108171}
    109172
    110173unsigned WebXRWebGLLayer::framebufferWidth() const
    111174{
    112     return m_framebuffer.width;
     175    if (m_framebuffer.object)
     176        return m_framebuffer.width;
     177    return WTF::switchOn(m_context,
     178        [&](const RefPtr<WebGLRenderingContextBase>& baseContext) {
     179            return baseContext->drawingBufferWidth();
     180        });
    113181}
    114182
    115183unsigned WebXRWebGLLayer::framebufferHeight() const
    116184{
    117     return m_framebuffer.height;
     185    if (m_framebuffer.object)
     186        return m_framebuffer.height;
     187    return WTF::switchOn(m_context,
     188        [&](const RefPtr<WebGLRenderingContextBase>& baseContext) {
     189            return baseContext->drawingBufferHeight();
     190        });
    118191}
    119192
     
    123196}
    124197
    125 double WebXRWebGLLayer::getNativeFramebufferScaleFactor(const WebXRSession&)
    126 {
    127     return 1.0;
     198double WebXRWebGLLayer::getNativeFramebufferScaleFactor(const WebXRSession& session)
     199{
     200    if (session.ended())
     201        return 0.0;
     202
     203    IntSize nativeSize = computeNativeWebGLFramebufferResolution();
     204    IntSize recommendedSize = computeRecommendedWebGLFramebufferResolution();
     205
     206    RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(!recommendedSize.isZero());
     207    return (nativeSize / recommendedSize).width();
    128208}
    129209
  • trunk/Source/WebCore/Modules/webxr/WebXRWebGLLayer.h

    r259190 r263346  
    3737namespace WebCore {
    3838
     39class IntSize;
    3940class WebGLFramebuffer;
    4041class WebGLRenderingContext;
     
    4950class WebXRWebGLLayer : public RefCounted<WebXRWebGLLayer> {
    5051public:
    51    
     52
    5253    using WebXRRenderingContext = WTF::Variant<
    5354        RefPtr<WebGLRenderingContext>
     
    5758    >;
    5859
    59     static ExceptionOr<Ref<WebXRWebGLLayer>> create(const WebXRSession&, WebXRRenderingContext&&, const XRWebGLLayerInit&);
     60    static ExceptionOr<Ref<WebXRWebGLLayer>> create(WebXRSession&, WebXRRenderingContext&&, const XRWebGLLayerInit&);
    6061    ~WebXRWebGLLayer();
    6162
     
    6364    bool ignoreDepthValues() const;
    6465
    65     const WebGLFramebuffer& framebuffer() const;
     66    WebGLFramebuffer* framebuffer() const;
    6667    unsigned framebufferWidth() const;
    6768    unsigned framebufferHeight() const;
     
    7273
    7374private:
    74     WebXRWebGLLayer(const WebXRSession&, WebXRRenderingContext&&, const XRWebGLLayerInit&);
     75    WebXRWebGLLayer(WebXRSession&, WebXRRenderingContext&&, const XRWebGLLayerInit&);
    7576
     77    static IntSize computeNativeWebGLFramebufferResolution();
     78    static IntSize computeRecommendedWebGLFramebufferResolution();
     79
     80    Ref<WebXRSession> m_session;
    7681    WebXRRenderingContext m_context;
    7782    bool m_antialias { false };
    7883    bool m_ignoreDepthValues { false };
     84    bool m_isCompositionDisabled { false };
    7985
    8086    struct {
Note: See TracChangeset for help on using the changeset viewer.