Title: [273381] trunk
Revision
273381
Author
commit-qu...@webkit.org
Date
2021-02-24 05:09:49 -0800 (Wed, 24 Feb 2021)

Log Message

Implement WebXR getViewport
https://bugs.webkit.org/show_bug.cgi?id=222270

Patch by Imanol Fernandez <ifernan...@igalia.com> on 2021-02-24
Reviewed by Sergio Villar Senin.

LayoutTests/imported/w3c:

Update WebXR Viewport test expectations.

* web-platform-tests/webxr/xrViewport_valid.https-expected.txt: Added.
* web-platform-tests/webxr/xrWebGLLayer_viewports.https-expected.txt: Added.

Source/WebCore:

* Modules/webxr/WebXRFrame.cpp:
(WebCore::WebXRFrame::getViewerPose): set WebXRView viewport modifiable value.
* Modules/webxr/WebXRFrame.h:
(WebCore::WebXRFrame::isAnimationFrame const): add method.

* Modules/webxr/WebXRSession.cpp: Implement supportsViewportScaling().
(WebCore::WebXRSession::supportsViewportScaling const):
* Modules/webxr/WebXRSession.h:

* Modules/webxr/WebXRView.cpp: Add viewport scale data.
(WebCore::WebXRView::create):
(WebCore::WebXRView::WebXRView):
(WebCore::WebXRView::recommendedViewportScale const):
(WebCore::WebXRView::requestViewportScale):
* Modules/webxr/WebXRView.h:
(WebCore::WebXRView::frame const):
(WebCore::WebXRView::currentViewportScale const):
(WebCore::WebXRView::setCurrentViewportScale):
(WebCore::WebXRView::requestedViewportScale const):
(WebCore::WebXRView::isViewportModifiable const):
(WebCore::WebXRView::setViewportModifiable):

* Modules/webxr/WebXRView.idl: add requestViewportScale() and recommendedViewportScale.

* Modules/webxr/WebXRViewport.cpp: Implement viewport rect values.
(WebCore::WebXRViewport::create):
(WebCore::WebXRViewport::WebXRViewport):
* Modules/webxr/WebXRViewport.h:
(WebCore::WebXRViewport::x const):
(WebCore::WebXRViewport::y const):
(WebCore::WebXRViewport::width const):
(WebCore::WebXRViewport::height const):
(WebCore::WebXRViewport::updateViewport):

* Modules/webxr/WebXRWebGLLayer.cpp: Implement getViewport()
(WebCore::WebXRWebGLLayer::WebXRWebGLLayer):
(WebCore::m_rightViewport):
(WebCore::WebXRWebGLLayer::getViewport):
* Modules/webxr/WebXRWebGLLayer.h:

* Modules/webxr/WebXRWebGLLayer.idl: Add MayThrowException

* platform/xr/PlatformXR.h: Add supportsViewportScaling method
(PlatformXR::Device::supportsViewportScaling const):

LayoutTests:

Update WebXR Viewport test expectations.

* platform/wpe/TestExpectations:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (273380 => 273381)


--- trunk/LayoutTests/ChangeLog	2021-02-24 12:53:56 UTC (rev 273380)
+++ trunk/LayoutTests/ChangeLog	2021-02-24 13:09:49 UTC (rev 273381)
@@ -1,3 +1,14 @@
+2021-02-24  Imanol Fernandez  <ifernan...@igalia.com>
+
+        Implement WebXR getViewport
+        https://bugs.webkit.org/show_bug.cgi?id=222270
+
+        Reviewed by Sergio Villar Senin.
+
+        Update WebXR Viewport test expectations.
+
+        * platform/wpe/TestExpectations:
+
 2021-02-17  Sergio Villar Senin  <svil...@igalia.com>
 
         Nullptr crash in ApplyStyleCommand::applyRelativeFontStyleChange

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (273380 => 273381)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2021-02-24 12:53:56 UTC (rev 273380)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2021-02-24 13:09:49 UTC (rev 273381)
@@ -1,3 +1,15 @@
+2021-02-24  Imanol Fernandez  <ifernan...@igalia.com>
+
+        Implement WebXR getViewport
+        https://bugs.webkit.org/show_bug.cgi?id=222270
+
+        Reviewed by Sergio Villar Senin.
+
+        Update WebXR Viewport test expectations.
+
+        * web-platform-tests/webxr/xrViewport_valid.https-expected.txt: Added.
+        * web-platform-tests/webxr/xrWebGLLayer_viewports.https-expected.txt: Added.
+
 2021-02-22  Ryan Haddad  <ryanhad...@apple.com>
 
         Implement the Top-level await proposal

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrViewport_valid.https-expected.txt (0 => 273381)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrViewport_valid.https-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrViewport_valid.https-expected.txt	2021-02-24 13:09:49 UTC (rev 273381)
@@ -0,0 +1,3 @@
+
+PASS XRViewport attributes are valid
+

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrWebGLLayer_viewports.https-expected.txt (0 => 273381)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrWebGLLayer_viewports.https-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrWebGLLayer_viewports.https-expected.txt	2021-02-24 13:09:49 UTC (rev 273381)
@@ -0,0 +1,4 @@
+
+PASS XRWebGLLayer reports a valid viewports for immersive sessions
+PASS XRWebGLLayer reports a valid viewports for inline sessions
+

