blob: 7058f1a0a25d9cb2fe376f84f7885e68afde5296 [file] [log] [blame]
#ifndef ANDROID_DVR_RAW_POSE_H_
#define ANDROID_DVR_RAW_POSE_H_
#include <atomic>
namespace android {
namespace dvr {
// POD raw data of a head pose with a count field for read consistency checking.
// Warning: The layout of this struct and RawPosePair are specific to match the
// corresponding buffer type in the shader in late_latch.cpp.
struct RawPose {
void Reset(uint32_t new_count) volatile {
qx = qy = qz = 0.0f;
qw = 1.0f;
px = py = pz = 0.0f;
count = new_count;
}
float qx, qy, qz, qw;
float px, py, pz;
std::atomic<uint32_t> count;
};
// RawPosePair is used for lock-free writing at about 1khz by the CPU/DSP
// and reading by the GPU. At creation time, pose1 is given count = 1 and
// pose2 is given count = 2.
//
// The lock-free write pattern is:
// - write to pose with least count.
// - memory write barrier.
// - write count = count + 2.
//
// For reads, there is an important assumption about the GPU: it generally
// processes things contiguously, without arbitrary preemptions that save and
// restore full cache states. In other words, if the GPU is preempted and then
// later resumed, any data that was read from memory before the preemption will
// be re-read from memory after resume. This allows the following read trick to
// work:
// - read the full RawPosePair into a shader.
// - select the pose with the newest count.
//
// The older pose may be partially written by the async stores from CPU/DSP, but
// because of the memory barrier and GPU characteristics, the highest count pose
// should always be a fully consistent RawPose.
struct RawPosePair {
RawPose pose1;
RawPose pose2;
};
} // namespace dvr
} // namespace android
#endif // ANDROID_DVR_RAW_POSE_H_