diff options
author | Brad Davis <[email protected]> | 2014-10-24 12:56:30 -0700 |
---|---|---|
committer | Brad Davis <[email protected]> | 2014-10-24 12:56:30 -0700 |
commit | 496894ecced1b0a4ae5ab176902bbd0f43a31ed1 (patch) | |
tree | 8b7d4be1fc8508253d399d98da6143212ceb8f3c /LibOVR/Src/Kernel | |
parent | 911239601768bacf9420ab9cfeffed7e861844ac (diff) |
Updating to 0.4.3 SDK0.4.3-official
Diffstat (limited to 'LibOVR/Src/Kernel')
53 files changed, 1373 insertions, 498 deletions
diff --git a/LibOVR/Src/Kernel/OVR_Alg.cpp b/LibOVR/Src/Kernel/OVR_Alg.cpp index 26731fc..c087777 100644 --- a/LibOVR/Src/Kernel/OVR_Alg.cpp +++ b/LibOVR/Src/Kernel/OVR_Alg.cpp @@ -5,16 +5,16 @@ Content : Static lookup tables for Alg functions Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, diff --git a/LibOVR/Src/Kernel/OVR_Alg.h b/LibOVR/Src/Kernel/OVR_Alg.h index 00264b5..f7f461f 100644 --- a/LibOVR/Src/Kernel/OVR_Alg.h +++ b/LibOVR/Src/Kernel/OVR_Alg.h @@ -6,16 +6,16 @@ Content : Simple general purpose algorithms: Sort, Binary Search, etc. Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, diff --git a/LibOVR/Src/Kernel/OVR_Allocator.cpp b/LibOVR/Src/Kernel/OVR_Allocator.cpp index 1dc3326..cb652c9 100644 --- a/LibOVR/Src/Kernel/OVR_Allocator.cpp +++ b/LibOVR/Src/Kernel/OVR_Allocator.cpp @@ -5,16 +5,16 @@ Content : Installable memory allocator implementation Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, diff --git a/LibOVR/Src/Kernel/OVR_Allocator.h b/LibOVR/Src/Kernel/OVR_Allocator.h index dfeeac5..0c12f0f 100644 --- a/LibOVR/Src/Kernel/OVR_Allocator.h +++ b/LibOVR/Src/Kernel/OVR_Allocator.h @@ -6,16 +6,16 @@ Content : Installable memory allocator Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -178,6 +178,7 @@ class Allocator { friend class System; public: + virtual ~Allocator(){} // *** Standard Alignment Alloc/Free diff --git a/LibOVR/Src/Kernel/OVR_Array.h b/LibOVR/Src/Kernel/OVR_Array.h index 6e0ad28..7855a5b 100644 --- a/LibOVR/Src/Kernel/OVR_Array.h +++ b/LibOVR/Src/Kernel/OVR_Array.h @@ -6,16 +6,16 @@ Content : Template implementation for Array Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -240,6 +240,7 @@ struct ArrayData : ArrayDataBase<T, Allocator, SizePolicy> void PushBack(const ValueType& val) { BaseType::ResizeNoConstruct(this->Size + 1); + OVR_ASSERT(this->Data != NULL); Allocator::Construct(this->Data + this->Size - 1, val); } @@ -393,31 +394,31 @@ public: // Basic access. ValueType& At(size_t index) { - OVR_ASSERT(index < Data.Size); - return Data.Data[index]; + OVR_ASSERT((Data.Data) && (index < Data.Size)); // Asserting that Data.Data is valid helps static analysis tools. + return Data.Data[index]; } const ValueType& At(size_t index) const { - OVR_ASSERT(index < Data.Size); - return Data.Data[index]; + OVR_ASSERT((Data.Data) && (index < Data.Size)); + return Data.Data[index]; } ValueType ValueAt(size_t index) const { - OVR_ASSERT(index < Data.Size); - return Data.Data[index]; + OVR_ASSERT((Data.Data) && (index < Data.Size)); + return Data.Data[index]; } // Basic access. ValueType& operator [] (size_t index) { - OVR_ASSERT(index < Data.Size); + OVR_ASSERT((Data.Data) && (index < Data.Size)); return Data.Data[index]; } const ValueType& operator [] (size_t index) const { - OVR_ASSERT(index < Data.Size); - return Data.Data[index]; + OVR_ASSERT((Data.Data) && (index < Data.Size)); + return Data.Data[index]; } // Raw pointer to the data. Use with caution! @@ -455,6 +456,7 @@ public: ValueType Pop() { + OVR_ASSERT((Data.Data) && (Data.Size > 0)); ValueType t = Back(); PopBack(); return t; @@ -473,6 +475,7 @@ public: const SelfType& operator = (const SelfType& a) { Resize(a.GetSize()); + OVR_ASSERT((Data.Data != NULL) || (Data.Size == 0)); for (size_t i = 0; i < Data.Size; i++) { *(Data.Data + i) = a[i]; } @@ -505,7 +508,7 @@ public: // RemoveAt. void RemoveAt(size_t index) { - OVR_ASSERT(index < Data.Size); + OVR_ASSERT((Data.Data) && (index < Data.Size)); if (Data.Size == 1) { Clear(); @@ -526,7 +529,7 @@ public: // is important, otherwise use it instead of regular RemoveAt(). void RemoveAtUnordered(size_t index) { - OVR_ASSERT(index < Data.Size); + OVR_ASSERT((Data.Data) && (index < Data.Size)); if (Data.Size == 1) { Clear(); diff --git a/LibOVR/Src/Kernel/OVR_Atomic.cpp b/LibOVR/Src/Kernel/OVR_Atomic.cpp index 079792e..e1796be 100644 --- a/LibOVR/Src/Kernel/OVR_Atomic.cpp +++ b/LibOVR/Src/Kernel/OVR_Atomic.cpp @@ -7,16 +7,16 @@ Content : Contains atomic operations and inline fastest locking Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -32,7 +32,7 @@ limitations under the License. #ifdef OVR_ENABLE_THREADS // Include Windows 8-Metro compatible Synchronization API -#if defined(OVR_OS_WIN32) && defined(NTDDI_WIN8) && (NTDDI_VERSION >= NTDDI_WIN8) +#if defined(OVR_OS_MS) && defined(NTDDI_WIN8) && (NTDDI_VERSION >= NTDDI_WIN8) #include <synchapi.h> #endif @@ -41,7 +41,7 @@ namespace OVR { // ***** Windows Lock implementation -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_MS) // ***** Standard Win32 Lock implementation diff --git a/LibOVR/Src/Kernel/OVR_Atomic.h b/LibOVR/Src/Kernel/OVR_Atomic.h index 47e76e0..8a3dcf8 100644 --- a/LibOVR/Src/Kernel/OVR_Atomic.h +++ b/LibOVR/Src/Kernel/OVR_Atomic.h @@ -8,16 +8,16 @@ Content : Contains atomic operations and inline fastest locking Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -33,7 +33,7 @@ limitations under the License. #include "OVR_Types.h" // Include System thread functionality. -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_MS) && !defined(OVR_OS_MS_MOBILE) #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif @@ -101,7 +101,7 @@ class Lock; struct AtomicOpsRawBase { -#if !defined(OVR_ENABLE_THREADS) || defined(OVR_CPU_X86) || defined(OVR_OS_WIN32) || defined(OVR_OS_IPHONE) +#if !defined(OVR_ENABLE_THREADS) || defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64) // Need to have empty constructor to avoid class 'unused' variable warning. struct FullSync { inline FullSync() { } }; struct AcquireSync { inline AcquireSync() { } }; @@ -117,7 +117,7 @@ struct AtomicOpsRawBase struct AcquireSync { inline AcquireSync() { } ~AcquireSync() { asm volatile("sync\n"); } }; struct ReleaseSync { inline ReleaseSync() { asm volatile("sync\n"); } }; -#elif defined(OVR_CPU_ARM) +#elif defined(OVR_CPU_ARM) // Includes Android and iOS. struct FullSync { inline FullSync() { asm volatile("dmb\n"); } ~FullSync() { asm volatile("dmb\n"); } }; struct AcquireSync { inline AcquireSync() { } ~AcquireSync() { asm volatile("dmb\n"); } }; struct ReleaseSync { inline ReleaseSync() { asm volatile("dmb\n"); } }; @@ -141,7 +141,7 @@ struct AtomicOpsRaw_4ByteImpl : public AtomicOpsRawBase // *** Thread - Safe Atomic Versions. -#elif defined(OVR_OS_WIN32) +#elif defined(OVR_OS_MS) // Use special defined for VC6, where volatile is not used and // InterlockedCompareExchange is declared incorrectly. @@ -406,7 +406,7 @@ struct AtomicOpsRaw_8ByteImpl : public AtomicOpsRawBase typedef uint64_t T; // *** Thread - Safe OS specific versions. -#elif defined(OVR_OS_WIN32) +#elif defined(OVR_OS_MS) // This is only for 64-bit systems. typedef LONG64 T; @@ -837,7 +837,7 @@ public: inline void Unlock() { } // Windows. -#elif defined(OVR_OS_WIN32) +#elif defined(OVR_OS_MS) CRITICAL_SECTION cs; public: diff --git a/LibOVR/Src/Kernel/OVR_CRC32.cpp b/LibOVR/Src/Kernel/OVR_CRC32.cpp index 07d0dc3..82cbe7f 100644 --- a/LibOVR/Src/Kernel/OVR_CRC32.cpp +++ b/LibOVR/Src/Kernel/OVR_CRC32.cpp @@ -5,16 +5,16 @@ Content : CRC-32 with polynomial used for sensor devices Created : June 20, 2014 Author : Chris Taylor -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, diff --git a/LibOVR/Src/Kernel/OVR_CRC32.h b/LibOVR/Src/Kernel/OVR_CRC32.h index 4fd31a5..e4edd65 100644 --- a/LibOVR/Src/Kernel/OVR_CRC32.h +++ b/LibOVR/Src/Kernel/OVR_CRC32.h @@ -6,16 +6,16 @@ Content : CRC-32 with polynomial used for sensor devices Created : June 20, 2014 Author : Chris Taylor -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, diff --git a/LibOVR/Src/Kernel/OVR_Color.h b/LibOVR/Src/Kernel/OVR_Color.h index 618a0b2..7b5e966 100644 --- a/LibOVR/Src/Kernel/OVR_Color.h +++ b/LibOVR/Src/Kernel/OVR_Color.h @@ -6,16 +6,16 @@ Content : Contains color struct. Created : February 7, 2013 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -36,7 +36,12 @@ struct Color { uint8_t R,G,B,A; - Color() {} + Color() + { + #if defined(OVR_BUILD_DEBUG) + R = G = B = A = 0; + #endif + } // Constructs color by channel. Alpha is set to 0xFF (fully visible) // if not specified. diff --git a/LibOVR/Src/Kernel/OVR_Compiler.h b/LibOVR/Src/Kernel/OVR_Compiler.h index dba5b19..03c2c4e 100644 --- a/LibOVR/Src/Kernel/OVR_Compiler.h +++ b/LibOVR/Src/Kernel/OVR_Compiler.h @@ -6,16 +6,16 @@ Content : Compiler-specific feature identification and utilities Created : June 19, 2014 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, diff --git a/LibOVR/Src/Kernel/OVR_ContainerAllocator.h b/LibOVR/Src/Kernel/OVR_ContainerAllocator.h index cc41d2b..46bea2e 100644 --- a/LibOVR/Src/Kernel/OVR_ContainerAllocator.h +++ b/LibOVR/Src/Kernel/OVR_ContainerAllocator.h @@ -6,16 +6,16 @@ Content : Template allocators and constructors for containers. Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, diff --git a/LibOVR/Src/Kernel/OVR_Delegates.h b/LibOVR/Src/Kernel/OVR_Delegates.h index 7d1c399..8d69540 100644 --- a/LibOVR/Src/Kernel/OVR_Delegates.h +++ b/LibOVR/Src/Kernel/OVR_Delegates.h @@ -5,16 +5,16 @@ Content : C++ Delegates Created : June 15, 2014 Authors : Chris Taylor -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -107,7 +107,7 @@ class Delegate0 } public: - OVR_FORCE_INLINE Delegate0() {} + OVR_FORCE_INLINE Delegate0() : _object(0), _stub(0){} // Function invocation @@ -223,7 +223,7 @@ class Delegate1 } public: - OVR_FORCE_INLINE Delegate1() {} + OVR_FORCE_INLINE Delegate1() : _object(0), _stub(0){} // Function invocation @@ -339,7 +339,7 @@ class Delegate2 } public: - OVR_FORCE_INLINE Delegate2() {} + OVR_FORCE_INLINE Delegate2() : _object(0), _stub(0){} // Function invocation @@ -455,7 +455,7 @@ class Delegate3 } public: - OVR_FORCE_INLINE Delegate3() {} + OVR_FORCE_INLINE Delegate3() : _object(0), _stub(0){} // Function invocation diff --git a/LibOVR/Src/Kernel/OVR_Deque.h b/LibOVR/Src/Kernel/OVR_Deque.h index 8e57091..951ed84 100644 --- a/LibOVR/Src/Kernel/OVR_Deque.h +++ b/LibOVR/Src/Kernel/OVR_Deque.h @@ -5,16 +5,16 @@ Content : Deque container Created : Nov. 15, 2013 Authors : Dov Katz -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -71,8 +71,7 @@ protected: int ElemCount; private: - Deque& operator= (const Deque& q) { }; // forbidden - Deque(const Deque<Elem, Allocator> &OtherDeque) { }; + OVR_NON_COPYABLE(Deque); }; template <class Elem, class Allocator = ContainerAllocator<Elem> > @@ -99,6 +98,7 @@ class CircularBuffer : public InPlaceMutableDeque<Elem, Allocator> public: CircularBuffer(int MaxSize = BaseType::DefaultCapacity) : BaseType(MaxSize) { }; + virtual ~CircularBuffer(){} // The following methods are inline as a workaround for a VS bug causing erroneous C4505 warnings // See: http://stackoverflow.com/questions/3051992/compiler-warning-at-c-template-base-class diff --git a/LibOVR/Src/Kernel/OVR_File.cpp b/LibOVR/Src/Kernel/OVR_File.cpp index a1e7747..c431928 100644 --- a/LibOVR/Src/Kernel/OVR_File.cpp +++ b/LibOVR/Src/Kernel/OVR_File.cpp @@ -6,16 +6,16 @@ Content : File wrapper class implementation (Win32) Created : April 5, 1999 Authors : Michael Antonov -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, diff --git a/LibOVR/Src/Kernel/OVR_File.h b/LibOVR/Src/Kernel/OVR_File.h index 60470fe..d9d3b0f 100644 --- a/LibOVR/Src/Kernel/OVR_File.h +++ b/LibOVR/Src/Kernel/OVR_File.h @@ -11,16 +11,16 @@ Notes : errno may not be preserved across use of BaseFile member functio : Directories cannot be deleted while files opened from them are in use (For the GetFullName function) -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -342,7 +342,7 @@ protected: }; // Buffer & the mode it's in - uint8_t* pBuffer; + uint8_t* pBuffer; BufferModeType BufferMode; // Position in buffer unsigned Pos; @@ -362,7 +362,8 @@ protected: // Hidden constructor BufferedFile(); - inline BufferedFile(const BufferedFile &source) : DelegatedFile() { OVR_UNUSED(source); } + BufferedFile(const BufferedFile &) : DelegatedFile(), pBuffer(NULL), BufferMode(NoBuffer), Pos(0), DataSize(0), FilePos(0) { } + public: // Constructor diff --git a/LibOVR/Src/Kernel/OVR_FileFILE.cpp b/LibOVR/Src/Kernel/OVR_FileFILE.cpp index b2a6f68..9b2123f 100644 --- a/LibOVR/Src/Kernel/OVR_FileFILE.cpp +++ b/LibOVR/Src/Kernel/OVR_FileFILE.cpp @@ -6,16 +6,16 @@ Content : File wrapper class implementation (Win32) Created : April 5, 1999 Authors : Michael Antonov -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -74,16 +74,20 @@ public: { if (pfileName && (pfileName[0]!=0) && pfileName[1]==':') { - Disabled = 1; + Disabled = TRUE; OldMode = ::SetErrorMode(SEM_FAILCRITICALERRORS); } else + { Disabled = 0; + OldMode = 0; + } } ~SysErrorModeDisabler() { - if (Disabled) ::SetErrorMode(OldMode); + if (Disabled) + ::SetErrorMode(OldMode); } }; #else @@ -129,18 +133,24 @@ protected: public: - FILEFile() + FILEFile() : + FileName(), + Opened(false), + fs(NULL), + OpenFlags(0), + ErrorCode(0), + LastOp(0) + #ifdef OVR_FILE_VERIFY_SEEK_ERRORS + ,pFileTestBuffer(NULL) + ,FileTestLength(0) + ,TestPos(0) + #endif { - Opened = 0; FileName = ""; - -#ifdef OVR_FILE_VERIFY_SEEK_ERRORS - pFileTestBuffer =0; - FileTestLength =0; - TestPos =0; -#endif } + // Initialize file by opening it FILEFile(const String& fileName, int flags, int Mode); + // The 'pfileName' should be encoded as UTF-8 to support international file names. FILEFile(const char* pfileName, int flags, int Mode); @@ -219,7 +229,7 @@ void FILEFile::init() else if (OpenFlags & Open_Write) omode = "r+b"; -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_MS) SysErrorModeDisabler disabler(FileName.ToCStr()); #endif @@ -574,7 +584,7 @@ Ptr<File> FileFILEOpen(const String& path, int flags, int mode) // Helper function: obtain file information time. bool SysFile::GetFileStat(FileStat* pfileStat, const String& path) { -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_MS) // 64-bit implementation on Windows. struct __stat64 fileStat; // Stat returns 0 for success. diff --git a/LibOVR/Src/Kernel/OVR_Hash.h b/LibOVR/Src/Kernel/OVR_Hash.h index 7522da7..3316d1e 100644 --- a/LibOVR/Src/Kernel/OVR_Hash.h +++ b/LibOVR/Src/Kernel/OVR_Hash.h @@ -6,16 +6,16 @@ Content : Template hash-table/set implementation Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -88,18 +88,19 @@ public: { const uint8_t* data = (const uint8_t*) data_in; size_t h = seed; - while (size > 0) + while (size-- > 0) { - size--; + #ifndef __clang_analyzer__ // It mistakenly thinks data is garbage. h = (h << 16) + (h << 6) - h + (size_t)data[size]; + #endif } return h; } size_t operator()(const C& data) const { - unsigned char* p = (unsigned char*) &data; - int size = sizeof(C); + const unsigned char* p = (const unsigned char*) &data; + const size_t size = sizeof(C); return SDBM_Hash(p, size); } @@ -552,7 +553,7 @@ public: // Allow non-const access to entries. C& operator*() const { - OVR_ASSERT(ConstIterator::Index >= 0 && ConstIterator::Index <= (intptr_t)ConstIterator::pHash->pTable->SizeMask); + OVR_ASSERT((ConstIterator::pHash) && ConstIterator::pHash->pTable && (ConstIterator::Index >= 0) && (ConstIterator::Index <= (intptr_t)ConstIterator::pHash->pTable->SizeMask)); return const_cast<SelfType*>(ConstIterator::pHash)->E(ConstIterator::Index).Value; } diff --git a/LibOVR/Src/Kernel/OVR_KeyCodes.h b/LibOVR/Src/Kernel/OVR_KeyCodes.h index 3b468da..8ecdc8b 100644 --- a/LibOVR/Src/Kernel/OVR_KeyCodes.h +++ b/LibOVR/Src/Kernel/OVR_KeyCodes.h @@ -5,16 +5,16 @@ Filename : OVR_KeyCodes.h Content : Common keyboard constants Created : September 19, 2012 -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, diff --git a/LibOVR/Src/Kernel/OVR_List.h b/LibOVR/Src/Kernel/OVR_List.h index 6b49f37..f9cad93 100644 --- a/LibOVR/Src/Kernel/OVR_List.h +++ b/LibOVR/Src/Kernel/OVR_List.h @@ -6,16 +6,16 @@ Content : Template implementation for doubly-connected linked List Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, diff --git a/LibOVR/Src/Kernel/OVR_Lockless.cpp b/LibOVR/Src/Kernel/OVR_Lockless.cpp index c227cec..6a5ec6b 100644 --- a/LibOVR/Src/Kernel/OVR_Lockless.cpp +++ b/LibOVR/Src/Kernel/OVR_Lockless.cpp @@ -5,16 +5,16 @@ Content : Test logic for lock-less classes Created : December 27, 2013 Authors : Michael Antonov -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, diff --git a/LibOVR/Src/Kernel/OVR_Lockless.h b/LibOVR/Src/Kernel/OVR_Lockless.h index 400b198..4d5b87e 100644 --- a/LibOVR/Src/Kernel/OVR_Lockless.h +++ b/LibOVR/Src/Kernel/OVR_Lockless.h @@ -6,16 +6,16 @@ Content : Lock-less classes for producer/consumer communication Created : November 9, 2013 Authors : John Carmack -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -92,7 +92,7 @@ public: return state; } - void SetState( T state ) + void SetState( const T& state ) { const int slot = UpdateBegin.ExchangeAdd_Sync(1) & 1; // Write to (slot ^ 1) because ExchangeAdd returns 'previous' value before add. diff --git a/LibOVR/Src/Kernel/OVR_Log.cpp b/LibOVR/Src/Kernel/OVR_Log.cpp index 7266497..627bba3 100644 --- a/LibOVR/Src/Kernel/OVR_Log.cpp +++ b/LibOVR/Src/Kernel/OVR_Log.cpp @@ -5,16 +5,16 @@ Content : Logging support Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -28,20 +28,59 @@ limitations under the License. #include "OVR_Std.h" #include <stdarg.h> #include <stdio.h> +#include <time.h> +#include "../Kernel/OVR_System.h" -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_MS) && !defined(OVR_OS_MS_MOBILE) #define WIN32_LEAN_AND_MEAN #include <windows.h> #elif defined(OVR_OS_ANDROID) #include <android/log.h> -#elif defined(OVR_OS_LINUX) || defined(OVR_OS_MAC) +#elif defined(OVR_OS_LINUX) || defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) #include <syslog.h> #endif + +class LogSubject : public OVR::SystemSingletonBase<LogSubject> +{ + static bool isShuttingDown; + +public: + + LogSubject(){ + isShuttingDown = false; + // Must be at end of function + PushDestroyCallbacks(); + } + + virtual ~LogSubject(){} // Required because we use delete this below. + + virtual void OnThreadDestroy() + { + isShuttingDown = true; + } + + virtual void OnSystemDestroy() + { + delete this; + } + + static bool IsValid() { + return isShuttingDown == false; + } + + OVR::Lock logSubjectLock; + OVR::ObserverScope<OVR::Log::LogHandler> logSubject; +}; + +bool LogSubject::isShuttingDown; + +OVR_DEFINE_SINGLETON(LogSubject); + namespace OVR { -// Global Log pointer. -Log* volatile OVR_GlobalLog = 0; + // Global Log pointer. + Log* volatile OVR_GlobalLog = 0; //----------------------------------------------------------------------------------- // ***** Log Implementation @@ -71,6 +110,49 @@ Log::~Log() OVR_GlobalLog = 0; } } +void Log::AddLogObserver(ObserverScope<LogHandler> *logObserver) +{ + if (OVR::System::IsInitialized() && LogSubject::GetInstance()->IsValid()) + { + Lock::Locker locker(&LogSubject::GetInstance()->logSubjectLock); + logObserver->GetPtr()->Observe(LogSubject::GetInstance()->logSubject); + } +} +void Log::LogMessageVargInt(LogMessageType messageType, const char* fmt, va_list argList) +{ + if (OVR::System::IsInitialized() && LogSubject::GetInstance()->IsValid()) + { + // Invoke subject + char buffer[MaxLogBufferMessageSize]; + char* pBuffer = buffer; + char* pAllocated = NULL; + + #if !defined(OVR_CC_MSVC) // Non-Microsoft compilers require you to save a copy of the va_list. + va_list argListSaved; + va_copy(argListSaved, argList); + #endif + + int result = FormatLog(pBuffer, MaxLogBufferMessageSize, Log_Text, fmt, argList); + + if(result >= MaxLogBufferMessageSize) // If there was insufficient capacity... + { + pAllocated = (char*)OVR_ALLOC(result + 1); // We assume C++ exceptions are disabled. FormatLog will handle the case that pAllocated is NULL. + pBuffer = pAllocated; + + #if !defined(OVR_CC_MSVC) + va_end(argList); // The caller owns argList and will call va_end on it. + va_copy(argList, argListSaved); + #endif + + FormatLog(pBuffer, (size_t)result + 1, Log_Text, fmt, argList); + } + + Lock::Locker locker(&LogSubject::GetInstance()->logSubjectLock); + LogSubject::GetInstance()->logSubject.GetPtr()->Call(pBuffer, messageType); + + delete[] pAllocated; + } +} void Log::LogMessageVarg(LogMessageType messageType, const char* fmt, va_list argList) { @@ -81,9 +163,32 @@ void Log::LogMessageVarg(LogMessageType messageType, const char* fmt, va_list ar return; #endif - char buffer[MaxLogBufferMessageSize]; - FormatLog(buffer, MaxLogBufferMessageSize, messageType, fmt, argList); - DefaultLogOutput(buffer, messageType); + char buffer[MaxLogBufferMessageSize]; + char* pBuffer = buffer; + char* pAllocated = NULL; + + #if !defined(OVR_CC_MSVC) // Non-Microsoft compilers require you to save a copy of the va_list. + va_list argListSaved; + va_copy(argListSaved, argList); + #endif + + int result = FormatLog(pBuffer, MaxLogBufferMessageSize, messageType, fmt, argList); + + if(result >= MaxLogBufferMessageSize) // If there was insufficient capacity... + { + pAllocated = (char*)OVR_ALLOC(result + 1); // We assume C++ exceptions are disabled. FormatLog will handle the case that pAllocated is NULL. + pBuffer = pAllocated; + + #if !defined(OVR_CC_MSVC) + va_end(argList); // The caller owns argList and will call va_end on it. + va_copy(argList, argListSaved); + #endif + + FormatLog(pBuffer, (size_t)result + 1, messageType, fmt, argList); + } + + DefaultLogOutput(pBuffer, messageType, result); + delete[] pAllocated; } void OVR::Log::LogMessage(LogMessageType messageType, const char* pfmt, ...) @@ -95,36 +200,60 @@ void OVR::Log::LogMessage(LogMessageType messageType, const char* pfmt, ...) } -void Log::FormatLog(char* buffer, unsigned bufferSize, LogMessageType messageType, +// Return behavior is the same as ISO C vsnprintf: returns the required strlen of buffer (which will +// be >= bufferSize if bufferSize is insufficient) or returns a negative value because the input was bad. +int Log::FormatLog(char* buffer, size_t bufferSize, LogMessageType messageType, const char* fmt, va_list argList) -{ - bool addNewline = true; +{ + OVR_ASSERT(buffer && (bufferSize >= 10)); // Need to be able to at least print "Assert: \n" to it. + if(!buffer || (bufferSize < 10)) + return -1; + + int addNewline = 1; + int prefixLength = 0; switch(messageType) { - case Log_Error: OVR_strcpy(buffer, bufferSize, "Error: "); break; - case Log_Debug: OVR_strcpy(buffer, bufferSize, "Debug: "); break; - case Log_Assert: OVR_strcpy(buffer, bufferSize, "Assert: "); break; - case Log_Text: buffer[0] = 0; addNewline = false; break; - case Log_DebugText: buffer[0] = 0; addNewline = false; break; - default: - buffer[0] = 0; - addNewline = false; - break; + case Log_Error: OVR_strcpy(buffer, bufferSize, "Error: "); prefixLength = 7; break; + case Log_Debug: OVR_strcpy(buffer, bufferSize, "Debug: "); prefixLength = 7; break; + case Log_Assert: OVR_strcpy(buffer, bufferSize, "Assert: "); prefixLength = 8; break; + case Log_Text: buffer[0] = 0; addNewline = 0; break; + case Log_DebugText: buffer[0] = 0; addNewline = 0; break; + default: buffer[0] = 0; addNewline = 0; break; } - size_t prefixLength = OVR_strlen(buffer); - char *buffer2 = buffer + prefixLength; - OVR_vsprintf(buffer2, bufferSize - prefixLength, fmt, argList); + char* buffer2 = buffer + prefixLength; + size_t size2 = bufferSize - (size_t)prefixLength; + int messageLength = OVR_vsnprintf(buffer2, size2, fmt, argList); if (addNewline) - OVR_strcat(buffer, bufferSize, "\n"); -} + { + if (messageLength < 0) // If there was a format error... + { + // To consider: append <format error> to the buffer here. + buffer2[0] = '\n'; // We are guaranteed to have capacity for this. + buffer2[1] = '\0'; + } + else + { + // If the printed string used all of the capacity or required more than the capacity, + // Chop the output by one character so we can append the \n safely. + int messageEnd = (messageLength >= (int)(size2 - 1)) ? (int)(size2 - 2) : messageLength; + buffer2[messageEnd + 0] = '\n'; + buffer2[messageEnd + 1] = '\0'; + } + } + if (messageLength >= 0) // If the format was OK... + return prefixLength + messageLength + addNewline; // Return the required strlen of buffer. + + return messageLength; // Else we cannot know what the required strlen is and return the error to the caller. +} -void Log::DefaultLogOutput(const char* formattedText, LogMessageType messageType) +void Log::DefaultLogOutput(const char* formattedText, LogMessageType messageType, int bufferSize) { bool debug = IsDebugMessage(messageType); + OVR_UNUSED(bufferSize); #if defined(OVR_OS_WIN32) // Under Win32, output regular messages to console if it exists; debug window otherwise. @@ -137,9 +266,14 @@ void Log::DefaultLogOutput(const char* formattedText, LogMessageType messageType ::OutputDebugStringA(formattedText); } - fputs(formattedText, stdout); + fputs(formattedText, stdout); + +#elif defined(OVR_OS_MS) // Any other Microsoft OSs + + ::OutputDebugStringA(formattedText); #elif defined(OVR_OS_ANDROID) + // To do: use bufferSize to deal with the case that Android has a limited output length. __android_log_write(ANDROID_LOG_INFO, "OVR", formattedText); #else @@ -154,6 +288,8 @@ void Log::DefaultLogOutput(const char* formattedText, LogMessageType messageType { OVR_ASSERT(false); } +#elif defined(OVR_OS_MS) // Any other Microsoft OSs + // TBD #elif defined(OVR_OS_ANDROID) // TBD #elif defined(OVR_OS_MAC) || defined(OVR_OS_LINUX) @@ -195,16 +331,37 @@ Log* Log::GetDefaultLog() //----------------------------------------------------------------------------------- // ***** Global Logging functions +#if !defined(OVR_CC_MSVC) +// The reason for va_copy is because you can't use va_start twice on Linux +#define OVR_LOG_FUNCTION_IMPL(Name) \ + void Log##Name(const char* fmt, ...) \ + { \ + if (OVR_GlobalLog) \ + { \ + va_list argList1; \ + va_start(argList1, fmt); \ + va_list argList2; \ + va_copy(argList2, argList1); \ + OVR_GlobalLog->LogMessageVargInt(Log_##Name, fmt, argList2); \ + va_end(argList2); \ + OVR_GlobalLog->LogMessageVarg(Log_##Name, fmt, argList1); \ + va_end(argList1); \ + } \ + } +#else #define OVR_LOG_FUNCTION_IMPL(Name) \ void Log##Name(const char* fmt, ...) \ { \ if (OVR_GlobalLog) \ { \ - va_list argList; va_start(argList, fmt); \ - OVR_GlobalLog->LogMessageVarg(Log_##Name, fmt, argList); \ - va_end(argList); \ + va_list argList1; \ + va_start(argList1, fmt); \ + OVR_GlobalLog->LogMessageVargInt(Log_##Name, fmt, argList1); \ + OVR_GlobalLog->LogMessageVarg(Log_##Name, fmt, argList1); \ + va_end(argList1); \ } \ } +#endif // #if !defined(OVR_OS_WIN32) OVR_LOG_FUNCTION_IMPL(Text) OVR_LOG_FUNCTION_IMPL(Error) diff --git a/LibOVR/Src/Kernel/OVR_Log.h b/LibOVR/Src/Kernel/OVR_Log.h index 7c9d65b..5982395 100644 --- a/LibOVR/Src/Kernel/OVR_Log.h +++ b/LibOVR/Src/Kernel/OVR_Log.h @@ -6,16 +6,16 @@ Content : Logging support Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -29,6 +29,8 @@ limitations under the License. #define OVR_Log_h #include "OVR_Types.h" +#include "../Kernel/OVR_Delegates.h" +#include "../Kernel//OVR_Observer.h" #include <stdarg.h> namespace OVR { @@ -92,7 +94,6 @@ enum LogMessageType # define OVR_LOG_VAARG_ATTRIBUTE(a,b) #endif - //----------------------------------------------------------------------------------- // ***** Log @@ -102,7 +103,7 @@ enum LogMessageType class Log { - friend class System; + friend class System; #ifdef OVR_OS_WIN32 void* hEventSource; @@ -112,16 +113,24 @@ public: Log(unsigned logMask = LogMask_Debug); virtual ~Log(); - // Log formating buffer size used by default LogMessageVarg. Longer strings are truncated. + typedef Delegate2<void, const char*, LogMessageType> LogHandler; + + // The following is deprecated, as there is no longer a max log buffer message size. enum { MaxLogBufferMessageSize = 4096 }; unsigned GetLoggingMask() const { return LoggingMask; } void SetLoggingMask(unsigned logMask) { LoggingMask = logMask; } + // Internal + // Invokes observers, then calls LogMessageVarg() + static void LogMessageVargInt(LogMessageType messageType, const char* fmt, va_list argList); + // This virtual function receives all the messages, // developers should override this function in order to do custom logging virtual void LogMessageVarg(LogMessageType messageType, const char* fmt, va_list argList); + static void AddLogObserver(ObserverScope<LogHandler> *logObserver); + // Call the logging function with specific message type, with no type filtering. void LogMessage(LogMessageType messageType, const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(3,4); @@ -129,14 +138,16 @@ public: // Helper used by LogMessageVarg to format the log message, writing the resulting // string into buffer. It formats text based on fmt and appends prefix/new line - // based on LogMessageType. - static void FormatLog(char* buffer, unsigned bufferSize, LogMessageType messageType, + // based on LogMessageType. Return behavior is the same as ISO C vsnprintf: returns the + // required strlen of buffer (which will be >= bufferSize if bufferSize is insufficient) + // or returns a negative value because the input was bad. + static int FormatLog(char* buffer, size_t bufferSize, LogMessageType messageType, const char* fmt, va_list argList); // Default log output implementation used by by LogMessageVarg. // Debug flag may be used to re-direct output on some platforms, but doesn't // necessarily disable it in release builds; that is the job of the called. - void DefaultLogOutput(const char* textBuffer, LogMessageType messageType); + void DefaultLogOutput(const char* textBuffer, LogMessageType messageType, int bufferSize = -1); // Determines if the specified message type is for debugging only. static bool IsDebugMessage(LogMessageType messageType) @@ -193,14 +204,21 @@ void LogError(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2); #define OVR_DEBUG_LOG(args) do { OVR::LogDebug args; } while(0) #define OVR_DEBUG_LOG_TEXT(args) do { OVR::LogDebugText args; } while(0) - #define OVR_ASSERT_LOG(c, args) do { if (!(c)) { OVR::LogAssert args; OVR_DEBUG_BREAK; } } while(0) + // Conditional logging. It logs when the condition 'c' is true. + #define OVR_DEBUG_LOG_COND(c, args) do { if ((c)) { OVR::LogDebug args; } } while(0) + #define OVR_DEBUG_LOG_TEXT_COND(c, args) do { if ((c)) { OVR::LogDebugText args; } } while(0) + + // Conditional logging & asserting. It asserts/logs when the condition 'c' is NOT true. + #define OVR_ASSERT_LOG(c, args) do { if (!(c)) { OVR::LogAssert args; OVR_DEBUG_BREAK; } } while(0) #else // If not in debug build, macros do nothing. - #define OVR_DEBUG_LOG(args) ((void)0) - #define OVR_DEBUG_LOG_TEXT(args) ((void)0) - #define OVR_ASSERT_LOG(c, args) ((void)0) + #define OVR_DEBUG_LOG(args) ((void)0) + #define OVR_DEBUG_LOG_TEXT(args) ((void)0) + #define OVR_DEBUG_LOG_COND(c, args) ((void)0) + #define OVR_DEBUG_LOG_TEXT_COND(args) ((void)0) + #define OVR_ASSERT_LOG(c, args) ((void)0) #endif diff --git a/LibOVR/Src/Kernel/OVR_Math.cpp b/LibOVR/Src/Kernel/OVR_Math.cpp index 706fb33..52977ed 100644 --- a/LibOVR/Src/Kernel/OVR_Math.cpp +++ b/LibOVR/Src/Kernel/OVR_Math.cpp @@ -5,16 +5,16 @@ Content : Implementation of 3D primitives such as vectors, matrices. Created : September 4, 2012 Authors : Andrew Reisse, Michael Antonov, Anna Yershova -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, diff --git a/LibOVR/Src/Kernel/OVR_Math.h b/LibOVR/Src/Kernel/OVR_Math.h index 82c1d03..c187cda 100644 --- a/LibOVR/Src/Kernel/OVR_Math.h +++ b/LibOVR/Src/Kernel/OVR_Math.h @@ -7,16 +7,16 @@ Created : September 4, 2012 Authors : Andrew Reisse, Michael Antonov, Steve LaValle, Anna Yershova, Max Katsev, Dov Katz -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -271,7 +271,7 @@ public: operator const CompatibleType& () const { - OVR_COMPILER_ASSERT(sizeof(Vector2<T>) == sizeof(CompatibleType)); + static_assert(sizeof(Vector2<T>) == sizeof(CompatibleType), "sizeof(Vector2<T>) failure"); return reinterpret_cast<const CompatibleType&>(*this); } @@ -424,7 +424,7 @@ public: operator const CompatibleType& () const { - OVR_COMPILER_ASSERT(sizeof(Vector3<T>) == sizeof(CompatibleType)); + static_assert(sizeof(Vector3<T>) == sizeof(CompatibleType), "sizeof(Vector3<T>) failure"); return reinterpret_cast<const CompatibleType&>(*this); } @@ -567,6 +567,10 @@ public: typedef Vector3<float> Vector3f; typedef Vector3<double> Vector3d; typedef Vector3<int32_t> Vector3i; + +static_assert((sizeof(Vector3f) == 3*sizeof(float)), "sizeof(Vector3f) failure"); +static_assert((sizeof(Vector3d) == 3*sizeof(double)), "sizeof(Vector3d) failure"); +static_assert((sizeof(Vector3i) == 3*sizeof(int32_t)), "sizeof(Vector3i) failure"); typedef Vector3<float> Point3f; typedef Vector3<double> Point3d; @@ -605,7 +609,7 @@ public: operator const CompatibleType& () const { - OVR_COMPILER_ASSERT(sizeof(Vector4<T>) == sizeof(CompatibleType)); + static_assert(sizeof(Vector4<T>) == sizeof(CompatibleType), "sizeof(Vector4<T>) failure"); return reinterpret_cast<const CompatibleType&>(*this); } @@ -789,7 +793,7 @@ public: operator const CompatibleType& () const { - OVR_COMPILER_ASSERT(sizeof(Size<T>) == sizeof(CompatibleType)); + static_assert(sizeof(Size<T>) == sizeof(CompatibleType), "sizeof(Size<T>) failure"); return reinterpret_cast<const CompatibleType&>(*this); } @@ -853,7 +857,7 @@ public: operator const CompatibleType& () const { - OVR_COMPILER_ASSERT(sizeof(Rect<T>) == sizeof(CompatibleType)); + static_assert(sizeof(Rect<T>) == sizeof(CompatibleType), "sizeof(Rect<T>) failure"); return reinterpret_cast<const CompatibleType&>(*this); } @@ -1168,7 +1172,7 @@ public: template <Axis A1, Axis A2, Axis A3, RotateDirection D, HandedSystem S> void GetEulerAngles(T *a, T *b, T *c) const { - OVR_COMPILER_ASSERT((A1 != A2) && (A2 != A3) && (A1 != A3)); + static_assert((A1 != A2) && (A2 != A3) && (A1 != A3), "(A1 != A2) && (A2 != A3) && (A1 != A3)"); T Q[3] = { x, y, z }; //Quaternion components x,y,z @@ -1228,7 +1232,7 @@ public: template <Axis A1, Axis A2, RotateDirection D, HandedSystem S> void GetEulerAnglesABA(T *a, T *b, T *c) const { - OVR_COMPILER_ASSERT(A1 != A2); + static_assert(A1 != A2, "A1 != A2"); T Q[3] = {x, y, z}; // Quaternion components @@ -1276,6 +1280,9 @@ public: typedef Quat<float> Quatf; typedef Quat<double> Quatd; +static_assert((sizeof(Quatf) == 4*sizeof(float)), "sizeof(Quatf) failure"); +static_assert((sizeof(Quatd) == 4*sizeof(double)), "sizeof(Quatd) failure"); + //------------------------------------------------------------------------------------- // ***** Pose @@ -1307,6 +1314,21 @@ public: Quat<T> Rotation; Vector3<T> Translation; + + static_assert((sizeof(T) == sizeof(double) || sizeof(T) == sizeof(float)), "(sizeof(T) == sizeof(double) || sizeof(T) == sizeof(float))"); + + void ToArray(T* arr) const + { + T temp[7] = { Rotation.x, Rotation.y, Rotation.z, Rotation.w, Translation.x, Translation.y, Translation.z }; + for (int i = 0; i < 7; i++) arr[i] = temp[i]; + } + + static Pose<T> FromArray(const T* v) + { + Quat<T> rotation(v[0], v[1], v[2], v[3]); + Vector3<T> translation(v[4], v[5], v[6]); + return Pose<T>(rotation, translation); + } Vector3<T> Rotate(const Vector3<T>& v) const { @@ -1338,6 +1360,9 @@ public: typedef Pose<float> Posef; typedef Pose<double> Posed; +static_assert((sizeof(Posed) == sizeof(Quatd) + sizeof(Vector3d)), "sizeof(Posed) failure"); +static_assert((sizeof(Posef) == sizeof(Quatf) + sizeof(Vector3f)), "sizeof(Posef) failure"); + //------------------------------------------------------------------------------------- // ***** Matrix4 @@ -1438,14 +1463,14 @@ public: // C-interop support. Matrix4(const typename CompatibleTypes<Matrix4<T> >::Type& s) { - OVR_COMPILER_ASSERT(sizeof(s) == sizeof(Matrix4)); + static_assert(sizeof(s) == sizeof(Matrix4), "sizeof(s) == sizeof(Matrix4)"); memcpy(M, s.M, sizeof(M)); } operator typename CompatibleTypes<Matrix4<T> >::Type () const { typename CompatibleTypes<Matrix4<T> >::Type result; - OVR_COMPILER_ASSERT(sizeof(result) == sizeof(Matrix4)); + static_assert(sizeof(result) == sizeof(Matrix4), "sizeof(result) == sizeof(Matrix4)"); memcpy(result.M, M, sizeof(M)); return result; } @@ -1720,7 +1745,7 @@ public: template <Axis A1, Axis A2, Axis A3, RotateDirection D, HandedSystem S> void ToEulerAngles(T *a, T *b, T *c) const { - OVR_COMPILER_ASSERT((A1 != A2) && (A2 != A3) && (A1 != A3)); + static_assert((A1 != A2) && (A2 != A3) && (A1 != A3), "(A1 != A2) && (A2 != A3) && (A1 != A3)"); T psign = -1; if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3)) // Determine whether even permutation @@ -1758,7 +1783,7 @@ public: template <Axis A1, Axis A2, RotateDirection D, HandedSystem S> void ToEulerAnglesABA(T *a, T *b, T *c) const { - OVR_COMPILER_ASSERT(A1 != A2); + static_assert(A1 != A2, "A1 != A2"); // Determine the axis that was not supplied int m = 3 - A1 - A2; @@ -2165,14 +2190,14 @@ public: // C-interop support. Matrix3(const typename CompatibleTypes<Matrix3<T> >::Type& s) { - OVR_COMPILER_ASSERT(sizeof(s) == sizeof(Matrix3)); + static_assert(sizeof(s) == sizeof(Matrix3), "sizeof(s) == sizeof(Matrix3)"); memcpy(M, s.M, sizeof(M)); } operator const typename CompatibleTypes<Matrix3<T> >::Type () const { typename CompatibleTypes<Matrix3<T> >::Type result; - OVR_COMPILER_ASSERT(sizeof(result) == sizeof(Matrix3)); + static_assert(sizeof(result) == sizeof(Matrix3), "sizeof(result) == sizeof(Matrix3)"); memcpy(result.M, M, sizeof(M)); return result; } @@ -2653,7 +2678,7 @@ public: Angle() : a(0) {} // Fix the range to be between -Pi and Pi - Angle(T a_, AngularUnits u = Radians) : a((u == Radians) ? a_ : ((T)MATH_DOUBLE_DEGREETORADFACTOR)) { FixRange(); } + Angle(T a_, AngularUnits u = Radians) : a((u == Radians) ? a_ : a_*((T)MATH_DOUBLE_DEGREETORADFACTOR)) { FixRange(); } T Get(AngularUnits u = Radians) const { return (u == Radians) ? a : a*((T)MATH_DOUBLE_RADTODEGREEFACTOR); } void Set(const T& x, AngularUnits u = Radians) { a = (u == Radians) ? x : x*((T)MATH_DOUBLE_DEGREETORADFACTOR); FixRange(); } diff --git a/LibOVR/Src/Kernel/OVR_Nullptr.h b/LibOVR/Src/Kernel/OVR_Nullptr.h index 3fd0969..5b08f3b 100644 --- a/LibOVR/Src/Kernel/OVR_Nullptr.h +++ b/LibOVR/Src/Kernel/OVR_Nullptr.h @@ -6,16 +6,16 @@ Content : Implements C++11 nullptr for the case that the compiler doesn't. Created : June 19, 2014 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, diff --git a/LibOVR/Src/Kernel/OVR_Observer.h b/LibOVR/Src/Kernel/OVR_Observer.h index 0f55551..76b4be6 100644 --- a/LibOVR/Src/Kernel/OVR_Observer.h +++ b/LibOVR/Src/Kernel/OVR_Observer.h @@ -6,16 +6,16 @@ Content : Observer pattern Created : June 20, 2014 Author : Chris Taylor -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -285,37 +285,37 @@ public: // Returns true if a call was made bool Call() { - OVR_OBSERVER_CALL_BODY(()); + OVR_OBSERVER_CALL_BODY(()) } template<class Param1> bool Call(Param1& p1) { - OVR_OBSERVER_CALL_BODY((p1)); + OVR_OBSERVER_CALL_BODY((p1)) } template<class Param1> bool Call(Param1* p1) { - OVR_OBSERVER_CALL_BODY((p1)); + OVR_OBSERVER_CALL_BODY((p1)) } template<class Param1, class Param2> bool Call(Param1& p1, Param2& p2) { - OVR_OBSERVER_CALL_BODY((p1, p2)); + OVR_OBSERVER_CALL_BODY((p1, p2)) } template<class Param1, class Param2> bool Call(Param1* p1, Param2* p2) { - OVR_OBSERVER_CALL_BODY((p1, p2)); + OVR_OBSERVER_CALL_BODY((p1, p2)) } template<class Param1, class Param2, class Param3> bool Call(Param1& p1, Param2& p2, Param3& p3) { - OVR_OBSERVER_CALL_BODY((p1, p2, p3)); + OVR_OBSERVER_CALL_BODY((p1, p2, p3)) } template<class Param1, class Param2, class Param3> bool Call(Param1* p1, Param2* p2, Param3* p3) { - OVR_OBSERVER_CALL_BODY((p1, p2, p3)); + OVR_OBSERVER_CALL_BODY((p1, p2, p3)) } #undef OVR_OBSERVER_CALL_BODY diff --git a/LibOVR/Src/Kernel/OVR_RefCount.cpp b/LibOVR/Src/Kernel/OVR_RefCount.cpp index c6301ed..f761811 100644 --- a/LibOVR/Src/Kernel/OVR_RefCount.cpp +++ b/LibOVR/Src/Kernel/OVR_RefCount.cpp @@ -5,16 +5,16 @@ Content : Reference counting implementation Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, diff --git a/LibOVR/Src/Kernel/OVR_RefCount.h b/LibOVR/Src/Kernel/OVR_RefCount.h index e6ae936..33c6f37 100644 --- a/LibOVR/Src/Kernel/OVR_RefCount.h +++ b/LibOVR/Src/Kernel/OVR_RefCount.h @@ -6,16 +6,16 @@ Content : Reference counting implementation headers Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, diff --git a/LibOVR/Src/Kernel/OVR_SharedMemory.cpp b/LibOVR/Src/Kernel/OVR_SharedMemory.cpp index edb7931..1a6ccd9 100644 --- a/LibOVR/Src/Kernel/OVR_SharedMemory.cpp +++ b/LibOVR/Src/Kernel/OVR_SharedMemory.cpp @@ -5,16 +5,16 @@ Content : Inter-process shared memory subsystem Created : June 1, 2014 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, diff --git a/LibOVR/Src/Kernel/OVR_SharedMemory.h b/LibOVR/Src/Kernel/OVR_SharedMemory.h index f0ecbe6..2cc8b04 100644 --- a/LibOVR/Src/Kernel/OVR_SharedMemory.h +++ b/LibOVR/Src/Kernel/OVR_SharedMemory.h @@ -6,16 +6,16 @@ Content : Inter-process shared memory subsystem Created : June 1, 2014 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -48,8 +48,7 @@ class SharedMemory : public RefCountBase<SharedMemory> { friend class SharedMemoryFactory; - SharedMemory(SharedMemory&) {} - void operator=(SharedMemory&) {} + OVR_NON_COPYABLE(SharedMemory); public: // Only constructed by the SharedMemory Factory diff --git a/LibOVR/Src/Kernel/OVR_Std.cpp b/LibOVR/Src/Kernel/OVR_Std.cpp index f9d1645..039f377 100644 --- a/LibOVR/Src/Kernel/OVR_Std.cpp +++ b/LibOVR/Src/Kernel/OVR_Std.cpp @@ -5,16 +5,16 @@ Content : Standard C function implementation Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -37,7 +37,7 @@ namespace OVR { // Case insensitive compare implemented in platform-specific way. int OVR_CDECL OVR_stricmp(const char* a, const char* b) { -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_MS) #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) return ::_stricmp(a, b); #else @@ -51,12 +51,12 @@ int OVR_CDECL OVR_stricmp(const char* a, const char* b) int OVR_CDECL OVR_strnicmp(const char* a, const char* b, size_t count) { -#if defined(OVR_OS_WIN32) -#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) - return ::_strnicmp(a, b, count); -#else - return ::strnicmp(a, b, count); -#endif +#if defined(OVR_OS_MS) + #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) + return ::_strnicmp(a, b, count); + #else + return ::strnicmp(a, b, count); + #endif #else return strncasecmp(a, b, count); @@ -68,7 +68,7 @@ wchar_t* OVR_CDECL OVR_wcscpy(wchar_t* dest, size_t destsize, const wchar_t* src #if defined(OVR_MSVC_SAFESTRING) wcscpy_s(dest, destsize, src); return dest; -#elif defined(OVR_OS_WIN32) +#elif defined(OVR_OS_MS) OVR_UNUSED(destsize); wcscpy(dest, src); return dest; @@ -107,7 +107,7 @@ wchar_t* OVR_CDECL OVR_wcscat(wchar_t* dest, size_t destsize, const wchar_t* src #if defined(OVR_MSVC_SAFESTRING) wcscat_s(dest, destsize, src); return dest; -#elif defined(OVR_OS_WIN32) +#elif defined(OVR_OS_MS) OVR_UNUSED(destsize); wcscat(dest, src); return dest; @@ -122,7 +122,7 @@ wchar_t* OVR_CDECL OVR_wcscat(wchar_t* dest, size_t destsize, const wchar_t* src size_t OVR_CDECL OVR_wcslen(const wchar_t* str) { -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_MS) return wcslen(str); #else size_t i = 0; @@ -134,7 +134,7 @@ size_t OVR_CDECL OVR_wcslen(const wchar_t* str) int OVR_CDECL OVR_wcscmp(const wchar_t* a, const wchar_t* b) { -#if defined(OVR_OS_WIN32) || defined(OVR_OS_LINUX) +#if defined(OVR_OS_MS) || defined(OVR_OS_LINUX) return wcscmp(a, b); #else // not supported, use custom implementation @@ -161,12 +161,12 @@ int OVR_CDECL OVR_wcscmp(const wchar_t* a, const wchar_t* b) int OVR_CDECL OVR_wcsicmp(const wchar_t* a, const wchar_t* b) { -#if defined(OVR_OS_WIN32) -#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) - return ::_wcsicmp(a, b); -#else - return ::wcsicmp(a, b); -#endif +#if defined(OVR_OS_MS) + #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) + return ::_wcsicmp(a, b); + #else + return ::wcsicmp(a, b); + #endif #elif defined(OVR_OS_MAC) || defined(__CYGWIN__) || defined(OVR_OS_ANDROID) || defined(OVR_OS_IPHONE) // not supported, use custom implementation const wchar_t *pa = a, *pb = b; @@ -193,16 +193,19 @@ int OVR_CDECL OVR_wcsicmp(const wchar_t* a, const wchar_t* b) } // This function is not inline because of dependency on <locale.h> -double OVR_CDECL OVR_strtod(const char* string, char** tailptr) +double OVR_CDECL OVR_strtod(const char* str, char** tailptr) { -#if !defined(OVR_OS_ANDROID) +#if !defined(OVR_OS_ANDROID) // The Android C library doesn't have localeconv. const char s = *localeconv()->decimal_point; - if (s != '.') + if (s != '.') // If the C library is using a locale that is not using '.' as a decimal point, we convert the input str's '.' chars to the char that the C library expects (e.g. ',' or ' '). { char buffer[347 + 1]; - OVR_strcpy(buffer, sizeof(buffer), string); + OVR_strcpy(buffer, sizeof(buffer), str); + + // Ensure null-termination of string + buffer[sizeof(buffer)-1] = '\0'; for (char* c = buffer; *c != '\0'; ++c) { @@ -213,11 +216,21 @@ double OVR_CDECL OVR_strtod(const char* string, char** tailptr) } } - return strtod(buffer, tailptr); + char *nextPtr = NULL; + double retval = strtod(buffer, &nextPtr); + + // If a tail pointer is requested, + if (tailptr) + { + // Return a tail pointer that points to the same offset as nextPtr, in the orig string + *tailptr = !nextPtr ? NULL : (char*)str + (int)(nextPtr - buffer); + } + + return retval; } #endif - return strtod(string, tailptr); + return strtod(str, tailptr); } diff --git a/LibOVR/Src/Kernel/OVR_Std.h b/LibOVR/Src/Kernel/OVR_Std.h index cc2de04..e7c298a 100644 --- a/LibOVR/Src/Kernel/OVR_Std.h +++ b/LibOVR/Src/Kernel/OVR_Std.h @@ -6,16 +6,16 @@ Content : Standard C function interface Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -35,7 +35,7 @@ limitations under the License. #include <stdlib.h> #include <ctype.h> -#if !defined(OVR_OS_WINCE) && defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) +#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) #define OVR_MSVC_SAFESTRING #include <errno.h> #endif @@ -46,7 +46,9 @@ limitations under the License. namespace OVR { -#if defined(OVR_OS_WIN32) +// Has the same behavior as itoa aside from also having a dest size argument. +// Return value: Pointer to the resulting null-terminated string, same as parameter str. +#if defined(OVR_OS_MS) inline char* OVR_CDECL OVR_itoa(int val, char *dest, size_t destsize, int radix) { #if defined(OVR_MSVC_SAFESTRING) @@ -57,8 +59,8 @@ inline char* OVR_CDECL OVR_itoa(int val, char *dest, size_t destsize, int radix) return itoa(val, dest, radix); #endif } -#else // OVR_OS_WIN32 -inline char* OVR_itoa(int val, char* dest, unsigned int len, int radix) +#else // OVR_OS_MS +inline char* OVR_itoa(int val, char* dest, size_t len, int radix) { if (val == 0) { @@ -67,12 +69,15 @@ inline char* OVR_itoa(int val, char* dest, unsigned int len, int radix) dest[0] = '0'; dest[1] = '\0'; } + else if(len > 0) + dest[0] = '\0'; return dest; } + // FIXME: Fix the following code to avoid memory write overruns when len is in sufficient. int cur = val; - unsigned int i = 0; - unsigned int sign = 0; + size_t i = 0; + size_t sign = 0; if (val < 0) { @@ -124,7 +129,7 @@ inline char* OVR_itoa(int val, char* dest, unsigned int len, int radix) dest[i++] = '-'; } - for (unsigned int j = 0; j < i / 2; ++j) + for (size_t j = 0; j < i / 2; ++j) { char tmp = dest[j]; dest[j] = dest[i - 1 - j]; @@ -151,6 +156,7 @@ inline char* OVR_CDECL OVR_strcpy(char* dest, size_t destsize, const char* src) strcpy_s(dest, destsize, src); return dest; #else + // FIXME: This should be a safer implementation OVR_UNUSED(destsize); return strcpy(dest, src); #endif @@ -162,6 +168,7 @@ inline char* OVR_CDECL OVR_strncpy(char* dest, size_t destsize, const char* src, strncpy_s(dest, destsize, src, count); return dest; #else + // FIXME: This should be a safer implementation OVR_UNUSED(destsize); return strncpy(dest, src, count); #endif @@ -173,6 +180,7 @@ inline char * OVR_CDECL OVR_strcat(char* dest, size_t destsize, const char* src) strcat_s(dest, destsize, src); return dest; #else + // FIXME: This should be a safer implementation OVR_UNUSED(destsize); return strcat(dest, src); #endif @@ -241,7 +249,7 @@ inline int OVR_CDECL OVR_strncmp(const char* ws1, const char* ws2, size_t size) inline uint64_t OVR_CDECL OVR_strtouq(const char *nptr, char **endptr, int base) { -#if defined(OVR_CC_MSVC) && !defined(OVR_OS_WINCE) +#if defined(OVR_CC_MSVC) return _strtoui64(nptr, endptr, base); #else return strtoull(nptr, endptr, base); @@ -250,7 +258,7 @@ inline uint64_t OVR_CDECL OVR_strtouq(const char *nptr, char **endptr, int base) inline int64_t OVR_CDECL OVR_strtoq(const char *nptr, char **endptr, int base) { -#if defined(OVR_CC_MSVC) && !defined(OVR_OS_WINCE) +#if defined(OVR_CC_MSVC) return _strtoi64(nptr, endptr, base); #else return strtoll(nptr, endptr, base); @@ -260,7 +268,7 @@ inline int64_t OVR_CDECL OVR_strtoq(const char *nptr, char **endptr, int base) inline int64_t OVR_CDECL OVR_atoq(const char* string) { -#if defined(OVR_CC_MSVC) && !defined(OVR_OS_WINCE) +#if defined(OVR_CC_MSVC) return _atoi64(string); #else return atoll(string); @@ -273,10 +281,14 @@ inline uint64_t OVR_CDECL OVR_atouq(const char* string) } -// Implemented in GStd.cpp in platform-specific manner. +// Implemented in OVR_Std.cpp in platform-specific manner. int OVR_CDECL OVR_stricmp(const char* dest, const char* src); int OVR_CDECL OVR_strnicmp(const char* dest, const char* src, size_t count); + +// This is like sprintf but with a destination buffer size argument. However, the behavior is different +// from vsnprintf in that the return value semantics are like sprintf (which returns -1 on capacity overflow) and +// not like snprintf (which returns intended strlen on capacity overflow). inline size_t OVR_CDECL OVR_sprintf(char *dest, size_t destsize, const char* format, ...) { va_list argList; @@ -301,6 +313,13 @@ inline size_t OVR_CDECL OVR_sprintf(char *dest, size_t destsize, const char* for return ret; } + +// This is like vsprintf but with a destination buffer size argument. However, the behavior is different +// from vsnprintf in that the return value semantics are like vsprintf (which returns -1 on capacity overflow) and +// not like vsnprintf (which returns intended strlen on capacity overflow). +// Return value: +// On success, the total number of characters written is returned. +// On failure, a negative number is returned. inline size_t OVR_CDECL OVR_vsprintf(char *dest, size_t destsize, const char * format, va_list argList) { size_t ret; @@ -323,6 +342,7 @@ inline size_t OVR_CDECL OVR_vsprintf(char *dest, size_t destsize, const char * f dest[destsize-1] = 0; #endif #else + // FIXME: This should be a safer implementation OVR_UNUSED(destsize); ret = (size_t)vsprintf(dest, format, argList); OVR_ASSERT(ret < destsize); @@ -330,14 +350,82 @@ inline size_t OVR_CDECL OVR_vsprintf(char *dest, size_t destsize, const char * f return ret; } -// Returns the number of characters in the formatted string. -inline size_t OVR_CDECL OVR_vscprintf(const char * format, va_list argList) +// Same behavior as ISO C99 vsnprintf. +// Returns the strlen of the resulting formatted string, or a negative value if the format is invalid. +// destsize specifies the capacity of the input buffer. +// +// Example usage: +// void Log(char *dest, size_t destsize, const char * format, ...) +// { +// char buffer[1024]; +// va_list argList; +// va_start(argList,format); +// int result = OVR_vsnprintf(dest, destsize, format, argList); +// assert(result < destsize); // Else we'd have to retry with a dynamically allocated buffer (of size=result+1) and new argList copy. +// va_end(argList); +// } + +inline int OVR_CDECL OVR_vsnprintf(char *dest, size_t destsize, const char * format, va_list argList) +{ + int ret; +#if defined(OVR_CC_MSVC) + OVR_DISABLE_MSVC_WARNING(4996) // 'vsnprintf': This function or variable may be unsafe. + ret = vsnprintf(dest, destsize, format, argList); // Microsoft vsnprintf is non-conforming; it returns -1 if destsize is insufficient. + if (ret < 0) // If there was a format error or if destsize was insufficient... + { + ret = _vscprintf(format, argList); // Get the expected dest strlen. If the return value is still -1 then there was a format error. + + if (destsize) // If we can 0-terminate the output... + { + if (ret < 0) + dest[0] = 0; + else + dest[destsize-1] = 0; + } + } + // Else the string was written OK and ret is its strlen. + OVR_RESTORE_MSVC_WARNING() +#else + ret = vsnprintf(dest, destsize, format, argList); +#endif + return ret; +} + + +// Same behavior as ISO C99 snprintf. +// Returns the strlen of the resulting formatted string, or a negative value if the format is invalid. +// destsize specifies the capacity of the input buffer. +// +// Example usage: +// char buffer[16]; +// int result = OVR_snprintf(buffer, sizeof(buffer), "%d", 37); +// if (result >= sizeof(buffer)) // If there was insufficient capacity... +// { +// char* p = new char[result + 1]; // Or char* p = (char*)OVR_ALLOC(result + 1); +// OVR_snprintf(p, (size_t)result, "%d", 37); +// delete[] p; +// } +// +inline int OVR_CDECL OVR_snprintf(char *dest, size_t destsize, const char * format, ...) { - size_t ret; + va_list argList; + va_start(argList,format); + int ret = OVR_vsnprintf(dest, destsize, format, argList); + va_end(argList); + return ret; +} + + +// Returns the strlen of the resulting formatted string, or a negative value if the format is invalid. +// Note: If you are planning on printing a string then it's more efficient to just use OVR_vsnprintf and +// look at the return value and handle the uncommon case that there wasn't enough space. +inline int OVR_CDECL OVR_vscprintf(const char * format, va_list argList) +{ + int ret; #if defined(OVR_CC_MSVC) - ret = (size_t) _vscprintf(format, argList); + ret = _vscprintf(format, argList); #else - ret = (size_t) vsnprintf(NULL, 0, format, argList); + ret = vsnprintf(NULL, 0, format, argList); #endif return ret; } @@ -352,12 +440,12 @@ int OVR_CDECL OVR_wcsicmp(const wchar_t* a, const wchar_t* b); inline int OVR_CDECL OVR_wcsicoll(const wchar_t* a, const wchar_t* b) { -#if defined(OVR_OS_WIN32) -#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) - return ::_wcsicoll(a, b); -#else - return ::wcsicoll(a, b); -#endif +#if defined(OVR_OS_MS) + #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) + return ::_wcsicoll(a, b); + #else + return ::wcsicoll(a, b); + #endif #else // not supported, use regular wcsicmp return OVR_wcsicmp(a, b); @@ -366,7 +454,7 @@ inline int OVR_CDECL OVR_wcsicoll(const wchar_t* a, const wchar_t* b) inline int OVR_CDECL OVR_wcscoll(const wchar_t* a, const wchar_t* b) { -#if defined(OVR_OS_WIN32) || defined(OVR_OS_LINUX) +#if defined(OVR_OS_MS) || defined(OVR_OS_LINUX) return wcscoll(a, b); #else // not supported, use regular wcscmp diff --git a/LibOVR/Src/Kernel/OVR_String.cpp b/LibOVR/Src/Kernel/OVR_String.cpp index 9262a3f..a539992 100644 --- a/LibOVR/Src/Kernel/OVR_String.cpp +++ b/LibOVR/Src/Kernel/OVR_String.cpp @@ -6,16 +6,16 @@ Content : String UTF8 string implementation with copy-on-write semantics Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -284,8 +284,10 @@ void String::operator = (const char* pstr) void String::operator = (const wchar_t* pwstr) { + pwstr = pwstr ? pwstr : L""; + DataDesc* poldData = GetData(); - size_t size = pwstr ? (size_t)UTF8Util::GetEncodeStringSize(pwstr) : 0; + size_t size = (size_t)UTF8Util::GetEncodeStringSize(pwstr); DataDesc* pnewData = AllocData(size, 0); UTF8Util::EncodeString(pnewData->Data, pwstr); @@ -673,13 +675,14 @@ void StringBuffer::AppendChar(uint32_t ch) size_t size = origSize + srcSize; Resize(size); + OVR_ASSERT(pData != NULL); memcpy(pData + origSize, buff, srcSize); } // Append a string void StringBuffer::AppendString(const wchar_t* pstr, intptr_t len) { - if (!pstr) + if (!pstr || !len) return; intptr_t srcSize = UTF8Util::GetEncodeStringSize(pstr, len); @@ -687,6 +690,7 @@ void StringBuffer::AppendString(const wchar_t* pstr, intptr_t len) size_t size = srcSize + origSize; Resize(size); + OVR_ASSERT(pData != NULL); UTF8Util::EncodeString(pData + origSize, pstr, len); } @@ -701,30 +705,36 @@ void StringBuffer::AppendString(const char* putf8str, intptr_t utf8StrSz) size_t size = utf8StrSz + origSize; Resize(size); + OVR_ASSERT(pData != NULL); memcpy(pData + origSize, putf8str, utf8StrSz); } - +// If pstr is NULL then the StringBuffer is cleared. void StringBuffer::operator = (const char* pstr) { pstr = pstr ? pstr : ""; size_t size = OVR_strlen(pstr); Resize(size); + OVR_ASSERT((pData != NULL) || (size == 0)); memcpy(pData, pstr, size); } +// If pstr is NULL then the StringBuffer is cleared. void StringBuffer::operator = (const wchar_t* pstr) { pstr = pstr ? pstr : L""; size_t size = (size_t)UTF8Util::GetEncodeStringSize(pstr); Resize(size); + OVR_ASSERT((pData != NULL) || (size == 0)); UTF8Util::EncodeString(pData, pstr); } void StringBuffer::operator = (const String& src) { - Resize(src.GetSize()); - memcpy(pData, src.ToCStr(), src.GetSize()); + const size_t size = src.GetSize(); + Resize(size); + OVR_ASSERT((pData != NULL) || (size == 0)); + memcpy(pData, src.ToCStr(), size); } void StringBuffer::operator = (const StringBuffer& src) @@ -745,6 +755,7 @@ void StringBuffer::Insert(const char* substr, size_t posAt, intptr_t len) OVR_ASSERT(byteIndex <= oldSize); Reserve(oldSize + insertSize); + OVR_ASSERT(pData != NULL); // pData is unilaterally written to below. memmove(pData + byteIndex + insertSize, pData + byteIndex, oldSize - byteIndex + 1); memcpy (pData + byteIndex, substr, insertSize); LengthIsSize = false; diff --git a/LibOVR/Src/Kernel/OVR_String.h b/LibOVR/Src/Kernel/OVR_String.h index 850118a..ecef940 100644 --- a/LibOVR/Src/Kernel/OVR_String.h +++ b/LibOVR/Src/Kernel/OVR_String.h @@ -7,16 +7,16 @@ Content : String UTF8 string implementation with copy-on-write semantics Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, diff --git a/LibOVR/Src/Kernel/OVR_StringHash.h b/LibOVR/Src/Kernel/OVR_StringHash.h index baa80a7..410a578 100644 --- a/LibOVR/Src/Kernel/OVR_StringHash.h +++ b/LibOVR/Src/Kernel/OVR_StringHash.h @@ -7,16 +7,16 @@ Content : String hash table used when optional case-insensitive Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, diff --git a/LibOVR/Src/Kernel/OVR_String_FormatUtil.cpp b/LibOVR/Src/Kernel/OVR_String_FormatUtil.cpp index a47ca4e..d52b6bb 100644 --- a/LibOVR/Src/Kernel/OVR_String_FormatUtil.cpp +++ b/LibOVR/Src/Kernel/OVR_String_FormatUtil.cpp @@ -5,16 +5,16 @@ Content : String format functions. Created : February 27, 2013 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -32,22 +32,45 @@ namespace OVR { void StringBuffer::AppendFormat(const char* format, ...) { va_list argList; + char buffer[512]; + char* bufferUsed = buffer; + char* bufferAllocated = NULL; va_start(argList, format); - size_t size = OVR_vscprintf(format, argList); - va_end(argList); - char* buffer = (char*) OVR_ALLOC(sizeof(char) * (size+1)); + #if !defined(OVR_CC_MSVC) // Non-Microsoft compilers require you to save a copy of the va_list. + va_list argListSaved; + va_copy(argListSaved, argList); + #endif + + int requiredStrlen = OVR_vsnprintf(bufferUsed, OVR_ARRAY_COUNT(buffer), format, argList); // The large majority of the time this will succeed. + + if(requiredStrlen >= (int)sizeof(buffer)) // If the initial capacity wasn't enough... + { + bufferAllocated = (char*)OVR_ALLOC(sizeof(char) * (requiredStrlen + 1)); + bufferUsed = bufferAllocated; + if(bufferAllocated) + { + #if !defined(OVR_CC_MSVC) + va_end(argList); + va_copy(argList, argListSaved); + #endif + requiredStrlen = OVR_vsnprintf(bufferAllocated, (requiredStrlen + 1), format, argList); + } + } + + if(requiredStrlen < 0) // If there was a printf format error... + { + bufferUsed = NULL; + } - va_start(argList, format); - size_t result = OVR_vsprintf(buffer, size+1, format, argList); - OVR_UNUSED1(result); va_end(argList); - OVR_ASSERT_LOG(result == size, ("Error in OVR_vsprintf")); - AppendString(buffer); + if(bufferUsed) + AppendString(bufferUsed); - OVR_FREE(buffer); + if(bufferAllocated) + OVR_FREE(bufferAllocated); } } // OVR diff --git a/LibOVR/Src/Kernel/OVR_String_PathUtil.cpp b/LibOVR/Src/Kernel/OVR_String_PathUtil.cpp index c954083..95f3de9 100644 --- a/LibOVR/Src/Kernel/OVR_String_PathUtil.cpp +++ b/LibOVR/Src/Kernel/OVR_String_PathUtil.cpp @@ -5,16 +5,16 @@ Content : String filename/url helper function Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, diff --git a/LibOVR/Src/Kernel/OVR_SysFile.cpp b/LibOVR/Src/Kernel/OVR_SysFile.cpp index d08dbb2..6ef27c7 100644 --- a/LibOVR/Src/Kernel/OVR_SysFile.cpp +++ b/LibOVR/Src/Kernel/OVR_SysFile.cpp @@ -6,16 +6,16 @@ Content : File wrapper class implementation (Win32) Created : April 5, 1999 Authors : Michael Antonov -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -59,16 +59,16 @@ public: virtual int GetErrorCode() { return Error_FileNotFound; } // ** Stream implementation & I/O - virtual int Write(const uint8_t *pbuffer, int numBytes) { return -1; OVR_UNUSED2(pbuffer, numBytes); } - virtual int Read(uint8_t *pbuffer, int numBytes) { return -1; OVR_UNUSED2(pbuffer, numBytes); } - virtual int SkipBytes(int numBytes) { return 0; OVR_UNUSED(numBytes); } - virtual int BytesAvailable() { return 0; } - virtual bool Flush() { return 0; } - virtual int Seek(int offset, int origin) { return -1; OVR_UNUSED2(offset, origin); } - virtual int64_t LSeek(int64_t offset, int origin) { return -1; OVR_UNUSED2(offset, origin); } + virtual int Write(const uint8_t * /*pbuffer*/, int /*numBytes*/) { return -1; } + virtual int Read(uint8_t * /*pbuffer*/, int /*numBytes*/) { return -1; } + virtual int SkipBytes(int /*numBytes*/) { return 0; } + virtual int BytesAvailable() { return 0; } + virtual bool Flush() { return 0; } + virtual int Seek(int /*offset*/, int /*origin*/) { return -1; } + virtual int64_t LSeek(int64_t /*offset*/, int /*origin*/) { return -1; } - virtual int CopyFromStream(File *pstream, int byteSize) { return -1; OVR_UNUSED2(pstream, byteSize); } - virtual bool Close() { return 0; } + virtual int CopyFromStream(File * /*pstream*/, int /*byteSize*/) { return -1; } + virtual bool Close() { return 0; } }; diff --git a/LibOVR/Src/Kernel/OVR_SysFile.h b/LibOVR/Src/Kernel/OVR_SysFile.h index 7bd0162..925c51d 100644 --- a/LibOVR/Src/Kernel/OVR_SysFile.h +++ b/LibOVR/Src/Kernel/OVR_SysFile.h @@ -11,16 +11,16 @@ Notes : errno may not be preserved across use of GBaseFile member functi : Directories cannot be deleted while files opened from them are in use (For the GetFullName function) -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, diff --git a/LibOVR/Src/Kernel/OVR_System.cpp b/LibOVR/Src/Kernel/OVR_System.cpp index 1b8d801..59cc9bc 100644 --- a/LibOVR/Src/Kernel/OVR_System.cpp +++ b/LibOVR/Src/Kernel/OVR_System.cpp @@ -6,16 +6,16 @@ Content : General kernel initialization/cleanup, including that Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -35,7 +35,9 @@ limitations under the License. namespace OVR { +#ifdef OVR_OS_WIN32 extern bool anyRiftsInExtendedMode(); +#endif // Stack of destroy listeners (push/pop semantics) static SystemSingletonInternal *SystemShutdownListenerStack = 0; diff --git a/LibOVR/Src/Kernel/OVR_System.h b/LibOVR/Src/Kernel/OVR_System.h index 66ecfe9..daaafb4 100644 --- a/LibOVR/Src/Kernel/OVR_System.h +++ b/LibOVR/Src/Kernel/OVR_System.h @@ -7,16 +7,16 @@ Content : General kernel initialization/cleanup, including that Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -50,8 +50,7 @@ class SystemSingletonInternal SystemSingletonInternal* NextSingleton; // No copying allowed - SystemSingletonInternal(const SystemSingletonInternal&) {} - void operator=(const SystemSingletonInternal&) {} + OVR_NON_COPYABLE(SystemSingletonInternal); protected: SystemSingletonInternal() : @@ -59,6 +58,8 @@ protected: { } + virtual ~SystemSingletonInternal(){} + // Call this to register the destroy events // Destroy callbacks will be called in the reverse order they were registered // Note: As a rule of thumb, call this at the end of the singleton class constructor. diff --git a/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.cpp b/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.cpp index 56b68ff..90ba3cc 100644 --- a/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.cpp +++ b/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.cpp @@ -5,16 +5,16 @@ Filename : OVR_ThreadCommandQueue.cpp Content : Command queue for operations executed on a thread Created : October 29, 2012 -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, diff --git a/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.h b/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.h index 31b836f..9c2a7d3 100644 --- a/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.h +++ b/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.h @@ -6,16 +6,16 @@ Content : Command queue for operations executed on a thread Created : October 29, 2012 Author : Michael Antonov -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, diff --git a/LibOVR/Src/Kernel/OVR_Threads.h b/LibOVR/Src/Kernel/OVR_Threads.h index 301b84f..1157325 100644 --- a/LibOVR/Src/Kernel/OVR_Threads.h +++ b/LibOVR/Src/Kernel/OVR_Threads.h @@ -6,16 +6,16 @@ Content : Contains thread-related (safe) functionality Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -325,19 +325,35 @@ public: // and set to the return value if Run function after the thread is finished. inline int GetExitCode() const { return ExitCode; } // Returns an OS handle -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_MS) void* GetOSHandle() const { return ThreadHandle; } #else pthread_t GetOSHandle() const { return ThreadHandle; } #endif -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_MS) ThreadId GetThreadId() const { return IdValue; } #else ThreadId GetThreadId() const { return (ThreadId)GetOSHandle(); } #endif - static int GetOSPriority(ThreadPriority); + // Returns the platform-specific equivalent const that corresponds to the given ThreadPriority. + static int GetOSPriority(ThreadPriority); + static ThreadPriority GetOVRPriority(int osPriority); // May return a value outside the ThreadPriority enum range in unusual cases. + + // Gets this instance's priority. + ThreadPriority GetPriority(); + + // Gets the current thread's priority. + static ThreadPriority GetCurrentPriority(); + + // Sets this instance's thread's priority. + // Some platforms (e.g. Unix) don't let you set thread priorities unless you have root privileges/ + bool SetPriority(ThreadPriority); + + // Sets the current thread's priority. + static bool SetCurrentPriority(ThreadPriority); + // *** Sleep // Sleep secs seconds @@ -352,6 +368,8 @@ public: private: #if defined(OVR_OS_WIN32) friend unsigned WINAPI Thread_Win32StartFn(void *phandle); +#elif defined(OVR_OS_MS) // Any other Microsoft OS... + friend DWORD WINAPI Thread_Win32StartFn(void *phandle); #else friend void *Thread_PthreadStartFn(void * phandle); @@ -369,7 +387,7 @@ protected: int Processor; ThreadPriority Priority; -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_MS) void* ThreadHandle; volatile ThreadId IdValue; diff --git a/LibOVR/Src/Kernel/OVR_ThreadsPthread.cpp b/LibOVR/Src/Kernel/OVR_ThreadsPthread.cpp index f375ddd..149f202 100644 --- a/LibOVR/Src/Kernel/OVR_ThreadsPthread.cpp +++ b/LibOVR/Src/Kernel/OVR_ThreadsPthread.cpp @@ -5,16 +5,16 @@ Content : Created : Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -33,11 +33,21 @@ limitations under the License. #include "OVR_Log.h" #include <pthread.h> +#include <sched.h> #include <time.h> #include <unistd.h> #include <sys/time.h> #include <errno.h> +#if defined(OVR_OS_MAC) || defined(OVR_OS_BSD) + #include <sys/sysctl.h> + #include <sys/param.h> + #if !defined(OVR_OS_MAC) + #include <pthread_np.h> + #endif +#endif + + namespace OVR { @@ -704,12 +714,88 @@ pthread_attr_t Thread::Attr; /* static */ int Thread::GetOSPriority(ThreadPriority p) -//static inline int MapToSystemPrority(Thread::ThreadPriority p) { OVR_UNUSED(p); return -1; } +/* static */ +Thread::ThreadPriority Thread::GetOVRPriority(int osPriority) +{ + #if defined(OVR_OS_LINUX) + return (ThreadPriority)(Thread::NormalPriority - osPriority); // This works for both SCHED_OTHER, SCHED_RR, and SCHED_FIFO. + #else + // Apple priorities are such that the min is a value less than the max. + static int minPriority = sched_get_priority_min(SCHED_FIFO); // We don't have a means to pass a policy type to this function. + static int maxPriority = sched_get_priority_max(SCHED_FIFO); + + return (ThreadPriority)(Thread::NormalPriority - (osPriority - ((minPriority + maxPriority) / 2))); + #endif +} + + +Thread::ThreadPriority Thread::GetPriority() +{ + int policy; + sched_param param; + + int result = pthread_getschedparam(ThreadHandle, &policy, ¶m); + + if(result == 0) + { + #if !defined(OVR_OS_LINUX) + if(policy == SCHED_OTHER) + { + return Thread::NormalPriority; //SCHED_OTHER allows only normal priority on BSD-style Unix and Mac OS X. + } + #endif + + return GetOVRPriority(param.sched_priority); + } + + return Thread::NormalPriority; +} + +/* static */ +Thread::ThreadPriority Thread::GetCurrentPriority() +{ + int policy; + sched_param param; + pthread_t currentThreadId = pthread_self(); + + int result = pthread_getschedparam(currentThreadId, &policy, ¶m); + + if(result == 0) + { + #if !defined(OVR_OS_LINUX) + if(policy == SCHED_OTHER) + { + return Thread::NormalPriority; //SCHED_OTHER allows only normal priority on BSD-style Unix and Mac OS X. + } + #endif + + return GetOVRPriority(param.sched_priority); + } + + return Thread::NormalPriority; +} + + +bool Thread::SetPriority(ThreadPriority) +{ + // We currently fail. To do: add code to support this via pthread_getschedparam/pthread_attr_setschedparam + // This won't work unless using SCHED_FIFO or SCHED_RR anyway, which require root privileges. + return false; +} + +/* static */ +bool Thread::SetCurrentPriority(ThreadPriority) +{ + // We currently fail. To do: add code to support this via pthread_getschedparam/pthread_attr_setschedparam + // This won't work unless using SCHED_FIFO or SCHED_RR anyway, which require root privileges. + return false; +} + bool Thread::Start(ThreadState initialState) { if (initialState == NotRunning) @@ -821,7 +907,25 @@ bool Thread::MSleep(unsigned msecs) /* static */ int Thread::GetCPUCount() { - return 1; + #if defined(OVR_OS_MAC) || defined(OVR_OS_BSD) + // http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man3/sysctlbyname.3.html + int cpuCount = 0; + size_t len = sizeof(cpuCount); + + if(sysctlbyname("hw.logicalcpu", &cpuCount, &len, NULL, 0) != 0) + cpuCount = 1; + + return cpuCount; + + #else // Linux, Android + + // Alternative: read /proc/cpuinfo + #ifdef _SC_NPROCESSORS_ONLN + return (int)sysconf(_SC_NPROCESSORS_ONLN); + #else + return 1; + #endif + #endif } diff --git a/LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp b/LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp index c1a368a..bdca233 100644 --- a/LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp +++ b/LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp @@ -6,16 +6,16 @@ Content : Windows specific thread-related (safe) functionality Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -68,7 +68,12 @@ MutexImpl::MutexImpl(bool recursive) { Recursive = recursive; LockCount = 0; +#if defined(OVR_OS_WIN32) // Older versions of Windows don't support CreateSemaphoreEx, so stick with CreateSemaphore for portability. hMutexOrSemaphore = Recursive ? CreateMutex(NULL, 0, NULL) : CreateSemaphore(NULL, 1, 1, NULL); +#else + // No CreateSemaphore() call, so emulate it. + hMutexOrSemaphore = Recursive ? CreateMutex(NULL, 0, NULL) : CreateSemaphoreEx(NULL, 1, 1, NULL, 0, SEMAPHORE_ALL_ACCESS); +#endif } MutexImpl::~MutexImpl() { @@ -827,19 +832,79 @@ int Thread::GetOSPriority(ThreadPriority p) { switch(p) { - case Thread::CriticalPriority: return THREAD_PRIORITY_TIME_CRITICAL; - case Thread::HighestPriority: return THREAD_PRIORITY_HIGHEST; - case Thread::AboveNormalPriority: return THREAD_PRIORITY_ABOVE_NORMAL; - case Thread::NormalPriority: return THREAD_PRIORITY_NORMAL; - case Thread::BelowNormalPriority: return THREAD_PRIORITY_BELOW_NORMAL; - case Thread::LowestPriority: return THREAD_PRIORITY_LOWEST; - case Thread::IdlePriority: return THREAD_PRIORITY_IDLE; + // If the process is REALTIME_PRIORITY_CLASS then it could have priority values 3 through14 and -3 through -14. + case Thread::CriticalPriority: return THREAD_PRIORITY_TIME_CRITICAL; // 15 + case Thread::HighestPriority: return THREAD_PRIORITY_HIGHEST; // 2 + case Thread::AboveNormalPriority: return THREAD_PRIORITY_ABOVE_NORMAL; // 1 + case Thread::NormalPriority: return THREAD_PRIORITY_NORMAL; // 0 + case Thread::BelowNormalPriority: return THREAD_PRIORITY_BELOW_NORMAL; // -1 + case Thread::LowestPriority: return THREAD_PRIORITY_LOWEST; // -2 + case Thread::IdlePriority: return THREAD_PRIORITY_IDLE; // -15 } return THREAD_PRIORITY_NORMAL; } +/* static */ +Thread::ThreadPriority Thread::GetOVRPriority(int osPriority) +{ + // If the process is REALTIME_PRIORITY_CLASS then it could have priority values 3 through14 and -3 through -14. + // As a result, it's possible for those cases that an unknown/invalid ThreadPriority enum be returned. However, + // in practice we don't expect to be using such processes. + + // The ThreadPriority types aren't linearly distributed, so we need to check for some values explicitly. + if(osPriority == THREAD_PRIORITY_TIME_CRITICAL) + return Thread::CriticalPriority; + if(osPriority == THREAD_PRIORITY_IDLE) + return Thread::IdlePriority; + return (ThreadPriority)(Thread::NormalPriority - osPriority); +} + +Thread::ThreadPriority Thread::GetPriority() +{ + int osPriority = ::GetThreadPriority(ThreadHandle); + + if(osPriority != THREAD_PRIORITY_ERROR_RETURN) + { + return GetOVRPriority(osPriority); + } + + return NormalPriority; +} + +/* static */ +Thread::ThreadPriority Thread::GetCurrentPriority() +{ + int osPriority = ::GetThreadPriority(::GetCurrentThread()); + + if(osPriority != THREAD_PRIORITY_ERROR_RETURN) + { + return GetOVRPriority(osPriority); + } + + return NormalPriority; +} + +bool Thread::SetPriority(ThreadPriority p) +{ + BOOL ret = ::SetThreadPriority(ThreadHandle, Thread::GetOSPriority(p)); + return (ret != FALSE); +} + +/* static */ +bool Thread::SetCurrentPriority(ThreadPriority p) +{ + BOOL ret = ::SetThreadPriority(::GetCurrentThread(), Thread::GetOSPriority(p)); + return (ret != FALSE); +} + + + // The actual first function called on thread start +#if defined(OVR_OS_WIN32) unsigned WINAPI Thread_Win32StartFn(void * phandle) +#else // Other Micorosft OSs... +DWORD WINAPI Thread_Win32StartFn(void *phandle) +#endif { Thread * pthread = (Thread*)phandle; if (pthread->Processor != -1) @@ -886,8 +951,15 @@ bool Thread::Start(ThreadState initialState) ExitCode = 0; SuspendCount = 0; ThreadFlags = (initialState == Running) ? 0 : OVR_THREAD_START_SUSPENDED; +#if defined(OVR_OS_WIN32) ThreadHandle = (HANDLE) _beginthreadex(0, (unsigned)StackSize, Thread_Win32StartFn, this, 0, (unsigned*)&IdValue); +#else // Other Micorosft OSs... + DWORD TheThreadId; + ThreadHandle = CreateThread(0, (unsigned)StackSize, + Thread_Win32StartFn, this, 0, &TheThreadId); + IdValue = (ThreadId)TheThreadId; +#endif // Failed? Fail the function if (ThreadHandle == 0) @@ -959,7 +1031,11 @@ void Thread::Exit(int exitCode) ThreadList::RemoveRunningThread(this); // Call the exit function. +#if defined(OVR_OS_WIN32) // _endthreadex doesn't exist on other Microsoft OSs and instead we need to call ExitThread directly. _endthreadex((unsigned)exitCode); +#else + ExitThread((unsigned)exitCode); +#endif } @@ -990,13 +1066,15 @@ bool Thread::MSleep(unsigned msecs) void Thread::SetThreadName( const char* name ) { #if !defined(OVR_BUILD_SHIPPING) || defined(OVR_BUILD_PROFILING) - // Looks ugly, but it is the recommended way to name a thread. - typedef struct tagTHREADNAME_INFO { + // http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx + #pragma pack(push,8) + struct THREADNAME_INFO { DWORD dwType; // Must be 0x1000 LPCSTR szName; // Pointer to name (in user address space) DWORD dwThreadID; // Thread ID (-1 for caller thread) DWORD dwFlags; // Reserved for future use; must be zero - } THREADNAME_INFO; + }; + #pragma pack(pop) THREADNAME_INFO info; @@ -1007,11 +1085,7 @@ void Thread::SetThreadName( const char* name ) __try { -#ifdef _WIN64 - RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD), (const ULONG_PTR *)&info ); -#else - RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD), (DWORD *)&info ); -#endif + RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(ULONG_PTR), reinterpret_cast<ULONG_PTR *>(&info)); } __except( GetExceptionCode()==0x406D1388 ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER ) { @@ -1024,7 +1098,13 @@ void Thread::SetThreadName( const char* name ) int Thread::GetCPUCount() { SYSTEM_INFO sysInfo; - GetSystemInfo(&sysInfo); + + #if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) // GetNativeSystemInfo requires WinXP+ and a corresponding SDK (0x0501) or later. + GetNativeSystemInfo(&sysInfo); + #else + GetSystemInfo(&sysInfo); + #endif + return (int) sysInfo.dwNumberOfProcessors; } diff --git a/LibOVR/Src/Kernel/OVR_Timer.cpp b/LibOVR/Src/Kernel/OVR_Timer.cpp index 50f4c1f..3a75ec2 100644 --- a/LibOVR/Src/Kernel/OVR_Timer.cpp +++ b/LibOVR/Src/Kernel/OVR_Timer.cpp @@ -5,16 +5,16 @@ Content : Provides static functions for precise timing Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -27,26 +27,63 @@ limitations under the License. #include "OVR_Timer.h" #include "OVR_Log.h" -#if defined (OVR_OS_WIN32) +#if defined(OVR_OS_MS) && !defined(OVR_OS_MS_MOBILE) #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <MMSystem.h> #elif defined(OVR_OS_ANDROID) #include <time.h> #include <android/log.h> - +#elif defined(OVR_OS_MAC) +#include <mach/mach_time.h> #else +#include <time.h> #include <sys/time.h> +#include <errno.h> +#endif + + +#if defined(OVR_BUILD_DEBUG) && defined(OVR_OS_WIN32) + #ifndef NTSTATUS + #define NTSTATUS DWORD + #endif + + typedef NTSTATUS (NTAPI* NtQueryTimerResolutionType)(PULONG MaximumTime, PULONG MinimumTime, PULONG CurrentTime); + NtQueryTimerResolutionType pNtQueryTimerResolution; +#endif + + + +#if defined(OVR_OS_MS) && !defined(OVR_OS_WIN32) // Non-desktop Microsoft platforms... + +// Add this alias here because we're not going to include OVR_CAPI.cpp +extern "C" { + double ovr_GetTimeInSeconds() + { + return Timer::GetSeconds(); + } +} + #endif + + + namespace OVR { // For recorded data playback -bool Timer::useFakeSeconds = false; -double Timer::FakeSeconds = 0; +bool Timer::useFakeSeconds = false; +double Timer::FakeSeconds = 0; + + //------------------------------------------------------------------------ +// *** Android Specific Timer + +#if defined(OVR_OS_ANDROID) // To consider: This implementation can also work on most Linux distributions + +//------------------------------------------------------------------------ // *** Timer - Platform Independent functions // Returns global high-resolution application timer in seconds. @@ -55,28 +92,23 @@ double Timer::GetSeconds() if(useFakeSeconds) return FakeSeconds; - return double(Timer::GetTicksNanos()) * 0.000000001; -} - - -#if !defined(OVR_OS_WIN32) - -// Unused on OSs other then Win32. -void Timer::initializeTimerSystem() -{ -} -void Timer::shutdownTimerSystem() -{ -} + // Choreographer vsync timestamp is based on. + struct timespec tp; + const int status = clock_gettime(CLOCK_MONOTONIC, &tp); +#ifdef OVR_BUILD_DEBUG + if (status != 0) + { + OVR_DEBUG_LOG(("clock_gettime status=%i", status )); + } +#else + OVR_UNUSED(status); #endif + return (double)tp.tv_sec; +} -//------------------------------------------------------------------------ -// *** Android Specific Timer - -#if defined(OVR_OS_ANDROID) uint64_t Timer::GetTicksNanos() { @@ -87,19 +119,38 @@ uint64_t Timer::GetTicksNanos() struct timespec tp; const int status = clock_gettime(CLOCK_MONOTONIC, &tp); +#ifdef OVR_BUILD_DEBUG if (status != 0) { OVR_DEBUG_LOG(("clock_gettime status=%i", status )); } +#else + OVR_UNUSED(status); +#endif + const uint64_t result = (uint64_t)tp.tv_sec * (uint64_t)(1000 * 1000 * 1000) + uint64_t(tp.tv_nsec); return result; } +void Timer::initializeTimerSystem() +{ + // Empty for this platform. +} + +void Timer::shutdownTimerSystem() +{ + // Empty for this platform. +} + + + + + //------------------------------------------------------------------------ // *** Win32 Specific Timer -#elif defined (OVR_OS_WIN32) +#elif defined (OVR_OS_MS) // This helper class implements high-resolution wrapper that combines timeGetTime() output @@ -108,8 +159,15 @@ uint64_t Timer::GetTicksNanos() struct PerformanceTimer { PerformanceTimer() - : OldMMTimeMs(0), MMTimeWrapCounter(0), PrefFrequency(0), - LastResultNanos(0), PerfMinusTicksDeltaNanos(0) + : UsingVistaOrLater(false), + TimeCS(), + OldMMTimeMs(0), + MMTimeWrapCounter(0), + PerfFrequency(0), + PerfFrequencyInverse(0), + PerfFrequencyInverseNanos(0), + PerfMinusTicksDeltaNanos(0), + LastResultNanos(0) { } enum { @@ -119,28 +177,39 @@ struct PerformanceTimer void Initialize(); void Shutdown(); + uint64_t GetTimeSeconds(); + double GetTimeSecondsDouble(); uint64_t GetTimeNanos(); - UINT64 getFrequency() { - if (PrefFrequency == 0) + if (PerfFrequency == 0) { LARGE_INTEGER freq; QueryPerformanceFrequency(&freq); - PrefFrequency = freq.QuadPart; + PerfFrequency = freq.QuadPart; + PerfFrequencyInverse = 1.0 / (double)PerfFrequency; + PerfFrequencyInverseNanos = 1000000000.0 / (double)PerfFrequency; } - return PrefFrequency; + return PerfFrequency; } - bool UsingVista; + double GetFrequencyInverse() + { + OVR_ASSERT(PerfFrequencyInverse != 0.0); // Assert that the frequency has been initialized. + return PerfFrequencyInverse; + } + + bool UsingVistaOrLater; CRITICAL_SECTION TimeCS; // timeGetTime() support with wrap. uint32_t OldMMTimeMs; uint32_t MMTimeWrapCounter; // Cached performance frequency result. - uint64_t PrefFrequency; + uint64_t PerfFrequency; // cycles per second, typically a large value like 3000000, but usually not the same as the CPU clock rate. + double PerfFrequencyInverse; // seconds per cycle (will be a small fractional value). + double PerfFrequencyInverseNanos; // nanoseconds per cycle. // Computed as (perfCounterNanos - ticksCounterNanos) initially, // and used to adjust timing. @@ -149,117 +218,166 @@ struct PerformanceTimer uint64_t LastResultNanos; }; -PerformanceTimer Win32_PerfTimer; +static PerformanceTimer Win32_PerfTimer; void PerformanceTimer::Initialize() { - MMRESULT mmr = timeBeginPeriod(1); - OVR_ASSERT(TIMERR_NOERROR == mmr); - OVR_UNUSED(mmr); + #if defined(OVR_OS_WIN32) // Desktop Windows only + // The following has the effect of setting the NT timer resolution (NtSetTimerResolution) to 1 millisecond. + MMRESULT mmr = timeBeginPeriod(1); + OVR_ASSERT(TIMERR_NOERROR == mmr); + OVR_UNUSED(mmr); + #endif InitializeCriticalSection(&TimeCS); MMTimeWrapCounter = 0; getFrequency(); - // Set Vista flag. On Vista, we can just use QPC() without all the extra work - OSVERSIONINFOEX ver; - ZeroMemory(&ver, sizeof(OSVERSIONINFOEX)); - ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - ver.dwMajorVersion = 6; // Vista+ + #if defined(OVR_OS_WIN32) // Desktop Windows only + // Set Vista flag. On Vista, we can just use QPC() without all the extra work + OSVERSIONINFOEX ver; + ZeroMemory(&ver, sizeof(OSVERSIONINFOEX)); + ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + ver.dwMajorVersion = 6; // Vista+ + + DWORDLONG condMask = 0; + VER_SET_CONDITION(condMask, VER_MAJORVERSION, VER_GREATER_EQUAL); - DWORDLONG condMask = 0; - VER_SET_CONDITION(condMask, VER_MAJORVERSION, VER_GREATER_EQUAL); + // VerifyVersionInfo returns true if the OS meets the conditions set above + UsingVistaOrLater = VerifyVersionInfo(&ver, VER_MAJORVERSION, condMask) != 0; + #else + UsingVistaOrLater = true; + #endif - // VerifyVersionInfo returns true if the OS meets the conditions set above - UsingVista = VerifyVersionInfo(&ver, VER_MAJORVERSION, condMask) != 0; + OVR_DEBUG_LOG(("PerformanceTimer UsingVistaOrLater = %d", (int)UsingVistaOrLater)); - OVR_DEBUG_LOG(("Performance timer Vista flag = %d", (int)UsingVista)); + #if defined(OVR_BUILD_DEBUG) && defined(OVR_OS_WIN32) + HMODULE hNtDll = LoadLibrary(L"NtDll.dll"); + if (hNtDll) + { + pNtQueryTimerResolution = (NtQueryTimerResolutionType)GetProcAddress(hNtDll, "NtQueryTimerResolution"); + //pNtSetTimerResolution = (NtSetTimerResolutionType)GetProcAddress(hNtDll, "NtSetTimerResolution"); + + if(pNtQueryTimerResolution) + { + ULONG MinimumResolution; // in 100-ns units + ULONG MaximumResolution; + ULONG ActualResolution; + pNtQueryTimerResolution(&MinimumResolution, &MaximumResolution, &ActualResolution); + OVR_DEBUG_LOG(("NtQueryTimerResolution = Min %ld us, Max %ld us, Current %ld us", MinimumResolution / 10, MaximumResolution / 10, ActualResolution / 10)); + } + + FreeLibrary(hNtDll); + } + #endif } void PerformanceTimer::Shutdown() { DeleteCriticalSection(&TimeCS); - MMRESULT mmr = timeEndPeriod(1); - OVR_ASSERT(TIMERR_NOERROR == mmr); - OVR_UNUSED(mmr); + + #if defined(OVR_OS_WIN32) // Desktop Windows only + MMRESULT mmr = timeEndPeriod(1); + OVR_ASSERT(TIMERR_NOERROR == mmr); + OVR_UNUSED(mmr); + #endif } + +uint64_t PerformanceTimer::GetTimeSeconds() +{ + if (UsingVistaOrLater) + { + LARGE_INTEGER li; + QueryPerformanceCounter(&li); + OVR_ASSERT(PerfFrequencyInverse != 0); // Initialize should have been called earlier. + return (uint64_t)(li.QuadPart * PerfFrequencyInverse); + } + + return (uint64_t)(GetTimeNanos() * .0000000001); +} + + +double PerformanceTimer::GetTimeSecondsDouble() +{ + if (UsingVistaOrLater) + { + LARGE_INTEGER li; + QueryPerformanceCounter(&li); + OVR_ASSERT(PerfFrequencyInverse != 0); + return (li.QuadPart * PerfFrequencyInverse); + } + + return (GetTimeNanos() * .0000000001); +} + + uint64_t PerformanceTimer::GetTimeNanos() { - uint64_t resultNanos; - LARGE_INTEGER li; + uint64_t resultNanos; + LARGE_INTEGER li; - // If on Vista, - if (UsingVista) + OVR_ASSERT(PerfFrequencyInverseNanos != 0); // Initialize should have been called earlier. + + if (UsingVistaOrLater) // Includes non-desktop platforms { // Then we can use QPC() directly without all that extra work QueryPerformanceCounter(&li); - - uint64_t frequency = getFrequency(); - uint64_t perfCounterSeconds = (uint64_t)li.QuadPart / frequency; - uint64_t perfRemainderNanos = (((uint64_t)li.QuadPart - perfCounterSeconds * frequency) * - Timer::NanosPerSecond) / frequency; - resultNanos = perfCounterSeconds * Timer::NanosPerSecond + perfRemainderNanos; + resultNanos = (uint64_t)(li.QuadPart * PerfFrequencyInverseNanos); } else { - - // On Win32 QueryPerformanceFrequency is unreliable due to SMP and - // performance levels, so use this logic to detect wrapping and track - // high bits. - ::EnterCriticalSection(&TimeCS); - - // Get raw value and perf counter "At the same time". - QueryPerformanceCounter(&li); - - DWORD mmTimeMs = timeGetTime(); - if (OldMMTimeMs > mmTimeMs) - MMTimeWrapCounter++; - OldMMTimeMs = mmTimeMs; - - // Normalize to nanoseconds. - uint64_t frequency = getFrequency(); - uint64_t perfCounterSeconds = uint64_t(li.QuadPart) / frequency; - uint64_t perfRemainderNanos = ( (uint64_t(li.QuadPart) - perfCounterSeconds * frequency) * - Timer::NanosPerSecond ) / frequency; - uint64_t perfCounterNanos = perfCounterSeconds * Timer::NanosPerSecond + perfRemainderNanos; - - uint64_t mmCounterNanos = ((uint64_t(MMTimeWrapCounter) << 32) | mmTimeMs) * 1000000; - if (PerfMinusTicksDeltaNanos == 0) - PerfMinusTicksDeltaNanos = perfCounterNanos - mmCounterNanos; + // On Win32 QueryPerformanceFrequency is unreliable due to SMP and + // performance levels, so use this logic to detect wrapping and track + // high bits. + ::EnterCriticalSection(&TimeCS); + + // Get raw value and perf counter "At the same time". + QueryPerformanceCounter(&li); + + DWORD mmTimeMs = timeGetTime(); + if (OldMMTimeMs > mmTimeMs) + MMTimeWrapCounter++; + OldMMTimeMs = mmTimeMs; + + // Normalize to nanoseconds. + uint64_t perfCounterNanos = (uint64_t)(li.QuadPart * PerfFrequencyInverseNanos); + uint64_t mmCounterNanos = ((uint64_t(MMTimeWrapCounter) << 32) | mmTimeMs) * 1000000; + if (PerfMinusTicksDeltaNanos == 0) + PerfMinusTicksDeltaNanos = perfCounterNanos - mmCounterNanos; - // Compute result before snapping. - // - // On first call, this evaluates to: - // resultNanos = mmCounterNanos. - // Next call, assuming no wrap: - // resultNanos = prev_mmCounterNanos + (perfCounterNanos - prev_perfCounterNanos). - // After wrap, this would be: - // resultNanos = snapped(prev_mmCounterNanos +/- 1ms) + (perfCounterNanos - prev_perfCounterNanos). - // - resultNanos = perfCounterNanos - PerfMinusTicksDeltaNanos; - - // Snap the range so that resultNanos never moves further apart then its target resolution. - // It's better to allow more slack on the high side as timeGetTime() may be updated at sporadically - // larger then 1 ms intervals even when 1 ms resolution is requested. - if (resultNanos > (mmCounterNanos + MMTimerResolutionNanos*2)) - { - resultNanos = mmCounterNanos + MMTimerResolutionNanos*2; - if (resultNanos < LastResultNanos) - resultNanos = LastResultNanos; - PerfMinusTicksDeltaNanos = perfCounterNanos - resultNanos; - } - else if (resultNanos < (mmCounterNanos - MMTimerResolutionNanos)) - { - resultNanos = mmCounterNanos - MMTimerResolutionNanos; - if (resultNanos < LastResultNanos) - resultNanos = LastResultNanos; - PerfMinusTicksDeltaNanos = perfCounterNanos - resultNanos; - } - - LastResultNanos = resultNanos; - ::LeaveCriticalSection(&TimeCS); + // Compute result before snapping. + // + // On first call, this evaluates to: + // resultNanos = mmCounterNanos. + // Next call, assuming no wrap: + // resultNanos = prev_mmCounterNanos + (perfCounterNanos - prev_perfCounterNanos). + // After wrap, this would be: + // resultNanos = snapped(prev_mmCounterNanos +/- 1ms) + (perfCounterNanos - prev_perfCounterNanos). + // + resultNanos = perfCounterNanos - PerfMinusTicksDeltaNanos; + + // Snap the range so that resultNanos never moves further apart then its target resolution. + // It's better to allow more slack on the high side as timeGetTime() may be updated at sporadically + // larger then 1 ms intervals even when 1 ms resolution is requested. + if (resultNanos > (mmCounterNanos + MMTimerResolutionNanos*2)) + { + resultNanos = mmCounterNanos + MMTimerResolutionNanos*2; + if (resultNanos < LastResultNanos) + resultNanos = LastResultNanos; + PerfMinusTicksDeltaNanos = perfCounterNanos - resultNanos; + } + else if (resultNanos < (mmCounterNanos - MMTimerResolutionNanos)) + { + resultNanos = mmCounterNanos - MMTimerResolutionNanos; + if (resultNanos < LastResultNanos) + resultNanos = LastResultNanos; + PerfMinusTicksDeltaNanos = perfCounterNanos - resultNanos; + } + + LastResultNanos = resultNanos; + ::LeaveCriticalSection(&TimeCS); } //Tom's addition, to keep precision @@ -272,6 +390,20 @@ uint64_t PerformanceTimer::GetTimeNanos() } +//------------------------------------------------------------------------ +// *** Timer - Platform Independent functions + +// Returns global high-resolution application timer in seconds. +double Timer::GetSeconds() +{ + if(useFakeSeconds) + return FakeSeconds; + + return Win32_PerfTimer.GetTimeSecondsDouble(); +} + + + // Delegate to PerformanceTimer. uint64_t Timer::GetTicksNanos() { @@ -283,25 +415,104 @@ uint64_t Timer::GetTicksNanos() void Timer::initializeTimerSystem() { Win32_PerfTimer.Initialize(); - } void Timer::shutdownTimerSystem() { Win32_PerfTimer.Shutdown(); } -#else // !OVR_OS_WIN32 && !OVR_OS_ANDROID + + +#elif defined(OVR_OS_MAC) + + +double Timer::TimeConvertFactorNanos = 0.0; +double Timer::TimeConvertFactorSeconds = 0.0; //------------------------------------------------------------------------ // *** Standard OS Timer +// Returns global high-resolution application timer in seconds. +double Timer::GetSeconds() +{ + if(useFakeSeconds) + return FakeSeconds; + + OVR_ASSERT(TimeConvertFactorNanos != 0.0); + return (double)mach_absolute_time() * TimeConvertFactorNanos; +} + + uint64_t Timer::GetTicksNanos() { if (useFakeSeconds) return (uint64_t) (FakeSeconds * NanosPerSecond); + + OVR_ASSERT(TimeConvertFactorSeconds != 0.0); + return (uint64_t)(mach_absolute_time() * TimeConvertFactorSeconds); +} + +void Timer::initializeTimerSystem() +{ + mach_timebase_info_data_t timeBase; + mach_timebase_info(&timeBase); + TimeConvertFactorSeconds = ((double)timeBase.numer / (double)timeBase.denom); + TimeConvertFactorNanos = TimeConvertFactorSeconds / 1000000000.0; +} - // TODO: prefer rdtsc when available? +void Timer::shutdownTimerSystem() +{ + // Empty for this platform. +} + + +#else // Posix platforms (e.g. Linux, BSD Unix) + + +bool Timer::MonotonicClockAvailable = false; + + +// Returns global high-resolution application timer in seconds. +double Timer::GetSeconds() +{ + if(useFakeSeconds) + return FakeSeconds; + + // http://linux/die/netman3/clock_gettime + #if defined(CLOCK_MONOTONIC) // If we can use clock_gettime, which has nanosecond precision... + if(MonotonicClockAvailable) + { + timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); // Better to use CLOCK_MONOTONIC than CLOCK_REALTIME. + return static_cast<double>(ts.tv_sec) + static_cast<double>(ts.tv_nsec) / 1E9; + } + #endif + + // We cannot use rdtsc because its frequency changes at runtime. + struct timeval tv; + gettimeofday(&tv, 0); + + return static_cast<double>(tv.tv_sec) + static_cast<double>(tv.tv_usec) / 1E6; +} + + +uint64_t Timer::GetTicksNanos() +{ + if (useFakeSeconds) + return (uint64_t) (FakeSeconds * NanosPerSecond); + + #if defined(CLOCK_MONOTONIC) // If we can use clock_gettime, which has nanosecond precision... + if(MonotonicClockAvailable) + { + timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return ((uint64_t)ts.tv_sec * 1000000000ULL) + (uint64_t)ts.tv_nsec; + } + #endif + + + // We cannot use rdtsc because its frequency changes at runtime. uint64_t result; // Return microseconds. @@ -315,6 +526,23 @@ uint64_t Timer::GetTicksNanos() return result * 1000; } + +void Timer::initializeTimerSystem() +{ + #if defined(CLOCK_MONOTONIC) + timespec ts; // We could also check for the availability of CLOCK_MONOTONIC with sysconf(_SC_MONOTONIC_CLOCK) + int result = clock_gettime(CLOCK_MONOTONIC, &ts); + MonotonicClockAvailable = (result == 0); + #endif +} + +void Timer::shutdownTimerSystem() +{ + // Empty for this platform. +} + + + #endif // OS-specific diff --git a/LibOVR/Src/Kernel/OVR_Timer.h b/LibOVR/Src/Kernel/OVR_Timer.h index ca585b2..6c8dbb7 100644 --- a/LibOVR/Src/Kernel/OVR_Timer.h +++ b/LibOVR/Src/Kernel/OVR_Timer.h @@ -6,16 +6,16 @@ Content : Provides static functions for precise timing Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -42,9 +42,9 @@ class Timer { public: enum { - MsPerSecond = 1000, // Milliseconds in one second. - NanosPerSecond = MsPerSecond * 1000 * 1000, - MksPerSecond = MsPerSecond * 1000 + MsPerSecond = 1000, // Milliseconds in one second. + MksPerSecond = 1000 * 1000, // Microseconds in one second. + NanosPerSecond = 1000 * 1000 * 1000, // Nanoseconds in one second. }; // ***** Timing APIs for Application @@ -65,10 +65,10 @@ public: { return uint32_t(GetTicksNanos() / 1000000); } // for recorded data playback - static void SetFakeSeconds(double fakeSeconds) + static void SetFakeSeconds(double fakeSeconds, bool enable = true) { FakeSeconds = fakeSeconds; - useFakeSeconds = true; + useFakeSeconds = enable; } private: @@ -79,7 +79,18 @@ private: // for recorded data playback static double FakeSeconds; - static bool useFakeSeconds; + static bool useFakeSeconds; + + #if defined(OVR_OS_ANDROID) + // Android-specific data + #elif defined (OVR_OS_MS) + // Microsoft-specific data + #elif defined(OVR_OS_MAC) + static double TimeConvertFactorNanos; // Conversion factor for GetTicksNanos + static double TimeConvertFactorSeconds; // Conversion factor for GetSeconds. + #else + static bool MonotonicClockAvailable; // True if clock_gettime supports CLOCK_MONOTONIC + #endif }; diff --git a/LibOVR/Src/Kernel/OVR_Types.h b/LibOVR/Src/Kernel/OVR_Types.h index ce8053d..c8af61c 100644 --- a/LibOVR/Src/Kernel/OVR_Types.h +++ b/LibOVR/Src/Kernel/OVR_Types.h @@ -6,16 +6,16 @@ Content : Standard library defines and simple types Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -40,15 +40,29 @@ limitations under the License. //----------------------------------------------------------------------------------- -// ****** Operating System +// ****** Operating system identification +// +// Try to use the most generic version of these defines as possible in order to achieve +// the simplest portable code. For example, instead of using #if (defined(OVR_OS_IPHONE) || defined(OVR_OS_MAC)), +// consider using #if defined(OVR_OS_APPLE). // // Type definitions exist for the following operating systems: (OVR_OS_x) // -// WIN32 - Win32 (Windows 95/98/ME and Windows NT/2000/XP) -// DARWIN - Darwin OS (Mac OS X) -// LINUX - Linux -// ANDROID - Android -// IPHONE - iPhone +// WIN32 - Win32 and Win64 (Windows XP and later) Does not include Microsoft phone and console platforms, despite that Microsoft's _WIN32 may be defined by the compiler for them. +// WIN64 - Win64 (Windows XP and later) +// MAC - Mac OS X (may be defined in addition to BSD) +// LINUX - Linux +// BSD - BSD Unix +// ANDROID - Android (may be defined in addition to LINUX) +// IPHONE - iPhone +// MS_MOBILE - Microsoft mobile OS. +// +// Meta platforms +// MS - Any OS by Microsoft (e.g. Win32, Win64, phone, console) +// APPLE - Any OS by Apple (e.g. iOS, OS X) +// UNIX - Linux, BSD, Mac OS X. +// MOBILE - iOS, Android, Microsoft phone +// #if (defined(__APPLE__) && (defined(__GNUC__) ||\ defined(__xlC__) || defined(__xlc__))) || defined(__MACOS__) @@ -57,22 +71,58 @@ limitations under the License. # else # define OVR_OS_DARWIN # define OVR_OS_MAC +# define OVR_OS_BSD # endif #elif (defined(WIN64) || defined(_WIN64) || defined(__WIN64__)) -# define OVR_OS_WIN32 +# define OVR_OS_WIN64 +# define OVR_OS_WIN32 // Defined for compatibility and because the Win64 API supports the Win32 API. #elif (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)) # define OVR_OS_WIN32 +#elif defined(ANDROID) || defined(__ANDROID__) +# define OVR_OS_ANDROID +# define OVR_OS_LINUX #elif defined(__linux__) || defined(__linux) # define OVR_OS_LINUX +#elif defined(_BSD_) || defined(__FreeBSD__) +# define OVR_OS_BSD #else # define OVR_OS_OTHER #endif -#if defined(ANDROID) -# define OVR_OS_ANDROID + +#if !defined(OVR_OS_MS_MOBILE) +# if (defined(_M_ARM) || defined(_M_IX86) || defined(_M_AMD64)) && !defined(OVR_OS_WIN32) && !defined(OVR_OS_CONSOLE) +# define OVR_OS_MS_MOBILE +# endif +#endif + +#if !defined(OVR_OS_MS) +# if defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) || defined(OVR_OS_MS_MOBILE) +# define OVR_OS_MS +# endif +#endif + +#if !defined(OVR_OS_APPLE) +# if defined(OVR_OS_MAC) || defined(OVR_OS_IPHONE) +# define OVR_OS_APPLE +# endif +#endif + +#if !defined(OVR_OS_UNIX) +# if defined(OVR_OS_ANDROID) || defined(OVR_OS_BSD) || defined(OVR_OS_LINUX) || defined(OVR_OS_MAC) +# define OVR_OS_UNIX +# endif +#endif + +#if !defined(OVR_OS_MOBILE) +# if defined(OVR_OS_ANDROID) || defined(OVR_OS_IPHONE) || defined(OVR_OS_MS_MOBILE) +# define OVR_OS_MOBILE +# endif #endif + + //----------------------------------------------------------------------------------- // ***** CPU Architecture // @@ -86,7 +136,7 @@ limitations under the License. // OTHER - CPU for which no special support is present or needed -#if defined(__x86_64__) || defined(WIN64) || defined(_WIN64) || defined(__WIN64__) +#if defined(__x86_64__) || defined(WIN64) || defined(_WIN64) || defined(__WIN64__) || defined(_M_AMD64) # define OVR_CPU_X86_64 # define OVR_64BIT_POINTERS #elif defined(__i386__) || defined(OVR_OS_WIN32) @@ -112,7 +162,7 @@ limitations under the License. // Altivec - Available on all modern ppc processors. // Neon - Available on some armv7+ processors. -#if defined(__SSE__) || defined(OVR_OS_WIN32) +#if defined(__SSE__) || defined(_M_IX86) || defined(_M_AMD64) // _M_IX86 and _M_AMD64 are Microsoft identifiers for Intel-based platforms. # define OVR_CPU_SSE #endif // __SSE__ @@ -196,7 +246,7 @@ typedef size_t UPInt; typedef ptrdiff_t SPInt; -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_MS) typedef char SByte; // 8 bit Integer (Byte) typedef unsigned char UByte; @@ -306,9 +356,9 @@ struct OVR_GUID #define OVR_BIG_ENDIAN 2 -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_MS) - // ***** Win32 + // ***** Windows and non-desktop platforms // Byte order #define OVR_BYTE_ORDER OVR_LITTLE_ENDIAN @@ -501,14 +551,25 @@ struct OVR_GUID // If not in debug build, macros do nothing #ifndef OVR_BUILD_DEBUG +// The expresssion is defined only in debug builds. It is defined away in release builds. # define OVR_DEBUG_CODE(c) + +// Causes a debugger breakpoint in debug builds. Has no effect in release builds. # define OVR_DEBUG_BREAK ((void)0) + +// In debug builds this tests the given expression; if false then executes OVR_DEBUG_BREAK, +// if true then no action. Has no effect in release builds. # define OVR_ASSERT(p) ((void)0) +// Acts the same as OVR_ASSERT in debug builds. Acts the same as OVR_UNUSED in release builds. +// Example usage: OVR_ASSERT_AND_UNUSED(x < 30, x); +#define OVR_ASSERT_AND_UNUSED(expression, value) OVR_UNUSED(value) + #else +// Causes a debugger breakpoint in debug builds. Has no effect in release builds. // Microsoft Win32 specific debugging support -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_MS) # ifdef OVR_CPU_X86 # if defined(__cplusplus_cli) # define OVR_DEBUG_BREAK do { __debugbreak(); } while(0) @@ -527,10 +588,23 @@ struct OVR_GUID # define OVR_DEBUG_BREAK do { *((int *) 0) = 1; } while(0) #endif +// The expresssion is defined only in debug builds. It is defined away in release builds. #define OVR_DEBUG_CODE(c) c -// This will cause compiler breakpoint -#define OVR_ASSERT(p) do { if (!(p)) { OVR_DEBUG_BREAK; } } while(0) +// In debug builds this tests the given expression; if false then executes OVR_DEBUG_BREAK, +// if true then no action. Has no effect in release builds. +#if defined(__clang_analyzer__) // During static analysis, make it so the analyzer thinks that failed asserts result in program exit. Reduced false positives. + #include <stdlib.h> + #define OVR_ASSERT(p) do { if (!(p)) { OVR_DEBUG_BREAK; exit(0); } } while(0) +#else + #define OVR_ASSERT(p) do { if (!(p)) { OVR_DEBUG_BREAK; } } while(0) +#endif + + + +// Acts the same as OVR_ASSERT in debug builds. Acts the same as OVR_UNUSED in release builds. +// Example usage: OVR_ASSERT_AND_UNUSED(x < 30, x); +#define OVR_ASSERT_AND_UNUSED(expression, value) OVR_ASSERT(expression); OVR_UNUSED(value) #endif // OVR_BUILD_DEBUG @@ -540,6 +614,8 @@ struct OVR_GUID // // Compile-time assert; produces compiler error if condition is false. // The expression must be a compile-time constant expression. +// This macro is deprecated in favor of static_assert, which provides better +// compiler output and works in a broader range of contexts. // // Example usage: // OVR_COMPILER_ASSERT(sizeof(int32_t == 4)); diff --git a/LibOVR/Src/Kernel/OVR_UTF8Util.cpp b/LibOVR/Src/Kernel/OVR_UTF8Util.cpp index 0e8f0e6..68e58ea 100644 --- a/LibOVR/Src/Kernel/OVR_UTF8Util.cpp +++ b/LibOVR/Src/Kernel/OVR_UTF8Util.cpp @@ -7,16 +7,16 @@ Notes : Notes : Much useful info at "UTF-8 and Unicode FAQ" http://www.cl.cam.ac.uk/~mgk25/unicode.html -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, diff --git a/LibOVR/Src/Kernel/OVR_UTF8Util.h b/LibOVR/Src/Kernel/OVR_UTF8Util.h index f80edfe..3b640f0 100644 --- a/LibOVR/Src/Kernel/OVR_UTF8Util.h +++ b/LibOVR/Src/Kernel/OVR_UTF8Util.h @@ -6,16 +6,16 @@ Content : UTF8 Unicode character encoding/decoding support Created : September 19, 2012 Notes : -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, |