Modified: trunk/LayoutTests/platform/wpe/TestExpectations (273380 => 273381)


--- trunk/LayoutTests/platform/wpe/TestExpectations	2021-02-24 12:53:56 UTC (rev 273380)
+++ trunk/LayoutTests/platform/wpe/TestExpectations	2021-02-24 13:09:49 UTC (rev 273381)
@@ -647,8 +647,6 @@
 imported/w3c/web-platform-tests/webxr/xrView_eyes.https.html [ Pass ]
 imported/w3c/web-platform-tests/webxr/xrView_match.https.html [ Pass ]
 imported/w3c/web-platform-tests/webxr/xrView_oneframeupdate.https.html [ Pass ]
-webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrWebGLLayer_constructor.https.html [ Pass ]
-webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrWebGLLayer_framebuffer_sameObject.https.html [ Pass ]
 imported/w3c/web-platform-tests/webxr/navigator_xr_sameObject.https.html [ Pass ]
 imported/w3c/web-platform-tests/webxr/xrReferenceSpace_originOffset_viewer.https.html [ Pass ]
 imported/w3c/web-platform-tests/webxr/xrReferenceSpace_relationships.https.html [ Pass ]
@@ -666,6 +664,10 @@
 imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_timestamp.https.html [ Pass ]
 imported/w3c/web-platform-tests/webxr/xrSession_requestReferenceSpace.https.html [ Pass ]
 imported/w3c/web-platform-tests/webxr/xrSession_viewer_referenceSpace.https.html [ Pass ]
+imported/w3c/web-platform-tests/webxr/xrViewport_valid.https.html [ Pass ]
+imported/w3c/web-platform-tests/webxr/xrWebGLLayer_constructor.https.html [ Pass ]
+imported/w3c/web-platform-tests/webxr/xrWebGLLayer_framebuffer_sameObject.https.html [ Pass ]
+imported/w3c/web-platform-tests/webxr/xrWebGLLayer_viewports.https.html [ Pass ]
 imported/w3c/web-platform-tests/webxr/render_state_vertical_fov_immersive.https.html [ Pass ]
 imported/w3c/web-platform-tests/webxr/render_state_update.https.html [ Pass ]
 http/wpt/webxr/xrSession_end_device_reports_shutdown.https.html [ Pass ]

Modified: trunk/Source/WebCore/ChangeLog (273380 => 273381)


--- trunk/Source/WebCore/ChangeLog	2021-02-24 12:53:56 UTC (rev 273380)
+++ trunk/Source/WebCore/ChangeLog	2021-02-24 13:09:49 UTC (rev 273381)
@@ -1,3 +1,55 @@
+2021-02-24  Imanol Fernandez  <ifernan...@igalia.com>
+
+        Implement WebXR getViewport
+        https://bugs.webkit.org/show_bug.cgi?id=222270
+
+        Reviewed by Sergio Villar Senin.
+
+        * Modules/webxr/WebXRFrame.cpp:
+        (WebCore::WebXRFrame::getViewerPose): set WebXRView viewport modifiable value.
+        * Modules/webxr/WebXRFrame.h:
+        (WebCore::WebXRFrame::isAnimationFrame const): add method.
+
+        * Modules/webxr/WebXRSession.cpp: Implement supportsViewportScaling().
+        (WebCore::WebXRSession::supportsViewportScaling const):
+        * Modules/webxr/WebXRSession.h:
+
+        * Modules/webxr/WebXRView.cpp: Add viewport scale data.
+        (WebCore::WebXRView::create):
+        (WebCore::WebXRView::WebXRView):
+        (WebCore::WebXRView::recommendedViewportScale const):
+        (WebCore::WebXRView::requestViewportScale):
+        * Modules/webxr/WebXRView.h:
+        (WebCore::WebXRView::frame const):
+        (WebCore::WebXRView::currentViewportScale const):
+        (WebCore::WebXRView::setCurrentViewportScale):
+        (WebCore::WebXRView::requestedViewportScale const):
+        (WebCore::WebXRView::isViewportModifiable const):
+        (WebCore::WebXRView::setViewportModifiable):
+
+        * Modules/webxr/WebXRView.idl: add requestViewportScale() and recommendedViewportScale.
+
+        * Modules/webxr/WebXRViewport.cpp: Implement viewport rect values.
+        (WebCore::WebXRViewport::create):
+        (WebCore::WebXRViewport::WebXRViewport):
+        * Modules/webxr/WebXRViewport.h:
+        (WebCore::WebXRViewport::x const):
+        (WebCore::WebXRViewport::y const):
+        (WebCore::WebXRViewport::width const):
+        (WebCore::WebXRViewport::height const):
+        (WebCore::WebXRViewport::updateViewport):
+
+        * Modules/webxr/WebXRWebGLLayer.cpp: Implement getViewport()
+        (WebCore::WebXRWebGLLayer::WebXRWebGLLayer):
+        (WebCore::m_rightViewport):
+        (WebCore::WebXRWebGLLayer::getViewport):
+        * Modules/webxr/WebXRWebGLLayer.h:
+
+        * Modules/webxr/WebXRWebGLLayer.idl: Add MayThrowException
+
+        * platform/xr/PlatformXR.h: Add supportsViewportScaling method
+        (PlatformXR::Device::supportsViewportScaling const):
+
 2021-02-17  Sergio Villar Senin  <svil...@igalia.com>
 
         Nullptr crash in ApplyStyleCommand::applyRelativeFontStyleChange

Modified: trunk/Source/WebCore/Modules/webxr/WebXRFrame.cpp (273380 => 273381)


--- trunk/Source/WebCore/Modules/webxr/WebXRFrame.cpp	2021-02-24 12:53:56 UTC (rev 273380)
+++ trunk/Source/WebCore/Modules/webxr/WebXRFrame.cpp	2021-02-24 13:09:49 UTC (rev 273381)
@@ -201,7 +201,8 @@
             return TransformationMatrix::fromProjection(fov, aspect, near, far).toColumnMajorFloatArray();
         });
 
-        auto xrView = WebXRView::create(view.eye, WTFMove(transform), Float32Array::create(projection.data(), projection.size()));
+        auto xrView = WebXRView::create(makeRef(*this), view.eye, WTFMove(transform), Float32Array::create(projection.data(), projection.size()));
+        xrView->setViewportModifiable(m_session->supportsViewportScaling());
 
         //  8.8. Append xrview to xrviews
         xrViews.append(WTFMove(xrView));

Modified: trunk/Source/WebCore/Modules/webxr/WebXRFrame.h (273380 => 273381)


--- trunk/Source/WebCore/Modules/webxr/WebXRFrame.h	2021-02-24 12:53:56 UTC (rev 273380)
+++ trunk/Source/WebCore/Modules/webxr/WebXRFrame.h	2021-02-24 13:09:49 UTC (rev 273381)
@@ -61,6 +61,7 @@
 
     void setActive(bool active) { m_active = active; }
     bool isActive() const { return m_active; }
+    bool isAnimationFrame() const { return m_isAnimationFrame; }
 
     static TransformationMatrix matrixFromPose(const PlatformXR::Device::FrameData::Pose&);
 

Modified: trunk/Source/WebCore/Modules/webxr/WebXRSession.cpp (273380 => 273381)


