diff options
Diffstat (limited to 'gfx/vr/VRPuppetCommandBuffer.h')
-rw-r--r-- | gfx/vr/VRPuppetCommandBuffer.h | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/gfx/vr/VRPuppetCommandBuffer.h b/gfx/vr/VRPuppetCommandBuffer.h new file mode 100644 index 0000000000..6acbcbe80d --- /dev/null +++ b/gfx/vr/VRPuppetCommandBuffer.h @@ -0,0 +1,236 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef GFX_VR_SERVICE_VRPUPPETCOMMANDBUFFER_H +#define GFX_VR_SERVICE_VRPUPPETCOMMANDBUFFER_H + +#include <inttypes.h> +#include "mozilla/Mutex.h" +#include "nsTArray.h" +#include "moz_external_vr.h" +#include "mozilla/TimeStamp.h" + +namespace mozilla { +namespace gfx { + +/** + * A Puppet Device command buffer consists of a stream of 64-bit + * commands. + * The first 8 bits identifies the command and informs format of + * the remaining 56 bits. + * + * These commands will be streamed into a buffer until + * VRPuppet_End (0x0000000000000000) has been received. + * + * When VRPuppet_End is received, this command buffer will + * be executed asynchronously, collecting the timer results + * requested. + * + * In addition to the effects seen through the WebXR/VR API, tests + * can get further feedback from the Puppet device. + * Command buffers can be constructed such that when expected states + * are not reached, the timeout timer will expire. + * Data recorded with timer commands is returned when the command + * buffer is completed, to validate against accepted ranges and to + * quantify performance regressions. + * Images submitted to the Puppet display are rendered with the + * 2d browser output in order to enable reftests to validate + * output against reference images. + * + * The state of the virtual puppet device is expressed to the VR service + * in the same manner as physical devices -- using the VRDisplayState, + * VRHMDSensorState and VRControllerState structures. + * + * By enabling partial updates of these structures, the command buffer + * size is reduced to the values that change each frame. This enables + * realtime capture of a session, with physical hardware, for + * replay in automated tests and benchmarks. + * + * All updates to the state structures are atomically updated in the + * VR session thread, triggered by VRPuppet_Commit (0x1500000000000000). + * + * Command buffers are expected to be serialized to a human readable, + * ascii format if stored on disk. The binary representation is not + * guaranteed to be consistent between versions or target platforms. + * They should be re-constructed with the VRServiceTest DOM api at + * runtime. + * + * The command set: + * + * 0x0000000000000000 - VRPuppet_End() + * - End of stream, resolve promise returned by VRServiceTest::Play() + * + * 0x0100000000000000 - VRPuppet_ClearAll() + * - Clear all structs + * + * 0x02000000000000nn - VRPuppet_ClearController(n) + * - Clear a single controller struct + * + * 0x03000000nnnnnnnn - VRPuppet_Timeout(n) + * - Reset the timeout timer to n milliseconds + * - Initially the timeout timer starts at 10 seconds + * + * 0x04000000nnnnnnnn - VRPuppet_Wait(n) + * - Wait n milliseconds before advancing to next command + * + * 0x0500000000000000 - VRPuppet_WaitSubmit() + * - Wait until a frame has been submitted before advancing to the next command + * + * 0x0600000000000000 - VRPuppet_WaitPresentationStart() + * - Wait until a presentation becomes active + * + * 0x0700000000000000 - VRPuppet_WaitPresentationEnd() + * - Wait until a presentation ends + * + * 0x0800cchhvvvvvvvv - VRPuppet_WaitHapticIntensity(c, h, v) + * - Wait until controller at index c's haptic actuator at index h reaches value + * v. + * - v is a 16.16 fixed point value, with 1.0f being the highest intensity and + * 0.0f indicating that the haptic actuator is not running + * + * 0x0900000000000000 - VRPuppet_CaptureFrame() + * - Captures the submitted frame. Must later call + * VRPuppet_AcknowledgeFrame or VRPuppet_RejectFrame + * to unblock + * + * 0x0900000000000000 - VRPuppet_AcknowledgeFrame() + * - Acknowledge the submitted frame, unblocking the Submit call. + * + * 0x0a00000000000000 - VRPuppet_RejectFrame() + * - Reject the submitted frame, unblocking the Submit call. + * + * 0x0b00000000000000 - VRPuppet_StartTimer() + * - Starts the timer + * + * 0x0c00000000000000 - VRPuppet_StopTimer() + * - Stops the timer, the elapsed duration is recorded for access after the end + * of stream + * + * 0x0d000000aaaaaaaa - VRPuppet_UpdateDisplay(a) + * - Start writing data to the VRDisplayState struct, at offset a + * + * 0x0e000000aaaaaaaa - VRPuppet_UpdateSensor(a) + * - Start writing data to the VRHMDSensorState struct, at offset a + * + * 0x0f000000aaaaaaaa - VRPuppet_UpdateControllers(a) + * - Start writing data to the VRControllerState array, at offset a + * + * 0x100000000000000 - VRPuppet_Commit + * - Atomically commit the VRPuppet_Data updates to VRDisplayState, + * VRHMDSensorState and VRControllerState. + * + * 0xf0000000000000dd - VRPuppet_Data(d) + * - 1 byte of data + * + * 0xf10000000000dddd - VRPuppet_Data(d) + * - 2 bytes of data + * + * 0xf200000000dddddd - VRPuppet_Data(d) + * - 3 bytes of data + * + * 0xf3000000dddddddd - VRPuppet_Data(d) + * - 4 bytes of data + * + * 0xf40000dddddddddd - VRPuppet_Data(d) + * - 5 bytes of data + * + * 0xf500dddddddddddd - VRPuppet_Data(d) + * - 6 bytes of data + * + * 0xf6dddddddddddddd - VRPuppet_Data(d) + * - 7 bytes of data + * + */ +enum class VRPuppet_Command : uint64_t { + VRPuppet_End = 0x0000000000000000, + VRPuppet_ClearAll = 0x0100000000000000, + VRPuppet_ClearController = 0x0200000000000000, + VRPuppet_Timeout = 0x0300000000000000, + VRPuppet_Wait = 0x0400000000000000, + VRPuppet_WaitSubmit = 0x0500000000000000, + VRPuppet_WaitPresentationStart = 0x0600000000000000, + VRPuppet_WaitPresentationEnd = 0x0700000000000000, + VRPuppet_WaitHapticIntensity = 0x0800000000000000, + VRPuppet_CaptureFrame = 0x0900000000000000, + VRPuppet_AcknowledgeFrame = 0x0a00000000000000, + VRPuppet_RejectFrame = 0x0b00000000000000, + VRPuppet_StartTimer = 0x0c00000000000000, + VRPuppet_StopTimer = 0x0d00000000000000, + VRPuppet_UpdateDisplay = 0x0e00000000000000, + VRPuppet_UpdateSensor = 0x0f00000000000000, + VRPuppet_UpdateControllers = 0x1000000000000000, + VRPuppet_Commit = 0x1100000000000000, + VRPuppet_Data1 = 0xf000000000000000, + VRPuppet_Data2 = 0xf100000000000000, + VRPuppet_Data3 = 0xf200000000000000, + VRPuppet_Data4 = 0xf300000000000000, + VRPuppet_Data5 = 0xf400000000000000, + VRPuppet_Data6 = 0xf500000000000000, + VRPuppet_Data7 = 0xf600000000000000, +}; + +static const int kNumPuppetHaptics = 8; + +class VRPuppetCommandBuffer { + public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(mozilla::gfx::VRPuppetCommandBuffer) + static VRPuppetCommandBuffer& Get(); + static bool IsCreated(); + + // Interface to VRTestSystem + void Submit(const nsTArray<uint64_t>& aBuffer); + void Reset(); + bool HasEnded(); + + // Interface to PuppetSession + void Run(VRSystemState& aState); + void StartPresentation(); + void StopPresentation(); + bool SubmitFrame(); + void VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex, + float aIntensity, float aDuration); + void StopVibrateHaptic(uint32_t aControllerIdx); + void StopAllHaptics(); + + static void EncodeStruct(nsTArray<uint64_t>& aBuffer, uint8_t* aSrcStart, + uint8_t* aDstStart, size_t aLength, + gfx::VRPuppet_Command aUpdateCommand); + + private: + VRPuppetCommandBuffer(); + ~VRPuppetCommandBuffer(); + void Run(); + bool RunCommand(uint64_t aCommand, double aDeltaTime); + void WriteData(uint8_t aData); + void SimulateHaptics(double aDeltaTime); + void CompleteTest(bool aTimedOut); + nsTArray<uint64_t> mBuffer; + mozilla::Mutex mMutex; + VRSystemState mPendingState; + VRSystemState mCommittedState; + double mHapticPulseRemaining[kVRControllerMaxCount][kNumPuppetHaptics]; + float mHapticPulseIntensity[kVRControllerMaxCount][kNumPuppetHaptics]; + + size_t mDataOffset; + bool mPresentationRequested; + bool mFrameSubmitted; + bool mFrameAccepted; + double mTimeoutDuration; // Seconds + double mWaitRemaining; // Seconds + double mBlockedTime; // Seconds + double mTimerElapsed; // Seconds + TimeStamp mLastRunTimestamp; + + // Test Results: + bool mEnded; + bool mEndedWithTimeout; + nsTArray<double> mTimerSamples; +}; + +} // namespace gfx +} // namespace mozilla + +#endif // GFX_VR_SERVICE_VRPUPPETCOMMANDBUFFER_H |