Commit 43fd0fc3 authored by Piotr Bialecki's avatar Piotr Bialecki Committed by Commit Bot

WebXR - Remove legacy hit test API

The approach to performing hit test has changed, the new API that
replaces the legacy one is already enabled by default in M81.
https://immersive-web.github.io/hit-test/

Change-Id: Ia89921505ae4ed537c28b117808182efbc79396c
Fixed: 1051626
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2050582Reviewed-by: default avatarAlexander Cooper <alcooper@chromium.org>
Reviewed-by: default avatarWill Harris <wfh@chromium.org>
Reviewed-by: default avatarYutaka Hirano <yhirano@chromium.org>
Commit-Queue: Piotr Bialecki <bialpio@chromium.org>
Cr-Commit-Position: refs/heads/master@{#741164}
parent e6d8fdde
...@@ -222,22 +222,4 @@ TEST_F(ArCoreDeviceTest, GetFrameData) { ...@@ -222,22 +222,4 @@ TEST_F(ArCoreDeviceTest, GetFrameData) {
GetFrameData(); GetFrameData();
} }
TEST_F(ArCoreDeviceTest, RequestHitTest) {
CreateSession();
mojom::XRRayPtr ray = mojom::XRRay::New();
std::vector<mojom::XRHitResultPtr> hit_results;
auto callback =
[](std::vector<mojom::XRHitResultPtr>* hit_results,
base::Optional<std::vector<mojom::XRHitResultPtr>> results) {
*hit_results = std::move(results.value());
};
environment_provider->RequestHitTest(std::move(ray),
base::BindOnce(callback, &hit_results));
// Have to get frame data to trigger the hit-test calculation.
GetFrameData();
EXPECT_FALSE(hit_results.empty());
}
} // namespace device } // namespace device
...@@ -91,16 +91,6 @@ const display::Display::Rotation kDefaultRotation = display::Display::ROTATE_0; ...@@ -91,16 +91,6 @@ const display::Display::Rotation kDefaultRotation = display::Display::ROTATE_0;
namespace device { namespace device {
struct ArCoreHitTestRequest {
ArCoreHitTestRequest() = default;
~ArCoreHitTestRequest() = default;
mojom::XRRayPtr ray;
mojom::XREnvironmentIntegrationProvider::RequestHitTestCallback callback;
private:
DISALLOW_COPY_AND_ASSIGN(ArCoreHitTestRequest);
};
ArCoreGl::ArCoreGl(std::unique_ptr<ArImageTransport> ar_image_transport) ArCoreGl::ArCoreGl(std::unique_ptr<ArImageTransport> ar_image_transport)
: gl_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()), : gl_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
ar_image_transport_(std::move(ar_image_transport)), ar_image_transport_(std::move(ar_image_transport)),
...@@ -420,11 +410,8 @@ void ArCoreGl::GetFrameData( ...@@ -420,11 +410,8 @@ void ArCoreGl::GetFrameData(
fps_meter_.AddFrame(base::TimeTicks::Now()); fps_meter_.AddFrame(base::TimeTicks::Now());
TRACE_COUNTER1("gpu", "WebXR FPS", fps_meter_.GetFPS()); TRACE_COUNTER1("gpu", "WebXR FPS", fps_meter_.GetFPS());
// Post a task to finish processing the frame so any calls to // Post a task to finish processing the frame to give a chance for
// RequestHitTest() that were made during this function, which can block // OnScreenTouch() tasks to run and added anchors to be registered.
// on the arcore_->Update() call above, can be processed in this frame.
// Additionally, this gives a chance for OnScreenTouch() tasks to run
// and added anchors to be registered.
gl_thread_task_runner_->PostTask( gl_thread_task_runner_->PostTask(
FROM_HERE, FROM_HERE,
base::BindOnce(&ArCoreGl::ProcessFrame, weak_ptr_factory_.GetWeakPtr(), base::BindOnce(&ArCoreGl::ProcessFrame, weak_ptr_factory_.GetWeakPtr(),
...@@ -641,27 +628,6 @@ void ArCoreGl::SetInputSourceButtonListener( ...@@ -641,27 +628,6 @@ void ArCoreGl::SetInputSourceButtonListener(
mojo::ReportBadMessage("Input eventing is not supported."); mojo::ReportBadMessage("Input eventing is not supported.");
} }
void ArCoreGl::RequestHitTest(
mojom::XRRayPtr ray,
mojom::XREnvironmentIntegrationProvider::RequestHitTestCallback callback) {
DVLOG(2) << __func__ << ": ray origin=" << ray->origin.ToString()
<< ", direction=" << ray->direction.ToString();
DCHECK(IsOnGlThread());
DCHECK(is_initialized_);
if (restrict_frame_data_) {
std::move(callback).Run(base::nullopt);
return;
}
std::unique_ptr<ArCoreHitTestRequest> request =
std::make_unique<ArCoreHitTestRequest>();
request->ray = std::move(ray);
request->callback = std::move(callback);
hit_test_requests_.push_back(std::move(request));
}
void ArCoreGl::SubscribeToHitTest( void ArCoreGl::SubscribeToHitTest(
mojom::XRNativeOriginInformationPtr native_origin_information, mojom::XRNativeOriginInformationPtr native_origin_information,
const std::vector<mojom::EntityTypeForHitTest>& entity_types, const std::vector<mojom::EntityTypeForHitTest>& entity_types,
...@@ -807,30 +773,6 @@ void ArCoreGl::ProcessFrame( ...@@ -807,30 +773,6 @@ void ArCoreGl::ProcessFrame(
frame_data->light_estimation_data = arcore_->GetLightEstimationData(); frame_data->light_estimation_data = arcore_->GetLightEstimationData();
} }
// The timing requirements for hit-test are documented here:
// https://github.com/immersive-web/hit-test/blob/master/explainer.md#timing
// The current implementation of frame generation on the renderer side is
// 1:1 with calls to this method, so it is safe to fire off the hit-test
// results here, one at a time, in the order they were enqueued prior to
// running the GetFrameDataCallback.
// Since mojo callbacks are processed in order, this will result in the
// correct sequence of hit-test callbacks / promise resolutions. If
// the implementation of the renderer processing were to change, this
// code is fragile and could break depending on the new implementation.
// TODO(https://crbug.com/844174): In order to be more correct by design,
// hit results should be bundled with the frame data - that way it would be
// obvious how the timing between the results and the frame should go.
for (auto& request : hit_test_requests_) {
std::vector<mojom::XRHitResultPtr> results;
if (arcore_->RequestHitTest(request->ray, &results)) {
std::move(request->callback).Run(std::move(results));
} else {
// Hit test failed, i.e. unprojected location was offscreen.
std::move(request->callback).Run(base::nullopt);
}
}
hit_test_requests_.clear();
// Running this callback after resolving all the hit-test requests ensures // Running this callback after resolving all the hit-test requests ensures
// that we satisfy the guarantee of the WebXR hit-test spec - that the // that we satisfy the guarantee of the WebXR hit-test spec - that the
// hit-test promise resolves immediately prior to the frame for which it is // hit-test promise resolves immediately prior to the frame for which it is
......
...@@ -49,7 +49,6 @@ namespace device { ...@@ -49,7 +49,6 @@ namespace device {
class ArCore; class ArCore;
class ArCoreFactory; class ArCoreFactory;
struct ArCoreHitTestRequest;
class ArImageTransport; class ArImageTransport;
using ArCoreGlCreateSessionCallback = base::OnceCallback<void( using ArCoreGlCreateSessionCallback = base::OnceCallback<void(
...@@ -110,10 +109,6 @@ class ArCoreGl : public mojom::XRFrameDataProvider, ...@@ -110,10 +109,6 @@ class ArCoreGl : public mojom::XRFrameDataProvider,
const gfx::Size& source_size) override; const gfx::Size& source_size) override;
// XREnvironmentIntegrationProvider // XREnvironmentIntegrationProvider
void RequestHitTest(
mojom::XRRayPtr,
mojom::XREnvironmentIntegrationProvider::RequestHitTestCallback) override;
void SubscribeToHitTest( void SubscribeToHitTest(
mojom::XRNativeOriginInformationPtr native_origin_information, mojom::XRNativeOriginInformationPtr native_origin_information,
const std::vector<mojom::EntityTypeForHitTest>& entity_types, const std::vector<mojom::EntityTypeForHitTest>& entity_types,
...@@ -231,8 +226,6 @@ class ArCoreGl : public mojom::XRFrameDataProvider, ...@@ -231,8 +226,6 @@ class ArCoreGl : public mojom::XRFrameDataProvider,
FPSMeter fps_meter_; FPSMeter fps_meter_;
std::vector<std::unique_ptr<ArCoreHitTestRequest>> hit_test_requests_;
mojo::Receiver<mojom::XRFrameDataProvider> frame_data_receiver_{this}; mojo::Receiver<mojom::XRFrameDataProvider> frame_data_receiver_{this};
mojo::Receiver<mojom::XRSessionController> session_controller_receiver_{this}; mojo::Receiver<mojom::XRSessionController> session_controller_receiver_{this};
mojo::AssociatedReceiver<mojom::XREnvironmentIntegrationProvider> mojo::AssociatedReceiver<mojom::XREnvironmentIntegrationProvider>
......
...@@ -662,14 +662,6 @@ enum EntityTypeForHitTest { ...@@ -662,14 +662,6 @@ enum EntityTypeForHitTest {
// all outstanding JavaScript promises at that time. The XRsession might end for // all outstanding JavaScript promises at that time. The XRsession might end for
// example due to a call to XRSession::end() method (exposed to JavaScript). // example due to a call to XRSession::end() method (exposed to JavaScript).
interface XREnvironmentIntegrationProvider { interface XREnvironmentIntegrationProvider {
// Performs a raycast into the scene and returns a list of XRHitResults sorted
// from closest to furthest hit from the ray. Each hit result contains a
// hit_matrix containing the transform of the hit where the rotation
// represents the normal of the surface hit.
// An empty result list means there were no hits. If a nullopt is returned,
// there was an error.
RequestHitTest(XRRay ray) => (array<XRHitResult>? results);
// Establishes a hit test subscription on the device. The subscription results // Establishes a hit test subscription on the device. The subscription results
// will be computed taking into account latest state of the native origin // will be computed taking into account latest state of the native origin
// identified by passed in |native_origin_information|. I.e., in each frame, // identified by passed in |native_origin_information|. I.e., in each frame,
......
...@@ -84,13 +84,6 @@ void VRDeviceBase::SetInlinePosesEnabled(bool enable) { ...@@ -84,13 +84,6 @@ void VRDeviceBase::SetInlinePosesEnabled(bool enable) {
inline_poses_enabled_ = enable; inline_poses_enabled_ = enable;
} }
void VRDeviceBase::RequestHitTest(
mojom::XRRayPtr ray,
mojom::XREnvironmentIntegrationProvider::RequestHitTestCallback callback) {
NOTREACHED() << "Unexpected call to a device without hit-test support";
std::move(callback).Run(base::nullopt);
}
void LogViewerType(VrViewerType type) { void LogViewerType(VrViewerType type) {
base::UmaHistogramSparse("VRViewerType", static_cast<int>(type)); base::UmaHistogramSparse("VRViewerType", static_cast<int>(type));
} }
......
...@@ -36,9 +36,6 @@ class DEVICE_VR_EXPORT VRDeviceBase : public mojom::XRRuntime { ...@@ -36,9 +36,6 @@ class DEVICE_VR_EXPORT VRDeviceBase : public mojom::XRRuntime {
void SetInlinePosesEnabled(bool enable) override; void SetInlinePosesEnabled(bool enable) override;
void ShutdownSession(mojom::XRRuntime::ShutdownSessionCallback) override; void ShutdownSession(mojom::XRRuntime::ShutdownSessionCallback) override;
virtual void RequestHitTest(
mojom::XRRayPtr ray,
mojom::XREnvironmentIntegrationProvider::RequestHitTestCallback callback);
device::mojom::XRDeviceId GetId() const; device::mojom::XRDeviceId GetId() const;
bool HasExclusiveSession(); bool HasExclusiveSession();
...@@ -72,7 +69,6 @@ class DEVICE_VR_EXPORT VRDeviceBase : public mojom::XRRuntime { ...@@ -72,7 +69,6 @@ class DEVICE_VR_EXPORT VRDeviceBase : public mojom::XRRuntime {
bool inline_poses_enabled_ = true; bool inline_poses_enabled_ = true;
private: private:
mojo::AssociatedRemote<mojom::XRRuntimeEventListener> listener_; mojo::AssociatedRemote<mojom::XRRuntimeEventListener> listener_;
bool presenting_ = false; bool presenting_ = false;
......
...@@ -915,7 +915,6 @@ static_idl_files_in_modules = get_path_info( ...@@ -915,7 +915,6 @@ static_idl_files_in_modules = get_path_info(
"//third_party/blink/renderer/modules/xr/xr_dom_overlay_state.idl", "//third_party/blink/renderer/modules/xr/xr_dom_overlay_state.idl",
"//third_party/blink/renderer/modules/xr/xr_frame.idl", "//third_party/blink/renderer/modules/xr/xr_frame.idl",
"//third_party/blink/renderer/modules/xr/xr_frame_request_callback.idl", "//third_party/blink/renderer/modules/xr/xr_frame_request_callback.idl",
"//third_party/blink/renderer/modules/xr/xr_hit_result.idl",
"//third_party/blink/renderer/modules/xr/xr_hit_test_options_init.idl", "//third_party/blink/renderer/modules/xr/xr_hit_test_options_init.idl",
"//third_party/blink/renderer/modules/xr/xr_hit_test_result.idl", "//third_party/blink/renderer/modules/xr/xr_hit_test_result.idl",
"//third_party/blink/renderer/modules/xr/xr_hit_test_source.idl", "//third_party/blink/renderer/modules/xr/xr_hit_test_source.idl",
......
...@@ -33,8 +33,6 @@ blink_modules_sources("xr") { ...@@ -33,8 +33,6 @@ blink_modules_sources("xr") {
"xr_frame_request_callback_collection.h", "xr_frame_request_callback_collection.h",
"xr_grip_space.cc", "xr_grip_space.cc",
"xr_grip_space.h", "xr_grip_space.h",
"xr_hit_result.cc",
"xr_hit_result.h",
"xr_hit_test_result.cc", "xr_hit_test_result.cc",
"xr_hit_test_result.h", "xr_hit_test_result.h",
"xr_hit_test_source.cc", "xr_hit_test_source.cc",
......
...@@ -10,7 +10,6 @@ modules_idl_files = [ ...@@ -10,7 +10,6 @@ modules_idl_files = [
"xr_dom_overlay_state.idl", "xr_dom_overlay_state.idl",
"xr_cube_map.idl", "xr_cube_map.idl",
"xr_frame.idl", "xr_frame.idl",
"xr_hit_result.idl",
"xr_input_source.idl", "xr_input_source.idl",
"xr_input_source_array.idl", "xr_input_source_array.idl",
"xr_input_source_event.idl", "xr_input_source_event.idl",
......
// Copyright 2018 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_hit_result.h"
#include "third_party/blink/renderer/modules/xr/xr_utils.h"
#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h"
namespace blink {
XRHitResult::XRHitResult(const TransformationMatrix& hit_transform)
: hit_transform_(std::make_unique<TransformationMatrix>(hit_transform)) {}
XRHitResult::~XRHitResult() {}
DOMFloat32Array* XRHitResult::hitMatrix() const {
if (!hit_transform_)
return nullptr;
return transformationMatrixToDOMFloat32Array(*hit_transform_);
}
} // namespace blink
// Copyright 2018 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_HIT_RESULT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_HIT_RESULT_H_
#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
namespace blink {
class TransformationMatrix;
class XRHitResult final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
explicit XRHitResult(const TransformationMatrix&);
~XRHitResult() override;
DOMFloat32Array* hitMatrix() const;
private:
const std::unique_ptr<TransformationMatrix> hit_transform_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_HIT_RESULT_H_
// Copyright 2018 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.
[RuntimeEnabled=WebXRIncubations, SecureContext, Exposed=Window]
interface XRHitResult {
readonly attribute Float32Array hitMatrix;
};
\ No newline at end of file
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
#include "third_party/blink/renderer/modules/xr/xr_dom_overlay_state.h" #include "third_party/blink/renderer/modules/xr/xr_dom_overlay_state.h"
#include "third_party/blink/renderer/modules/xr/xr_frame.h" #include "third_party/blink/renderer/modules/xr/xr_frame.h"
#include "third_party/blink/renderer/modules/xr/xr_frame_provider.h" #include "third_party/blink/renderer/modules/xr/xr_frame_provider.h"
#include "third_party/blink/renderer/modules/xr/xr_hit_result.h"
#include "third_party/blink/renderer/modules/xr/xr_hit_test_source.h" #include "third_party/blink/renderer/modules/xr/xr_hit_test_source.h"
#include "third_party/blink/renderer/modules/xr/xr_input_source_event.h" #include "third_party/blink/renderer/modules/xr/xr_input_source_event.h"
#include "third_party/blink/renderer/modules/xr/xr_input_sources_change_event.h" #include "third_party/blink/renderer/modules/xr/xr_input_sources_change_event.h"
...@@ -73,8 +72,6 @@ const char kNoSpaceSpecified[] = "No XRSpace specified."; ...@@ -73,8 +72,6 @@ const char kNoSpaceSpecified[] = "No XRSpace specified.";
const char kNoRigidTransformSpecified[] = "No XRRigidTransform specified."; const char kNoRigidTransformSpecified[] = "No XRRigidTransform specified.";
const char kHitTestNotSupported[] = "Device does not support hit-test!";
const char kAnchorsNotSupported[] = "Device does not support anchors!"; const char kAnchorsNotSupported[] = "Device does not support anchors!";
const char kDeviceDisconnected[] = "The XR device has been disconnected."; const char kDeviceDisconnected[] = "The XR device has been disconnected.";
...@@ -682,50 +679,6 @@ XRInputSourceArray* XRSession::inputSources() const { ...@@ -682,50 +679,6 @@ XRInputSourceArray* XRSession::inputSources() const {
return input_sources_; return input_sources_;
} }
ScriptPromise XRSession::requestHitTest(ScriptState* script_state,
XRRay* ray,
XRSpace* space,
ExceptionState& exception_state) {
DVLOG(2) << __func__;
if (ended_) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
kSessionEnded);
return ScriptPromise();
}
if (!space) {
exception_state.ThrowTypeError(kNoSpaceSpecified);
return ScriptPromise();
}
// Reject the promise if device doesn't support the hit-test API.
if (!xr_->xrEnvironmentProviderRemote()) {
exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
kHitTestNotSupported);
return ScriptPromise();
}
device::mojom::blink::XRRayPtr ray_mojo = device::mojom::blink::XRRay::New();
ray_mojo->origin =
FloatPoint3D(ray->origin()->x(), ray->origin()->y(), ray->origin()->z());
ray_mojo->direction = {ray->direction()->x(), ray->direction()->y(),
ray->direction()->z()};
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
xr_->xrEnvironmentProviderRemote()->RequestHitTest(
std::move(ray_mojo),
WTF::Bind(&XRSession::OnHitTestResults, WrapPersistent(this),
WrapPersistent(resolver)));
hit_test_promises_.insert(resolver);
return promise;
}
ScriptPromise XRSession::requestHitTestSource( ScriptPromise XRSession::requestHitTestSource(
ScriptState* script_state, ScriptState* script_state,
XRHitTestOptionsInit* options_init, XRHitTestOptionsInit* options_init,
...@@ -866,26 +819,6 @@ ScriptPromise XRSession::requestHitTestSourceForTransientInput( ...@@ -866,26 +819,6 @@ ScriptPromise XRSession::requestHitTestSourceForTransientInput(
return promise; return promise;
} }
void XRSession::OnHitTestResults(
ScriptPromiseResolver* resolver,
base::Optional<Vector<device::mojom::blink::XRHitResultPtr>> results) {
DCHECK(hit_test_promises_.Contains(resolver));
hit_test_promises_.erase(resolver);
if (!results) {
resolver->Reject();
return;
}
HeapVector<Member<XRHitResult>> hit_results;
for (const auto& mojom_result : results.value()) {
XRHitResult* hit_result = MakeGarbageCollected<XRHitResult>(
TransformationMatrix(mojom_result->hit_matrix.matrix()));
hit_results.push_back(hit_result);
}
resolver->Resolve(hit_results);
}
void XRSession::OnSubscribeToHitTestResult( void XRSession::OnSubscribeToHitTestResult(
ScriptPromiseResolver* resolver, ScriptPromiseResolver* resolver,
device::mojom::SubscribeToHitTestResult result, device::mojom::SubscribeToHitTestResult result,
...@@ -966,13 +899,6 @@ void XRSession::EnsureEnvironmentErrorHandler() { ...@@ -966,13 +899,6 @@ void XRSession::EnsureEnvironmentErrorHandler() {
} }
void XRSession::OnEnvironmentProviderError() { void XRSession::OnEnvironmentProviderError() {
HeapHashSet<Member<ScriptPromiseResolver>> hit_test_promises;
hit_test_promises_.swap(hit_test_promises);
for (ScriptPromiseResolver* resolver : hit_test_promises) {
resolver->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kInvalidStateError, kDeviceDisconnected));
}
HeapHashSet<Member<ScriptPromiseResolver>> create_anchor_promises; HeapHashSet<Member<ScriptPromiseResolver>> create_anchor_promises;
create_anchor_promises_.swap(create_anchor_promises); create_anchor_promises_.swap(create_anchor_promises);
for (ScriptPromiseResolver* resolver : create_anchor_promises) { for (ScriptPromiseResolver* resolver : create_anchor_promises) {
...@@ -1932,7 +1858,6 @@ void XRSession::Trace(blink::Visitor* visitor) { ...@@ -1932,7 +1858,6 @@ void XRSession::Trace(blink::Visitor* visitor) {
visitor->Trace(overlay_element_); visitor->Trace(overlay_element_);
visitor->Trace(dom_overlay_state_); visitor->Trace(dom_overlay_state_);
visitor->Trace(callback_collection_); visitor->Trace(callback_collection_);
visitor->Trace(hit_test_promises_);
visitor->Trace(create_anchor_promises_); visitor->Trace(create_anchor_promises_);
visitor->Trace(request_hit_test_source_promises_); visitor->Trace(request_hit_test_source_promises_);
visitor->Trace(reference_spaces_); visitor->Trace(reference_spaces_);
......
...@@ -44,7 +44,6 @@ class XRDOMOverlayState; ...@@ -44,7 +44,6 @@ class XRDOMOverlayState;
class XRHitTestOptionsInit; class XRHitTestOptionsInit;
class XRHitTestSource; class XRHitTestSource;
class XRPlane; class XRPlane;
class XRRay;
class XRReferenceSpace; class XRReferenceSpace;
class XRRenderState; class XRRenderState;
class XRRenderStateInit; class XRRenderStateInit;
...@@ -148,11 +147,6 @@ class XRSession final ...@@ -148,11 +147,6 @@ class XRSession final
XRTransientInputHitTestOptionsInit* options_init, XRTransientInputHitTestOptionsInit* options_init,
ExceptionState& exception_state); ExceptionState& exception_state);
ScriptPromise requestHitTest(ScriptState* script_state,
XRRay* ray,
XRSpace* space,
ExceptionState&);
// Called by JavaScript to manually end the session. // Called by JavaScript to manually end the session.
ScriptPromise end(ScriptState* script_state, ExceptionState&); ScriptPromise end(ScriptState* script_state, ExceptionState&);
...@@ -327,10 +321,6 @@ class XRSession final ...@@ -327,10 +321,6 @@ class XRSession final
void UpdateVisibilityState(); void UpdateVisibilityState();
void OnHitTestResults(
ScriptPromiseResolver* resolver,
base::Optional<Vector<device::mojom::blink::XRHitResultPtr>> results);
void OnSubscribeToHitTestResult( void OnSubscribeToHitTestResult(
ScriptPromiseResolver* resolver, ScriptPromiseResolver* resolver,
device::mojom::SubscribeToHitTestResult result, device::mojom::SubscribeToHitTestResult result,
...@@ -408,7 +398,6 @@ class XRSession final ...@@ -408,7 +398,6 @@ class XRSession final
Member<Element> overlay_element_; Member<Element> overlay_element_;
Member<XRDOMOverlayState> dom_overlay_state_; Member<XRDOMOverlayState> dom_overlay_state_;
bool environment_error_handler_subscribed_ = false; bool environment_error_handler_subscribed_ = false;
HeapHashSet<Member<ScriptPromiseResolver>> hit_test_promises_;
// Set of promises returned from CreateAnchor that are still in-flight. // Set of promises returned from CreateAnchor that are still in-flight.
HeapHashSet<Member<ScriptPromiseResolver>> create_anchor_promises_; HeapHashSet<Member<ScriptPromiseResolver>> create_anchor_promises_;
// Set of promises returned from requestHitTestSource and // Set of promises returned from requestHitTestSource and
......
...@@ -48,9 +48,6 @@ enum XRVisibilityState { ...@@ -48,9 +48,6 @@ enum XRVisibilityState {
long requestAnimationFrame(XRFrameRequestCallback callback); long requestAnimationFrame(XRFrameRequestCallback callback);
void cancelAnimationFrame(long handle); void cancelAnimationFrame(long handle);
[RuntimeEnabled=WebXRIncubations, CallWith=ScriptState, RaisesException]
Promise<FrozenArray<XRHitResult>> requestHitTest(XRRay ray, XRSpace space);
// https://github.com/immersive-web/real-world-geometry/blob/master/plane-detection-explainer.md // https://github.com/immersive-web/real-world-geometry/blob/master/plane-detection-explainer.md
[RuntimeEnabled=WebXRIncubations] readonly attribute XRWorldTrackingState worldTrackingState; [RuntimeEnabled=WebXRIncubations] readonly attribute XRWorldTrackingState worldTrackingState;
[RuntimeEnabled=WebXRIncubations, RaisesException] void updateWorldTrackingState(optional XRWorldTrackingStateInit state = {}); [RuntimeEnabled=WebXRIncubations, RaisesException] void updateWorldTrackingState(optional XRWorldTrackingStateInit state = {});
......
...@@ -639,7 +639,7 @@ class MockRuntime { ...@@ -639,7 +639,7 @@ class MockRuntime {
if (!this.supportedModes_.includes(device.mojom.XRSessionMode.kImmersiveAr)) { if (!this.supportedModes_.includes(device.mojom.XRSessionMode.kImmersiveAr)) {
// Reject outside of AR. // Reject outside of AR.
return Promise.resolve({ return Promise.resolve({
result : device.mojom.SubscribeToHitTestResult.FAILED, result : device.mojom.SubscribeToHitTestResult.FAILURE_GENERIC,
subscriptionId : 0 subscriptionId : 0
}); });
} }
...@@ -648,7 +648,7 @@ class MockRuntime { ...@@ -648,7 +648,7 @@ class MockRuntime {
if (!this.input_sources_.has(nativeOriginInformation.inputSourceId)) { if (!this.input_sources_.has(nativeOriginInformation.inputSourceId)) {
// Reject - unknown input source ID. // Reject - unknown input source ID.
return Promise.resolve({ return Promise.resolve({
result : device.mojom.SubscribeToHitTestResult.FAILED, result : device.mojom.SubscribeToHitTestResult.FAILURE_GENERIC,
subscriptionId : 0 subscriptionId : 0
}); });
} }
...@@ -657,14 +657,14 @@ class MockRuntime { ...@@ -657,14 +657,14 @@ class MockRuntime {
if (nativeOriginInformation.referenceSpaceCategory == device.mojom.XRReferenceSpaceCategory.UNBOUNDED if (nativeOriginInformation.referenceSpaceCategory == device.mojom.XRReferenceSpaceCategory.UNBOUNDED
|| nativeOriginInformation.referenceSpaceCategory == device.mojom.XRReferenceSpaceCategory.BOUNDED_FLOOR) { || nativeOriginInformation.referenceSpaceCategory == device.mojom.XRReferenceSpaceCategory.BOUNDED_FLOOR) {
return Promise.resolve({ return Promise.resolve({
result : device.mojom.SubscribeToHitTestResult.FAILED, result : device.mojom.SubscribeToHitTestResult.FAILURE_GENERIC,
subscriptionId : 0 subscriptionId : 0
}); });
} }
} else { } else {
// Planes and anchors are not yet supported by the mock interface. // Planes and anchors are not yet supported by the mock interface.
return Promise.resolve({ return Promise.resolve({
result : device.mojom.SubscribeToHitTestResult.FAILED, result : device.mojom.SubscribeToHitTestResult.FAILURE_GENERIC,
subscriptionId : 0 subscriptionId : 0
}); });
} }
......
...@@ -11198,10 +11198,6 @@ interface XRFrame ...@@ -11198,10 +11198,6 @@ interface XRFrame
method getHitTestResultsForTransientInput method getHitTestResultsForTransientInput
method getPose method getPose
method getViewerPose method getViewerPose
interface XRHitResult
attribute @@toStringTag
getter hitMatrix
method constructor
interface XRHitTestResult interface XRHitTestResult
attribute @@toStringTag attribute @@toStringTag
method constructor method constructor
...@@ -11334,7 +11330,6 @@ interface XRSession : EventTarget ...@@ -11334,7 +11330,6 @@ interface XRSession : EventTarget
method constructor method constructor
method end method end
method requestAnimationFrame method requestAnimationFrame
method requestHitTest
method requestHitTestSource method requestHitTestSource
method requestHitTestSourceForTransientInput method requestHitTestSourceForTransientInput
method requestReferenceSpace method requestReferenceSpace
......
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>let additionalChromiumResources = ["../resources/xr-internal-device-mocking.js"];</script>
<script src="/webxr/resources/webxr_util.js"></script>
<script src="/webxr/resources/webxr_test_constants.js"></script>
<script src="/webxr/resources/webxr_test_asserts.js"></script>
<canvas />
<script>
// Because AR is not yet in the core webxr spec, this is an internal-chrome only test.
let testName = "Ensures hit-test returns expected mock results";
let fakeDeviceInitParams = { supportedModes: ["immersive-ar"],
views: VALID_VIEWS,
supportsEnvironmentIntegration: true,
supportedFeatures: ALL_FEATURES };
let expectedHitMatrix = [1, 0, 0, 1,
0, 1, 0, 2,
0, 0, 1, 3,
0, 0, 0, 1];
let testFunction = function(session, fakeDeviceController, t) {
assert_equals(session.mode, 'immersive-ar');
assert_not_equals(session.environmentBlendMode, 'opaque');
return session.requestReferenceSpace('local').then((referenceSpace) => {
let ray = new XRRay({x : 0.0, y : 0.0, z : 0.0}, {x : 1.0, y : 0.0, z: 0.0});
let hit = new device.mojom.XRHitResult();
hit.hitMatrix = new gfx.mojom.Transform();
hit.hitMatrix.matrix = expectedHitMatrix;
fakeDeviceController.setHitTestResults({ results: [hit] });
return session.requestHitTest(ray, referenceSpace).then(
(hitResults) => {
t.step(() => {
// Test that hit results are what we expected.
assert_equals(hitResults.length, 1);
assert_equals(hitResults[0].hitMatrix.length, 16);
assert_matrix_approx_equals(
hitResults[0].hitMatrix,
expectedHitMatrix,
FLOAT_EPSILON,
"Hit test matrix does not equals input test matrix");
});
});
});
};
xr_session_promise_test(
testName, testFunction, fakeDeviceInitParams, 'immersive-ar');
</script>
...@@ -3,25 +3,8 @@ ...@@ -3,25 +3,8 @@
/* This file contains extensions to the base mocking from the WebPlatform tests /* This file contains extensions to the base mocking from the WebPlatform tests
* for interal tests. The main mocked objects are found in * for interal tests. The main mocked objects are found in
* ../external/wpt/resources/chromium/webxr-test.js. */ * ../external/wpt/resources/chromium/webxr-test.js. */
MockRuntime.prototype.setHitTestResults = function(results) {
this.hittest_results_ = results;
};
// XREnvironmentIntegrationProvider implementation // XREnvironmentIntegrationProvider implementation
MockRuntime.prototype.requestHitTest = function(ray) {
let hit_results = this.hittest_results_;
if (!hit_results) {
const hit = new device.mojom.XRHitResult();
// No change to the underlying matrix/leaving it null results in identity.
hit.hitMatrix = new gfx.mojom.Transform();
hit_results = {results: [hit]};
}
return Promise.resolve(hit_results);
};
MockRuntime.prototype.getSubmitFrameCount = function() { MockRuntime.prototype.getSubmitFrameCount = function() {
return this.presentation_provider_.submit_frame_count_; return this.presentation_provider_.submit_frame_count_;
}; };
......
...@@ -9,32 +9,30 @@ ...@@ -9,32 +9,30 @@
<script> <script>
// This test manipulates mojo directly to simulate some behavior, and as such is // This test manipulates mojo directly to simulate some behavior, and as such is
// chromium specific. // chromium specific.
let testName = "Outstanding promises get rejected if environmentProvider disconencts"; const testName = "Outstanding promises get rejected if environmentProvider disconnects";
let fakeDeviceInitParams = { supportedModes: ["immersive-ar"], const fakeDeviceInitParams = { supportedModes: ["immersive-ar"],
views: VALID_VIEWS, views: VALID_VIEWS,
supportsEnvironmentIntegration: true, supportsEnvironmentIntegration: true,
supportedFeatures: ALL_FEATURES }; supportedFeatures: ALL_FEATURES };
let refSpace = undefined; let refSpace = undefined;
let ray = new XRRay({x : 0.0, y : 0.0, z : 0.0}, {x : 1.0, y : 0.0, z: 0.0}); const testFunction = function(session, fakeDeviceController, t) {
// Override some promise-based method from mock runtime so that we can
let testFunction = function(session, fakeDeviceController, t) {
// Override the xr-internal-device-mock for requestHitTest so that we can
// also return a promise that never resolves or rejects. // also return a promise that never resolves or rejects.
// This is so that we can simulate a disconnect while the mojo call is still // This is so that we can simulate a disconnect while the mojo call is still
// outstanding. // outstanding.
let immediatelyResolveHitTest = true; let immediatelyResolvePromise = true;
MockRuntime.prototype.requestHitTest = function(Ray) { MockRuntime.prototype.subscribeToHitTest = function(nativeOriginInformation, entityTypes, ray) {
if (immediatelyResolveHitTest) { if (!immediatelyResolvePromise) {
var hit = new device.mojom.XRHitResult(); return new Promise((resolve,reject) => { });
hit.hitMatrix = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
hit_results = {results: [hit]};
return Promise.resolve(hit_results);
} }
return new Promise((resolve,reject) => { }); return Promise.resolve({
result : device.mojom.SubscribeToHitTestResult.SUCCESS,
subscriptionId : 1001
});
} }
return session.requestReferenceSpace('local') return session.requestReferenceSpace('local')
...@@ -43,16 +41,16 @@ let testFunction = function(session, fakeDeviceController, t) { ...@@ -43,16 +41,16 @@ let testFunction = function(session, fakeDeviceController, t) {
// Request a first hit test to ensure that all of the mojo connections are // Request a first hit test to ensure that all of the mojo connections are
// up and running. // up and running.
return session.requestHitTest(ray, refSpace); return session.requestHitTestSource({"space" :refSpace});
}) })
.then(() => { .then(() => {
immediatelyResolveHitTest = false; immediatelyResolveHitTest = false;
let hitTestPromise = session.requestHitTest(ray, refSpace); const hitTestSourcePromise = session.requestHitTestSource({"space" :refSpace})
fakeDeviceController.closeEnvironmentIntegrationProvider(); fakeDeviceController.closeEnvironmentIntegrationProvider();
return hitTestPromise; return hitTestSourcePromise;
}) })
.then(() => { .then(() => {
assert_unreached("HitTestPromise should not resolve"); assert_unreached("Promise should not resolve");
}, },
(err) => { (err) => {
assert_equals(err.name, "InvalidStateError"); assert_equals(err.name, "InvalidStateError");
...@@ -60,6 +58,6 @@ let testFunction = function(session, fakeDeviceController, t) { ...@@ -60,6 +58,6 @@ let testFunction = function(session, fakeDeviceController, t) {
}; };
xr_session_promise_test( xr_session_promise_test(
testName, testFunction, fakeDeviceInitParams, 'immersive-ar'); testName, testFunction, fakeDeviceInitParams, 'immersive-ar', {requiredFeatures: ["hit-test"]});
</script> </script>
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