--- trunk/Source/WebCore/Modules/webxr/WebXRSession.cpp	2021-02-24 12:53:56 UTC (rev 273380)
+++ trunk/Source/WebCore/Modules/webxr/WebXRSession.cpp	2021-02-24 13:09:49 UTC (rev 273381)
@@ -306,6 +306,14 @@
     return m_device->recommendedResolution(m_mode);
 }
 
+// https://immersive-web.github.io/webxr/#view-viewport-modifiable
+bool WebXRSession::supportsViewportScaling() const
+{
+    ASSERT(m_device);
+    // Only immersive sessions support viewport scaling.
+    return m_mode == XRSessionMode::ImmersiveVr && m_device->supportsViewportScaling();
+}
+
 // https://immersive-web.github.io/webxr/#shut-down-the-session
 void WebXRSession::shutdown(InitiatedBySystem initiatedBySystem)
 {

Modified: trunk/Source/WebCore/Modules/webxr/WebXRSession.h (273380 => 273381)


--- trunk/Source/WebCore/Modules/webxr/WebXRSession.h	2021-02-24 12:53:56 UTC (rev 273380)
+++ trunk/Source/WebCore/Modules/webxr/WebXRSession.h	2021-02-24 13:09:49 UTC (rev 273381)
@@ -81,6 +81,7 @@
 
     IntSize nativeWebGLFramebufferResolution() const;
     IntSize recommendedWebGLFramebufferResolution() const;
+    bool supportsViewportScaling() const; 
 
     // EventTarget.
     ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); }

Modified: trunk/Source/WebCore/Modules/webxr/WebXRView.cpp (273380 => 273381)


--- trunk/Source/WebCore/Modules/webxr/WebXRView.cpp	2021-02-24 12:53:56 UTC (rev 273380)
+++ trunk/Source/WebCore/Modules/webxr/WebXRView.cpp	2021-02-24 13:09:49 UTC (rev 273381)
@@ -28,6 +28,7 @@
 
 #if ENABLE(WEBXR)
 
+#include "WebXRFrame.h"
 #include "WebXRRigidTransform.h"
 #include <_javascript_Core/TypedArrayInlines.h>
 #include <wtf/IsoMallocInlines.h>
@@ -34,22 +35,43 @@
 
 namespace WebCore {
 
+// Arbitrary value for minimum viewport scaling.
+// Below this threshold the resulting viewport would be too pixelated.
+static constexpr double kMinViewportScale = 0.1;
+
 WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRView);
 
-Ref<WebXRView> WebXRView::create(XREye eye, Ref<WebXRRigidTransform>&& transform, Ref<Float32Array>&& projection)
+Ref<WebXRView> WebXRView::create(Ref<WebXRFrame>&& frame, XREye eye, Ref<WebXRRigidTransform>&& transform, Ref<Float32Array>&& projection)
 {
-    return adoptRef(*new WebXRView(eye, WTFMove(transform), WTFMove(projection)));
+    return adoptRef(*new WebXRView(WTFMove(frame), eye, WTFMove(transform), WTFMove(projection)));
 }
 
-WebXRView::WebXRView(XREye eye, Ref<WebXRRigidTransform>&& transform, Ref<Float32Array>&& projection)
-    : m_eye(eye)
+WebXRView::WebXRView(Ref<WebXRFrame>&& frame, XREye eye, Ref<WebXRRigidTransform>&& transform, Ref<Float32Array>&& projection)
+    : m_frame(WTFMove(frame))
+    , m_eye(eye)
     , m_transform(WTFMove(transform))
-    , m_projection(projection)
+    , m_projection(WTFMove(projection))
 {
 }
 
 WebXRView::~WebXRView() = default;
 
+// https://immersive-web.github.io/webxr/#dom-xrview-recommendedviewportscale
+Optional<double> WebXRView::recommendedViewportScale() const
+{
+    // Return null if the system does not implement a heuristic or method for determining a recommended scale.
+    return WTF::nullopt;
+}
+
+// https://immersive-web.github.io/webxr/#dom-xrview-requestviewportscale
+void WebXRView::requestViewportScale(Optional<double> value)
+{
+    if (!value || *value <= 0.0)
+        return;
+    m_requestedViewportScale = std::clamp(*value, kMinViewportScale, 1.0);
+}
+
+
 } // namespace WebCore
 
 #endif // ENABLE(WEBXR)

