Commit 9f117237 authored by Klaus Weidner's avatar Klaus Weidner Committed by Commit Bot

WebXR: Add XRViewData reference to XRView

The Blink WebXR code has two parallel classes. XRViewData corresponds
to the internal "view" from the spec, and XRView is what is exposed
to JS. XRViewData has session lifetime, while XRView is ephemeral
and created per frame.

This change adds a reference from the XRView to the underlying
XRViewData object, as expected by the spec's algorithms. This requires
making XRViewData and their containing list garbage-collected objects.

Bug: 1133381
Change-Id: I696a1a899ab8fdf27a2107bbadeb61773c4ade84
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2438690Reviewed-by: default avatarBrandon Jones <bajones@chromium.org>
Commit-Queue: Klaus Weidner <klausw@chromium.org>
Cr-Commit-Position: refs/heads/master@{#812345}
parent 7cc1d3fe
......@@ -114,8 +114,8 @@ void XRCanvasInputProvider::UpdateInputSource(PointerEvent* event) {
// position of the screen interaction and shoves it backwards through the
// projection matrix to get a 3D point in space, which is then returned in
// matrix form so we can use it as an XRInputSource's pointerMatrix.
XRViewData& view = session_->views()[0];
TransformationMatrix viewer_from_pointer = view.UnprojectPointer(
XRViewData* view = session_->views()[0];
TransformationMatrix viewer_from_pointer = view->UnprojectPointer(
element_x, element_y, canvas_->OffsetWidth(), canvas_->OffsetHeight());
// Update the pointer pose in input space. For screen tapping, input
......
......@@ -109,19 +109,19 @@ const unsigned int kMonoOrStereoLeftView = 0;
const unsigned int kStereoRightView = 1;
void UpdateViewFromEyeParameters(
XRViewData& view,
XRViewData* view,
const device::mojom::blink::VREyeParametersPtr& eye,
double depth_near,
double depth_far) {
const device::mojom::blink::VRFieldOfViewPtr& fov = eye->field_of_view;
view.UpdateProjectionMatrixFromFoV(
view->UpdateProjectionMatrixFromFoV(
fov->up_degrees * kDegToRad, fov->down_degrees * kDegToRad,
fov->left_degrees * kDegToRad, fov->right_degrees * kDegToRad, depth_near,
depth_far);
const TransformationMatrix matrix(eye->head_from_eye.matrix());
view.SetHeadFromEyeTransform(matrix);
view->SetHeadFromEyeTransform(matrix);
}
// Returns the session feature corresponding to the given reference space type.
......@@ -2075,7 +2075,7 @@ void XRSession::SetXRDisplayInfo(
display_info_ = std::move(display_info);
}
Vector<XRViewData>& XRSession::views() {
const HeapVector<Member<XRViewData>>& XRSession::views() {
// TODO(bajones): For now we assume that immersive sessions render a stereo
// pair of views and non-immersive sessions render a single view. That doesn't
// always hold true, however, so the view configuration should ultimately come
......@@ -2084,9 +2084,10 @@ Vector<XRViewData>& XRSession::views() {
if (immersive()) {
// If we don't already have the views allocated, do so now.
if (views_.IsEmpty()) {
views_.emplace_back(XRView::kEyeLeft);
views_.emplace_back(MakeGarbageCollected<XRViewData>(XRView::kEyeLeft));
if (display_info_->right_eye) {
views_.emplace_back(XRView::kEyeRight);
views_.emplace_back(
MakeGarbageCollected<XRViewData>(XRView::kEyeRight));
}
}
// In immersive mode the projection and view matrices must be aligned with
......@@ -2101,7 +2102,7 @@ Vector<XRViewData>& XRSession::views() {
}
} else {
if (views_.IsEmpty()) {
views_.emplace_back(XRView::kEyeNone);
views_.emplace_back(MakeGarbageCollected<XRViewData>(XRView::kEyeNone));
}
float aspect = 1.0f;
......@@ -2118,7 +2119,7 @@ Vector<XRViewData>& XRSession::views() {
// inlineVerticalFieldOfView should only be null in immersive mode.
DCHECK(inline_vertical_fov.has_value());
views_[kMonoOrStereoLeftView].UpdateProjectionMatrixFromAspect(
views_[kMonoOrStereoLeftView]->UpdateProjectionMatrixFromAspect(
inline_vertical_fov.value(), aspect, render_state_->depthNear(),
render_state_->depthFar());
}
......@@ -2159,6 +2160,7 @@ void XRSession::Trace(Visitor* visitor) const {
visitor->Trace(prev_base_layer_);
visitor->Trace(hit_test_source_ids_to_hit_test_sources_);
visitor->Trace(hit_test_source_ids_to_transient_input_hit_test_sources_);
visitor->Trace(views_);
EventTargetWithInlineData::Trace(visitor);
}
......
......@@ -254,7 +254,7 @@ class XRSession final
void OnButtonEvent(
device::mojom::blink::XRInputSourceStatePtr input_source) override;
Vector<XRViewData>& views();
const HeapVector<Member<XRViewData>>& views();
void AddTransientInputSource(XRInputSource* input_source);
void RemoveTransientInputSource(XRInputSource* input_source);
......@@ -519,7 +519,7 @@ class XRSession final
HashSet<uint64_t> hit_test_source_ids_;
HashSet<uint64_t> hit_test_source_for_transient_input_ids_;
Vector<XRViewData> views_;
HeapVector<Member<XRViewData>> views_;
Member<XRInputSourceArray> input_sources_;
Member<XRWebGLLayer> prev_base_layer_;
......
......@@ -10,8 +10,8 @@
namespace blink {
XRView::XRView(XRFrame* frame, const XRViewData& view_data)
: eye_(view_data.Eye()), frame_(frame) {
XRView::XRView(XRFrame* frame, XRViewData* view_data)
: eye_(view_data->Eye()), frame_(frame), view_data_(view_data) {
switch (eye_) {
case kEyeLeft:
eye_string_ = "left";
......@@ -23,9 +23,9 @@ XRView::XRView(XRFrame* frame, const XRViewData& view_data)
eye_string_ = "none";
}
ref_space_from_eye_ =
MakeGarbageCollected<XRRigidTransform>(view_data.Transform());
MakeGarbageCollected<XRRigidTransform>(view_data->Transform());
projection_matrix_ =
transformationMatrixToDOMFloat32Array(view_data.ProjectionMatrix());
transformationMatrixToDOMFloat32Array(view_data->ProjectionMatrix());
}
XRFrame* XRView::frame() const {
......@@ -148,6 +148,7 @@ void XRView::Trace(Visitor* visitor) const {
visitor->Trace(frame_);
visitor->Trace(projection_matrix_);
visitor->Trace(ref_space_from_eye_);
visitor->Trace(view_data_);
ScriptWrappable::Trace(visitor);
}
......
......@@ -25,12 +25,13 @@ class MODULES_EXPORT XRView final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
XRView(XRFrame*, const XRViewData&);
XRView(XRFrame*, XRViewData*);
enum XREye { kEyeNone = 0, kEyeLeft = 1, kEyeRight = 2 };
const String& eye() const { return eye_string_; }
XREye EyeValue() const { return eye_; }
XRViewData* ViewData() const { return view_data_; }
XRFrame* frame() const;
XRSession* session() const;
......@@ -50,11 +51,12 @@ class MODULES_EXPORT XRView final : public ScriptWrappable {
XREye eye_;
String eye_string_;
Member<XRFrame> frame_;
Member<XRViewData> view_data_;
Member<XRRigidTransform> ref_space_from_eye_;
Member<DOMFloat32Array> projection_matrix_;
};
class MODULES_EXPORT XRViewData {
class MODULES_EXPORT XRViewData final : public GarbageCollected<XRViewData> {
public:
XRViewData(XRView::XREye eye) : eye_(eye) {}
......@@ -83,6 +85,8 @@ class MODULES_EXPORT XRViewData {
return projection_matrix_;
}
void Trace(Visitor*) const {}
private:
const XRView::XREye eye_;
TransformationMatrix ref_space_from_eye_;
......
......@@ -16,14 +16,14 @@ XRViewerPose::XRViewerPose(XRFrame* frame,
: XRPose(pose_model_matrix, frame->session()->EmulatedPosition()) {
DVLOG(3) << __func__ << ": emulatedPosition()=" << emulatedPosition();
Vector<XRViewData>& view_data = frame->session()->views();
const HeapVector<Member<XRViewData>>& view_data = frame->session()->views();
bool camera_access_enabled = frame->session()->IsFeatureEnabled(
device::mojom::XRSessionFeature::CAMERA_ACCESS);
// Snapshot the session's current views.
for (XRViewData& view : view_data) {
view.UpdatePoseMatrix(transform_->TransformMatrix());
for (XRViewData* view : view_data) {
view->UpdatePoseMatrix(transform_->TransformMatrix());
XRView* xr_view = MakeGarbageCollected<XRView>(frame, view);
views_.push_back(xr_view);
if (camera_access_enabled) {
......
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