VRPuppetCommandBuffer.h (8291B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef GFX_VR_SERVICE_VRPUPPETCOMMANDBUFFER_H 8 #define GFX_VR_SERVICE_VRPUPPETCOMMANDBUFFER_H 9 10 #include <inttypes.h> 11 #include "mozilla/Mutex.h" 12 #include "nsTArray.h" 13 #include "moz_external_vr.h" 14 #include "mozilla/TimeStamp.h" 15 16 namespace mozilla { 17 namespace gfx { 18 19 /** 20 * A Puppet Device command buffer consists of a stream of 64-bit 21 * commands. 22 * The first 8 bits identifies the command and informs format of 23 * the remaining 56 bits. 24 * 25 * These commands will be streamed into a buffer until 26 * VRPuppet_End (0x0000000000000000) has been received. 27 * 28 * When VRPuppet_End is received, this command buffer will 29 * be executed asynchronously, collecting the timer results 30 * requested. 31 * 32 * In addition to the effects seen through the WebXR/VR API, tests 33 * can get further feedback from the Puppet device. 34 * Command buffers can be constructed such that when expected states 35 * are not reached, the timeout timer will expire. 36 * Data recorded with timer commands is returned when the command 37 * buffer is completed, to validate against accepted ranges and to 38 * quantify performance regressions. 39 * Images submitted to the Puppet display are rendered with the 40 * 2d browser output in order to enable reftests to validate 41 * output against reference images. 42 * 43 * The state of the virtual puppet device is expressed to the VR service 44 * in the same manner as physical devices -- using the VRDisplayState, 45 * VRHMDSensorState and VRControllerState structures. 46 * 47 * By enabling partial updates of these structures, the command buffer 48 * size is reduced to the values that change each frame. This enables 49 * realtime capture of a session, with physical hardware, for 50 * replay in automated tests and benchmarks. 51 * 52 * All updates to the state structures are atomically updated in the 53 * VR session thread, triggered by VRPuppet_Commit (0x1500000000000000). 54 * 55 * Command buffers are expected to be serialized to a human readable, 56 * ascii format if stored on disk. The binary representation is not 57 * guaranteed to be consistent between versions or target platforms. 58 * They should be re-constructed with the VRServiceTest DOM api at 59 * runtime. 60 * 61 * The command set: 62 * 63 * 0x0000000000000000 - VRPuppet_End() 64 * - End of stream, resolve promise returned by VRServiceTest::Play() 65 * 66 * 0x0100000000000000 - VRPuppet_ClearAll() 67 * - Clear all structs 68 * 69 * 0x02000000000000nn - VRPuppet_ClearController(n) 70 * - Clear a single controller struct 71 * 72 * 0x03000000nnnnnnnn - VRPuppet_Timeout(n) 73 * - Reset the timeout timer to n milliseconds 74 * - Initially the timeout timer starts at 10 seconds 75 * 76 * 0x04000000nnnnnnnn - VRPuppet_Wait(n) 77 * - Wait n milliseconds before advancing to next command 78 * 79 * 0x0500000000000000 - VRPuppet_WaitSubmit() 80 * - Wait until a frame has been submitted before advancing to the next command 81 * 82 * 0x0600000000000000 - VRPuppet_WaitPresentationStart() 83 * - Wait until a presentation becomes active 84 * 85 * 0x0700000000000000 - VRPuppet_WaitPresentationEnd() 86 * - Wait until a presentation ends 87 * 88 * 0x0800cchhvvvvvvvv - VRPuppet_WaitHapticIntensity(c, h, v) 89 * - Wait until controller at index c's haptic actuator at index h reaches value 90 * v. 91 * - v is a 16.16 fixed point value, with 1.0f being the highest intensity and 92 * 0.0f indicating that the haptic actuator is not running 93 * 94 * 0x0900000000000000 - VRPuppet_CaptureFrame() 95 * - Captures the submitted frame. Must later call 96 * VRPuppet_AcknowledgeFrame or VRPuppet_RejectFrame 97 * to unblock 98 * 99 * 0x0900000000000000 - VRPuppet_AcknowledgeFrame() 100 * - Acknowledge the submitted frame, unblocking the Submit call. 101 * 102 * 0x0a00000000000000 - VRPuppet_RejectFrame() 103 * - Reject the submitted frame, unblocking the Submit call. 104 * 105 * 0x0b00000000000000 - VRPuppet_StartTimer() 106 * - Starts the timer 107 * 108 * 0x0c00000000000000 - VRPuppet_StopTimer() 109 * - Stops the timer, the elapsed duration is recorded for access after the end 110 * of stream 111 * 112 * 0x0d000000aaaaaaaa - VRPuppet_UpdateDisplay(a) 113 * - Start writing data to the VRDisplayState struct, at offset a 114 * 115 * 0x0e000000aaaaaaaa - VRPuppet_UpdateSensor(a) 116 * - Start writing data to the VRHMDSensorState struct, at offset a 117 * 118 * 0x0f000000aaaaaaaa - VRPuppet_UpdateControllers(a) 119 * - Start writing data to the VRControllerState array, at offset a 120 * 121 * 0x100000000000000 - VRPuppet_Commit 122 * - Atomically commit the VRPuppet_Data updates to VRDisplayState, 123 * VRHMDSensorState and VRControllerState. 124 * 125 * 0xf0000000000000dd - VRPuppet_Data(d) 126 * - 1 byte of data 127 * 128 * 0xf10000000000dddd - VRPuppet_Data(d) 129 * - 2 bytes of data 130 * 131 * 0xf200000000dddddd - VRPuppet_Data(d) 132 * - 3 bytes of data 133 * 134 * 0xf3000000dddddddd - VRPuppet_Data(d) 135 * - 4 bytes of data 136 * 137 * 0xf40000dddddddddd - VRPuppet_Data(d) 138 * - 5 bytes of data 139 * 140 * 0xf500dddddddddddd - VRPuppet_Data(d) 141 * - 6 bytes of data 142 * 143 * 0xf6dddddddddddddd - VRPuppet_Data(d) 144 * - 7 bytes of data 145 * 146 */ 147 enum class VRPuppet_Command : uint64_t { 148 VRPuppet_End = 0x0000000000000000, 149 VRPuppet_ClearAll = 0x0100000000000000, 150 VRPuppet_ClearController = 0x0200000000000000, 151 VRPuppet_Timeout = 0x0300000000000000, 152 VRPuppet_Wait = 0x0400000000000000, 153 VRPuppet_WaitSubmit = 0x0500000000000000, 154 VRPuppet_WaitPresentationStart = 0x0600000000000000, 155 VRPuppet_WaitPresentationEnd = 0x0700000000000000, 156 VRPuppet_WaitHapticIntensity = 0x0800000000000000, 157 VRPuppet_CaptureFrame = 0x0900000000000000, 158 VRPuppet_AcknowledgeFrame = 0x0a00000000000000, 159 VRPuppet_RejectFrame = 0x0b00000000000000, 160 VRPuppet_StartTimer = 0x0c00000000000000, 161 VRPuppet_StopTimer = 0x0d00000000000000, 162 VRPuppet_UpdateDisplay = 0x0e00000000000000, 163 VRPuppet_UpdateSensor = 0x0f00000000000000, 164 VRPuppet_UpdateControllers = 0x1000000000000000, 165 VRPuppet_Commit = 0x1100000000000000, 166 VRPuppet_Data1 = 0xf000000000000000, 167 VRPuppet_Data2 = 0xf100000000000000, 168 VRPuppet_Data3 = 0xf200000000000000, 169 VRPuppet_Data4 = 0xf300000000000000, 170 VRPuppet_Data5 = 0xf400000000000000, 171 VRPuppet_Data6 = 0xf500000000000000, 172 VRPuppet_Data7 = 0xf600000000000000, 173 }; 174 175 static const int kNumPuppetHaptics = 8; 176 177 class VRPuppetCommandBuffer { 178 public: 179 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(mozilla::gfx::VRPuppetCommandBuffer) 180 static VRPuppetCommandBuffer& Get(); 181 static bool IsCreated(); 182 183 // Interface to VRTestSystem 184 void Submit(const nsTArray<uint64_t>& aBuffer); 185 void Reset(); 186 bool HasEnded(); 187 188 // Interface to PuppetSession 189 void Run(VRSystemState& aState); 190 void StartPresentation(); 191 void StopPresentation(); 192 bool SubmitFrame(); 193 void VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex, 194 float aIntensity, float aDuration); 195 void StopVibrateHaptic(uint32_t aControllerIdx); 196 void StopAllHaptics(); 197 198 static void EncodeStruct(nsTArray<uint64_t>& aBuffer, uint8_t* aSrcStart, 199 uint8_t* aDstStart, size_t aLength, 200 gfx::VRPuppet_Command aUpdateCommand); 201 202 private: 203 VRPuppetCommandBuffer(); 204 ~VRPuppetCommandBuffer(); 205 void Run(); 206 bool RunCommand(uint64_t aCommand, double aDeltaTime); 207 void WriteData(uint8_t aData); 208 void SimulateHaptics(double aDeltaTime); 209 void CompleteTest(bool aTimedOut); 210 nsTArray<uint64_t> mBuffer; 211 mozilla::Mutex mMutex MOZ_UNANNOTATED; 212 VRSystemState mPendingState; 213 VRSystemState mCommittedState; 214 double mHapticPulseRemaining[kVRControllerMaxCount][kNumPuppetHaptics]; 215 float mHapticPulseIntensity[kVRControllerMaxCount][kNumPuppetHaptics]; 216 217 size_t mDataOffset; 218 bool mPresentationRequested; 219 bool mFrameSubmitted; 220 bool mFrameAccepted; 221 double mTimeoutDuration; // Seconds 222 double mWaitRemaining; // Seconds 223 double mBlockedTime; // Seconds 224 double mTimerElapsed; // Seconds 225 TimeStamp mLastRunTimestamp; 226 227 // Test Results: 228 bool mEnded; 229 bool mEndedWithTimeout; 230 nsTArray<double> mTimerSamples; 231 }; 232 233 } // namespace gfx 234 } // namespace mozilla 235 236 #endif // GFX_VR_SERVICE_VRPUPPETCOMMANDBUFFER_H