Modified: trunk/Source/WebCore/Modules/webxr/WebXRView.h (273380 => 273381)


--- trunk/Source/WebCore/Modules/webxr/WebXRView.h	2021-02-24 12:53:56 UTC (rev 273380)
+++ trunk/Source/WebCore/Modules/webxr/WebXRView.h	2021-02-24 13:09:49 UTC (rev 273381)
@@ -39,23 +39,36 @@
 
 class WebXRFrame;
 class WebXRRigidTransform;
+class WebXRSession;
 
 class WebXRView : public RefCounted<WebXRView> {
     WTF_MAKE_ISO_ALLOCATED_EXPORT(WebXRView, WEBCORE_EXPORT);
 public:
-    WEBCORE_EXPORT static Ref<WebXRView> create(XREye, Ref<WebXRRigidTransform>&&, Ref<Float32Array>&&);
+    WEBCORE_EXPORT static Ref<WebXRView> create(Ref<WebXRFrame>&&, XREye, Ref<WebXRRigidTransform>&&, Ref<Float32Array>&&);
     WEBCORE_EXPORT ~WebXRView();
 
+    const WebXRFrame& frame() const { return m_frame.get(); }
     XREye eye() const { return m_eye; }
     const Float32Array& projectionMatrix() const { return m_projection.get(); }
     const WebXRRigidTransform& transform() const { return m_transform.get(); }
 
+    Optional<double> recommendedViewportScale() const;
+    void requestViewportScale(Optional<double>);
+
+    double requestedViewportScale() const { return m_requestedViewportScale; }
+    bool isViewportModifiable() const { return m_viewportModifiable; }
+    void setViewportModifiable(bool modifiable) { m_viewportModifiable = modifiable; }
+
 private:
-    WebXRView(XREye, Ref<WebXRRigidTransform>&&, Ref<Float32Array>&&);
+    WebXRView(Ref<WebXRFrame>&&, XREye, Ref<WebXRRigidTransform>&&, Ref<Float32Array>&&);
 
+    Ref<WebXRFrame> m_frame;
     XREye m_eye;
     Ref<WebXRRigidTransform> m_transform;
     Ref<Float32Array> m_projection;
+    bool m_viewportModifiable { false };
+    double m_requestedViewportScale { 1.0 };
+
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/Modules/webxr/WebXRView.idl (273380 => 273381)


--- trunk/Source/WebCore/Modules/webxr/WebXRView.idl	2021-02-24 12:53:56 UTC (rev 273380)
+++ trunk/Source/WebCore/Modules/webxr/WebXRView.idl	2021-02-24 13:09:49 UTC (rev 273381)
@@ -34,4 +34,6 @@
     readonly attribute XREye eye;
     readonly attribute Float32Array projectionMatrix;
     [SameObject] readonly attribute WebXRRigidTransform transform;
+    readonly attribute double? recommendedViewportScale;
+    undefined requestViewportScale(double? scale);
 };

Modified: trunk/Source/WebCore/Modules/webxr/WebXRViewport.cpp (273380 => 273381)


--- trunk/Source/WebCore/Modules/webxr/WebXRViewport.cpp	2021-02-24 12:53:56 UTC (rev 273380)
+++ trunk/Source/WebCore/Modules/webxr/WebXRViewport.cpp	2021-02-24 13:09:49 UTC (rev 273381)
@@ -34,33 +34,16 @@
 
 WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRViewport);
 
-Ref<WebXRViewport> WebXRViewport::create()
+Ref<WebXRViewport> WebXRViewport::create(const IntRect& viewport)
 {
-    return adoptRef(*new WebXRViewport);
+    return adoptRef(*new WebXRViewport(viewport));
 }
 
-WebXRViewport::WebXRViewport() = default;
-
-int WebXRViewport::x() const
+WebXRViewport::WebXRViewport(const IntRect& viewport)
+    : m_viewport(viewport)
 {
-    return 0;
 }
 
-int WebXRViewport::y() const
-{
-    return 0;
-}
-
-int WebXRViewport::width() const
-{
-    return 0;
-}
-
-int WebXRViewport::height() const
-{
-    return 0;
-}
-
 } // namespace WebCore
 
 #endif // ENABLE(WEBXR)

Modified: trunk/Source/WebCore/Modules/webxr/WebXRViewport.h (273380 => 273381)


