Commit e3d309c6 authored by Piotr Bialecki's avatar Piotr Bialecki Committed by Commit Bot

WebXR - anchor manager refactor

Refactor part 2/2. Previous part:
https://crrev.com/c/2087701

Separate anchor manager logic into "update" step and "obtain data" step,
similarly to the approach found in plane manager.

Change-Id: Ief886b53c1b933b7dae441bbe572b0302d82d28d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2107564
Commit-Queue: Piotr Bialecki <bialpio@chromium.org>
Reviewed-by: default avatarKlaus Weidner <klausw@chromium.org>
Cr-Commit-Position: refs/heads/master@{#751563}
parent 84610985
...@@ -22,68 +22,34 @@ ArCoreAnchorManager::ArCoreAnchorManager(util::PassKey<ArCoreImpl> pass_key, ...@@ -22,68 +22,34 @@ ArCoreAnchorManager::ArCoreAnchorManager(util::PassKey<ArCoreImpl> pass_key,
ArPose_create( ArPose_create(
arcore_session_, nullptr, arcore_session_, nullptr,
internal::ScopedArCoreObject<ArPose*>::Receiver(ar_pose_).get()); internal::ScopedArCoreObject<ArPose*>::Receiver(ar_pose_).get());
DCHECK(ar_pose_.is_valid());
} }
ArCoreAnchorManager::~ArCoreAnchorManager() = default; ArCoreAnchorManager::~ArCoreAnchorManager() = default;
mojom::XRAnchorsDataPtr ArCoreAnchorManager::GetAnchorsData( mojom::XRAnchorsDataPtr ArCoreAnchorManager::GetAnchorsData() const {
ArFrame* arcore_frame) { std::vector<uint64_t> all_anchors_ids;
auto updated_anchors = GetUpdatedAnchorsData(arcore_frame); all_anchors_ids.reserve(anchor_id_to_anchor_object_.size());
auto all_anchor_ids = GetAllAnchorIds(); for (const auto& anchor_id_and_object : anchor_id_to_anchor_object_) {
all_anchors_ids.push_back(anchor_id_and_object.first.GetUnsafeValue());
return mojom::XRAnchorsData::New(all_anchor_ids, std::move(updated_anchors)); }
}
std::vector<mojom::XRAnchorDataPtr> ArCoreAnchorManager::GetUpdatedAnchorsData(
ArFrame* arcore_frame) {
std::vector<mojom::XRAnchorDataPtr> result;
ArFrame_getUpdatedAnchors(arcore_session_, arcore_frame, std::vector<mojom::XRAnchorDataPtr> updated_anchors;
arcore_anchors_.get()); updated_anchors.reserve(updated_anchor_ids_.size());
for (const auto& anchor_id : updated_anchor_ids_) {
const device::internal::ScopedArCoreObject<ArAnchor*>& anchor =
anchor_id_to_anchor_object_.at(anchor_id);
ForEachArCoreAnchor(arcore_anchors_.get(), [this,
&result](ArAnchor* ar_anchor) {
// pose // pose
ArAnchor_getPose(arcore_session_, anchor.get(), ar_pose_.get());
ArAnchor_getPose(arcore_session_, ar_anchor, ar_pose_.get());
mojom::Pose pose = GetMojomPoseFromArPose(arcore_session_, ar_pose_.get()); mojom::Pose pose = GetMojomPoseFromArPose(arcore_session_, ar_pose_.get());
// ID updated_anchors.push_back(mojom::XRAnchorData::New(
AnchorId anchor_id; anchor_id.GetUnsafeValue(), device::mojom::Pose::New(pose)));
bool created; }
std::tie(anchor_id, created) = CreateOrGetAnchorId(ar_anchor);
DCHECK(!created)
<< "Anchor creation is app-initiated - we should never encounter an "
"anchor that was created outside of `ArCoreImpl::CreateAnchor()`.";
result.push_back(mojom::XRAnchorData::New(anchor_id.GetUnsafeValue(),
device::mojom::Pose::New(pose)));
});
return result;
}
std::vector<uint64_t> ArCoreAnchorManager::GetAllAnchorIds() {
std::vector<uint64_t> result;
ArSession_getAllAnchors(arcore_session_, arcore_anchors_.get());
ForEachArCoreAnchor(arcore_anchors_.get(), [this,
&result](ArAnchor* ar_anchor) {
// ID
AnchorId anchor_id;
bool created;
std::tie(anchor_id, created) = CreateOrGetAnchorId(ar_anchor);
DCHECK(!created)
<< "Anchor creation is app-initiated - we should never encounter an "
"anchor that was created outside of `ArCoreImpl::CreateAnchor()`.";
result.emplace_back(anchor_id);
});
return result; return mojom::XRAnchorsData::New(std::move(all_anchors_ids),
std::move(updated_anchors));
} }
template <typename FunctionType> template <typename FunctionType>
...@@ -108,10 +74,75 @@ void ArCoreAnchorManager::ForEachArCoreAnchor(ArAnchorList* arcore_anchors, ...@@ -108,10 +74,75 @@ void ArCoreAnchorManager::ForEachArCoreAnchor(ArAnchorList* arcore_anchors,
continue; continue;
} }
fn(anchor.get()); fn(std::move(anchor));
} }
} }
void ArCoreAnchorManager::Update(ArFrame* ar_frame) {
// First, ask ARCore about all Anchors updated in the current frame.
ArFrame_getUpdatedAnchors(arcore_session_, ar_frame, arcore_anchors_.get());
// Collect the IDs of updated anchors.
std::set<AnchorId> updated_anchor_ids;
ForEachArCoreAnchor(arcore_anchors_.get(), [this, &updated_anchor_ids](
device::internal::
ScopedArCoreObject<
ArAnchor*> ar_anchor) {
// ID
AnchorId anchor_id;
bool created;
std::tie(anchor_id, created) = CreateOrGetAnchorId(ar_anchor.get());
DCHECK(!created)
<< "Anchor creation is app-initiated - we should never encounter an "
"anchor that was created outside of `ArCoreImpl::CreateAnchor()`.";
updated_anchor_ids.insert(anchor_id);
});
DVLOG(3) << __func__
<< ": updated_anchor_ids.size()=" << updated_anchor_ids.size();
// Then, ask about all Anchors that are still tracked.
ArSession_getAllAnchors(arcore_session_, arcore_anchors_.get());
// Collect the objects of all currently tracked anchors.
// |ar_plane_address_to_id_| should *not* grow.
std::map<AnchorId, device::internal::ScopedArCoreObject<ArAnchor*>>
anchor_id_to_anchor_object;
ForEachArCoreAnchor(arcore_anchors_.get(), [this,
&anchor_id_to_anchor_object](
device::internal::
ScopedArCoreObject<
ArAnchor*> ar_anchor) {
// ID
AnchorId anchor_id;
bool created;
std::tie(anchor_id, created) = CreateOrGetAnchorId(ar_anchor.get());
DCHECK(!created)
<< "Anchor creation is app-initiated - we should never encounter an "
"anchor that was created outside of `ArCoreImpl::CreateAnchor()`.";
anchor_id_to_anchor_object[anchor_id] = std::move(ar_anchor);
});
DVLOG(3) << __func__ << ": anchor_id_to_anchor_object.size()="
<< anchor_id_to_anchor_object.size();
// Shrink |ar_plane_address_to_id_|, removing all planes that are no longer
// tracked or were subsumed - if they do not show up in
// |plane_id_to_plane_object| map, they are no longer tracked.
base::EraseIf(
ar_anchor_address_to_id_,
[&anchor_id_to_anchor_object](const auto& anchor_address_and_id) {
return !base::Contains(anchor_id_to_anchor_object,
anchor_address_and_id.second);
});
anchor_id_to_anchor_object_.swap(anchor_id_to_anchor_object);
updated_anchor_ids_.swap(updated_anchor_ids);
}
std::pair<AnchorId, bool> ArCoreAnchorManager::CreateOrGetAnchorId( std::pair<AnchorId, bool> ArCoreAnchorManager::CreateOrGetAnchorId(
void* anchor_address) { void* anchor_address) {
auto it = ar_anchor_address_to_id_.find(anchor_address); auto it = ar_anchor_address_to_id_.find(anchor_address);
...@@ -162,7 +193,8 @@ base::Optional<AnchorId> ArCoreAnchorManager::CreateAnchor( ...@@ -162,7 +193,8 @@ base::Optional<AnchorId> ArCoreAnchorManager::CreateAnchor(
DVLOG(2) << __func__ << ": plane_id=" << plane_id; DVLOG(2) << __func__ << ": plane_id=" << plane_id;
auto ar_anchor = plane_manager->CreateAnchor(plane_id, pose); auto ar_anchor = plane_manager->CreateAnchor(
util::PassKey<ArCoreAnchorManager>(), plane_id, pose);
if (!ar_anchor.is_valid()) { if (!ar_anchor.is_valid()) {
return base::nullopt; return base::nullopt;
} }
......
...@@ -31,7 +31,7 @@ class ArCoreAnchorManager { ...@@ -31,7 +31,7 @@ class ArCoreAnchorManager {
// anchors. // anchors.
void Update(ArFrame* ar_frame); void Update(ArFrame* ar_frame);
mojom::XRAnchorsDataPtr GetAnchorsData(ArFrame* arcore_frame); mojom::XRAnchorsDataPtr GetAnchorsData() const;
bool AnchorExists(AnchorId id) const; bool AnchorExists(AnchorId id) const;
...@@ -50,19 +50,11 @@ class ArCoreAnchorManager { ...@@ -50,19 +50,11 @@ class ArCoreAnchorManager {
private: private:
// Executes |fn| for each still tracked, anchor present in |arcore_anchors|. // Executes |fn| for each still tracked, anchor present in |arcore_anchors|.
// |fn| will receive a non-owning `ArAnchor*`. // |fn| will receive a `device::internal::ScopedArCoreObject<ArAnchor*>` that
// can be stored.
template <typename FunctionType> template <typename FunctionType>
void ForEachArCoreAnchor(ArAnchorList* arcore_anchors, FunctionType fn); void ForEachArCoreAnchor(ArAnchorList* arcore_anchors, FunctionType fn);
// Returns vector containing information about all anchors updated in the
// current frame.
std::vector<mojom::XRAnchorDataPtr> GetUpdatedAnchorsData(
ArFrame* arcore_frame);
// The result will contain IDs of all anchors still tracked in the current
// frame.
std::vector<uint64_t> GetAllAnchorIds();
// Owned by ArCoreImpl - non-owning pointer is fine since ArCoreAnchorManager // Owned by ArCoreImpl - non-owning pointer is fine since ArCoreAnchorManager
// is also owned by ArCoreImpl. // is also owned by ArCoreImpl.
ArSession* arcore_session_; ArSession* arcore_session_;
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include "base/optional.h" #include "base/optional.h"
#include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event.h"
#include "base/util/type_safety/pass_key.h" #include "base/util/type_safety/pass_key.h"
#include "chrome/browser/android/vr/arcore_device/arcore_java_utils.h"
#include "chrome/browser/android/vr/arcore_device/arcore_plane_manager.h" #include "chrome/browser/android/vr/arcore_device/arcore_plane_manager.h"
#include "chrome/browser/android/vr/arcore_device/type_converters.h" #include "chrome/browser/android/vr/arcore_device/type_converters.h"
#include "device/vr/public/mojom/vr_service.mojom.h" #include "device/vr/public/mojom/vr_service.mojom.h"
...@@ -459,6 +458,10 @@ mojom::VRPosePtr ArCoreImpl::Update(bool* camera_updated) { ...@@ -459,6 +458,10 @@ mojom::VRPosePtr ArCoreImpl::Update(bool* camera_updated) {
plane_manager_->Update(arcore_frame_.get()); plane_manager_->Update(arcore_frame_.get());
TRACE_EVENT_END0("gpu", "ArCorePlaneManager Update"); TRACE_EVENT_END0("gpu", "ArCorePlaneManager Update");
TRACE_EVENT_BEGIN0("gpu", "ArCoreAnchorManager Update");
anchor_manager_->Update(arcore_frame_.get());
TRACE_EVENT_END0("gpu", "ArCoreAnchorManager Update");
return GetMojomVRPoseFromArPose(arcore_session_.get(), arcore_pose.get()); return GetMojomVRPoseFromArPose(arcore_session_.get(), arcore_pose.get());
} }
...@@ -475,7 +478,7 @@ mojom::XRAnchorsDataPtr ArCoreImpl::GetAnchorsData() { ...@@ -475,7 +478,7 @@ mojom::XRAnchorsDataPtr ArCoreImpl::GetAnchorsData() {
TRACE_EVENT0("gpu", __func__); TRACE_EVENT0("gpu", __func__);
return anchor_manager_->GetAnchorsData(arcore_frame_.get()); return anchor_manager_->GetAnchorsData();
} }
mojom::XRLightEstimationDataPtr ArCoreImpl::GetLightEstimationData() { mojom::XRLightEstimationDataPtr ArCoreImpl::GetLightEstimationData() {
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
#include "chrome/browser/android/vr/arcore_device/arcore_plane_manager.h" #include "chrome/browser/android/vr/arcore_device/arcore_plane_manager.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/trace_event/trace_event.h"
#include "chrome/browser/android/vr/arcore_device/type_converters.h" #include "chrome/browser/android/vr/arcore_device/type_converters.h"
namespace device { namespace device {
...@@ -199,8 +198,6 @@ void ArCorePlaneManager::Update(ArFrame* ar_frame) { ...@@ -199,8 +198,6 @@ void ArCorePlaneManager::Update(ArFrame* ar_frame) {
mojom::XRPlaneDetectionDataPtr ArCorePlaneManager::GetDetectedPlanesData() mojom::XRPlaneDetectionDataPtr ArCorePlaneManager::GetDetectedPlanesData()
const { const {
TRACE_EVENT0("gpu", __FUNCTION__);
std::vector<uint64_t> all_plane_ids; std::vector<uint64_t> all_plane_ids;
all_plane_ids.reserve(plane_id_to_plane_object_.size()); all_plane_ids.reserve(plane_id_to_plane_object_.size());
for (const auto& plane_id_and_object : plane_id_to_plane_object_) { for (const auto& plane_id_and_object : plane_id_to_plane_object_) {
...@@ -220,13 +217,8 @@ mojom::XRPlaneDetectionDataPtr ArCorePlaneManager::GetDetectedPlanesData() ...@@ -220,13 +217,8 @@ mojom::XRPlaneDetectionDataPtr ArCorePlaneManager::GetDetectedPlanesData()
ArPlane_getType(arcore_session_, ar_plane, &plane_type); ArPlane_getType(arcore_session_, ar_plane, &plane_type);
// pose // pose
internal::ScopedArCoreObject<ArPose*> plane_pose; ArPlane_getCenterPose(arcore_session_, ar_plane, ar_pose_.get());
ArPose_create( mojom::Pose pose = GetMojomPoseFromArPose(arcore_session_, ar_pose_.get());
arcore_session_, nullptr,
internal::ScopedArCoreObject<ArPose*>::Receiver(plane_pose).get());
ArPlane_getCenterPose(arcore_session_, ar_plane, plane_pose.get());
mojom::Pose pose =
GetMojomPoseFromArPose(arcore_session_, plane_pose.get());
// polygon // polygon
int32_t polygon_size; int32_t polygon_size;
...@@ -305,7 +297,8 @@ base::Optional<gfx::Transform> ArCorePlaneManager::GetMojoFromPlane( ...@@ -305,7 +297,8 @@ base::Optional<gfx::Transform> ArCorePlaneManager::GetMojoFromPlane(
} }
device::internal::ScopedArCoreObject<ArAnchor*> device::internal::ScopedArCoreObject<ArAnchor*>
ArCorePlaneManager::CreateAnchor(PlaneId id, ArCorePlaneManager::CreateAnchor(util::PassKey<ArCoreAnchorManager> pass_key,
PlaneId id,
const device::mojom::Pose& pose) const { const device::mojom::Pose& pose) const {
auto it = plane_id_to_plane_object_.find(id); auto it = plane_id_to_plane_object_.find(id);
if (it == plane_id_to_plane_object_.end()) { if (it == plane_id_to_plane_object_.end()) {
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
namespace device { namespace device {
class ArCoreImpl; class ArCoreImpl;
class ArCoreAnchorManager;
using PlaneId = util::IdTypeU64<class PlaneTag>; using PlaneId = util::IdTypeU64<class PlaneTag>;
...@@ -55,8 +56,9 @@ class ArCorePlaneManager { ...@@ -55,8 +56,9 @@ class ArCorePlaneManager {
// Creates Anchor object given a plane ID. This is needed since Plane objects // Creates Anchor object given a plane ID. This is needed since Plane objects
// are managed by this class in its entirety and are not accessible outside // are managed by this class in its entirety and are not accessible outside
// it. // it. Callable only from ArCoreAnchorManager.
device::internal::ScopedArCoreObject<ArAnchor*> CreateAnchor( device::internal::ScopedArCoreObject<ArAnchor*> CreateAnchor(
util::PassKey<ArCoreAnchorManager> pass_key,
PlaneId id, PlaneId id,
const device::mojom::Pose& pose) const; const device::mojom::Pose& pose) const;
......
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