Commit 78bd0693 authored by Klaus Weidner's avatar Klaus Weidner Committed by Commit Bot

Use ARCore camera frame time to estimate frame intervals

This should be more accurate than using wallclock time, but
is a bit clunky since unfortunately ARCore uses an unspecified
time base, so it's not directly compatible with base::TimeTicks.

Bug: 1064629
Change-Id: If4a73f26b7b5aaa7e87a615a15ad4b9031f5aa32
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2119637
Commit-Queue: Klaus Weidner <klausw@chromium.org>
Reviewed-by: default avatarPiotr Bialecki <bialpio@chromium.org>
Cr-Commit-Position: refs/heads/master@{#753410}
parent 5f3b5ea2
...@@ -45,6 +45,10 @@ class ArCore { ...@@ -45,6 +45,10 @@ class ArCore {
// when the camera image was updated successfully. // when the camera image was updated successfully.
virtual mojom::VRPosePtr Update(bool* camera_updated) = 0; virtual mojom::VRPosePtr Update(bool* camera_updated) = 0;
// Camera image timestamp. This returns TimeDelta instead of TimeTicks since
// ARCore internally uses an arbitrary and unspecified time base.
virtual base::TimeDelta GetFrameTimestamp() = 0;
// Return latest estimate for the floor height. // Return latest estimate for the floor height.
virtual float GetEstimatedFloorHeight() = 0; virtual float GetEstimatedFloorHeight() = 0;
......
...@@ -363,13 +363,13 @@ void ArCoreGl::GetFrameData( ...@@ -363,13 +363,13 @@ void ArCoreGl::GetFrameData(
base::TimeTicks arcore_update_started = base::TimeTicks::Now(); base::TimeTicks arcore_update_started = base::TimeTicks::Now();
mojom::VRPosePtr pose = arcore_->Update(&camera_updated); mojom::VRPosePtr pose = arcore_->Update(&camera_updated);
base::TimeTicks now = base::TimeTicks::Now(); base::TimeTicks now = base::TimeTicks::Now();
if (!arcore_update_completed_.is_null()) { base::TimeDelta frame_timestamp = arcore_->GetFrameTimestamp();
arcore_update_interval_ = now - arcore_update_completed_; if (!arcore_last_frame_timestamp_.is_zero()) {
arcore_update_next_expected_ = now + arcore_update_interval_; arcore_frame_interval_ = frame_timestamp - arcore_last_frame_timestamp_;
arcore_update_next_expected_ = now + arcore_frame_interval_;
} }
arcore_update_completed_ = now; arcore_last_frame_timestamp_ = frame_timestamp;
base::TimeDelta arcore_update_elapsed = base::TimeDelta arcore_update_elapsed = now - arcore_update_started;
arcore_update_completed_ - arcore_update_started;
TRACE_COUNTER1("gpu", "ARCore update elapsed (ms)", TRACE_COUNTER1("gpu", "ARCore update elapsed (ms)",
arcore_update_elapsed.InMilliseconds()); arcore_update_elapsed.InMilliseconds());
......
...@@ -232,9 +232,9 @@ class ArCoreGl : public mojom::XRFrameDataProvider, ...@@ -232,9 +232,9 @@ class ArCoreGl : public mojom::XRFrameDataProvider,
bool restrict_frame_data_ = false; bool restrict_frame_data_ = false;
base::TimeTicks arcore_update_completed_;
base::TimeTicks arcore_update_next_expected_; base::TimeTicks arcore_update_next_expected_;
base::TimeDelta arcore_update_interval_; base::TimeDelta arcore_last_frame_timestamp_;
base::TimeDelta arcore_frame_interval_;
FPSMeter fps_meter_; FPSMeter fps_meter_;
mojo::Receiver<mojom::XRFrameDataProvider> frame_data_receiver_{this}; mojo::Receiver<mojom::XRFrameDataProvider> frame_data_receiver_{this};
......
...@@ -465,6 +465,15 @@ mojom::VRPosePtr ArCoreImpl::Update(bool* camera_updated) { ...@@ -465,6 +465,15 @@ mojom::VRPosePtr ArCoreImpl::Update(bool* camera_updated) {
return GetMojomVRPoseFromArPose(arcore_session_.get(), arcore_pose.get()); return GetMojomVRPoseFromArPose(arcore_session_.get(), arcore_pose.get());
} }
base::TimeDelta ArCoreImpl::GetFrameTimestamp() {
DCHECK(arcore_session_.is_valid());
DCHECK(arcore_frame_.is_valid());
int64_t out_timestamp_ns;
ArFrame_getTimestamp(arcore_session_.get(), arcore_frame_.get(),
&out_timestamp_ns);
return base::TimeDelta::FromNanoseconds(out_timestamp_ns);
}
mojom::XRPlaneDetectionDataPtr ArCoreImpl::GetDetectedPlanesData() { mojom::XRPlaneDetectionDataPtr ArCoreImpl::GetDetectedPlanesData() {
DVLOG(2) << __func__; DVLOG(2) << __func__;
......
...@@ -64,6 +64,7 @@ class ArCoreImpl : public ArCore { ...@@ -64,6 +64,7 @@ class ArCoreImpl : public ArCore {
const base::span<const float> uvs) override; const base::span<const float> uvs) override;
gfx::Transform GetProjectionMatrix(float near, float far) override; gfx::Transform GetProjectionMatrix(float near, float far) override;
mojom::VRPosePtr Update(bool* camera_updated) override; mojom::VRPosePtr Update(bool* camera_updated) override;
base::TimeDelta GetFrameTimestamp() override;
mojom::XRPlaneDetectionDataPtr GetDetectedPlanesData() override; mojom::XRPlaneDetectionDataPtr GetDetectedPlanesData() override;
......
...@@ -34,6 +34,7 @@ namespace { ...@@ -34,6 +34,7 @@ namespace {
DO(ArFrame_create) \ DO(ArFrame_create) \
DO(ArFrame_destroy) \ DO(ArFrame_destroy) \
DO(ArFrame_getLightEstimate) \ DO(ArFrame_getLightEstimate) \
DO(ArFrame_getTimestamp) \
DO(ArFrame_getUpdatedAnchors) \ DO(ArFrame_getUpdatedAnchors) \
DO(ArFrame_getUpdatedTrackables) \ DO(ArFrame_getUpdatedTrackables) \
DO(ArFrame_hitTestRay) \ DO(ArFrame_hitTestRay) \
...@@ -275,6 +276,13 @@ void ArFrame_getLightEstimate(const ArSession* session, ...@@ -275,6 +276,13 @@ void ArFrame_getLightEstimate(const ArSession* session,
out_light_estimate); out_light_estimate);
} }
void ArFrame_getTimestamp(const ArSession* session,
const ArFrame* frame,
int64_t* out_timestamp_ns) {
return g_arcore_api->impl_ArFrame_getTimestamp(session, frame,
out_timestamp_ns);
}
void ArFrame_getUpdatedAnchors(const ArSession* session, void ArFrame_getUpdatedAnchors(const ArSession* session,
const ArFrame* frame, const ArFrame* frame,
ArAnchorList* out_anchor_list) { ArAnchorList* out_anchor_list) {
......
...@@ -196,6 +196,10 @@ mojom::VRPosePtr FakeArCore::Update(bool* camera_updated) { ...@@ -196,6 +196,10 @@ mojom::VRPosePtr FakeArCore::Update(bool* camera_updated) {
return pose; return pose;
} }
base::TimeDelta FakeArCore::GetFrameTimestamp() {
return base::TimeTicks::Now() - base::TimeTicks();
}
float FakeArCore::GetEstimatedFloorHeight() { float FakeArCore::GetEstimatedFloorHeight() {
return 2.0; return 2.0;
} }
......
...@@ -31,6 +31,7 @@ class FakeArCore : public ArCore { ...@@ -31,6 +31,7 @@ class FakeArCore : public ArCore {
const base::span<const float> uvs) override; const base::span<const float> uvs) override;
gfx::Transform GetProjectionMatrix(float near, float far) override; gfx::Transform GetProjectionMatrix(float near, float far) override;
mojom::VRPosePtr Update(bool* camera_updated) override; mojom::VRPosePtr Update(bool* camera_updated) override;
base::TimeDelta GetFrameTimestamp() override;
void Pause() override; void Pause() override;
void Resume() override; void Resume() override;
......
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