--- trunk/Source/WebCore/Modules/webxr/WebXRViewport.h	2021-02-24 12:53:56 UTC (rev 273380)
+++ trunk/Source/WebCore/Modules/webxr/WebXRViewport.h	2021-02-24 13:09:49 UTC (rev 273381)
@@ -27,6 +27,7 @@
 
 #if ENABLE(WEBXR)
 
+#include "IntRect.h"
 #include <wtf/IsoMalloc.h>
 #include <wtf/Ref.h>
 #include <wtf/RefCounted.h>
@@ -36,15 +37,19 @@
 class WebXRViewport : public RefCounted<WebXRViewport> {
     WTF_MAKE_ISO_ALLOCATED(WebXRViewport);
 public:
-    static Ref<WebXRViewport> create();
+    static Ref<WebXRViewport> create(const IntRect&);
 
-    int x() const;
-    int y() const;
-    int width() const;
-    int height() const;
+    int x() const { return m_viewport.x(); }
+    int y() const { return m_viewport.y(); }
+    int width() const { return m_viewport.width(); }
+    int height() const { return m_viewport.height(); }
 
+    void updateViewport(const IntRect& viewport) { m_viewport = viewport; }
+
 private:
-    WebXRViewport();
+    explicit WebXRViewport(const IntRect&);
+
+    IntRect m_viewport;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/Modules/webxr/WebXRWebGLLayer.cpp (273380 => 273381)


--- trunk/Source/WebCore/Modules/webxr/WebXRWebGLLayer.cpp	2021-02-24 12:53:56 UTC (rev 273380)
+++ trunk/Source/WebCore/Modules/webxr/WebXRWebGLLayer.cpp	2021-02-24 13:09:49 UTC (rev 273381)
@@ -37,7 +37,9 @@
 #include "WebGL2RenderingContext.h"
 #endif
 #include "WebGLRenderingContextBase.h"
+#include "WebXRFrame.h"
 #include "WebXRSession.h"
+#include "WebXRView.h"
 #include "WebXRViewport.h"
 #include "XRWebGLLayerInit.h"
 #include <wtf/IsoMallocInlines.h>
@@ -97,6 +99,8 @@
     : WebXRLayer(session->scriptExecutionContext())
     , m_session(WTFMove(session))
     , m_context(WTFMove(context))
+    , m_leftViewportData({ WebXRViewport::create({ }) })
+    , m_rightViewportData({ WebXRViewport::create({ }) })
 {
     // 7. Initialize layer’s ignoreDepthValues as follows:
     //   7.1 If layerInit’s ignoreDepthValues value is false and the XR Compositor will make use of depth values,
@@ -144,9 +148,18 @@
         // 2. Initialize layer’s framebuffer to null.
         m_framebuffer.object = nullptr;
     }
+
+    auto canvasElement = canvas();
+    if (canvasElement)
+        canvasElement->addObserver(*this);
 }
 
-WebXRWebGLLayer::~WebXRWebGLLayer() = default;
+WebXRWebGLLayer::~WebXRWebGLLayer()
+{
+    auto canvasElement = canvas();
+    if (canvasElement)
+        canvasElement->removeObserver(*this);
+}
 
 bool WebXRWebGLLayer::antialias() const
 {
@@ -183,9 +196,39 @@
         });
 }
 
