1 #ifndef ANDROID_DVR_SHARED_BUFFERS_H_
2 #define ANDROID_DVR_SHARED_BUFFERS_H_
3 
4 #include <dvr/dvr_config.h>
5 #include <dvr/dvr_pose.h>
6 #include <dvr/dvr_vsync.h>
7 #include <libbroadcastring/broadcast_ring.h>
8 
9 // This header is shared by VrCore and Android and must be kept in sync.
10 namespace android {
11 namespace dvr {
12 
13 // Increment when the layout for the buffers change.
14 enum : uint32_t { kSharedBufferLayoutVersion = 2 };
15 
16 // Note: These buffers will be mapped from various system processes as well
17 // as VrCore and the application processes in a r/w manner.
18 //
19 // Therefore it is possible for the application to mess with the contents of
20 // these buffers.
21 //
22 // While using them, assume garbage memory: Your logic must not crash or lead
23 // to execution of unsafe code as a function of the contents of these buffers.
24 
25 // Sanity check for basic type sizes.
26 static_assert(sizeof(DvrPoseAsync) == 128, "Unexpected size for DvrPoseAsync");
27 static_assert(sizeof(DvrPose) == 112, "Unexpected size for DvrPose");
28 static_assert(sizeof(DvrVsync) == 32, "Unexpected size for DvrVsync");
29 static_assert(sizeof(DvrConfig) == 16, "Unexpected size for DvrConfig");
30 
31 // A helper class that provides compile time sized traits for the BroadcastRing.
32 template <class DvrType, size_t StaticCount>
33 class DvrRingBufferTraits {
34  public:
35   using Record = DvrType;
36   static constexpr bool kUseStaticRecordSize = false;
37   static constexpr uint32_t kStaticRecordCount = StaticCount;
38   static constexpr int kMaxReservedRecords = 1;
39   static constexpr int kMinAvailableRecords = 1;
40 };
41 
42 // Traits classes.
43 using DvrPoseTraits = DvrRingBufferTraits<DvrPose, 0>;
44 using DvrVsyncTraits = DvrRingBufferTraits<DvrVsync, 2>;
45 using DvrConfigTraits = DvrRingBufferTraits<DvrConfig, 2>;
46 
47 // The broadcast ring classes that will expose the data.
48 using DvrPoseRing = BroadcastRing<DvrPose, DvrPoseTraits>;
49 using DvrVsyncRing = BroadcastRing<DvrVsync, DvrVsyncTraits>;
50 using DvrConfigRing = BroadcastRing<DvrConfig, DvrConfigTraits>;
51 
52 // This is a shared memory buffer for passing pose data estimated at vsyncs.
53 //
54 // This will be primarily used for late latching and EDS where we bind this
55 // buffer in a shader and extract the right vsync-predicted pose.
56 struct __attribute__((packed, aligned(16))) DvrVsyncPoseBuffer {
57   enum : int {
58     // The number vsync predicted poses to keep in the ring buffer.
59     // Must be a power of 2.
60     kSize = 8,
61     kIndexMask = kSize - 1,
62 
63     // The number of vsyncs (from the current vsync) we predict in vsync buffer.
64     // The other poses are left alone.
65     kMinFutureCount = 4
66   };
67 
68   // The vsync predicted poses.
69   // The pose for the vsync n is:
70   // vsync_poses[n % kSize]
71   //
72   // This buffer is unsynchronized: It is possible to get torn reads as the
73   // sensor service updates the predictions as new sensor measurements come
74   // in. In particular, it is possible to get the position and an updated
75   // orientation while reading.
76   DvrPoseAsync vsync_poses[kSize];
77 
78   // The latest sensor pose for GPU usage.
79   DvrPose current_pose;
80 
81   // Current vsync_count (where sensord is writing poses from).
82   uint32_t vsync_count;
83 
84   // For 16 byte alignment.
85   uint8_t padding[12];
86 };
87 
88 static_assert(sizeof(DvrVsyncPoseBuffer) == 1152,
89               "Unexpected size for DvrVsyncPoseBuffer");
90 
91 // The keys for the dvr global buffers.
92 enum DvrGlobalBuffers : int32_t {
93   kVsyncPoseBuffer = 1,
94   kVsyncBuffer = 2,
95   kSensorPoseBuffer = 3,
96   kVrFlingerConfigBufferKey = 4
97 };
98 
99 }  // namespace dvr
100 }  // namespace android
101 
102 #endif  // ANDROID_DVR_SHARED_BUFFERS_H_
103