Commit 880ec6d5 authored by Brandon Jones's avatar Brandon Jones Committed by Commit Bot

Stop tracking a VRDisplayInfo for each XRSession.

Part one of what's likely to be a three step process to remove
VRDisplayInfo entirely and start sending view information as an
array of views rather than and explicit left and right eye.

Removes the VRDisplayInfo instance previously stored on the
XRSession, and begins tracking the session's internal view
changes as an array (though they are still supplied to the
session as left/right.)

Bug: 998146
Change-Id: I0a86e43fca74ba9cd48f1e33a9033da2e899ed4c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2446837
Commit-Queue: Brandon Jones <bajones@chromium.org>
Reviewed-by: default avatarAlexander Cooper <alcooper@chromium.org>
Reviewed-by: default avatarKlaus Weidner <klausw@chromium.org>
Cr-Commit-Position: refs/heads/master@{#814925}
parent 21d37bf0
......@@ -55,13 +55,13 @@ void XRBoundedReferenceSpace::EnsureUpdated() {
stage_parameters_id_ = session()->StageParametersId();
const device::mojom::blink::VRDisplayInfoPtr& display_info =
session()->GetVRDisplayInfo();
const device::mojom::blink::VRStageParametersPtr& stage_parameters =
session()->GetStageParameters();
if (display_info && display_info->stage_parameters) {
// Use the transform given by xrDisplayInfo's stage_parameters if available.
if (stage_parameters) {
// Use the transform given by stage_parameters if available.
mojo_from_bounded_native_ = std::make_unique<TransformationMatrix>(
display_info->stage_parameters->mojo_from_floor.matrix());
stage_parameters->mojo_from_floor.matrix());
// In order to ensure that the bounds continue to line up with the user's
// physical environment we need to transform them from native to offset.
......@@ -74,10 +74,9 @@ void XRBoundedReferenceSpace::EnsureUpdated() {
// We may not have bounds if we've lost tracking after being created.
// Whether we have them or not, we need to clear the existing bounds.
offset_bounds_geometry_.clear();
if (display_info->stage_parameters->bounds &&
display_info->stage_parameters->bounds->size() >=
kMinimumNumberOfBoundVertices) {
for (const auto& bound : *(display_info->stage_parameters->bounds)) {
if (stage_parameters->bounds &&
stage_parameters->bounds->size() >= kMinimumNumberOfBoundVertices) {
for (const auto& bound : *(stage_parameters->bounds)) {
FloatPoint3D p = offset_from_native.MapPoint(
FloatPoint3D(bound.x(), 0.0, bound.z()));
offset_bounds_geometry_.push_back(RoundedDOMPoint(p));
......
......@@ -69,18 +69,18 @@ XRPose* XRReferenceSpace::getPose(XRSpace* other_space) {
}
void XRReferenceSpace::SetMojoFromFloor() {
const device::mojom::blink::VRDisplayInfoPtr& display_info =
session()->GetVRDisplayInfo();
const device::mojom::blink::VRStageParametersPtr& stage_parameters =
session()->GetStageParameters();
if (display_info && display_info->stage_parameters) {
// Use the transform given by xrDisplayInfo's stage_parameters if available.
if (stage_parameters) {
// Use the transform given by stage_parameters if available.
mojo_from_floor_ = std::make_unique<TransformationMatrix>(
display_info->stage_parameters->mojo_from_floor.matrix());
stage_parameters->mojo_from_floor.matrix());
} else {
mojo_from_floor_.reset();
}
display_info_id_ = session()->DisplayInfoPtrId();
stage_parameters_id_ = session()->StageParametersId();
}
base::Optional<TransformationMatrix> XRReferenceSpace::MojoFromNative() {
......@@ -103,9 +103,9 @@ base::Optional<TransformationMatrix> XRReferenceSpace::MojoFromNative() {
return *mojo_from_native;
}
case ReferenceSpaceType::kLocalFloor: {
// Check first to see if the xrDisplayInfo has updated since the last
// Check first to see if the stage_parameters has updated since the last
// call. If so, update the floor-level transform.
if (display_info_id_ != session()->DisplayInfoPtrId())
if (stage_parameters_id_ != session()->StageParametersId())
SetMojoFromFloor();
if (mojo_from_floor_) {
......
......@@ -64,7 +64,7 @@ class XRReferenceSpace : public XRSpace {
// latest display parameters of a session.
void SetMojoFromFloor();
unsigned int display_info_id_ = 0;
unsigned int stage_parameters_id_ = 0;
// Floor from mojo (aka local-floor_from_mojo) transform.
std::unique_ptr<TransformationMatrix> mojo_from_floor_;
......
......@@ -105,8 +105,7 @@ const float kMinDefaultFramebufferScale = 0.1f;
const float kMaxDefaultFramebufferScale = 1.0f;
// Indices into the views array.
const unsigned int kMonoOrStereoLeftView = 0;
const unsigned int kStereoRightView = 1;
const unsigned int kMonoView = 0;
void UpdateViewFromEyeParameters(
XRViewData* view,
......@@ -470,17 +469,58 @@ void XRSession::updateRenderState(XRRenderStateInit* init,
void XRSession::UpdateEyeParameters(
const device::mojom::blink::VREyeParametersPtr& left_eye,
const device::mojom::blink::VREyeParametersPtr& right_eye) {
auto display_info = display_info_.Clone();
display_info->left_eye = left_eye.Clone();
display_info->right_eye = right_eye.Clone();
SetXRDisplayInfo(std::move(display_info));
wtf_size_t required_size = left_eye ? 1 : 0;
required_size += right_eye ? 1 : 0;
bool updated = false;
if (pending_view_parameters_.size() != required_size) {
pending_view_parameters_.resize(required_size);
updated = true;
}
wtf_size_t view_index = 0;
if (left_eye) {
if (!pending_view_parameters_[view_index] ||
!pending_view_parameters_[view_index]->Equals(*left_eye)) {
pending_view_parameters_[view_index] = left_eye.Clone();
updated = true;
}
view_index++;
}
if (right_eye) {
if (!pending_view_parameters_[view_index] ||
!pending_view_parameters_[view_index]->Equals(*right_eye)) {
pending_view_parameters_[view_index] = right_eye.Clone();
updated = true;
}
view_index++;
}
if (updated) {
update_views_next_frame_ = true;
view_parameters_id_++;
}
}
void XRSession::UpdateStageParameters(
const device::mojom::blink::VRStageParametersPtr& stage_parameters) {
auto display_info = display_info_.Clone();
display_info->stage_parameters = stage_parameters.Clone();
SetXRDisplayInfo(std::move(display_info));
// We don't necessarily trust the backend to only send us display info changes
// when something has actually changed, and a change here can trigger several
// other interfaces to recompute data or fire events, so it's worthwhile to
// validate that an actual change has occurred.
if (stage_parameters_) {
// If the new parameters are identical to the old ones we don't need to
// update.
if (stage_parameters_->Equals(*stage_parameters))
return;
} else if (!stage_parameters) {
// Don't bother updating from null to null either.
return;
}
stage_parameters_id_++;
stage_parameters_ = stage_parameters.Clone();
}
ScriptPromise XRSession::requestReferenceSpace(
......@@ -1357,13 +1397,14 @@ DoubleSize XRSession::DefaultFramebufferSize() const {
}
double scale = default_framebuffer_scale_;
double width = display_info_->left_eye->render_width;
double height = display_info_->left_eye->render_height;
double width = 0;
double height = 0;
if (display_info_->right_eye) {
width += display_info_->right_eye->render_width;
height = std::max(display_info_->left_eye->render_height,
display_info_->right_eye->render_height);
// For the moment, concatenate all the views into a big strip.
// Won't scale well for displays that use more than a stereo pair.
for (const auto& view : pending_view_parameters_) {
width += view->render_width;
height = std::max(height, static_cast<double>(view->render_height));
}
return DoubleSize(width * scale, height * scale);
......@@ -1766,8 +1807,8 @@ base::Optional<TransformationMatrix> XRSession::GetMojoFrom(
return TransformationMatrix();
case device::mojom::blink::XRReferenceSpaceType::kLocalFloor:
case device::mojom::blink::XRReferenceSpaceType::kBoundedFloor:
// Information about -floor spaces is currently stored elsewhere (in stage
// parameters of display_info_). It probably should eventually move here.
// Information about -floor spaces is currently stored elsewhere (in
// stage_parameters_). It probably should eventually move here.
return base::nullopt;
}
}
......@@ -2055,34 +2096,8 @@ bool XRSession::RemoveHitTestSource(
void XRSession::SetXRDisplayInfo(
device::mojom::blink::VRDisplayInfoPtr display_info) {
// We don't necessarily trust the backend to only send us display info changes
// when something has actually changed, and a change here can trigger several
// other interfaces to recompute data or fire events, so it's worthwhile to
// validate that an actual change has occurred.
if (display_info_) {
if (display_info_->Equals(*display_info))
return;
if (display_info_->stage_parameters && display_info->stage_parameters &&
!display_info_->stage_parameters->Equals(
*(display_info->stage_parameters))) {
// Stage parameters changed.
stage_parameters_id_++;
} else if (!!(display_info_->stage_parameters) !=
!!(display_info->stage_parameters)) {
// Either stage parameters just became available (sometimes happens if
// detecting the bounds doesn't happen until a few seconds into the
// session for platforms such as WMR), or the stage parameters just went
// away (probably due to tracking loss).
stage_parameters_id_++;
}
} else if (display_info && display_info->stage_parameters) {
// Got stage parameters for the first time this session.
stage_parameters_id_++;
}
display_info_id_++;
display_info_ = std::move(display_info);
UpdateEyeParameters(display_info->left_eye, display_info->right_eye);
UpdateStageParameters(display_info->stage_parameters);
}
const HeapVector<Member<XRViewData>>& XRSession::views() {
......@@ -2093,23 +2108,26 @@ const HeapVector<Member<XRViewData>>& XRSession::views() {
// assumes that the views are arranged as follows.
if (views_dirty_) {
if (immersive()) {
// If we don't already have the views allocated, do so now.
if (views_.IsEmpty()) {
views_.emplace_back(MakeGarbageCollected<XRViewData>(XRView::kEyeLeft));
if (display_info_->right_eye) {
views_.emplace_back(
MakeGarbageCollected<XRViewData>(XRView::kEyeRight));
}
}
// In immersive mode the projection and view matrices must be aligned with
// the device's physical optics.
UpdateViewFromEyeParameters(
views_[kMonoOrStereoLeftView], display_info_->left_eye,
render_state_->depthNear(), render_state_->depthFar());
if (display_info_->right_eye) {
UpdateViewFromEyeParameters(
views_[kStereoRightView], display_info_->right_eye,
render_state_->depthNear(), render_state_->depthFar());
if (views_.size() != pending_view_parameters_.size()) {
views_.clear();
}
for (wtf_size_t i = 0; i < pending_view_parameters_.size(); ++i) {
if (views_.size() <= i) {
// TODO(crbug.com/998146): Replace with eyes communicated from the
// XR runtime.
XRView::XREye eye = i ? XRView::kEyeRight : XRView::kEyeLeft;
if (pending_view_parameters_.size() == 1) {
eye = XRView::kEyeNone;
}
views_.emplace_back(MakeGarbageCollected<XRViewData>(eye));
}
UpdateViewFromEyeParameters(views_[i], pending_view_parameters_[i],
render_state_->depthNear(),
render_state_->depthFar());
}
} else {
if (views_.IsEmpty()) {
......@@ -2130,7 +2148,7 @@ const HeapVector<Member<XRViewData>>& XRSession::views() {
// inlineVerticalFieldOfView should only be null in immersive mode.
DCHECK(inline_vertical_fov.has_value());
views_[kMonoOrStereoLeftView]->UpdateProjectionMatrixFromAspect(
views_[kMonoView]->UpdateProjectionMatrixFromAspect(
inline_vertical_fov.value(), aspect, render_state_->depthNear(),
render_state_->depthFar());
}
......
......@@ -260,8 +260,8 @@ class XRSession final
void OnMojoSpaceReset();
const device::mojom::blink::VRDisplayInfoPtr& GetVRDisplayInfo() const {
return display_info_;
const device::mojom::blink::VRStageParametersPtr& GetStageParameters() const {
return stage_parameters_;
}
mojo::PendingAssociatedRemote<
......@@ -271,7 +271,7 @@ class XRSession final
bool EmulatedPosition() const {
// If we don't have display info then we should be using the identity
// reference space, which by definition will be emulating the position.
if (!display_info_) {
if (!pending_view_parameters_.size()) {
return true;
}
......@@ -279,18 +279,16 @@ class XRSession final
}
// Immersive sessions currently use two views for VR, and only a single view
// for smartphone immersive AR mode. Convention is that we use the left eye
// if there's only a single view.
bool StereoscopicViews() { return display_info_ && display_info_->right_eye; }
// for smartphone immersive AR mode.
bool StereoscopicViews() { return pending_view_parameters_.size() >= 2; }
void UpdateEyeParameters(
const device::mojom::blink::VREyeParametersPtr& left_eye,
const device::mojom::blink::VREyeParametersPtr& right_eye);
void UpdateStageParameters(
const device::mojom::blink::VRStageParametersPtr& stage_parameters);
// Incremented every time display_info_ is changed, so that other objects that
// depend on it can know when they need to update.
unsigned int DisplayInfoPtrId() const { return display_info_id_; }
// Incremented every time stage_parameters_ is changed, so that other objects
// that depend on it can know when they need to update.
unsigned int StageParametersId() const { return stage_parameters_id_; }
// Returns true if the session recognizes passed in hit_test_source as still
......@@ -518,7 +516,9 @@ class XRSession final
HashSet<uint64_t> hit_test_source_ids_;
HashSet<uint64_t> hit_test_source_for_transient_input_ids_;
unsigned int view_parameters_id_ = 0;
HeapVector<Member<XRViewData>> views_;
Vector<device::mojom::blink::VREyeParametersPtr> pending_view_parameters_;
Member<XRInputSourceArray> input_sources_;
Member<XRWebGLLayer> prev_base_layer_;
......@@ -532,9 +532,8 @@ class XRSession final
HeapHashSet<Member<ScriptPromiseResolver>> request_hit_test_source_promises_;
HeapVector<Member<XRReferenceSpace>> reference_spaces_;
unsigned int display_info_id_ = 0;
unsigned int stage_parameters_id_ = 0;
device::mojom::blink::VRDisplayInfoPtr display_info_;
device::mojom::blink::VRStageParametersPtr stage_parameters_;
HeapMojoReceiver<device::mojom::blink::XRSessionClient,
XRSession,
......
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