-RefPtr<WebXRViewport> WebXRWebGLLayer::getViewport(const WebXRView&)
+// https://immersive-web.github.io/webxr/#dom-xrwebgllayer-getviewport
+ExceptionOr<RefPtr<WebXRViewport>> WebXRWebGLLayer::getViewport(WebXRView& view)
 {
-    return { };
+    // 1. Let session be view’s session.
+    // 2. Let frame be session’s animation frame.
+    // 3. If session is not equal to layer’s session, throw an InvalidStateError and abort these steps.
+    if (&view.frame().session() != m_session.ptr())
+        return Exception { InvalidStateError };
+
+    // 4. If frame’s active boolean is false, throw an InvalidStateError and abort these steps.
+    // 5. If view’s frame is not equal to frame, throw an InvalidStateError and abort these steps.
+    if (!view.frame().isActive() || !view.frame().isAnimationFrame())
+        return Exception { InvalidStateError }; 
+
+    auto& viewportData = view.eye() == XREye::Right ? m_rightViewportData : m_leftViewportData;
+
+    // 6. If the viewport modifiable flag is true and view’s requested viewport scale is not equal to current viewport scale:
+    //   6.1 Set current viewport scale to requested viewport scale.
+    //   6.2 Compute the scaled viewport.
+    if (view.isViewportModifiable() && view.requestedViewportScale() != viewportData.currentScale) {
+        viewportData.currentScale = view.requestedViewportScale();
+        m_viewportsDirty = true;
+    }
+
+    // 7. Set the view’s viewport modifiable flag to false.
+    view.setViewportModifiable(false);
+
+    if (m_viewportsDirty)
+        computeViewports();
+
+    // 8. Let viewport be the XRViewport from the list of viewport objects associated with view.
+    // 9. Return viewport.
+    return RefPtr<WebXRViewport>(viewportData.viewport.copyRef());
 }
 
 double WebXRWebGLLayer::getNativeFramebufferScaleFactor(const WebXRSession& session)
@@ -213,6 +256,38 @@
     });
 }
 
