Commit 9a578ad0 authored by Piotr Bialecki's avatar Piotr Bialecki Committed by Commit Bot

Add WebXR Anchors API - Web IDL and stubs

Add Web IDL for XRAnchor and related interfaces along with stub
implementation so that everything compiles & links.

Additionally, refactor XRPlaneSet into an XRSetlike template class to
allow for code reuse between XRPlaneSet, XRAnchorSet, and potentially
other setlikes.

Bug: 992027
Change-Id: I59f1b622dcfb6cd3034ca6f493381443d2094956
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1746955
Commit-Queue: Piotr Bialecki <bialpio@chromium.org>
Reviewed-by: default avatarBrandon Jones <bajones@chromium.org>
Reviewed-by: default avatarMounir Lamouri <mlamouri@chromium.org>
Cr-Commit-Position: refs/heads/master@{#688757}
parent d826fdb1
......@@ -507,6 +507,8 @@ modules_idl_files =
"webusb/usb_isochronous_out_transfer_result.idl",
"webusb/usb_out_transfer_result.idl",
"xr/xr.idl",
"xr/xr_anchor.idl",
"xr/xr_anchor_set.idl",
"xr/xr_bounded_reference_space.idl",
"xr/xr_frame.idl",
"xr/xr_hit_result.idl",
......
......@@ -12,6 +12,10 @@ blink_modules_sources("xr") {
"type_converters.h",
"xr.cc",
"xr.h",
"xr_anchor.cc",
"xr_anchor.h",
"xr_anchor_set.cc",
"xr_anchor_set.h",
"xr_bounded_reference_space.cc",
"xr_bounded_reference_space.h",
"xr_canvas_input_provider.cc",
......@@ -58,6 +62,7 @@ blink_modules_sources("xr") {
"xr_session.h",
"xr_session_event.cc",
"xr_session_event.h",
"xr_setlike.h",
"xr_space.cc",
"xr_space.h",
"xr_target_ray_space.cc",
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/xr/xr_anchor.h"
#include "third_party/blink/renderer/modules/xr/xr_session.h"
#include "third_party/blink/renderer/modules/xr/xr_space.h"
namespace blink {
XRSpace* XRAnchor::anchorSpace() const {
return nullptr;
}
TransformationMatrix XRAnchor::poseMatrix() const {
return {};
}
double XRAnchor::lastChangedTime() const {
return last_changed_time_;
}
void XRAnchor::detach() {}
void XRAnchor::Trace(blink::Visitor* visitor) {
visitor->Trace(session_);
visitor->Trace(anchor_space_);
ScriptWrappable::Trace(visitor);
}
} // namespace blink
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_ANCHOR_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_ANCHOR_H_
#include <memory>
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h"
namespace blink {
class XRSession;
class XRSpace;
class XRAnchor : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
XRSpace* anchorSpace() const;
TransformationMatrix poseMatrix() const;
double lastChangedTime() const;
void detach();
void Trace(blink::Visitor* visitor) override;
private:
// Anchor's pose in device (mojo) space.
std::unique_ptr<TransformationMatrix> pose_matrix_;
Member<XRSession> session_;
double last_changed_time_;
// Cached anchor space - it will be created by `anchorSpace()` if it's not
// set.
mutable Member<XRSpace> anchor_space_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_ANCHOR_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
[
SecureContext,
Exposed=Window,
RuntimeEnabled=WebXRAnchors
]
interface XRAnchor {
readonly attribute XRSpace anchorSpace;
readonly attribute DOMHighResTimeStamp lastChangedTime;
void detach();
};
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/xr/xr_anchor_set.h"
namespace blink {
XRAnchorSet::XRAnchorSet(HeapHashSet<Member<XRAnchor>> anchors)
: anchors_(anchors) {}
const HeapHashSet<Member<XRAnchor>>& XRAnchorSet::elements() const {
return anchors_;
}
void XRAnchorSet::Trace(blink::Visitor* visitor) {
visitor->Trace(anchors_);
ScriptWrappable::Trace(visitor);
}
} // namespace blink
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_ANCHOR_SET_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_ANCHOR_SET_H_
#include "third_party/blink/renderer/bindings/core/v8/iterable.h"
#include "third_party/blink/renderer/modules/xr/xr_anchor.h"
#include "third_party/blink/renderer/modules/xr/xr_setlike.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
namespace blink {
class XRAnchorSet : public ScriptWrappable, public XRSetlike<XRAnchor> {
DEFINE_WRAPPERTYPEINFO();
public:
explicit XRAnchorSet(HeapHashSet<Member<XRAnchor>> anchors);
void Trace(blink::Visitor* visitor) override;
protected:
const HeapHashSet<Member<XRAnchor>>& elements() const override;
private:
HeapHashSet<Member<XRAnchor>> anchors_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_ANCHOR_SET_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
[
SecureContext,
Exposed=Window,
RuntimeEnabled=WebXRAnchors
]
interface XRAnchorSet {
readonly setlike<XRAnchor>;
};
......@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/modules/xr/xr_plane.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/modules/xr/type_converters.h"
#include "third_party/blink/renderer/modules/xr/xr_plane_space.h"
#include "third_party/blink/renderer/modules/xr/xr_reference_space.h"
......@@ -72,6 +73,18 @@ HeapVector<Member<DOMPointReadOnly>> XRPlane::polygon() const {
return polygon_;
}
ScriptPromise XRPlane::createAnchor(ScriptState* script_state,
XRPose* pose,
XRSpace* space) {
// TODO(https://crbug.com/992033): Implement anchor creation from a plane
// instead of rejecting the promise. This'll cause the string literal used
// below to be removed.
return ScriptPromise::RejectWithDOMException(
script_state,
MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotSupportedError,
"Device does not support anchors!"));
}
void XRPlane::Update(const device::mojom::blink::XRPlaneDataPtr& plane_data,
double timestamp) {
DVLOG(3) << __func__;
......
......@@ -9,6 +9,7 @@
#include "base/optional.h"
#include "device/vr/public/mojom/vr_service.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/geometry/dom_point_read_only.h"
#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
......@@ -17,6 +18,7 @@ namespace blink {
class XRSession;
class XRSpace;
class XRPose;
class XRPlane : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
......@@ -41,6 +43,10 @@ class XRPlane : public ScriptWrappable {
HeapVector<Member<DOMPointReadOnly>> polygon() const;
double lastChangedTime() const;
ScriptPromise createAnchor(ScriptState* script_state,
XRPose* pose,
XRSpace* space);
// Updates plane data from passed in |plane_data|. The resulting instance
// should be equivalent to the instance that would be create by calling
// XRPlane(plane_data).
......
......@@ -19,4 +19,6 @@ interface XRPlane {
readonly attribute FrozenArray<DOMPointReadOnly> polygon;
readonly attribute XRPlaneOrientation? orientation;
readonly attribute DOMHighResTimeStamp lastChangedTime;
[RuntimeEnabled=WebXRAnchors, CallWith=ScriptState] Promise<XRAnchor> createAnchor(XRPose pose, XRSpace space);
};
......@@ -8,22 +8,8 @@ namespace blink {
XRPlaneSet::XRPlaneSet(HeapHashSet<Member<XRPlane>> planes) : planes_(planes) {}
unsigned XRPlaneSet::size() const {
return planes_.size();
}
bool XRPlaneSet::hasForBinding(ScriptState*,
XRPlane* plane,
ExceptionState&) const {
DCHECK(plane);
return planes_.find(plane) != planes_.end();
}
XRPlaneSet::IterationSource* XRPlaneSet::StartIteration(
ScriptState* script_state,
ExceptionState& exception_state) {
return MakeGarbageCollected<XRPlaneSet::IterationSource>(planes_);
const HeapHashSet<Member<XRPlane>>& XRPlaneSet::elements() const {
return planes_;
}
void XRPlaneSet::Trace(blink::Visitor* visitor) {
......@@ -31,31 +17,4 @@ void XRPlaneSet::Trace(blink::Visitor* visitor) {
ScriptWrappable::Trace(visitor);
}
XRPlaneSet::IterationSource::IterationSource(
const HeapHashSet<Member<XRPlane>>& planes)
: index_(0) {
for (auto plane : planes) {
planes_.push_back(plane);
}
}
bool XRPlaneSet::IterationSource::Next(ScriptState* script_state,
Member<XRPlane>& key,
Member<XRPlane>& value,
ExceptionState& exception_state) {
if (index_ >= planes_.size()) {
return false;
}
key = value = planes_[index_];
++index_;
return true;
}
void XRPlaneSet::IterationSource::Trace(blink::Visitor* visitor) {
visitor->Trace(planes_);
SetlikeIterable<Member<XRPlane>>::IterationSource::Trace(visitor);
}
} // namespace blink
......@@ -5,53 +5,24 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_PLANE_SET_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_PLANE_SET_H_
#include "third_party/blink/renderer/bindings/core/v8/iterable.h"
#include "third_party/blink/renderer/modules/xr/xr_plane.h"
#include "third_party/blink/renderer/modules/xr/xr_setlike.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
namespace blink {
class XRPlaneSet : public ScriptWrappable,
public SetlikeIterable<Member<XRPlane>> {
class XRPlaneSet : public ScriptWrappable, public XRSetlike<XRPlane> {
DEFINE_WRAPPERTYPEINFO();
public:
explicit XRPlaneSet(HeapHashSet<Member<XRPlane>> planes);
unsigned size() const;
// Returns true if passed in |plane| is a member of the XRPlaneSet.
bool hasForBinding(ScriptState* script_state,
XRPlane* plane,
ExceptionState& exception_state) const;
void Trace(blink::Visitor* visitor) override;
private:
class IterationSource final
: public SetlikeIterable<Member<XRPlane>>::IterationSource {
public:
explicit IterationSource(const HeapHashSet<Member<XRPlane>>& planes);
bool Next(ScriptState* script_state,
Member<XRPlane>& key,
Member<XRPlane>& value,
ExceptionState& exception_state) override;
void Trace(blink::Visitor* visitor) override;
private:
HeapVector<Member<XRPlane>> planes_;
unsigned index_;
};
// Starts iteration over XRPlaneSet.
// Needed for SetlikeIterable to work properly.
XRPlaneSet::IterationSource* StartIteration(
ScriptState* script_state,
ExceptionState& exception_state) override;
protected:
const HeapHashSet<Member<XRPlane>>& elements() const override;
private:
HeapHashSet<Member<XRPlane>> planes_;
};
......
......@@ -61,6 +61,8 @@ const char kNoSpaceSpecified[] = "No XRSpace specified.";
const char kHitTestNotSupported[] = "Device does not support hit-test!";
const char kAnchorsNotSupported[] = "Device does not support anchors!";
const char kDeviceDisconnected[] = "The XR device has been disconnected.";
const double kDegToRad = M_PI / 180.0;
......@@ -355,6 +357,17 @@ ScriptPromise XRSession::requestReferenceSpace(ScriptState* script_state,
return promise;
}
ScriptPromise XRSession::createAnchor(ScriptState* script_state,
XRPose* pose,
XRSpace* space) {
// TODO(https://crbug.com/992033): Implement anchor creation from a session
// instead of rejecting the promise.
return ScriptPromise::RejectWithDOMException(
script_state,
MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotSupportedError,
kAnchorsNotSupported));
}
int XRSession::requestAnimationFrame(V8XRFrameRequestCallback* callback) {
TRACE_EVENT0("gpu", __FUNCTION__);
// Don't allow any new frame requests once the session is ended.
......
......@@ -33,12 +33,14 @@ class ResizeObserver;
class ScriptPromiseResolver;
class V8XRFrameRequestCallback;
class XR;
class XRAnchorSet;
class XRCanvasInputProvider;
class XRSpace;
class XRPose;
class XRRay;
class XRReferenceSpace;
class XRRenderState;
class XRRenderStateInit;
class XRSpace;
class XRViewData;
class XRWorldInformation;
class XRWorldTrackingState;
......@@ -85,6 +87,7 @@ class XRSession final
XRRenderState* renderState() const { return render_state_; }
XRWorldTrackingState* worldTrackingState() { return world_tracking_state_; }
XRSpace* viewerSpace() const;
XRAnchorSet* trackedAnchors() const { return nullptr; }
bool immersive() const;
......@@ -103,6 +106,10 @@ class XRSession final
ScriptPromise requestReferenceSpace(ScriptState* script_state,
const String& type);
ScriptPromise createAnchor(ScriptState* script_state,
XRPose* pose,
XRSpace* space);
int requestAnimationFrame(V8XRFrameRequestCallback* callback);
void cancelAnimationFrame(int id);
......
......@@ -54,5 +54,8 @@ enum XRVisibilityState {
[RuntimeEnabled=WebXRPlaneDetection] readonly attribute XRWorldTrackingState worldTrackingState;
[RuntimeEnabled=WebXRPlaneDetection, RaisesException] void updateWorldTrackingState(optional XRWorldTrackingStateInit state);
[RuntimeEnabled=WebXRAnchors] readonly attribute XRAnchorSet trackedAnchors;
[RuntimeEnabled=WebXRAnchors, CallWith=ScriptState] Promise<XRAnchor> createAnchor(XRPose pose, XRSpace space);
[CallWith=ScriptState, Measure] Promise<void> end();
};
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_SETLIKE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_SETLIKE_H_
#include "third_party/blink/renderer/bindings/core/v8/iterable.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
namespace blink {
// Utility class to simplify implementation of various `setlike` classes.
// The consumer of the class needs only to implement the |elements()| method -
// everything else should be provided by this class. For examples, see
// `XRPlaneSet` and `XRAnchorSet`.
template <typename ElementType>
class XRSetlike : public SetlikeIterable<Member<ElementType>> {
public:
unsigned size() const { return elements().size(); }
// Returns true if passed in |element| is a member of the XRSetlike.
bool hasForBinding(ScriptState* script_state,
ElementType* element,
ExceptionState& exception_state) const {
DCHECK(element);
auto all_elements = elements();
return all_elements.find(element) != all_elements.end();
}
protected:
virtual const HeapHashSet<Member<ElementType>>& elements() const = 0;
private:
class IterationSource final
: public SetlikeIterable<Member<ElementType>>::IterationSource {
public:
explicit IterationSource(const HeapHashSet<Member<ElementType>>& elements)
: index_(0) {
elements_.ReserveInitialCapacity(elements.size());
for (auto element : elements) {
elements_.push_back(element);
}
}
bool Next(ScriptState* script_state,
Member<ElementType>& key,
Member<ElementType>& value,
ExceptionState& exception_state) override {
if (index_ >= elements_.size()) {
return false;
}
key = value = elements_[index_];
++index_;
return true;
}
void Trace(blink::Visitor* visitor) override {
visitor->Trace(elements_);
SetlikeIterable<Member<ElementType>>::IterationSource::Trace(visitor);
}
private:
HeapVector<Member<ElementType>> elements_;
unsigned index_;
};
// Starts iteration over XRSetlike.
// Needed for SetlikeIterable to work properly.
XRSetlike::IterationSource* StartIteration(
ScriptState* script_state,
ExceptionState& exception_state) override {
return MakeGarbageCollected<XRSetlike::IterationSource>(elements());
}
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_SETLIKE_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment