Fix display orientation handling
- Apply the orientation compensator before the filter. Otherwise, we
won't tend to identity, but rather to a rotated frame, which is
incorrect.
- Enable rate limiting when orientation changes, but only when a new
world-to-screen pose arrives. This makes sure that rate limiting is
applied at the point of discontinuity regardless of the order of
operations.
Test: atest --host libheadtracking-test
Bug: 188502620
Change-Id: I58e1c3807f875ae2735e65122a3ffb8483bde2a3
diff --git a/media/libheadtracking/HeadTrackingProcessor.cpp b/media/libheadtracking/HeadTrackingProcessor.cpp
index 3f1a18d..47f7cf0 100644
--- a/media/libheadtracking/HeadTrackingProcessor.cpp
+++ b/media/libheadtracking/HeadTrackingProcessor.cpp
@@ -57,7 +57,14 @@
}
void setWorldToScreenPose(int64_t timestamp, const Pose3f& worldToScreen) override {
- mScreenPoseDriftCompensator.setInput(timestamp, worldToScreen);
+ if (mPhysicalToLogicalAngle != mPendingPhysicalToLogicalAngle) {
+ // We're introducing an artificial discontinuity. Enable the rate limiter.
+ mRateLimiter.enable();
+ mPhysicalToLogicalAngle = mPendingPhysicalToLogicalAngle;
+ }
+
+ mScreenPoseDriftCompensator.setInput(
+ timestamp, worldToScreen * Pose3f(rotateY(-mPhysicalToLogicalAngle)));
mWorldToScreenTimestamp = timestamp;
}
@@ -66,10 +73,7 @@
}
void setDisplayOrientation(float physicalToLogicalAngle) override {
- if (mPhysicalToLogicalAngle != physicalToLogicalAngle) {
- mRateLimiter.enable();
- }
- mPhysicalToLogicalAngle = physicalToLogicalAngle;
+ mPendingPhysicalToLogicalAngle = physicalToLogicalAngle;
}
void calculate(int64_t timestamp) override {
@@ -80,8 +84,7 @@
}
if (mWorldToScreenTimestamp.has_value()) {
- const Pose3f worldToLogicalScreen = mScreenPoseDriftCompensator.getOutput() *
- Pose3f(rotateY(-mPhysicalToLogicalAngle));
+ const Pose3f worldToLogicalScreen = mScreenPoseDriftCompensator.getOutput();
mScreenHeadFusion.setWorldToScreenPose(mWorldToScreenTimestamp.value(),
worldToLogicalScreen);
}
@@ -129,6 +132,9 @@
private:
const Options mOptions;
float mPhysicalToLogicalAngle = 0;
+ // We store the physical to logical angle as "pending" until the next world-to-screen sample it
+ // applies to arrives.
+ float mPendingPhysicalToLogicalAngle = 0;
std::optional<int64_t> mWorldToHeadTimestamp;
std::optional<int64_t> mWorldToScreenTimestamp;
Pose3f mHeadToStagePose;