+// https://immersive-web.github.io/webxr/#xrview-obtain-a-scaled-viewport
+void WebXRWebGLLayer::computeViewports()
+{
+    auto roundDown = [](double value) -> int {
+        // Round down to integer value and ensure that the value is not zero.
+        return std::max(1, static_cast<int>(std::floor(value)));
+    };
+
+    auto width = framebufferWidth();
+    auto height = framebufferHeight();
+
+    if (m_session->mode() == XRSessionMode::ImmersiveVr) {
+        // Update left viewport
+        auto scale = m_leftViewportData.currentScale;
+        m_leftViewportData.viewport->updateViewport(IntRect(0, 0, roundDown(width * 0.5 * scale), roundDown(height * scale)));
+
+        // Update right viewport
+        scale = m_rightViewportData.currentScale;
+        m_rightViewportData.viewport->updateViewport(IntRect(width * 0.5, 0, roundDown(width * 0.5 * scale), roundDown(height * scale)));
+    } else {
+        // We reuse m_leftViewport for XREye::None.
+        m_leftViewportData.viewport->updateViewport(IntRect(0, 0, width, height));
+    }
+
+    m_viewportsDirty = false;
+}
+
+void WebXRWebGLLayer::canvasResized(CanvasBase&)
+{
+    m_viewportsDirty = true;
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(WEBXR)

Modified: trunk/Source/WebCore/Modules/webxr/WebXRWebGLLayer.h (273380 => 273381)


--- trunk/Source/WebCore/Modules/webxr/WebXRWebGLLayer.h	2021-02-24 12:53:56 UTC (rev 273380)
+++ trunk/Source/WebCore/Modules/webxr/WebXRWebGLLayer.h	2021-02-24 13:09:49 UTC (rev 273381)
@@ -27,6 +27,7 @@
 
 #if ENABLE(WEBXR)
 
+#include "CanvasBase.h"
 #include "ExceptionOr.h"
 #include "WebXRLayer.h"
 #include <wtf/IsoMalloc.h>
@@ -48,7 +49,7 @@
 class WebXRViewport;
 struct XRWebGLLayerInit;
 
-class WebXRWebGLLayer : public WebXRLayer {
+class WebXRWebGLLayer : public WebXRLayer, private CanvasObserver {
     WTF_MAKE_ISO_ALLOCATED(WebXRWebGLLayer);
 public:
 
@@ -69,7 +70,7 @@
     unsigned framebufferWidth() const;
     unsigned framebufferHeight() const;
 
-    RefPtr<WebXRViewport> getViewport(const WebXRView&);
+    ExceptionOr<RefPtr<WebXRViewport>> getViewport(WebXRView&);
 
     static double getNativeFramebufferScaleFactor(const WebXRSession&);
 
@@ -82,14 +83,28 @@
 private:
     WebXRWebGLLayer(Ref<WebXRSession>&&, WebXRRenderingContext&&, const XRWebGLLayerInit&);
 
+    void computeViewports();
     static IntSize computeNativeWebGLFramebufferResolution();
     static IntSize computeRecommendedWebGLFramebufferResolution();
 
+    void canvasChanged(CanvasBase&, const FloatRect&) final { };
+    void canvasResized(CanvasBase&) final;
+    void canvasDestroyed(CanvasBase&) final { };
+
     Ref<WebXRSession> m_session;
     WebXRRenderingContext m_context;
+
+    struct ViewportData {
+        Ref<WebXRViewport> viewport;
+        double currentScale { 1.0 };
+    };
+
+    ViewportData m_leftViewportData;
+    ViewportData m_rightViewportData;
     bool m_antialias { false };
     bool m_ignoreDepthValues { false };
     bool m_isCompositionEnabled { true };
+    bool m_viewportsDirty { true };
 
     struct {
         RefPtr<WebGLFramebuffer> object;

Modified: trunk/Source/WebCore/Modules/webxr/WebXRWebGLLayer.idl (273380 => 273381)


--- trunk/Source/WebCore/Modules/webxr/WebXRWebGLLayer.idl	2021-02-24 12:53:56 UTC (rev 273380)
+++ trunk/Source/WebCore/Modules/webxr/WebXRWebGLLayer.idl	2021-02-24 13:09:49 UTC (rev 273381)
@@ -49,7 +49,7 @@
     readonly attribute unsigned long framebufferHeight;
 
     // Methods
-    WebXRViewport? getViewport(WebXRView view);
+    [MayThrowException] WebXRViewport? getViewport(WebXRView view);
 
     // Static Methods
     static double getNativeFramebufferScaleFactor(WebXRSession session);

Modified: trunk/Source/WebCore/platform/xr/PlatformXR.h (273380 => 273381)


--- trunk/Source/WebCore/platform/xr/PlatformXR.h	2021-02-24 12:53:56 UTC (rev 273380)
+++ trunk/Source/WebCore/platform/xr/PlatformXR.h	2021-02-24 13:09:49 UTC (rev 273381)
@@ -75,6 +75,7 @@
     virtual WebCore::IntSize recommendedResolution(SessionMode) { return { 1, 1 }; }
 
     bool supportsOrientationTracking() const { return m_supportsOrientationTracking; }
+    bool supportsViewportScaling() const { return m_supportsViewportScaling; }
 
     virtual void initializeTrackingAndRendering(SessionMode) = 0;
     virtual void shutDownTrackingAndRendering() = 0;
@@ -141,6 +142,7 @@
     EnabledFeaturesPerModeMap m_enabledFeaturesMap;
 
     bool m_supportsOrientationTracking { false };
+    bool m_supportsViewportScaling { false };
     WeakPtr<TrackingAndRenderingClient> m_trackingAndRenderingClient;
 };
 

Modified: trunk/Source/WebCore/testing/WebFakeXRDevice.cpp (273380 => 273381)


--- trunk/Source/WebCore/testing/WebFakeXRDevice.cpp	2021-02-24 12:53:56 UTC (rev 273380)
+++ trunk/Source/WebCore/testing/WebFakeXRDevice.cpp	2021-02-24 13:09:49 UTC (rev 273381)
@@ -65,6 +65,12 @@
         m_trackingAndRenderingClient->sessionDidEnd();
 }
 
+WebCore::IntSize SimulatedXRDevice::recommendedResolution(PlatformXR::SessionMode)
+{
+    // Return at least a 2 pixel size so we can have different viewports for left and right eyes
+    return IntSize(2, 2);
+}
+
 void SimulatedXRDevice::shutDownTrackingAndRendering()
 {
     if (m_supportsShutdownNotification)

Modified: trunk/Source/WebCore/testing/WebFakeXRDevice.h (273380 => 273381)


--- trunk/Source/WebCore/testing/WebFakeXRDevice.h	2021-02-24 12:53:56 UTC (rev 273380)
+++ trunk/Source/WebCore/testing/WebFakeXRDevice.h	2021-02-24 13:09:49 UTC (rev 273381)
@@ -80,6 +80,7 @@
     void simulateShutdownCompleted();
     void scheduleOnNextFrame(Function<void()>&&);
 private:
+    WebCore::IntSize recommendedResolution(PlatformXR::SessionMode) final;
     void initializeTrackingAndRendering(PlatformXR::SessionMode) final { }
     void shutDownTrackingAndRendering() final;
     bool supportsSessionShutdownNotification() const final { return m_supportsShutdownNotification; }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to