Files
mitch030504--Wiicompiled_VR…/aurora-main/lib/stereo_interpolation.hpp
T
iChris4 e7eab8a6b2 Refactor stereo frame worker and interpolation tests for enhanced VR performance
- Updated stereo_frame_worker_smoke.cpp to allow dynamic headset rates and prediction lead time.
- Improved logging to include motion diagnostics and adjusted frame submission logic based on headset frequency.
- Enhanced stereo_interpolation_test.cpp with additional tests for camera motion separation and playback cadence.
- Introduced MkwVRReadSceneView function to read the camera view matrix for improved scene rendering.
- Modified VR first-person logic to support scene view reading and validation.
- Added scene_camera.hpp to encapsulate camera motion handling and inverse view calculations.
- Ensured that the VR integration layer correctly logs motion diagnostics and handles scene playback accurately.
2026-10-01 00:37:49 +02:00

100 lines
3.4 KiB
C++

#pragma once
#include <algorithm>
#include <cstdint>
namespace aurora::stereo {
// Scene playback uses the producer's cadence on a local monotonic clock. The
// compositor may predict head poses several frames ahead; sampling the two known
// scene endpoints at that future time would clamp every image to the newest one.
// Anchor when history starts. If production later arrives earlier on that grid
// (e.g. after shader warm-up), advance the origin enough to reach the new pair.
// Never move playback backwards to follow a late seal or the prediction horizon.
class ScenePlaybackClock {
public:
void begin_scene(uint64_t boundary, uint64_t now, bool continuous) noexcept {
if (!continuous || originBoundary_ == 0 || now < originTime_ || boundary <= lastBoundary_ ||
sample_time(now) < boundary) {
originBoundary_ = boundary;
originTime_ = now;
}
lastBoundary_ = boundary;
}
uint64_t sample_time(uint64_t now) const noexcept {
if (originBoundary_ == 0 || now < originTime_)
return 0;
return originBoundary_ + (now - originTime_);
}
private:
uint64_t originBoundary_ = 0;
uint64_t originTime_ = 0;
uint64_t lastBoundary_ = 0;
};
// The current scene belongs to boundary, and playback blends from the preceding
// scene for one guest interval. Head tracking is applied afterwards, undelayed.
inline float interpolation_weight(uint64_t sampleTime, uint64_t boundary, uint64_t interval) noexcept {
if (sampleTime == 0 || boundary == 0 || interval == 0)
return 1.0f;
if (sampleTime <= boundary)
return 0.0f;
return static_cast<float>(std::min(static_cast<double>(sampleTime - boundary) / static_cast<double>(interval), 1.0));
}
// Worker-owned window. A fresh eye pair can still repeat the same game-scene
// time, or move it backwards when an overdue scene is replaced. Neither is
// visible in the compositor's submission FPS. Discontinuities have no comparable
// scene time, so they break the sequence rather than counting as backwards motion.
struct MotionSamples {
uint32_t samples = 0;
uint32_t blended = 0;
uint32_t atPrevious = 0;
uint32_t atCurrent = 0;
uint32_t discontinuous = 0;
uint32_t repeated = 0;
uint32_t backwards = 0;
uint64_t lastSceneTime = 0;
uint64_t minStep = UINT64_MAX;
uint64_t maxStep = 0;
void record(uint64_t displayTime, uint64_t boundary, uint64_t interval,
bool continuous, float weight) noexcept {
++samples;
if (!continuous || displayTime == 0 || boundary < interval || interval == 0) {
++discontinuous;
lastSceneTime = 0;
return;
}
if (weight <= 0.0f)
++atPrevious;
else if (weight >= 1.0f)
++atCurrent;
else
++blended;
const uint64_t sceneTime = boundary - interval +
static_cast<uint64_t>(static_cast<double>(interval) * weight);
if (lastSceneTime != 0) {
if (sceneTime >= lastSceneTime) {
const auto step = sceneTime - lastSceneTime;
minStep = std::min(minStep, step);
maxStep = std::max(maxStep, step);
}
// Float interpolation weights can differ by a few nanoseconds at a boundary.
if (sceneTime + 1000 < lastSceneTime)
++backwards;
else if (sceneTime <= lastSceneTime + 1000)
++repeated;
}
lastSceneTime = sceneTime;
}
void clear_window() noexcept {
const auto last = lastSceneTime;
*this = {};
lastSceneTime = last;
}
};
} // namespace aurora::stereo