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 {
// when the camera image was updated successfully.
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.
virtual float GetEstimatedFloorHeight() = 0;
......
......@@ -363,13 +363,13 @@ void ArCoreGl::GetFrameData(
base::TimeTicks arcore_update_started = base::TimeTicks::Now();
mojom::VRPosePtr pose = arcore_->Update(&camera_updated);
base::TimeTicks now = base::TimeTicks::Now();
if (!arcore_update_completed_.is_null()) {
arcore_update_interval_ = now - arcore_update_completed_;
arcore_update_next_expected_ = now + arcore_update_interval_;
base::TimeDelta frame_timestamp = arcore_->GetFrameTimestamp();
if (!arcore_last_frame_timestamp_.is_zero()) {
arcore_frame_interval_ = frame_timestamp - arcore_last_frame_timestamp_;
arcore_update_next_expected_ = now + arcore_frame_interval_;
}
arcore_update_completed_ = now;
base::TimeDelta arcore_update_elapsed =
arcore_update_completed_ - arcore_update_started;
arcore_last_frame_timestamp_ = frame_timestamp;
base::TimeDelta arcore_update_elapsed = now - arcore_update_started;
TRACE_COUNTER1("gpu", "ARCore update elapsed (ms)",
arcore_update_elapsed.InMilliseconds());
......
......@@ -232,9 +232,9 @@ class ArCoreGl : public mojom::XRFrameDataProvider,
bool restrict_frame_data_ = false;
base::TimeTicks arcore_update_completed_;
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_;
mojo::Receiver<mojom::XRFrameDataProvider> frame_data_receiver_{this};
......
......@@ -465,6 +465,15 @@ mojom::VRPosePtr ArCoreImpl::Update(bool* camera_updated) {
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() {
DVLOG(2) << __func__;
......
......@@ -64,6 +64,7 @@ class ArCoreImpl : public ArCore {
const base::span<const float> uvs) override;
gfx::Transform GetProjectionMatrix(float near, float far) override;
mojom::VRPosePtr Update(bool* camera_updated) override;
base::TimeDelta GetFrameTimestamp() override;
mojom::XRPlaneDetectionDataPtr GetDetectedPlanesData() override;
......
......@@ -34,6 +34,7 @@ namespace {
DO(ArFrame_create) \
DO(ArFrame_destroy) \
DO(ArFrame_getLightEstimate) \
DO(ArFrame_getTimestamp) \
DO(ArFrame_getUpdatedAnchors) \
DO(ArFrame_getUpdatedTrackables) \
DO(ArFrame_hitTestRay) \
......@@ -275,6 +276,13 @@ void ArFrame_getLightEstimate(const ArSession* session,
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,
const ArFrame* frame,
ArAnchorList* out_anchor_list) {
......
......@@ -196,6 +196,10 @@ mojom::VRPosePtr FakeArCore::Update(bool* camera_updated) {
return pose;
}
base::TimeDelta FakeArCore::GetFrameTimestamp() {
return base::TimeTicks::Now() - base::TimeTicks();
}
float FakeArCore::GetEstimatedFloorHeight() {
return 2.0;
}
......
......@@ -31,6 +31,7 @@ class FakeArCore : public ArCore {
const base::span<const float> uvs) override;
gfx::Transform GetProjectionMatrix(float near, float far) override;
mojom::VRPosePtr Update(bool* camera_updated) override;
base::TimeDelta GetFrameTimestamp() override;
void Pause() 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